[DOCS] Reset the trackers to the tree, and add a checked ROADMAP.md - #422
Open
justin13888 wants to merge 11 commits into
Open
[DOCS] Reset the trackers to the tree, and add a checked ROADMAP.md#422justin13888 wants to merge 11 commits into
justin13888 wants to merge 11 commits into
Conversation
`SLICES.md` tracks slices and nothing tracks packages, so "what state is `capsule-server` in" has had no answer that could be checked. `ROADMAP.md` gives every package the repository declares one row, with a state drawn from a closed set defined at the top of the file. The row is only worth reading if it cannot quietly fall behind, so `docs-truth` gains a fourth check that resolves every row against the manifests themselves rather than against a second committed list — a committed list is tautological, since both files are hand-edited and a package added to neither passes. Adding a package now fails the gate until this file gains a row: 47 today, across cargo, gradle, tuist, SwiftPM, bun, the catalog, uv, the submodule and the review buckets. `capsule-core-swift` is a package the plan for this change missed. It carries its own `Package.swift`, `lint-check-swift` loops over it, and `test-swift` does not — which the row says, because a gate that covers format and lint only is not the same claim as a gate. A state defined and used by no row is reported in the success line rather than failed. Failing it would put steady pressure on whoever edits the file to give the spare term a row, which is a dishonest state assignment — the exact defect this check exists to prevent.
Deploying capsule with
|
| Latest commit: |
09b9570
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://5e4e3d3b.capsule-22k.pages.dev |
| Branch Preview URL: | https://docs-reset-trackers-and-add.capsule-22k.pages.dev |
The Baseline and Sequencing sections described the workspace as it was before `S-C59`, and in three places contradicted the rest of the same file. - Sequencing said the Salvo tree was still live, that `architecture-check` was reporting-only with 63 violations, and that Kynos was a git dependency pinned at rev `6513109`. `mise run architecture-check` runs inside `check-rust` and prints "boundaries are intact"; `Cargo.toml` takes `kynos = "0.1.0"` from crates.io; the gates table two hundred lines below already said so. - It owed `capsule-sdk` two things — the gRPC sync half re-fronted on REST, and a schema sourced from Kynos. Both landed: `sync.rs` drives `GET /v1/sync` through the generated client with `tonic` and `prost` out of the manifest, and `build.rs` reads `capsule-server/openapi.json`. - Baseline presented the retired Salvo `capsule-api` as what ships, and claimed the CLI covers E2E cases 1-3. `capsule demo` is offline by design and the networked commands have no server to reach; the cases are owed to `S-Q1`. - The prose said the `core-import-media` bucket was gone. `S-C59` recorded that decision and did not carry it out — the directory is in the tree, so the prose now says so and names the issue that removes it. - `capsule-core::exif` was called `RETIRED` in the Baseline and again in `S-B6`. It is live in `capsule-core/src/exif/`. - The index preamble counted 141 slices. There are 205 rows and 205 detail blocks, 23 of them lane U. - The gates table described the four `spargen::omit!` operations the Salvo document forced. Kynos makes both of those defects unrepresentable and all four generate; the four narrowed today are the `application/cbor` ones, narrowed because spargen's `classify_media` has no such media type.
Each of these is a row the tree already disproves. `S-D1`, `S-D2`, `S-D7`, `S-D8`, `S-D10` read `RETIRED | ready`. `RETIRED` never meant "capsule-sdk is review material" — Sequencing says the SDK rows carry it because the crate's wire contract was being re-sourced. That re-source landed: `build.rs` generates from `capsule-server/openapi.json`, `sync.rs` drives `GET /v1/sync` through the generated client, `tonic` and `prost` are out of the manifest, and no retired package is a dependency. The five are `MIXED | done` (`S-D8` `done*`, its 401-retry-once still owed to `S-D17`): the client half ships and the server half is the one being rebuilt. `S-D26` and `S-I5` landed and read `ready`. `remote.rs` writes the rotated pair back through `checkpoint` on every exit path; `84f719f6` added the fifteen `cli.import.*` keys and put `capsule-cli/src` in `i18n-guard`'s scope. `S-Z9` read `blocked` on a Kynos document that exists: `gen_openapi.rs` emits fifty-nine operations at OpenAPI 3.2 and `openapi-check-kynos` gates them inside `check-rust`. Only the docs work is left. `S-B1`, `S-B5`, `S-B13` read `ready` with their one precondition absent — `rawshift` is a pinned submodule that nothing in `Cargo.toml` names, which the gates table already recorded as "stabilizing, unconsumed". They are `blocked`. `S-B14`'s owed column named the wasm entry point and not the larger half: nothing calls `Lqip::encode`, because producing an `RgbaImage` needs a decoder and `S-C59` took the only one to `legacy-review/`. `S-D12` placed the cadence scheduler in core; it is in `capsule-sdk::recovery`. `S-C59` said the `core-import-media` bucket had gone; it recorded the decision and left the directory. Recount: 87 ACTIVE / 75 RETIRED / 43 MIXED, and 98 done / 57 done* / 28 ready / 9 part / 9 blocked / 4 post-v1.
`capsule-sdk/openapi.json` does not exist — `S-C59` deleted it and made
`capsule-server/openapi.json` the one contract — yet eight places still
named it, four of them Rust doc comments a reader would grep from. Where the
citation was about history (`S-C28`'s status audit, the conformance
rationale) it now says so; where it was a live claim it names the file that
exists.
Three further claims the tree disproves:
- `developer-docs.md` said the REST reference was blocked because no Kynos
document existed. `gen_openapi.rs` emits fifty-nine operations at OpenAPI
3.2 and `openapi-check-kynos` gates them inside `check-rust`; what is left
is the reference generation, which is `S-Z9`.
- `filesystem/server.md` said the store in the tree is still flat.
`capsule-server::blob`'s filesystem backend writes
`blobs/{hash[0:2]}/{hash[2:4]}/{hash}.bin`, creates each shard on demand
and fsyncs it.
- `dependencies.md`, `gen_openapi.rs` and ADR-0002 gave the wrong reason for
the four `spargen::omit!` narrowings. The structurally invalid Salvo
operations are gone; the four narrowed today are the `application/cbor`
ones, because spargen's `classify_media` has no such media type.
`mls-resilience.md` put `ReconcileOutcome` in `capsule-core::crypto::mls`,
which has never existed; it is `capsule-core::crypto::authority`, and its
entry point takes a `ServerChainView`. The unbackticked citation inside a
fenced block is exactly what `module-paths` cannot see.
`licensing.md` described the `VideoTranscoder` seam in the present tense
after `S-C59` retired the module holding it; it is a constraint on the
rebuild.
`capsule-cli`'s `DEFAULT_ENDPOINT` comment pointed at `mise run serve-api`,
a task that retired with the binary it launched.
`module-map.md` gains the normative sentence ADR-0005 needs: an app links
exactly the `capsule_core_ffi` + `capsule_sdk` namespace pair.
Each was already being acted on and was written down nowhere a reader could find it, which is the condition `adr/README.md` exists to end. ADR-0004 retires `capsule-wire`. It was extracted so the response taxonomy could outlive the framework, and Kynos removes the defect it was extracted to fix: the status is part of the return type, there is one declaration, and `conformance.rs` asserts both directions of the agreement. The server owns `problem`, `limits` and `body`; the only occurrence of `capsule_wire` outside the crate is a prose reference in a module comment; a third of the crate adapts a framework the workspace no longer has. `proposed`, with no `Contract:` line: the crate is still a workspace member and still a dependency of `capsule-server`, and #400 lands it. ADR-0005 records that an app links exactly the `capsule_core_ffi` + `capsule_sdk` pair. Three namespaces exist and the number reads as three things an app links; it is not, because two Rust staticlibs cannot share a binary. `accepted`, and `module-map.md` gains the sentence its `Contract:` line points at. ADR-0006 records the server's runtime shape — one binary, one configuration loader, three adapters per typed port, no generic TTL or CAS abstraction. `proposed`: `src/bin/` holds only `gen_openapi.rs`, `src/store/` holds only the in-memory double, and nothing reads a configuration variable. #401-#403 land it. The filename says "three adapters per port" rather than "three adapter pairs": `store/mod.rs` declares six typed stores, not two.
The `Owns` cells were written from directory listings and got several packages wrong in ways a reader would act on. `AssetKit` is the asset-provider abstraction over PhotoKit and the managed store, not a windowing layer; `CapsuleCatalog` owns the contract, the Swift-native models and the in-memory reference implementation, and the `CatalogError` mapping belongs to `CapsuleCatalogFFI`; `FeatureCollections` is the collections home rather than three named screens. `capsule-core-swift` and `capsule-core-kotlin` are standalone harnesses that link `capsule-core` over uniffi and ship the `HardwareSigner` references, not adapter libraries in their own right. `capsule-web`'s row now says the thing a reader most needs from it: it cannot enroll, upload or edit, because a browser holds neither key. Each cell now paraphrases the comment in `Project.swift` or the package's own README, which are the sources that move when the package does.
5 tasks
The oracles read the files this repository happens to have rather than the
files their formats allow, so the promise at the top of `ROADMAP.md` — that
adding a package fails the gate until a row exists — did not hold as written.
- **Package roots one level down were invisible.** `manifestDirs` scanned
only the repository root, so `apps/viewer/package.json` declared a package
no gate could see. It now recurses exactly one level, skipping hidden and
pruned directories, and names a nested root repo-relative — the convention
`Cargo.toml` already uses for `capsule-cli/entity`. A package root is not
searched for further roots: a bun or cargo package legitimately carries
sub-manifests that are not packages. The depth bound is documented as a
bound; the alternative is walking `node_modules` and `target` on every
docs-only pull request.
- **Kotlin's `include` is variadic.** `include(":a", ":b")` is one call
declaring two modules, and the DSL tolerates `include (…)`. The regex
matched neither.
- **Slice-id resolution covered one column.** `Next milestone` and `Notes`
cite slices constantly, and so does the deferred register below the table;
four stale citations in this file were found in exactly those unchecked
cells. Resolution is now a single pass over every backticked `S-…` in the
document, reported once, with the `Open slices` column keeping only its
shape check.
- **`miseTasks` did not know two spellings mise supports.** A quoted header,
`[tasks."docs:build"]`, and a file task in a subdirectory, where
`mise-tasks/docs/build` is `docs:build`. Neither is used here yet, and
missing either would have failed a *correct* row — the worse of the two
ways for a gate to be wrong.
`checkRoadmap`'s `@returns` now names `unused`, which it has returned since
it was written.
Ten new unit tests; 42 in this file, 107 across `capsule-docs`.
- `capsule-wire` said only retired code depends on it. `capsule-server` declares it at `Cargo.toml:49` — ADR-0004 in this same branch says so — and what is true is narrower: declared, and called by nothing. - `capsule-wasm`'s `Owns` claimed LQIP decode. `grep -rni lqip capsule-wasm/` is empty, and the row's own `Notes` says `S-B14` owes it the entry point. - `capsule-android` was `blocked`, which this file defines as a dependency *outside* the package gating it. The missing DI layer is inside the package and the work has started, so it is `stabilizing` — with the caveat that matters spelled out, since `check-kotlin` is lint-only and passes on a package that does not compile. - `capsule-server` has a binary, `gen_openapi`; what it lacks is a *serve* binary. - `capsule-cli/entity` has five entities, not the two named. - `xtask` does not check licences: `mise run license-check` is `cargo deny` over `deny.toml`. `blocked` now joins `frozen` as a defined state no row uses, which the `roadmap` check reports rather than failing, for the reason recorded in the pull request.
- **`prost` left the manifests, not the dependency graph.** `Cargo.lock` resolves `prost v0.13.5` through `tzf-rs`, which `capsule-core` takes for timezone lookup. `architecture-check` reads *declared* dependencies, so a transitive edge is outside what it proves — and `prost` is on its retired list, which makes "left the dependency tree" a claim the gate does not back. Same overreach in `S-D1`'s note: the crate's *manifest* declares no retired dependency. - **The `ACTIVE` legend still excluded `capsule-core`'s exif tree** while the `RETIRED` row two lines down, and the Baseline, both say it is live. - **`S-B2` still called its EXIF input `RETIRED`.** Its derivative input is; `capsule-core::exif` is not. - **`mls-resilience.md`'s contract skeleton named `MlsError`**, which exists nowhere in the workspace. `resilience.rs:206` and `:270` take `&mut self` and return `Result<ReconcileOutcome>` and `Result<RekeyOutcome>`. - **ADR-0004 called `salvo_adapter.rs` a third of the crate.** It is 267 of 528 lines. Decision 12: a `MIXED` remainder with a named live home is `done*` with an `Owed →` pointer, not "owed by construction". `S-D8` was already read that way, so `S-D1` and `S-D2` gain `Owed → S-Q1` (E2E cases 2 and 3, #409) and `S-D7` gains `Owed → S-D17` (#408); the rule at the top of the file now says which of the two readings applies when. Recount: 95 done / 60 done*. The prose head now points at `ROADMAP.md` and says which file answers which question.
The cell sat one line above the `RETIRED` cell that #423 rewrites when the `core-import-media` bucket goes, and it had grown a forward reference into exactly the text that PR replaces. Deleting `exif` from the list is the whole of the repair; the cross-reference added a semantic coupling between two adjacent table rows two different branches are editing, for no gain.
justin13888
added a commit
that referenced
this pull request
Sep 2, 2026
…omment Two loose ends from the `docs-truth` filter widening. `hk.pkl`'s `check-docs-truth` step says it "Mirrors the `docs-truth` paths filter in ci.yml", which stopped being true the moment eight manifest globs went into ci.yml alone — so the same package-addition that now fires the CI job still slipped past pre-push. Both lists carry the eight. The ci.yml comment also described the `roadmap` check in the present tense, but neither that check nor the ROADMAP.md it reads exists at this commit; both arrive with `#422`. Say so, and say why the globs are correct to land first.
5 tasks
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.
Description
Resets
SLICES.mdand the design docs to what the merged tree actually holds, and adds a rootROADMAP.md— the package-level view — behind a newdocs-truthgate that resolves every row against the manifests themselves.Summary
ROADMAP.md(new): one row per package across every toolchain — 47 today: 11 cargo, 2 gradle, 24 tuist, 1 SwiftPM, 2 bun, thelocales/catalog,capsule-vision, therawshiftsubmodule and the fourlegacy-review/buckets. Columns are Package · Kind · Owns · State · Gate · Owner docs · Open slices · Next milestone · Notes, with a closed seven-state set defined at the top and a deferred register below the table.SLICES.mdstays the slice-level tracker;ROADMAP.mdnever restates a slice's status.capsule-docs/scripts/check-roadmap.mjs(new, plus 32 unit tests): a fourthdocs-truthcheck. Node builtins only, no toolchain, matching the three existing checks. It parsesCargo.toml,settings.gradle.kts,Project.swift, thePackage.swift/package.json/pyproject.tomlpackage roots,locales/,.gitmodulesandlegacy-review/*at run time, so adding a package fails the gate untilROADMAP.mdgains a row. It also fails on an orphan row, an unknown state, a slice id with no detail block inSLICES.md, aGatenaming a taskmisedoes not have, a row whoseKinddisagrees with the manifest that declared it, a duplicate row, and a malformed row.SLICES.md: the Baseline and Sequencing prose reset to the merged tree, the index preamble and row-count recount (205 rows; 87 ACTIVE / 75 RETIRED / 43 MIXED; 98 done / 57 done* / 28 ready / 9 part / 9 blocked / 4 post-v1), the gates-table row for the fourspargen::omit!operations rewritten to the realapplication/cborreason, and corrections on thirteen named rows:S-D1/S-D2/S-D7/S-D8/S-D10RETIRED | ready→MIXED | done(both items the tracker owedcapsule-sdklanded),S-D26andS-I5→done,S-Z9unblocked,S-B1/S-B5/S-B13→blockedon an unconsumed Rawshift,S-B14's missing owed producer, andS-D12's misplaced cadence scheduler.capsule-sdk/openapi.jsoncitations, the "REST is blocked" paragraph, the flat-blob-store claim,capsule-core::crypto::mls, thelicensing.mdtense, and one normative sentence inmodule-map.mdfor ADR-0005.capsule-wire's retirement, the single uniffi namespace pair an app links, and the server's runtime shape.Validation
Every command run inside the lane worktree. Round 2 at
09b95705, after the reviewrepairs and the merge of the moved base (
chore/merge-v1-head-397at99dd4bc8, acapsule-web/bun.lockregeneration; merge commit0fe7e290, no conflicts).git merge chore/merge-v1-head-397mise run check-docs-truthcross-links: 529,endpoint-census: 84,module-paths: 120,roadmap: 47 package(s) checked, all rows resolve. States defined and unused: frozen, blockedbun run testincapsule-docs/mise run test-docscheck-roadmap.test.mjs, 10 of them new this round)mise run lint-check-docsmise run lint-check-mdmise run check-docsgrep -c '^### S-' SLICES.mdmise run check-rustwas not re-run: this round changed only Markdown andcapsule-docs/scripts/*.mjs, no Rust source or doc comment. Its round-1 result stands.09b95705shrinks theACTIVE-legend repair to the two words it needs. That cell sits oneline above the
RETIREDcell #431 rewrites when thecore-import-mediabucket goes, and thelonger wording had grown a forward reference into exactly the text that PR replaces. All four
docs gates were re-run after it and pass unchanged.
Not touched, deliberately, for the branches stacked on this one: the
S-C27index row andits
### S-C27detail block are byte-identical to the base (git show 99dd4bc8:SLICES.md);#430 owns them. The repair round touches neither the intro
legacy-review/buckets paragraphnor the
RETIREDArea cell, both of which #431 edits.Round 1 at
1043a414— all pass:mise run check-docs-truth(with the negative check:delete the
capsule-wasmrow, mistype oneGatetask, mistype one slice id → threefindings, exit 1; restored, exit 0),
mise run test-docs,lint-check-docs,lint-check-md,check-docs,mise run architecture-check("boundaries are intact"),mise run check-rust(fmt, clippy, i18n-check, i18n-guard, openapi-check-kynos,architecture-check, license-check, translate-readme-check, build-rust, build-check-wasm,
build-ffi, lint-check-ffi, gen-bindings, verify-examples),
mise run test-rust(160 run,160 passed, 0 skipped). CI was green on every required job.
Not run, and why:
mise run check-swiftmise-tasks/check-swiftexits 0 with "Skipping swift checks" on this Linux host. No Swift file changed.mise run check-webcapsule-web/change is the base's ownbun.lock, carried in by the merge.mise run check-kotlin/check-visioni18n-guardprints an informational list of 56 error codes the Swift client names nowhere;it is pre-existing, unrelated to this change, and does not fail the task.
Risks and rollout
check-roadmap's oracles are regex over manifest text, not parsers, which is what keepsdocs-truthtoolchain-free. A conditional declaration is therefore invisible to them:Project.swift'sffiEnabled ? …ternary still matchesmodule(", soCapsuleCatalogFFIis required to have a row (markedexcluded), whilesettings.gradle.kts's commented-out:cli/:desktopmatch nothing and must not have one. Both cases are pinned by unit tests.docs-truthpaths filter (.github/workflows/ci.yml:77-90) does not listCargo.toml,settings.gradle.kts,capsule-swift/Project.swiftor the package roots, so a pull request that adds a package without touching any.mdwill not run the roadmap check in CI.ci.ymlis outside this lane's manifest; filed on ci: close the gate holes — test job outside required, missing path filters, pre-push parity, and the Kotlin smoke test #416's territory and named in the report rather than edited here.Related Issues
Refs #398. Stacked on #418 (
chore/merge-v1-head-397), which is this PR's base.Refs #421 — the README half of #398, split out (decision 1).
Refs #423 — deleting
legacy-review/core-import-media, deferred on a manifest boundary (decision 9).Contributor Checklist
Decisions taken
Deliverable boundary
Taken: Everything except the README rewrite and its translations - ROADMAP.md, check-roadmap.mjs, the SLICES.md reset, the confirmed design-doc corrections, the core-import-media deletion, and ADRs 0004-0006. Manifest excludes README.md, README..md x12 and xtask/translations/readme/.json.
Rejected: The whole issue including the README - xtask/src/translate_readme.rs:543-549 makes FileBackend bail when a block's source no longer matches the README, so mise run translate-readme cannot regenerate an edited README; it needs translate-readme-extract plus authored target text in 12 locales, and until that lands mise run translate-readme-check inside check-rust (mise.toml:106) is red for every branch in the programme.
Rejected: SLICES.md corrections only, deferring ROADMAP.md - the issue's title deliverable is ROADMAP.md and it has no dependency on the README half.
Reverses: Add the README slice, run mise run translate-readme-extract, fill xtask/translations/readme/.json, run mise run translate-readme.
Filed: the lane files "docs: honest README status paragraph + ROADMAP link, with the 12 regenerated translations" and links it from the PR.
ROADMAP row granularity for the Apple client
Taken: One row per Tuist target - 22 module() targets, CapsuleCatalogFFI (excluded, TUIST_FFI=1 only), and the Capsule app target = 24 rows; check-roadmap's Swift oracle regexes module("Name" plus appTarget's name:.
Rejected: One capsule-swift row - the issue asks for one row per package across every toolchain including tuist targets, and capsule-swift/Modules/ holds 23 independently-tested framework targets (Project.swift:103-133); collapsing them empties the Open slices column for lane U's 23 slices.
Rejected: Grouped rows - a group has no single Gate or State.
Reverses: Replace the 24 rows with one capsule-swift row and drop the Project.swift oracle from check-roadmap.mjs.
What check-roadmap resolves package names against
Taken: The manifests themselves, parsed at run time by regex over Cargo.toml, settings.gradle.kts, Project.swift, the two package.json files, locales/ and legacy-review/*/ - adding a package fails the gate until ROADMAP.md gains a row; no new committed data file; node builtins only.
Rejected: A committed package list - tautological: both hand-edited, so a new package is absent from both and the gate passes.
Rejected: An xtask subcommand in check-rust - docs-truth.mjs:20-33 keeps these checks toolchain-free so docs-only PRs pay no cargo build.
Reverses: Add capsule-docs/roadmap-packages.txt, read it in checkRoadmap, delete the five parsers.
ADR-0005's status and Contract line
Taken: Status accepted with Contract pointing at capsule-docs/src/content/docs/design/module-map.md, plus one normative sentence in module-map.md's Client Boundaries table stating that an app links exactly the capsule_core_ffi + capsule_sdk namespace pair.
Rejected: Status proposed with no Contract line - the decision has landed (capsule-core-ffi/src/lib.rs:32-38, mise-tasks/gen-bindings:23-30); adr/README.md:92 reserves proposed for decisions not landed anywhere.
Rejected: Contract pointing at developer-docs.md:151 - a directory listing, not a normative statement.
Reverses: Set Status to proposed, delete the Contract line, revert the module-map.md sentence.
Note for ADR-0004 and ADR-0006: Status proposed, no Contract line (neither has landed; issues #400 and #401 land them).
Amendment (orchestrator, before launch): the S-C27 row/detail note is OWNED BY LANE #400 (capsule-wire retirement), not this lane; do not touch S-C27. ADR-0004 is written here as
Status: proposedwith no Contract line; lane #400 flips it to accepted when the crate actually retires.Decisions taken inside the manifest, in the same shape
capsule-core-swiftgets a ROADMAP row, andswiftpmjoins the Kind setTaken: A 47th package.
capsule-core-swift/Package.swiftdeclares a real SwiftPM package (the Secure Enclave signer and its software fallbacks);mise-tasks/lint-check-swift:6loops over it, somise run check-swiftis its gate, andmise-tasks/test-swiftdrives only the Tuist workspace, which the Notes cell says.Rejected: The plan's 45-row list, which had no row for it - the check-roadmap oracle finds it from its own manifest, so omitting it fails the gate. A plan count is not evidence; the tree is.
Rejected: Folding it under
capsule-swift-capsule-swiftis not itself a package row, only its Tuist targets are, and this package is built by a different toolchain.Reverses: Delete the row, drop
Package.swiftfrommanifestDirs, and dropswiftpmfrom the Kind vocabulary.A defined state no row uses is reported, not failed
Taken:
checkRoadmapreturns the unused states andreportRoadmapnames them in its line; the gate stays green. No package in the tree is honestlyfrozentoday, andfrozenis one of the seven states the issue mandates.Rejected: The plan's "a state defined at the top that no row uses" as a hard finding - it puts steady pressure on whoever edits the file to give the spare term a row, which is a dishonest state assignment, the exact defect this check exists to prevent.
Rejected: Dropping
frozenfrom the vocabulary - the issue names the seven states, and a state set that shrinks whenever it is briefly unused stops being a closed set.Reverses: Push the unused states into
findingsand delete theunusedfield.The
excludedstate is defined as "outside the shipped build", not "outside every gate"Taken:
capsule-visionisexcludedwith gatemise run check-vision, and the Notes cell says the gate is format and lint only. The plan's wording ("outside every gate") would have made that row self-contradicting.Rejected:
excludedwith gate—- false;mise.toml:111-113runs format and lint over it.Rejected:
stabilizing- the state means "live and inside a gate with the contract still moving"; research notebooks that ship in no client are not that.Reverses: Restore the narrower definition and set the row's gate to
—.The deferred register is a second table, not prose
Taken: A four-column register below the package table, so
deferredhas checkable users and the package table stays exactly nine columns. The check finds the package table by itsPackageheader and collects state usage from every table with aStatecolumn.Rejected: The plan's "single pipe table" with a bullet-list register - the state-usage scan would then have to guess at prose, and a bullet list is not a row anyone can resolve.
Reverses: Collapse the register into a bullet list and scan the whole document body for backticked state names.
legacy-review/core-import-mediais described honestly rather than deletedTaken: The tracker now says the bucket exists, why it is a stale twin, and which issue removes it; the directory stays and
ROADMAP.mdcarries areview-onlyrow for it. Filed as cleanup: delete legacy-review/core-import-media, the stale twin S-C59 recorded as gone #423.Rejected: Deleting it here - the deletion dangles two present-tense citations in
capsule-docs/src/content/docs/design/import/pipeline.md(:54,:129, both "the old plaintext decode/extract path is review-only underlegacy-review/core-import-media/") and one inSLICES.md:708, andpipeline.mdis outside this lane's manifest. The run's manifest-discipline gate says stop and report a revised manifest rather than widen.Rejected: Leaving the prose claiming the bucket is gone - that is the class of defect docs: reset the tracker and design docs to what the tree holds, and add ROADMAP.md #398 exists to remove, and the prose head is inside the manifest, so correcting it costs nothing.
Reverses:
git rm -r legacy-review/core-import-media, repair the three citations, drop theROADMAP.mdrow, and record the deleting sha in theS-C59note - the whole of cleanup: delete legacy-review/core-import-media, the stale twin S-C59 recorded as gone #423.Five SDK rows change Area, not only Status
Taken:
S-D1,S-D2,S-D7,S-D8,S-D10goRETIRED | ready→MIXED | done(S-D8done*).SLICES.md's own Area legend saysRETIREDmeans the target sits in alegacy-review/bucket, and Sequencing says the SDK rows carry it because the crate's wire contract was being re-sourced. Both of the items that section owed have landed -capsule-sdk/build.rsreadscapsule-server/openapi.json,sync.rsdrivesGET /v1/syncthrough the generated client,tonic/tonic-prost/prostare out of the manifest, and no retired package is a dependency - so the marking has no basis left.Rejected: The issue's own remedy, flipping them
ready→doneand leaving Area alone -SLICES.md:57-62saysdoneis not available on aRETIREDrow and that an implementedRETIREDslice reverts toready. That remedy asks for a state the file's own legend forbids.Rejected: Leaving all five untouched because the legend makes
readycorrect - true only whileRETIREDis correct, and it is not.Rejected: Extending the same correction to
S-D9andS-D17- the same reasoning applies to them, and neither is a row this lane's manifest names. Named in the unresolved-notes section below instead.Reverses: Restore
RETIRED | readyon all five and drop the correction notes from their detail blocks.ADR-0006's filename says "three adapters per port", not "three adapter pairs"
Taken:
adr/0006-the-server-is-a-binary-with-config-and-three-adapters-per-port.md.capsule-server/src/store/mod.rsdeclares six typed stores -AuthStateStore,UploadSessionStore,CohortStore, and the three ceremony stores - and its own comment says three adapters are planned per port.Rejected: The filename the plan gave - "three adapter pairs" describes neither the count nor the shape, and an ADR whose title miscounts the thing it decides is the kind of record this directory exists to stop producing.
Reverses: Rename the file and reword the title.
A
MIXEDremainder with a named live home isdone*, notdoneTaken:
S-D1andS-D2gainOwed → S-Q1(E2E cases 2 and 3, e2e: land the bounded E2E cases whose server legs now exist (cases 1, 2, 3, 6, 7, 9, 12, 13) #409);S-D7gainsOwed → S-D17(sdk: recovery calls a route the contract does not serve, and three smaller gaps #408). TheMIXEDrule at the top ofSLICES.mdis narrowed: the retiring half is "owed by construction" only where no slice carries it, and where a named slice does, the row isdone*andOwed →points at it.Rejected: Leaving all three
done-S-D8already records the identical remainder (S-D17) asdone*with that pointer, so one remainder would be read two ways in one table, three rows apart.Rejected: Dropping the
Owed →pointers fromS-D8instead, for consistency downward - it would delete the only navigation a reader has from a landed row to the work still outstanding against it.Reverses: Restore
doneon the three rows, delete theirOwed →cells and the twodone*notes, and restore the original sentence atSLICES.md:58.Slice-id resolution covers every cell of a row, and the whole document
Taken: One pass over every backticked
S-…inROADMAP.md, reported once with its line; theOpen slicescolumn keeps only its shape check.citedSlicesis exported and unit-tested.Rejected: Validating the
Open slicescolumn alone - the four prose defects the review found (capsule-wire's Notes,capsule-wasm's Owns,capsule-server's Notes,xtask's Owns) all sat in columns nothing checked, andNext milestoneandNotescite slices constantly.Rejected: Adding a path-citation discipline to
Notesas well - that is a secondmodule-pathscheck, for a file that cites few paths, and it would fail on the prose aNotescell is for.Reverses: Restrict the regex to the
Open slicescolumn and deletecitedSlices.Package-root discovery recurses one level, and the Gradle regex matches argument lists
Taken:
manifestDirsdescends one level (pruning hidden and skipped directories, and never searching inside a package root for a second one) and names a nested root repo-relative; the Gradle oracle matchesinclude(argument lists, soinclude(":a", ":b")andinclude (":c")both resolve. The promise atROADMAP.md:14-20therefore holds as written.Rejected: Documenting the blind spot and keeping root-only scanning - a gate that cannot catch the change it exists to catch is worse than no gate, because the file it guards reads as guarded.
Rejected: An unbounded walk - it would read
node_modules,targetand.buildon every docs-only pull request, againstdocs-truth's stated no-toolchain, cheap-to-run contract. The one-level bound is documented as a bound in the module comment.Reverses: Restore root-only scanning, restore the single-argument
includeregex, and document the blind spot instead.Unresolved review notes
All findings from the orchestrator review are closed in
f0d5c3cc,adea7c2cand46d5559f. What remains open is what was open before it, plus two items the repairssurfaced.
legacy-review/core-import-mediadeletion needscapsule-docs/src/content/docs/design/import/pipeline.md(two sentences) andSLICES.md:708, neither of which this lane's manifest lists. Per the run's manifest-discipline gate the lane stopped rather than widening: the deletion is not in this PR, the prose says so, and cleanup: delete legacy-review/core-import-media, the stale twin S-C59 recorded as gone #423 carries the whole of it with the exact edits enumerated.docs-truthpaths filter (.github/workflows/ci.yml:77-90) lists**/*.mdandcapsule-*/src/**but notCargo.toml,settings.gradle.kts,capsule-swift/Project.swift, or thepackage.json/Package.swift/pyproject.tomlpackage roots. A pull request that adds a package without touching Markdown will not run the roadmap check in CI. The gate itself now catches such a package (decision 14); the filter still decides whether it runs.ci.ymlis outside this lane's manifest; ci: close the gate holes — test job outside required, missing path filters, pre-push parity, and the Kotlin smoke test #416 owns that file.S-D9andS-D17keepRETIRED | ready. The Area argument in decision 10 applies to them identically — the SDK is not review material and its contract is re-sourced — but neither row is named in this lane's manifest. Whoever takes sdk: recovery calls a route the contract does not serve, and three smaller gaps #408 should correct them in the same direction or say why not.serve-apicitations left standing.SLICES.md:5059(insideS-P8) and:5418(insideS-U19) still namemise run serve-api, a task that retired with the Salvo binary. Both sit in slice detail blocks this lane's manifest does not name — lane P and lane U own them.capsule-sdk/build.rsstill says "OpenAPI 3.1" in the doc comment onbuild_rest_client, while the document it reads is 3.2. Outside this lane's manifest (which names four doc comments, all incapsule-server, plus one incapsule-cli).frozenandblockedare defined states no row uses. Reported in theroadmapcheck's success line rather than failed, for the reason in decision 6.blockedjoined the list whencapsule-androidmoved tostabilizing: after that correction, no package in the tree is gated by a dependency outside itself, and none is frozen.capsule-core-kotlin's row does not mention that its smoke test is red. Android build is red: capsule-android references a DI layer that is not in the tree #389's second compile failure isSoftwareSignerSmokeTest.ktcallingFfiWorkspace.createwithout theclientparameter the regenerated binding added. The row'sNotessays "smoke tests only" and itsNext milestoneis StrongBox on a device runner, both of which read as healthier than the tree is. Not one of the review's findings and the instruction was to change nothing else, so it is recorded here rather than edited; Android build is red: capsule-android references a DI layer that is not in the tree #389 covers the repair.