Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions devlog/_plan/260927_release_train_4/account-pool/000_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Release train 4: account pool lane

This lane will carry generic OAuth manual account pause from PR #6087 and a narrower, bounded Antigravity 401/validated-403 rotation from PR #5099. The other candidates stay open with specific reasons. The Desktop Send report remains open until a controlled both-exhausted trace locates the submission gate. The detailed inventory is in [001_inventory.md](001_inventory.md); the implementation and disposition steps are in [010_pause.md](010_pause.md), [020_desktop.md](020_desktop.md), [030_auth_failover.md](030_auth_failover.md), and [040_closeout.md](040_closeout.md).

## Loop specification

- **Archetype and trigger:** satisfy-spec, started by the delegated release-train-4 account-pool lane request.
- **Goal:** review all five nominated PRs and nine issues against the current `dev`, integrate the release-ready account behavior, and leave truthful GitHub dispositions.
- **Non-goals:** no `main` or `preview` changes, release, version bump, installed-app or real-user-account modification, fork push, other-lane file edits, or broad rewrite of Codex/Anthropic pool selectors. No native GitHub stack.
- **Verifier:** focused tests for changed behavior and negative cases; `bun run test:changed`, `bun run typecheck`, `bun run lint:gui` and `bun run build:gui` if GUI changes, `bun run privacy:scan`, `bun run structure:check`, `bun run skill:surface:check`; isolated-home browser QA for the pause control (temporary HOME, OPENCODEX_HOME and CODEX_HOME, with client sync disabled); required PR CI at the exact head and post-merge `dev` CI. The existing package scripts were checked in `package.json`; the baseline typecheck passed after a frozen-lockfile Bun install; the first attempt lacked `bun-types`. Every conditional branch in the decade docs names its activation and observable result.
- **Stop condition:** selected behavior is merged into `dev` with current-head required CI and `dev` CI success, source PRs and issues have accurate disposition comments, and the lane report names any remaining gaps. A failing security review, missing GUI proof, or failed CI keeps the corresponding PR unmerged.
- **Memory artifact:** this numbered devlog unit, the bound `cxc` goalplan/ledger, Git commits, PR Verification and CI URLs. Security working notes, if needed, stay in ignored `.tmp/`.
- **Expected outcomes:** DONE means the selected patches and dispositions satisfy the checks; NOOP applies to a candidate already fully covered on `dev`; NEEDS_HUMAN applies to a product choice or Desktop evidence that cannot be inferred; UNSAFE applies to a verified security blocker. Deferred features are recorded as open work, not claimed complete.
- **Escalation:** independent security review or maintainer objection that cannot be resolved from available evidence, repository/CI state preventing exact-head proof, or a product choice that would change Reserve entitlement. Replan within this lane where possible.
- **Unattended scope and resources:** only this dedicated worktree, its `codex/t4-account-pool-*` branches, the authorized `dev` PR/merge/issue writes, temporary isolated homes, a same-commit verification checkout at `/private/tmp/t4-account-pool-verify`, and `pr-assets` screenshot upload. GitHub CLI uses the authenticated maintainer identity. The coordinator imposed no token or wall-clock limit; do not invent one. Run focused tests locally because seven lanes share this machine. Run `test:changed` and any full suite from the same committed tree in `/private/tmp/t4-account-pool-verify`, where test cleanup is permitted; never bypass the worktree cleanup guard. Document the full-suite exception and leave comprehensive coverage to CI.

## Baseline and order

Initial source: `origin/dev` `24b2f39b77a29711c5064987de169ecf4a97c58b` on 2026-09-27. Refresh it before each implementation and merge. This lane is C4 for OAuth/auth and release integration; the first work phase is documentation only.

| Work phase | Dependency | Concrete outcome |
| --- | --- | --- |
| wp0 | none | This entire roadmap, candidate verdicts, source ownership and exact patch plans are written and independently audited. No production patch. |
| wp1 | wp0 | Cherry-pick the three immutable #6087 commits (`c6fbe06527`, `e51a1d7bc9`, `480083070a`) into `codex/t4-account-pool-pause`, audit/refine pause semantics, test store/selection/refresh/API/CLI/GUI, perform isolated-home browser QA and the security review, then run the **PR-1 gate** in [040_closeout.md](040_closeout.md): open, exact-head CI, merge, `dev` CI, close #6087. #5956 is evaluated but held. |
| wp2 | wp1 | Record the distinct Desktop/Reserve decisions and issue evidence for #5879, #4878, #4961 and #4869. No speculative proxy patch for a client composer gate. |
| wp3 | wp1 merged, wp2 | Reimplement only the narrowly classified 401/403 rotation idea from #5099 on top of the merged PR-1, with bounded reads and existing send budget, then run the **PR-2 gate**. Keep #3738 and post-stream resume out of this change. If the audit or security review fails, no PR-2 is opened; if PR-2 CI fails and cannot be repaired, PR-2 stays open and unmerged. |
| wp4 | wp1, wp2, wp3 outcomes | Post the remaining PR/issue dispositions that depend on the PR-1/PR-2 outcomes, read them back, and write the final lane report. |

