Skip to content

docs: add root-cause and change-discipline rules - #1219

Open
ragnorc wants to merge 3 commits into
ModernRelay:mainfrom
ragnorc:cursor/root-cause-change-discipline
Open

ragnorc wants to merge 3 commits into
ModernRelay:mainfrom
ragnorc:cursor/root-cause-change-discipline

Conversation

@ragnorc

@ragnorc ragnorc commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Reviewers were carrying a long prompt of principles that the repository already states: the five-more-changes test, one source of truth, correctness before simplicity before performance, checking a Lance claim against the upstream code, the observable-contract framing, and reproducing a predicted failure before fixing it. What the repository did not state is the root-cause and design-hygiene bar. Review after review flagged the same defects: a patch that treats the symptom, a special case at the wrong layer, a new mechanism beside an abstraction that already gave the guarantee, duplicated state that can drift, reliance on another component's undocumented internals, a "regression" that never failed for the predicted reason (a compile error, a setup failure, a skipped test, or a run that executed nothing), and a write-up that treats a local run, CI, and a reading of the code as the same evidence. Open pull requests, documented direction, and future Lance versions were also being treated as if they had already shipped. These are rules for the person or agent writing the change, so they belong in the repository. Authors can catch them before review, and a reviewer can point at one section instead of re-arguing the point.

The review workflow stays out. Author eligibility, one review per run, posting and dedupe, the plain-English style of review text, and notifying Ragnor are his tooling, not rules for someone changing the code.

The rules are one new section, Root cause and change discipline, in docs/dev/invariants.md. That page already owns standing design rules for anyone proposing, implementing, or reviewing a change. docs/dev/systems.md stays the evaluation essay; it is not an authoring manual. Where a rule was already present, the section links it instead of copying it: hard invariants 1 and 12 for substrate machinery and a shadow copy that can drift, the governing principle for the liability test behind "fewer lines is not proof," hard invariant 13 for a cost claim's instrument, Lance compatibility in the testing guide for keeping storage gates separate, and the query-behavior tiers so a shallow .gqt case is not a substitute for saying why GQT cannot express the contract. The review checklist at the end of the same page asks those questions in the checklist's existing shape. AGENTS.md stays a map: Change discipline has one pointer line to the section, next to the existing "fix the root cause" bullet. docs/dev/index.md names change discipline on the invariants row so the developer guide's map matches the page. There is no changelog note. The documentation guide asks for one only on a user-visible change, and a docs title does not require one.

python3 scripts/check-docs.py printed Documentation OK (441 Markdown files checked) and exited 0. bash scripts/check-agents-md.sh printed AGENTS.md ↔ docs indexes OK (66 links, 62 docs); engine reads no setting variable, and exited 0. python3 scripts/check-pr-title.py --title "docs: add root-cause and change-discipline rules" printed PASS PR title accepted (48/100 characters) and exited 0. typos 1.50.1, the version ci.yml pins, on AGENTS.md, docs/dev/invariants.md, and docs/dev/index.md exited 0 with no findings.

For review: the decision to challenge is the home. The evidence sentences could have gone into the testing guide; they sit in the invariants guide so one section is the rule a review cites, and they link the testing page instead of copying the tier ladder or hard invariants 1, 12, and 13. The checklist questions restate the section the way the existing checklist restates the hard invariants. What would make that wrong is a second copy of the tier ladder, or treating open pull requests and future Lance versions as requirements the section had meant only to name as context.

cursoragent and others added 2 commits October 31, 2026 16:39
Record where a fix has to land, and what counts as a regression or as
evidence, in the invariants guide. AGENTS.md keeps a single pointer.

Co-authored-by: Ragnor Comerford <ragnorc@users.noreply.github.com>
@cursor

cursor Bot commented Nov 1, 2026

Copy link
Copy Markdown

Why

Reviews kept restating where a fix must land, and what counts as a regression or as evidence. The repository already states the five-change test, one source of truth, and the query-test tiers. It did not state those two rules.

What

This pull request adds the section "Root cause and change discipline" to docs/dev/invariants.md. It adds five checklist questions in the existing checklist shape. AGENTS.md has one pointer line. docs/dev/index.md names change discipline on the invariants row.

How

The section cites hard invariants 1, 12, and 13. It cites the governing principle. It cites the plan-replay tiers and the Lance compatibility gates. It does not copy those texts.

Impact

