Discovered while resolving vreko-dev/vreko#511**. Corrected 2026-07-09 — the original finding overclaimed severity, but the underlying process gap is confirmed and, if anything, sharper than first filed.**
What actually happened (corrected)
CANON.md §16 ("Workspace Artifact Two-File Contract") documented generated.fileIndex's relocation to the sidecar-only file as settled, deliberate architecture — complete with a table, a reading order, and a "vreko-dev/vreko#322 Scope Note" distinguishing which half of a related split was "spec-intended" vs. still open. It read, and was written, as a ratified design decision.
It was not a decision. It was an internal drift from an already-published, correct external contract, written up as if it were one. @workspacejson/spec@0.4.1 on npm — verified directly via npm pack — has always correctly declared fileIndex as a required v0.3 field. The relocation (29905e6bd, 2026-06-17) only ever affected Vreko's own unreleased dev branch (the emitter, plus a vendored local copy of the spec's types that had itself silently drifted from the real published package). Nobody checked either the local copy or the emitter's behavior against the actual npm-published contract before writing the canon entry — a single npm pack @workspacejson/spec@0.4.1 away, and nobody ran it.
This is arguably a worse instance than originally filed: it's not "a canon-delta missed that an external promise was broken" (which at least requires noticing something happened elsewhere). It's "a canon-delta certified a local file's behavior as correct architecture without checking it against ground truth that was one command and thirty seconds away."
Why this is a process finding, not a doc-fix
Fixing the CANON.md text (already done, as part of vreko-dev/vreko#511) treats the symptom. The actual question: something in the canon-delta pipeline accepted an unverified internal claim as a ruling, over a fact that was mechanically checkable. A canon-delta was authored describing the sidecar move as intentional; it was reviewed or self-certified; it merged into the authoritative architecture record. At no point in that path did anything run the one command that would have shown the local copy no longer matched what was actually published.
This is exactly the failure class META-83 names: "Canon content is policy — Q authors or reviews; agents do not invent assertions." Whatever wrote or merged CANON.md §16 either wasn't Q, or was Q without the information (or the habit of checking) needed to catch a local-vs-published drift dressed as an architecture note.
Why it's urgent now, not eventually
META-93 proposes giving canon dispatch-blocking authority — the conductor reads canon and refuses dispatch when required keys are missing or contradicted. Under that model, a wrong canon entry doesn't just mislead a reader who happens to check external contracts by hand; it becomes the thing that actively blocks or licenses future dispatch. This incident is a live example of what ships if the canon-delta pipeline goes live before its acceptance criteria exist: canon can certify an unverified internal claim as ground truth, and once it does, everything downstream trusts it — including, in this case, decisions about whether an external consumer was affected, which the first fix pass got wrong for exactly this reason.
What needs investigating (not yet known)
- What is the actual current canon-delta pipeline — who/what authors a §-level CANON.md addition, what review (if any) happens before merge, and was this instance representative or an outlier?
- Was this specific §16 addition agent-authored, Q-authored, or Q-reviewed-but-missing-context?
- What else did this pipeline accept? §16 is the instance found because vreko-dev/vreko#508 forced a behavioral check that happened to lead to checking the actual npm package. Nothing suggests it's the only one — worth a scan of other CANON.md §-additions for the same pattern (a design rationale documented for an internal-only file state, never checked against whatever external ground truth it claims to describe).
- Does this change META-83's scope, or is it evidence supporting META-83's existing scope as already-necessary?
- New: should canon-delta review include a standing checklist item — "if this claims an external contract's state, name the command that verifies it, and show its output"? This incident and its correction both turned entirely on one
npm pack command nobody thought to run the first time either.
Done condition
- Canon-delta authorship/review path documented as it actually works today (not as intended).
- Determination recorded on whether this instance was agent-authored, and if so, what let it merge without a ground-truth check.
- At least a spot-check of other CANON.md §-additions for the same pattern — report findings, don't assume this was isolated.
- Explicit link back to META-83: does this incident change that issue's scope or priority.
- Consider whether "cite the verification command" becomes a standing canon-delta review requirement.
Discovered while resolving vreko-dev/vreko#511**. Corrected 2026-07-09 — the original finding overclaimed severity, but the underlying process gap is confirmed and, if anything, sharper than first filed.**
What actually happened (corrected)
CANON.md §16 ("Workspace Artifact Two-File Contract") documented
generated.fileIndex's relocation to the sidecar-only file as settled, deliberate architecture — complete with a table, a reading order, and a "vreko-dev/vreko#322 Scope Note" distinguishing which half of a related split was "spec-intended" vs. still open. It read, and was written, as a ratified design decision.It was not a decision. It was an internal drift from an already-published, correct external contract, written up as if it were one.
@workspacejson/spec@0.4.1on npm — verified directly vianpm pack— has always correctly declaredfileIndexas a required v0.3 field. The relocation (29905e6bd, 2026-06-17) only ever affected Vreko's own unreleaseddevbranch (the emitter, plus a vendored local copy of the spec's types that had itself silently drifted from the real published package). Nobody checked either the local copy or the emitter's behavior against the actual npm-published contract before writing the canon entry — a singlenpm pack @workspacejson/spec@0.4.1away, and nobody ran it.This is arguably a worse instance than originally filed: it's not "a canon-delta missed that an external promise was broken" (which at least requires noticing something happened elsewhere). It's "a canon-delta certified a local file's behavior as correct architecture without checking it against ground truth that was one command and thirty seconds away."
Why this is a process finding, not a doc-fix
Fixing the CANON.md text (already done, as part of vreko-dev/vreko#511) treats the symptom. The actual question: something in the canon-delta pipeline accepted an unverified internal claim as a ruling, over a fact that was mechanically checkable. A canon-delta was authored describing the sidecar move as intentional; it was reviewed or self-certified; it merged into the authoritative architecture record. At no point in that path did anything run the one command that would have shown the local copy no longer matched what was actually published.
This is exactly the failure class META-83 names: "Canon content is policy — Q authors or reviews; agents do not invent assertions." Whatever wrote or merged CANON.md §16 either wasn't Q, or was Q without the information (or the habit of checking) needed to catch a local-vs-published drift dressed as an architecture note.
Why it's urgent now, not eventually
META-93 proposes giving canon dispatch-blocking authority — the conductor reads canon and refuses dispatch when required keys are missing or contradicted. Under that model, a wrong canon entry doesn't just mislead a reader who happens to check external contracts by hand; it becomes the thing that actively blocks or licenses future dispatch. This incident is a live example of what ships if the canon-delta pipeline goes live before its acceptance criteria exist: canon can certify an unverified internal claim as ground truth, and once it does, everything downstream trusts it — including, in this case, decisions about whether an external consumer was affected, which the first fix pass got wrong for exactly this reason.
What needs investigating (not yet known)
npm packcommand nobody thought to run the first time either.Done condition