The phase order establishes operator account state before another failure class consumes that roster. Desktop disposition is placed before the final HTTP design so Reserve/client behavior cannot accidentally be treated as evidence that HTTP retry repairs Send. If the phase evidence changes a candidate verdict, amend the corresponding decade doc before implementation.

## Cross-cutting contracts

1. Operator pause, `needsReauth`, quota evidence and upstream cooldown have separate owners. A same-account login clears reauthentication while preserving pause; deletion removes account-bound state. This adopts architect proposal AP-01.
2. Eligibility is evaluated before quota or priority preference. Codex, Anthropic and generic OAuth keep distinct selectors; only compatible predicates are shared. This adopts AP-02 and defers a universal selector.
3. Main-account hard lock remains enabled at 98% in either the 5-hour or weekly window; only fresh valid lower usage releases its block. Partial, credits-only, unknown and reset-time-only observations do not. Reset-credit consumption does not resume a paused account or defeat the lock. This adopts AP-03/AP-04.
4. Anthropic model-aware routing (AP-05) needs a separate matching/persistence contract and is deferred with #5561. Desktop authless and Reserve entitlement must be designed separately (AP-06), so #5879/#4961 remain open. Post-output continuation is a different protocol from pre-output rotation (AP-07), so #5616 remains open.
5. Generic OAuth same-request funding remains at most six accounts, including all retry ladders. A 401 or 403 rotates only in the precisely classified Antigravity primary-inference case, before response commitment; unrelated 403, another provider's 401, Kiro refusal, or a non-replayable request remains terminal. No new health disk format or background timer is introduced in this release slice.
6. New test files are registered in both layout registries. The file-size ratchet is never raised; additions to capped files move to siblings. Exhaustive locale/union/count consumers are reconciled after combining the changes and the latest `dev`.

## Source of truth and review

The change map in `structure/INDEX.md` requires review of `structure/providers-and-adapters.md`, `structure/transports/inventory.md`, `structure/gui-and-management-api.md`, and `structure/data-planes/images.md` for the OAuth pause paths, plus `structure/transports/responses-failover.md` for refusal rotation. Update only prose whose current contract changes. Public workflows live in `docs-site/`. Review root, `src/`, `gui/`, and `docs-site/` scoped `AGENTS.md` before writes. `MAINTAINERS.md` requires explicit security review for authentication changes.

## Architect consultation and continuity

Architect handle `01a0e35e-f65a-7c30-b000-aec2cf5e6e78` proposed AP-01 through AP-07 against the initial source. AP-01–AP-04 and AP-07 are accepted as invariants; AP-05/AP-06 are accepted as design boundaries but their implementations are deferred. Its proposed `260928_account_pool_train4` location is rejected because the coordinator owns `devlog/_plan/260927_release_train_4/account-pool/`. The same architect reflected on the executable plan and found its selected implementation coherent but three issue-disposition corrections necessary: #3375 manual reset-credit identity is already implemented; #3376 has history, estimate, Codex reset-first and scheduled activation already; #5099 must stay open when only its narrow slice is carried. Those corrections are folded into `001_inventory.md` and `040_closeout.md`; the same architect returned ALIGNED on the current revision before the independent A audit.

The previous release-train-2 outcome at `devlog/_plan/260927_merge_train_2/020_outcome.md` recorded #5956 as needing a complete #5649 action decision and #5879 as needing ownership/retry redesign. This review preserves those concerns while checking their current heads. No earlier test result is treated as fresh proof.

## Audit round 1 and repair

Independent reviewer handle `01a0e36f-6501-7b61-a531-c86435c74162` returned `VERDICT: FAIL` on the first staged revision. Main accepted all five blocking findings: #6087 gained a third doc correction; existing same-account refresh precedes 401 pool rotation; Google error normalization can hide the structured 403 reason; the body reader needs explicit 4 KiB/2 s options; and image/web-search sidecars are a reachable but separate path. The P2 demand for path-specific integration evidence was accepted too. `010_pause.md`, `030_auth_failover.md` and the inventory now carry those corrections. The 401 refresh/catch order and Google normalized-marker seam change the execution design, so the same architect must reflect on this revision before the same reviewer re-audits it. No production code has been changed.

