Skip to content

Commit d35592b

Browse files
authored
merge dev into main for the v2.32.1 release
release: promote dev into main for v2.32.1
2 parents 96e2f67 + bb89eaf commit d35592b

27 files changed

Lines changed: 2996 additions & 25 deletions
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
# 000 — v2.32.1 hotfix train: baseline, scope, and work-phase map
2+
3+
Unit opened 2026-08-24. Session `01a0339b-4c6e-73e3-8890-23f65c5bbd46`.
4+
Goalplan slug `prepare-opencodex-dev-as-the-verified-release-ca`.
5+
6+
## Baseline correction
7+
8+
The planning note this unit started from was written against a v2.31 baseline.
9+
That baseline is void. Verified live on 2026-08-24:
10+
11+
| Ref | SHA | Meaning |
12+
|-----|-----|---------|
13+
| `origin/dev` | `c44e43f00` | Merge of #2453 (wait yield_time_ms underscore) |
14+
| `origin/main` | `96e2f67c3` | `release: v2.32.0` |
15+
16+
```
17+
git merge-base --is-ancestor origin/dev origin/main -> exit 0 (dev IS an ancestor of main)
18+
git merge-base --is-ancestor origin/main origin/dev -> exit 1
19+
git rev-list --count origin/dev..origin/main -> 27
20+
git rev-list --count origin/main..origin/dev -> 0
21+
git diff --name-status origin/dev origin/main -> M package.json
22+
git show origin/main:package.json -> "version": "2.32.0"
23+
```
24+
25+
Three facts follow, and they set the entire unit:
26+
27+
1. **The next release is v2.32.1, not v2.31.1.** v2.32.0 is already published from
28+
`main` (`npm` `latest` = 2.32.0, GitHub release `v2.32.0` targets `96e2f67c3`).
29+
A 2.31.x number would move backwards over a shipped release.
30+
2. **`dev` and `main` have NOT diverged.** `dev` is an *ancestor* of `main`:
31+
0 commits ahead, 27 behind. The 27 are main-side promotion and release commits
32+
accumulated since 2.25.0. This was recorded incorrectly in the first draft of
33+
this document — the original text read the one-way `--is-ancestor` result as
34+
divergence. Corrected here after an independent audit re-ran both directions.
35+
3. **The net tree delta is one line.** `main` carries `version: 2.32.0`; `dev`
36+
still says `2.27.0` because release bumps are made on the promotion commit and
37+
never flow back. Nothing else differs.
38+
39+
### What wp1 therefore is
40+
41+
Because `dev` is strictly behind `main`, `git merge origin/main` on `dev` is a
42+
**fast-forward**, not a merge commit. That is the intended operation and it is
43+
recorded as such: wp1 advances `dev` to `96e2f67c3` so the release lineage and
44+
the version line are one. `git merge-tree` confirms the only content change:
45+
46+
```
47+
git merge-tree $(git merge-base origin/dev origin/main) origin/dev origin/main
48+
- "version": "2.27.0",
49+
+ "version": "2.32.0",
50+
```
51+
52+
`bun.lock`, `scripts/release.ts`, and `.github/workflows/release.yml` are
53+
untouched. **Mandatory post-condition: `dev` package.json reads exactly
54+
`2.32.0`.** Keeping `2.27.0` would regress the release ledger; bumping to
55+
`2.32.1` belongs to the promotion commit, not to wp1.
56+
57+
## Why bugfix-only
58+
59+
The open queue is far larger than one train can absorb: 46 open PRs, 25 of them
60+
draft, 21 `review-ready`, 11 `intake: hygiene-blocked`, plus 67 open issues.
61+
Merging by availability rather than by risk is how a hotfix release grows a
62+
regression radius it cannot verify. This train is capped at five runtime fixes
63+
plus one repository-infrastructure fix, each of which closes a defect class that
64+
is *currently user-visible on the shipped v2.32.0*.
65+
66+
## Included units
67+
68+
| # | PR | Defect class it closes |
69+
|---|-----|------------------------|
70+
| wp3 | #2483 | Model unusable — capitalized/dotted Claude vendor ids take the legacy `thinking.enabled` wire and get a 400 |
71+
| wp4 | #2481 | Catalog inconsistency — slash-bearing models vanish from the picker while direct calls still work |
72+
| wp5 | #2473 | Thread unrecoverable — a >16 MiB turn repeatedly dies on the WS transport with no SSE escape |
73+
| wp6 | #2477 | Tool authorization boundary — namespace aliases restored outside the caller's `tool_choice` |
74+
| wp7 | #2476 | Disk/CPU amplification — a ~24 MiB snapshot rewritten every two seconds unchanged |
75+
| wp2 | #2427 | Verification cost — the full suite reads as hung, which pushes contributors toward unverified merges |
76+
77+
## Excluded, with reason
78+
79+
Excluded because they widen the regression radius, not because they lack value:
80+
81+
- **#1905** per-model compaction budgets — 27 files, `+813/-80`, touches config,
82+
management, and catalog. First candidate for v2.33.0.
83+
- **#2418** subagent scoped cooldown — 8 files, `+2044/-111`, changes routing,
84+
credential admission, quota probing, and encrypted recovery together. Needs its
85+
own security lane.
86+
- **#2470** Google thought-signature — three unrelated concerns in one PR
87+
(signature replay, output clamps, Windows fixtures). Must be split.
88+
- **#2475** Kiro tool-search priority, **#2425** xAI hosted `x_search`,
89+
**#2429** `test:changed` — not release blockers; #2429 is stacked on #2427.
90+
- **#2462** and every OAuth / remote-dashboard / hosted-SaaS / billing PR —
91+
product-direction and security-boundary changes, currently hygiene-blocked.
92+
- All 11 `intake: hygiene-blocked` PRs, by policy.
93+
94+
## Work-phase map (dependency order)
95+
96+
The order is a dependency chain, not a difficulty ranking. Each phase consumes
97+
the verified output of the one before it.
98+
99+
```
100+
wp0 docs (this unit)
101+
102+
└─ wp1 dev fast-forward to main (v2.32.0) [every later head depends on it]
103+
104+
├─ wp3 #2483 anthropic ids ┐
105+
├─ wp4 #2481 selectedModels │ runtime fixes, merged
106+
├─ wp5 #2473 oversized WS ├─ sequentially, each verified
107+
├─ wp6 #2477 namespace authz [sec review] │ on the SERIAL runner
108+
├─ wp7 #2476 snapshot writes [conditional]┘
109+
│ │
110+
│ └──── all of wp3..wp7 must be merged-or-deferred ────┐
111+
│ │
112+
└─ wp9 #2472 mixed-sequence regression │
113+
[independent of wp3..wp7; may run any time after wp1]│
114+
│ │
115+
└──────────────┬───────────────────────────┘
116+
117+
wp2 #2427 test runner [LAST, or deferred]
118+
119+
wp8 freeze + GO/NO-GO
120+
[requires wp3..wp7, wp9, and wp2]
121+
```
122+
123+
The join is explicit because the ordering rule is easy to lose in a tree
124+
drawing: **wp2 does not start until every runtime phase has a terminal
125+
outcome.** It is drawn as a sibling of nothing — it is downstream of all of
126+
them.
127+
128+
### Why #2427 moved to the end (audit amendment)
129+
130+
The first draft put #2427 first, reasoning that landing the verification
131+
instrument early means every later phase is verified by the same runner. The
132+
A-phase auditor argued the opposite and it is the stronger argument: #2427
133+
switches the suite from serial isolated execution to file-parallel isolated
134+
execution (`scripts/test.ts` default becomes `bun test --isolate --parallel
135+
./tests/`), and its own PR body reports **7 failures across 902 files** on its
136+
exact head. Landing an unproven runner first makes every subsequent runtime
137+
failure ambiguous: flakiness from parallel shared-state contention would be
138+
indistinguishable from a regression introduced by the runtime PR under test.
139+
140+
A verification instrument must be changed against a known-good baseline, not
141+
used to establish one. #2427 therefore runs LAST, immediately before freeze, and
142+
only with a pre/post gate: the runtime phases are verified on the serial runner,
143+
then #2427's head must produce a green exact-head `bun run test` plus required
144+
cross-platform CI. If it does not, it is deferred and the train proceeds on the
145+
existing runner. It is a convenience, never a blocker.
146+
147+
wp8 depends on **every** runtime phase, not only on the phase drawn above it.
148+
149+
## Out of scope for this unit (STRICT)
150+
151+
No `dev` -> `main` promotion, no tag, no npm publish, no release workflow
152+
dispatch, no version bump beyond what the backmerge carries. This unit ends at a
153+
frozen, verified `dev` SHA plus a GO/NO-GO report. Promotion is a human decision.
154+
155+
## Verification doctrine
156+
157+
Exact-head evidence only. A remembered green run is not evidence. Every phase
158+
closes with fresh command output captured at the SHA being claimed, and every
159+
merge is proven with its merge SHA plus
160+
`git merge-base --is-ancestor <merge> origin/dev`.
161+
162+
## Known defects already shipped in v2.32.0 (audit amendment)
163+
164+
v2.32.0 is the v2.27.0-line tree plus a version bump, so every defect open
165+
against 2.31.0 also ships in 2.32.0. The audit was right that a hotfix train
166+
without this ledger is choosing its scope blind. Dispositions:
167+
168+
| Issue | Defect | Fixing PR | Disposition | NO-GO? |
169+
|-------|--------|-----------|-------------|--------|
170+
| #2407 | Kiro drops tools loaded by `tool_search` | #2475 (draft, red suite) | Decide at wp2/wp8 on exact-head evidence; include only if it goes green before freeze | No |
171+
| #2458 | Gemini 3.7 Flash video input 502 — routed provider emits undeclared client tool `get_video_duration` | none | Defer: the candidate fix touches the undeclared-tool guard, the same authorization surface wp6 is hardening. Two changes to one guard in one hotfix is exactly the regression radius this train exists to avoid | No |
172+
| #2459 | Windows bare npm reinstall can leave a live proxy on a mixed old/new module graph | none | Defer: install/service surface, not a runtime defect the proxy can fix mid-session; needs its own unit | No |
173+
174+
None forces NO-GO, but each is now a recorded decision rather than an omission.
175+
If any acquires a verified fix before freeze it may be reconsidered — the
176+
inclusion bar stays exact-head green plus review, not urgency.
177+
178+
## Two review-ready PRs the first draft did not mention (audit amendment)
179+
180+
- **#2474** (`fix(scripts): run ocx-run commands in the requested workdir`) —
181+
a real defect: `scripts/ocx-run:128` never enters the requested workdir.
182+
But root `package.json` excludes `scripts/` from the published artifact, so it
183+
cannot affect the shipped runtime. **This train does not use `ocx-run` in any
184+
verification step**, so it is deferred as repository-operations work rather
185+
than included. If a later phase adopts `ocx-run` for verification, this
186+
becomes a prerequisite and must be pulled in first.
187+
- **#2432** (docs, `__omit__` reasoning-effort sentinel) — currently
188+
`CHANGES_REQUESTED` with unfixed table formatting. Excluded pending its
189+
requested changes; docs-only work does not need a hotfix train.
190+
191+
## Per-phase verifiers (audit amendment, PLAN-VERIFIER-REAL-01)
192+
193+
The auditor ran the baseline commands and proved they pass while observing none
194+
of the planned fixes:
195+
196+
```
197+
bun run typecheck -> exit 0, 0.60s
198+
bun test tests/namespace-tool-compat.test.ts \
199+
tests/selected-models.test.ts \
200+
tests/anthropic-reasoning.test.ts -> 67 pass 0 fail, exit 0
201+
```
202+
203+
Green there means nothing yet: on current `dev`,
204+
`tests/selected-models.test.ts:15` has no slash-bearing selector,
205+
`tests/anthropic-reasoning.test.ts:53` has no capitalized/dotted id, and
206+
`tests/namespace-tool-compat.test.ts:239` hand-builds an alias map without ever
207+
testing `tool_choice` authorization. That run is a **preflight**, not fix
208+
evidence.
209+
210+
Each phase therefore names its own verifier, run at that phase's exact merge
211+
head, plus the specific assertion that must newly exist:
212+
213+
| Phase | Verifier command | Assertion that must be present after merge |
214+
|-------|------------------|--------------------------------------------|
215+
| wp3 #2483 | `bun test tests/anthropic-reasoning.test.ts` | capitalized + dotted + dashed + date-pinned ids classify correctly, and the explicit-disable caller is covered |
216+
| wp4 #2481 | `bun test tests/selected-models.test.ts tests/codex-catalog.test.ts tests/slug-codec.test.ts` | an encoded slug in `selectedModels` keeps a slash-bearing model visible at the route/sync level, not only in the helper |
217+
| wp5 #2473 | `bun test tests/ws-upstream.test.ts tests/sse-failed-tail.test.ts` | oversized frame opens zero sockets; adjacent-byte boundary routes WS vs SSE |
218+
| wp6 #2477 | `bun test tests/namespace-tool-compat.test.ts tests/responses-parser.test.ts` | a foreign tool-type selector authorizes no alias and restores no call |
219+
| wp7 #2476 | `bun test tests/responses-state-write-amplification.test.ts tests/responses-state.test.ts` | unchanged flush does not rewrite; deleted snapshot is regenerated; eviction order unchanged |
220+
| wp2 #2427 | `bun run test` (full, exact head) + cross-platform CI | exit 0 |
221+
| wp8 | `bun run typecheck`, `bun run test`, `bun run privacy:scan` at the frozen SHA | all exit 0 |
222+
223+
## The #2472 canary, restated (audit amendment)
224+
225+
The original criterion — a 100-call zero-output canary — is not a feasible gate
226+
as written, and the audit demonstrated why. The proxy currently listening on
227+
:10100 is PID 922, started 2026-08-23: the **stale process from the bug report
228+
itself**, not a frozen candidate. Worse, the defect needs Cursor
229+
native-shell/host-shell interleaving with duplicate call ids; duplicates are
230+
already dropped at `src/adapters/cursor/protobuf-events.ts:1055` while the two
231+
execution paths stay separate at `src/adapters/cursor/live-transport.ts:1445`.
232+
An ordinary local prompt cannot deterministically produce that sequence, so a
233+
"100 calls, zero empty results" run would prove nothing while spending real
234+
provider credits and restarting the user's live proxy.
235+
236+
Restated criterion: the mandatory gate is an **automated mixed-sequence
237+
regression** driving the interleaved native/host shell path with duplicate call
238+
ids, asserting a typed error or failover instead of a silent empty success.
239+
A live canary stays **optional and separately authorized**: isolated port and
240+
config, disposable workdir, the exact frozen SHA, a bounded call budget, and
241+
teardown evidence. Restarting PID 922 is not part of this unit.
242+
243+
**That regression does not exist and no included PR writes it**, which the
244+
second audit round correctly called out: a mandatory gate with no implementing
245+
phase is a wish, not a gate. It therefore gets its own work-phase, **wp9**,
246+
documented at `090_wp9_issue2472_mixed_sequence_regression.md`. wp9 is
247+
independent of wp3–wp7 and may run any time after wp1, but it must have a
248+
terminal outcome before freeze. If wp9 concludes the sequence cannot be driven
249+
deterministically in-process, #2472 is recorded as an explicitly deferred known
250+
defect and **stops being a GO criterion** — with that finding written down,
251+
rather than left as an unmet checkbox.

0 commit comments

Comments
 (0)