Development record
The comparative reading receives one widening run's candidates, a positional exception to the prior-run exhaust, with the run derived from the record and no operand added
Context
Two rulings the cold-reading workstream shipped cannot both hold as written.
The first is the prior-run exhaust. The include table's exclusions state that the instrument's own output is never its input, itd-186's fourth criterion pins it (prior manifests and reading records never reach a reading), and the readings companion states the general rule: no reading sees another's output, because a returned item is revision history on the next run.
The second is the comparative reading's object. The 2026-08-28 rulings fix it as the widening reading's returned configurations before admission, and admit no other source. Those configurations are reading records in the readings store, which the first ruling excludes.
itd-199 resolved the collision by refusing: the comparative position does not assemble, because its object "is not repository material and has no channel today". That was the right move over serving the position a corpus that is not its object, and it leaves one of the four positions structurally unavailable. Iteration 2 needs all four.
The design fixes the invocation at a position and a target state (ruling M8, framework section 8.2, companion section 4.1). The widening run whose candidates a comparative reading characterises must therefore come from the record, not from an operand.
Decision
At the comparative position, and at no other, the assembler admits two body fields of one derived widening run's items: the configuration and what admits it, keyed by the item's identifier. Everything else in the readings store stays excluded at that position as at every other: the run's manifest, the items' envelopes and patterns, every disposition, admission and surprise, and every other run. The exception is a row of the include table, so the rendered charter and the assembler version carry it, and the manifest asserts the exclusion of the rest of the store by rows derived from the ledger's own directory list.
The ground is that the candidate text is cold and its fate is warm. The widening reading produced the configurations without ledger access, under the same blindness the comparative reading holds; what has happened to them since (dispositions, admissions, surprises) is the researcher's judgement, which is exactly what a reading must not see. The store holds both halves, and they separate at field and directory grain, which is the separation the assembler already performs on a shipped intent.
The candidate run is derived from the record, and the invocation gains nothing. At the comparative position the assembler selects the committed widening run at the target whose items all carry no disposition and no admission. Exactly one must qualify: with none it refuses and says so; with more than one it refuses and names them, and the operator resolves that by dispositioning one run's items, which is the act the design places after the comparative reading anyway. The invocation stays a position and a target state, as the design specifies.
The ruled order is a gate. Admission follows characterisation, so at the widening position no disposition of any state can be written until a committed comparative run names the widening run, and a comparative assembly refuses if any candidate already carries a disposition or an admission. A widening run with fewer than two candidates yields a comparative run with an empty item set, committed through the ingest verb, so the not-exercised outcome is a run record and never a mutable file.
The comparative preset refusal is withdrawn. itd-199's tenth criterion refused a preset naming a comparative scope. The committed presets gain a comparative entry naming the criteria discipline, and every other include row excludes the comparative position, so no scope can hand it the tree, the brief or the intents.
Alternatives Considered
- Keep the refusal. Leaves the position unavailable and Iteration 2 unable to run Step 4. Rejected: the design names four positions and the companion fixes this one's object.
- Name the widening run with an operand. A closed shape that keeps the no-prose property, and the draft of this decision took it. Rejected because the design fixes the invocation at a position and a target state and an added operand contradicts that letter; the record already holds enough to derive the run, and the one ambiguous case (two undispositioned widening runs) is resolved by the very act the design sequences next.
- Admit the whole run. Simpler, and wrong: the run's manifest, patterns and envelopes are the instrument's account of itself, which is revision history. Rejected on the same ground the exception rests on.
- A separate candidates file outside the readings store. Would duplicate the reading records and give the assembler a second source of truth for one item. Rejected under the one-canonical-primitive rule.
Consequences
- Brief invariant 15's read-block clause gains the one positional exception with its limit (one run, two fields, one position). Its operand enumeration does not move.
- itd-186's fourth criterion gains the same exception, and the read-block eval gains a comparative case: with dispositions, admissions and a second run planted, the comparative bundle carries the named run's two candidate fields and nothing else from the store.
- itd-199's surviving condition on the comparative refusal is re-dispositioned through the condition verb, with this decision's delivering intent as the occasion.
- The operator is told what the assembler selected and why. The result and the manifest name the widening run derived, and a refusal for none or more than one lists the widening runs at the target with each run's item count and its disposition state, so the operator sees what to disposition to make the selection unambiguous.
- The closing run at Step 4 is repeatable, because the gate makes a disposition impossible before the comparative run, and a second comparative run over the same widening run is a second run; recurrence stays warm work.
Status note
Accepted by the maintainer on 2026-09-02, at the planning interview for the Iteration 2 intents, and corrected the same day to the derived form: the draft's named operand contradicted the design's invocation of a position and a target state, and the maintainer's instruction is that Iteration 2 runs exactly as the design specifies. The exception to the exhaust and the ordering gate are the companion's own positions and are unchanged.
Frontmatter
| id | adr-2609021016272867 |
|---|---|
| type | adr |
| status | accepted |
| date | 2026-09-02 |
.abcd/development/decisions/adrs/2609021016272867-the-comparative-reading-receives-one.md
open on GitHub ↗ · commit history ↗
References7
- adr-55The construal stands in the record; its history does notrelated
- adr-56An exclusion control asserts only what it can proverelated
- adr-58A reading is commissioned about something, so the invocation takes a scoperelated
- itd-183The cold reading sees exactly what the assembler passes — positive inclusion, field projection, and a per-run manifestrelated
- itd-186The read-block eval falsifies the firewall — planted warm content that reaches a reading fails the build loudlyrelated
- itd-199A reading is about something narrower than everything, and its scope is a committed, adjustable choicerelated
- itd-2609020625407419A comparative reading receives the widening run's items as its candidate set, and characterises them before anyone admits onerelated
Referenced by1
- adr-2609021016286571The invocation is a position and a target state, and the committed preset for the position supplies the restrelated
mentions12
- adr-2609021016275803No session holds both a reading and the ledger, and a per-run context stamp is how the record shows it
- dcn-26090200000000032026-09-02 — adr-2609021016272867, adr-2609021016275803, adr-2609021016270132 and adr-2609021016288378 are adopted (maintainer, at the same interview, each checked against the framework and the companion first). adr-2609021016272867: the comparative reading receives two body fields of one named widening run's items as the single exception to the prior-run exhaust, through a fourth closed operand naming the run; the maintainer chose the named operand over a derived selection because two widening runs coexist after the closing run, on the condition that an absent operand lists the runs the operator may choose from. adr-2609021016275803: per-run context stamps and a session-separation check that reports held-for-what-was-seen or unobserved, never clean; `scribe assemble` and `scribe ingest` with a ledger-only allow list derived from the ledger's directory list. adr-2609021016270132: the principles family is a declared record store with four typed keys, forward-only, read cold by statement and never by citation, with the inheritance check. adr-2609021016288378: in its three-surface form, because the single-section draft contradicted the design's two landings and adr-55's definition of the construal.
- dcn-26090200000000102026-09-02 — The invocation is a position and a target state and nothing else, as the design specifies (maintainer: "all I want is to run Iteration 2 exactly as designed in v4"). adr-2609021016286571 supersedes adr-58: the scope operand and the override stamp go, the committed preset for the position supplies what the reading is handed, and changing it is a commit. adr-2609021016272867 is corrected the same day from a named candidate-run operand to a derived selection: the comparative assembly takes the one committed widening run at the target whose items carry no disposition and no admission, and refuses naming the runs when none or more than one qualifies. Both corrections close the only two points at which the record contradicted the framework's and the companion's letter on the invocation; the earlier entry today that recorded the named operand is superseded by this one.
- dcn-26090200000000112026-09-02 — adr-56's third rule is refined, not contradicted, by the source-and-tests ruling (maintainer): a control that admits an input it cannot examine may pass it only with a per-item unscanned mark in its attestation, so the second rule (an attestation never says more than the examination) carries what the third rule carried; refusal stays the rule for an input the control claims to have examined and could not. Invariant 16 amended to say so. Every ADR is now checked against the framework v4 and the companion v4: adr-58 is superseded by adr-2609021016286571, adr-2609021016272867 is corrected to the derived run, and none of adr-55, adr-57, adr-2609021016275803, adr-2609021016270132, adr-2609021016288378 or adr-2609021016286571 contradicts either document. The two-hundred-thousand-token target is a clarification the documents do not speak to, kept as such.
- dcn-26092300000000092026-09-23 — The cold-reading research workstream lives in a separate fork, not in this repository, so its open rulings are taken there (product thinker, ruling on iss-2609021857343626, the reading of "at the target" in adr-2609021016272867's comparative derivation). That record is closed here as out of scope for this repository, naming the fork as its home. The code that ships here is unaffected by the move.
- iss-2609021833302981The comparative assembly cannot follow the widening ingest that supplies its candidates: reading ingest writes the widening run's reading records into the committed ledger, where they are uncommitted by construction, and the comparative position's candidate row reaches that store, so the dirty gate refuses the next assembly naming those very records; committing them closes the other end, because the derivation selects a widening run whose own target commit equals the target and the commit has just moved HEAD off it. Both gates are stated in commands/reading.md (Assemble one reading's input: refuses unless HEAD resolves to the target and no included path is uncommitted; The comparative position derives its candidate set from the record: the one committed widening run at the target) and the derivation rule is adr-2609021016272867, so which of the two gives is a design decision the record has not made. Found by rehearsing the opening-run loop on a fixture: the comparative position is reachable only over a widening run whose records were already committed at HEAD, which no run of the loop produces.
- iss-2609021857343626ruling owed on the reading of 'at the target' in adr-2609021016272867 for the comparative derivation; the implementation accepts a widening run whose target is an ancestor of the comparative's target when only the readings store changed between them, so the run's own records can be committed between ingest and the next reading; the alternative is an assembly whose target may differ from HEAD at the comparative position, which reads no tree; the maintainer chooses and the register gains the entry
- iss-2610262031401131The read-block entry puts all the instrument's own outputs inside the block, while invariant 15 admits widening-run items at the comparative position
- iss-2610262041359075The reading-position glossary says `comparative` does not assemble and refuses for want of a channel; the comparative-reading intent says it can now be commissioned and assembles a derived widening run
- itd-2609021003095168The invocation is a position and a target state, and the committed preset for the position supplies what the reading is handed
- spc-2609020626039834The comparative channel: one widening run's candidates, two fields each, characterised before anyone admits one
- spc-2609021004075744The invocation is a position and a target state: the scope operand and the override stamp leave, and the committed preset for the position is applied by the assembler