-
Notifications
You must be signed in to change notification settings - Fork 917
fix(config): validate codexToolMode; test(types): pin barrel re-export identity #2119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dd07be5
759e999
95b98d9
58ceae3
8bfe087
67c787b
6c359d6
8024c84
c9894bb
a2d4cb7
7290371
bf01d20
6b21bd8
11a6d98
bf3a7fe
c054d48
0ac3ba1
9eb1b75
a77ee5d
cc738c0
914013e
e4f0730
83306e1
1f06d4f
9ba4d44
5343d9a
963f524
ce97e67
b0c8620
d697e25
b84f8e5
8f0c1e6
f788aff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,153 @@ | ||
| # 260819 — Next roadmap (post-triage, post-cleanup) | ||
|
|
||
| > **Status: executed 2026-08-19.** R1-R4 are closed; see `050_execution_ledger.md` | ||
| > for what happened and `060_outcome.md` for the closeout. Two sections of this | ||
| > document were corrected by audit lanes during execution — the corrections are | ||
| > in `010` and `030`, and the reasons are in `050`. Read this file for the | ||
| > sequencing decision, not for current PR state. | ||
|
|
||
| Baseline: dev @ 3ad904e03 (local, 1 ahead of origin/dev 63bfd149d). | ||
| Inputs: the 260819 triage-execution outcome (12 merged, 5 downgraded), the | ||
| 260818 mega-file split risk assessment, and a live read of 53 open PRs / | ||
| 75 open issues on 2026-08-19. | ||
|
|
||
| This document is a sequencing decision, not an inventory. The inventory is in | ||
| `260819_triage_execution/030_outcome.md`; what follows is what to do next and | ||
| in what order, with the constraint that makes the order non-arbitrary. | ||
|
|
||
| ## The one constraint that orders everything | ||
|
|
||
| Five files carry the repository: `responses/core.ts` (4532), `config.ts` | ||
| (3987), `service.ts` (3387), `registry.ts` (2692), `types.ts` (1884). | ||
| The split program wants to move all of them. Twenty-plus open PRs edit them. | ||
| A split lands as a whole-file rewrite, so **every open PR touching a split | ||
| file is rebased onto moved code the moment the split merges.** | ||
|
|
||
| The 000_risk_assessment already named this ("never interleave"). What has | ||
| changed since it was written is that the interleaving already happened: the | ||
| WP1 stack sat while 102 commits landed on dev, and it now conflicts. | ||
|
|
||
| So the order is: **drain the contributor queue first, split second.** Not | ||
| because the split is less valuable, but because the split's cost is | ||
| proportional to the size of the queue it has to rebase, and the queue is the | ||
| thing that decays if left alone. | ||
|
|
||
| ## R1 — Unblock the split stack (this week, small) | ||
|
|
||
| The WP1 types stack is the cheapest split and it is currently the most | ||
| expensive to leave alone: it conflicts with dev today and the conflict grows | ||
| with every `types.ts` edit. | ||
|
|
||
| | PR | State | Action | | ||
| |---|---|---| | ||
| | #2019 WP1 | draft, 102 behind, red CI | rebase onto dev, re-run; the red is stale-base, not the change | | ||
| | #2023 WP1b | draft, child of #2019 | rebase after parent; green on its own base already | | ||
| | #2036 WP2a | draft, 42 behind | rebase; independent of WP1 | | ||
|
|
||
| **The red CI on #2019 is not a defect in the change.** Its failing shard | ||
| asserts `invalidateCodexModelsCacheWithPermit(permit, owningCodexHome)`, | ||
| a string that exists on the PR head and no longer exists on dev — dev removed | ||
| it in `6c0bde453`. The PR is running dev's newer test file against its own | ||
| older source. Three other shards fail the same way (hidden raw reasoning, | ||
| Command Code catalog, GUI models page). A rebase is the whole fix. | ||
|
|
||
| Both stacks also fail `hygiene: missing_regression_test`, which is correct | ||
| and not waivable by rebase: a pure-move PR changes `src/` without changing a | ||
| test. The honest resolution is `test-exception-approved`, not a decorative | ||
| test — the barrel's oracle is the existing 400-file import surface, and a new | ||
| test asserting "the barrel re-exports X" restates the compiler. | ||
|
|
||
| ## R2 — Land the response-temp stack (ready now) | ||
|
|
||
| `#2084` (sweeper) and `#2089` (doctor) are the only PRs of ours that are | ||
| green, hygiene-clean, and 5 commits behind. `#2089` is `CLEAN`; `#2084` is | ||
| `BLOCKED` only by the review requirement. | ||
|
|
||
| Merge order is forced: `#2084` to dev, then retarget `#2089` from | ||
| `codex/tmp-reclaim-1-sweeper` to dev. Do not merge the child first. | ||
|
|
||
| This closes a real user-visible defect (multi-GB temp accumulation across | ||
| reboots) and the design holds up on read: the boot floor retires a vacuous | ||
| PID probe rather than claiming a file is dead, `eligible` is reported instead | ||
| of `matched` so the operator is not told live temps are abandoned, and the | ||
| dry run shares one predicate with the reclaim so report and removal cannot | ||
| disagree. | ||
|
|
||
| ## R3 — Resolve the duplicate-fix collisions (before more arrive) | ||
|
|
||
| Three PRs fix the same `prompt_cache_retention` bug (#2092) three different | ||
| ways, and they are mutually incompatible: | ||
|
|
||
| | PR | Scope | Consequence | | ||
| |---|---|---| | ||
| | #2091 | strip for all ChatGPT-backend Responses | broadest; also drops it where a deployment honors it | | ||
| | #2099 | strip for `gpt-5.6*` prefix, forward mode | wrong branch (targets main) | | ||
| | #2102 | strip for `gpt-5.6`/`gpt-5.6-`, passthrough | narrowest and most precise | | ||
|
|
||
| Pick one and close the other two with the reason. On the evidence in the | ||
| issue, #2102's model-scoped strip is the defensible default: the backend's | ||
| cache behavior varies by deployment, so a global strip silently removes a | ||
| parameter some accounts accept. | ||
|
|
||
| A second collision: `#2056` and `#2062` both address K12 short-window quota, | ||
| and `#2062` targets main. | ||
|
|
||
| **Eight PRs currently target `main` and are auto-labeled `[WRONG BRANCH]`:** | ||
| #2110, #2109, #2099, #2082, #2063, #2062, #2032, #2029. These cannot merge | ||
| as-is. Retarget or close — leaving them open costs contributor goodwill and | ||
| re-triage time on every pass. Note that #2099 and #2062 appear in the | ||
| collision lists above, so retargeting them and picking a winner is one | ||
| decision, not two. | ||
|
|
||
| ## R4 — The `modelRecordValue` family (one review, four PRs) | ||
|
|
||
| `#2077`, `#2085`, `#2086`, `#2100` are the same fix applied at four call | ||
| sites: a bare `map[modelId]` lookup where the runtime uses `modelRecordValue`, | ||
| so a `gpt-oss` entry fails to cover `gpt-oss:120b`. They are independent, | ||
| small, and each carries a focused test. | ||
|
|
||
| Review them as one batch with one shared verdict on the contract, then merge | ||
| individually. Reviewing them separately spends four reviews on one idea. | ||
|
|
||
| `#2077` additionally fixes a real crash path: a routed model id of | ||
| `constructor` or `toString` returned an `Object.prototype` function through | ||
| the prototype chain, which made `buildBehaviorFingerprintV1` throw inside a | ||
| linker that contractually does not throw. | ||
|
|
||
| ## R5 — Then, and only then, the split program | ||
|
|
||
| Resume at WP2b (the stateful config train) with the sequencing rule from | ||
| 000_risk_assessment intact: one work package per PR train, service and | ||
| registry never in the same change, Wave C never mixed with behavior fixes. | ||
|
|
||
| The rule that matters most is the oracle rule: a guard test rewritten in the | ||
| same PR as the code it guards must be driven red once against a deliberate | ||
| violation. `core-lab-boundary` and `repo-hygiene` already follow it; WP5 | ||
| Wave C rewrites seven source-invariant tests and cannot be exempt. | ||
|
|
||
| ## What this roadmap deliberately does not do | ||
|
|
||
| - **No new feature work is scheduled.** The queue has 53 open PRs; adding | ||
| scope before draining it makes the split more expensive, not less. | ||
| - **`#1704` (combo quota badges) stays parked.** It is 817 commits behind and | ||
| `CONFLICTING`. It is a re-cut, not a rebase, and it should be re-cut against | ||
| the GUI as it exists after the split — not before. | ||
| - **The Antigravity stack (#2068-#2071) is not sequenced here.** Four PRs, | ||
| ~5600 added lines, one author, all `BLOCKED`. It needs its own review lane | ||
| and its own decision about landing order; folding it into a general roadmap | ||
| would understate that. | ||
|
|
||
| ## Branch hygiene (done 2026-08-19) | ||
|
|
||
| Local 106 -> 25, origin 66 -> 22. Every deleted branch was verified merged | ||
| into `origin/dev` or backed by a `MERGED`/`CLOSED` PR, with SHAs recorded in | ||
| `.tmp/branch-cleanup-*.txt` so any deletion is recoverable. | ||
|
|
||
| Release branches (`release-2.25.0`, `release-2.26.0` and their previews, | ||
| `codex/promote-*`) were deleted only after confirming each is an ancestor of | ||
| `main` or `preview` and preserved by its `v*` tag. | ||
|
|
||
| Six branches showed as "unmerged" while their PRs read `MERGED` — squash | ||
| merges, where the branch commit never enters dev's ancestry. Each was | ||
| confirmed by locating its merge commit in dev before deletion. A plain | ||
| `--merged` filter would have missed all six and left them to rot. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,98 @@ | ||
| # 010 — R1: rebase the mega-file split stack | ||
|
|
||
| Work-phase: wp2. Scope: **review + rebase + push. No merges.** | ||
|
|
||
| ## Why the CI is red, precisely | ||
|
|
||
| **Corrected 2026-08-19 after an independent audit lane refuted the first | ||
| version of this section.** The original text named the right mechanism and the | ||
| wrong direction; both corrections are below. | ||
|
|
||
| The failing assertion in shard 2/4 is a source-invariant test that reads code | ||
| as text. Run `32130164359` reports: | ||
|
|
||
| ``` | ||
| Expected to contain: "invalidateCodexModelsCacheWithPermit(permit, owningCodexHome)" | ||
| Received source: invalidateCodexModelsCacheWithPermit(permit, owningCodexHome, { allowWhenDesiredDisabled: true }) | ||
| ``` | ||
|
|
||
| So the **test** carried the old two-argument assertion and the **source** | ||
| carried the new three-argument call. The three-argument call arrived on dev in | ||
| `91979cf14`; `6c0bde453` then updated the assertion to match — but it landed | ||
| *after* this run. GitHub merges the PR head with the base before running CI, so | ||
| the run executed **dev's newer source against the PR's older test**. | ||
|
|
||
| That is the inverse of what this document first claimed ("dev's newer test | ||
| against the PR's older source"). The conclusion — stale-base merge skew, not a | ||
| defect in the extraction — survives; the mechanism statement had to be fixed. | ||
|
|
||
| The failure set is also larger than first recorded. Actual reds: test 1/4 | ||
| (hidden raw reasoning), 2/4 (the sync-cache assertion above), 3/4 (Command Code | ||
| catalog), 4/4 (server local API auth), gates (Models-page GUI), and macos | ||
| (multiple). Six legs, not four. | ||
|
Comment on lines
+29
to
+32
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win Make the exit criterion cover all failing legs. Lines [29-32] identify six failing legs: four test shards, Also applies to: 93-98 🤖 Prompt for AI Agents |
||
|
|
||
| The control: `#2023` is a strict history superset of `#2019` | ||
| (`git merge-base --is-ancestor 194f9f2a b2ac2500` exits 0), and **every | ||
| cross-platform job passes on its base** — shards 1-4, gates, macos, keyring, | ||
| npm-global. It is *not* "fully green": `hygiene` and `enforce-target` fail on | ||
| it, as they do on every PR in this stack. | ||
|
|
||
| **What the control does and does not prove.** It shows the extraction does not | ||
| break the suite when the suite and the source agree. It does not prove the | ||
| rebased `#2019` head is defect-free against *current* dev — only a CI run on | ||
| the new head can. Treat "stale base" as the hypothesis this rebase tests, not | ||
| as an established fact. | ||
|
|
||
| ## Verified rebase cost | ||
|
|
||
| A scratch rebase of `codex/split-wp1b-type-clusters` onto `origin/dev` | ||
| (102 commits) conflicts in exactly one file, `src/types.ts`, with **3 hunks**. | ||
|
|
||
| Three dev commits touched `src/types.ts` since the fork point (`b04cd26e7`): | ||
|
|
||
| | Commit | Change | | ||
| |---|---| | ||
| | `11e03eb44` | replay: durable thought signatures per credential (#2078) | | ||
| | `fd85c8238` | cursor: HTTP/1.1 compatibility transport (#1903) | | ||
| | `b5a98d690` | release-audit regressions from the 260818 merge train | | ||
|
|
||
| All three add or modify type declarations. Because WP1b turns `types.ts` into | ||
| a pure barrel, each conflict resolves the same way: **the new declaration moves | ||
| to the leaf that owns its cluster, and the barrel gains a re-export line.** | ||
| This is mechanical, but it is not automatic — resolving it by taking "ours" | ||
| would silently drop three landed changes. | ||
|
|
||
| ## Order | ||
|
|
||
| `#2019` and `#2036` are independent; `#2023` is a child of `#2019`. | ||
|
|
||
| 1. Rebase `codex/split-wp1-types` onto `origin/dev`; resolve `types.ts`; | ||
| force-push. Confirm the four shards go green. | ||
| 2. Rebase `codex/split-wp1b-type-clusters` onto the NEW `#2019` head, not onto | ||
| dev. Rebasing it onto dev directly would orphan the parent PR's diff. | ||
| 3. Rebase `codex/split-wp2a-config-names` onto `origin/dev` (42 behind, already | ||
| green — this is upkeep, not a fix). | ||
|
|
||
| All three branches are ours (`lidge-jun`), so force-push is in scope. | ||
|
|
||
| ## The hygiene failure is real and is not fixed by rebasing | ||
|
|
||
| All three PRs fail `hygiene: missing_regression_test`: they change `src/` | ||
| without changing a test. That gate is correct here — and the honest answer is | ||
| `test-exception-approved`, not a manufactured test. | ||
|
|
||
| A pure-move PR's oracle is the ~400 test files that import through the barrel | ||
| plus `tsc --noEmit`. A new test asserting "the barrel re-exports `OcxTool`" | ||
| restates what the compiler already proves and would pass even if the extraction | ||
| were wrong in every way that matters. | ||
|
|
||
| Verified: dev's `src/types.ts` exports 85 names; the WP1b barrel re-exports all | ||
| 85 across six leaves (`tools`, `wire`, `request`, `config`, `provider`, | ||
| `accounts`), reducing 1884 lines to 103. | ||
|
|
||
| ## Exit criteria | ||
|
|
||
| - `c-2019`: new head pushed; the four previously-red shards no longer FAILURE. | ||
| - `c-2023`: rebased onto the new parent head; base ancestry correct. | ||
| - `c-2036`: rebased onto dev; still green. | ||
| - No merges. No `src/` change beyond conflict resolution. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| # 020 — R2: merge the response-state temp reclaim stack | ||
|
|
||
| Work-phase: wp1. Scope: **the only merges authorized this session.** | ||
|
|
||
| ## State at plan time | ||
|
|
||
| | PR | Head | Base | Checks | mergeStateStatus | | ||
| |---|---|---|---|---| | ||
| | #2084 sweeper | `816024c95` | `dev` | zero FAILURE | `BLOCKED` (review requirement only) | | ||
| | #2089 doctor | `3cb6bb497` | `codex/tmp-reclaim-1-sweeper` | zero FAILURE | `CLEAN` | | ||
|
|
||
| Both are hygiene-green (they carry real tests) and 5 commits behind dev. | ||
| `#2084`'s `BLOCKED` is the review-requirement ruleset, which admin merge | ||
| passes — it is not a failing check. | ||
|
|
||
| ## Order is forced | ||
|
|
||
| `#2089` targets `#2084`'s branch. Merging the child first would land the | ||
| doctor command on top of a sweeper that is not on `dev`. | ||
|
|
||
| 1. Merge `#2084` into `dev`. | ||
| 2. Retarget `#2089` base from `codex/tmp-reclaim-1-sweeper` to `dev`. | ||
| GitHub rewrites the child's diff on retarget; confirm it shows only the | ||
| doctor changes afterward, not the sweeper's. | ||
| 3. Merge `#2089`. | ||
|
|
||
| After step 1 the parent branch is deletable, but **not before step 2** — deleting | ||
| the base of an open PR closes it. | ||
|
|
||
| ## What the change actually does (read, not summarized from the title) | ||
|
|
||
| The defect: `~/.opencodex` accumulates multi-GB of | ||
| `responses-state.json.ocx.<pid>.<seq>.tmp`, growing after every reboot. | ||
|
|
||
| Root cause is two-part, and the second part is the interesting one: | ||
|
|
||
| 1. The existing cleanup ran **once per process, at cache load** — before that | ||
| process writes anything. So a crashed-and-restarted proxy swept too early to | ||
| see its predecessor's temp (15-minute grace) and never looked again. | ||
| 2. The cleanup **skipped any file whose owning PID was still alive**. After a | ||
| reboot the OS reissues PIDs, so an old file is permanently mistaken for a | ||
| live process's. That is why growth tracked reboots. | ||
|
|
||
| ### Design points that hold up on review | ||
|
|
||
| - **The boot floor retires a vacuous probe, it does not claim death.** A temp | ||
| older than the current boot cannot be owned by the PID we would probe, so the | ||
| probe is meaningless and is skipped. The comment is explicit that this does | ||
| not prove the file is dead; the unconditional 15-minute grace remains the | ||
| safety floor. | ||
| - **An anomalous boot time disables the floor rather than clamping it.** | ||
| Clamping a future-dated boot to "now" would retire the liveness probe for | ||
| every file past the grace — the worst possible response. Absent floor costs a | ||
| missed reclaim; a wrong floor costs a live file. | ||
| - **`ENOENT` on unlink counts as reclaimed, not failed.** Another proxy sharing | ||
| the config dir may have won the race; reporting that as failure would tell an | ||
| operator a file is "in use or locked" when nobody holds it. | ||
| - **The sweep covers the resolved directory too.** Atomic writes place the temp | ||
| beside the *resolved* target, so a symlinked config dir strands temps where a | ||
| literal-dir scan never looks. | ||
| - **The periodic pass rides the liveness tick, not the TTL tick**, because | ||
| `sweepExpiredOnWrite` puts `sweepExpired` on hot write paths and a directory | ||
| scan does not belong there. It carries a 25 ms wall-clock deadline: an entry | ||
| cap bounds syscalls, not time, and on a network-mounted config dir each | ||
| `lstat` can cost 10-20 ms. | ||
| - **The doctor reports `eligible`, never `matched`.** `matched` increments | ||
| before the file-type, age, boot-floor and liveness gates, so reporting it | ||
| would tell an operator that live-PID and young temps are abandoned. | ||
| - **Report is the default; reclaim is opt-in** behind | ||
| `--reclaim-response-temps`, and a typo'd `--reclaim*` flag warns instead of | ||
| silently degrading to "nothing to reclaim". | ||
| - **Dry run and reclaim share one predicate**, so the report and the subsequent | ||
| removal cannot disagree about which files are reclaimable. | ||
|
|
||
| ## Exit criteria | ||
|
|
||
| - `c-2084`: `gh pr view` state MERGED; merge commit is an ancestor of | ||
| `origin/dev`; post-merge CI inspected on the merge SHA. | ||
| - `c-2089`: base reads `dev`; state MERGED; ancestry proof; CI inspected. |
There was a problem hiding this comment.
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
Keep the stale-base diagnosis conditional until rebase validation.
010_r1_split_rebase.mdsays the original mechanism was backwards and that stale-base skew was only a hypothesis. These lines still state that the red CI is not a defect in the change. Replace that claim with a conditional diagnosis and point to the later rebase evidence in050_execution_ledger.md.🤖 Prompt for AI Agents