TASK-127 — diff each contract document against the payload it describes - #21
Merged
Merged
Conversation
TASK-092's reviewer answered the question the row was dispatched on: byte identity is real, not echoed, so the argument that overrode a locked not-dispatchable verdict holds. It also found the repair path the tools advertise leaves trailing whitespace, and that the tests cannot catch it — TASK-122. And that the goals writer takes the file as truth rather than the store, which means phase 002's P-O1.2 may not be met by that row alone — TASK-123, where the direction is the user's to choose. TASK-070 is dropped on the evidence it asked for. USER-004 is answered. The queue is empty for the first time today. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The concurrency lesson was the wrong fix stated the right way: the cap counts agents, tests/parallel counts 8 workers, and 3 x 8 on 14 cores is what stalled two agents. Narrowing the workers rather than the agents keeps the third slot. TASK-094 is the chain head — two P0s say in their own cells to stay open until it lands, because four review rounds went into hardening a category ADR-007 decision 4 removes rather than fixes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The sweep in TASK-111 found one sibling with zero CI coverage (tests/test_conformance.py:440) and left one shape uncovered on purpose; both are now rows rather than notes in an evidence file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
PR #20 lands the store-backed read for the fifteen task columns and the KR tables. Verification item 1 asked for 0 call sites across all three stores; OKR.md and .perry/config.md reach 0, BOARD.md does not — four registers have no store. The row does not close on this. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The remote merged TASK-113 (checks read live state) and TASK-115 (readonly guard coverage) at 10:51Z; the local branch never took them, so three of their own target checks were red here and green on CI.
…ibes KR-O2.4's metric is a count of contract-payload keys documented but not emitted, or emitted but not documented, and nothing in the repository computed it. `test_contract_invariance` records the payload's SHAPE against a baseline, so an emitted-and-undocumented key passes it cleanly and a documented-and-never-emitted key was never in its baseline to begin with; the seven other modules that read a contract file each assert that one named field appears in the prose. Seven spot checks are not a count. `tests/contract_key_parity.py` reads each page's `jsonc` payload sketch and its key tables, runs the invocation the page states in its own `# ` heading, and diffs the two sets of field paths in both directions. Discovery is `schema/*-contract.md` and the run prints how many files it matched — the KR text says "all three contracts" and the glob finds FIVE. The per-contract result is recorded in `tests/fixtures/contract-key-parity.json` so the number is comparable by someone who was not here. Measured today: 0 documented-not-emitted, 17 emitted-not-documented. Neither is asserted to be zero. This row measures the gap; closing it is whatever rows the measurement produces. What could not be compared is named rather than dropped: 20 documented keys across `perry-task/list` and `perry-roles/list` sit in collections Perry's own state leaves empty (`intake.rows`, `asks.items`, `roles.cards`), and 3 more in `expired_sunsets`. A silently narrowed denominator is worse than a smaller one that is stated. Proved by mutation, both directions: removing `startable` from its emit sites names `tasks[].startable` in `documented_not_emitted`; planting a key names `tasks[].undeclared_key` in `emitted_not_documented`; moving one page out of `schema/` takes the discovered count from 5 to 4; a sixth page declaring an unemitted key is reported with no edit to the check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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
KR-O2.4's metric is a count: contract-payload keys documented but not emitted, or emitted but not documented. Nothing in the repository computed it, so the KR could only be scored by hand.
tests/contract_key_parity.pycomputes it. For each page found byschema/*-contract.mdit reads thejsoncpayload sketch and the key tables, runs the invocation the page states in its own#heading, and diffs the two sets of field paths in both directions.The denominator
The KR text says "all three contracts". The glob finds five.
perry-decide/list/1.0perry-events/list/1.0perry-goals/list/2.0perry-roles/list/1.0perry-task/list/1.11Neither count is asserted to be zero. The baseline in
tests/fixtures/contract-key-parity.jsonis what makes a change to either one visible. Closing the gap is whatever rows the measurement produces — this row measures it.schema/README.md § The three read contractscarries the same three-vs-five error and a staleperry-goals/list/1.0row (it is2.0). Both are reported, not edited: thegoalslane owns that text.What could not be compared, by name
perry-task/list— the 6 fields of an intake row and the 8 fields of an ask.intake.rowsandasks.itemsare empty in Perry's own state, so those collections offer no entry to compare against.perry-roles/list— the 6 frozen card fields. Perry's own repo has no.perry/roles/, socardsis[].perry-decide/list—expired_sunsets[].id,.title,.sunset. Same reason.23 keys in total. They are printed by name with the reason, never dropped: a silently narrowed denominator is worse than a smaller one that is stated.
Verification — V3, by mutation
startablefrom all four of its emit sites inbin/perry-taskperry-task/list/1.11: keys the document declares and the tool does not emit changed / was: [] / now: ['tasks[].startable'] / appeared: ['tasks[].startable']task["undeclared_key"]on the live list path... keys the tool emits and the document does not declare changed ... appeared: ['tasks[].undeclared_key']schema/roles-list-contract.mdout5 != 4 : the number of contract files changed — decide-list-contract.md, events-list-contract.md, goals-list-contract.md, task-list-contract.mdcontract files discovered: 6andperry-sixth/list/1.0 … documented_not_emitted: 1 / invented_keyTests
python3 tests/parallel -j 4— 64 modules, 1880 tests, 152s.test_diagnosered, and it was red on the same worktree before this branch (63 modules / 1867 tests / 144s at the cut):dangling: ['DESIGN-900', 'REL-00'], the TASK-126 cause. Not this row's.bash tests/run— steps 1, 3 and 4 clean; step 2 carries the sametest_diagnosered.python3 bin/perry-lint— 0 errors, 3 pre-existingNS-01warnings.git diff --check— clean.Out of scope, and untouched
No contract document's content edited, no contract version bumped, KR-O2.4's text not edited,
tests/test_contract_invariance.py's baseline not touched. The oneschema/README.mdchange is a new subsection saying where the baseline lives, as the spec's file scope permits.🤖 Generated with Claude Code