docs(plans): correct the S11 provenance plan against waves 1 and 2

Why

The merged plan states facts the wave-1 and wave-2 builds falsified. Guardrail 4 bars a step MR from fixing them in place, so each divergence sits in its own MR description, where the next step's author will not look. This folds them back.

Five would misdirect a later step. Step 10's RouteTable() pin is off by one against main, Step 4's truncation contract is wrong three ways, Step 5 asks for a suppression guardrail 25 forbids, Step 2's Tests: field names a file that cannot reach the symbols it must cover, and Step 8 rests its chore type on a claim that the answers a client sees do not change.

What

Step Correction Build
Approach, Over-ceiling Five more steps were forecast under the ceiling and landed over it the five below
2 The Tests: file reaches neither new symbol, so the unit cases get their own refactor(npm): split the publish charge into a ... (!2803 - merged) • Hayley Swimelar • 19.5
3 Two files outside the list: the fuzz:npm target with its 10m to 15m bump, and the corpus index chore(npm): parse and shape-check an attestatio... (!2806 - closed) • Hayley Swimelar • 19.5
4 The truncation contract, and the FuzzJSONStringReaderBounds registration lands here chore(npm): bounded JSON string reader for stre... (!2805 - closed) • Hayley Swimelar • 19.5
5 No file-level squawk header, one statement-level ban-drop-column, and a different timeout precedent chore(datastore): add npm_versions.attestation_... (!2813 - closed) • Hayley Swimelar • 19.5
6 wire_npm_authz_test.go and the S09 row join the list, "two modified test files" is three, and route_disagreements.md stayed untouched chore(npm): attestations route grammar and auth... (!2807 - closed) • Hayley Swimelar • 19.5
7 Step 3's fixture builder needed no extension chore(npm): verify a bundle's subject against t... (!2812 - closed) • Hayley Swimelar • 19.5
8 Five classes of client-visible answer move, all spec-ordered, none a regression chore(npm): apply the _attachments key rules at... (!2814 - closed) • Hayley Swimelar • 19.5
10 The pin moves 15 to 16, the oracle and census rows land here, and guardrail 20's order goes on Depends on chore(npm): mount the attestations route on an ... (!2811 - closed) • Hayley Swimelar • 19.5
11 Position 3's key needs a bound, the value drains into a pre-sized buffer, Limits.validate() gains its arm, and the cause names the limit chore(npm): bounded JSON string reader for stre... (!2805 - closed) • Hayley Swimelar • 19.5
14 Why the mux cannot supply package_name, and who consumes the stamp chore(npm): mount the attestations route on an ... (!2811 - closed) • Hayley Swimelar • 19.5
16 The version capture is validated before any use of it chore(npm): attestations route grammar and auth... (!2807 - closed) • Hayley Swimelar • 19.5
18 npm_command stays audit, with the grouping reason chore(npm): mount the attestations route on an ... (!2811 - closed) • Hayley Swimelar • 19.5
20 blobSizeDeltas keeps its parameter order, and the asymmetric rows are extended rather than relaxed refactor(npm): split the publish charge into a ... (!2803 - merged) • Hayley Swimelar • 19.5

Three things a reviewer would otherwise ask:

  • The ## Status table is byte-identical to main. It belongs to docs(plans): record the open step MRs in the S1... (!2810 - closed) • Hayley Swimelar • 19.5, and no hunk here goes near it. The last command below is the check.
  • Rules over digits. The over-ceiling correction states the pattern the five builds share, the overshoot sitting on the test side, rather than five counts that go stale on the next push.
  • The 2026-09-21 S11 rulings are not folded in. Keyed entries, bounds, UTF-8, and digest case wait for the docs(specs) MR that settles them, with a second corrections batch behind it.

Test plan

mise exec -- npx markdownlint-cli2@0.18.1 docs/plans/2026-09-11-npm-provenance-attestations.md docs/plans/README.md
mise exec -- vale --minAlertLevel=error docs/plans/2026-09-11-npm-provenance-attestations.md docs/plans/README.md
mise run lint:links
diff <(git show origin/main:docs/plans/2026-09-11-npm-provenance-attestations.md | sed -n '/^## Status$/,$p') <(sed -n '/^## Status$/,$p' docs/plans/2026-09-11-npm-provenance-attestations.md)

markdownlint and the diff print nothing. Vale reports 0 errors, and its 5 new warnings are all the spelling of mux, a word the plan already uses. lychee is clean over 3,013 unique links with fragments on, which covers the one anchor this MR adds.

Guardrails

  • 12. No docs/testing/ scenario is added or affected: this MR changes plan prose alone, and no service behavior moves with it.
  • 24. No docs/user/ page is affected for the same reason, and docs/plans/ does not publish to docs.gitlab.com.
Context for LLM agents

Rationale

  • Restating each correction as "the plan said X, the build did Y" in the step text. Rejected: a plan states what is true, and the narration belongs in this description. The one exception is Step 10's pin, where main reading 15 rather than 14 is itself the fact a later step checks against.
  • Folding the five over-ceiling line counts into the plan. Rejected: a count written into a plan is stale at the next push, and the pattern the five share is what a later step acts on. The counts stay in the five MR descriptions.
  • Correcting Step 8's five answer classes inside the Scope field. Rejected: Scope says what the step does, and the moved answers are a separate contract a reviewer checks against the spec, so they get their own Answers that move field.
  • Chosen: correct each step in place, one field at a time, and leave every untouched claim alone.

Non-goals

  • Filling the Status table. docs(plans): record the open step MRs in the S1... (!2810 - closed) • Hayley Swimelar • 19.5 owns it, and a second writer is what guardrail 4's single-writer rule exists to stop.
  • The 2026-09-21 S11 rulings on keyed entries, bounds, UTF-8, and digest case. Each needs a spec amendment first, and folding a ruling into plan text ahead of its spec would make the plan the authority.
  • Four more Files-list gaps of the same class, each recorded in its own MR description: Step 2's docs/dev/storage-accounting.md, Step 5's migrations_checksum_test.go and npm_schema_integration_test.go, Step 8's streampub_test.go, and Step 10's observe_test.go and wire_npm_observability_integration_test.go. Steps 3, 6, and 10 got the treatment here because they carry a correction this MR was scoped to; closing the rest belongs with the second batch, in one pass, rather than four at a time. Step 10's Tests field accordingly names the three files its corrected Files list carries.
  • Re-running the plan's LOC estimates. They are forecasts, and the Over-ceiling section now says how to read them.

Related to #1273

Merge request reports

Loading
Loading