From be6f45d48e75f6fa8ab7b927591b89dfee49b9fc Mon Sep 17 00:00:00 2001 From: JUN Date: Mon, 14 Sep 2026 12:33:40 +0900 Subject: [PATCH] docs(devlog): plan the round 2/3 delivery lanes and closure policy Records the roadmap for two more delivery rounds against the open backlog: per-lane issue assignment, orchestrator models, explicit per-lane write scopes, the contributor merge queue, and the merge and closure policy the rounds follow. The lane split was audited three times and changed each time. Two round-1 lanes had both claimed the same Responses source file and are now one lane; the Models dashboard and the catalog backend now have one owner each; the reasoning-ladder file has a single owner across both rounds; and because any lane that adds a user-facing setting has to edit the shared config schema, one lane per wave owns that schema while the others land behavior only. Documentation only. Nothing in the build, typecheck or test path reads from devlog/, and this branch touches no source, test, workflow or release file. --- .../000_roadmap.md | 64 ++++++++ .../010_lane_assignments.md | 141 ++++++++++++++++++ .../020_merge_and_closure_policy.md | 52 +++++++ .../030_round1_dispatch.md | 44 ++++++ 4 files changed, 301 insertions(+) create mode 100644 devlog/_plan/260914_round23_delivery_roadmap/000_roadmap.md create mode 100644 devlog/_plan/260914_round23_delivery_roadmap/010_lane_assignments.md create mode 100644 devlog/_plan/260914_round23_delivery_roadmap/020_merge_and_closure_policy.md create mode 100644 devlog/_plan/260914_round23_delivery_roadmap/030_round1_dispatch.md diff --git a/devlog/_plan/260914_round23_delivery_roadmap/000_roadmap.md b/devlog/_plan/260914_round23_delivery_roadmap/000_roadmap.md new file mode 100644 index 0000000000..5fb5389c58 --- /dev/null +++ b/devlog/_plan/260914_round23_delivery_roadmap/000_roadmap.md @@ -0,0 +1,64 @@ +# 260914 — Round 2/3 delivery roadmap + +## Where this starts + +The 2026-09-14 triage delivery loop closed with #4519, #4534, #4535, #4536, +#4539, #4555, #4562 and #4563 on dev. What it did not do is reduce the open +surface: 63 pull requests and 63 issues are still open, and a large share of the +pull requests are contributor work that is already green and simply never got +landed. This unit plans two more delivery rounds against that backlog. + +## Objective + +Rebuild the lane roadmap, run two merge rounds, and finish with a closure sweep +that closes at least 10 issues and at least 10 pull requests with written +reasons. Every close names either a merge commit or the change that supersedes +it. + +## Delivery constraints carried from the session + +- Lanes are **worktree Codex threads**, one per branch. Subagents inside a lane + are that lane's workers; they never own a branch of their own. +- Lane orchestrators split between `anthropic/claude-opus-5` and `kimi/k3[1m]`. +- Inside a lane, implementation is delegated to `devin/swe-2` and + `xai/grok-4.6` subagents at roughly a 2:3 ratio. +- Each lane runs `cxc-loop` itself: its own goal, its own PABCD cycle. +- **No local suite.** `bun run test`, `bun run typecheck` and `bun install` are + not run locally. Proof is hosted CI at the exact final head, nothing else. +- Pushes use `--no-verify`. +- Merges into dev are admin squash merges, taken on maintainer judgment under + the MAINTAINERS.md single-maintainer dev integration policy, with exact-head + CI recorded. +- Landing another author's work carries a `Co-authored-by` trailer in a branch + commit so it survives the squash. + +## Round shape + +Two merge rounds, then one closure sweep. + +| Round | Work | Merge target | +|---|---|---| +| 1 (wp2) | 5 lane threads on issues that have no pull request, plus review-and-land of the already-green contributor queue | dev | +| 2 (wp3) | 4 lane threads on the second issue cluster, plus the second contributor batch | dev | +| Sweep (wp4) | Close resolved issues with merge references, close superseded and abandoned pull requests with reasons | — | + +## Acceptance criteria + +1. This roadmap unit exists with per-lane issue assignment, dispatch models and + acceptance criteria. +2. Round 1 lanes were dispatched as separate worktree threads and their pull + requests reached green hosted CI at their exact final head. +3. Round 1 pull requests were admin squash-merged into dev with recorded merge + commits. +4. Round 2 lanes were dispatched and squash-merged into dev the same way. +5. At least 10 issues are closed with a merge-commit reference or a written + supersession reason. +6. At least 10 pull requests are closed — merged, or closed with a written reason + naming the superseding change. + +## What would make this fail + +The backlog is contributor work, so the failure mode is not "no code lands", it +is "code lands that nobody reviewed". A green check on a three-day-old head is +not evidence about the head being merged. Every merge in this unit re-reads the +diff at the head it is about to squash, and re-reads CI at that same SHA. diff --git a/devlog/_plan/260914_round23_delivery_roadmap/010_lane_assignments.md b/devlog/_plan/260914_round23_delivery_roadmap/010_lane_assignments.md new file mode 100644 index 0000000000..82a69602b8 --- /dev/null +++ b/devlog/_plan/260914_round23_delivery_roadmap/010_lane_assignments.md @@ -0,0 +1,141 @@ +# 010 — Lane assignments + +Each lane is one worktree Codex thread on its own branch. The orchestrator model +is named per lane; inside the lane the implementation work goes to devin/swe-2 +and xai/grok-4.6 subagents at roughly a 2:3 ratio. Every lane runs cxc-loop, +pushes with --no-verify, opens one pull request against dev, and runs no local +suite. + +This split is the second revision. The first one was audited and failed: two +round-1 lanes both owned src/server/responses/core.ts, two round-2 lanes both +owned the Models dashboard, and src/codex/catalog/effort.ts had two claimants +across rounds. Lanes in the same round are now disjoint by file, and the only +remaining overlaps are sequential, where the later round branches from dev after +the earlier one has landed. The write-scope exclusions below are the mechanism; +they are part of each lane's dispatch, not advice. + +## Round 1 lanes — branch from current dev + +| Lane | Orchestrator | Issues | Carried | Write scope | +|---|---|---|---|---| +| R1-L1 catalog normalization | claude-opus-5 | #4570, #4505 | — | src/codex/catalog/parsing.ts and catalog normalization; **not** catalog/effort.ts | +| R1-L2 pool routing and prompt cache | kimi/k3 | #4546, #4550 | — | src/codex/routing.ts, pool and session affinity; **not** src/providers/devin*, src/providers/antigravity*, src/server/responses/* | +| R1-L3 cursor policy and errors | claude-opus-5 | #4508, #4542 | #4509 (HeiTuz), #4544 (001005HS) | src/adapters/cursor/* | +| R1-L4 responses terminal, reasoning payload, media | claude-opus-5 | #4469, #4311, #4312, #4532 | #4549 (jiaoyun286) | src/server/responses/*, src/responses/*, src/adapters/anthropic* | +| R1-L5 provider account lifecycle edges | kimi/k3 | #4503, #3781 | — | src/providers/devin*, src/providers/antigravity*; **not** the pool kernel | + +### What each lane owns + +**R1-L1** — #4570 is a live-catalog regression where +zhipu-bigmodel-coding/glm-5.3-flash loses its contextWindow on 2.54.0, so the +model arrives with no context budget. #4505 is the neighbouring modality gap: +DeepSeek V4.1 Flash and GLM-5.3 Flash declare no image input, which disables +combo image routing on OpenCode Go and CommandCode. Both are parsing and +normalization. The reasoning ladder is explicitly not this lane's, because +R2-L6 owns effort.ts. + +**R1-L2** — #4546 is the expensive one: pool routing rotates accounts mid-thread, +which destroys the prompt-cache prefix and produces a 10x-50x token burn above +the 80% usage threshold. #4550 is the same subsystem from the other side, an +existing Codex CLI thread that bypasses the pool over a direct WebSocket while +status still claims opencodex-local. + +**R1-L3** — #4508 loses the Cursor data-policy "action required" signal into a +bare failed_precondition, and #4542 makes the native-exec refusal name +shell_command/exec_command even when the catalog has no shell tool, which makes +kimi-k3 abandon the turn. #4509 and #4544 are contributor attempts at exactly +this surface; both are carried with attribution rather than reimplemented blind. + +**R1-L4** — this is the merged Responses lane. #4469 is reasoning +encrypted_content never reaching the caller that asked for it; #4311 is paginated +Codex history silently stopping projection after provider metadata relabeling; +#4312 reports an Anthropic content_filter terminal as a 502 so Codex retries +something that can never succeed; #4532 is dynamic image downscaling on append +busting the prompt prefix cache, which #4549 fixes. They were two lanes until the +audit showed #4549 already diffs core.ts, encrypted-payload.ts, compact.ts and +collaboration.ts — the same files #4469 needs. One lane, one merge. + +**R1-L5** — #4503 is the Devin provider's detached credential rekey leaving a +host-selection window, and #3781 is the Antigravity quota-refresh failure with +missing canonical Fake-IP handling. Both are vendor-local and stay out of the +pool kernel that R1-L2 owns. + +## Round 2 lanes — branch from dev after round 1 lands + +Cutting these after round 1 is what makes the remaining overlaps safe. R2-L6 +needs src/codex/catalog/parsing.ts, which R1-L1 also changes, and #4461 edits it +too. + +Round 2 runs in two waves, and inside wave A exactly one lane owns the config +schema. That rule is the thing that took three audit passes to get right: any +lane that adds a user-facing setting has to edit src/config.ts and +src/types/config.ts, so "disjoint" cannot be expressed in feature terms alone. +L8 is the schema owner for wave A; L6 and L7 land behavior only, and if either +one genuinely needs a new setting it files a follow-up instead of editing the +shared schema. + +The waves exist for the same reason. Wave A is L6, L7 and L8, which +are disjoint from each other. Wave B is L9 alone, branched from dev after L8 +lands. The second audit found why: #3630 and #3377 are config-schema changes in +src/config.ts and src/types/config.ts, and L9's carried #4042 already edits both +of those files plus src/server/background-lifecycle.ts, which is exactly where a +refresh timer would register. Naming L8's scope as catalog-refresh-status.ts and +convergence.ts did not remove that collision, it only hid it. Sequencing does +remove it. + +| Lane | Orchestrator | Issues | Carried | Write scope | +|---|---|---|---|---| +| R2-L6 codex runtime and Windows probe (wave A) | claude-opus-5 | #4204, #4458 | #4461 (S0RYUASUKA) | src/codex/runtime.ts, catalog/effort.ts, catalog/bundled.ts, catalog/parsing.ts; **no new config-schema fields** | +| R2-L7 web-search bridge (wave A) | kimi/k3 | #4429 residual, #2730 | — | src/web-search/*, src/server/search.ts; **no new config-schema fields** | +| R2-L8 catalog auto-refresh backend (wave A) | claude-opus-5 | #3630, #3377 | — | src/codex/catalog-refresh-status.ts, convergence.ts, src/config.ts, src/types/config.ts, src/server/background-lifecycle.ts; **not** gui/, **not** management/config-routes.ts | +| R2-L9 dashboard model and usage surface (wave B, branches after L8 lands) | kimi/k3 | #4175, #4209 | #4193 (chilung-cgu), #4042 (Vocllum) | gui/src/pages/Models.tsx, gui/src/pages/Usage.tsx, src/server/management/config-routes.ts, and the config-schema files only as rebased on top of L8 | + +**R2-L6** — #4204 has a stale persisted CLI 0.135.0 stripping max and ultra while +Codex Desktop runs 0.153.4, and #4458 is the Windows prompt probe missing the +Codex App runtime and its base prompt source. Both are runtime resolution, and +effort.ts has exactly one owner in the whole unit. + +#2279 was in this lane and is deferred out of the unit. It asks for a per-model +setting that suppresses synthetic max while retaining ultra, which is a +config-schema field, and the third audit pass showed that putting a schema field +in L6 collides with L8 no matter how the rest of the scope is drawn. It is a real +ask and it stays open; it just does not fit a lane that has to run beside a +schema owner. + +**R2-L7** — #4429 is only partly landed. #4515 (cb2e15ba6f) shipped the +passthrough backends and said so, but the residual is mixed-tool continuation: +a key-auth Responses gateway (Kimi K3) still echoes hosted web_search back as a +client function_call, and webSearchBridge stays Ollama-only. The lane closes the +residual, not the whole issue as if nothing had landed. #2730 is the related ask +to let /v1/alpha/search use a configured backend without ChatGPT forward auth. + +**R2-L8** — #3630 wants periodic catalog auto-refresh so newly released models +appear without a manual ocx sync. #3377 wants per-model capability declarations +for text-only, context tier, and video processing mode. Backend only; the +dashboard side of the same story belongs to R2-L9. + +**R2-L9** — #4175 is the Dashboard toggle for Fast selector rows, which #4193 +already implements. #4209 wants the dashboard to distinguish a hub model change +that is saved from one that is synced from one that is actually active on a given +client. #4042 adds a configurable usage history size limit and has gone stale. + +## Contributor merge queue + +These need review plus an admin squash, not new implementation. The reviewers +found that every one of them was sitting with Cross-platform CI and React Doctor +in action_required, which is the fork-workflow approval gate — so none of them +had ever produced exact-head suite proof. Approving those runs at the current +head is the first step for each, and the merge waits on the result. + +- Batch 1 (round 1): #4565, #4452, #4451, #4383, #4139, #4517, #4298, #4071, + #4033 +- Batch 2 (round 2): #3952, #3748, #3742, #4224, #4265, #4199, #4177, #3833, + #4178, #4566, #4564, #4568, #4569 +- Held: #4309 is 288 commits behind dev and its provider-count assertions cannot + be trusted until it is rebased. + +Draft state is a gate artifact, not an author objection: the contributor gate +opens fork pull requests as drafts and holds them until a four-box checklist is +ticked, and the local-CI box is an attestation a fork author cannot satisfy +because fork contributors cannot start repository CI. Marking such a pull request +ready before an admin squash is a maintainer action, and it is recorded as one. diff --git a/devlog/_plan/260914_round23_delivery_roadmap/020_merge_and_closure_policy.md b/devlog/_plan/260914_round23_delivery_roadmap/020_merge_and_closure_policy.md new file mode 100644 index 0000000000..04c569e647 --- /dev/null +++ b/devlog/_plan/260914_round23_delivery_roadmap/020_merge_and_closure_policy.md @@ -0,0 +1,52 @@ +# 020 — Merge and closure policy for this unit + +## Merge policy + +Every merge in this unit is an admin squash into dev. The authority is the +single-maintainer dev integration clause in MAINTAINERS.md: a maintainer with +GitHub maintain or admin access may integrate through a pull request without a +second approval, including their own, provided the decision and the exact-head CI +evidence are recorded. That clause covers dev only. main and preview are +untouched here, and no direct push to a protected branch happens at any point — +the bypass is pull-request-only, which --no-verify does not change. + +Squash is the merge method for the whole unit. What gets verified is the round's +final tip after the squash, not each intermediate branch state, because a squash +collapses the branch into one commit on dev and the only thing dev ever sees is +that commit. + +Before any squash the lane's diff is re-read at the head about to be merged, and +the check rollup is read at that same SHA. A green run on an older head is +evidence about the older head. + +## What a lane must deliver + +1. One branch, one pull request against dev, filled to the repository pull + request template (Summary, Verification, Checklist). +2. Closes #N lines for every issue the lane resolves. GitHub will not auto-close + them because these target dev rather than main, so the sweep closes them by + hand with the merge reference. +3. A Co-authored-by trailer in a branch commit for every carried contributor pull + request, so it survives the squash and reaches the contributor graph. Prose + naming the author is not equivalent; CREDITS.md exists because that mistake + was made 27 times. +4. Verification stated honestly: hosted CI at the exact head. Local suite runs + are labelled NOT RUN because they were not run. + +## Closure policy + +An issue closes when a merged commit on dev resolves it, and the closing comment +names that commit. An issue also closes when it is superseded, and then the +comment names what superseded it and why the original ask is satisfied. + +A pull request closes one of three ways in this unit: + +- **Merged.** The ordinary case for the contributor merge queue. +- **Superseded.** A lane landed the same behavior; the closing comment names the + merge commit and the carried attribution, so the author can see where their + work went. +- **Abandoned against current dev.** The branch conflicts, the approach no longer + matches the subsystem it targets, and reviving it would cost more than + reimplementing. The comment says that plainly and leaves the door open. + +No pull request is closed merely for being old, and none is closed silently. diff --git a/devlog/_plan/260914_round23_delivery_roadmap/030_round1_dispatch.md b/devlog/_plan/260914_round23_delivery_roadmap/030_round1_dispatch.md new file mode 100644 index 0000000000..be9e277888 --- /dev/null +++ b/devlog/_plan/260914_round23_delivery_roadmap/030_round1_dispatch.md @@ -0,0 +1,44 @@ +# 030 — Round 1 dispatch record + +Five worktree Codex threads were created for round 1, one per lane, each with its +own checkout and branch. Each was told to run cxc-loop itself, to delegate +implementation to devin/swe-2 and xai/grok-4.6 subagents at roughly a 2:3 ratio, +to run no local suite, to push with --no-verify, and to open one pull request +against dev without merging it. + +| Lane | Orchestrator | Branch | Issues | +|---|---|---|---| +| R1-L1 catalog normalization | anthropic/claude-opus-5 | codex/260914-l1-catalog-normalization | #4570, #4505 | +| R1-L2 pool routing and prompt cache | kimi/k3[1m] | codex/260914-l2-pool-routing-cache | #4546, #4550 | +| R1-L3 cursor policy and errors | anthropic/claude-opus-5 | codex/260914-l3-cursor-policy-errors | #4508, #4542 | +| R1-L4 responses terminal and media | anthropic/claude-opus-5 | codex/260914-l4-responses-media | #4469, #4311, #4312, #4532 | +| R1-L5 provider account edges | kimi/k3[1m] | codex/260914-l5-provider-account-edges | #4503, #3781 | + +## Contributor merge queue, batch 1 + +The review pass found the thing that had actually been blocking this queue. +Every fork pull request in it was sitting with Cross-platform CI and React Doctor +in `action_required` — the fork-workflow approval gate — so the suite had never +run at those heads. The green checks visible on each pull request were the +hygiene, labeler and target gates only. Nine runs were approved at the exact +current head: + +| PR | Head | Approved run | +|---|---|---| +| #4565 | 449a692f4 | 34794874697 | +| #4452 | 4b213ef2b | 34796097782 | +| #4451 | daf735d67 | 34794900986 | +| #4383 | 713fbe66e | 34794898049 | +| #4139 | 2a8ca25cb | 34794890662 | +| #4517 | 3a45afe6a | 34795340237 | +| #4298 | cdbac2727 | 34778679348 | +| #4071 | 78a9e097b | 34774091261 | +| #4033 | 84b197e76 | 34745744790 | + +#4309 is held out: it is 288 commits behind dev, and its provider-count +assertions cannot be trusted until it is rebased. + +Two reviewer subagents read the diffs first. All five of batch 1's luvs01 pull +requests came back MERGE with specific justification; the other four came back +HOLD for exactly one reason each, the missing exact-head suite run, which is what +the approvals above address.