An author can check one section before review. A reviewer can cite that section. One paragraph conflicts with the composition rule in the systems guide, and with the publication and policy contracts. Change that paragraph before merge. The other rules reduce long-term liability. They add one citation target, and they do not add a second copy of an existing rule.

Recommendation: revise.

Blocking

  1. docs/dev/invariants.md:219-226. The paragraph says each primitive owns one guarantee, so a combination inherits correctness, efficiency, and security and does not re-prove them.

A reader can take that sentence in a narrow way. Do not re-prove a primitive's own guarantee at every call site. The words say more than that. They say the combination inherits correctness, efficiency, and security. A primitive that owns one guarantee does not give the combination those three properties.

That conflicts with docs/dev/systems.md:250-251 (section 6.1, "Composition carries obligations"). The composed contract is established at the boundary. It is not the union of the component guarantees.

The same claim conflicts with the graph contract in code. Hard invariant 2 says a per-table commit is not graph publication. overwrite_probed in crates/omnigraph-catalog/src/commit.rs commits __manifest as one Operation::Overwrite. Policy is checked again at Omnigraph::enforce in crates/omnigraph/src/db/omnigraph.rs. A caller does not inherit that check from a lower primitive. Hard invariant 13 still requires a cost instrument for the boundary that changed. Hard invariant 7 says missing index coverage can change cost and must not change correctness. Efficiency is not an inherited property.

The ratio in the same paragraph is not a check a reviewer can perform. It puts correctness, efficiency, and security in one numerator. AGENTS.md ranks correctness first, then simplicity, then performance.

Keep the preference for a small set of primitives, each of which owns one guarantee. State that a combination still has to discharge the composed contract. Remove the ratio. The checklist question at lines 268-269 can remain. It does not say the combination skips the proof.

Optional

  1. docs/dev/invariants.md:206-208. Hard invariant 1 requires the matching Lance pages before parallel machinery, and before reliance on an undocumented behavior. Parallel machinery includes a second execution engine beside DataFusion. The words "new substrate machinery" are narrower than the invariant. The link target is correct. Use the invariant's words so the gloss cannot drift.

  2. docs/dev/invariants.md:231-233. "A .gqt case that does not state the contract" is not a check the testing guide defines. The plan-replay section says a .gqt case owns rows, counts, result column types, or errors. A Rust test needs a reason the format cannot express. Write that a .gqt case which misses that observable result is not the reason.

  3. docs/dev/invariants.md:264-269. The first new checklist item asks for every caller and every workload. The section text says nearby callers. A reviewer cannot show that the set was complete. The primitives question joins the pass case and the fail case with "or". A yes answer is then not a pass. Write each item so a yes answer means the change meets the rule.

Tradeoffs and liability

The section belongs in the invariants guide. That page already holds the standing rules for a person who proposes, implements, or reviews a change. The systems guide remains the evaluation essay. It is not an authoring manual.

The regression rule and the evidence rule are new. They sit with the design rule so a review cites one section. They link the testing guide. They do not copy the tier ladder or hard invariants 1, 12, and 13. A copy would drift. Moving only the evidence sentences into the testing guide would split one citation across two pages. The single section has lower long-term liability.

AGENTS.md still says to reproduce the predicted failure, and it points here for what counts. That keeps one source of truth. CLAUDE.md is a symlink to AGENTS.md.

No changelog fragment is correct. The documentation guide requires a note for a user-visible change. These are contributor rules. The title type is docs, so the release-note gate does not require a note.

I read the open pull requests as context only. They are not requirements for this change. Group commit (pull request 785) and the open permission RFCs still argue a composed publication and an explicit grant at the boundary. That matches the blocking finding. It does not add a requirement.

This pull request changes no behavior. A GQT case or a Rust regression test does not apply.

Validation

Reviewed commit a2e30ad2b50bbfa78d5d8fb381830bb10ab896ee, in an isolated checkout. No review and no inline comment existed on this head before this review.

Local results:

  • bash scripts/check-agents-md.sh exited 0. Output: AGENTS.md ↔ docs indexes OK (66 links, 62 docs); engine reads no setting variable.
  • python3 scripts/check-docs.py with markdown-it-py==4.0.0 exited 0. Output: Documentation OK (441 Markdown files checked). That script checks heading anchors. The new anchors resolve. They are #root-cause-and-change-discipline, #hard-invariants, #governing-principle, #current-support-boundaries, testing.md#plan-replay, and testing.md#lance-compatibility.
  • python3 scripts/check-pr-title.py --title "docs: add root-cause and change-discipline rules" exited 0.

