| name | parseltongue-bench |
| description | Use pg-bench CLI daemon for instant .pltg inspection — search, lens, diagnose, dissect, compose. Activates when working with .pltg files, debugging consistency, tracing provenance, or exploring parseltongue codebase. Always prefer pg-bench over grep/read for this codebase. |
| user-invocable | true |
pg-bench
Persistent daemon that holds a loaded .pltg Bench in memory. Start once, query instantly.
eval and interpret are the primary interface. eval is pure (clean copy each time), interpret accumulates state (clean resets it). Both accept S-expressions with the full std library, scopes (lens, screen, ops, search, hologram), and fmt for formatted output.
Start
pg-bench serve parseltongue/core/validation/core.pltg & pg-bench wait
pg-bench index parseltongue/core
wait blocks until bench is ready (~200ms with Merkle cache). No sleep needed — socket opens immediately, wait polls until bench status leaves initialized.
Start variants:
pg-bench serve file.pltg — foreground (blocking)
pg-bench start file.pltg — daemonized (returns immediately)
pg-bench up file.pltg — foreground; pg-bench up -d to detach
Lifecycle: the server loads a frozen cache immediately (~20ms) so queries work right away, then computes a live evaluation in a background thread. Use pg-bench status to check whether the bench is frozen or live.
Always index with all default extensions. The .md and .pltg files matter — pltg nodes quote from them.
Eval: pure S-expression evaluation
pg-bench eval '(+ 1 2)'
pg-bench eval '(scope lens (find "engine"))'
pg-bench eval '(scope screen (issues))'
pg-bench eval '(fmt "viz" (scope lens (kind "fact")))' > out.html
pg-bench eval -f script.pltg
echo '(+ 1 2)' | pg-bench eval
pg-bench '(+ 1 2)'
Pure — uses a clean copy of the loaded system. Never polluted by interpret. See pg-bench eval --help for the full operator reference.
Interpret: stateful directive execution
pg-bench interpret '(defterm my-val 42 :origin "test")'
pg-bench interpret '(fact check true :evidence ("f.py" :quotes ("x")))'
pg-bench interpret -f setup.pltg
pg-bench clean
Like eval, but also accepts directives (defterm, fact, axiom, derive). State accumulates across calls. Does not affect the main loaded system or the eval scope.
Scopes
Scopes are registered subsystem query languages accessible via (scope name expr).
Lens scope — structural navigation over the pltg graph
pg-bench eval '(scope lens (kind "fact"))'
pg-bench eval '(scope lens (inputs "engine.derive"))'
pg-bench eval '(scope lens (downstream "engine.derive"))'
pg-bench eval '(scope lens (roots))'
pg-bench eval '(scope lens (layer 2))'
pg-bench eval '(scope lens (focus "engine."))'
pg-bench eval '(scope lens (find "engine.eval"))'
pg-bench eval '(scope lens (fuzzy "derive"))'
pg-bench eval '(scope lens (terms "axiom"))'
pg-bench eval '(scope lens (quotes "name"))'
pg-bench eval '(scope lens (atom "name"))'
Screen scope — consistency results (alias: diagnose, evaluation)
pg-bench eval '(scope screen (issues))'
pg-bench eval '(scope screen (warnings))'
pg-bench eval '(scope screen (danglings))'
pg-bench eval '(scope screen (loader))'
pg-bench eval '(scope screen (focus "engine."))'
pg-bench eval '(scope screen (find "engine"))'
pg-bench eval '(scope screen (consistent))'
Ops scope — fast set operations over tagged form lists
pg-bench eval '(scope ops (and-forms L1 L2))'
pg-bench eval '(scope ops (or-forms L1 L2))'
pg-bench eval '(scope ops (not-forms L1 L2))'
pg-bench eval '(scope ops (count-forms L))'
pg-bench eval '(scope ops (str format "{}" (V data)))'
pg-bench eval '(scope ops (list get (V data) N))'
Hologram scope — after dissect/compose/stain
pg-bench eval '(scope hologram (left))'
pg-bench eval '(scope hologram (right))'
pg-bench eval '(scope hologram (divergent))'
pg-bench eval '(scope hologram (common))'
pg-bench eval '(scope hologram (only 0))'
pg-bench eval '(scope hologram (dissect "diff-name"))'
pg-bench eval '(scope hologram (compose n1 n2))'
pg-bench eval '(scope hologram (dissect (stain "name")))'
fmt — format bench forms for display
pg-bench eval '(fmt "md" (scope lens (kind "fact")))'
pg-bench eval '(fmt "viz" (scope lens (focus "engine.")))'
pg-bench eval '(fmt "viz" (scope hologram (divergent)))'
Perspectives: "md" (markdown), "ascii" (terminal), "viz" (interactive HTML).
Viz: interactive HTML visualization
(fmt "viz" expr) renders any scope result as a self-contained HTML file with three view modes, search, kind filters, and an evidence panel. Pipe output to a file and open in browser.
pg-bench eval '(fmt "viz" (scope lens (kind "fact")))' > temp/facts.html
pg-bench eval '(fmt "viz" (scope lens (focus "engine.")))' > temp/engine.html
pg-bench eval '(fmt "viz" (scope lens (kind "all")))' > temp/full.html
pg-bench eval '(fmt "viz" (scope screen (issues)))' > temp/issues.html
pg-bench eval '(fmt "viz" (scope screen (warnings)))' > temp/warnings.html
pg-bench eval '(fmt "viz" (scope hologram (divergent)))' > temp/divergent.html
pg-bench eval '(fmt "viz" (scope hologram (common)))' > temp/common.html
pg-bench eval '(fmt "viz" (scope ops (and-forms (scope lens (kind "fact")) (scope lens (focus "engine.")))))' > temp/eng_facts.html
The HTML includes:
- Cards view: one card per node with kind dot, name, value, inputs
- Layers view: depth-based stacked layout showing the full dependency structure
- Graph view: D3 force-directed graph with zoom/pan, clickable nodes
- Search bar: live filter across all nodes
- Kind filter: toggle node kinds on/off (fact, axiom, theorem, term, diff)
- Detail panel: click any node to see full quotes, file:line, confidence scores, derivation tree
Works with all tagged form types: ln (lens), dx (screen), sr (search), hn (hologram). Cached on disk via Store for instant re-renders.
Always pipe to temp/ — never to stdout for reading. Open the file in a browser.
Search: S-expression query language
pg-bench search "raise ValueError"
pg-bench search '(and "import" "quote")'
pg-bench search '(or "raise ValueError" "raise SyntaxError")'
pg-bench search '(not (in "engine.py" "raise") "KeyError")'
pg-bench search '(in "engine.py" "raise")'
pg-bench search '(in "tests/*" "raise")'
pg-bench search '(in "engine" "raise")'
pg-bench search '(not-in "engine.py" "raise")'
pg-bench search '(near "raise" "ValueError" 2)'
pg-bench search '(seq "def derive" "raise")'
pg-bench search '(re "raise (ValueError|NameError)")'
pg-bench search '(lines 400 500 (in "engine.py" (re ".")))'
pg-bench search '(context 3 "raise")'
pg-bench search '(before 3 "raise")'
pg-bench search '(after 3 "raise")'
pg-bench search '(rank "callers" query)'
pg-bench search '(strategy "stemmed" "evaluate")'
pg-bench search '(count (in "engine.py" "raise"))'
pg-bench search '(limit 5 query)'
pg-bench search '(scope lens (find "engine"))'
pg-bench search '(scope screen (issues))'
pg-bench search '(not (in "engine.py" (near "raise" "ValueError" 3)) "KeyError")'
Results include pltg provenance: [engine.derivation-impl-count] def derive( — the pltg node that quotes that line.
Lens: structural navigation (CLI shortcuts)
pg-bench find "error"
pg-bench fuzzy "eval"
pg-bench find "error" --scope screen
pg-bench view engine.eval-bind
pg-bench view
pg-bench focus "engine."
pg-bench consumer engine.derive
pg-bench inputs engine.derive
pg-bench subgraph engine.derive
pg-bench subgraph engine.derive -d downstream
pg-bench subgraph engine.derive -d both
pg-bench kinds
pg-bench roots
Hologram: multi-lens views (requires live)
pg-bench dissect atoms.theorem-derivation-sources
pg-bench dissect atoms.theorem-derivation-sources --bias divergence
pg-bench compose engine.eval-bind engine.derive
pg-bench compose engine.eval-bind engine.derive --bias left
pg-bench stain all-contract-facts-ok all-product-facts-ok
Biases control how lens outputs are combined: neutral (side by side), left (left primary), right (right primary), divergence (only differences). The hologram scope in the search system has analogous structural operators (divergent, common, only N) at the posting-set level.
Diagnosis
pg-bench screen
pg-bench screen --what issues
pg-bench screen --what warnings
pg-bench screen --what danglings
pg-bench screen --what ok
pg-bench screen --what stats
pg-bench screen --focus "engine."
pg-bench diagnose --what issues
History: time travel over indexed states
Each pg-bench index commits an immutable delta layer. Restore is non-destructive (appends reverse delta).
pg-bench history layers
pg-bench history files
pg-bench history files -l 2
pg-bench history file NAME
pg-bench history file NAME -l 2
pg-bench history diff
pg-bench history diff --from 1 --to 3
pg-bench history diff-file NAME
pg-bench history restore 2
pg-bench history restore-file NAME 2
pg-bench history compact --yes
Operations
pg-bench ping
pg-bench wait
pg-bench status
pg-bench reload
pg-bench purge
pg-bench clean
Typical cold start is ~200ms (Merkle cache). Chain as single command:
pg-bench serve core.pltg & pg-bench wait && pg-bench find "engine"
Advanced usage patterns
project — resolve in parent before crossing scope boundary
pg-bench eval '(scope lens (focus (project engine-prefix)))'
delegate — defer resolution past current scope
pg-bench eval '(delegate (file-hits ?file))'
Map-reduce pipeline example
Pipeline: diagnostics → lens evidence → search intersection → per-file report.
Run via pg-bench interpret -f pipeline.pltg.
; ── 1. Issues from diagnostics ──
(defterm issues (scope evaluation (issues)) :origin "all issues")
; ── 2. Enrich with lens evidence (intersect issues with full graph) ──
(defterm ln-issues
(scope ops (and-forms (scope lens (kind "all")) (project issues)))
:origin "ln forms for issue nodes"
:using (issues))
; ── 3. Extract fields via vectorized ops ──
(defterm evidence (scope ops (list get (V (project ln-issues)) 6)) :origin "ln-ev" :using (ln-issues))
(defterm issue-names (scope ops (list get (V (project ln-issues)) 1)) :origin "names" :using (ln-issues))
(defterm issue-ev-docs (scope ops (list get (V (project evidence)) 1)) :origin "docs" :using (evidence))
; ── 4. Unique source docs → regex for search ──
(defterm issue-docs (scope ops (list unique (list filter (project issue-ev-docs)))) :origin "unique docs" :using (issue-ev-docs))
(defterm doc-regex (scope ops (str join "|" (project issue-docs))) :origin "regex" :using (issue-docs))
; ── 5. Cross-scope search: test files referencing issue docs ──
(defterm issue-test-hits (scope search (in "test_*" (re (project doc-regex)))) :origin "test hits" :using (doc-regex))
(defterm synthetic-hits (scope search (in "test_*" (re "generate|synthetic"))) :origin "synth hits")
; ── 6. File intersection ──
(defterm common-files
(scope ops (list unique (and-forms
(list get (project issue-test-hits) 1)
(list get (project synthetic-hits) 1))))
:origin "files matching both"
:using (issue-test-hits synthetic-hits))
; ── 7. Per-file search via axiom (delegate defers past ops scope) ──
(defterm file-hits :origin "search hits for one file")
(axiom file-hits-rule
(= (file-hits ?file)
(scope search (in ?file (or (re (project doc-regex))
(re "generate|synthetic")))))
:origin "search one file"
:using (in or re doc-regex))
; ── 8. Per-file report section ──
(defterm rs :origin "report section per file")
(axiom rs-rule
(= (rs ?file)
(scope ops (str format "\n── {} ──\n {}"
?file
(str join "\n " (list get (delegate (file-hits ?file)) 4)))))
:origin "section"
:using (str list format join get file-hits))
; ── 9. Recurse over all files via splat ──
(defterm report-all :origin "all sections")
(axiom report-all-base (= (report-all (?file)) (rs ?file)) :origin "base")
(axiom report-all-step
(= (report-all (?file ?...rest)) (+ (rs ?file) (report-all (?...rest))))
:origin "step")
; ── 10. Execute ──
(defterm body (report-all (strict (project common-files))) :origin "body" :using (common-files))
body
Key patterns:
(project expr) — resolve in parent (bench) engine before entering scope
(delegate expr) — defer resolution past current scope
(?file ?...rest) — splat axioms for recursive list traversal
(strict ...) — force evaluation before axiom pattern matching
(scope ops (list get (V data) N)) — vectorized field extraction
(scope ops (str format ...)) — vectorized string formatting
See also parseltongue/core/demos/ for governance pipelines, spec validation, and revenue reports.
Bench first, grep second
This codebase is heavily covered by .pltg. The fastest path:
pg-bench find/fuzzy — instant structural nodes with kind + file:line
pg-bench search — full-text with provenance tracing
pg-bench eval '(scope lens/screen ...)' — structured queries
- grep/glob — only for things outside pltg coverage
Bench is cached via Merkle trees. After first load, queries are ~2ms.