Crate Org Follow-up — Implementation Plan
Crate Org Follow-up Implementation Plan
Section titled “Crate Org Follow-up Implementation Plan”For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Land the SSOT/discoverability fixes, naming corrections, and 5 build-time extractions specified in 2026-05-08-crate-org-followup-design.md, and add vox-arch-check lints to prevent regression.
Architecture: Six sequential PRs. PR1 fixes names everywhere docs read them. PR2–PR5 perform extractions/splits ranked by build-time impact ÷ disruption cost (smallest-first). PR6 adds enforcement so the gains stick. Each PR is independently mergeable and revertable; verification commands are explicit.
Tech Stack: Rust 2024, cargo, cargo metadata, vox-doc-pipeline, vox-arch-check (workspace’s own architectural lint binary), TOML, Markdown.
Spec: 2026-05-08-crate-org-followup-design.md
Authoritative ground truth (do NOT update from memory — re-read before editing):
crates/<name>/Cargo.toml(the actualname = "..."field)Cargo.toml[workspace.dependencies]docs/src/architecture/layers.toml- The actual
crates/<name>/directory existence
Project rules to honor (from CLAUDE.md / AGENTS.md):
- Auto-generated docs MUST be regenerated, never hand-edited:
docs/src/SUMMARY.md,docs/src/architecture/architecture-index.md,docs/src/feed.xml,*.generated.md,.cursorignore/.aiignore/.aiexclude(regen viavox-doc-pipelineorvox ci sync-ignore-files). - Project automation MUST be
.voxfiles viavox run, never.ps1/.sh/.pyglue. - All
```voxdoc snippets must compile viavox-doc-pipelinedoctest runner; use// vox:skipto opt out per-block. archive/anddocs/src/archive/are tombstoned — do NOT read or modify.- Use
Edit/Write/Read/Glob/Greptools, notcat/sed/awk/echo.
Status (2026-05-15): All PRs 1–6 landed in one session (2026-05-15). The 156 checkboxes below were not individually ticked — see the status callout in 2026-05-08-crate-org-followup-design.md for the authoritative summary. C3 and Tier D (C5) are deferred with their own plan docs.
vox-arch-checkreports clean.
Pre-flight (do once before starting)
Section titled “Pre-flight (do once before starting)”-
Step 0.1: Confirm baseline build is clean. This is the reference point for all verifications.
Run:
cargo build --workspacecargo run -p vox-arch-checkExpected: both clean (exit 0, no errors).
-
Step 0.2: Confirm doc pipeline is clean.
Run:
cargo run -p vox-doc-pipeline -- --checkExpected: clean exit. If it fails, regenerate first with
cargo run -p vox-doc-pipelineand re-run--check. -
Step 0.3: Read the spec.
Read
docs/src/architecture/2026-05-08-crate-org-followup-design.mdend-to-end before starting Task 1.
PR1 — SSOT + Descriptions + vox-mcp-meta merge
Section titled “PR1 — SSOT + Descriptions + vox-mcp-meta merge”PR1 lands all of Track A (SSOT/discoverability), the description rewrites portion of Track B, and the C1 merge. Eight tasks, single PR.
Task 1: Flip the gamify ↔ ludus directives in live policy surfaces
Section titled “Task 1: Flip the gamify ↔ ludus directives in live policy surfaces”The crate is canonical vox-gamify. Every live doc claiming vox-ludus is canonical is drift.
Files:
-
Modify:
AGENTS.md:195 -
Modify:
.cursor/rules/retired-surfaces.mdc:13 -
Modify:
.github/copilot-instructions.md:18 -
Modify:
.github/PULL_REQUEST_TEMPLATE.md:5,7,10,14 -
Modify:
contracts/proximity/retired-surfaces.v1.json:14-17 -
Step 1.1: Flip the AGENTS.md retired-surfaces row.
Read
AGENTS.mdlines 190–202. Find the row reading:| `vox-gamify` | `vox-ludus` |Replace with:
| `vox-ludus` | `vox-gamify` | -
Step 1.2: Flip the .cursor rule row.
In
.cursor/rules/retired-surfaces.mdc:13, apply the same flip as step 1.1. -
Step 1.3: Flip the copilot instructions line.
In
.github/copilot-instructions.md, find:Use `vox-ludus`, NOT `vox-gamify`.Replace with:
Use `vox-gamify`, NOT `vox-ludus`. -
Step 1.4: Update the PR template gamify references.
Read
.github/PULL_REQUEST_TEMPLATE.md(whole file).- Line 5: change
## Ludus / gamify (if applicable)to## Gamify (if applicable). - Line 7: rephrase the body around
vox-gamify(preserve any archive doc reference, just replace the crate name). - Line 10: change
Ludus section if new VOX_LUDUS_*toGamify section if new VOX_LUDUS_*(env-var prefix unchanged). - Line 14: change
cargo test -p vox-ludustocargo test -p vox-gamify.
- Line 5: change
-
Step 1.5: Flip the proximity contract JSON.
In
contracts/proximity/retired-surfaces.v1.jsonlines 14–17, find the entry:{"retired_symbol": "vox-gamify","canonical_replacement": "vox-ludus"}Replace with:
{"retired_symbol": "vox-ludus","canonical_replacement": "vox-gamify"} -
Step 1.6: Verify with grep.
Run:
rg "vox-ludus.*vox-gamify|Use \`vox-ludus\`" -n .cursor .github AGENTS.md contracts/proximityExpected: no matches in any live file (every match should be in
archive/or generated reports — not these paths).
Task 2: Fix gamify references in docs and crates/vox-gamify/README.md
Section titled “Task 2: Fix gamify references in docs and crates/vox-gamify/README.md”Files:
-
Modify:
crates/vox-gamify/README.md -
Modify:
docs/src/contributors/toestub-contributor-guide.md:202 -
Modify:
docs/src/reference/agent-quick-reference.md:40 -
Modify:
docs/agents/database-nomenclature.md:36,112,113 -
Modify:
docs/src/reference/clavis-ssot.md:26 -
Modify:
docs/src/reference/env-vars.md:62,66,69,73 -
Modify:
docs/src/reference/cli.md:525 -
Modify:
docs/src/reference/hitl-and-doubt.md:39 -
Modify:
docs/src/reference/mens-serving-ssot.md:19 -
Step 2.1: Rewrite
crates/vox-gamify/README.md.Read the file. Change the H1 from
# vox-ludusto# vox-gamify. Replace every othervox-ludustoken in the body withvox-gamify. Leave the user-visible CLI verbvox ludusalone if it appears (it’s a Latin alias and out of scope). -
Step 2.2: Flip the toestub contributor guide row.
In
docs/src/contributors/toestub-contributor-guide.mdline 202, flip the same way as Task 1.1. -
Step 2.3: Flip the agent-quick-reference row.
In
docs/src/reference/agent-quick-reference.mdline 40, flip the same way. -
Step 2.4: Update database-nomenclature references.
In
docs/agents/database-nomenclature.md:- Line 36: replace
vox-luduswithvox-gamify. - Lines 112–113: replace any
crates/vox-ludus/...paths withcrates/vox-gamify/.... Replacevox-ludusreferences withvox-gamify.
- Line 36: replace
-
Step 2.5: Update clavis-ssot reference.
In
docs/src/reference/clavis-ssot.md:26, replacevox-luduswithvox-gamify. -
Step 2.6: Update env-vars paths.
In
docs/src/reference/env-vars.mdlines 62, 66, 69, 73, change everycrates/vox-ludus/src/...tocrates/vox-gamify/src/.... Leave the env-var name prefixVOX_LUDUS_*alone. -
Step 2.7: Update cli.md reference.
In
docs/src/reference/cli.md:525, replacevox-luduswithvox-gamify. -
Step 2.8: Update hitl-and-doubt.md.
In
docs/src/reference/hitl-and-doubt.md:39, replacevox-luduswithvox-gamify. -
Step 2.9: Update mens-serving-ssot.md.
In
docs/src/reference/mens-serving-ssot.md:19, replacevox-luduswithvox-gamify. -
Step 2.10: Verify all gamify references.
Run:
rg "vox-ludus" docs/src docs/agents crates/vox-gamify --files-without-match docs/src/archive contracts/reports CHANGELOG.mdExpected: zero results outside the allowed exemptions (archive/, generated reports, CHANGELOG history).
Task 3: Fix other retired-form directives (Track A2)
Section titled “Task 3: Fix other retired-form directives (Track A2)”Files:
-
Modify:
docs/src/contributors/coding-agents.md:20 -
Modify:
docs/src/reference/ref-decorators.md:17-30 -
Modify:
docs/src/reference/ref-syntax.md:174,178 -
Modify:
docs/src/reference/ref-type-system.md:87 -
Modify:
docs/src/reference/vox-db-language-surface.md:19-21 -
Modify:
docs/src/reference/vox-fullstack-artifacts.md:20,33 -
Modify:
docs/src/reference/orchestration-unified.md:25 -
Modify:
docs/src/reference/hitl-and-doubt.md:32 -
Modify:
docs/src/.well-known/llms-full.txt:38 -
Step 3.1: Update coding-agents.md vox-dei reference.
In
docs/src/contributors/coding-agents.md:20, replace:`vox-dei` is now a small HITL crate, not the orchestratorwith:
`vox-dei` was retired; the orchestrator is `vox-orchestrator`. -
Step 3.2: Unify decorator references in ref-decorators.md.
In
docs/src/reference/ref-decorators.mdlines 17–30, replace any standalone@server/@query/@mutationdecorator descriptions with the unified@endpoint(kind: server|query|mutation)form perAGENTS.md:198. Preserve any route-mapping table. -
Step 3.3: Update ref-syntax.md examples.
In
docs/src/reference/ref-syntax.md:- Line 174: change
@query fn …to@endpoint(kind: query) fn …. - Line 178: change
@mutation fn …to@endpoint(kind: mutation) fn ….
- Line 174: change
-
Step 3.4: Update ref-type-system.md example.
In
docs/src/reference/ref-type-system.md:87, change@server fn update_task(...)to@endpoint(kind: server) fn update_task(...). Also change any->totoif the surrounding examples use thetoarrow form (verify by reading the surrounding 10 lines first). -
Step 3.5: Update vox-db-language-surface decorator rows.
In
docs/src/reference/vox-db-language-surface.mdlines 19–21, replace the three rows recommending@query fn,@mutation fn,@server fnwith rows recommending@endpoint(kind: query),@endpoint(kind: mutation),@endpoint(kind: server)respectively. Preserve route-mapping columns. -
Step 3.6: Update vox-fullstack-artifacts.md.
In
docs/src/reference/vox-fullstack-artifacts.mdlines 20 and 33, replace@server fnwith@endpoint(kind: server). -
Step 3.7: Update orchestration-unified.md.
In
docs/src/reference/orchestration-unified.md:25, drop thevox-dei-dmention. The daemon isvox-orchestrator-d. Replace inline. -
Step 3.8: Update hitl-and-doubt.md ResolutionAgent reference.
In
docs/src/reference/hitl-and-doubt.md:32, the line saysResolutionAgent (from the vox-dei crate). Thevox-deicrate no longer exists. Verify the actual home by grepping forResolutionAgentincrates/:rg "struct ResolutionAgent|impl ResolutionAgent|pub struct ResolutionAgent" crates/Update the doc with the actual crate path (likely
vox-orchestrator::dei_shim). IfResolutionAgentno longer exists, drop the parenthetical. -
Step 3.9: Update llms-full.txt vox-ars line.
In
docs/src/.well-known/llms-full.txt:38, replace:`vox-ars` → replaced by `vox-skills`with:
`vox-ars` → `vox-ars-runtime` (now `vox-openclaw-runtime`)This matches
AGENTS.md:194.
Task 4: Fix crate-name drift (vox-pm → vox-package, vox-mens → vox-ml-cli, etc.)
Section titled “Task 4: Fix crate-name drift (vox-pm → vox-package, vox-mens → vox-ml-cli, etc.)”Files:
-
Modify:
docs/agents/cli-toolchain.md:18,20,22,24,46,48 -
Modify:
docs/agents/database-nomenclature.md:21 -
Modify:
docs/agents/orchestrator.md:60 -
Modify:
docs/agents/script-registry.json:58 -
Modify:
docs/src/reference/env-vars.md:15,34 -
Modify:
docs/src/reference/cli.md:24,33,48,85,223,566-570 -
Modify:
docs/src/reference/changelog.md:46 -
Modify:
docs/src/reference/mens-serving-ssot.md:19 -
Modify:
docs/src/reference/vox-portability-ssot.md:40,115 -
Modify:
README.md:71 -
Modify:
crates/vox-db/README.md:3 -
Step 4.1: Update cli-toolchain.md row by row.
Read
docs/agents/cli-toolchain.mdlines 1–60.- Line 18: split the conflated row “vox-compiler (Codegen, SSG)” into separate rows for
vox-compiler,vox-codegen,vox-ssg. - Line 20: change
vox-pm/tovox-package/. - Line 22: change
vox-tensor/description “Burn-based ML training” to “Pure-CPU JSONL data loaders / training-pair types (Burn extracted 2026-05-08)”. - Line 24: change
vox-toestub/tovox-code-audit/. - Line 46: drop the
vox train --nativerow (Burn removed; this command does not exist). - Line 48: verify
vox mens corpusis the actual subcommand by greppingcrates/vox-cli/src/commands/. If not, update.
- Line 18: split the conflated row “vox-compiler (Codegen, SSG)” into separate rows for
-
Step 4.2: Update database-nomenclature.md vox-pm row.
In
docs/agents/database-nomenclature.md:21, change every cell in thevox-pmrow:- Crate name:
vox-pm→vox-package - Path:
crates/vox-pm→crates/vox-package - Leave description text intact unless it mentions Burn / training (then replace per the same pattern).
- Crate name:
-
Step 4.3: Update orchestrator.md vox-mens reference.
In
docs/agents/orchestrator.md:60, replacevox-menswithvox-ml-cli. -
Step 4.4: Verify script-registry.json CI subcommand.
Read
docs/agents/script-registry.json:58. Verify thereplacementfield references a CI subcommand that actually exists by greppingcrates/vox-cli/src/commands/ci/:rg "no-vox-dei-import|no_vox_dei_import" crates/vox-cli/src/commands/ci/If found, leave alone. If not found, find the actual subcommand name and update.
-
Step 4.5: Update env-vars.md vox-pm references.
In
docs/src/reference/env-vars.md:- Line 15: change header
## Codex / Turso (vox-db, vox-pm)to## Codex / Turso (vox-db, vox-package). - Line 34: change
vox-pm exposes ...tovox-package exposes .... Verify the feature reference (replication = ["vox-db/replication"]) matchescrates/vox-package/Cargo.toml:11.
- Line 15: change header
-
Step 4.6: Update cli.md crate references.
In
docs/src/reference/cli.md:- Line 24: in the section about specialized domains, leave the user-visible CLI verb
vox mensalone, but if the binary namevox-mensappears, change tovox-ml-cli. - Line 33: same pattern.
- Line 48: same.
- Line 85: change header
## Package management (vox-pm)to## Package management (vox-package). - Line 223: change
vox-pmtovox-package. - Lines 566–570: change
vox-mens-...tovox-ml-cli-....
- Line 24: in the section about specialized domains, leave the user-visible CLI verb
-
Step 4.7: Update changelog reference.
In
docs/src/reference/changelog.md:46, changevox-pm/README.mdtovox-package/README.md. -
Step 4.8: Update mens-serving-ssot vox-runtime reference.
In
docs/src/reference/mens-serving-ssot.md:19, replacevox-runtime(which doesn’t exist) with the canonical pair:vox-actor-runtime/vox-workflow-runtime. Surrounding context determines which. -
Step 4.9: Update vox-portability-ssot.md.
In
docs/src/reference/vox-portability-ssot.mdlines 40 and 115, changevox-pmtovox-package. -
Step 4.10: Update README.md vox-mens row.
In
README.md:71, decide: ifvox-mensis a plugin distribution name (external), document thevox-mensplugin →vox-ml-clibinary mapping in the same row. If it’s a stale internal reference, replace withvox-ml-cli. Default to documenting the mapping (preserves user-facing surface). -
Step 4.11: Update vox-db README.
In
crates/vox-db/README.md:3, changeWraps vox-pm::CodeStoretoWraps vox-package::CodeStore. -
Step 4.12: Add ADR footnotes.
ADR files
docs/src/adr/004-codex-arca-turso-ssot.mdanddocs/src/adr/015-vox-docker-oci-portability-ssot.mdreferencevox-pmhistorically. Don’t rewrite the ADR body, but at the bottom of each file add a one-line note:> Nomenclature note (2026-05-08): `vox-pm` was renamed to `vox-package`; references in this ADR are historical. -
Step 4.13: Verify name drift is gone.
Run:
rg "vox-pm\b|vox-mens\b" docs/src docs/agents README.md crates/vox-db/README.md --files-without-match docs/src/archive docs/src/adr docs/src/reference/changelog.mdExpected: zero matches outside ADRs and changelog.
Task 5: Fix layers.toml comment + the two narration docs
Section titled “Task 5: Fix layers.toml comment + the two narration docs”Files:
-
Modify:
docs/src/architecture/layers.toml:135(comment in known_inversions) -
Modify:
docs/src/architecture/2026-05-08-workspace-reorg-outcome.md(top of file) -
Modify:
docs/src/architecture/2026-05-08-naming-and-guards-design.md(top of file) -
Step 5.1: Fix the layers.toml inversion-reason comment.
Read
docs/src/architecture/layers.toml:135and the surrounding[[known_inversions]]block. The comment mentions “vox dei” as a CLI subcommand. Verify by:rg "Subcommand|fn dei|name = \"dei\"" crates/vox-cli/src/commands/dei.rsIf
deiexists, leave alone. If not, replacevox deiwith the actual subcommand name in the comment. -
Step 5.2: Add a one-line note to workspace-reorg-outcome.md.
At the top of
docs/src/architecture/2026-05-08-workspace-reorg-outcome.md, immediately after the H1, add a blockquote:> **Naming note (2026-05-08):** The CI guard binary referenced as `vox-layer-check` in this narration was renamed to `vox-arch-check` later in the same series; references below are historical. -
Step 5.3: Add the same note to naming-and-guards-design.md.
At the top of
docs/src/architecture/2026-05-08-naming-and-guards-design.md, immediately after the H1, add the identical blockquote from step 5.2.
Task 6: Expand where-things-live.md to cover all 83 crates
Section titled “Task 6: Expand where-things-live.md to cover all 83 crates”Files:
-
Modify:
docs/src/architecture/where-things-live.md -
Step 6.1: Read current contents and the layers.toml to align.
Read
docs/src/architecture/where-things-live.mdend-to-end anddocs/src/architecture/layers.tomlend-to-end. Note: the table is grouped in two sections — “Quick reference: subsystem → crate” and “Plugins”. Plugins live at L4. -
Step 6.2: Replace the “Quick reference” section with a layer-grouped table.
Restructure the “Quick reference: subsystem → crate” table so it covers every L0/L1/L2/L3/L5 entry from
layers.toml. Use this exact structure (one section per layer, alphabetical within section). Each row is| Crate | One-line scope |. For the scope column, use the description from the spec’s Track-B description table where one is provided; otherwise read the crate’slib.rsfirst 30 lines and write a one-sentence summary.## Quick reference: subsystem → crate (by layer)### L0 — pure types| Crate | One-line scope ||---|---|| [`vox-arch-check`](../../../crates/vox-arch-check/) | CI guard binary; enforces layers.toml. || [`vox-db-types`](../../../crates/vox-db-types/) | Pure-data L0 leaf for vox-db: row types, IDs, schema descriptors. || [`vox-mesh-types`](../../../crates/vox-mesh-types/) | Pure-data mesh transport types. || [`vox-orchestrator-types`](../../../crates/vox-orchestrator-types/) | Pure-data L0 leaf for vox-orchestrator: agent/task IDs, file affinity, switch actions, provider catalogs. || [`vox-primitives`](../../../crates/vox-primitives/) | Pure-data primitives shared workspace-wide. || [`vox-protocol`](../../../crates/vox-protocol/) | Daemon wire-protocol pure-data types. || [`workspace-hack`](../../../crates/workspace-hack/) | Cargo-hakari unification crate; do not edit by hand. |### L1 — primitives & utilities... (every L1 crate)### L2 — domain libraries... (every L2 crate)### L3 — heavy runtimes... (every L3 crate)### L5 — surfaces... (every L5 crate)For each crate not in the spec’s description table, read its
lib.rsfirst 30 lines and the Cargo.tomldescription(if present after PR1’s description rewrites land — which they do in Task 7 below, so do Task 6 AFTER Task 7 completes for the description-rich rows). If the description is missing, write a one-sentence summary based on the lib.rs docstring. -
Step 6.3: Replace the “Plugins” section with a complete L4 list.
Section structure:
## Plugins (L4 — cdylib only; never compile-time deps for L0..L3)| Plugin crate | Provides ||---|---|| [`vox-plugin-browser`](../../../crates/vox-plugin-browser/) | (read lib.rs first line) || [`vox-plugin-catalog`](../../../crates/vox-plugin-catalog/) | (read lib.rs first line) || [`vox-plugin-cloud`](../../../crates/vox-plugin-cloud/) | (read lib.rs first line) || [`vox-plugin-grammar-export`](../../../crates/vox-plugin-grammar-export/) | (read lib.rs first line) || [`vox-plugin-mens-candle-cuda`](../../../crates/vox-plugin-mens-candle-cuda/) | (existing) || [`vox-plugin-nvml-probe`](../../../crates/vox-plugin-nvml-probe/) | (read lib.rs first line) || [`vox-plugin-oratio`](../../../crates/vox-plugin-oratio/) | (existing) || [`vox-plugin-oratio-mic`](../../../crates/vox-plugin-oratio-mic/) | (existing) || [`vox-plugin-populi-mesh`](../../../crates/vox-plugin-populi-mesh/) | (read lib.rs first line) || [`vox-plugin-publication`](../../../crates/vox-plugin-publication/) | (read lib.rs first line) || [`vox-plugin-runtime-container`](../../../crates/vox-plugin-runtime-container/) | (existing) || [`vox-plugin-runtime-wasm`](../../../crates/vox-plugin-runtime-wasm/) | (existing) || [`vox-plugin-script-execution`](../../../crates/vox-plugin-script-execution/) | (read lib.rs first line) || [`vox-plugin-webhook`](../../../crates/vox-plugin-webhook/) | (read lib.rs first line) |Replace each
(read lib.rs first line)with the actual one-line summary from that crate’slib.rs. -
Step 6.4: Update the “When to NOT add a new crate” footer.
Add a paragraph noting the binary-tool exception:
### Binary-only toolsCrates with `kind = "binary"` in `layers.toml` (e.g., `vox-arch-check`, `vox-ml-cli`, `vox-orchestrator-d`) don't need a `[workspace.dependencies]` entry in the root `Cargo.toml` — they're consumed via `cargo run -p <name>`, not as library dependencies. The "Add a new workspace crate" instruction below applies to libraries only.Adjust the existing instruction at the bottom to reference this exception.
-
Step 6.5: Verify coverage.
Run a quick sanity check by counting crates referenced in the doc vs. layers.toml:
rg "crates/vox-" docs/src/architecture/where-things-live.md | rg -o "vox-[a-z0-9-]+" | sort -u | wc -lExpected: ≥80 (some crates may be referenced multiple times; the number of unique names should match the layers.toml count of 79 + workspace-hack).
Task 7: Rewrite stale Cargo.toml descriptions and vox-corpus lib.rs docstring
Section titled “Task 7: Rewrite stale Cargo.toml descriptions and vox-corpus lib.rs docstring”Files (one-line description = field rewrite per crate):
-
crates/vox-orchestrator/Cargo.toml:3 -
crates/vox-orchestrator-types/Cargo.toml -
crates/vox-package/Cargo.toml -
crates/vox-actor-runtime/Cargo.toml -
crates/vox-cli-core/Cargo.toml -
crates/vox-crypto/Cargo.toml -
crates/vox-db/Cargo.toml -
crates/vox-db-types/Cargo.toml -
crates/vox-doc-pipeline/Cargo.toml -
crates/vox-eval/Cargo.toml -
crates/vox-grammar-export/Cargo.toml -
crates/vox-identity/Cargo.toml -
crates/vox-integration-tests/Cargo.toml -
crates/vox-lsp/Cargo.toml -
crates/vox-protocol/Cargo.toml -
crates/vox-scientia-ingest/Cargo.toml -
crates/vox-ssg/Cargo.toml -
crates/vox-tensor/Cargo.toml -
crates/vox-test-harness/Cargo.toml -
crates/vox-corpus/src/lib.rs(docstring only; description is separate) -
Step 7.1: Rewrite the
vox-orchestratordescription.Read
crates/vox-orchestrator/Cargo.tomllines 1–10. Replace the existingdescription = "Multi-agent file-affinity queue system..."with:description = "Slim coordinator for the multi-agent file-affinity router; queue/lock/oplog live in vox-orchestrator-queue, MCP tools in vox-orchestrator-mcp." -
Step 7.2: Add descriptions to the other 18 crates.
For each crate listed below, open
crates/<name>/Cargo.tomland add (or replace) thedescription =field directly under thename = ...line. Verify the crate’s actual scope by readingcrates/<name>/src/lib.rsfirst 30 lines before applying — if the suggested description does not match reality, prefer accuracy.Use these exact descriptions:
Crate Description vox-orchestrator-typesPure-data L0 leaf for vox-orchestrator: agent/task IDs, file affinity, switch actions, provider catalogs.vox-packageVox package manager: Vox.toml manifests, vox.lock, content-addressed artifact cache, registry client, dependency resolver.vox-actor-runtimeProcess-oriented runtime: actors, mailboxes, supervision, scheduling, LLM/Mens activity primitives.vox-cli-coreShared internals for the vox CLI binary (argv parsing helpers, exit-code policy).vox-cryptoPure-Rust crypto primitives (chacha20poly1305 AEAD, ed25519, x25519); sole crypto SSOT per AGENTS.md §Cryptography Policy.vox-dbCodex / VoxDb facade: schema migrations, store ops, Turso/libSQL access for the Vox workspace.vox-db-typesPure-data L0 leaf for vox-db: row types, IDs, schema descriptors.vox-doc-pipelineDoc generator: regenerates SUMMARY.md, architecture-index.md, feed.xml from frontmatter.vox-evalVox expression evaluator (interpreter for vox run --interp).vox-grammar-exportExports the Vox grammar artifact for downstream tooling.vox-identityIdentity primitives: signing keys, trust ledger entries.vox-integration-testsCross-crate integration test harness (test-only L5).vox-lspVox Language Server (stdio JSON-RPC).vox-protocolDaemon wire-protocol pure-data types.vox-scientia-ingestScientia corpus ingestion.vox-ssgStatic site generator for the Vox docs surface.vox-tensorPure-CPU JSONL data loaders / training-pair types (Burn extracted 2026-05-08).vox-test-harnessShared test fixtures and harness primitives.Standard placement (matches existing crates):
[package]name = "vox-foo"description = "..."version.workspace = trueedition.workspace = true -
Step 7.3: Update vox-corpus lib.rs docstring.
Read
crates/vox-corpus/src/lib.rsfirst 30 lines. The current docstring claimsvox-corpusis “training SSOT for Mens” but the module set is broader:training/,mcp_meta/,synthetic_search_gen/,tool_workflow_corpus/,codegen_vox/. Replace the leading//!block with one accurate sentence://! Corpus crate for the Vox workspace: aggregates training data, MCP meta corpora,//! synthetic-search generators, tool-workflow corpora, and codegen-Vox samples.//! Used by `vox-ml-cli` and downstream training pipelines. -
Step 7.4: Verify with cargo metadata.
Run:
cargo metadata --no-deps --format-version 1 | rg "\"name\":\"vox-orchestrator\"" -A 1Expected: the
descriptionfield is the new one from step 7.1.Run a broader check:
cargo metadata --no-deps --format-version 1 | rg "\"description\":null,\"name\":\"vox-"Expected: zero null descriptions for the 19 crates above (other crates may still have null until PR6 lints).
Task 8: Add binary-layer paragraph to layers.toml header
Section titled “Task 8: Add binary-layer paragraph to layers.toml header”Files:
-
Modify:
docs/src/architecture/layers.toml(header comment, ~lines 1–22) -
Step 8.1: Add the binary-tool exception note.
Read
docs/src/architecture/layers.tomllines 1–25. Insert a new paragraph in the header comment block, immediately before the[guards]table:# Binary-tool exception: a `kind = "binary"` crate at any layer is a *tool*# (e.g., vox-arch-check, vox-ml-cli, vox-orchestrator-d) consumed via# `cargo run -p <name>` rather than as a library dep. Such crates are exempt# from the orphan rule and from the convention that workspace surfaces sit at L5.# Only product-shipped binaries (the user-visible CLI surface) live at L5.Place the new comment block so it reads naturally between the layer-list comment and the
[guards]section.
Task 9: Merge vox-mcp-meta into vox-mcp-registry (C1)
Section titled “Task 9: Merge vox-mcp-meta into vox-mcp-registry (C1)”Files:
-
Read:
crates/vox-mcp-meta/src/lib.rs(entire file — it’s small) -
Modify:
crates/vox-mcp-registry/src/lib.rs(add re-exports) -
Modify:
crates/vox-mcp-registry/Cargo.toml(any new deps if vox-mcp-meta had them) -
Delete:
crates/vox-mcp-meta/(entire directory) -
Modify:
Cargo.toml([workspace.dependencies]— remove thevox-mcp-metaline) -
Modify:
docs/src/architecture/layers.toml(remove thevox-mcp-meta = ...line) -
Modify: every consumer’s
Cargo.tomland source that importsvox_mcp_meta::* -
Step 9.1: Read
vox-mcp-metato understand what it exports.Read
crates/vox-mcp-meta/src/lib.rsandcrates/vox-mcp-meta/Cargo.toml. The crate is ~62 LoC; the agent audit found it re-exportsvox-mcp-registry::TOOL_REGISTRYplus 4 static&[&str]constants. Document the exact symbols you’ll need to re-home. -
Step 9.2: Find every consumer.
Run:
rg "vox_mcp_meta|vox-mcp-meta" --type rust --type toml -lSave the file list.
-
Step 9.3: Move the symbols into
vox-mcp-registry.Copy each public symbol from
vox-mcp-meta/src/lib.rstovox-mcp-registry/src/lib.rs. Preserve the public interface exactly (same names, same types, samepubvisibility). -
Step 9.4: Update consumer imports.
For every file in step 9.2’s list that uses
vox_mcp_meta::X, change the import tovox_mcp_registry::X. For everyCargo.tomlthat has avox-mcp-meta = ...dep, replace it withvox-mcp-registry = ...(deduplicate ifvox-mcp-registryis already there). -
Step 9.5: Remove the workspace dep.
In root
Cargo.toml[workspace.dependencies], delete the line:vox-mcp-meta = { path = "crates/vox-mcp-meta" } -
Step 9.6: Remove the layer entry.
In
docs/src/architecture/layers.toml, delete the row:vox-mcp-meta = { layer = 2 } -
Step 9.7: Delete the crate directory.
Remove the
crates/vox-mcp-meta/directory entirely. From the workspace root:Remove-Item -Recurse -Force crates/vox-mcp-meta(PowerShell — bash equivalent:
rm -rf crates/vox-mcp-meta.) -
Step 9.8: Build and verify.
Run:
cargo build --workspacecargo run -p vox-arch-checkBoth must be clean.
Task 10: PR1 verification, regenerate auto-generated docs, and commit
Section titled “Task 10: PR1 verification, regenerate auto-generated docs, and commit”-
Step 10.1: Regenerate auto-generated docs.
Run:
cargo run -p vox-doc-pipelineThis regenerates
docs/src/SUMMARY.md,docs/src/architecture/architecture-index.md,docs/src/feed.xml. Do NOT hand-edit them per CLAUDE.md.If
vox-doc-pipelinefinds frontmatter issues in the docs you edited (Task 1–8), fix them in the source markdown and re-run. -
Step 10.2: Sync ignore files.
Run:
cargo run -p vox-cli -- ci sync-ignore-filesExpected: no diff (we didn’t touch
.voxignore). -
Step 10.3: Run final verification.
Run all in sequence:
cargo build --workspacecargo run -p vox-arch-checkcargo run -p vox-doc-pipeline -- --checkcargo test --workspace --no-runAll must succeed. If a test fails to compile, investigate and fix before commit.
-
Step 10.4: Commit.
Stage everything explicitly (no
git add -A— see CLAUDE.md / Bash safety):git add AGENTS.md .cursor .github contracts/proximity crates/vox-gamify/README.mdgit add docs/src/contributors docs/src/reference docs/agents docs/src/.well-knowngit add docs/src/architecture/where-things-live.md docs/src/architecture/layers.tomlgit add docs/src/architecture/2026-05-08-workspace-reorg-outcome.mdgit add docs/src/architecture/2026-05-08-naming-and-guards-design.mdgit add Cargo.toml crates/vox-orchestrator/Cargo.tomlgit add crates/vox-orchestrator-types/Cargo.toml crates/vox-package/Cargo.tomlgit add crates/vox-actor-runtime/Cargo.toml crates/vox-cli-core/Cargo.tomlgit add crates/vox-crypto/Cargo.toml crates/vox-db/Cargo.tomlgit add crates/vox-db-types/Cargo.toml crates/vox-doc-pipeline/Cargo.tomlgit add crates/vox-eval/Cargo.toml crates/vox-grammar-export/Cargo.tomlgit add crates/vox-identity/Cargo.toml crates/vox-integration-tests/Cargo.tomlgit add crates/vox-lsp/Cargo.toml crates/vox-protocol/Cargo.tomlgit add crates/vox-scientia-ingest/Cargo.toml crates/vox-ssg/Cargo.tomlgit add crates/vox-tensor/Cargo.toml crates/vox-test-harness/Cargo.tomlgit add crates/vox-corpus/src/lib.rs crates/vox-db/README.mdgit add crates/vox-mcp-registry/ docs/src/SUMMARY.mdgit add docs/src/architecture/architecture-index.md docs/src/feed.xmlgit add docs/src/adr/004-codex-arca-turso-ssot.mdgit add docs/src/adr/015-vox-docker-oci-portability-ssot.mdgit rm -r crates/vox-mcp-metagit commit -m "$(cat <<'EOF'refactor(docs+crates): SSOT/discoverability fixes + crate descriptions + vox-mcp-meta mergePR1 of crate-org-followup-2026:- Fix inverted gamify/ludus directives in 12 live policy surfaces.- Fix retired-form (vox-pm, vox-mens, @server fn, vox-dei, ResolutionAgent) references in ~25 docs.- Expand where-things-live.md to cover all 83 workspace crates by layer.- Add canonical descriptions to 19 crates that had none.- Rewrite stale vox-orchestrator description (post-Phase-5).- Update vox-corpus lib.rs docstring to match actual scope.- Add binary-tool exception note to layers.toml.- Merge vox-mcp-meta (62 LoC of re-exports) into vox-mcp-registry.Spec: docs/src/architecture/2026-05-08-crate-org-followup-design.mdEOF)" -
Step 10.5: Push and open PR.
git push -u origin HEADgh pr create --title "refactor: SSOT/discoverability fixes + crate descriptions + vox-mcp-meta merge" --body "$(cat <<'EOF'## Summary- PR1 of [2026-05-08 crate-org-followup](./2026-05-08-crate-org-followup-design.md).- Fixes SSOT drift across ~37 live docs + 19 missing Cargo.toml descriptions.- Merges vox-mcp-meta into vox-mcp-registry.## Test plan- [x] cargo build --workspace clean- [x] cargo run -p vox-arch-check clean- [x] cargo run -p vox-doc-pipeline -- --check clean- [x] cargo test --workspace --no-run cleanEOF)"
PR2 — Split vox-package into vox-package-types (L1) + vox-package (L3)
Section titled “PR2 — Split vox-package into vox-package-types (L1) + vox-package (L3)”Removes both documented layer inversions (vox-package → vox-compiler, vox-package → vox-db).
Task 11: Survey vox-package and identify the type-only surface
Section titled “Task 11: Survey vox-package and identify the type-only surface”Files:
-
Read:
crates/vox-package/src/lib.rs -
Read:
crates/vox-package/src/manifest.rs -
Read:
crates/vox-package/src/lockfile.rs -
Read:
crates/vox-package/src/package_kind.rs -
Read:
crates/vox-package/src/registry.rs -
Read:
crates/vox-package/src/resolver/(whole subdir) -
Read:
crates/vox-package/src/artifact_cache.rs -
Read:
crates/vox-package/src/workspace.rs -
Step 11.1: Read every vox-package source file and classify each.
For each file, decide: type-only (no async, no DB, no compiler — moves to L1) or build-runtime (stays in L3). Record the classification in a working note.
The audit suggests these are pure-data L1 candidates:
manifest.rs(Vox.toml manifest types)lockfile.rs(vox.lock types)package_kind.rs(package_kind enum)resolver/types only (the resolver request/response structs; not the implementation)
These stay L3:
artifact_cache.rs(DB-backed cache)registry.rs(HTTP client)resolver/implementation (calls compiler)workspace.rs(uses vox-db)bin/,deploy_coolify.rs
Verify by reading each file.
Task 12: Create the new vox-package-types crate
Section titled “Task 12: Create the new vox-package-types crate”Files:
-
Create:
crates/vox-package-types/Cargo.toml -
Create:
crates/vox-package-types/src/lib.rs -
Step 12.1: Scaffold the new crate.
Create
crates/vox-package-types/Cargo.toml:[package]name = "vox-package-types"description = "Pure-data L1 leaf for vox-package: Vox.toml manifest types, vox.lock types, package_kind enum, resolver request/response types."version.workspace = trueedition.workspace = true[dependencies]serde = { workspace = true, features = ["derive"] }serde_json = { workspace = true }toml = { workspace = true }thiserror = { workspace = true }semver = { workspace = true }workspace-hack = { workspace = true }[lints]workspace = trueCreate
crates/vox-package-types/src/lib.rs://! Pure-data L1 leaf for vox-package: Vox.toml manifest types, vox.lock//! types, package_kind enum, resolver request/response types. No async,//! no DB, no compiler dependency. -
Step 12.2: Add to workspace.
In root
Cargo.toml[workspace.dependencies], add (alphabetical order):vox-package-types = { path = "crates/vox-package-types" }In
docs/src/architecture/layers.toml, add to the L1 section (alphabetical):vox-package-types = { layer = 1 }
Task 13: Move type-only modules from vox-package to vox-package-types
Section titled “Task 13: Move type-only modules from vox-package to vox-package-types”-
Step 13.1: Move manifest, lockfile, package_kind.
For each of
manifest.rs,lockfile.rs,package_kind.rs:- Move the file from
crates/vox-package/src/<name>.rstocrates/vox-package-types/src/<name>.rs. - Remove any non-pure-data imports (anything that pulls
tokio,vox-db,vox-compiler). - Add a
mod <name>; pub use <name>::*;line incrates/vox-package-types/src/lib.rs.
- Move the file from
-
Step 13.2: Move resolver type definitions.
Read
crates/vox-package/src/resolver/. Identify which files are type-only (request/response/error types) vs. implementation (HTTP/DB calls). Move only the type files intocrates/vox-package-types/src/resolver/. The implementation stays. -
Step 13.3: Update vox-package to depend on vox-package-types.
In
crates/vox-package/Cargo.toml[dependencies], add:vox-package-types = { workspace = true }Remove unused deps that were only there for the type files (e.g., if
semveris no longer needed in vox-package after the move).In
crates/vox-package/src/lib.rs, replace the oldmod manifest; mod lockfile; ...lines with re-exports from the new types crate:pub use vox_package_types::{manifest, lockfile, package_kind, resolver as resolver_types}; -
Step 13.4: Update internal
vox-packagesource imports.Inside
crates/vox-package/src/, everyuse crate::manifest::...becomesuse vox_package_types::manifest::.... Same forlockfile::,package_kind::,resolver::types::. -
Step 13.5: Update external callers.
Run:
rg "use vox_package::(manifest|lockfile|package_kind|resolver::(types|Request|Response|Error))" --type rustEach caller may either:
- Continue using
vox_package::manifest::...(works because of the re-export in lib.rs); or - Switch to
vox_package_types::manifest::...directly (slightly faster compile because L1 crates compile sooner).
For now, prefer not switching callers; just keep the re-export. Fewer files to touch in this PR. The lint in PR6 won’t penalize either form.
- Continue using
-
Step 13.6: Build and verify the split compiles.
Run:
cargo build -p vox-package-typescargo build -p vox-packagecargo build --workspaceAll clean.
Task 14: Remove the known_inversions for vox-package
Section titled “Task 14: Remove the known_inversions for vox-package”-
Step 14.1: Verify the inversion is gone.
Run:
cargo run -p vox-arch-checkAt this point, the strict layer-check will still pass because the inversions are still listed in
[[known_inversions]]. We need to verify that they’re now unused (i.e., vox-package no longer needs them). To check this, temporarily remove them and re-run. -
Step 14.2: Remove both inversion entries.
In
docs/src/architecture/layers.toml, delete both:[[known_inversions]]from = "vox-package"to = "vox-compiler"reason = "..."[[known_inversions]]from = "vox-package"to = "vox-db"reason = "..." -
Step 14.3: Verify strict layer-check still passes.
Run:
cargo run -p vox-arch-checkMust be clean. If it fails: vox-package still has a transitive edge to vox-compiler or vox-db at L3 that violates layering. If so, the inversion was real — restore the entry, but document why and revisit splitting in a follow-up.
Expected case: vox-package is now L3 and depends on L3 (vox-db, vox-compiler). That’s allowed (within-layer). The split removed the L1-or-lower → L3 edge.
Wait — re-read layers.toml. vox-package was originally L2, NOT L1. If vox-package is at L2 with deps to vox-db (L3) and vox-compiler (L3), the inversions exist because L2→L3 is going UP. Verify the current layer assignment: does the
[crates]table still listvox-package = { layer = 2 }?If yes: split’s effect is to pull manifest/lockfile/package_kind out as L1, but leave vox-package at L2 with the same L2→L3 edges. The inversions remain. Fix by: moving vox-package itself to L3 in
layers.toml, since it now does runtime work (DB, compiler-driver). The L1 split (vox-package-types) is the new pure-data home. -
Step 14.4: Re-tier vox-package to L3.
In
docs/src/architecture/layers.toml, move thevox-packageentry from the L2 section to the L3 section. Keep the layer-2 entry deleted; insert at L3 alphabetically. Update its annotation:vox-package = { layer = 3 } -
Step 14.5: Re-run arch-check.
cargo run -p vox-arch-checkMust be clean now.
Task 15: PR2 verification and commit
Section titled “Task 15: PR2 verification and commit”-
Step 15.1: Full verification.
cargo build --workspacecargo run -p vox-arch-checkcargo test -p vox-package -p vox-package-typescargo run -p vox-doc-pipeline -- --checkAll clean.
-
Step 15.2: Add a row to where-things-live.md.
In
docs/src/architecture/where-things-live.mdL1 section (added in Task 6), insert (alphabetical):| [`vox-package-types`](../../../crates/vox-package-types/) | Pure-data L1 leaf for vox-package: manifest, lockfile, package_kind, resolver types. |Verify the L3 row for
vox-packageis in the L3 section (Task 6 may have placed it under L2 — move it). -
Step 15.3: Commit.
git add crates/vox-package-types crates/vox-packagegit add Cargo.toml docs/src/architecture/layers.tomlgit add docs/src/architecture/where-things-live.mdgit commit -m "$(cat <<'EOF'refactor(vox-package): split into vox-package-types (L1) + vox-package (L3)Removes both documented layer inversions (vox-package → vox-compiler,vox-package → vox-db) by moving manifest/lockfile/package_kind/resolvertype definitions to a new pure-data L1 crate. vox-package itself movesfrom L2 to L3 to reflect its actual runtime scope.Spec: docs/src/architecture/2026-05-08-crate-org-followup-design.md (C2)EOF)"
PR3 — Extract vox-cli-ci (C3) + side-quest
Section titled “PR3 — Extract vox-cli-ci (C3) + side-quest”Task 16: Survey vox-cli/src/commands/ci/
Section titled “Task 16: Survey vox-cli/src/commands/ci/”Files:
-
Read:
crates/vox-cli/src/commands/ci/(whole subdir) -
Read:
crates/vox-cli/src/commands/mod.rs -
Read:
crates/vox-cli/Cargo.toml -
Step 16.1: List the ci/ subdir contents.
Run:
Get-ChildItem -Recurse crates/vox-cli/src/commands/ci/ | Select-Object FullNameNote: there are likely many files (the audit found ~17.3K LoC). Identify the top-level dispatcher (probably
mod.rs) and the public entry point. -
Step 16.2: Identify deps used only inside ci/.
Run:
rg "use crate::|use super::|use vox_" crates/vox-cli/src/commands/ci/ --type rustBucket each import:
use crate::commands::ci::...(intra-ci) — fine, will move with the codeuse crate::commands::other::...(cross-cutting; need to expose those publicly or copy into vox-cli-ci)use vox_<other>::...(workspace dep — record for the new crate’s Cargo.toml)use std::.../ external (record but no action)
-
Step 16.3: Read the ci-command registration in
commands/mod.rs.Find the dispatcher that routes
vox ci <subcommand>. Note the public function name (likely something likedispatch_ci(args: ...) -> Result<...>).
Task 17: Create the vox-cli-ci crate skeleton
Section titled “Task 17: Create the vox-cli-ci crate skeleton”Files:
-
Create:
crates/vox-cli-ci/Cargo.toml -
Create:
crates/vox-cli-ci/src/lib.rs -
Step 17.1: Scaffold.
Create
crates/vox-cli-ci/Cargo.toml:[package]name = "vox-cli-ci"description = "vox CLI 'ci' subcommand dispatcher and implementations (sync-ignore-files, secret-env-guard, generate-plugin-catalog-docs, etc.)."version.workspace = trueedition.workspace = true[dependencies]# Add deps from Step 16.2 here. At minimum:clap = { workspace = true }anyhow = { workspace = true }tokio = { workspace = true }workspace-hack = { workspace = true }# plus every vox-* dep used inside ci/[lints]workspace = trueCreate
crates/vox-cli-ci/src/lib.rs://! vox CLI `ci` subcommand: sync-ignore-files, secret-env-guard, doc-pipeline//! check, plugin-catalog generators, ssot-drift, etc. Extracted from vox-cli//! to isolate CI-only edits from the main CLI binary's incremental rebuild. -
Step 17.2: Add to workspace.
In root
Cargo.toml[workspace.dependencies]:vox-cli-ci = { path = "crates/vox-cli-ci" }In
docs/src/architecture/layers.toml(L3 section, alphabetical):vox-cli-ci = { layer = 3 }Note: this is L3, not L5. The L5 surface remains
vox-cli(the binary).vox-cli-ciis a library crate.
Task 18: Move ci/ into vox-cli-ci
Section titled “Task 18: Move ci/ into vox-cli-ci”-
Step 18.1: Move the directory.
Move
crates/vox-cli/src/commands/ci/tocrates/vox-cli-ci/src/. Preserve the internal structure.PowerShell:
Move-Item crates/vox-cli/src/commands/ci/* crates/vox-cli-ci/src/Remove-Item crates/vox-cli/src/commands/ci -Recurse -
Step 18.2: Rename the entry-point module.
If
crates/vox-cli-ci/src/mod.rswas the old dispatcher entry, rename it to a more idiomatic name likedispatch.rs(Cargo convention disfavorsmod.rsfor the crate root’s child modules in Rust 2024). Updatecrates/vox-cli-ci/src/lib.rsto match://! ... (from step 17.1)pub mod dispatch;pub use dispatch::dispatch_ci; // or whatever the original entry function is -
Step 18.3: Fix imports inside vox-cli-ci.
Every
use crate::commands::ci::...in moved files becomesuse crate::.... Everyuse crate::commands::<other>::...must be re-resolved — either:- The shared item moves with ci/ if it’s only used by ci (preferable)
- The shared item stays in vox-cli; vox-cli-ci re-imports it via a
vox-clireverse dep (NOT recommended — creates cycle) - The shared item is extracted to
vox-cli-core(which already exists at L3)
If you hit a cross-cut, prefer moving the helper to
vox-cli-core. -
Step 18.4: Update vox-cli to call vox-cli-ci.
In
crates/vox-cli/Cargo.toml, add:vox-cli-ci = { workspace = true }In
crates/vox-cli/src/commands/mod.rs, replace thepub mod ci;line with:// Moved to vox-cli-ci crate.pub use vox_cli_ci::dispatch_ci;Find the call site that dispatches
Subcommand::Ci(args)(likely incrates/vox-cli/src/main.rsor equivalent) and update it to callvox_cli_ci::dispatch_ci(args).awaitinstead of the local function. -
Step 18.5: Build and verify.
cargo build -p vox-cli-cicargo build -p vox-clicargo build --workspaceExpect compile errors at first (missing imports, name resolution). Fix iteratively. Common patterns:
- Add a missing
vox-*dep tovox-cli-ci/Cargo.toml - Re-export an internal helper as
pubinvox-cli/src/something.rsif vox-cli-ci needs it - If the same helper is needed in both: extract to
vox-cli-core
- Add a missing
-
Step 18.6: Run a smoke test.
cargo run -p vox-cli -- ci --helpcargo run -p vox-cli -- ci sync-ignore-filescargo run -p vox-cli -- ci secret-env-guardAll must produce identical output to before the extraction. If any output differs, investigate.
Task 19: Side-quest — gate vox-orchestrator-mcp behind mcp-server feature
Section titled “Task 19: Side-quest — gate vox-orchestrator-mcp behind mcp-server feature”-
Step 19.1: Find the current dep declaration.
In
crates/vox-cli/Cargo.toml, find:vox-orchestrator-mcp = { workspace = true }(or similar — it’s currently unconditional per the audit).
-
Step 19.2: Make it optional and gate it.
Change to:
vox-orchestrator-mcp = { workspace = true, optional = true }Find the
[features]section. Locate themcp-serverfeature and adddep:vox-orchestrator-mcpto its dep list:mcp-server = ["dep:vox-orchestrator-mcp", "dep:axum", "dep:rmcp"]# (preserve existing entries; just add the new dep) -
Step 19.3: Gate the call sites.
Run:
rg "vox_orchestrator_mcp" crates/vox-cli/src/ --type rustFor each occurrence outside
mod mcp_server, wrap with#[cfg(feature = "mcp-server")]or move into a feature-gated module. -
Step 19.4: Verify default build excludes vox-orchestrator-mcp.
cargo build -p vox-cli --no-default-featurescargo build -p vox-cli --features mcp-servercargo build --workspaceAll clean. Default build (no mcp-server) should NOT pull
vox-orchestrator-mcp— verify with:cargo tree -p vox-cli --no-default-features | rg "vox-orchestrator-mcp"Expected: zero matches.
Task 20: PR3 verification and commit
Section titled “Task 20: PR3 verification and commit”-
Step 20.1: Full verification.
cargo build --workspacecargo run -p vox-arch-checkcargo test -p vox-cli-ci -p vox-clicargo run -p vox-doc-pipeline -- --checkAll clean.
-
Step 20.2: Add the row to where-things-live.md.
In the L3 section, alphabetical:
| [`vox-cli-ci`](../../../crates/vox-cli-ci/) | vox CLI 'ci' subcommand dispatcher (sync-ignore-files, secret-env-guard, etc.). Extracted from vox-cli to isolate CI-only edits. | -
Step 20.3: Commit.
git add crates/vox-cli-ci crates/vox-cligit add Cargo.toml docs/src/architecture/layers.tomlgit add docs/src/architecture/where-things-live.mdgit rm -r crates/vox-cli/src/commands/ci # if not already removed by Move-Itemgit commit -m "$(cat <<'EOF'refactor(vox-cli): extract vox-cli-ci + gate vox-orchestrator-mcp behind mcp-serverExtracts the 17.3K LoC ci/ subdir from vox-cli into a dedicated vox-cli-cilibrary crate, isolating CI-only edits from the main CLI's incrementalrebuild. Side-quest: makes the vox-orchestrator-mcp dep optional behind themcp-server feature, so default CLI builds skip it.Spec: docs/src/architecture/2026-05-08-crate-org-followup-design.md (C3 + side-quest)EOF)"
PR4 — Move ops_ludus from vox-db into vox-gamify (C4)
Section titled “PR4 — Move ops_ludus from vox-db into vox-gamify (C4)”Task 21: Survey vox-db/src/store/ops_ludus/ and vox-gamify/src/db/
Section titled “Task 21: Survey vox-db/src/store/ops_ludus/ and vox-gamify/src/db/”Files:
-
Read:
crates/vox-db/src/store/ops_ludus/(whole subdir) -
Read:
crates/vox-gamify/src/db/(whole subdir) -
Step 21.1: List both subdirs.
Get-ChildItem -Recurse crates/vox-db/src/store/ops_ludus/Get-ChildItem -Recurse crates/vox-gamify/src/db/ -
Step 21.2: Identify migration SQL vs. typed ops.
Migration SQL (CREATE TABLE statements, schema versioning) typically lives under
crates/vox-db/src/schema/. Theops_ludus/subdir holds typed ops (functions likeinsert_quest,select_companions, etc.). Read enough of each file to confirm.Plan rule: migrations stay in
vox-db/schema/, only the typed ops API moves tovox-gamify/db/. -
Step 21.3: Find external callers.
Run:
rg "ops_ludus|crate::store::ops_ludus|vox_db::store::ops_ludus" --type rust -lList the files that will need updating.
Task 22: Move ops_ludus into vox-gamify
Section titled “Task 22: Move ops_ludus into vox-gamify”-
Step 22.1: Copy files into vox-gamify.
Move every typed-ops file from
crates/vox-db/src/store/ops_ludus/intocrates/vox-gamify/src/db/(merge with the existingdb/subdir there). Preserve internal structure where possible.Move-Item crates/vox-db/src/store/ops_ludus/* crates/vox-gamify/src/db/Remove-Item crates/vox-db/src/store/ops_ludus -Recurse -
Step 22.2: Update imports in moved files.
Inside the moved files, every
use crate::store::...becomesuse vox_db::store::...if it referred to vox-db’s other store ops.use super::types::Questetc. stays.If a moved file used a private item from
vox_db, that item must now be made public (or replicated in vox-gamify). Prefer making vox-db’s helper public if it’s a clean abstraction. -
Step 22.3: Re-export from vox-db (compat shim).
In
crates/vox-db/src/store/mod.rs(or wherever the oldpub mod ops_ludus;lived), replace with a re-export shim:// Moved to vox-gamify::db (2026-05-08 crate-org-followup, PR4).// Compat re-export so older callers don't break in the same PR.pub use vox_gamify::db as ops_ludus;This requires
vox-dbto depend onvox-gamify, which would create an L3→L3 same-layer edge (allowed) but a new dep cycle if vox-gamify still depends on vox-db. Check for cycle. If cycle: skip the re-export. Update callers in step 22.4 instead. -
Step 22.4: Update external callers.
For each file from step 21.3:
- Replace
use vox_db::store::ops_ludus::Xwithuse vox_gamify::db::X. - Verify the caller’s
Cargo.tomlalready hasvox-gamify. If not, add it. - If a caller is in
vox-dbitself, it’s a sign that vox-db is using its own gamify ops — investigate whether that caller belongs in vox-gamify too.
- Replace
-
Step 22.5: Build and verify.
cargo build -p vox-gamifycargo build -p vox-dbcargo build --workspaceExpected: clean. If a cycle was detected in step 22.3, the compat shim won’t compile — drop it and rely on direct caller updates from step 22.4.
Task 23: PR4 verification and commit
Section titled “Task 23: PR4 verification and commit”-
Step 23.1: Run gamify and db tests.
cargo test -p vox-gamifycargo test -p vox-dbcargo test --workspace --no-run -
Step 23.2: Manual migration smoke test.
Create a fresh DB and run vox-db migrations to confirm gamify-domain tables are still created (migrations stayed in
vox-db/schema/):$env:VOX_DB_URL = "file:.\test-migration.db"cargo run -p vox-cli -- db initcargo run -p vox-cli -- db schema-list | rg "ludus|gamify|quest|companion"Remove-Item test-migration.dbExpected: gamify-domain tables (
gamify_*,ludus_*) appear in the schema list. -
Step 23.3: Run arch-check + doc-pipeline.
cargo run -p vox-arch-checkcargo run -p vox-doc-pipeline -- --check -
Step 23.4: Commit.
git add crates/vox-db crates/vox-gamifygit commit -m "$(cat <<'EOF'refactor(vox-db,vox-gamify): move ops_ludus typed ops to vox-gamifyThe ~3.2K LoC of gamify-domain typed ops in vox-db/src/store/ops_ludus/conceptually belongs in vox-gamify (which already has its own db/ module).Migrations stay in vox-db/schema/ — only the typed API moves. Relievesvox-db budget pressure (32K → ~29K) and consolidates the gamify domaininto one crate.Spec: docs/src/architecture/2026-05-08-crate-org-followup-design.md (C4)EOF)"
PR5 — Extract vox-orchestrator-core (C5)
Section titled “PR5 — Extract vox-orchestrator-core (C5)”Task 24: Survey vox-orchestrator/src/orchestrator/
Section titled “Task 24: Survey vox-orchestrator/src/orchestrator/”Files:
-
Read:
crates/vox-orchestrator/src/orchestrator/(whole subdir — 12.3K LoC) -
Read:
crates/vox-orchestrator/src/lib.rs -
Read:
crates/vox-orchestrator/Cargo.toml -
Step 24.1: List the orchestrator/ subdir.
Get-ChildItem -Recurse crates/vox-orchestrator/src/orchestrator/ | Where-Object {-not $_.PSIsContainer} | Select-Object FullName -
Step 24.2: Identify the public boundary.
Read
crates/vox-orchestrator/src/lib.rs. Find everypub mod orchestrator;andpub use orchestrator::...line. Record the public types/functions exposed from this subdir. -
Step 24.3: Identify cross-cuts.
Run:
rg "use crate::|use super::" crates/vox-orchestrator/src/orchestrator/ --type rustBucket: intra-orchestrator/ (move with code), cross-cut to other vox-orchestrator modules (need to expose those publicly or move with). Cross-cuts to other crates already work.
Task 25: Create the vox-orchestrator-core crate
Section titled “Task 25: Create the vox-orchestrator-core crate”Files:
-
Create:
crates/vox-orchestrator-core/Cargo.toml -
Create:
crates/vox-orchestrator-core/src/lib.rs -
Step 25.1: Scaffold.
Create
crates/vox-orchestrator-core/Cargo.toml:[package]name = "vox-orchestrator-core"description = "Core router/dispatcher logic for vox-orchestrator (the densest subdir of the post-Phase-5 monolith). Parent crate vox-orchestrator now hosts dei_shim, planning, services, runtime glue."version.workspace = trueedition.workspace = true[dependencies]# Mirror vox-orchestrator's [dependencies] minus anything used only by# the modules that stayed in the parent. Start permissive; trim after# cargo build identifies the actual subset.tokio = { workspace = true }serde = { workspace = true }serde_json = { workspace = true }tracing = { workspace = true }thiserror = { workspace = true }anyhow = { workspace = true }vox-orchestrator-types = { workspace = true }vox-orchestrator-queue = { workspace = true }vox-db = { workspace = true }vox-config = { workspace = true }vox-bounded-fs = { workspace = true }workspace-hack = { workspace = true }# Add others as the build complains.[lints]workspace = trueCreate
crates/vox-orchestrator-core/src/lib.rs://! Core router/dispatcher logic extracted from vox-orchestrator (formerly//! crates/vox-orchestrator/src/orchestrator/). The parent vox-orchestrator//! crate now hosts dei_shim, planning, services, runtime glue, and//! coordination across the queue/mcp/core boundary. -
Step 25.2: Add to workspace + layers.
Root
Cargo.toml[workspace.dependencies]:vox-orchestrator-core = { path = "crates/vox-orchestrator-core" }docs/src/architecture/layers.tomlL3 section:vox-orchestrator-core = { layer = 3, max_loc = 20_000 }
Task 26: Move orchestrator/ subdir into vox-orchestrator-core
Section titled “Task 26: Move orchestrator/ subdir into vox-orchestrator-core”-
Step 26.1: Move files.
Move-Item crates/vox-orchestrator/src/orchestrator/* crates/vox-orchestrator-core/src/Remove-Item crates/vox-orchestrator/src/orchestrator -Recurse -
Step 26.2: Adjust the entry-point module.
If the moved subdir had a
mod.rs, rename todispatch.rsor similar (Rust 2024 prefers named files). Updatecrates/vox-orchestrator-core/src/lib.rsto declare the modules:pub mod dispatch;pub use dispatch::*;Adjust as needed based on what the subdir actually exposes.
-
Step 26.3: Fix imports inside vox-orchestrator-core.
Every
use crate::...that referred to a module outside the moved subdir must now be either:use vox_orchestrator::...(creates dep cycle if vox-orchestrator depends on vox-orchestrator-core) — DO NOT use thisuse vox_orchestrator_types::...(preferred — pull pure types from L0 leaf)- Move the helper into vox-orchestrator-core too if it’s a tight collaborator
- Move the helper to a shared L1/L2 crate if it’s broadly useful
-
Step 26.4: Update vox-orchestrator to depend on vox-orchestrator-core.
crates/vox-orchestrator/Cargo.toml[dependencies]:vox-orchestrator-core = { workspace = true }Replace the old
pub mod orchestrator;incrates/vox-orchestrator/src/lib.rswith:pub use vox_orchestrator_core as orchestrator;This preserves the public path
vox_orchestrator::orchestrator::Xfor external callers. -
Step 26.5: Build incrementally.
cargo build -p vox-orchestrator-coreFix imports until clean. Then:
cargo build -p vox-orchestratorcargo build --workspaceLikely failures + fixes:
- Missing dep in
vox-orchestrator-core/Cargo.toml→ add it - Cross-cut import that creates cycle → break by moving the helper or pulling pure types from L0
- Test code using internals → may need to add
pub(crate)visibility in vox-orchestrator-core
- Missing dep in
Task 27: Update layers.toml budgets
Section titled “Task 27: Update layers.toml budgets”-
Step 27.1: Re-measure LoC of vox-orchestrator and vox-orchestrator-core.
Get-ChildItem -Recurse -Filter *.rs crates/vox-orchestrator/src | ForEach-Object { (Get-Content $_.FullName).Count } | Measure-Object -SumGet-ChildItem -Recurse -Filter *.rs crates/vox-orchestrator-core/src | ForEach-Object { (Get-Content $_.FullName).Count } | Measure-Object -Sum -
Step 27.2: Update budgets.
In
docs/src/architecture/layers.toml, adjustvox-orchestrator’smax_loc:- Old:
60_000 - New: round up to next 5K above current size (e.g., if current is 41K, set to 45_000)
Set
vox-orchestrator-core’smax_locto the next 5K above its current size (probably 15_000 or 20_000).This is a tightening — future bloat will trip the lint earlier.
- Old:
Task 28: PR5 verification and commit
Section titled “Task 28: PR5 verification and commit”-
Step 28.1: Full verification.
cargo build --workspacecargo run -p vox-arch-checkcargo test -p vox-orchestrator -p vox-orchestrator-corecargo run -p vox-doc-pipeline -- --checkAll clean.
-
Step 28.2: Measure incremental build win.
Touch a file inside vox-orchestrator-core and time the rebuild:
Add-Content crates/vox-orchestrator-core/src/lib.rs "`n// touch"Measure-Command { cargo build -p vox-orchestrator-core }# UndoRemove-Item crates/vox-orchestrator-core/src/lib.rsgit checkout crates/vox-orchestrator-core/src/lib.rsCompare to a touched-orchestrator baseline (before extraction). Expected: ≥15% reduction on edits inside the extracted code path. Record the number in the PR description.
-
Step 28.3: Add the row to where-things-live.md.
L3 section:
| [`vox-orchestrator-core`](../../../crates/vox-orchestrator-core/) | Core router/dispatcher for vox-orchestrator (extracted from the densest subdir of the post-Phase-5 crate). |Update
vox-orchestrator’s scope description to reflect the post-extraction reality. -
Step 28.4: Update vox-orchestrator’s Cargo.toml description.
In
crates/vox-orchestrator/Cargo.toml, update thedescriptionto reflect the new shape:description = "Glue crate for the multi-agent file-affinity router: dei_shim, planning, services, runtime glue. Core router lives in vox-orchestrator-core, queue/lock/oplog in vox-orchestrator-queue, MCP in vox-orchestrator-mcp." -
Step 28.5: Commit.
git add crates/vox-orchestrator crates/vox-orchestrator-coregit add Cargo.toml docs/src/architecture/layers.tomlgit add docs/src/architecture/where-things-live.mdgit commit -m "$(cat <<'EOF'refactor(vox-orchestrator): extract vox-orchestrator-core (12.3K LoC)Pulls the densest subdir of post-Phase-5 vox-orchestrator (therouter/dispatcher) into a dedicated L3 crate. Smaller wedge than theoriginally-deferred Phase 6 runtime split, but still deliversmeaningful incremental-build savings on edits to that path.Spec: docs/src/architecture/2026-05-08-crate-org-followup-design.md (C5)EOF)"
PR6 — vox-arch-check enhancements (lock in the gains)
Section titled “PR6 — vox-arch-check enhancements (lock in the gains)”Task 29: Add description_present lint to vox-arch-check
Section titled “Task 29: Add description_present lint to vox-arch-check”Files:
-
Modify:
crates/vox-arch-check/src/main.rs -
Modify:
docs/src/architecture/layers.toml[guards]section -
Step 29.1: Read the existing arch-check structure.
Read
crates/vox-arch-check/src/main.rsend-to-end. Note the existing rules: layer ordering (strict), fan-in (warn), loc_budget (warn), orphan (warn), docstring (warn). Each rule is invoked inrun()and accumulates findings into aReport. -
Step 29.2: Add the
description_presentrule.In
crates/vox-arch-check/src/main.rs, add a new function alongside the existingcheck_*functions:/// Warn (or fail) if a workspace member at L1+ has no `description` field/// in its Cargo.toml or has one shorter than 40 characters. Binary-only/// crates (`kind = "binary"`) and `workspace-hack` are exempt.fn check_description_present(meta: &cargo_metadata::Metadata,cfg: &LayersConfig,) -> Vec<String> {let mut findings = Vec::new();for pkg in &meta.packages {let Some(entry) = cfg.crates.get(&pkg.name) else { continue };if entry.layer < 1 { continue }if entry.kind == "binary" { continue }if pkg.name == "workspace-hack" { continue }let desc = pkg.description.as_deref().unwrap_or("");if desc.len() < 40 {findings.push(format!("{}: Cargo.toml description is missing or shorter than 40 chars (\"{}\")",pkg.name, desc,));}}findings} -
Step 29.3: Wire the rule into
run()and theReport.In
run(), after the existing rule calls, add:let description_findings = check_description_present(&metadata, &config);Add a field to the
Reportstruct:struct Report {// ... existing fieldsdescription: Vec<String>,}Update
print_summary()to print the new findings under a “Description present:” heading. -
Step 29.4: Add the strictness control.
Extend
GuardsConfig:#[derive(Debug, Default, Deserialize)]struct GuardsConfig {// ... existing#[serde(default)]description: Option<String>,}In
Report::strict_failed(), treat description findings as strict only ifcfg.guards.description == Some("error"). Default is"warn"(non-failing). -
Step 29.5: Document in layers.toml.
Add to the
[guards]section indocs/src/architecture/layers.toml:description = "warn"(Add a comment noting that this becomes “error” after PR1 lands and all 19 missing descriptions are filled in.)
Task 30: Add where_things_live_coverage lint
Section titled “Task 30: Add where_things_live_coverage lint”-
Step 30.1: Add the rule.
In
crates/vox-arch-check/src/main.rs:/// Warn if a workspace member is not mentioned in/// `docs/src/architecture/where-things-live.md`. Detection: the doc must/// contain the literal substring `crates/<name>/` for every workspace/// member. Plugin and test-only crates are also expected to appear (in the/// Plugins or surfaces sections respectively).fn check_where_things_live_coverage(meta: &cargo_metadata::Metadata,cfg: &LayersConfig,repo_root: &Path,) -> Result<Vec<String>> {let path = repo_root.join("docs/src/architecture/where-things-live.md");let body = std::fs::read_to_string(&path).with_context(|| format!("read {}", path.display()))?;let mut findings = Vec::new();for pkg in &meta.packages {if !cfg.crates.contains_key(&pkg.name) { continue }if pkg.name == "workspace-hack" { continue }let needle = format!("crates/{}/", pkg.name);if !body.contains(&needle) {findings.push(format!("{}: not listed in where-things-live.md (no `{}` substring)",pkg.name, needle,));}}Ok(findings)} -
Step 30.2: Wire into
run()andReport.Same pattern as Task 29: call the function, store findings in a new
Reportfield, print in summary, gate strictness via a newwhere_things_livefield inGuardsConfig. -
Step 30.3: Document.
Add to
[guards]:where_things_live = "warn"
Task 31: Tighten docstring rule to strict for L0–L2
Section titled “Task 31: Tighten docstring rule to strict for L0–L2”-
Step 31.1: Modify the
docstringrule.Find the existing
check_docstring(or equivalent) function. Currently warns for anylib.rsnot starting with//!. Change the strict-or-warn decision per finding based on the crate’s layer:let strict_for_this_crate = entry.layer <= 2;// accumulate strict findings vs. warn findings separately -
Step 31.2: Update Report.
Treat the strict-docstring findings the same way as layer-ordering findings (fail-by-default unless
--warn-only). Warn-docstring findings stay warn. -
Step 31.3: Verify zero findings on current tree.
After PR1’s
vox-corpusdocstring fix, verify L0–L2 crates all have//!docstrings:cargo run -p vox-arch-checkExpected: clean. If not, add
//!docstrings to the offending L0–L2 crates inline.
Task 32: Add a regression test fixture
Section titled “Task 32: Add a regression test fixture”Files:
-
Create:
crates/vox-arch-check/tests/fixtures/missing-desc/Cargo.toml -
Create:
crates/vox-arch-check/tests/fixtures/missing-desc/src/lib.rs -
Create:
crates/vox-arch-check/tests/integration.rs -
Step 32.1: Create a fixture crate with no description.
crates/vox-arch-check/tests/fixtures/missing-desc/Cargo.toml:[package]name = "vox-arch-check-fixture-missing-desc"version = "0.0.0"edition = "2024"# description intentionally missingcrates/vox-arch-check/tests/fixtures/missing-desc/src/lib.rs://! Fixture for description_present lint tests. -
Step 32.2: Add an integration test.
crates/vox-arch-check/tests/integration.rs://! Smoke tests: the description_present rule fires on a fixture crate//! that is missing its description, and is silent on a fixture crate//! that has a long-enough one.use std::process::Command;#[test]fn description_present_fires_on_missing() {// The fixture is excluded from the main workspace via// root Cargo.toml's `exclude = [...]`. We invoke arch-check// pointed at the fixture directory directly.// Detailed wiring depends on how arch-check accepts a metadata-root// override; if it doesn't, this test is a //! TODO.}If
vox-arch-checkdoesn’t currently accept a non-default metadata path, add a CLI flag--manifest-paththat maps through tocargo_metadata::MetadataCommand::manifest_path(). Then write the test against the fixture. -
Step 32.3: Add the fixture to root Cargo.toml
exclude.In root
Cargo.toml:exclude = [# ... existing entries"crates/vox-arch-check/tests/fixtures/missing-desc",]
Task 33: PR6 verification, lint regen, and commit
Section titled “Task 33: PR6 verification, lint regen, and commit”-
Step 33.1: Run arch-check on the actual workspace.
cargo run -p vox-arch-checkExpected: clean (all PRs 1–5 fixed the underlying issues).
-
Step 33.2: Run with
--warn-onlyto verify the report is structurally correct.cargo run -p vox-arch-check -- --warn-only -
Step 33.3: Run the integration test.
cargo test -p vox-arch-checkExpected: passes.
-
Step 33.4: Switch description guard to
errorafter confirming clean.In
docs/src/architecture/layers.toml:description = "error"where_things_live = "error"Re-run
cargo run -p vox-arch-check. Must be clean. -
Step 33.5: Full workspace verification.
cargo build --workspacecargo test --workspace --no-runcargo run -p vox-doc-pipeline -- --check -
Step 33.6: Commit.
git add crates/vox-arch-check Cargo.tomlgit add docs/src/architecture/layers.tomlgit commit -m "$(cat <<'EOF'feat(vox-arch-check): add description_present + where_things_live coverage lints- Adds description_present lint (warn-by-default; strict per [guards]):every L1+ library crate must have a Cargo.toml description ≥40 chars.- Adds where_things_live_coverage lint: every workspace member must belisted in docs/src/architecture/where-things-live.md.- Tightens existing docstring lint to strict for L0–L2 crates only.- Adds integration test fixture for the new lints.- Promotes both new guards from warn → error in layers.toml afterPR1–PR5 fixed the underlying drift.Spec: docs/src/architecture/2026-05-08-crate-org-followup-design.md (PR6)EOF)"
Self-review
Section titled “Self-review”Before opening PR6, run a final pass over all 6 PRs:
- Coverage: every section of the spec maps to a task. Spec sections: A1 (gamify) → Task 1, 2; A2 → Task 3; A3 → Task 4; A4 → Task 6; A5 → Task 5; B descriptions → Task 7; B binary-layer doc → Task 8; C1 → Task 9; C2 → Tasks 11–15; C3 → Tasks 16–20; side-quest → Task 19; C4 → Tasks 21–23; C5 → Tasks 24–28; PR6 → Tasks 29–33. ✔
- No placeholders: every step contains the actual edit, not “TBD” or “similar to”. The only judgment call is the docstring summary in Task 6.3 / 6.4 (“read lib.rs first line”) which the executing agent has to read fresh — that’s intentional.
- Verification at every PR boundary: every PR ends with
cargo build --workspace,cargo run -p vox-arch-check,cargo run -p vox-doc-pipeline -- --check, and (where applicable)cargo test. - Commits: every PR has an explicit commit step with file list and message body.
- Open questions: the spec’s open questions (vox ludus CLI verb, AGENTS.md row interpretation, vox-arch-check workspace.dependencies absence, Phase-6 future) are all defaulted in the plan; the executing agent does not have to make those calls unless they discover the default is wrong.
Risks and recovery
Section titled “Risks and recovery”- A wrong line number in the docs edits. Tasks 1–4 reference specific line numbers from the audit. If a line has shifted, the executing agent should grep for the surrounding text and apply the edit at the right location. If a previously-recorded reference is gone entirely, log it and continue (it may have been fixed in a parallel commit).
- A vox-package or vox-orchestrator-core extraction reveals a hidden cycle. Recover by NOT committing the partial extraction; restore via
git checkout .after capturing the cycle in a comment for the next attempt. - An auto-generated doc check fails after edits. Re-run
cargo run -p vox-doc-pipeline(without--check) to regenerate; commit the regenerated files alongside the edits. - Arch-check fails on a real, unintentional inversion you didn’t introduce. Don’t add a new known_inversion to silence it; investigate the root cause and either fix the cycle or document the decision in this plan.
End of plan.