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
120 changes: 120 additions & 0 deletions devlog/_plan/260806_stacked_bug_campaign/000_plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# 000 — Plan: stacked bug campaign with contributor attribution (2026-08-06)

## Objective

Land a maintainer-authored **stacked PR chain** (`stack 01..N`) against `dev`
that covers the great majority of open bug issues and open contributor bug/fix
PRs at the 2026-08-06 cutoff, **crediting every original contributor by name**.

The campaign explicitly does *not* merge contributor PRs. Each contributor's
work is either cherry-picked with authorship preserved or reimplemented with a
`Co-authored-by:` trailer plus a named citation of their PR/issue. Their PR then
receives a comment saying where their work landed and that their name went with
it.

## Base

| Fact | Value |
|------|-------|
| Worktree | `/Users/jun/.codex/worktrees/42d5/opencodex` |
| Cutoff snapshot | 2026-08-06T13:49:07Z (`.snapshot_issues.json`, `.snapshot_prs.json`) |
| Snapshot base | `origin/dev` = `43a1fdc45` |
| Working base | `origin/dev` = `e9d957bf6` (advanced during triage when #1129 merged) |
| Stack branch prefix | `codex/260806-stackNN-<slug>` |
| Open at cutoff | 49 issues, 34 PRs |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Record the verified 32-PR cutoff

The cutoff is recorded here as 34 PRs, but 002_pr_triage.md:1-8 lists and independently states that exactly 32 PRs were open at this same cutoff, and 160_phase17_closeout.md:51-52 uses 32 as the required reconciliation total. Leaving 34 here makes the campaign's frozen base internally inconsistent, so update this value to 32.

Useful? React with 👍 / 👎.

Comment thread
coderabbitai[bot] marked this conversation as resolved.

`e9d957bf6` is the working base because #1129 merged mid-triage; the two extra
commits are the maintainer's own restore-watchdog test margin and its merge.
No in-scope item depends on the difference.

## Scope rules

In scope:

- Bugs and code-level bug-like defects open at the cutoff.
- Contributor PRs that fix such a defect, whatever their state (draft,
conflicting, over-scoped) — the *fix* is what matters, not the packaging.

Out of scope, recorded with a reason rather than silently dropped:

- Items opened after the cutoff.
- Feature programs (provider onboarding, cost overlay, remote E2EE, OMP,
account-picker slices, localization mega-PRs).
- Roadmap/tracking issues and upstream-owned defects.
- `needs-info` issues with no reproduction on the current tree.
- Maintainer PRs already in flight (`#557`, `#1008`) — left alone deliberately.
- Release automation, version bumps, and any publish action.

## Method

`cxc-loop` HOTL over `cxc-pabcd`. Work-phase 1 (this unit) is docs-only: freeze
the snapshot, triage everything, and write every implementation phase's decade
doc to diff-level precision. Implementation begins at work-phase 2, one decade
doc per PABCD cycle, one stack PR per cycle.
Comment on lines +50 to +53

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Align the stack-unit definition with the final chain.

These lines define one stack PR per phase. The final disposition combines phases 10 and 11 in #1137, phases 9 and 14 in #1139, and phases 12 and 13 in #1144. Define a stack slice as the unit, or split the combined stack entries.

Also applies to: 76-77

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@devlog/_plan/260806_stacked_bug_campaign/000_plan.md` around lines 50 - 53,
Update the stack-unit definition in the cxc-loop/cxc-pabcd plan, including the
corresponding section at the later referenced lines, to match the final chain:
define a stack slice as the unit, or split the combined phase entries so phases
10/11, 9/14, and 12/13 map to their respective stack PRs.


Triage was executed by four parallel sol-medium lanes (two issue lanes, two PR
lanes), each required to confirm the defect against the current tree with
`path:line` citations rather than restating the reporter's claim. Their verdicts
are recorded in `001_issue_triage.md` and `002_pr_triage.md`.

## Attribution contract (the point of this campaign)

Every stack commit that derives from contributor work carries:

1. `Co-authored-by: <Display Name> <email>` using the identity from the
contributor's own commits on their PR head.
2. A commit body naming the source PR and, where applicable, the issue.
3. A PR description crediting the contributor in prose, not only in a trailer.

Where a fix is reimplemented rather than cherry-picked, the contributor is still
credited — they found the defect and proved the code path, which is the
expensive part. The reimplementation reason is stated plainly in the PR body so
the record is honest in both directions.

## Work-phase map

Dependency-ordered. Each row is one PABCD cycle and one stacked PR; each stacks
on the previous head, and stack 01 targets `dev`.

| Phase | Doc | Subject | Issue | Source PR(s) | Credited |
|-------|-----|---------|-------|--------------|----------|
| 1 | (this unit) | Triage + roadmap | — | — | — |
| 2 | `010` | Bounded translated-SSE inspection | #1112 | #1114 | ingwannu |
| 3 | `020` | Empty native-profile stage sweep | #1120 | #1124 | ingwannu |
| 4 | `030` | Native-main ACL timeout retry | — | #1130 | luvs01 |
| 5 | `040` | Bounded rollout inspection | — | #1115 | Simon |
| 6 | `050` | Anthropic response-model identity | #1117 | #1122, #1121 | Giulio Leone, ingwannu |
| 7 | `060` | GitHub Copilot Responses normalization | #1110 | #1111 | Simon |
| 8 | `070` | Darwin eager rewrite relay gate | #1127 | #947 | 0xWinner98, biao |
| 9 | `080` | Vision raw-body image synchronization | — | #1047 | Bailey |
| 10 | `090` | Gemini/CCA reasoning-effort documentation + coverage | — | #978 | Pranav Yerramaneni |
| 11 | `100` | Routed structured-output schema preservation | — | #985 | Pranav Yerramaneni |
| 12 | `110` | Cursor structured-edit conversion | #1017 | #1036 | NexusCore |
| 13 | `120` | Reasoning-replay empty-delta handoff | — | #1126 | NexusCore |
| 14 | `130` | Usage-log attempt persistence | — | #1093 | Takashi Yamashiro |
| 15 | `140` | Effort-picker fail-closed + Pi loopback export | — | #1092, #1085 | Eachann, n3wr1ch |
| 16 | `150` | Test-home isolation + Desktop allowlist docs | #241 | #997, #999 | Yuxin Qiao |
| 17 | `160` | Closeout: attribution comments, full suite, dispositions | — | — | — |

Phase order puts small merge-clean adoptions first so the stack has a stable
base, then the larger adapted reimplementations. Phases 2-5 are near-verbatim
adoptions; 6-15 are adapted or reimplemented.

## Verification floor per implementation phase

- `bun run typecheck` exit 0
- the phase's focused test files, 0 failures
- `bun run privacy:scan` green
- `bun run lint:gui` + `bun run build:gui` when the phase touches `gui/`
- one full `bun run test` near the end of the campaign

A remembered pass is not evidence; each phase records its command output.

## Authorization boundary

Authorized for this campaign: pushing `codex/260806-stack*` branches, creating
the stack PRs, and commenting on superseded contributor PRs.

Not authorized without a fresh request: merging anything, closing any PR or
issue, force-pushing contributor branches, pushing `dev`/`main`/`preview`,
deleting branches, npm publish, releases.
75 changes: 75 additions & 0 deletions devlog/_plan/260806_stacked_bug_campaign/001_issue_triage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# 001 — Issue triage (49 open at the 2026-08-06T13:49Z cutoff)

Two sol-medium lanes classified every open issue against the working tree.
Rule applied: a reporter's claim is not evidence — each verdict cites the code
path that proves or refutes it. Snapshot: `.snapshot_issues.json`.

## Classification key

| Class | Meaning |
|-------|---------|
| `FIXABLE` | Real defect with a bounded fix; enters the stack |
| `LARGE` | Real defect, but program-scale; deferred with reason |
| `UPSTREAM` | Not fixable in this repository |
| `NEEDS_INFO` | Cannot be confirmed on the current tree |
| `FEATURE` | Enhancement, not a bug |

## In-scope defects (enter the stack)

| # | Reporter | Class | Proof on the current tree | Phase |
|---|----------|-------|---------------------------|-------|
| 1112 | lidge-jun | FIXABLE | `trackSseForRequestLog` (`src/server/relay.ts:353`) appends into `buffer` inside `inspectChunk` at `:382` with no cap and re-parses each payload through three string helpers; `relaySseWithHeartbeat` (`:498`) repeats the same unbounded append at `:540` | 010 |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the trackSseForRequestLog anchor.

The supplied source context starts trackSseForRequestLog at src/server/relay.ts:354, but this row cites line 353. Use the exact symbol line so the triage evidence remains directly verifiable.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@devlog/_plan/260806_stacked_bug_campaign/001_issue_triage.md` at line 21,
Update the line reference for trackSseForRequestLog in the triage row from 353
to its actual declaration line, 354, while preserving the existing issue
description and related inspectChunk and relaySseWithHeartbeat references.

| 1120 | MarcusNeufeldt | FIXABLE | `runOwnedStageSweep` (`src/codex/native-profile-startup.ts:131`) always calls `entry.manager.sweepStages()`, and `sweepStages` (`src/codex/native-profile-manager.ts:916`) enters the locked path (`sweepStagesLocked`, `:828`) even with zero artifacts | 020 |
| 1117 | giulioleone097 | FIXABLE | `applyFinalRouteRequestNormalization` (`src/server/responses/core.ts:856`, called at `:1532`) overwrites `parsed.modelId` with the bare upstream id; the image loop then emits that value (`src/images/loop.ts:903`), as do the JSON/streaming and web-search paths | 050 |
| 1110 | Simon-Opopeee | FIXABLE | The `github-copilot` entry (`src/providers/registry.ts:2043`) declares `adapter: "openai-chat"` at `:2046`; Responses is forced per model by `modelWireDefaults` at `:2060-2067`. Those responses reach the Responses relay, which composes only generic image/id/snapshot repairs — no Copilot-specific normalization exists | 060 |
| 1127 | 0xWinner98 | FIXABLE | `selectEagerPath` (`src/lib/bun-stream-caps.ts:99`) returns null whenever `needsClientRewrite` is set (`:106`), and its Darwin tail admits only `config-eager` (`:112`); inline payload rewrite and budget remain Win32-only in `core.ts` | 070 |
| 1017 | Vincent-HD | FIXABLE | Codex's freeform custom tool is exposed as a single-string `input` parameter (`src/responses/parser.ts:167-173`); the Cursor adapter emits normalized arguments with no structured-edit conversion (`src/adapters/cursor/protobuf-events.ts`, tool-call emission path) | 110 |
| 241 | Lingchen97 | UPSTREAM (docs) | Routed rows are emitted with `visibility = "list"` (`src/codex/catalog/sync.ts:240`); the Desktop allowlist is outside this repo. Documented workaround only | 150 |

## Real but program-scale (deferred, reason recorded)

| # | Reporter | Why deferred |
|---|----------|--------------|
| 1102 | comfuture | Non-loopback requires credentials (`src/server/auth-cors.ts:211`) and Responses accepts only the dedicated header (`auth-cors.ts:369`); token inheritance exists only when the shim is the parent (`src/codex/shim.ts:381`). Transparent hand-off to a directly spawned binary needs a new trust/admission design |
| 1059 | lidge-jun | Windows suite failures cross temp-write, ACL, replacement, journal, catalog, and coordinator paths (`src/config.ts:198-219`, `src/codex/internal/catalog-writer.ts:47`). Run 31095755263 failed all four shards. No subset can be honestly proven fixed from macOS — injected I/O tests cannot establish Windows ACL inheritance, replacement semantics, or real cross-process SQLite locking |
| 1049 | lidge-jun | Pre-substrate homes are classified `legacy-uncoordinated` (`src/codex/inject-coordination.ts:24`) and bypass the lock (`src/codex/inject.ts:870`). Crash-safe adoption is migration-grade work needing its own recovery matrix |

## Upstream-owned (no repo-side fix exists)

| # | Reporter | Evidence |
|---|----------|----------|
| 92 | webmastertorch | The proxy recognizes valid Fernet task content but holds no key (`src/server/responses/encrypted-payload.ts:204`) and now rejects routed delivery cleanly (`src/server/responses/core.ts:1507`). Plaintext must be retained upstream — openai/codex#33551 |
| 417 | lidge-jun | The relay forwards bytes without decode/re-encode (`src/server/index.ts:305`); the Korean/1.3 MB regression is an ancestor of HEAD. Upstream openai/codex#35161 |
| 1100 | c3right | OpenCodex advertises effort levels but strips inherited summary capability conservatively (`src/codex/catalog/parsing.ts:341`); explicit per-model opt-in works (`src/codex/catalog/effort.ts:139`). Codex gates its whole reasoning object on the summary flag before ingress |

## Needs reproduction (cannot be confirmed on the current tree)

| # | Reporter | What is missing |
|---|----------|-----------------|
| 1128 | c040340 | The asserted missing policy is not borne out: DeepSeek disables upstream SSE (`src/providers/registry.ts:1310`), `core.ts:874` applies it, and routed `/responses/compact` re-enters `handleResponses` (`src/server/responses/compact.ts:553`) |
| 1024 | brunoflma | NVIDIA Nemotron is text-only by classification (`src/providers/registry.ts:658`); MiMo is excluded because the measured endpoint accepts images (`registry.ts:363`). The remaining custom route needs its provider config |
| 994 | hamzasoussi53 | The suspected zen DeepSeek path is fixed with coverage (`src/providers/registry.ts:1967`, `tests/opencode-zen-deepseek-reasoning.test.ts:55`), but the report never identifies provider/model |
| 904 | lidge-jun | Relay paths are byte-clean (`src/server/index.ts:305`); needs a failing client/provider capture |
| 796 | hooliy-01 | Ark hosts receive the structured placeholder (`src/adapters/openai-chat.ts:546`), but no live Ark endpoint verifies acceptance (`tests/volcengine-ark-assistant-content.test.ts:16`) |
| 418 | brunoflma | The latest trace completed on an inherited native model because `model` was omitted; it did not reproduce the original custom-parent→custom-child failure |

## Features / roadmap (out of scope for a bug campaign)

`#1125`, `#1107`, `#1091`, `#1086`, `#1082`, `#1076`, `#1073`, `#1062`, `#1060`,
`#1058`, `#1048`, `#974`, `#823`, `#822`, `#821`, `#820`, `#809`, `#755`, `#695`,
`#657`, `#572`, `#561`, `#540`, `#415`, `#414`, `#386`, `#201`, `#178`, `#177`,
`#95`.

Spot-checked rather than assumed: `#1086` (tri-state `fastMode` already applied
at `src/server/responses/core.ts:903`; only the per-model map is missing),
`#1073` (runtime already resolves `modelContextWindows[id]` then provider
`contextWindow` at `src/codex/catalog/provider-fetch.ts:528`), `#809` (every
`/api/*` route is management-authenticated at `src/server/index.ts:676`, so a
data-plane catalog route is a new security-sensitive API), and `#1048` (reduced
scope already merged in #1106).

## Coverage

7 issues enter the stack, 3 are real-but-large, 3 upstream, 6 need
reproduction, 30 are features/roadmap. Total 49 — every open issue accounted
for.
Loading
Loading