Skip to content
GitHubRSS

The parallel plan (2026-09-27)

Status: the working plan while the parallel workstreams run. Each stream’s merged items are recorded in docs/history/ws-<id>.md.

Owner, 2026-09-27: “have a bigger vision first, do planning, describe implementation, shard to tasks and spread to many sessions for fast execution, then supervise and re-loop.” The target the owner set is throughput: many merged PRs an hour, not one session’s six.

vx reaches 1.0 as the runner a team can trust blind: no stale hit, no lost signal, no leaked process, no doc that lies, and still the fastest warm run. The feature set is closed (roadmap milestone 2 is done but for two owner items), so what stands between here and 1.0 is:

  1. Correctness by area. A review of one area at a time keeps finding real defects. The 2026-09-27 reviews produced items 1005–1017, five of them stale hits (a link out of a glob grant, nested projects readable from a root sandbox, a cycle’s edge placement, a bun patch’s content, an input written during its own command). Every area gets that review, and every lead becomes one small PR with a differential row.
  2. The 1.0 contract (roadmap milestone 3): the config schema and the plugin API are pinned surfaces, with deprecation that names the replacement.
  3. Numbers that hold on real repos (roadmap 2.5, Next 6/21/25).
  4. Adoption that works on a real Turbo or Nx repo on the first try.
  5. Docs that match the code, checked line by line.

Each workstream owns a disjoint slice of the tree, so ten sessions can merge all day without touching each other’s files. The coordinator (the session that wrote this) keeps the queue full, supervises, and routes a lead that crosses a boundary to the stream that owns it.

IDStreamOwns (write access)
ACache and keyssrc/cache/, src/orchestrator/{task-hash,key-fold,stable-keys,local-shortcircuit,execute-task,miss-save}.ts
BSandbox and execsrc/exec/, src/orchestrator/sandbox-request.ts
CScheduler and run lifecyclesrc/graph/, the rest of src/orchestrator/ (run, signals, admission, placement, events, plugin host)
DWorkspace and configsrc/workspace/, src/config.ts
ECLI and UXsrc/cli/, src/bin.ts, src/util/
FRemote and telemetry pluginspackages/vx-reapi, packages/vx-otel, packages/vx-github, packages/vx-mcp
GAdoptionpackages/vx-migrate, packages/vx-lockfile, packages/vx-schedule-history
HThe 1.0 contractsrc/index.ts, tests/package-boundaries.unsafe.test.ts, new contract tests, docs/design/versioning-1.0.md, docs/schema.md
IPerformancepackages/vx-bench, docs/benchmarks.md; run-path changes go to the owning stream as a measured proposal
JDocs accuracypackages/vx/docs/*.md (not design/, history/, STATUS), packages/vx/docs/modules/, root README, packages/vx-docs/

Tests follow the code: a stream adds and edits the tests of the files it owns. A file two streams need is edited by its owner; the other files a lead in its log and the coordinator routes it.

  • Value, not count (owner, 2026-09-27: “I don’t want lots of small PRs just for the sake. Each PR should fix something, introduce a new feature or refactor. Have real value.”). A PR is one of: a fix for a defect a user could hit (with the row that reproduces it), a feature, or a refactor that removes a real cost (duplication, a wrong abstraction, a measured slowdown). Never a PR for a comment, a rename, a test that pins what is already pinned, or a doc tweak with no wrong claim behind it; fold small related findings into the PR they belong to. Throughput is merged value per hour, not PRs per hour.
  • One item, one PR, one branch (ws-<id>/<slug> from origin/main). Repro first, fix, a row that is red without the fix, docs in the same commit. The gate is unchanged: CI=true bun packages/vx/src/bin.ts run ci --all.
  • Never idle (owner, 2026-09-27). Never end a turn without a PR in flight or an item started; a check-in is at most ten minutes out. Queue empty: next backlog item. Backlog empty: the next failure class, a mutation sweep of an unswept file, a measured cost cut, or a refactor that removes real duplication. Target: 100 merged PRs per hour across streams, so keep up to three independent PRs in flight (one branch and worktree each, all from origin/main).
  • Conventional Commits for every commit subject and PR title: fix(cache): … (A-19).
  • Never idle on CI. While a PR’s CI runs, start the next item on a new branch. Merge your own PR on green (rebase, full-SHA expectedHeadSha). A check-in that waits on CI is at most five minutes out.
  • Records do not go in STATUS.md. Each stream keeps docs/history/ws-<id>.md, appends one entry per merged PR, numbered <ID>-<n> (A-1, A-2, …), and cites it at the end of the commit subject. One writer per file, so no two PRs collide on a number. The coordinator folds the streams into STATUS at each supervision round.
  • Leads outside your slice go in your log under “Leads for other streams” and nowhere else.
  • On a conflict, rebase onto origin/main, re-gate, push. Never force-push a branch you did not create.
  • Every merge to main auto-releases (item 1018). The npm.yml run is red at the first plugin until the owner publishes the seven plugin names once; that is recorded and is no stream’s work.

Each stream starts with a review of its slice. It reads the code for the failure classes named in CLAUDE.md (a stale hit, a lost signal, a leaked process, a refusal that is a stack, a comment that claims a guarantee the code lacks), writes the leads to its log, then fixes them in order of harm, one PR each. The named starts:

  • A. Every input that can change a task’s output but not its key: env, symlinked inputs, package.json fields, lockfile claims, files a task writes into its own inputs, restore over a dirty tree. Then the restore path under concurrent writers.
  • B. Next 24 (strace’s own PTRACE_LISTEN error: a row that reaches it, then -D), Next 23 (the two signal rows’ evidence), grant resolution on macOS paths (a non-canonical temp root).
  • C. Cancellation and continue semantics across the scheduler’s tiers, persistent tasks under --affected, plugin hook failures at each stage, the exit code for every way a run can end.
  • D. --filter and --affected against renames, deletes and nested projects; config-eval purity bypasses; schema refusals that name the field and the fix.
  • E. Every verb’s exit code, --json shape and error line against docs/cli.md; a stack reaching the user is a defect.
  • F. The REAPI client’s retry and deadline classes (item 1017’s sibling cases: other codes a server’s timer can send), the OTel and GitHub sinks’ deadlines, the MCP tools against their README.
  • G. turbo() and nx() on real public repos cloned in the container (one Turbo, one Nx, one pnpm, one yarn), each a row or a recorded refusal; Next 25’s per-task load cost.
  • H. A test that pins the config schema’s surface (every field, its type, its refusal) and one that pins the plugin API’s types, both generated from the source of truth; the deprecation path (a removed field refused with the replacement named).
  • I. Roadmap 2.5 on real repos with node_modules (refine or router, astro), warm, cold and restore; then the warm path’s next lever with an A/B and an A/A control. A run-path change goes to its owning stream as a measured proposal.
  • J. Every sentence in docs/*.md and the READMEs that states a behaviour, checked against the code; each wrong one fixed or pinned.

The coordinator checks every stream’s PRs and session state every ten minutes. It nudges an idle worker, routes cross-stream leads, reassigns a stream that has run dry to the stream with the longest lead list, and folds the logs into STATUS. When a stream’s review is exhausted and its leads are merged, the stream re-reviews its slice at a deeper level (the next failure class, or a mutation sweep of a file no sweep has named), or the coordinator retires it.