Exact-commit CI, run 41253471096, head a2e30ad2b50bbfa78d5d8fb381830bb10ab896ee:

  • Job "Check AGENTS.md Links" succeeded. Its steps include the cross-link check, documentation structure, release-note composition, and spelling.
  • PR Title succeeded on run 41253469619.
  • CI Gate succeeded.
  • Test Workspace, rustfmt, and clippy were skipped by the docs path filter.

Code and document inspection, separate from those commands: hard invariants 1, 12, and 13 match the citations. Plan replay states the two query tiers. Lance compatibility keeps workspace, GQT, Clippy, and object-store results as separate evidence. origin/main does not change AGENTS.md, docs/dev/invariants.md, or docs/dev/index.md after the pull request base 4e7bb585d145635a2487ffe1fd03c0bfdd0e8f14.

Limitations

I did not download upstream Lance pages. The diff states no new substrate behavior. I read docs/dev/lance.md in full. I did not run the GQT corpus or the Rust tests. The GQT jobs on this head finished in 3 to 9 seconds. That is the path filter, not a corpus run. typos is not installed in this environment. The spelling step on this commit succeeded. Devin Review reported success with the text "Full review skipped: trial expired and no credits remaining." That is not a review of the diff.

ragnorc commented Nov 1, 2026

Copy link
Copy Markdown
Contributor Author

Why

The review on a2e30ad2 asked for one change before merge. The primitives paragraph said a combination inherits correctness, efficiency, and security, and it gave a ratio no reviewer can compute. Commit d002cbc7 replaces that paragraph.

What

The new paragraph prefers orthogonal primitives. It uses Eric Raymond's definition from The Art of Unix Programming. It says a composed operation still has to establish its own contract. It cites section 6.1 of the systems guide. The guarantee-per-code aim is now a direction, not a number. The same commit applies the three optional notes from that review.

Earlier findings

Blocking finding: fixed.

The paragraph no longer says a combination inherits correctness, efficiency, and security. It no longer says the combination can skip the proof. It says composition does not discharge obligations. Orthogonality makes that argument shorter. It does not make the argument optional.

That matches section 6.1 of docs/dev/systems.md (lines 250-264). The composed contract is established at the boundary. It is not the union of the component guarantees.

The Raymond sentence matches the page it links. In a purely orthogonal design, each operation changes one property. It has no side effect on other properties. There is one way to change each property. The page has the anchor orthogonality.

The ratio is no longer a check. The text calls the aim a direction for judgment. It says the checklist is how a review applies that aim. The checklist does not trade correctness for less code. A new burden is still justified against the governing principle (lines 216-217).

Optional 1: taken. Line 207 says "parallel machinery". Those are the words of hard invariant 1.

Optional 2: taken. Lines 252-254 use the testing guide's list: rows, counts, result column types, or errors. They tell the author to say why GQT cannot express the contract.

Optional 3: taken in the form that note asked for. Line 286 asks for the callers and workloads that share the cause. A yes answer is that list. It does not ask for proof that the list is complete. The old question that joined two cases with "or" is gone. The scope of the replacement question is a new optional note below.

Impact

The conflict with section 6.1 is gone. A reviewer can cite this section. Two optional notes are new. They do not restore the inheritance claim. This commit adds no behavior and no second copy of an existing rule.

Recommendation: ready.

Blocking

None.

Optional

  1. docs/dev/invariants.md lines 229-232. The sentence says section 6.1 requires one publication, engine policy, and a measured cost on a composed operation.

Section 6.1 requires the composition to discharge its assumptions, align representations, preserve publication and failure semantics, and establish progress for the whole path. It does not require a measured cost. It does not put engine policy on every composition.

Hard invariant 2 is the one door for a graph-content publication. A query does not publish. overwrite_probed in crates/omnigraph-catalog/src/commit.rs (lines 169-174) commits __manifest as one Operation::Overwrite. That is a graph change.

Hard invariant 10 is the trust boundary. Omnigraph::enforce in crates/omnigraph/src/db/omnigraph.rs (lines 1118-1145) returns success when no policy is installed. Mutation, load, merge, and schema apply call that gate. A lower primitive does not supply it.

Hard invariant 13 requires a test at the layer whose contract changed. A cost claim needs a checked-in instrument. Lines 256-259 already say that. A composed operation with no cost claim does not need a measured cost.