## Audit round 2 and repair (2026-09-28, successor thread)

The successor re-ran both roles with gpt-6-sol because round 1 used a different model. Architect `01a0e381-241d-7fa3-8051-e125e06bea5a` revalidated AP-01..AP-07 and D1, D3, D4, D5 as ALIGNED against current source, agreed #6013 should stay a separate Anthropic slice, and found D2 MISALIGNED: a marker searched anywhere in the normalized message could be forged by reflected upstream text. Reviewer `01a0e381-2289-7642-bb37-5bd03456f6d8` returned FAIL with three High findings: the adapter normalizer reads with default 64 KiB/5 s bounds so the 4 KiB/2 s limit did not hold there; the Antigravity runTurn fixture is unreachable because the Google adapter only defines fetchResponse; and this file still said two #6087 commits. Two Medium findings asked for a post-save GUI refresh-failure case and an explicit terminal-refresh quorum exception.

All five were accepted and folded: 030 now applies the explicit bounds on the raw Antigravity 403 read inside the Google normalization seam, emits a formatter-owned prefix matched only with startsWith, drops runTurn, names the passthrough wire fixture, and states that the status helper uses captured activation plus a live sibling without the current-quorum gate; 010 adds the post-save refresh-failure case; the phase table names all three donor commits. The reviewer also recommended deferring wp3. Main rebutted in part: wp3 stays, but in a separate PR-2 after PR-1 (wp1) merges, and is held with a comment if its own audit, security review or CI fails. That keeps the pause release independent of the auth slice's risk.
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Candidate and issue inventory

Observed 2026-09-27/28 against `origin/dev` `24b2f39b77`. GitHub states and heads are point-in-time; refresh before posting or merging. “Hold” means leave the original open with a concrete English comment. No held item is described as fixed.

## Pull requests

