Development record
The consistency pass runs where records are written and names each finding the same way every time
Typed links: builds_on itd-48 (the consistency pass these five follow-ups extend, and the intent they were routed to) and itd-34 (the kinds lint the scheduling piece sits beside); related_issues iss-2609260926323349 (the tracking record of the five, which this draft carries once planned); related_intents itd-62 (the managed pre-commit gates of ruling J23, beside which A2's hook sits); related_adrs adr-2609300821558671 (the filing-time match G1's key is distinct from).
Press Release
The consistency pass runs where records are written and names each finding the same way every time. The pass that finds two records contradicting each other,
abcd intent consistency, gains five things together: cross-document lint codes for the contradictions a rule can see without a model, so record-lint names them on every change; a pre-commit hook that runs the rule checks on every commit and the model pass on the records a commit touches wherever the owner has a model route, and that warns, stops, or fixes the obvious and files the rest, as the repository chose at setup; the pass run beside the kinds lint, so a shape finding and a contradiction are reported together; a corpus too large for one review measured, reported and read in chunks instead of skipped; and a stable key for each finding, so a contradiction found on Monday is the same finding on Friday and a person answers it once."I used to rediscover the same contradiction every time I ran the pass and could never tell whether it was new," said Iris, a product thinker. "Now the obvious ones fail the commit that introduces them, the subtle ones come back under the same id, and the big record is read in pieces instead of being passed over."
Why This Matters
itd-48 shipped the consistency pass (Role 2 of the intent auditor) and none of the five follow-ups routed to it from the predecessor store's spc-33 (A1, A2, A3, A4, G1; itd-48, Routed Deferrals); since then iss-2609260926323349 has been their only home. Without them the pass is a report a person remembers to run: a contradiction a rule could catch waits for the next model run, and nothing runs it when a record changes. A finding is already linked rather than filed twice when its open record is found (itd-48's second criterion, and the filing-time duplicate check every route shares), but a report row carries only its number, so nothing says a row is the same contradiction as last week's, and a contradiction whose record was resolved comes back as new. The product thinker ruled on 2026-09-29 (ruling BT2) that the five are planned together as one intent rather than one at a time or closed.
Mechanism
We expect the pass to catch contradictions earlier and to be answered once because the cheap cases move into a gate that runs on every change and the expensive cases keep one identity across runs; shown wrong if, after it ships, the same contradiction is still filed twice across two runs, or a contradiction a lint code covers still reaches the default branch.
What's In Scope
- A1, cross-document lint codes: the mechanical half of Role 2 as
record-lint codes that need no model, for the contradictions
record_schemadoes not already refuse: abuilds_onorrouted_fromedge with no reciprocal mention, and arelated_issuesentry the issue does not link back. A cross-reference naming no record and one-way supersession are alreadyrecord_schemafindings and stay there. The new codes are warnings, so a record that passes record-lint today keeps passing. - A2, a pre-commit hook for the pass. The A1 codes run on the whole
corpus on every commit, with no model. The model pass runs on the staged
records plus the records they link to or that link to them, where the
owner's personal settings provide a model route; where none does, the
commit proceeds and the status carries "deep check owed" naming the
records. The hook never refuses a commit on a judgement it could not
obtain. On a finding it does what the repository chose at setup (the
ahoysetup interview asks): warn (print the finding by its key and proceed), stop (refuse the commit naming the finding), or automatic (fix a mechanical contradiction, such as a missing back-link, in the same commit with a note of the change, and file a judgement contradiction as an issue carrying its key, then proceed). The hook is a gate in the core-owned managed pre-commit gates (iss-84 with itd-62, ruling J23), and its build waits for them. - A3, one run beside the kinds lint (itd-34): the hook's single invocation runs record-lint's kind rules, the A1 codes and, where it runs, the model pass, and reports them together, with no model call when no route is configured.
- A4, chunked review of a corpus too large for one request. The pass measures the assembled corpus against the request limit and reports an overflow with its size; on an overflow it reviews the corpus in chunks, one after another, and the report covers every chunk.
- G1, a stable key for each finding: a deterministic key on every report
row, derived from the class, both end paths and the collapsed quotes,
written into the record a finding files, so the same contradiction carries
the same key on every run; distinct from the filing-time duplicate check,
which matches prose. A finding whose record is already resolved or won't
fix is marked
addressedon the report, naming the record, and files nothing. G1 lands first: the hook and the chunked review name findings by it.
What's Out of Scope
- Role 1 (the per-intent fidelity audit) and Role 3 beyond its scheduling.
- Any change to the judgement itself: the classes and the rubric stay itd-48's.
Scope Conditions
- Holds for a repository whose record carries a brief and intents the pass can read; a repository with neither has nothing to compare.
- The hook's model pass holds only where the owner's personal settings provide a model route; elsewhere the pass is marked owed, never assumed run.
Acceptance Criteria
- Given two records whose frontmatter states contradict in a way a rule
can see (a one-way
builds_onor arelated_issuesentry with no back-link), when record-lint runs, then a cross-document code names the rule and both files, with no model run. - Given a repository that chose stop, when a commit introduces a contradiction, then the commit is refused naming the finding by its key; given warn, then the finding is printed by its key and the commit proceeds.
- Given a repository that chose automatic, when a commit introduces a missing back-link and a judgement contradiction, then the back-link is added in the same commit with a note naming the change, an issue carrying the second finding's key is filed, and the commit proceeds.
- Given the
ahoysetup interview, when it runs in a repository, then it asks which of warn, stop or automatic the hook uses, and records the answer. - Given no model route in the owner's personal settings, when the hook runs, then the A1 codes run, no model is called, the commit is not refused for the model pass, and the status names the records whose deep check is owed.
- Given a route is configured and a commit stages one record, when the hook runs, then the model pass reviews that record and the records linked to or from it, and the A1 codes cover the whole corpus.
- Given a commit the kind rules and the pass both judge, when the hook runs, then both report in one run.
- Given a corpus larger than one request, when the pass runs, then the report states the overflow and its size, the corpus is reviewed in chunks, and the report covers every chunk; given a corpus that fits, then no overflow is reported and nothing is chunked.
- Given the same contradiction found on two runs, when the second report is ingested, then the row carries the same key as the first and the key is written in the filed record.
- Given a finding whose record is resolved or won't fix, when it is
found again, then the report marks it
addressednaming the record and files nothing.
Decisions
Ruled at this draft's planning interview, 2026-10-02 (the product thinker and technical facilitator, one question at a time):
- A3 stays in this intent (iss-2609260926323349's body routed it to itd-34, which is shipped; its deferral and ruling BT2 route it here).
- A4 stays, and builds its own trigger: the pass measures the corpus and reports an overflow before it chunks.
- The hook runs the rule checks always and the model pass only where a route exists, marking it owed otherwise; it never refuses a commit on a judgement it could not obtain.
- What the hook does on a finding is asked at setup: warn, stop, or automatic (fix the obvious, file the rest).
- Scope: the rule checks cover the whole corpus; the model pass covers the staged records and their links.
- The hook waits for the core-owned managed pre-commit gates (iss-84 with itd-62, ruling J23); A1, A4 and G1 do not.
- G1 lands first.
- Impact is additive: the A1 codes start as warnings.
SOTA
Surveyed on 2026-10-23; sources, evidence tiers and the local fit risks are in the verification-assurance SOTA note. The decisions above stand; the research checks G1's key and A2's hook against outside practice.
- Fingerprint keys are versioned names, so an algorithm change does not orphan old findings. SARIF 2.1.0's
partialFingerprintskeys carry a version component; consumers "SHOULD use the latest version of the partial fingerprint available in both results", and property names should "describe the information used to compute the partial fingerprint" and never be removed (SARIF 2.1.0 specification). - A path change is a new finding on the forge. Code scanning closes the old alert and opens a new one when "the filepath differs for the same result" (forge documentation, SARIF support for code scanning). G1's key, as shipped, already satisfies this:
findingkey.Derivemaps each end to an identity path that drops the status folder for intents, specs and the issue ledger, so a record moved fromopen/toresolved/keeps its key and theaddressedrule can find it (internal/core/record/findingkey/findingkey.go). - A pre-commit hook judges the staged content. The common framework "only runs on the staged contents of files by temporarily stashing the unstaged changes while running hooks", because unstaged content "can lead to both false-positives and false-negatives during committing"; hooks that do not operate on files are
always_run(pre-commit documentation). A2's "staged records plus their links" for the model pass and "whole corpus" for the A1 codes match the two shapes. - The
addressedmarking has an outside name: SARIF'sbaselineStateabsent(found in the baseline, not now) andunchanged, should the report ever want the standard's vocabulary. - Locally,
findingkey.Derivealready collapses whitespace, drops the status folder from each end's path and keys on class, both identity paths and quotes, under a versioned derivation domain (abcd/finding-key/v1, key prefixcfk-, bumped only when the derivation changes); the model-matrix note records that two models agree on a key only when they quote the same text.
Path 2, confirmed as shipped: findingkey.Derive already drops the status folder (SARIF's stable-path rule) and versions its derivation domain (abcd/finding-key/v1, as SARIF versions its fingerprint names). SARIF export is not worth adopting: one consumer, no ingestion target. No dependency. The independent fit-challenge is still owed before the build, and the questions below are kept for it.
Questions this pass raised for the fit-challenge before the build. They are kept here, not under Open Questions, so they do not hold a build the record already rules ready:
- The residual risk the code itself states: a contradiction quoted differently gets a new key, so an edited sentence reads as a new finding and the old one as
addressed. Is that acceptable for the hook's report, or should the report pair a new key with the key it most resembles?
Open Questions
None open.
Audit Notes
Empty. Populated by intent-auditor when intent moves to shipped/.
Grounds
- pursued: contradictions get into the records unnoticed and are answered twice, and unattended runs write records with no one checking them for contradictions; wrong if, after it ships, the same contradiction is still filed twice, a rule-catchable one still gets in, or an unattended run still lands a contradiction the check covers.
Frontmatter
| id | itd-2609291923559186 |
|---|---|
| type | intent |
| lifecycle | planned |
| kind | standalone |
| severity | minor |
.abcd/development/intents/planned/itd-2609291923559186-the-consistency-pass-runs-where-records.md
open on GitHub ↗ · commit history ↗
References4
- adr-2609300821558671A reading finding is matched against the record when it is stored, reversing itd-180's warm-work-only rulerelated
- itd-34Intents Promote In Three Flavours — Standalone, Bundle-Member, Disciplinebuilds on
- itd-48`intent-fidelity-reviewer` Gains Its Cross-Doc And Kind-Classification Rolesbuilds on
- itd-62abcd Routes The Invisible Risks An Amateur Cannot See To A Real, Fail-Closed Gate That Wraps A Trusted Scannerrelated
Referenced by7
- iss-2609260926323349itd-48 shipped the consistency pass (Role 2) and nothing tracks the five spc-33 deferrals it was the routed home for: spc-33:A1 (Role-2 mechanical half, cross-doc lint codes), spc-33:A2 (Role-2 pre-commit hook, blocking-vs-advisory policy), spc-33:A3 (Role-3 pre-commit scheduling, whose shape role now belongs to the kinds lint in itd-34), spc-33:A4 (chunked corpus review, dormant until a report shows bundle_overflow: true) and spc-33:G1 (a stable reconciliation key for consistency findings across re-runs). This record is their home until one is planned; A3 goes with itd-34, the rest are follow-ups of the shipped pass.related
- iss-2610262039276483The consistency-pass hook runs rule checks over the whole corpus at commit time, but the lint contract's pre-commit tier lints only staged lines so that old findings never blockrelated
- iss-2610262041032173The glossary keeps 'product thinker' off personas; the consistency-pass press release uses it as a persona's role hint.related
- iss-2610262042503210itd-84 says model contradiction detection must never hold a gate shut on its own; itd-2609291923559186's hook can refuse a commit on onerelated
- iss-2610262044079779itd-87 escalates a finding that matches a resolved or wontfixed record as a new entry; the consistency pass marks such a finding addressed and files nothingrelated
- iss-2610262044513201Shipped itd-48 says Role 2 findings are only reported and a person acts on them; itd-2609291923559186 adds an automatic mode that fixes mechanical contradictions in the commitrelated
- spc-2610021456200324The consistency pass at commit time: a stable finding key, cross-document lint codes, chunked review, and a pre-commit gateimplemented by
mentions6
- dcn-26092900000000072026-09-29 — The product thinker answered twenty-six owed rulings and the published-history question in one interview, asked one at a time by orchestrator abcd-23 of autonomous run A (recorded by lane recRulings for orchestrator abcd-cb). The answers are kept verbatim in the local-tier file `.abcd/.work.local/scratch/reports/rulings-answered-2609-29.md`, dated 2026-09-29, and are restated here because that file is not committed. Published history is left as it is, with no rewrite. The build loop's fidelity audit runs once, on the lane that closes the spec, over the whole delivery (AI). On the vendor denylist the product thinker answered, verbatim: "I think we need an allow list rather than trying to catch a deny list." The interviewer's reading of that answer, recorded as a reading and not as the product thinker's words, is that the per-provider allowlist is the control and the vendor denylist is not extended to chase spellings, with whether the bundled `anthropic/*` entry stays as a backstop left to the technical facilitator (AA(a)). Only a route the person set up on their own machine may use their paid key, and a repository's own route to it is refused, which replaces the route half of itd-2609081951381895 decision 8 (AA(b)). The live site setup, the API adapter and the decision adapter may each close on tests against a simulated service, with the live paid check recorded as owed to a person (iss-2609291925387011, iss-2609291925393913, iss-2609291925398978). itd-111's last criterion is met by an agent's timing check on macOS plus the Linux CI run, so the intent may be finished. Automated dependency updates are switched on, pushed with a personal or app token the person creates and stores as a repository secret (itd-2609221842494980; creating the token is the person's act, and the lane builds everything else and names the secret it expects). itd-6 adds a Go MCP module, proposed for the person's explicit sign-off before it is fetched; closing itd-6 on a fake server was not ruled in this interview. (A later answer the same day, H1b in the local-tier file `.abcd/.work.local/scratch/reports/rulings-answered-2609-29-b.md`, dated 2026-09-29, rules that it is not: itd-6 is finished only after running once against the real RepoPrompt app, a check owed to a person.) For itd-148: the store under the home folder wins (adr-2609091248200336); the store draft itd-2609091014076309 owns add, list and clean-up and itd-148 uses them; a session that declares itself the coordinator is exempt from the write block in the primary checkout and every other session is blocked; and the store draft is planned first, with nothing from the store draft, the merged-worktree clean-up included, built before its planning interview (Q4). itd-148's own wait is not part of that ruling: it follows from Q2, because itd-148 uses the store's verbs, and is carried by the `blocked_by` below. itd-148 and spc-42 are rewritten to match in this change, and itd-148 is now `blocked_by` the store draft. A release retrospective is seeded from a release, the intents a tag shipped (AD); itd-24 and its spec are rewritten to the release in this change. An unpointed route is refused naming the one setting to add, as built in 35100512e, so AC11 of itd-2609170822093401 is complete (BR1). A missed target becomes `next`, whatever the following release is numbered (BS1). Spec pieces keep "step" and the lane stages are renamed, a breaking change to the JSON fields `step`, `performed` and `refusal.step` that resolves iss-2609291313276243 and corrects the glossary entry `core/step.md` (BU1), and the old command spellings are removed in that same breaking release (BT1). The text board shows Later as a count only while the site and `--json` keep the full list (BV1), and an intent in progress appears only under Now (BV2). A pause of zero is allowed (BW1); drain stays in the agents' help list until it runs end to end (BX1); a managed repository must hold the drain eligibility decision in its own record, and drain refuses there until it does (BX2); a capture without a remedy is refused (BX3), which tightens the one-line capture friction `commands/capture.md` promises, so the lane that builds it reconciles that page, the principle wording and every caller that files a capture; a run's pick reason keeps the shared `pursued:` kind with its marker (BZ1); and an intent whose blocker was superseded waits on the successor, transitively (BZ2). The five itd-48 follow-ups are planned as one intent, drafted as itd-2609291923559186 (BT2), and all warn rules share one shrink-only baseline file in which a new warning fails, drafted as itd-2609291924469783 (BT3); both drafts wait on their planning interviews. Each ruling that contradicts a shipped behaviour or another record is amended in the change that builds it, not here. itd-7's planning interview stays owed.
- dcn-26100200000000022026-10-02 — The consistency pass follow-ups are planned as one intent (itd-2609291923559186, spc-2610021456200324, impact additive) after two adversarial reviews and a planning interview with the product thinker and technical facilitator, asked one at a time. Rulings: A3 stays in this intent, though iss-2609260926323349's body had routed it to the shipped itd-34; A4 stays and builds its own overflow signal; the pre-commit gate runs the rule checks on every commit and the model pass only where the owner's personal settings provide a route, marking it owed otherwise, and never refuses a commit on a judgement it could not obtain; what the gate does on a finding (warn, stop, or automatic: fix the obvious and file the rest) is asked at setup; the rule checks cover the whole corpus and the model pass covers the staged records and their links; the gate waits for the core-owned managed pre-commit gates (iss-84 with itd-62, ruling J23); G1 lands first; the new A1 codes are warnings, and the 136 one-way `builds_on` edges that exist when the rule lands are baselined, so only new ones are flagged. The 10 acceptance criteria are the product thinker's. Grounds: "pursued: contradictions get into the records unnoticed and are answered twice, and unattended runs write records with no one checking them for contradictions; wrong if, after it ships, the same contradiction is still filed twice, a rule-catchable one still gets in, or an unattended run still lands a contradiction the check covers."
- dcn-26100200000000102026-10-02 — H4-0 (2026-10-02; recorded by lane rd2) is no new ruling: no question was put, because ruling H3-0 above settles it. The draft itd-2609291923559186 had no record of two adversarial reviews either, so the interviewer abcd-a2 [75597f] ran both reviews before its planning interview, on branch plan/consistency-followups, which is not on the default branch at this entry's base (same local-tier file as the H3-0 entry above).
- iss-84Managed pre-commit gates: the interim prepare-this-repo skill offers the secrets and absolute-path pre-commit config from a private template directory outside the repo. The gate belongs to the configuration layer itself: a core-owned surface should install and maintain commit gates in managed repos, replacing the template copy. Seeded from the scaffold-repo retirement analysis; relates to the pluggable safety gate draft (itd-62).
- itd-2610271130017437A finding with a safe fix is fixed where it is found
- spc-33abcd-mints-collision-proof-record-ids-across-parallel-agents