docs(specs): retire S06 and repair its references

🗑️ What this does

Retires S06 (storage layer) from the tree and repairs every reference it leaves behind, following the S04-C precedent in !2879 (merged). The spec has been a 22-line landing stub since dddc6cc7 converted its content into docs/dev/storage.md and docs/dev/storage-composition.md. This MR deletes the stub, turns its index row into a retired row, and removes every S06 citation from the code: Go comments, the config proto, SQL migration comments, CI, and scripts.

Handbook !21252 removed the three ADR passages (ADR-007 twice, ADR-008 once) that linked docs/specs/S06-storage-layer.md, and the sync:adrs job has brought that change into main, so deleting the spec leaves no ADR link dangling.

✅ Eligibility

Finding Re-verified
Completed with zero implementing plans ✅ docs/specs/README.md ## Completion and retirement names S06 and S22 as the Implemented specs whose plans were deleted before the retired-row rule existed; dddc6cc7 deleted S06's plan and settles completion. No retired plan row names S06.
The spec is a stub ✅ 22 lines, pointing at the two dev docs.
No blocking open issue ✅ the open S06 hits are follow-ups whose outcome now lands in storage.md (for example #198). #615 owns the deferred blob FKs; this MR only re-points their TODO markers at it.
Destination carries the contract ✅ every structural citation in the tree maps to a storage.md section (table below); nothing needed authoring.

📚 Citation to destination

Citation in the tree Now carried by
AC#7 (Exists tri-state), AC#9 (multipart copy above 5 GB), AC#12 (signed HTTPS URLFor) ### StorageDriver, ### Move semantics and ### S3 driver, ## Security considerations
BlobStore AC, OpenBlob execution steps ### BlobStore, ### Delivery mode, ### Object metadata
Session Lifecycle AC ### Session, ### Commit protocol
Commit Protocol step numbers ### Commit protocol; its list is renumbered, so these were restated, not re-pointed
Crash-Recovery A1a to G1b, B1 ### ResumeSession recovery branches, ### Failure scenario catalog, ### dirty as a poison pill; the ids survive without the S06 prefix
"Deferred DB Writes", "Canonical cleanup" their own sections
Data Model, Step 6 attachment FK ## Data model, ### blob_storage_blobs, ### upload_sessions
"Session-to-URL binding" ### upload_sessions and the ## Error cases row
Error Cases, Security Considerations, Observability, Configuration the matching sections
Step 22 (mandatory storage) storage-composition.md ### One shared store, threaded into the format tiers
Plan-step decisions, Resolution #21, S06 Testing, PathResolver ACs dropped as point-in-time; the code, ## Testing and ### PathResolver state what survives

The three ADR delegations the handbook MR removes (the metadata_sha1 rationale, the per-failure flow, and the consistency model) are all carried by ### blob_storage_blobs, ### Object metadata and ## Consistency and crash recovery.

🔍 Reference sites and how each was resolved

Site Resolution
docs/specs/README.md index row Retired row naming this MR and both dev docs
docs/specs/README.md completion paragraph Names S22 alone, since S06 now has a retired row
docs/plans/README.md npm-hosted row Links the storage layer
13 live specs, 15 live plans Each reference links the storage.md section carrying its contract; line-pinned citations became the section link or the restated contract; references to the deleted storage-layer plan keep the step with a commit-pinned permalink. No plan Status table is touched.
The five relative links to the spec file Re-pointed with the rest; they are what docs:lint would otherwise fail on
docs/dev/observability.md The 18 storage metric Owner cells link storage.md#observability
docs/dev/development-model.md Table and prose ids link or name the storage layer; ### S06 delivery strategy is removed, because it recorded how a finished phase was sequenced and its stub-first lesson is already stated under ### When dependencies are not yet available
docs/dev/database-query-patterns.md "the S06 catalog" became "the storage query catalog"
docs/roadmap/closed-beta.md tallies Recomputed from the index: Implemented 6 to 5, Retired 1 to 2, tracked 55 to 54, approved-or-better 40 to 39, closed-beta scope 40 of 50 to 39 of 49
docs/roadmap/closed-beta.md rows, retrospectives, owner tables Dated narrative; the bare id stays
docs/roadmap/closed-beta.md mermaid nodes Node identifiers, untouched
.gitlab/issue_templates/engineer_onboarding.md Links storage.md instead of the spec
internal/storage/session_expiry.md The GCS citation links storage.md#gcs-driver; the dead plan-step pointer became the current fact that StorageConfig carries no override
internal/remote/operations.md Gains ## The cache-fill tee, carrying the contracts the capped fetch.go comments could no longer hold (below)
Go comments, 126 files Removed or restated per go-style.md ### Reference only what does not rot; any other spec, plan-step or AC citation in an edited block went too
config.proto, gen/ Four comments fixed and regenerated
SQL migrations Data-model citations cite storage.md; the five TODO(S06-Step-6) markers are TODO(blob-fk) and point at #615
.gitlab-ci.yml, .mise.toml, testdata, scripts/conformance/run.sh Banners and comments name the storage subject

Two lines keep the literal S06 because they mean monolith/S06, a live spec.

✂️ Comment compression

Editing a comment block caps the whole block (### Comment caps), and many storage blocks were several times over cap, so the Go diff is mostly deletions. The dropped text was restatement, AC and plan-step lists, and test-first narration. Comments found untrue against the code were corrected in the same edit:

  • internal/storage/metrics.go: the header claimed the metrics are an unwired skeleton.
  • internal/storage/stub/stub.go: New claimed the interface lands in later plan steps.
  • internal/format/maven/upload_stream_test.go: the header claimed its cases fail.
  • internal/metrics/cardinality.go: "above" meant "below".

Where a compressed comment carried a contract stated nowhere else, the contract moved to the package's own page instead of being lost: fetch.go's cache-fill tee states, its no-concurrent-Close rule, the detached session context, and the unbounded terminal calls tracked in #396 now live in internal/remote/operations.md.

In pg_session.go, the prose above the closeFlushFail failpoint is deleted rather than rewritten. The failpoint's injected body counts as comment lines, so any rewrite there exceeds the cap; with the directive first the block passes, as internal/accounting/emit.go already does. The injected code and the arming sites carry what the prose said.

Non-comment changes: three test assertion messages, and TestInstrumentQuery_CoversS06NameSet / s06QueryNames renamed to TestInstrumentQuery_CoversStorageNameSet / storageQueryNames. No behavior change.

📏 Size

This MR exceeds 500 reviewable lines on purpose. The deletion and the sweep are one concern: a partial sweep leaves some sites pointing at a file that still exists and others at the dev doc, and lychee forces the link repairs to land with the deletion anyway. The branch is one commit per file group, so it reads commit by commit:

File group Files Added Removed
internal/storage Go 65 418 2192
internal/format Go 30 103 540
Other Go (cmd, datastore, remote, server, smaller packages) 32 127 518
docs/specs 13 168 166
docs/plans 16 166 153
docs/dev 3 29 38
Roadmap, sidecar pages, issue template 4 79 24
SQL, CI, scripts, testdata 13 40 36
proto and generated gen/ 2 10 10

The retirement commit itself (the stub deletion and the retired row) lands on top of these.

📋 Guardrails

  • Configuration reference (guardrail 14): the config.proto change is comment-only, with no schema or loader change, so docs/dev/configuration-reference.md does not change, and it must not gain a spec identifier.
  • User docs (guardrail 24): docs/user/** is unaffected; a retirement changes no customer-visible surface.
  • E2e catalogs: no scenario is added or affected; this changes no behavior.
  • Verification: lychee --offline --include-fragments '**/*.md' 0 errors; markdownlint-cli2 0 issues; vale 0 errors on changed files; golangci-lint run ./... 0 issues; the integration-tagged lint is clean on changed lines; the unit tests pass; check-comment-caps.sh --base origin/main passes; git grep S06-storage-layer is empty across the tree.
  • Duo spec-status-changes: the retired row has no spec file to match by design, per docs/specs/README.md ### The retired row.

Related to #1338

Edited by David Fernandez

Merge request reports

Loading
Loading