rulecatcher 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rulecatcher-0.1.0/PKG-INFO +439 -0
- rulecatcher-0.1.0/README.md +432 -0
- rulecatcher-0.1.0/pyproject.toml +17 -0
- rulecatcher-0.1.0/setup.cfg +4 -0
- rulecatcher-0.1.0/src/rulecatcher/__init__.py +5 -0
- rulecatcher-0.1.0/src/rulecatcher/__main__.py +7 -0
- rulecatcher-0.1.0/src/rulecatcher/cli.py +950 -0
- rulecatcher-0.1.0/src/rulecatcher/compare.py +454 -0
- rulecatcher-0.1.0/src/rulecatcher/db.py +681 -0
- rulecatcher-0.1.0/src/rulecatcher/detect.py +174 -0
- rulecatcher-0.1.0/src/rulecatcher/engine.py +115 -0
- rulecatcher-0.1.0/src/rulecatcher/explain.py +232 -0
- rulecatcher-0.1.0/src/rulecatcher/governance.py +94 -0
- rulecatcher-0.1.0/src/rulecatcher/graphing.py +732 -0
- rulecatcher-0.1.0/src/rulecatcher/history.py +47 -0
- rulecatcher-0.1.0/src/rulecatcher/linting.py +221 -0
- rulecatcher-0.1.0/src/rulecatcher/models.py +139 -0
- rulecatcher-0.1.0/src/rulecatcher/present.py +185 -0
- rulecatcher-0.1.0/src/rulecatcher/report.py +260 -0
- rulecatcher-0.1.0/src/rulecatcher/session.py +122 -0
- rulecatcher-0.1.0/src/rulecatcher/snapshot.py +218 -0
- rulecatcher-0.1.0/src/rulecatcher/tokenize.py +112 -0
- rulecatcher-0.1.0/src/rulecatcher/triage.py +289 -0
- rulecatcher-0.1.0/src/rulecatcher.egg-info/PKG-INFO +439 -0
- rulecatcher-0.1.0/src/rulecatcher.egg-info/SOURCES.txt +27 -0
- rulecatcher-0.1.0/src/rulecatcher.egg-info/dependency_links.txt +1 -0
- rulecatcher-0.1.0/src/rulecatcher.egg-info/entry_points.txt +2 -0
- rulecatcher-0.1.0/src/rulecatcher.egg-info/top_level.txt +1 -0
- rulecatcher-0.1.0/tests/test_rulecatcher.py +1462 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: rulecatcher
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: SQLite-backed rule catcher for emergent LLM DSLs.
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
|
|
8
|
+
# RuleCatcher
|
|
9
|
+
|
|
10
|
+
`rulecatcher` is a small SQLite-backed CLI for catching emergent syntax rules from symbolic text.
|
|
11
|
+
|
|
12
|
+
The first version is intentionally simple:
|
|
13
|
+
|
|
14
|
+
1. Read one or more text files.
|
|
15
|
+
2. Learn repeated next-token expectations from history.
|
|
16
|
+
3. Store those expectations as candidate rules with evidence and confidence.
|
|
17
|
+
4. Let a human adopt or reject the rules.
|
|
18
|
+
5. Lint future text against the adopted rule stack.
|
|
19
|
+
6. Suggest normalizations when the stack predicts a different next token.
|
|
20
|
+
|
|
21
|
+
This is not a full parser or reasoning engine. It is the first runtime loop for:
|
|
22
|
+
|
|
23
|
+
```txt
|
|
24
|
+
observe pattern
|
|
25
|
+
-> propose rule
|
|
26
|
+
-> adopt/reject
|
|
27
|
+
-> stack rule
|
|
28
|
+
-> lint future text
|
|
29
|
+
-> normalize drift
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Why SQLite
|
|
33
|
+
|
|
34
|
+
The system needs durable internal state for:
|
|
35
|
+
|
|
36
|
+
- candidate rules
|
|
37
|
+
- rule evidence
|
|
38
|
+
- adoption status
|
|
39
|
+
- decision history
|
|
40
|
+
- source artifacts
|
|
41
|
+
- stack history
|
|
42
|
+
|
|
43
|
+
That becomes database-shaped quickly, so the MVP uses SQLite as the source of truth.
|
|
44
|
+
|
|
45
|
+
## Commands
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
rulecatcher catch examples/runes.txt
|
|
49
|
+
cat examples/runes.txt | rulecatcher catch - --label shell-demo
|
|
50
|
+
rulecatcher review
|
|
51
|
+
rulecatcher review --scope syntax --rule-type next_kind
|
|
52
|
+
rulecatcher review --scope syntax --json
|
|
53
|
+
rulecatcher adopt 1 --actor silas --reason "stable core syntax"
|
|
54
|
+
rulecatcher reject 7 --source review-loop --reason "too noisy"
|
|
55
|
+
rulecatcher stack --scope global
|
|
56
|
+
rulecatcher explain 3 --json
|
|
57
|
+
rulecatcher explain --scope alpha --rule-type next_token --prefix-token state --prefix-token '=>' --expected-token open
|
|
58
|
+
rulecatcher report --scope alpha --json
|
|
59
|
+
rulecatcher export-scope --scope alpha > alpha.rulecatcher.json
|
|
60
|
+
rulecatcher import-scope alpha.rulecatcher.json --scope beta --replace-scope --json
|
|
61
|
+
rulecatcher compare scope:alpha scope:beta --json
|
|
62
|
+
rulecatcher compare alpha.rulecatcher.json scope:alpha
|
|
63
|
+
rulecatcher triage --scope global
|
|
64
|
+
rulecatcher triage --scope global --focus all
|
|
65
|
+
rulecatcher triage --scope global --all
|
|
66
|
+
rulecatcher triage --scope alpha --recommendation review --json
|
|
67
|
+
rulecatcher apply-triage --scope alpha --recommendation adopt --dry-run --json
|
|
68
|
+
rulecatcher apply-triage --scope alpha --recommendation adopt --focus core --actor silas
|
|
69
|
+
rulecatcher apply-triage --scope alpha --recommendation adopt --actor silas
|
|
70
|
+
rulecatcher history --scope global --json
|
|
71
|
+
rulecatcher govern --scope global
|
|
72
|
+
rulecatcher govern --scope alpha --recommendation review --json
|
|
73
|
+
rulecatcher graph --scope global --format mermaid
|
|
74
|
+
rulecatcher graph --scope syntax --layer rules --rule-type next_kind --format table
|
|
75
|
+
rulecatcher graph --scope alpha --layer metasystem --format dot
|
|
76
|
+
rulecatcher graph --scope alpha --layer metasystem --json
|
|
77
|
+
rulecatcher conflicts --scope syntax --json
|
|
78
|
+
rulecatcher lint examples/runes_broken.txt
|
|
79
|
+
printf 'state => closed\n' | rulecatcher lint - --label incoming-check
|
|
80
|
+
printf 'door closed\n' | rulecatcher lint - --scope syntax --json
|
|
81
|
+
rulecatcher normalize examples/runes_broken.txt
|
|
82
|
+
rulecatcher normalize examples/runes_broken.txt --in-place
|
|
83
|
+
printf 'state => closed\nmode => safe\n' | rulecatcher session --scope alpha --label live --format jsonl
|
|
84
|
+
printf 'door => open\nwindow => closed\n' | rulecatcher session --scope beta --label learn-beta --learn --format jsonl
|
|
85
|
+
printf 'state => open\nstate => open\nstate => open\n' | rulecatcher session --scope alpha --label teach --learn --triage --format jsonl
|
|
86
|
+
printf 'state => open\nstate => open\nstate => open\n' | rulecatcher session --scope alpha --label auto --learn --triage --apply-triage adopt --format jsonl
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
All commands accept `--db` to choose a database path. The default is `.rulecatcher.db` in the current working directory.
|
|
90
|
+
Commands that read or apply rules also accept `--scope`, so multiple emergent
|
|
91
|
+
DSLs can live in one database without contaminating each other.
|
|
92
|
+
Use `catch --replace-scope` when you want to discard a scope and rebuild it
|
|
93
|
+
from a new artifact set instead of accumulating more history.
|
|
94
|
+
|
|
95
|
+
## Rule Types in the MVP
|
|
96
|
+
|
|
97
|
+
The MVP learns two rule families:
|
|
98
|
+
|
|
99
|
+
- `next_token`: for a repeated prefix history, expect a specific next token
|
|
100
|
+
- `next_kind`: for a repeated syntax-class prefix, expect a specific token class
|
|
101
|
+
|
|
102
|
+
Example:
|
|
103
|
+
|
|
104
|
+
```txt
|
|
105
|
+
state => open
|
|
106
|
+
state => open
|
|
107
|
+
state => open
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
This can induce a rule like:
|
|
111
|
+
|
|
112
|
+
```txt
|
|
113
|
+
["state", "=>"] -> "open"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
If future text says:
|
|
117
|
+
|
|
118
|
+
```txt
|
|
119
|
+
state => closed
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
then `lint` can flag the drift and `normalize` can suggest `open`.
|
|
123
|
+
|
|
124
|
+
Class rules are what let the tool generalize beyond exact strings. If it sees
|
|
125
|
+
enough examples of:
|
|
126
|
+
|
|
127
|
+
```txt
|
|
128
|
+
identifier => identifier
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
it can learn reusable syntax expectations like:
|
|
132
|
+
|
|
133
|
+
```txt
|
|
134
|
+
[<IDENTIFIER>] -> <OPERATOR>
|
|
135
|
+
[<IDENTIFIER>, <OPERATOR>] -> <IDENTIFIER>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
That means novel text such as `door closed` can be flagged as structurally
|
|
139
|
+
broken even if `door` and `closed` never appeared in the corpus.
|
|
140
|
+
|
|
141
|
+
## Keyword-Aware Tokenization
|
|
142
|
+
|
|
143
|
+
By default the tokenizer classifies every word as `<IDENTIFIER>`. For notations
|
|
144
|
+
where certain words are structural keywords (e.g. `state`, `as` in a state-graph
|
|
145
|
+
DSL), that conflation hides grammar: a declaration like `state x ...` and a
|
|
146
|
+
transition like `name --> ...` share the `[<BOS>, IDENTIFIER]` prefix and pull
|
|
147
|
+
the line-initial rule's confidence down.
|
|
148
|
+
|
|
149
|
+
Pass `--keyword` (repeatable) to `catch` to lift chosen words into their own
|
|
150
|
+
`<KEYWORD>` class:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
rulecatcher catch grammar.txt --scope dsl --keyword state --keyword as
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
The keyword set is persisted per scope, so `lint`, `normalize`, and
|
|
157
|
+
`session --learn` reconstruct the same token classes automatically — you only
|
|
158
|
+
declare keywords at `catch` time. Omitting `--keyword` on a later `catch`
|
|
159
|
+
reuses the scope's stored keywords; the default (no keywords ever set) is
|
|
160
|
+
unchanged from prior behaviour.
|
|
161
|
+
|
|
162
|
+
## Example
|
|
163
|
+
|
|
164
|
+
See [examples/runes.txt](examples/runes.txt) and [examples/runes_broken.txt](examples/runes_broken.txt).
|
|
165
|
+
|
|
166
|
+
## Installation
|
|
167
|
+
|
|
168
|
+
For normal development:
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
python3 -m pip install --no-build-isolation -e .
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The `--no-build-isolation` form matters in offline or restricted environments
|
|
175
|
+
where `pip` cannot download build dependencies.
|
|
176
|
+
|
|
177
|
+
You can also run the module directly:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
python3 -m rulecatcher --help
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Machine Use
|
|
184
|
+
|
|
185
|
+
Most governance commands now support `--json`, which is the preferred mode when
|
|
186
|
+
another LLM or automation wants to consume the tool programmatically.
|
|
187
|
+
|
|
188
|
+
High-value machine surfaces:
|
|
189
|
+
|
|
190
|
+
- `review --json`
|
|
191
|
+
- `stack --json`
|
|
192
|
+
- `explain --json`
|
|
193
|
+
- `report --json`
|
|
194
|
+
- `import-scope --json`
|
|
195
|
+
- `compare --json`
|
|
196
|
+
- `triage --json`
|
|
197
|
+
- `apply-triage --json`
|
|
198
|
+
- `history --json`
|
|
199
|
+
- `govern --json`
|
|
200
|
+
- `conflicts --json`
|
|
201
|
+
- `graph --json`
|
|
202
|
+
- `lint --json`
|
|
203
|
+
- `normalize --json`
|
|
204
|
+
- `session --format jsonl`
|
|
205
|
+
|
|
206
|
+
This lets another model consume stable rule objects, explicit graph nodes and
|
|
207
|
+
edges, lint violations, normalization suggestions, and conflict groups without
|
|
208
|
+
scraping human-oriented text.
|
|
209
|
+
|
|
210
|
+
## Scope Report
|
|
211
|
+
|
|
212
|
+
`rulecatcher report` is the one-call orientation surface for a live scope.
|
|
213
|
+
|
|
214
|
+
Example:
|
|
215
|
+
|
|
216
|
+
```bash
|
|
217
|
+
rulecatcher report --scope alpha --json
|
|
218
|
+
rulecatcher report --scope alpha
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
The report aggregates:
|
|
222
|
+
|
|
223
|
+
- scope summary counts
|
|
224
|
+
- active adopted stack
|
|
225
|
+
- pending triage pressure
|
|
226
|
+
- health attention on adopted rules
|
|
227
|
+
- conflict groups
|
|
228
|
+
- recent decision history
|
|
229
|
+
- derived next-action items
|
|
230
|
+
|
|
231
|
+
This is the shell surface for asking: "what matters in this scope right now,
|
|
232
|
+
and what should I do next?"
|
|
233
|
+
|
|
234
|
+
## Rule Explain
|
|
235
|
+
|
|
236
|
+
`rulecatcher explain` answers the question "why this rule?" in one call.
|
|
237
|
+
|
|
238
|
+
It can resolve a rule by local id:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
rulecatcher explain 3 --json
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Or by stable signature:
|
|
245
|
+
|
|
246
|
+
```bash
|
|
247
|
+
rulecatcher explain --scope alpha --rule-type next_token --prefix-token state --prefix-token '=>' --expected-token open
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The explanation payload includes:
|
|
251
|
+
|
|
252
|
+
- the canonical rule object
|
|
253
|
+
- rule health and recommendation
|
|
254
|
+
- supporting evidence rows
|
|
255
|
+
- decision history for the same rule signature
|
|
256
|
+
- competing rules with the same prefix
|
|
257
|
+
- observed transition alternatives for that prefix
|
|
258
|
+
|
|
259
|
+
This is the shell surface for asking: "what made this rule appear, how stable
|
|
260
|
+
is it, and what else could have happened here?"
|
|
261
|
+
|
|
262
|
+
## Structural Repair Hints
|
|
263
|
+
|
|
264
|
+
When a generalized `next_kind` rule catches a novel structural syntax break,
|
|
265
|
+
`rulecatcher normalize` now surfaces grounded concrete token hints from the
|
|
266
|
+
rule's observed evidence instead of only the abstract expected class.
|
|
267
|
+
|
|
268
|
+
For example, if a scope learned that identifiers are usually followed by `=>`,
|
|
269
|
+
then input like:
|
|
270
|
+
|
|
271
|
+
```txt
|
|
272
|
+
door closed
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
can yield a suggestion such as:
|
|
276
|
+
|
|
277
|
+
```txt
|
|
278
|
+
consider inserting one of ['=>'] before 'closed'
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
These hints are intentionally advisory. They help another LLM repair syntax
|
|
282
|
+
using observed evidence, but they do not pretend that a class-rule violation is
|
|
283
|
+
always safe to auto-rewrite.
|
|
284
|
+
|
|
285
|
+
## Portability
|
|
286
|
+
|
|
287
|
+
`rulecatcher export-scope` and `rulecatcher import-scope` make a learned
|
|
288
|
+
language stack portable.
|
|
289
|
+
|
|
290
|
+
The snapshot includes:
|
|
291
|
+
|
|
292
|
+
- artifacts bound to the scope
|
|
293
|
+
- observed transitions
|
|
294
|
+
- candidate and adopted rules with evidence
|
|
295
|
+
- rule health counters
|
|
296
|
+
- decision history
|
|
297
|
+
|
|
298
|
+
This gives another LLM a shareable JSON bundle for replaying a scope elsewhere.
|
|
299
|
+
Use `import-scope --replace-scope` when you want the target scope to be rebuilt
|
|
300
|
+
from the snapshot instead of merged into the existing local state.
|
|
301
|
+
|
|
302
|
+
## Evolution Compare
|
|
303
|
+
|
|
304
|
+
`rulecatcher compare` lets another LLM inspect how one language state differs
|
|
305
|
+
from another.
|
|
306
|
+
|
|
307
|
+
It accepts two references:
|
|
308
|
+
|
|
309
|
+
- a local scope name such as `alpha` or `scope:alpha`
|
|
310
|
+
- an exported snapshot path such as `alpha.rulecatcher.json` or `snapshot:alpha.rulecatcher.json`
|
|
311
|
+
|
|
312
|
+
Example:
|
|
313
|
+
|
|
314
|
+
```bash
|
|
315
|
+
rulecatcher compare scope:alpha scope:beta --json
|
|
316
|
+
rulecatcher compare alpha-before.rulecatcher.json scope:alpha
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
The comparison payload is signature-based rather than id-based, so it survives
|
|
320
|
+
export/import and can report:
|
|
321
|
+
|
|
322
|
+
- rules added, removed, or changed
|
|
323
|
+
- observed transition deltas
|
|
324
|
+
- decision-history additions and removals
|
|
325
|
+
- artifact-path changes across corpora
|
|
326
|
+
|
|
327
|
+
This is the shell surface for asking: "what language did I have before, what
|
|
328
|
+
language do I have now, and what actually changed?"
|
|
329
|
+
|
|
330
|
+
## Candidate Triage
|
|
331
|
+
|
|
332
|
+
`rulecatcher triage` closes the gap between "a pattern exists" and "should this
|
|
333
|
+
become part of the language stack?"
|
|
334
|
+
|
|
335
|
+
It only inspects pending rules and turns them into explicit proposals with
|
|
336
|
+
recommendations:
|
|
337
|
+
|
|
338
|
+
- `adopt`: strong candidate with no known conflict
|
|
339
|
+
- `review`: candidate needs a deliberate decision because the evidence is mixed
|
|
340
|
+
or it conflicts with the active stack
|
|
341
|
+
- `reject`: candidate is currently weaker than a competing pending rule for the
|
|
342
|
+
same prefix
|
|
343
|
+
|
|
344
|
+
By default, triage only emits the frontier proposals and then auto-focuses on
|
|
345
|
+
core rules that are not mostly BOS/EOL boundary framing. Use `--focus all` when
|
|
346
|
+
you want the full proposal set, including boundary-heavy rules. `--focus core`
|
|
347
|
+
forces only the core subset.
|
|
348
|
+
|
|
349
|
+
This is the surface another LLM can use to ask: "you seem to be inventing this
|
|
350
|
+
rule; do you want to keep it?"
|
|
351
|
+
|
|
352
|
+
## Batch Application
|
|
353
|
+
|
|
354
|
+
`rulecatcher apply-triage` lets another LLM move from recommendation to action
|
|
355
|
+
without issuing one `adopt` or `reject` call per rule.
|
|
356
|
+
|
|
357
|
+
It selects the same filtered proposal set that `triage` would expose, then
|
|
358
|
+
applies the chosen recommendation family through the normal decision pathway so
|
|
359
|
+
history still records provenance and rationale. Use `--dry-run` to preview the
|
|
360
|
+
exact proposal set before mutating the stack. It respects the same focus policy
|
|
361
|
+
as `triage`, so the default application path also prefers core rules over
|
|
362
|
+
boundary-only boilerplate.
|
|
363
|
+
|
|
364
|
+
## Decision History
|
|
365
|
+
|
|
366
|
+
`rulecatcher history` makes the evolution of the language stack inspectable.
|
|
367
|
+
|
|
368
|
+
Every explicit `adopt` or `reject` decision is now persisted with optional
|
|
369
|
+
`actor`, `source`, and `reason` metadata. When adopting a rule automatically
|
|
370
|
+
displaces an older adopted rule for the same prefix, that displacement is also
|
|
371
|
+
recorded as an automatic history event.
|
|
372
|
+
|
|
373
|
+
This lets another LLM answer questions like:
|
|
374
|
+
|
|
375
|
+
- "why is this rule in the stack?"
|
|
376
|
+
- "what replaced the previous rule?"
|
|
377
|
+
- "was this change deliberate or automatic?"
|
|
378
|
+
|
|
379
|
+
## Rule Health
|
|
380
|
+
|
|
381
|
+
`rulecatcher govern` turns accumulated lint outcomes into a health surface for
|
|
382
|
+
the active rule stack.
|
|
383
|
+
|
|
384
|
+
Recommendation heuristics in this version:
|
|
385
|
+
|
|
386
|
+
- `untested`: the rule has never been evaluated during linting or live sessions
|
|
387
|
+
- `tentative`: the rule has only clean hits so far, but not enough repetitions
|
|
388
|
+
to call it stable
|
|
389
|
+
- `healthy`: the rule has at least three clean hits and no violations
|
|
390
|
+
- `watch`: the rule has started drifting and should be monitored
|
|
391
|
+
- `review`: the rule is breaking often enough that the stack should probably be
|
|
392
|
+
reconsidered
|
|
393
|
+
|
|
394
|
+
This is the governance surface that answers: "the history predicted this next,
|
|
395
|
+
but reality did something else; is that rule still worth keeping?"
|
|
396
|
+
|
|
397
|
+
## Live Sessions
|
|
398
|
+
|
|
399
|
+
`rulecatcher session` is the stream-oriented surface for real-time use.
|
|
400
|
+
|
|
401
|
+
It reads stdin line by line and emits one event per input line plus a final
|
|
402
|
+
summary event. With `--learn`, the full stream is also folded back into the
|
|
403
|
+
scope as a new learnable artifact after the line events are emitted. With
|
|
404
|
+
`--triage`, the stream also emits a pending-rule proposal event so newly caught
|
|
405
|
+
patterns can be surfaced immediately. With `--apply-triage`, a session can also
|
|
406
|
+
batch-apply selected recommendation families directly after triage. Use
|
|
407
|
+
`--triage-focus` when you want to force `core` or `all` proposal visibility in
|
|
408
|
+
live runs.
|
|
409
|
+
|
|
410
|
+
## Notes
|
|
411
|
+
|
|
412
|
+
- The tokenizer is intentionally light and dependency-free.
|
|
413
|
+
- This version optimizes for the governance loop, not perfect language generalization.
|
|
414
|
+
- Graph and hypergraph projections can be layered on later from the SQLite store.
|
|
415
|
+
|
|
416
|
+
## Metasystem-Transition Graph
|
|
417
|
+
|
|
418
|
+
`rulecatcher graph` now builds an explicit graph object first, then renders it
|
|
419
|
+
for the shell.
|
|
420
|
+
|
|
421
|
+
Example:
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
rulecatcher graph --format mermaid
|
|
425
|
+
rulecatcher graph --scope syntax --layer rules --rule-type next_kind --format table
|
|
426
|
+
rulecatcher graph --scope alpha --layer metasystem --format dot
|
|
427
|
+
rulecatcher graph --scope alpha --layer metasystem --json
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Available layers:
|
|
431
|
+
|
|
432
|
+
- `observed`: raw prefix-to-next-token transitions
|
|
433
|
+
- `rules`: explicit stacked rule geometry
|
|
434
|
+
- `metasystem`: observed transitions plus rules, decision history, and rule health
|
|
435
|
+
|
|
436
|
+
The `--json` surface now includes `graph.nodes`, `graph.edges`, and `summary`,
|
|
437
|
+
so another LLM can traverse the learned syntax geometry directly instead of
|
|
438
|
+
reconstructing it from flat rows. `--format dot` gives a shell-friendly export
|
|
439
|
+
path for Graphviz or other downstream tooling.
|