7.3 KiB
id, title, parent, depends_on, created, claimed_by, claimed_at, blocked
| id | title | parent | depends_on | created | claimed_by | claimed_at | blocked |
|---|---|---|---|---|---|---|---|
| T01.a | A provenance annotation for a target announced but not yet written | T01 | 2026-09-16 | null | null | false |
Description
Extend the @provenance mechanism so that a symbol aligned on a target its developers have announced but not yet written can be annotated honestly, and make the reference requirement enforced.
Why this runs first. Every later child in this batch annotates at least one symbol that has no upstream path:symbol to cite — useShapeQuery has zero occurrences in nextgraph-rs. The weakness is recorded, deliberately unfixed, in .project/rules/nextgraph/surface-mirrors-the-sdk.md § "The gap that same example exposes": an author holding the strongest possible justification has only two bad moves left — cite an approximate symbol, which is precisely the readUnion failure, or declare invention, which understates the alignment and tells a later reader the shape is ours to change. Fix the mechanism before anyone has to use it.
Files in scope: packages/polyfill/test/provenance.test.ts (the format and its checks), the @provenance header block in packages/polyfill/src/index.ts, the kind table in .project/rules/nextgraph/no-divergence-from-nextgraph.md (the taxonomy lives there and must gain the same entry), and any existing annotation whose kind changes under the new taxonomy.
This child does NOT change the published surface. No symbol is added, removed or re-signed, so there is no contract edit and no version bump here. Do not touch .project/concepts/app-contract/polyfill-surface/contract_polyfill-surface.md — the children that change the surface each own their own edit to it.
Open questions — record the decision beside the code, do not guess a design:
- "A mandatory reference on every function, which must resolve" collides with a reason already written down.
test/provenance.test.tsstates, at length, that it deliberately does not check therefpath exists on disk:nextgraph-rsis a sibling checkout that may be absent on another machine, and a test that goes red for that reason teaches nothing — it just trains people to skip it. Decide what "must resolve" means here (a well-formed citation into a named checkout; resolve when the checkout is present and skip otherwise; resolve against a pinned commit) and record the reasoning next to the test. If it cannot be settled from the doctrine leaves, stop and ask rather than inventing a checker that will be skipped. - What the new kind is called, and what it takes as evidence. There is no
file:symbol, so the citation has to be the statement itself — whose statement, and where it was made. Neither existing kind fits:declared-not-wiredneeds a declaration in the tree,reserved-nameneeds a name in the tree. Name it so it can never be read asinvention, because the whole point is that it is the strongest justification, not the weakest.
Pass condition. The hard gate below, plus: every published symbol still carries a well-formed annotation; the new kind is exercised by a test case (its first real annotation belongs to T01.c, which reads this child's ## Result before annotating); and the taxonomy in the rule file and the one in the test agree.
Hard gate: bun test → 0 fail; bunx tsc --noEmit -p packages/polyfill/tsconfig.json → exit 0; bunx tsc --noEmit -p packages/polyfill/e2e/tsconfig.json → exit 0; python3 ~/.claude/skills/concept/lint.py → 0 ERROR. Anti-cheat: no any, no @ts-ignore, no deleting or skipping a test, no widening an assertion.
Resolved since planning (2026-09-16). The "the ref must resolve" proposal FALLS: provenance.test.ts documents why it deliberately does not check disk — nextgraph-rs is a sibling checkout that may be absent, and a test red for that reason trains people to skip it. That reason holds. The third way to implement instead: check resolution ONLY when the sibling checkout is present, skip otherwise — the argument is preserved and a dead citation is still caught where it can be. The new kind for "announced by the developers, not yet written" is still needed.
Progress
- 2026-09-16 — Baseline before any edit:
bun test394 pass / 0 fail,lint.py0 ERROR. Proof set isprovenance.test.tsplus every source file carrying an annotation. - 2026-09-16 — Measured the "must resolve" question instead of guessing: all 92 existing
refs resolve in../nextgraph-rstoday, path AND symbol. So the third way costs nothing to adopt and catches rot the reader cannot (the citation is the thing that moved). Implemented it: upstream refs checked only when the checkout is present (../nextgraph-rsor$NEXTGRAPH_RS), announced records checked ALWAYS because they point into this working copy. - 2026-09-16 — Named the kind
announced-not-written, parallel todeclared-not-wired: it says what is there (a statement) and what is not (anything in the tree). Evidence isref= the.mdrecord here + the announced name, plusannounced-by=<who>@<YYYY-MM-DD>. The record must be prose, never one of our own source files — otherwise our code stands as the evidence for its own shape, wearing the strongest label in the set. - 2026-09-16 — Found a pre-existing disagreement the pass condition forces to fix: the test's closed set had five kinds, the rule file's table six (
reserved-namemissing from the test), and the rule's prose said "five kinds" over a six-row table. Test,src/index.tsheader and rule table now carry the same seven; the prose says "a closed set" instead of a number that rots. - 2026-09-16 — Mutation-checked both new checks rather than trusting green: a renamed upstream symbol goes red; a real
announced-not-writtenline in a.tsfile parses end to end and goes red whenannounced-byis dropped. Both probes reverted,git diffclean on the probed files. - 2026-09-16 — Gate:
bun test397 pass / 0 fail; bothtscexit 0;lint.py0 ERROR.
Result
Done. The provenance taxonomy gains announced-not-written: upstream's developers have stated the direction, and the tree carries nothing — not a definition, not even a name. Being the strongest kind available there, it is the hardest to assert: its ref is the .md in this working copy where the statement is on record (never a source file), and it carries announced-by=<who>@<YYYY-MM-DD>, refused on every other kind. The third way on resolution is implemented: upstream citations are checked only when ../nextgraph-rs (or $NEXTGRAPH_RS) is present; announced records are checked always: they point here. The kind is exercised by a fixture test over a pure malformations(), and verified through the parser.
Files. packages/polyfill/test/provenance.test.ts, packages/polyfill/src/index.ts (header block), .project/rules/nextgraph/no-divergence-from-nextgraph.md, .project/rules/nextgraph/surface-mirrors-the-sdk.md.
Surprises. The test's closed set was missing reserved-name, which the rule table already had, and the rule said "five kinds" over six rows — both fixed. All 92 existing refs already resolve, so the new check cost no fix-ups.
Follow-ups. T01.c's annotation is written out verbatim in surface-mirrors-the-sdk.md § "The gap that same example exposed" — copy it. announced-by is nextgraph-developers; a named individual would be stronger evidence, and the record names none.