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
27 changes: 27 additions & 0 deletions devlog/_plan/260821_bug_merge_train/000_triage_matrix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# 000 — Bug merge-train triage matrix (2026-08-21)

Session: 01a024bb-1acb-7633-908b-29e4fe4d96c5 (worktree a6a7, detached at c0cbe494e).
Objective: drive the six open bug-labeled PRs to merged on `dev` with strict review,
adversarial xai/grok-4.6 subagent verdicts, and a final green dev CI gate.

## In-scope PRs (state as of 2026-08-21T14:30Z)

| PR | Title | Head | Behind dev | Draft | CI on head | Existing review state |
|----|-------|------|-----------:|-------|------------|----------------------|
| #2294 | fix(release): reject credential-bearing SSH remotes | 71598fa45 (ingw/fix-release-ssh-credential-boundary, moved from 86ed0a46a — re-fetch before review) | 3 | yes | green (test 1-4/4 pass on prior head; re-verify) | none; security-review boundary (scripts/release.ts) — Draft on purpose |
| #2289 | fix(service): restart existing installs w/o re-register | 240fc9364 (fix/2287-service-restart) | 9 | yes | green incl. Service lifecycle | none; Closes #2287 |
| #2295 | fix(codex): recover zero-byte coordinator remnants | 6d5f0cf2c (ingw/fix-zero-byte-coordinator-2291) | 0 | yes | green | MERGED to train 728ca1e8b; suite green; landing on dev |
| #2270 | fix(responses): apply_patch on routed Responses | 398b7ade4 (fix/apply-patch-routed-lowering) | 48 | yes | Ingwannu: two CHANGES_REQUESTED resolved on this head; third review says no remaining technical blocker | Linux shards green |
| #2281 | fix: call_id thought-signature replay for Claude Code | b31f3dbed (fix/claude-code-thought-signature-replay) | 50 | no (review-ready + hygiene-blocked label) | BLOCKED state | CodeRabbit minor: normalize promptCacheKey via anthropicSessionKeyFromParts before storing as clientThreadId (core.ts ~1888-1896); lidge-jun review priority 63/80 confirms repro |
| #2296 | fix(codex): bind Desktop reconnects to one pool account | 574cadc86 (ingw/fix-app-pool-affinity-2046) | 0 | yes | green (test shards pass; one cancelled enforce-target) | none; addresses #2046 reconnect rotation only |

## Baseline dev CI status (pre-train blocker)

Run 32486877508 on dev head c0cbe494e: attempt 1 **failed** on
`(fail) multiAgentGuidanceText > the v2 default catalog path uses the request collector, not the synchronous one (#1852)` (macos job). Rerun of failed jobs (attempt 2) is **green** (conclusion: success), and the test passes locally at c0cbe494e (52/52). Cycle 1 exits as recorded flake per 010; no direct dev push needed. Watch for recurrence during the train.

## Hygiene notes

- #2281 carries `intake: hygiene-blocked` (missing_regression_test) despite having test files — the label state needs re-check after any new commit.
- #2281 is a first-time contributor PR; gate binds completion to exact head. New commits reset the checklist; since we (maintainer) will merge manually, that is acceptable.
- User authorized: stash/merge/cherry-pick/close/extra commits, push with --no-verify, suite on ssh lidge if needed, final CI green on dev is the exit gate.
40 changes: 40 additions & 0 deletions devlog/_plan/260821_bug_merge_train/001_dependency_analysis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# 001 — Dependency and conflict analysis (r2, post-audit)

Audit r1 (grok-4.6 "Avicenna") failed the initial order; accepted findings are folded in below.
Rejected findings and why: none rejected outright; the "2270 has no file overlap" observation was
accepted and 2270 moved before 2281 (it still sits after 2289 because its 48-behind rebase wants a
stable dev, and nothing else touches its files so waiting costs only one rebase, which it owes anyway).

## File overlap between PR heads

- **src/server/responses/core.ts**: #2281 (+12) and #2296 (+6/-9). Semantic neighborhood: _reasoningReplayScope creation (2281) vs pool-affinity key derivation (2296) both hang off handleResponsesInner request-context setup.
- **src/cli/registry.ts** + **docs .../reference/cli/lifecycle.md**: #2289 and #2295. Disjoint commands (service vs doctor); textual conflict likely trivial.
- **Runtime semantic risk without file overlap**: #2270's routed custom-tool lowering executes in the same request path as 2281's replay scope and 2296's affinity key. Post-merge full-suite runs after each of these three is the guard, plus a targeted cross-check at 2281/2296 time that replay-scope and lowering still compose (tests in tests/responses-custom-tool-repair.test.ts + tests/claude-code-thought-signature-scope.test.ts both green on the merged tree).
- All other files disjoint.