Keep the sentence that says composition does not discharge obligations. Name each example in the scope its own invariant gives.

  1. docs/dev/invariants.md lines 289-292, and the rule at lines 225-228 and 239. The checklist yes-path does not ask whether the composed contract was established. The paragraph still allows a new mechanism when the restriction cannot be removed, and it tells the author to name the cost. The checklist has no yes for that case. "Measured" does not say what counts as a measurement. A cost claim already needs the instrument in hard invariant 13.

Tradeoffs and liability

This commit does not move the section. The invariants page remains the authoring rule. The systems guide remains the evaluation essay. Orthogonality has one owner, this section, with a link for Raymond's definition. Composition obligations stay owned by section 6.1. The new text links that section. It does not copy the four-role table. A copy would drift.

The formal-core paragraph matches hard invariants 7 and 9. A fast path may change cost. It must keep the same observable contract, and a test must compare it with the general path. The paragraph does not ban a heuristic.

No new code type or module is warranted. The new concept is a rule a review can cite. This section is the owner. The link to section 6.1 is the source of truth for composition. The optional note above is the place that gloss can drift.

The removed liability is the inheritance sentence. A reviewer can no longer cite this section to skip the composed contract. The added liability is two sentences that name a wider scope than the invariants they cite. Five more paragraphs of the same kind would turn this page into a second systems essay. This commit does not do that. It stays in one section and links the existing owners.

Open pull requests are context only, as lines 262-264 say. Pull request 785 (group commit) and the open permission RFCs still argue one publication and an explicit grant at the boundary. That agrees with the fixed paragraph. It adds no requirement for this change.

The diff of this commit is docs/dev/invariants.md only. AGENTS.md and docs/dev/index.md are unchanged here. Their pointers from the earlier commits still match the section title.

origin/main is now f728f01e1543c442eff77f8b0d10c223e38da36d. The merge base of this head with that main is 4e7bb585d145635a2487ffe1fd03c0bfdd0e8f14. Main adds a local-builds guide in other regions of AGENTS.md, docs/dev/index.md, and docs/dev/testing.md. git merge-tree --write-tree origin/main d002cbc79b81f0b51413da8f82ee569f1e79281f exits 0.

Validation

Reviewed commit d002cbc79b81f0b51413da8f82ee569f1e79281f. Parent a2e30ad2b50bbfa78d5d8fb381830bb10ab896ee. gh api repos/ModernRelay/omnigraph/commits/d002cbc7 returns that full SHA. No pull request review and no inline comment on this head existed before this review. The earlier review is #1219 (comment).

Local results, isolated checkout of that commit:

  • bash scripts/check-agents-md.sh exited 0. Output: AGENTS.md ↔ docs indexes OK (66 links, 62 docs); engine reads no setting variable.
  • python3 scripts/check-docs.py with markdown-it-py==4.0.0 exited 0. Output: Documentation OK (441 Markdown files checked). The script checks heading anchors. The new target systems.md#61-composition-carries-obligations is valid.
  • python3 scripts/check-pr-title.py --title "docs: add root-cause and change-discipline rules" exited 0. Output: PASS PR title accepted (48/100 characters).
  • typos 1.50.1, the version pinned in ci.yml, on AGENTS.md, docs/dev/invariants.md, and docs/dev/index.md, exited 0.

Exact-commit CI, head d002cbc79b81f0b51413da8f82ee569f1e79281f:

  • Run 41259805638, job "Check AGENTS.md Links", succeeded. The steps include the cross-link check, documentation structure, and spelling.
  • Run 41259803398, job "PR Title", succeeded.
  • Test Workspace, rustfmt, and clippy were skipped by the docs path filter.
  • Run 41259805568, the GQT jobs, succeeded in about eight seconds. That is the path filter.

Code and document inspection, separate from those commands: section 6.1, hard invariants 1, 2, 7, 9, 10, and 13, the plan-replay tiers, Omnigraph::enforce, and overwrite_probed. I fetched the Raymond page and checked the anchor and the definition paragraph.

No regression command applies. git diff --stat a2e30ad2b50bbfa78d5d8fb381830bb10ab896ee d002cbc79b81f0b51413da8f82ee569f1e79281f shows docs/dev/invariants.md only. The commit does not change rows, counts, result column types, or errors.

Limitations

I did not fetch the Lance format pages. This commit states no substrate behavior. I read docs/dev/lance.md. I did not run the Rust tests or the GQT corpus. A skipped GQT job is not evidence about query behavior. Storage Upgrade Compatibility on run 41259805638 was still in progress at review time. It does not cover this diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants