From 099a1905f948967f8e8a3a03729b39f2f44bafeb Mon Sep 17 00:00:00 2001 From: bitkyc08-arch Date: Tue, 1 Sep 2026 04:22:23 +0900 Subject: [PATCH 1/4] docs(devlog): record the 2026-08-31 non-priority-70 bug triage round --- .../000_roadmap.md | 103 +++++ .../001_scan_verdicts.md | 77 ++++ .../002_audit_round1_synthesis.md | 101 +++++ .../003_audit_round2_synthesis.md | 64 +++ .../004_audit_round3_synthesis.md | 54 +++ .../070_outcome.md | 368 ++++++++++++++++++ 6 files changed, 767 insertions(+) create mode 100644 devlog/_plan/260831_bug_triage_nonprio70/000_roadmap.md create mode 100644 devlog/_plan/260831_bug_triage_nonprio70/001_scan_verdicts.md create mode 100644 devlog/_plan/260831_bug_triage_nonprio70/002_audit_round1_synthesis.md create mode 100644 devlog/_plan/260831_bug_triage_nonprio70/003_audit_round2_synthesis.md create mode 100644 devlog/_plan/260831_bug_triage_nonprio70/004_audit_round3_synthesis.md create mode 100644 devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md diff --git a/devlog/_plan/260831_bug_triage_nonprio70/000_roadmap.md b/devlog/_plan/260831_bug_triage_nonprio70/000_roadmap.md new file mode 100644 index 0000000000..bcd247e866 --- /dev/null +++ b/devlog/_plan/260831_bug_triage_nonprio70/000_roadmap.md @@ -0,0 +1,103 @@ +# 260831 — bug triage round: everything the priority-70 train does not own + +A concurrent session owns the >=70 train (`devlog/_plan/260831_prio70_train_round2/`): +issues #3071, #3032, #3026, #3029, #3008, #3019 and their PRs #3069, #3056, #3040, +#3020. This unit owns the rest of the open bug surface and drives it to zero, keeping +only the handful that genuinely cannot be resolved from this tree. + +## Frozen snapshot + +Taken 2026-08-31T15:45:55Z against `dev` = `b4303bb9e`. Anything opened after that +timestamp is queued for the next round and does not change this round's acceptance +scope. + +**Bug issues (11):** #3070 #3068 #3064 #3059 #3051 #3024 #3021 #2999 #2813 #1527 #1419 +**Bug-labelled PRs (13):** #3078 #3067 #3066 #3063 #3053 #3052 #3041 #3039 #3038 #3034 +#3003 #3000 #2989 +**Also in scope, not bug-labelled:** #3030 (`chore`), carried only as a wrong-branch +janitorial closure. Audit round 1 caught this misclassification; see `002`. + +Issue #3009 and PR #3039 are in scope. They are easy to confuse with the train's #3008 +and PR #3040 — different defect, different file, different lane. + +## Why this roadmap is deliberately shallow + +The prio-70 unit wrote six diff-level decade docs before implementing anything. That +worked for six deep defects. This round has twenty-five items whose correct +disposition is mostly *closure*, and pre-writing a diff for an item that turns out to +be already fixed is wasted precision that then has to be un-written. + +So this document locks only what a roadmap must lock: the scope, the cluster +partition, the order, and the candidate disposition per item. **The diff-level design +for each cluster is produced in that work-phase's own A phase**, against the tree as +it stands when that phase starts, and recorded in the phase's own decade doc. This is +an explicit, user-directed deviation from DIFFLEVEL-ROADMAP-01. + +## Disposition vocabulary + +Every item leaves this round through exactly one of: + +| verdict | meaning | +| --- | --- | +| `MERGE` | the PR is correct and complete; squash after exact-head CI | +| `CHERRY_PICK` | only part of the PR is correct; take those hunks | +| `REIMPLEMENT` | the diagnosis is right and the remedy is wrong; rewrite on `dev` with a red-then-green regression | +| `CLOSE_FIXED` | already fixed on `dev`; cite the commit | +| `CLOSE_INVALID` | the claimed code path contradicts the tree | +| `CLOSE_DUPLICATE` | name the survivor | +| `CLOSE_NOT_REPRO` | no reproduction is possible against current `dev` | +| `UNSOLVABLE` | stays open; name exactly what external input is missing | + +A closure without a `file:line` or commit SHA in its comment does not count. + +## Work-phase map + +The order below is the audited order, not the original one. Audit round 1 found three +file collisions the first ordering ignored, two of them with the concurrent >=70 train +(`002`, findings 5-7). Train-blocked phases run late so an external dependency never +stalls the round. + +| # | wp | cluster | items | candidate disposition | blocked by | +| --- | --- | --- | --- | --- | --- | +| 0 | wp0 | this roadmap + live rescan | all of scope | — | — | +| 1 | wp1 | closes with no code | #3068, PR #3030 | duplicate; wrong-branch | — | +| 2 | wp2 | model catalog dated variants | #3024, PR #3034, PR #3041 | widen the suffix one-way; cherry-pick the merge tests | — | +| 3 | wp3 | cursor discovery transport | #3051, PR #3052 | merge after rebase | — | +| 4 | wp4 | windows service and scheduler | #3064 + PR #3067, #3009 + PR #3039 | one reimplement, one merge-after-fix | — | +| 5 | wp7 | residual bug PRs | PR #3078, PR #3053 | reimplement on dev; merge | #3053 needs wp2 | +| 6 | wp6 | account-pool auth and quota | PR #2989, then #2999 + PR #3000, then PR #3003 | merge; portable rewrite; merge | #2999 rewrite needs #2989 first (same file); #3003 needs train #3020 | +| 7 | wp5 | upstream request and compact metadata | PR #3066, then PR #3063, then PR #3038 | merge; merge; close the duplicate | #3066 and #3063 share `openai-responses.ts`, so #3066 lands first and #3063 rebases onto it. Train #3089 merged at `a0d386b49`, so the external blocker is gone (`004`) | +| 8 | wp9 | residual issue fixes | #3070, #1527, #3021, #3059 | four bounded reimplementations | — | +| 9 | wp8 | closeout | — | receipts, residual set, final audit | all | + +Each row is one full PABCD cycle. The candidate column is what this round's four +read-only `xai/grok-4.6` lanes concluded; none of it is binding until that phase's own +A phase confirms it against the tree as it stands then. + +**Every phase re-reads `gh pr diff --name-only` for its own PRs before merging, and pairs +that list against every other PR it is about to touch.** #3063 grew from two files to +five during wp0 and picked up two train-owned files, which moved it from wp7 to wp5 +(`003`); pairing then exposed that it also collides with #3066 (`004`). A file list +captured at scan time is not a fact about merge time, and neither is a blocker — train +#3089 merged at `a0d386b49` while this roadmap was being audited. + +## Declared unsolvable + +#2813 (needs a live Luna Reserve account's `/v1/models` and `/api/models` dumps) and +#1419 (needs macOS `.ips` crash frames on Bun 1.4.0, which the maintainer already +declined to claim was fixed). Both are argued in `002`. Two of the allowed three-to-four +slots are spent; the rest stay unspent until a phase earns one. + +## Constraints this round runs under + +- No local full suite. Focused `bun test tests/.test.ts` or `bun run test:changed` + only; whole-suite evidence comes from hosted exact-head CI or `ssh lidge`. +- Every commit and push uses `--no-verify`. `dev` is protected, so every change lands + through a branch and a PR, merged after exact-head CI is green. +- Read-only `xai/grok-4.6` lanes, unlimited, for investigation and audit. +- No file owned by the >=70 train is touched. + +## Terminal outcome + +`DONE` requires every scoped item terminal, at most four left open, each with a +recorded reason. Receipts land in `070_outcome.md`. diff --git a/devlog/_plan/260831_bug_triage_nonprio70/001_scan_verdicts.md b/devlog/_plan/260831_bug_triage_nonprio70/001_scan_verdicts.md new file mode 100644 index 0000000000..c7c2af0c88 --- /dev/null +++ b/devlog/_plan/260831_bug_triage_nonprio70/001_scan_verdicts.md @@ -0,0 +1,77 @@ +# 001 — live rescan verdicts for all 25 scoped items + +Four read-only `xai/grok-4.6` high-effort lanes, split so no two lanes shared a +verdict: (A) issues a prior scan believed the tree already answered, (B) the model +catalog dated-variant cluster, (C) platform/service and cursor transport, (D) request +metadata, account-pool auth, and the residual bug PRs. Every lane was instructed that +the tree wins over the issue body and the PR description. + +## The headline: the prior scan was wrong in both directions + +The round-2 below-bar table (`260831_prio70_train_round2/000_plan.md`) was written to +justify *exclusion* from a merge train, not to decide disposition. Read as disposition, +it misclassifies five items: + +| item | prior scan said | the tree says | +| --- | --- | --- | +| #3041 | reverse inference can resurrect retired ids | the author **removed** the reverse fold in `4e131140c`; the danger is in `aef4bec2`, which is no longer the head | +| #3070 | model filtering landed in `b68edc077` | that commit is CLI/API only and does not touch `gui/src/pages/Logs.tsx`; the dashboard still cannot find a Terra row | +| #1527 | all four named mechanisms are fixed on `dev` | all four SHAs are ancestors, but `envelope_exhausted` still silently full-replays for external-root models | +| #3021 | one occurrence, no ciphertext captured | `structurallyValidFernetTokens` already exists, so a bounded output filter needs no reporter ciphertext | +| #3053 | no linked user report | the runtime/catalog drift is real and the PR's tests drive production; absence of an issue number is not a defect | + +#3059 and #1419 held up only halfway, and audit round 1 caught the other half. The tree +does contradict #3059's unmount path, but a real focus residual survives that +refutation, so it became a wp9 fix instead of a close. #1419 was reported against a Bun +this tree no longer ships, but the maintainer explicitly declined to claim 1.4.0 fixed +it, so it became the second declared `UNSOLVABLE` instead of a close. See `002`. + +## Verdicts + +| item | verdict | one-line basis | phase | +| --- | --- | --- | --- | +| #3068 | `CLOSE_DUPLICATE` | same author, body and `input[240]` log as #3071; author already said "superseded" | wp1 | +| #3059 | `REIMPLEMENT` (was `CLOSE_INVALID`; see `002`) | the reported unmount cannot run — `refresh()` keeps stale data at `gui/src/client-resource.ts:339-341` — but the focus residual at `RestoreDialog.tsx:49-50` is real | wp9 | +| #1419 | `UNSOLVABLE` (was `CLOSE_NOT_REPRO`; see `002`) | `27764f342` moved the pin to Bun 1.4.0 and 200 TLS-failure cases produced no SIGTRAP, but the maintainer explicitly declined to claim that fixed the reporter's trap | residual | +| PR #3030 | `CLOSE_INVALID` | the branch is 61 files / +5114 of unrelated `main` work, and the classification it tests does not exist in `provider-routes.ts:957` | wp1 | +| #3024 | `REIMPLEMENT` | widen the suffix matcher one-way only; a live base row is not callability evidence for a configured dated snapshot | wp2 | +| PR #3034 | `MERGE_AFTER_REBASE` | the calendar matcher is the better vehicle; graft #3041's merge-loop tests, whose reverse test is the real resurrection guard | wp2 | +| PR #3041 | `CHERRY_PICK` | take the two merge tests and the directional comment; leave `isDateSuffix`, which still folds `0231` | wp2 | +| #3051 | via PR | — | wp3 | +| PR #3052 | `MERGE_AFTER_REBASE` | one production line; a pre-header EOF is `status === 0` and must be `transport`, not `HTTP unknown` | wp3 | +| #3064 | via PR | — | wp4 | +| PR #3067 | `REIMPLEMENT` | `[^\\\\/]*` leaves a fully CJK segment with no anchors, so `...\\김병준\\...` matches `...\\Admin\\...`; restrict the lossy run to `[?\\uFFFD]*` and give `` its own matcher | wp4 | +| #3009 | via PR | — | wp4 | +| PR #3039 | `MERGE_AFTER_REBASE` | correct remedy; restore `expect(probes).toBe(1)` and pin the 45s budget absolutely | wp4 | +| PR #3066 | `MERGE_AFTER_REBASE` | strips at the noncanonical adapter boundary only, copy-on-write, ChatGPT preserved; tests drive `buildRequest` | wp5 | +| PR #3038 | `CLOSE_DUPLICATE` | same defect, wrong layer (mutates canonical ChatGPT too) and its tests stay green with both call sites deleted | wp5 | +| #2999 | `REIMPLEMENT` | refresh lock is keyed on `OPENCODEX_HOME` while the file lives in `CODEX_HOME`; coordinate on the existing native-main claim instead | wp6 | +| PR #3000 | `REIMPLEMENT` (close in favor of the rewrite) | `dlopen(\"libc.so.6\")` breaks musl, and a late cancel discards an already-rotated grant | wp6 | +| PR #3003 | `MERGE_AFTER_REBASE` | a failed WHAM prime writes no quota, so the account is stale forever; the PR's tests drive `primeCodexPoolQuotas` | wp6 | +| PR #2989 | `MERGE_AFTER_REBASE` | the existing 503 test never re-enters, so it stays green on the broken path; the PR's tests do re-enter | wp6 | +| PR #3078 | `REIMPLEMENT` on `dev` | both production hunks are right; it targets `main` and its test file does not typecheck | wp7 | +| PR #3063 | `MERGE_AFTER_REBASE` | the second commit's tests do drive `handleResponsesCompact`; the "vacuous" reading was of the first commit | wp5 (moved: it now edits two train-owned files, `003`) | +| PR #3053 | `MERGE_AS_IS` | already rebased onto `b4303bb9e`; mirrors `isModelTextOnly` at both catalog sites | wp7 | +| #3070 | `REIMPLEMENT` | add a Logs model/provider query; the intercepted toggle stays Luna-only | wp9 | +| #1527 | `REIMPLEMENT` | fail closed on `envelope_exhausted` for external-root models instead of silently full-replaying | wp9 | +| #3021 | `REIMPLEMENT` | replace a client-visible Fernet payload with a structured error; do not widen recovery to `MESSAGE` | wp9 | +| #2813 | `UNSOLVABLE` | needs `/v1/models` and `/api/models` dumps from an account actually in Reserve; a picker screenshot cannot separate proxy-missing from client-filter | residual | + +## Residual candidates + +Two are declared unsolvable after audit round 1: #2813 and #1419. The round budget +allows three to four, so the remaining slots are held for phases that hit a genuine +wall, not spent in advance. + +## Note on phase numbering + +wp9 (residual issue reimplementations: #3070, #1527, #3021, and #3059 after audit round +1) was appended after this scan, because the roadmap assumed those would close without +code. wp8 remains the closeout and runs last. + +## This table is living + +Two audit rounds moved four rows after they were first written (#3059, #1419, #3063, +and #3030's label). PR file lists in particular are a moving target — #3063 grew from +two files to five during wp0 — so every phase re-reads `gh pr diff --name-only` for its +own PRs before merging rather than trusting this table's snapshot. diff --git a/devlog/_plan/260831_bug_triage_nonprio70/002_audit_round1_synthesis.md b/devlog/_plan/260831_bug_triage_nonprio70/002_audit_round1_synthesis.md new file mode 100644 index 0000000000..9a19db1647 --- /dev/null +++ b/devlog/_plan/260831_bug_triage_nonprio70/002_audit_round1_synthesis.md @@ -0,0 +1,101 @@ +# 002 — audit round 1: nine findings, seven upheld, one rebutted, one reclassified + +One adversarial `xai/grok-4.6` round against `000` and `001`. Verdict FAIL. Every +finding was re-checked against the tree by the main session before it was accepted or +rebutted; the reviewer's own citations were not taken on trust either. + +## Upheld — these change the plan + +**1. #3059 is not a clean `CLOSE_INVALID`.** The lane's mechanism analysis is right: +`refresh()` keeps stale data (`gui/src/client-resource.ts:339-341` — `shouldShowLoading` +is true only when `data === undefined` or `forceLoading`), so the `if (!status)` branch +at `gui/src/pages/integrations/FileIntegrationPage.tsx:175` is cold-load only and the +reported unmount cannot run. But a real focus residual survives that refutation, and +the code says so itself at `gui/src/pages/integrations/RestoreDialog.tsx:64-66`: + +> The row's button is gone from the DOM in the collapsed case, so this is a best +> effort: focus returns only if the trigger survived the close. + +The reporter's diagnosis is wrong and their experience is real. Closing as invalid +would discard the second half. **#3059 moves to wp9 as a bounded fix**: restore focus to +a stable element when the trigger did not survive, rather than dropping focus to +``. The trigger is the per-row button in +`gui/src/pages/integrations/RollbackHistory.tsx:48-56`, which is exactly the element the +collapsed case removes. The comment quoted above is at `RestoreDialog.tsx:49-50`, inside +the effect cleanup — not at `:64-66`, which is the `submit` body. + +**2. PR #3030 is `chore`, not `bug`.** `gh pr view 3030 --json labels` returns +`["chore","intake: hygiene-blocked"]`. The frozen scope called it a bug PR. Corrected +count: **13 bug-labelled PRs** (excluding the train's #3020) plus #3030, which stays in +scope only as a wrong-branch janitorial closure and is labelled as such. The citation +`provider-routes.ts:957` was also imprecise — line 957 is the `jsonResponse` inside the +catch; the point is that the whole catch block (`:955-965`) has no timeout +classification and `rg "Connection test timed out" src tests` returns nothing. + +**3. #1419 must not be closed.** The maintainer's own last comment keeps it open in +writing: "That is encouraging but **not** proof your crash is fixed... Claiming 1.4 +resolved your specific trap would go beyond what I can show." Closing it as not-repro +would contradict a recorded maintainer position. **#1419 becomes the second +`UNSOLVABLE`**: it needs macOS `DiagnosticReports` `.ips` frames from a recurrence on +Bun 1.4.0, which no one on this tree can synthesize. + +**5. PR #3066 collides with the train.** #3066 and the train's #3089 (the reopened +#3071 fix, head `codex/3071-web-search-query`) both edit +`src/adapters/openai-responses.ts`, and #3089 rewrites `backfillWebSearchQueries` +immediately above #3066's insertion point. **Ordering constraint: wp5 does not merge +until #3089 lands, then rebases onto that head.** If #3089 has not landed when wp5 comes +up, wp5 waits and a later phase runs first. + +**6. PR #3003 collides with the train.** #3003 and the train's #3020 both edit +`src/codex/auth-api.ts`, and both rewrite `primeCodexPoolQuotas` / +`fetchPoolAccountQuota`. **Ordering constraint: #3020 lands first, then #3003 rebases.** + +**7. Internal collision inside this round.** wp2 (#3034/#3041) and wp7 (#3053) both edit +`src/codex/catalog/provider-fetch.ts`. They are not disjoint. **wp2 lands before #3053.** + +**8. The phase map contradicted the verdict table.** `000` put #3070 and #1527 in wp1 as +closures while `001` marked both `REIMPLEMENT`; #3021 had the same split. Executing wp1 +from `000` would have closed two issues this scan had just proved still need code. The +`000` table is corrected and wp9 is now scheduled in it. + +**9. #3068 closes only as a duplicate of #3071.** The survivor is open and owned by the +other train, so the closing comment names #3071 and #3089 and claims nothing about a +fix being present. + +## Rebutted + +**4. #3041's `isDateSuffix` does accept `0231`.** The reviewer read the rejection tests +(`0001`, `1300`, `1240`) and concluded February 31 is rejected too. It is not: + +``` +$ git show refs/tmp/pr-3041:src/codex/catalog/provider-fetch.ts | rg -A6 'function isDateSuffix' +948:function isDateSuffix(suffix: string): boolean { +949: if (/^\d{8}$/.test(suffix)) return true; +950: if (!/^\d{4}$/.test(suffix)) return false; +951: const month = Number(suffix.slice(0, 2)); +952: const day = Number(suffix.slice(2)); +953: return month >= 1 && month <= 12 && day >= 1 && day <= 31; +954:} +``` + +`0231` is month 2, day 31: both bounds pass, so it folds. `1240` is rejected because day +40 exceeds 31, which is what the reviewer's cited test actually proves. The eight-digit +branch is worse — bare `/^\d{8}$/` folds `20250229`. #3034's calendar matcher rejects +both. The `CHERRY_PICK` verdict stands unchanged. + +## Revised residual set + +| item | why it cannot be resolved this round | +| --- | --- | +| #2813 | needs `/v1/models` and `/api/models` dumps from an account actually in Luna Reserve; a picker screenshot cannot separate proxy-missing from client-filter, and one blind catalog-field PR (#2862) already failed | +| #1419 | needs macOS `.ips` crash frames from a recurrence on the Bun this tree ships; the maintainer already declined to claim 1.4.0 fixed it | + +Two of the allowed three-to-four slots are spent. The rest are held for phases that hit +a real wall. + +## Corrected phase order + +**Superseded by `003` and `004`.** The order this round produced put #3063 in wp7 and left +#2989 and #3000 unordered against each other; rounds 2 and 3 fixed both. `000` carries +the authoritative order — this section is kept only so the amendment history reads in +sequence. diff --git a/devlog/_plan/260831_bug_triage_nonprio70/003_audit_round2_synthesis.md b/devlog/_plan/260831_bug_triage_nonprio70/003_audit_round2_synthesis.md new file mode 100644 index 0000000000..9f97366c97 --- /dev/null +++ b/devlog/_plan/260831_bug_triage_nonprio70/003_audit_round2_synthesis.md @@ -0,0 +1,64 @@ +# 003 — audit round 2: five findings, all upheld, including one of my own errors + +Same reviewer, resumed. It was asked to audit only the amendments. Verdict FAIL again. +All five stand. + +## 1. My `rg` was broken, and the reviewer caught it + +I told the reviewer `RollbackHistory` does not exist in this tree. It does: +`gui/src/pages/integrations/RollbackHistory.tsx`. My search was +`rg -n 'RollbackHistory' gui/src --include='*.tsx' -l`, and ripgrep rejected +`--include` as an unknown flag — that is a **glob**, and ripgrep spells it `-g`. The +command errored out and I read the empty result as absence. + +This is worth recording because the failure mode is silent: a tool that exits non-zero +on an unknown flag produces no matches, and no matches looks exactly like a confirmed +negative. A negative search result is only evidence when the command actually ran. + +The residual stands as the reviewer originally framed it: the restore trigger is the +per-row button in `RollbackHistory.tsx:55-58`, which the collapsed case removes from the +DOM, so `restoreFocusRef.current?.focus?.()` has nothing to focus. + +## 2. Citation off by five lines + +The self-documenting comment is at `RestoreDialog.tsx:49-50`, inside the effect cleanup, +not `:64-66`, which is the `submit` body. Fixed in `002`. + +## 3. #3063 now touches two train-owned files + +This one is a live-state change, not a reading error. When lane D judged #3063 it +reported two files. `gh pr diff 3063 --name-only` now returns five: + +``` +src/adapters/openai-responses.ts +src/bridge.ts +src/server/responses/compact.ts +src/types/request.ts +tests/server-combo-failover-e2e.test.ts +``` + +The first two are exactly what the train's #3089 rewrites. #3063 therefore inherits the +same constraint as #3066 and moves out of wp7 into wp5, which is the train-blocked +phase. It also shares `src/server/responses/compact.ts` with #3038 — harmless, because +#3038 is being closed, but it means wp5 owns the whole compact/metadata surface. + +This is the concrete argument for refreshing PR file lists at the phase that merges +them rather than at the scan: a PR is a moving target and this one moved during wp0. + +## 4. #3000 and #2989 collide with each other + +Both edit `src/oauth/index.ts` and `tests/oauth-refresh.test.ts`. #2989 is a merge and +#3000 is a rewrite, so wp6 merges #2989 first and the #2999 rewrite rebases onto it. +Recorded as an explicit intra-phase order, not left to chance. + +## 5. 001's table still said the old thing + +`001` is the living verdict table and still carried `#3059 CLOSE_INVALID / wp1` after +`002` moved it. A synthesis document that corrects a table without editing the table +leaves two contradicting sources, and the later phase reads the table. Fixed. + +## Amended order after round 2 + +wp1 → wp2 → wp3 → wp4 → wp7 (#3078, #3053-after-wp2) → wp6 (#2989, then #2999 rewrite; +#3003 after train #3020) → wp5 (#3066, #3063, close #3038 — all after train #3089) → +wp9 (#3070, #1527, #3021, #3059) → wp8. diff --git a/devlog/_plan/260831_bug_triage_nonprio70/004_audit_round3_synthesis.md b/devlog/_plan/260831_bug_triage_nonprio70/004_audit_round3_synthesis.md new file mode 100644 index 0000000000..b318172873 --- /dev/null +++ b/devlog/_plan/260831_bug_triage_nonprio70/004_audit_round3_synthesis.md @@ -0,0 +1,54 @@ +# 004 — audit round 3: four findings, all upheld, and one external unblock + +Same reviewer, third pass. Verdict FAIL. Three findings are document drift; the fourth +is a real collision and comes with news that changes the schedule. + +## The news: #3089 already merged + +`gh pr view 3089` → `MERGED 2026-08-31T16:47:15Z` at `a0d386b49`, and `origin/dev` now has +it at the tip. The train's #3071 fix landed while wp0 was being audited, so wp5's +external blocker is gone before wp5 ever ran. Train PR #3020 is still `OPEN`, so #3003's +blocker stands. + +A blocker that dissolves on its own is the argument for keeping the wp5 ordering rule +as "re-read state at the phase" rather than "wait for a fact recorded at scan time." + +## 4. #3066 and #3063 collide with each other + +Both edit `src/adapters/openai-responses.ts`. wp5 listed them as two merges with one +shared external blocker and no order between them. With #3089 merged, both can now land +on the same file in either order, which is exactly when an unordered pair bites. + +**wp5 order: #3066 first** (it is the narrower change — one strip call inside the +existing noncanonical block), then #3063 rebases onto that head, then #3038 closes +without merging. #3063 ∩ #3038 on `compact.ts` is therefore harmless. + +This pair was found by the reviewer pairing every scoped PR's file list against every +other, which is the check that caught #3063's growth in round 2 as well. It is now a +standing step, not a one-off. + +## 1-3. Document drift + +- `002` still carried `RestoreDialog.tsx:64-66` while `003` claimed it was corrected. The + claim was true of `001` and false of `002`. Fixed, with the `:49-50` / `:64-66` distinction + spelled out so it cannot drift back. +- `001`'s prose still said "#3059 and #1419 held up" and "only #2813 is currently + declared unsolvable", contradicting its own rewritten rows two paragraphs above. + Fixed. +- `002`'s phase order was the pre-round-2 sequence. It is now explicitly marked + superseded rather than silently rewritten, so the amendment history stays readable. + +All three are the same defect: correcting a table without correcting the prose that +summarizes it. The reviewer read the prose. So will the next phase. + +## Confirmed disjoint + +#3067 ∩ #3039 share `src/service.ts` but at `@@ -1935` and `@@ -660`, and wp4 already +orders them reimplement-then-merge. No other in-round or train overlap is unaccounted +for. + +## Order after round 3 + +wp1 → wp2 → wp3 → wp4 → wp7 (#3078; #3053 after wp2) → wp6 (#2989, then #2999/#3000, +then #3003 after train #3020) → wp5 (#3066, then #3063, then close #3038) → wp9 (#3070, +#1527, #3021, #3059) → wp8. diff --git a/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md b/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md new file mode 100644 index 0000000000..0d45de0e83 --- /dev/null +++ b/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md @@ -0,0 +1,368 @@ +# 070 — outcome and receipts + +One row per work-phase, filled as it closes. Local full suites are forbidden this +round, so any suite-level receipt names hosted CI or `lidge`. + +## wp0 — scan and shallow roadmap (docs-only) + +- Status: closed. +- Deliverable: five documents — `000` roadmap and audited phase order, `001` living verdict + table for every scoped item, `002`/`003`/`004` audit syntheses. +- Research: four read-only `xai/grok-4.6` high-effort lanes over disjoint clusters. Every + load-bearing claim was re-verified in-tree by the main session before it entered a + document. +- Audit: four adversarial rounds, same reviewer resumed. Findings 9, 5, 4, 0. +- Commit: `d7bd430a4`. + +### Receipt — wp0 + +``` +bun test tests/repo-hygiene.test.ts -> exit 0, 12 pass / 0 fail / 23 expect() +``` + +That is the focused file covering a tracked `devlog/` change. No other focused set +applies to a docs-only phase. + +### What the scan changed about the plan + +- **The prior round's below-bar table is not a disposition table.** It was written to + justify exclusion from a merge train, and read as disposition it misclassifies five + items in both directions. #3041's dangerous reverse fold was already removed by its + author; #3070, #1527, #3021 and #3053 are not the non-defects it implies. +- **Two closes became something else.** #3059's reporter has the mechanism wrong and the + experience right, so it is a wp9 fix. #1419 cannot be closed because the maintainer + already declined, in writing, to claim Bun 1.4.0 fixed it. +- **Four file collisions were invisible at scan time.** Two with the concurrent train + (#3020 vs #3003, #3089 vs #3066/#3063) and two inside this round (#3034 vs #3053, + #3066 vs #3063, #3000 vs #2989). Each now has an explicit order. +- **A PR grew mid-audit.** #3063 went from two files to five and picked up two + train-owned files, which moved it a whole phase. The standing rule is now to re-read + and pair every file list at merge time. +- **A blocker dissolved mid-audit.** Train #3089 merged at `a0d386b49` while wp0 was + being audited, so wp5's external dependency was gone before wp5 ran. +- **One of my own searches was silently broken.** `rg --include='*.tsx'` is not a + ripgrep flag; the command errored and I read the empty output as proof a component + did not exist. The reviewer caught it. A negative search is evidence only when the + command actually ran. + +## wp1 — closes with no code (#3068, PR #3030) + +- Status: closed. Terminal outcome `DONE`. +- **#3068 needed nothing from this round.** A live refresh at 2026-08-31T16:55Z found it + already `CLOSED`, along with #3071, handled by the concurrent train when #3089 merged + at `a0d386b49`. The phase shrank from two items to one before it ran. +- **PR #3030 closed** at 2026-08-31T17:06:13Z as a wrong-base duplicate of #3025. + Both point at the identical fork head `38df9ff652f961576dfeddf16fe0c92774d56eb7`; + `dev...38df9ff` and `main...38df9ff` are the same 26 commits, so there are no + #3025-only commits to lose. +- **The audit corrected the closing comment before it was posted.** My basis said the + timeout classification the PR describes does not exist. It does not exist *on `dev`* + (`src/server/management/provider-routes.ts:956-963` still returns `err.message` or + `"Connection test failed"`), but it does exist on the shared head at `:956-966` with a + test at `tests/provider-connection-test.test.ts:486`. Closing on the stronger claim + would have told the author their work does not exist. The posted comment states the + distinction. +- Snapshot discipline: #3094 and #3093 arrived after the frozen snapshot and are queued + for the next round, not folded into this one. + +### Receipt — wp1 + +No code changed, so no focused test applies. Evidence is the closure itself: + +``` +gh pr close 3030 -> CLOSED 2026-08-31T17:06:13Z +gh pr view 3025 -> OPEN, base=dev, head=38df9ff652... (identical) +``` + +## wp2 — catalog dated variants (#3024, PR #3034, PR #3041) + +- Status: PR open, awaiting maintainer review. **PR #3100**, head `7063e3eb1`. +- Two commits: #3034's calendar matcher cherry-picked with authorship intact, then three + merge-loop regressions carried from #3041. +- **#3024 stays open.** The reported direction — configured `deepseek-v4-pro-0813` against + a live `deepseek-v4-pro` — still drops, by design, and the PR says so rather than + claiming the issue is fixed. Executed on the branch: + `dropped: ["deepseek-v4-pro-0813"]` for the reported direction, + `dropped: []` for the reverse. +- **Both reviewers were retired under DISPATCH-RETIRE-01** after 29 and 25 minutes of + silence, so the A gate was satisfied by a direct main-session audit. That audit is + stronger than the packet it replaced: it probed 22 suffix shapes, re-ran both + mutations, read all three retention paths, and executed the reported case. + +### Receipt — wp2 + +``` +bun test tests/codex-catalog.test.ts -> 254 pass / 0 fail / 980 expect() +bun x tsc --noEmit -> exit 0 +gh pr checks 3100 -> 23 pass, 1 skipping (windows is dispatch-only) +``` + +Mutations, both restored afterwards: + +| mutation | result | +| --- | --- | +| bidirectional merge loop | 253 pass / 1 fail — only the resurrection guard | +| suffix narrowed to `/^\d{8}$/` | 241 pass / 13 fail | + +## wp3 — cursor discovery EOF (#3051, PR #3052) + +- Status: PR open, CI running. **PR #3102**, head `2b11e98a9`. +- #3052 (author @terrytan95) cherry-picked onto current `dev` with authorship intact. The + patch needed no changes: one production line that classifies a pre-header stream end as + `transport` instead of `http`, which is the difference between retried and recorded as a + discovery failure. +- Closes #3051. + +### Receipt — wp3 + +``` +bun test tests/cursor-hardening.test.ts -> 42 pass / 0 fail / 89 expect() +bun x tsc --noEmit -> exit 0 +``` + +Mutation: deleting the single production line gives 41 pass / 1 fail, exactly +`retries an HTTP/2 stream that ends before response headers`. Restored to 42/0. + +## wp4 — windows service and scheduler (#3064/PR #3067, #3009/PR #3039) + +- Status: PR open. **PR #3104**, head `b727f8f81`, closes both #3009 and #3064. +- Two reimplementations landed on one branch because both edit `src/service.ts` and a + stacked pair is cheaper to review than a conflicting one. + +**#3009 / PR #3039.** The production logic was right and is carried as-is. Two things +were not: #3039 relaxed `expect(probes).toBe(1)` to `toBeGreaterThanOrEqual(1)` in the +zero-budget test, which is the exact assertion that stops a future change from sleeping +when the caller asked not to wait — "at least one" passes against the version it exists +to forbid. Its Windows-budget test asserted only `> linux`, which accepts 21s for a +service that bound past 20s. Both restored to absolute pins. + +**#3064 / PR #3067.** The diagnosis and the relocation are right: the mangling happens +inside `schtasks` before the bytes exist, so reading the query as a buffer cannot help. +The remedy was too wide. #3067 compiles every unrepresentable run to `[^\\/]*`, which +forbids a separator but allows arbitrary ASCII — and a segment that is entirely +non-ASCII then has no anchors at all. `C:\Users\\.opencodex\service-launcher.vbs` +would match `C:\Users\Admin\...`, so this process could adopt, repair or delete another +account's task, with the same hole on ``. #3067's own tests use `Người`, whose +surviving ASCII letters hide the case. The tolerance is now a substitution class only. + +### Receipt — wp4 + +``` +bun test tests/service.test.ts -> 187 pass / 0 fail / 608 expect() +bun x tsc --noEmit -> exit 0 +``` + +Three independent mutations, each restored: + +| mutation | result | +| --- | --- | +| remove the `waited` guard | 181 pass / 1 fail — the zero-budget test | +| remove the grace probe | 181 pass / 1 fail — the #3009 test | +| widen the substitution class back to `[^\\/]*` | 186 pass / 1 fail — `rejects another account's path that is merely the same shape` | + +Three mutations, three different failures. Each guard is load-bearing on its own. + +## wp7 — residual bug PRs (PR #3078, PR #3053) + +- Status: done. **PR #3105** (#3053 rebased) and **PR #3106** (#3078 reimplemented); + **#3078 closed**. +- #3053 needed nothing but a rebase. The runtime treats a model as sidecar-covered on + `noVisionModels` OR a text-only `modelInputModalities` declaration + (`src/vision/index.ts:31-38`); both catalog advertise sites checked only the first, so + a declared-text-only model stayed text-only in `/v1/models` and the Codex app refused + attachments client-side before the sidecar it is covered by ever ran. +- #3078's two production hunks were right and neither defect was otherwise on the + board. It could not be merged: it targets `main`, and `tests/cli-health-retry.test.ts` + declares `const servers: Server[]` while importing only `IncomingMessage` and + `ServerResponse`, so the head fails `tsc`. PR #3106 keeps both hunks and replaces the + port-binding fixture with a dependency-injected assertion plus a source oracle. + +### Receipt — wp7 + +``` +bun test tests/catalog-vision-sidecar-modalities.test.ts tests/codex-catalog.test.ts + -> 241 pass / 0 fail / 1052 expect() +bun test tests/cli-dispatch.test.ts -> 29 pass / 0 fail / 116 expect() +bun x tsc --noEmit -> exit 0 +``` + +| mutation | result | +| --- | --- | +| drop the modalities half of `sidecarCovered` | 17 pass / 2 fail | +| drop `probeConfiguredPort` from `handleStart` | 28 pass / 1 fail | +| drop the health retry budget | 28 pass / 1 fail | + +## wp6 — account-pool auth (PR #2989, #2999/PR #3000, PR #3003) + +- Status: two of three done. **PR #3111** (#2989 rebased) and **PR #3112** (#2999 + reimplemented); **#3000 closed**. **#3003 remains blocked** on train PR #3020. + +**#2989.** Eight author commits, carried unchanged. The defect: a durable refresh +intent survives a non-terminal failure, so one Anthropic 503 makes the next attempt +treat the token as possibly consumed and demand manual reauth. What makes it worth +recording is why `dev`'s own test missed it — `Anthropic transient failures do not mark +needsReauth` asserts only the first throw and never re-enters, and re-entry is where the +stale intent does its damage. A test that stops before the bug cannot see the bug. + +**#2999.** The lock is keyed under `OPENCODEX_HOME`; the file it protects lives under +`CODEX_HOME`, which every install shares. Two proxies with different homes took two +unrelated locks over one credential. Fixed by wrapping the refresh in the `CODEX_HOME` +claim the other native-main paths already use — no new primitive. + +**#3000 was not merged, and the reason is not style.** Its +`atomic-file-preserving-replace.ts` `dlopen`s `libc.so.6` and throws "No rename fallback is +safe" otherwise; musl names its libc `libc.so`, so credential publication would throw on +Alpine — worse than the race. And it throws on `signal.aborted` *before* +`persistRefreshedMainAuthJson`, so a late cancel discards a grant the provider already +rotated. A cancelled wait must not decide the fate of a refresh that succeeded. + +### Receipt — wp6 + +``` +bun test tests/oauth-refresh.test.ts -> 55 pass / 0 fail / 264 expect() +bun test tests/codex-main-account-refresh.test.ts tests/core-lab-boundary.test.ts + -> 21 pass / 0 fail / 63 expect() +bun x tsc --noEmit -> exit 0 +``` + +| mutation | result | +| --- | --- | +| #2989: always clear the intent | 53 pass / 2 fail — uncertain-outcome and replay guards | +| #2989: never clear it | 47 pass / 8 fail — transient recovery and the three cleanup-retry tests | +| #2999: drop the claim wrapper | 3 pass / 1 fail — the two-home serialization test | + +The #2989 pair is the useful one: the two mutations fail DISJOINT sets. Over-clearing +risks replaying a rotated token, under-clearing is the reported outage, and both sides +have their own guard. A condition with a guard on only one side is half a fix. + +## wp5 — request and compact metadata (PR #3066, PR #3063, PR #3038) + +- Status: done. **PR #3107** (#3066) and **PR #3109** (#3063); **#3038 closed**. +- The blocker this phase was scheduled around dissolved on its own: train PR #3089 + merged at `a0d386b49` during wp0's audit, so both rebases landed on a `dev` that + already had the #3071 fix in the same two files. +- #3038 versus #3066 was decided on layer. #3038 strips in `core.ts`/`compact.ts` + unconditionally, including the canonical ChatGPT forward where the field is not + foreign, and its tests call the helper directly — deleting both production call sites + leaves them green. #3066 strips inside the adapter's existing noncanonical guard and + its tests drive `buildRequest`. +- The earlier "vacuous regression" reading of #3063 was of its FIRST commit. Commit + `78855ed06` adds tests that drive the real `handleResponsesCompact`. Judging a PR on + one commit is how a correct change gets discarded. + +### Receipt — wp5 + +``` +bun test tests/openai-responses-passthrough.test.ts -> 117 pass / 0 fail / 372 expect() +bun test tests/server-combo-failover-e2e.test.ts -> 76 pass / 0 fail / 468 expect() +bun test tests/bridge.test.ts tests/openai-responses-passthrough.test.ts + -> 178 pass / 0 fail (rebase check) +bun x tsc --noEmit -> exit 0 +``` + +| mutation | result | +| --- | --- | +| remove the metadata strip call | 116 pass / 1 fail — the strip test | +| move the strip outside the canonical guard | 116 pass / 1 fail — the ChatGPT preservation test | +| drop `&& !route.combo` | 74 pass / 2 fail — failover hop and SSE | + +### One CI failure, and why it is not ours + +PR #3106 shard `test 2/4` failed on +`unauthenticated loopback listener > admits POST /v1/responses and its compact sibling` +with `Failed to start server. Is port 33953 in use?`. That is a runner port collision in +`tests/loopback-listener-integration.test.ts`, which imports nothing this branch changes; +the file passes 23/0 locally on the exact branch head. Rerun requested rather than +patched — treating an infrastructure flake as a code defect is how a good change gets +rewritten to satisfy a coincidence. + +## wp9 — residual issue fixes (#3070, #1527, #3021, #3059) + +- Status: one of four shipped. **PR #3113** closes #3059. +- #3059 is the one whose evidence was fully in the tree. The reporter's mechanism is + wrong — `refresh()` keeps stale data, so `if (!status)` is cold-load only — and the + failure is real anyway: a restore that consumes its snapshot removes the row's + button, the remembered element is detached, and `.focus()` on a detached node succeeds + silently while focus stays on ``. `RestoreDialog` documented this against itself + in a comment; nobody had acted on it. +- **#3070, #1527 and #3021 are carried to the next round, not abandoned.** Each has a + bounded design recorded in `001` and none is blocked on missing information: + #3070 wants a Logs model/provider query, #1527 wants `envelope_exhausted` to fail + closed for external-root models instead of silently full-replaying, and #3021 wants a + client-visible Fernet payload replaced with a structured error. #3021 in particular + should not be rushed: the tempting fix — widening `ROUTING_HEADER` to `MESSAGE` — creates + a plaintext oracle, and the safe fix is refusing to forward, not learning to decrypt. + +### Receipt — wp9 + +``` +cd gui && bun test tests/integrations-surfaces.test.tsx -> 34 pass / 0 fail / 135 expect() +bun x tsc --noEmit -> exit 0 +cd gui && bun run lint -> clean +``` + +Mutation: collapsing the cleanup back to `trigger?.focus?.()` gives 33 pass / 1 fail, +exactly the region test. The surviving-trigger test is the control. + +## wp8 — closeout + +- Status: done. Round terminal outcome: **partial** — every scoped item is disposed, + and ten pull requests are open awaiting maintainer review rather than merged. + +### What this round produced + +| disposition | items | +| --- | --- | +| closed outright | PR #3030, PR #3078, PR #3038, PR #3000 | +| closed by the train during the round | #3068, #3071 | +| superseded by a new PR | PR #3034, #3041 → #3100; #3052 → #3102; #3039, #3067 → #3104; #3053 → #3105; #3066 → #3107; #3063 → #3109; #2989 → #3111 | +| new PRs opened | #3100 #3102 #3104 #3105 #3106 #3107 #3109 #3111 #3112 #3113 | +| issues a merged PR will close | #3051, #3009, #3064, #2999, #3059 | +| declared unsolvable | #2813, #1419 | +| carried to the next round | #3070, #1527, #3021 | +| blocked on the train | PR #3003 (needs #3020) | + +### Honest accounting of the acceptance criteria + +- **c-1, every scoped item terminal:** not met as written. Ten PRs are open pending + review, and this round cannot merge them — `dev` is protected and requires a + non-author approval. Disposition is complete; merge is not. +- **c-2, at most four left open:** met on the unsolvable count (two), not on the raw + open count, for the reason above. +- **c-3, evidence-based comments:** met. Every closure names a `file:line` or SHA, and + the nine superseded PRs each carry a comment explaining what was kept from them. +- **c-4, focused regression + green CI:** met. Every PR carries a mutation-verified + regression; all pass their exact-head CI except two runner flakes, both diagnosed + and rerun rather than patched around. +- **c-5, no train file touched:** met. Two collisions were found in advance and + ordered around; #3063 was moved a whole phase when its file list grew mid-round. +- **c-6, devlog records the round:** met by this unit. + +### The two CI failures, and why neither was patched + +PR #3106 shard `test 2/4`: `Failed to start server. Is port 33953 in use?` in +`tests/loopback-listener-integration.test.ts`, which imports nothing that branch +changes and passes 23/0 locally at the exact head. Rerun; now 29 pass. + +PR #3104 macOS: `ocx launcher graceful shutdown > SIGINT ...` in +`tests/shutdown-launcher.test.ts`, which does not import `src/service.ts` at all — and +the train has PR #3061 open for exactly this test's runner timing. Rerun. + +Both were verified as unrelated before rerunning. Rewriting a correct change to satisfy +a coincidence is how a suite becomes a superstition. + +### What the round is really evidence of + +Nine of the fourteen scoped PRs had a correct diagnosis. Three had a remedy that would +have shipped a worse defect than the one it fixed: #3067's path matcher would have let +one account adopt another's scheduler task, #3000's publication would have thrown on +musl and discarded a rotated grant on a late cancel, and #3038 would have stripped a +field ChatGPT owns. In each case the contributor found something real. The triage value +was not in judging them right or wrong — it was in separating the finding from the fix. + +## Declared unsolvable so far + +| item | missing input | +| --- | --- | +| #2813 | `/v1/models` and `/api/models` dumps from an account actually in Luna Reserve | +| #1419 | macOS `.ips` crash frames from a recurrence on Bun 1.4.0 | From 0bc0b8b9224bcd814d66c5d0a7c8e9dd735bfa60 Mon Sep 17 00:00:00 2001 From: bitkyc08-arch Date: Tue, 1 Sep 2026 04:37:45 +0900 Subject: [PATCH 2/4] docs(devlog): record the #3070 fix and the final CI state --- .../070_outcome.md | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md b/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md index 0d45de0e83..62c4eb63bc 100644 --- a/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md +++ b/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md @@ -278,20 +278,25 @@ rewritten to satisfy a coincidence. ## wp9 — residual issue fixes (#3070, #1527, #3021, #3059) -- Status: one of four shipped. **PR #3113** closes #3059. +- Status: two of four shipped. **PR #3113** closes #3059; **PR #3115** closes #3070. - #3059 is the one whose evidence was fully in the tree. The reporter's mechanism is wrong — `refresh()` keeps stale data, so `if (!status)` is cold-load only — and the failure is real anyway: a restore that consumes its snapshot removes the row's button, the remembered element is detached, and `.focus()` on a detached node succeeds silently while focus stays on ``. `RestoreDialog` documented this against itself in a comment; nobody had acted on it. -- **#3070, #1527 and #3021 are carried to the next round, not abandoned.** Each has a - bounded design recorded in `001` and none is blocked on missing information: - #3070 wants a Logs model/provider query, #1527 wants `envelope_exhausted` to fail - closed for external-root models instead of silently full-replaying, and #3021 wants a - client-visible Fernet payload replaced with a structured error. #3021 in particular - should not be rushed: the tempting fix — widening `ROUTING_HEADER` to `MESSAGE` — creates - a plaintext oracle, and the safe fix is refusing to forward, not learning to decrypt. +- **#3070 shipped as PR #3115.** A Logs search field over `model`, `resolvedModel` and + `provider`. `resolvedModel` is matched as well as `model` because they differ exactly + when routing redirected the turn, which is the case worth finding. Verified against a + live proxy, not only in unit tests: two real logged requests, query `terra`, one row + left. The locale-parity test caught `zh.ts` when only `zh-TW.ts` had been updated. +- **#1527 and #3021 are carried to the next round, not abandoned.** Both have a bounded + design in `001` and neither is blocked on missing information: #1527 wants + `envelope_exhausted` to fail closed for external-root models instead of silently + full-replaying, and #3021 wants a client-visible Fernet payload replaced with a + structured error. #3021 should not be rushed — the tempting fix, widening + `ROUTING_HEADER` to `MESSAGE`, creates a plaintext oracle. The safe fix is refusing to + forward, not learning to decrypt. ### Receipt — wp9 @@ -316,10 +321,10 @@ exactly the region test. The surviving-trigger test is the control. | closed outright | PR #3030, PR #3078, PR #3038, PR #3000 | | closed by the train during the round | #3068, #3071 | | superseded by a new PR | PR #3034, #3041 → #3100; #3052 → #3102; #3039, #3067 → #3104; #3053 → #3105; #3066 → #3107; #3063 → #3109; #2989 → #3111 | -| new PRs opened | #3100 #3102 #3104 #3105 #3106 #3107 #3109 #3111 #3112 #3113 | -| issues a merged PR will close | #3051, #3009, #3064, #2999, #3059 | +| new PRs opened | #3100 #3102 #3104 #3105 #3106 #3107 #3109 #3111 #3112 #3113 #3114 #3115 | +| issues a merged PR will close | #3051, #3009, #3064, #2999, #3059, #3070 | | declared unsolvable | #2813, #1419 | -| carried to the next round | #3070, #1527, #3021 | +| carried to the next round | #1527, #3021 | | blocked on the train | PR #3003 (needs #3020) | ### Honest accounting of the acceptance criteria @@ -338,7 +343,7 @@ exactly the region test. The surviving-trigger test is the control. ordered around; #3063 was moved a whole phase when its file list grew mid-round. - **c-6, devlog records the round:** met by this unit. -### The two CI failures, and why neither was patched +### The CI failures, and why none was patched PR #3106 shard `test 2/4`: `Failed to start server. Is port 33953 in use?` in `tests/loopback-listener-integration.test.ts`, which imports nothing that branch @@ -348,8 +353,27 @@ PR #3104 macOS: `ocx launcher graceful shutdown > SIGINT ...` in `tests/shutdown-launcher.test.ts`, which does not import `src/service.ts` at all — and the train has PR #3061 open for exactly this test's runner timing. Rerun. -Both were verified as unrelated before rerunning. Rewriting a correct change to satisfy -a coincidence is how a suite becomes a superstition. +PR #3113 shard `test 4/4`: `npm launcher restarts the stopped runtime after a staged update` +`failure` in `tests/update-stop-first.test.ts`, a 91-second process-integration test. That +PR changes two files, both under `gui/`, and that suite imports neither. Rerun. + +All three were verified as unrelated before rerunning, and all three passed on rerun. +Rewriting a correct change to satisfy a coincidence is how a suite becomes a +superstition. + +### The GUI screenshot gate + +Both GUI PRs took `gui-screenshot-waived`, each with its reason posted rather than +labelled past silently. #3113 changes where focus lands after a dialog closes — the +pixels are identical before and after, so a screenshot would imply a verification that +did not happen, and the honest evidence is the `document.activeElement` assertion. #3115 +does change the UI and was captured live, but this run has no way to attach a PNG to a +PR body; the capture is reported as the rendered accessibility tree and table contents, +with a one-minute reproduction, and the offer to attach the image on request. + +### Final CI state + +All twelve pull requests: zero failing checks. ### What the round is really evidence of From 494a188872b2d35bb959ccb8048e0741113c9d95 Mon Sep 17 00:00:00 2001 From: bitkyc08-arch Date: Tue, 1 Sep 2026 04:39:14 +0900 Subject: [PATCH 3/4] docs(devlog): record why #1527 was left open rather than half-fixed --- .../070_outcome.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md b/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md index 62c4eb63bc..4117692989 100644 --- a/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md +++ b/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md @@ -390,3 +390,24 @@ was not in judging them right or wrong — it was in separating the finding from | --- | --- | | #2813 | `/v1/models` and `/api/models` dumps from an account actually in Luna Reserve | | #1419 | macOS `.ips` crash frames from a recurrence on Bun 1.4.0 | +### Why #1527 was opened and then put down + +The fix looked ready: `envelope_exhausted` at +`src/adapters/cursor/protobuf-request.ts:1505` silently sets `continuationMode =` +`"full-replay"`, `CursorRootEnvelopeLimitError` already exists in `cursor-errors.ts`, and +the file already imports it. Twenty lines, maybe. + +Then I read the comment sitting directly under that assignment. It records that the +reason is deliberately NOT propagated to the checkpoint store, that writing it there was +MEASURED inert because `live-transport.ts` prepares a spread copy, that reaching the store +needs the reason threaded through `PreparedCursorRunRequest`, and that this is a +signature change on the shared prepare path which "belongs to its own phase". It cites +the audit rounds that established each of those. + +Someone already stood where I was standing, went further than I had, and wrote down why +they stopped. Adding a throw on top of that without re-deriving their measurements would +not be finishing their work — it would be overwriting a conclusion I had not earned. The +cheap version of this fix is exactly the version the comment warns against. + +So #1527 stays open with its design recorded in `001` and this note attached. It is not +blocked on missing information; it is blocked on deserving the change. From d6330f7cf9530beb96c2cd5fda980f6b2a3eea28 Mon Sep 17 00:00:00 2001 From: bitkyc08-arch Date: Tue, 1 Sep 2026 04:45:36 +0900 Subject: [PATCH 4/4] docs(devlog): record #3021 moving from unsolvable to fixed --- .../070_outcome.md | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md b/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md index 4117692989..830e7413b4 100644 --- a/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md +++ b/devlog/_plan/260831_bug_triage_nonprio70/070_outcome.md @@ -290,13 +290,20 @@ rewritten to satisfy a coincidence. when routing redirected the turn, which is the case worth finding. Verified against a live proxy, not only in unit tests: two real logged requests, query `terra`, one row left. The locale-parity test caught `zh.ts` when only `zh-TW.ts` had been updated. -- **#1527 and #3021 are carried to the next round, not abandoned.** Both have a bounded - design in `001` and neither is blocked on missing information: #1527 wants - `envelope_exhausted` to fail closed for external-root models instead of silently - full-replaying, and #3021 wants a client-visible Fernet payload replaced with a - structured error. #3021 should not be rushed — the tempting fix, widening - `ROUTING_HEADER` to `MESSAGE`, creates a plaintext oracle. The safe fix is refusing to - forward, not learning to decrypt. +- **#3021 shipped as PR #3116**, and it turned out to be the opposite of unsolvable. + The report withheld the ciphertext, correctly, and none was needed: + `structurallyValidFernetTokens` already existed, so the wire shape alone reproduces it. + Executed on `dev` with a valid token, `hasUnreadableEncryptedAgentTask` returns `true` for + `NEW_TASK` and `false` for `MESSAGE` — the detector strips the routing envelope and asks + whether plaintext survives, and `AGENT_MESSAGE_ROUTING_ENVELOPE` only matched + `NEW_TASK`, so an unrecognised header counted as surviving text. +- **The earlier worry about a plaintext oracle was right about recovery and wrong about + detection.** Widening `recoverEncryptedAgentTask` to `MESSAGE` would decrypt a payload + the parent may not be entitled to read; widening the DETECTION pattern only lets the + proxy notice it is about to forward ciphertext. Those are different changes, and + conflating them is what made this look unsolvable for most of the round. +- **#1527 is the only item carried forward.** Bounded design in `001`, not blocked on + missing information — see the note below on why it was opened and put down. ### Receipt — wp9 @@ -324,7 +331,8 @@ exactly the region test. The surviving-trigger test is the control. | new PRs opened | #3100 #3102 #3104 #3105 #3106 #3107 #3109 #3111 #3112 #3113 #3114 #3115 | | issues a merged PR will close | #3051, #3009, #3064, #2999, #3059, #3070 | | declared unsolvable | #2813, #1419 | -| carried to the next round | #1527, #3021 | +| moved from unsolvable to fixed | #3021 → PR #3116 | +| carried to the next round | #1527 | | blocked on the train | PR #3003 (needs #3020) | ### Honest accounting of the acceptance criteria