| PR and head | Verdict | Evidence and remaining condition |
| --- | --- | --- |
| [#6087](https://github.com/lidge-jun/opencodex/pull/6087), `480083070ac4cb27863cee91452e3f65e8aa5dd0`, chilung-cgu | **Squash carry with review fixes** in wp1; retain chilung-cgu co-author credit from the donor commits. | Three commits descend from first parent `24b2f39b77`; 49 changed paths include API, selection, CLI, GUI, locales, tests and docs. It is draft and its current checks are not passing readiness evidence. The patch adds generic-provider operator pause, not Anthropic pause (`src/server/management/oauth-account-routes.ts` in the donor). Validate all no-survivor, concurrent selection and reauth paths; perform explicit auth security review and isolated-home GUI QA before our PR. |
| [#5956](https://github.com/lidge-jun/opencodex/pull/5956), `b05e99d239eb0f87fe0fb2fd737a9fefeb612343`, codingbooo | **Hold**; no partial cherry-pick this train. | 95 commits behind `dev`, conflicting, maintainer changes requested. Its auto-pause policy is narrower than #5649's notification and desktop-action request. The old train's owner decision remains unresolved: `devlog/_plan/260927_merge_train_2/020_outcome.md:30`. It also touches capped `src/server/index.ts`. Require a separately agreed action/resume policy and fresh regressions before reconsidering. |
| [#5879](https://github.com/lidge-jun/opencodex/pull/5879), `9a5b6d9d72dcf59d2b6741778f597ba335bf2123`, MateuszJuszczyk | **Hold**. | Draft/conflicting; auto-application needs retry on injection failure, a fresh quota recovery signal, and catalog convergence. The behavior is an opt-in Desktop account gate mitigation, not a confirmed repair for the both-exhausted Send state (#4878). It also needs a product decision separating Reserve capability from authless (#4961). |
| [#5099](https://github.com/lidge-jun/opencodex/pull/5099), `9473f496b19a335dee56cfa5d638ff446ced6d63`, MerryEcho | **Reimplement narrow auth-failover slice** in wp3; retain MerryEcho co-author credit from the donor commits. Keep donor open after the narrow slice lands; comment with thanks and explain the remaining independent health/recovery proposal and rejected dynamic cap. | Draft/conflicting, changes requested, 181 commits behind `dev`. The bounded Antigravity 401 and classified 403 idea addresses one item of #3375. Its persistent health/sweep and 15-rotation design are rejected for this train; the current six-account funding cap in `src/oauth/generic-account-failover.ts:50` remains authoritative. |
| [#3738](https://github.com/lidge-jun/opencodex/pull/3738), `4e7ea19036e1ce52f5f54b18b38c5b35a3703e3e`, y2ambition-ai | **Hold/split**. | 29 files, +2,505 lines and 2,642 commits behind `dev`. It blends fresh quota admission, selection and a pre-output SSE wait. Existing 98% lock and bounded history have since landed. The wait does not implement #5616's post-output continuation. Reconsider distinct admission and wait contracts after current tests and client behavior are specified. |

## Issues

| Issue | This lane's disposition and evidence boundary |
| --- | --- |
| [#6013](https://github.com/lidge-jun/opencodex/issues/6013) | **Hold open.** Anthropic pool manual pause and account-specific threshold are two missing slices. #6087's generic-provider route explicitly excludes Anthropic; `src/oauth/anthropic-routing.ts:111` has one pool threshold. A later design must cover affinity, after-await selection, pool-disabled recovery and the meaning of zero. |
| [#5649](https://github.com/lidge-jun/opencodex/issues/5649) | **Hold open.** #5956 supplies an opt-in Codex threshold and pause, but not the requested account/reset-context alert and settled resume behavior. Existing switching threshold in `src/codex/account-auto-switch.ts:32` is a different control. |
| [#5616](https://github.com/lidge-jun/opencodex/issues/5616) | **Hold open.** Requested auto-continuation after output has streamed. #3738 only waits before output; replay after a committed text/tool boundary needs a separate continuation contract (`structure/transports/responses-failover.md`). |
| [#5561](https://github.com/lidge-jun/opencodex/issues/5561) | **Hold open.** Model-specific Anthropic routing requires carrying model identity into the selector; current `src/server/responses/request-transport.ts:548` calls a resolver without it. Specify exact-match/unsupported behavior and preserve affinity/429 failover. |
| [#4878](https://github.com/lidge-jun/opencodex/issues/4878) | **P1, hold open with a concrete comment.** The reported both-exhausted transition is not independently captured with selected provider, Enter/Send and correlated ingress. Windows evidence in the issue supports a provider-blind Desktop composer gate and independently successful proxy inference, but not the precise both-exhausted transition. #5879 does not establish a repair. Do not infer proxy routing is the cause or close the issue. |
| [#4961](https://github.com/lidge-jun/opencodex/issues/4961) | **Hold open.** `src/codex/loopback-target.ts:50` and `src/codex/catalog/reserve.ts:19` tie Reserve eligibility to `codexDesktopAuthless`. A new capability contract needs migration and catalog/request parity; this train does not silently change an operator's Reserve entitlement. |
| [#4869](https://github.com/lidge-jun/opencodex/issues/4869) | **Hold open.** Per-thread external-provider routing is separate from account-pool auth failover. The issue awaits evidence that an affected Desktop request reaches the proxy; it is owned by client integration. |
| [#3375](https://github.com/lidge-jun/opencodex/issues/3375) | **Hold open** (with a partial-landing note only if wp3 merges). The umbrella still needs session affinity, selector consumption of declared strategy/threshold, pool health/attribution and scheduled warmup. Stable manual reset-credit identity is already implemented by `src/codex/auth-api/routes.ts:431`, `src/cli/account-auth.ts:348` and `src/codex/auth-api/reset-credit-service.ts:314`; do not list it as missing. A 401/403 slice does not close the epic. |
| [#3376](https://github.com/lidge-jun/opencodex/issues/3376) | **Hold open.** `src/codex/quota-history.ts` retains bounded observations; `src/codex/quota-capacity.ts:15` returns an explicit low-confidence estimate/sample count; `src/codex/routing/selection.ts:315` has Codex reset-first; `src/codex/quota-auto-refresh.ts:326` schedules opted-in activation. The latest issue measurement still finds an already-opted-in idle weekly window unstarted until its later due deadline. Keep open for that initial activation behavior and separately verify whether Anthropic reset ordering is still absent; do not repeat the issue body's older “none implemented” premise. |

## Overlap map

- #6087 and #5099 both touch `src/oauth/generic-account-failover.ts` and Responses dispatch. Pause eligibility lands first; new status rotation consumes that same roster.
- #6087 and #6013 share the operator term “pause” but use different pool engines. Do not claim one closes the other.
- #5956 and #5649 share Codex low-quota action but differ on notification/resume. Neither should override the main-account 98% policy.
- #5879 and #4961 share `codexDesktopAuthless` semantics; #4878 is a reported client composer symptom, not proof of either route's repair.
- #5099 and #3375 overlap only one subrequirement. #3738 and #5616 describe different pre/post-output boundaries.

No issue is closed during inventory. GitHub comments and any closures happen in wp4 after the relevant `dev` merge or verified hold decision.
Loading
Loading