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.
Files changed (29) hide show
  1. rulecatcher-0.1.0/PKG-INFO +439 -0
  2. rulecatcher-0.1.0/README.md +432 -0
  3. rulecatcher-0.1.0/pyproject.toml +17 -0
  4. rulecatcher-0.1.0/setup.cfg +4 -0
  5. rulecatcher-0.1.0/src/rulecatcher/__init__.py +5 -0
  6. rulecatcher-0.1.0/src/rulecatcher/__main__.py +7 -0
  7. rulecatcher-0.1.0/src/rulecatcher/cli.py +950 -0
  8. rulecatcher-0.1.0/src/rulecatcher/compare.py +454 -0
  9. rulecatcher-0.1.0/src/rulecatcher/db.py +681 -0
  10. rulecatcher-0.1.0/src/rulecatcher/detect.py +174 -0
  11. rulecatcher-0.1.0/src/rulecatcher/engine.py +115 -0
  12. rulecatcher-0.1.0/src/rulecatcher/explain.py +232 -0
  13. rulecatcher-0.1.0/src/rulecatcher/governance.py +94 -0
  14. rulecatcher-0.1.0/src/rulecatcher/graphing.py +732 -0
  15. rulecatcher-0.1.0/src/rulecatcher/history.py +47 -0
  16. rulecatcher-0.1.0/src/rulecatcher/linting.py +221 -0
  17. rulecatcher-0.1.0/src/rulecatcher/models.py +139 -0
  18. rulecatcher-0.1.0/src/rulecatcher/present.py +185 -0
  19. rulecatcher-0.1.0/src/rulecatcher/report.py +260 -0
  20. rulecatcher-0.1.0/src/rulecatcher/session.py +122 -0
  21. rulecatcher-0.1.0/src/rulecatcher/snapshot.py +218 -0
  22. rulecatcher-0.1.0/src/rulecatcher/tokenize.py +112 -0
  23. rulecatcher-0.1.0/src/rulecatcher/triage.py +289 -0
  24. rulecatcher-0.1.0/src/rulecatcher.egg-info/PKG-INFO +439 -0
  25. rulecatcher-0.1.0/src/rulecatcher.egg-info/SOURCES.txt +27 -0
  26. rulecatcher-0.1.0/src/rulecatcher.egg-info/dependency_links.txt +1 -0
  27. rulecatcher-0.1.0/src/rulecatcher.egg-info/entry_points.txt +2 -0
  28. rulecatcher-0.1.0/src/rulecatcher.egg-info/top_level.txt +1 -0
  29. 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.