ROFL as a linter over its own rule files, and 21 rule packs cut to their decisions - #5
Open
Disentinel wants to merge 18 commits into
Open
ROFL as a linter over its own rule files, and 21 rule packs cut to their decisions#5Disentinel wants to merge 18 commits into
Disentinel wants to merge 18 commits into
Conversation
scanners/rofl_lint.ts turns every rule file into facts about its clauses and comment blocks; rules/rofl-lint.rofl holds the criteria as rule bodies (orphan blocks, dangling names, twins, aliases, implied premises, unread relations); npm run rofllint renders them. test/rofl-lint.test.ts pins the rows found in js-callgraph and js-effects and measures the instrument with a mutant set. Nothing here is a gate: every relation is a candidate list, non-empty on an honest checkout by design. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
catches_via(try_statement, handler) in rules/js-controlflow.rofl is the fact about the language as a row; caught_here reads it through try_catches, so may_throw, thrown_by and the effect layer stand on one guard instead of the effect layer carrying its own. leaky/useLeaky in alpha.mjs is the corpus site the defect never had; the tripwire the finding asked for fired on it before the repair went in. The witness moves from an absence to a floor. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
…by the try_catches repair Golden set 85/85 worlds; the DANGLING lines are nextver's own and predate this branch. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
No rule text moves — every mutant anchor and every golden holds. What stays beside a rule is the reason it is not the obvious rule; what went was history, measurements, the ghost of section 4 whose rules moved to js-dataflow on 2026-09-04, and a section header that had been renumbered by hand. js-effects 791 -> 222 comment lines, js-callgraph 570 -> 135. The limitations list is kept whole and renumbered. rofl-lint's comment-side controls flip from present to absent with the repair. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
Twins since the 2026-09-08 repair moved top_call from call_site to site; frontier_at's transfer arm now reads top_call and top_site is gone. Goldens 85/85; the callgraph world moves by exactly one rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
…on twins Three items rofl-lint priced: the value layer written twice (fourteen may_be_node/may_be_lit pairs), four relations nothing reads, eighteen implied premises. Declared as the refactoring_queue world in facts/checks.rofl and as a pack of w_queue. The decision on the other thirty-three pairs — a name beats a mode column until the boilerplate is tenfold; templates as sugar deferred past ten real templates — is in the ledger. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
…irst w_concat_value -> w_url_pack -> w_fetch_semantics / w_express_semantics -> w_service_graph, ordered by work_needs; the queue hands out the value abstraction first because four items stand on it. The principle is in the ledger: one abstract value per question, entry points per syntax, library meaning as an authored table with provenance, and what libraries disagree on as a column a reader can refuse by name. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
No rule text moves. 1249 comment lines to 235; sixteen numbered sections, each note the reason a rule is not the obvious rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
No rule text moves. 933 comment lines to 179; eight numbered sections, the mechanism table and the three-state gate kept with their reasons. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
No rule text moves. js-modules 463 comment lines to 119 (sections renumbered: 7 was used twice), js-model 397 to 82. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
…sions No rule text moves. Comment lines: js-ambient 384 to 134, js-host 300 to 109, js-env 232 to 77, js-globals 211 to 73. The lint reports no orphan block, dangling name or renumbered section in any of the four. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
…bulary: cut the comments to the decisions No rule text moves. Comment lines: js-resolve 152 to 70, js-attrs 140 to 55, js-pack-home 136 to 41, js-structure 96 to 27, js-env-api 60 to 23, js-vocabulary 60 to 22. The lint reports no orphan block, dangling name or renumbered section in any of the six. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
…e dogfood note 6174 comment lines to 1605 with no rule text moved; the settled count is 674. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
No rule text moves. Comment lines: nullary 204 to 87, worklist 186 to 75. The lint reports no orphan block, dangling name or renumbered section in either; the clause-side rows it still reports (needs_reach = waits_on, held_by :- held, unread held_by) are left for the refactoring queue. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
No rule text moves. Comment lines: ingest 123 to 54, rule-shape 112 to 62, depends 106 to 55. The one dangling name left, needed_hot in ingest, is the file's own: a relation it reads that nothing declares, queued as w_ingest_declares_half_its_host_relations. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
nextver removed test/ and docs/dogfood/; the branch's three test edits, its new mutant file for the lint and its dogfood note go with them. The three settlements that cited those paths now cite the rule and the queue. Goldens re-blessed: the lint and refactoring worlds are new, and the callgraph, controlflow, effects, worklist, worlds and findings worlds carry this branch's rows over nextver's base. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
The question was whether two model-written rule files (
rules/js-effects.rofl,rules/js-callgraph.rofl) could be shorter, and whether the answer would be visible structurally if ROFL itself were the linter. It was, so the instrument was built and then run over the tree.The instrument
scanners/rofl_lint.tsturns every rule and fact pack into facts about its clauses (what it concludes, what it reads, an alpha-normalised body, which premises are implied through every arm of another premise) and its comment blocks (what follows each, banners, dates, backticked names).rules/rofl-lint.roflholds the criteria as rule bodies:orphan_block,dangling_mention/dangling_bare,section_twice/title_twice/list_repeats,twin,paired_arm,shape_twin,alias,implied,unread/unasserted_audit. Every one is a candidate list, none an[audit]: they are non-empty on an honest tree by design.npm run rofllintrenders the report;facts/rofl-lint.roflis the committed census andrules_rofl-lintis a golden world, so a repair shows up as a count moving on bless.What it found and what was repaired
fn_bindingcited and defined nowhere; section 6 twice and a list restarting in js-effects. All repaired.top_call=top_site: one rule, one name now.caught_heresaid atrywith only afinallycatches; repaired at the source withcatches_via(try_statement, handler)andtry_catches, andeff_catch_herecollapsed onto it. The old finding'switness_absentbecamewitness_in_atleast.The comment cut
21 rule packs, every
rules/js-*.roflplus nullary, worklist, ingest, rule-shape and depends, cut to a header and one note per decision anchored to its clause. No rule text moved by a character: every golden held on every step and only the lint world moved on each bless. rules/js-* went from 6174 comment lines to 1605 against 3287 lines of rules. The instrument caught its own author six times on the way (do_while,may_be_*,resolve_*,replaced_by,rule_shape,peak_rows), which is the argument for running it on every file.The ledger
facts/refactoring.roflis a new queue volume (w_queue,refactoring_queueworld) holding what the lint still reports on the clause side and was deliberately left for a decision: themay_be_node/may_be_littemplate, the unread relations, the implied premises, the twins in worklist (needs_reach=waits_on), depends (code_needs=generated) and ingest, and ingest's undeclared host relations.parts/joinedabstraction, library meaning as an authored table) is recorded as five dependent items infacts/worklist.rofland one design-principle finding.Merge with nextver
nextver removed
test/anddocs/dogfood/. The branch's edits to three test files, its mutant file for the lint (test/rofl-lint.test.ts, eight mutants) and its dogfood note went with them; the instrument's liveness now rests on the golden census alone, which is the same disposition the other 191 files got. Three settlements that cited those paths now cite the rule and the queue.npm test: 87/87 worlds on both engines. The twoDANGLINGgrave lines (test/version-plan.test.ts,test/publishes.test.ts) are nextver's ownremoved_inrows pointing at shas outside this shallow clone.Next, per the owner: put
npm run rofllintinto CI.🤖 Generated with Claude Code
https://claude.ai/code/session_011pE9mh2aKYpNhpEzgsJ6ps
Generated by Claude Code