## Disposition order (r2 — least-rebase, lock-current-first)

1. **CI fix**: restore dev green (multiAgentGuidanceText #1852 macos failure; rerun already green — confirm and root-cause flakiness).
2. **#2295** (0 behind, green head CI, no rebase owed; lands registry.ts/lifecycle.md first so #2289 absorbs the conflict in the rebase it already owes).
3. **#2294** (3 behind, tiny, no overlap; NAMED SECURITY REVIEW GATE — see below).
4. **#2296** (0 behind; lock core.ts while its base is current; C4 auth — NAMED SECURITY REVIEW GATE; cancelled enforce-target check must be re-run green on the pre-merge head).
5. **#2289** (9 behind; rebase absorbs 2295's registry/lifecycle hunks; Service lifecycle CI green required).
6. **#2270** (48 behind; no file overlap with anything above; single rebase onto stable dev; full suite on the rebased head BEFORE merge).
7. **#2281** (50 behind; takes the core.ts conflict on rebase as the last mover; pre-merge blockers below).

## Named gates (merge-blocking, not notes)

- **Security review gate (#2294, #2296)**: per MAINTAINERS.md/AGENTS.md these surfaces (release automation; auth/account binding) require explicit security review. The maintainer (this session, acting for the owner account) performs and RECORDS a written security review in the cycle doc: threat cases checked, rejection matrix, log-boundary check (no token/secret in output), before merge. The grok-4.6 adversarial verdict is additive, not the security review itself.
- **Pre-merge CI-on-head gate (all)**: merge only from a head whose CI (or local full suite for shared-surface PRs: #2270, #2281, #2296) is green ON THE REBASED HEAD, not a stale ancestor. Cancelled/skipped required checks are re-run, not ignored.
- **#2281 pre-merge blockers**: (a) stacked commit normalizing promptCacheKey via anthropicSessionKeyFromParts (CodeRabbit finding) + test rows; (b) hygiene label missing_regression_test resolved — the PR does carry tests, so re-trigger the deterministic check after the stacked commit and confirm the label drops, or record the maintainer override rationale; (c) rebase onto final-form dev; (d) full suite green on that head.
- **Post-merge dev CI check after EVERY merge** before starting the next cycle (train stops on red).

## Merge mechanics per PR

fetch pr/N -> read full diff (AGENTS.md review rules) -> rebase onto current dev if behind -> focused tests + typecheck -> FULL SUITE (bun run test) pre-merge for every non-trivial PR (AGENTS.md bar; ssh lidge if local env-limited) -> grok-4.6 adversarial verdict -> security review doc where gated -> stack fix commits if needed. Head remotes: #2294/#2295/#2296/#2289 are in-repo branches (push origin); #2270 head is olddonkey/opencodex, #2281 head is Hsia97/opencodex, both maintainerCanModify=true -> push https://github.com/<owner>/opencodex.git HEAD:<branch> (--no-verify is a local-hook flag). Then merge to dev (merge commit convention) -> push --no-verify -> dev CI green -> next. #2270 extra: dismiss/refresh the stale CHANGES_REQUESTED review so reviewDecision matches the converged head.

## Issue closure map

- #2287 -> close after #2289 lands (manual, base is dev).
- #2291 -> close after #2295 lands.
- #2046 -> #2296 fixes reconnect-rotation only; comment with landing commit; keep open unless the remaining Desktop-UI half is split into its own issue at wp6 D.
20 changes: 20 additions & 0 deletions devlog/_plan/260821_bug_merge_train/002_audit_synthesis.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 002 — Audit synthesis (round 1 -> round 2)

Reviewers: Avicenna (grok-4.6, plan-shape audit) FAIL; Hegel (grok-4.6, deep repo audit) FAIL.

## Accepted (folded into r3 docs)
1. Order rework (Avicenna): CI -> 2295 -> 2294 -> 2296 -> 2289 -> 2270 -> 2281. Adopted in 001 r2 and decade docs 020-065.
2. Fork mechanics (Hegel): #2270 head lives on olddonkey/opencodex, #2281 on Hsia97/opencodex, both maintainerCanModify=true — verified via gh. Stacked commits to those heads push to the FORK remote (https://github.com/<owner>/opencodex.git <local>:<branch>), enabled by maintainerCanModify; --no-verify applies locally. 001 mechanics corrected.
3. Full-suite bar (both): bun run typecheck + bun run test required before approving ANY non-trivial PR (AGENTS.md:178 area); full suite explicitly pre-merge for #2281/#2289/#2295 too, not only 2270/2296. Decade docs updated.
4. #2294 gates (Hegel): add bun run prepush (scripts/AGENTS.md), and record the non-author maintainer review — author is Ingwannu; the merging maintainer account (lidge-jun) supplies the non-author security APPROVE, satisfying MAINTAINERS.md no-self-approval.
5. #2270 stale CHANGES_REQUESTED (Hegel): reviewDecision still CHANGES_REQUESTED although the same reviewer's later comment on exact head 398b7ade4 says no remaining technical blocker. Pre-merge step: dismiss the stale review with rationale (or fresh APPROVE) so the recorded decision matches the converged state.
6. #2294 head drift (Hegel): head moved 86ed0a46a -> 71598fa45; re-fetch and re-review at the new head. 000 corrected.
7. CI cycle-1 (Hegel): rerun attempt 2 green + local 52/52 pass -> exit as flake (010 rewritten); no direct dev push.
8. Docs-sync (Hegel): after both 2295 (en-only doctor docs) and 2289 (8-locale lifecycle) land, verify locales do not contradict the English lifecycle page; added to 070.
9. CODEOWNERS/owner review for core.ts PRs (Hegel): lidge-jun review recorded at 040/065 merge time.

## Rejected (with evidence)
1. "#2270 already collides with intervening dev on src/providers/registry.ts" (Hegel): git merge-tree merge-base(origin/dev, pr/2270) shows 0 conflict markers; same for pr/2281. Rebase risk is semantic, not textual; covered by full suite on rebased head.
2. "#2281 hygiene failure is unsponsored_surface" (Hegel): latest pr-hygiene comment on #2281 says missing_regression_test (fetched via gh api). Treated per 065: re-trigger after stacked commit; drop or record maintainer override.
3. "#2296 cancelled enforce-target ignored" (Avicenna): not ignored — 040 requires it re-run green pre-merge. Kept.

7 changes: 7 additions & 0 deletions devlog/_plan/260821_bug_merge_train/010_fix_dev_macos_ci.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# 010 — Cycle 1: dev CI status (resolved as flake)

Evidence:
- Run 32486877508 (dev c0cbe494e) attempt 1: platform-macos failed on multiAgentGuidanceText #1852 test; attempt 2 (rerun --failed): conclusion success.
- Local repro at exact c0cbe494e: bun test tests/multi-agent-compat.test.ts -> 52 pass / 0 fail; paired with server-combo-failover-e2e -> 120 pass.
Exit: flake recorded; dev is green at c0cbe494e. No dev push. If the same test fails again during the train, escalate to root-cause mode (test reads catalog collector timing — suspect CI-runner timing sensitivity).

46 changes: 46 additions & 0 deletions devlog/_plan/260821_bug_merge_train/020_merge_2295.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# 020 — Cycle 2: PR #2295 (zero-byte coordinator, #2291)

0 behind dev; lands first among PRs. Review: coordinator-doctor state machine (8 classifications), fail-closed defaults, doctor --recover-zero-byte-coordinator gating (proxy stopped + BEGIN IMMEDIATE + identity revalidation + backup-not-delete), no SQLite sidecar creation on diagnosis path, age-gate race reasoning.
Verify: bun test tests/codex-coordinator-doctor.test.ts tests/codex-inject-write-lock.test.ts tests/codex-transition-state*.test.ts tests/cli-doctor.test.ts tests/cli-dispatch.test.ts, bun run typecheck, bun run privacy:scan, FULL SUITE (bun run test) pre-merge. grok verdict. Merge, push --no-verify, dev CI green. Close #2291 with landing commit.

## Review round 1 (Volta, grok-4.6) — FAIL — synthesis

Finding 1 (age gate bypasses lock): ACCEPTED AS RESIDUAL RISK, REBUTTED AS BLOCKER.
RCA: a creator stalled >1s between file creation and BEGIN IMMEDIATE is classified stable-zero-byte.
But the consequence is exactly the ENOENT behavior: clean homes still enter the coordinated path
(inject-coordination.ts:96-99 comment + code — the SQLite transaction safely initializes the same file,
still serialized by the lock); ONLY residue/indeterminate legacy homes take legacy-uncoordinated, which
is the identical compatibility boundary those homes used for years pre-coordination and would use today
if the remnant pathname were absent. The trade fixes #2291 (zero-byte blocks sync forever, fail-closed
with no operator exit). Residual: legacy-residue home + creator stalled >1s + concurrent write —
accepted; the alternative is the unfixable wedge this PR exists to remove.

Finding 2 (recovery rename TOCTOU): REBUTTED AS BLOCKER.
RCA: window between final sameIdentity check (coordinator-doctor.ts:306) and renameSync (:312) allows a
same-uid attacker to swap a file that then gets MOVED (not deleted) to a same-directory backup.
The namespace is 0o700/owner-checked and the file 0o600/owner-checked (inspectTarget); only the same
user can race it. Per AGENTS.md's own boundary statement, a same-user local process is outside the
enforceable threat model (it can already rename these files itself). Recovery is opt-in (--yes),
proxy-stopped, and evidence-preserving. Non-blocking.

Finding 3 (fail-open vs dev): REBUTTED.
RCA: on dev, an existing zero-byte coordinator stayed "coordinated" and then wedged sync (issue #2291's
literal symptom). The PR routes only proven (zero bytes + user_version 0 + no tables via immutable read
+ 1s settled identity) remnants to the absent-file boundary. unversioned-nonempty / rowless /
unsupported / changed / unsafe all remain fail-closed. This is the intended fix, not an accident.

Disposition: proceed to merge; findings 1-2 recorded as accepted residual risks in this doc.
Focused tests 55/55, typecheck pass, privacy:scan pass, full suite pending (bg session).

## Verification close-out (train head 728ca1e8b)

Full suite re-run on lidge after completing the temporary worktree's gui
dependency install: the first run's 7 failures were all "Unhandled error
between tests: Cannot find package 'react'" (gui/src/i18n/shared.ts and
friends) — an incomplete `gui/node_modules` environment artifact, not test
logic. After `bun install --cwd gui` on the same commit: **14175 pass /
16 skip / 0 fail across 890 files (464.61s), exit 0**
(/tmp/ocx-train-suite-r2.log on lidge). Locally, the same four representative
files that hit the missing-package path pass 55/55 after the identical fix.
Merge-blocker verdict stands; accepted residuals unchanged. Train branch is
ready to land on dev.
4 changes: 4 additions & 0 deletions devlog/_plan/260821_bug_merge_train/030_merge_2294.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# 030 — Cycle 3: PR #2294 (release SSH credential boundary)

NAMED SECURITY REVIEW GATE (scripts/release.ts). Written review in this doc before merge: userinfo rejection matrix (ssh:// password, encoded ':', scp-like user:pass@), control-char/query/fragment rejection, GIT_SSH_COMMAND single-literal '-i' proof, log-boundary check (accepted value printed pre-push — verify nothing secret-bearing can pass validation).
Head moved to 71598fa45 — re-fetch and review the live head. Verify: bun test tests/release-helper.test.ts, bun run typecheck, bun run privacy:scan, bun run prepush (scripts/AGENTS.md bar for release tooling). Non-author security review: author is Ingwannu; merging maintainer (lidge-jun) records the security APPROVE (no self-approval). grok verdict. Merge, push --no-verify, dev CI green.
5 changes: 5 additions & 0 deletions devlog/_plan/260821_bug_merge_train/040_merge_2296.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# 040 — Cycle 4: PR #2296 (Desktop reconnect pool affinity, #2046)

C4 auth surface — NAMED SECURITY REVIEW GATE: HMAC fallback key non-persistence + non-correlatability across restarts, no raw session/thread-id storage or logging (privacy:scan + manual grep), account-qualified selector exclusion from automatic affinity, failover/terminal accounting carries the same key.
Cancelled enforce-target check on head must re-run green pre-merge. Verify: bun test tests/codex-auth-context.test.ts, typecheck, privacy:scan, FULL SUITE on head (shared server surface). grok verdict. Merge, push --no-verify, dev CI green. Comment on #2046 (rotation half fixed; UI-denial half remains).

4 changes: 4 additions & 0 deletions devlog/_plan/260821_bug_merge_train/050_merge_2289.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# 050 — Cycle 5: PR #2289 (service restart, closes #2287)

Rebase (9 behind) absorbs #2295's registry.ts/lifecycle.md hunks. Review: bare 'ocx service' idempotency, repair/restart alias routing (src/service.ts, src/cli/registry.ts), Windows WINDOWS_SCHTASKS_CREATE_ACCESS_DENIED path, 8-locale docs consistency.
Verify: bun test tests/cli-help.test.ts tests/service.test.ts tests/winsw.test.ts, bun run typecheck, FULL SUITE (bun run test) pre-merge; Service lifecycle CI green on head. grok verdict. Merge, push --no-verify, dev CI green. Close #2287 with landing commit.
4 changes: 4 additions & 0 deletions devlog/_plan/260821_bug_merge_train/060_merge_2270.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# 060 — Cycle 6: PR #2270 (apply_patch routed lowering)

48 behind; single rebase onto now-stable dev. Preserve the !isCanonicalOpenAiForwardProvider boundary (already on head 398b7ade4; maintainer review r3 found no remaining technical blocker). Review: supportsResponsesCustomTools capability plumbing (registry/derive/types), compaction-body-last reorder invariant, byte-identical non-compaction pin test.
Fork head (olddonkey/opencodex, maintainerCanModify=true): stacked commits push to the fork remote. Pre-merge: dismiss stale CHANGES_REQUESTED (converged per reviewer's own head-398b7ade4 comment) or record fresh APPROVE. Verify on REBASED head BEFORE merge: bun test tests/custom-tool-compat.test.ts tests/namespace-tool-compat.test.ts tests/openai-responses-passthrough.test.ts tests/responses-custom-tool-repair.test.ts, bun run typecheck, FULL SUITE (shared routing/adapter surface; ssh lidge if local env-limited). grok verdict. Merge, push --no-verify, dev CI green.
4 changes: 4 additions & 0 deletions devlog/_plan/260821_bug_merge_train/065_merge_2281.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# 065 — Cycle 7: PR #2281 (thought-signature replay, last mover)

Takes the core.ts rebase conflict deliberately. Pre-merge blockers (ALL merge-blocking): (a) stacked commit: normalize promptCacheKey via anthropicSessionKeyFromParts before assigning clientThreadId (src/server/responses/core.ts ~1888-1896; helper at src/oauth/anthropic-routing.ts:573-594) + trimmed/overlong-key test rows; (b) missing_regression_test hygiene label re-checked after stacked commit — drop or record maintainer override; (c) rebase onto final dev, resolve core.ts against #2296's affinity changes with a semantic re-check (replay scope + affinity key compose; both test files green on merged tree); (d) FULL SUITE green on that head.
Fork head (Hsia97/opencodex, maintainerCanModify=true): stacked commits push to the fork remote. Also: reviewDecision is CHANGES_REQUESTED (lidge-jun priority-63 review) — the stacked fixes must answer that review, then refresh/dismiss it. Verify: bun test tests/claude-code-thought-signature-scope.test.ts tests/google-signature-history-roundtrip.test.ts, bun run typecheck, FULL SUITE. Owner (CODEOWNERS core.ts) review recorded at merge. grok verdict. Merge, push --no-verify, dev CI green.
8 changes: 8 additions & 0 deletions devlog/_plan/260821_bug_merge_train/070_final_gate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 070 — Cycle 7: final gate

1. Confirm final dev head CI fully green (gh run list --branch dev; the ci aggregate job).
1b. Docs-sync check: after 2295 (en-only doctor docs) + 2289 (8-locale lifecycle) both land, confirm locale lifecycle pages do not contradict the English page (AGENTS.md docs-sync rule).
2. If macos/windows shard flakes, rerun; if real regression from the train, fix forward on dev.
3. Close remaining linked issues with landing-commit comments (#2287, #2291, #2046 decision).
4. Move devlog unit to _fin with terminal outcomes recorded per PR.
5. Goalplan criteria capturedEvidence filled; cxc loop validate green; update_goal complete.
Loading
Loading