Skip to content

Commit 8e01dd4

Browse files
authored
Merge pull request #2159 from lidge-jun/codex/promote-2.27.0
[WRONG BRANCH] release: promote dev to main for 2.27.0
2 parents b4336b7 + 43256f7 commit 8e01dd4

156 files changed

Lines changed: 13027 additions & 2157 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
# Default reviewers
2-
* @lidge-jun @Ingwannu @Wibias
2+
* @lidge-jun @Ingwannu
33

44
# High-impact runtime behavior
5-
/src/adapters/ @lidge-jun @Ingwannu @Wibias
6-
/src/providers/ @lidge-jun @Ingwannu @Wibias
7-
/src/codex/ @lidge-jun @Ingwannu @Wibias
8-
/src/server/ @lidge-jun @Ingwannu @Wibias
5+
/src/adapters/ @lidge-jun @Ingwannu
6+
/src/providers/ @lidge-jun @Ingwannu
7+
/src/codex/ @lidge-jun @Ingwannu
8+
/src/server/ @lidge-jun @Ingwannu
99

1010
# Repository automation and release security
1111
/.github/ @lidge-jun @Ingwannu

.github/workflows/ci.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,11 @@ jobs:
607607
bun run build
608608
609609
- name: Test
610-
run: bun test --isolate tests --shard=${{ matrix.shard }}/4
610+
# --timeout: the Linux batches and the macOS control both pass 60000; this leg was
611+
# the only one left on Bun's 5s default, and it is the slowest hardware on the board.
612+
# Three of its failures were the default firing on tests that had not hung — the
613+
# composed-acceptance cases spawn a real `ocx start` and were still working at 41s.
614+
run: bun test --isolate --timeout 60000 tests --shard=${{ matrix.shard }}/4
611615

612616
- name: CLI help smoke
613617
run: bun run src/cli/index.ts help

MAINTAINERS.md

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,23 @@ review and merge policy.
99
| --- | --- | --- |
1010
| [@lidge-jun](https://github.com/lidge-jun) | Project owner | Project direction, releases, repository administration, and final governance decisions |
1111
| [@Ingwannu](https://github.com/Ingwannu) | Maintainer | Issue and pull-request triage, `dev` integration, security review, and repository maintenance |
12-
| [@Wibias](https://github.com/Wibias) | Maintainer | Issue and pull-request triage, `dev` integration, and provider/CI maintenance |
1312

1413
The table describes project responsibilities. Actual repository permissions remain controlled
1514
through GitHub repository settings.
1615

1716
`dev` is the only integration line. The former `dev2-go` carry duty is retired;
1817
see [The retired `dev2-go` line](#the-retired-dev2-go-line).
1918

19+
## Former maintainers
20+
21+
| GitHub account | Project role | Period |
22+
| --- | --- | --- |
23+
| [@Wibias](https://github.com/Wibias) | Maintainer | 2026-07-27 – 2026-08-19 |
24+
25+
Former maintainers keep contributor standing and are welcome to open issues and pull requests like
26+
anyone else. Authorship credit in git history, release notes, and code comments is not rewritten
27+
when a maintainer steps down.
28+
2029
## Review and merge policy
2130

2231
- Pull requests target `dev`. It is the only integration line, and promotion to
@@ -98,17 +107,35 @@ Adding or removing a maintainer requires:
98107

99108
### Change log
100109

110+
- 2026-08-19 — [@Wibias](https://github.com/Wibias) stepped down as a maintainer
111+
and is now a contributor. This follows his own decision to stop developing
112+
opencodex; it is not a disciplinary action, and it was made with the owner's
113+
agreement (requirement 1). Requirement 2 does not apply to a maintainer's own
114+
resignation, which needs no second maintainer to ratify it. Requirement 3 is
115+
met by this file and `.github/CODEOWNERS`, where the default-reviewer line
116+
and the four runtime paths that listed him (`/src/adapters/`,
117+
`/src/providers/`, `/src/codex/`, `/src/server/`) drop back to the two
118+
remaining maintainers. Repository permission was reduced to read access at
119+
the same time, so the roster and the GitHub settings agree again.
120+
121+
Nothing he authored is being unwound. His commits, the pull requests he
122+
merged, the release-note attributions, and the code comments citing his
123+
reviews stay exactly as they are, and the trust-lane gate derived from his
124+
work in `.github/scripts/pr-sponsored-surface.cjs` keeps its attribution.
125+
Returning to the maintainer table later would go through the same three
126+
requirements that govern every addition.
127+
101128
- 2026-07-27 — [@Wibias](https://github.com/Wibias) added as a maintainer.
102129
Requirement 1 (agreement from the project owner) is met: the owner requested
103130
the addition. **Requirement 2 (review by another current maintainer) was
104131
never satisfied in the form this document describes.** The three commits that
105132
carried the addition (`a2693c02`, `dc3a4ade`, `02bbd47a`) landed on `dev` as
106133
direct owner pushes with no associated pull request, so no second maintainer
107134
reviewed them. Requirement 3 is met by this file and `.github/CODEOWNERS`.
108-
The addition is in effect regardless: @Wibias holds write access on the
109-
repository and has been merging pull requests since 2026-07-26. This entry
110-
records the gap rather than papering over it — a later maintainer change
111-
should go through a reviewed pull request.
135+
The addition took effect regardless: @Wibias held write access on the
136+
repository and merged pull requests from 2026-07-26 until he stepped down on
137+
2026-08-19. This entry records the gap rather than papering over it — a later
138+
maintainer change should go through a reviewed pull request.
112139

113140
Scope covers issue and pull-request triage, `dev` integration, and
114141
provider/CI maintenance. (This entry originally also described carrying
161 KB
Loading
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Evidence — FastWire B2 (OpenRouter)
2+
3+
`010_logs_openrouter_priority_lower_bound.png` — Logs table with three seeded OpenRouter
4+
requests on `openai/gpt-5.6-sol`, captured against a local proxy with a temporary
5+
`OPENCODEX_HOME`:
6+
7+
| Row | Attempt outcome | Rendering |
8+
| --- | --- | --- |
9+
| `or-priority-confirmed` | upstream echoed `service_tier: "priority"` | `≥$0.1105` — priced at the standard rate but marked a floor, because OpenRouter publishes no bundled tier price and documents priority as higher cost |
10+
| `or-priority-declined` | upstream echoed `service_tier: "default"` | `~$0.1105` — a real downgrade, so no floor marker |
11+
| `or-standard` | no tier requested | `~$0.1105` |
12+
13+
All three totals match on purpose: without a bundled priority price every row is computed at
14+
the standard rate, so the only thing that differs is whether the cost is presented as an
15+
estimate (`~$`) or as a known lower bound (`≥$`). The marker matches the convention used by
16+
the parallel xAI unit (#2072).
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# WP1 — types.ts value-leaf extraction (stacked PR 1 of the split program)
2+
3+
Unit: devlog/_plan/260818_megafile_split_program. Risk basis: 000_risk_assessment.md.
4+
Branch: codex/split-wp1-types on dev @ b04cd26e7 (post FastWire B0/B1 merge).
5+
Class: C2 (mechanical move, shared-runtime file, full-suite gate).
6+
7+
## Loop spec
8+
9+
- Archetype: pure-move refactor, zero behavior change.
10+
- Trigger: split program WP1, lowest-risk opener.
11+
- Goal: src/types.ts stops carrying runtime value code; values live in leaves;
12+
every existing import keeps working via re-export.
13+
- Non-goals: NO type-cluster split yet (OcxConfig/OcxProviderConfig stay),
14+
NO consumer retargeting to leaf paths, NO behavior or signature change.
15+
- Verifier: bun run typecheck && bun run test (full — shared runtime file).
16+
- Stop: both green + core-lab-boundary green; PR opened against dev.
17+
- Memory artifact: this doc + ledger attests.
18+
19+
## Scope (IN)
20+
21+
Extract the two VALUE clusters from src/types.ts (1867 lines) into leaves:
22+
23+
1. src/types/tools.ts — lines ~236-292:
24+
namespacedToolName, toolChoiceAliases, toolAllowedByChoice,
25+
resolveToolChoiceWireName, modelInList, OcxToolChoice (type),
26+
isAllowedToolChoice, toolChoiceToolPredicate.
27+
Needs `import type { OcxTool } from "../types"` — type-only, erased at
28+
runtime, so the types.ts -> tools.ts re-export is NOT a runtime cycle.
29+
2. src/types/wire.ts — lines ~1760-1839:
30+
UPSTREAM_HTTP_VERSION_VALUES, UpstreamHttpVersion,
31+
REASONING_SUMMARY_DELIVERY_VALUES, ReasoningSummaryDelivery,
32+
CodexAccountMode, OPENAI_PROVIDER_TIER_VERSION,
33+
MODEL_ADAPTER_OVERRIDE_ALLOWED, ANTHROPIC_WIRE_MODELS (internal),
34+
anthropicWireModelsForProvider (internal), captureWireAdapterHardPins,
35+
isWirePinnedModel, pinnedWireAdapter. Self-contained, no imports.
36+
37+
src/types.ts keeps every current export via `export ... from "./types/..."`;
38+
type-only names re-exported with `export type`.
39+
40+
## Scope (OUT)
41+
42+
- All interface/type clusters stay in types.ts this PR.
43+
- No import-path changes anywhere else in src/ or tests/.
44+
- No lab imports anywhere new (types is on the protected graph as a value
45+
import from responses/core.ts: modelInList, namespacedToolName).
46+
47+
## File change map
48+
49+
- ADD src/types/tools.ts (~60 lines incl. docs)
50+
- ADD src/types/wire.ts (~85 lines incl. docs)
51+
- EDIT src/types.ts: delete moved bodies, add two re-export blocks at the
52+
same positions; net -120 lines.
53+
54+
## Accept criteria
55+
56+
1. bun run typecheck exit 0.
57+
2. bun run test full suite: same pass count as base (13k+), 0 fail.
58+
3. tests/core-lab-boundary.test.ts green (covers the new static edges
59+
types.ts -> types/tools.ts, types/wire.ts on the protected walk).
60+
4. rg confirms no consumer file changed: git diff --stat touches exactly 3
61+
files.
62+
5. Value identity preserved: MODEL_ADAPTER_OVERRIDE_ALLOWED still a single
63+
ReadonlySet instance (only one declaration site, re-export not re-create).
64+
65+
Activation grounding: criterion 3's scenario is the existing boundary test
66+
run; criterion 5's scenario is the full suite (service-tier tests compare
67+
set membership through both import paths).
68+
69+
## Verifier reality (PLAN-VERIFIER-REAL-01)
70+
71+
- bun run typecheck: exists in package.json, reads src/ via tsconfig
72+
include ["src"] — observes both new files. To be run in C.
73+
- bun run test: tests/ suite imports ../src/types in 400 files — observes
74+
the barrel; core-lab-boundary walks the import graph from the three
75+
protected roots which reach types.ts — observes the new edges.
76+
77+
## Stacked-PR plan (DEV-STACK-01)
78+
79+
PR 1 (this): value leaves + barrel. Target: dev.
80+
PR 2 (next cycle): type-cluster split (request/config/provider/accounts)
81+
stacked on PR 1's head branch.
82+
Later cycles per 000_risk_assessment.md order (config leaves, registry, ...).
83+
84+
## Audit amendments (A-phase, 2 auditors: grok-4.6 NEAR-PASS / gpt-5.6-sol FAIL->fixed)
85+
86+
1. CYCLE FIX (sol blocker): OcxTool (lines 211-232) moves INTO types/tools.ts.
87+
tools.ts imports NOTHING from ../types — dependency is strictly one-way
88+
(types.ts -> types/tools.ts). types.ts re-exports OcxTool as a type.
89+
2. RECIPE FIX (grok finding 7): `export type { X } from` does not BIND X in
90+
the barrel. types.ts still uses OcxTool (line 106), OcxToolChoice (299),
91+
UpstreamHttpVersion (1455), CodexAccountMode (1470),
92+
ReasoningSummaryDelivery (1574) — so the barrel adds a local
93+
`import type { OcxTool, OcxToolChoice } from "./types/tools"` and
94+
`import type { UpstreamHttpVersion, ReasoningSummaryDelivery,
95+
CodexAccountMode } from "./types/wire"` next to the Kiro import.
96+
3. OcxToolChoice + its guards travel with tools.ts (they are one cluster).
97+
4. Extensionless specifiers only (lab walker resolves `${base}.ts`).
98+
5. AC4 corrected: scope proof = `git diff --stat <base>..HEAD -- src tests`
99+
showing exactly 3 src files; devlog/plan files are committed separately.
100+
6. AC5 proof corrected: identity is preserved by ESM re-export semantics
101+
(single declaration site); drop the false 'both import paths' claim.
102+
7. Protected-roots note corrected: PROTECTED has 4 files; only
103+
responses/core.ts puts types.ts on the runtime graph (core.ts:63).
104+
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# WP1b — types.ts type-cluster split (stacked PR 2, layer 2 of the stack)
2+
3+
Stack (DEV-STACK-01/03): layer 1 = #2019 (codex/split-wp1-types, value leaves).
4+
This layer: codex/split-wp1b-type-clusters, base = codex/split-wp1-types.
5+
Thesis: src/types.ts becomes a pure barrel; all type clusters move to leaves.
6+
Class: C2 pure-move, type-only (zero runtime code moves in this layer).
7+
8+
## Loop spec
9+
10+
- Archetype: pure-move refactor, zero behavior change (type-only).
11+
- Verifier: bun run typecheck + full bun run test on lidge (remote contract).
12+
- Stop: green + PR opened with base codex/split-wp1-types + stack map in body.
13+
14+
## Measured dependency structure (one-way, no cycles)
15+
16+
- request cluster (lines 6-368): needs KiroOAuthMetadata (oauth/types),
17+
OcxTool + OcxToolChoice (types/tools). Nothing else external.
18+
- config cluster (370-1180): needs OcxProviderConfig only (provider cluster).
19+
- provider cluster (1183-1698): needs UpstreamHttpVersion x2,
20+
ReasoningSummaryDelivery x3, CodexAccountMode x2 (types/wire).
21+
- accounts cluster (1700-1729): self-contained.
22+
23+
## File change map
24+
25+
- ADD src/types/request.ts <- lines 6-368 + import type {KiroOAuthMetadata}
26+
from ../oauth/types, import type {OcxTool, OcxToolChoice} from ./tools
27+
- ADD src/types/config.ts <- lines 370-1180 + import type
28+
{OcxProviderConfig} from ./provider
29+
- ADD src/types/provider.ts <- lines 1183-1698 + import type {...} from ./wire
30+
- ADD src/types/accounts.ts <- lines 1700-1729, no imports
31+
- EDIT src/types.ts -> pure barrel (~30 lines): export type blocks for the 4
32+
new leaves + existing tools/wire re-exports (values stay `export {}`,
33+
types stay `export type {}`). KiroOAuthMetadata import dropped from barrel.
34+
35+
## Accept criteria
36+
37+
1. typecheck exit 0. 2. lidge full suite 0 fail (>= 13201 pass baseline).
38+
3. core-lab-boundary green (barrel value re-exports still walked; type-only
39+
leaves are erased so runtime graph SHRINKS, never grows).
40+
4. Source diff: exactly 5 files under src/ (4 adds + barrel).
41+
5. Public surface byte-compatible: src/index.ts exports (OcxConfig, OcxContext,
42+
OcxMessage, OcxParsedRequest, OcxProviderConfig, OcxRequestOptions, OcxTool,
43+
AdapterEvent) all still resolve from ./types.
44+
45+
## Risks
46+
47+
- `export type ... from` binds nothing locally (WP1 lesson) — but the new
48+
barrel needs NO local bindings once all interfaces leave; only the 4
49+
import-type lines vanish too. Residual: none expected.
50+
- interface merging/declaration duplication: each name must exist in exactly
51+
one leaf; grep-verify no name appears in two files.
52+
- Tests importing `import * as types from ../src/types` (namespace): type-only
53+
namespaces erased; runtime namespace keeps the same value exports via
54+
tools/wire re-exports. No test currently reads a VALUE that moves (nothing
55+
moves at runtime this layer).
56+
57+
58+
## Audit amendments round 2 (grok-4.6 NEAR-PASS / sol FAIL -> both fixed)
59+
60+
CORRECTED extract ranges (file is 1727 lines):
61+
62+
- request.ts: lines 5-211 (incl. leading JSDoc) + 224-364
63+
+ import type { KiroOAuthMetadata } from ../oauth/types
64+
+ import type { OcxTool, OcxToolChoice } from ./tools
65+
+ import type { TierDecision, TierObservationContext } from ./provider
66+
(OcxRequestOptions.tierDecision:235 / tierObservation:237 — missed edge)
67+
- config.ts: lines 366-1181 (incl. closing brace 1181) MINUS the
68+
RefreshPolicy block (1074-1080, moves to provider — see below)
69+
+ import type { OcxProviderConfig, RefreshPolicy } is WRONG — instead:
70+
+ import type { OcxProviderConfig } from ./provider (604)
71+
+ import type { CodexAccount } from ./accounts (874 — missed edge)
72+
- provider.ts: lines 1183-1687 + RefreshPolicy block (1074-1080; sole
73+
consumer is OcxProviderConfig.refreshPolicy:1484 — relocation keeps the
74+
graph one-way, avoids the config<->provider cycle)
75+
+ import type { UpstreamHttpVersion, ReasoningSummaryDelivery,
76+
CodexAccountMode } from ./wire
77+
+ REWRITE 2 inline type-query paths (1659, 1665):
78+
import("./adapters/cursor/...") -> import("../adapters/cursor/...")
79+
- accounts.ts: lines 1700-1727, no imports
80+
- BARREL KEEPS lines 213-222 (tools value re-exports) and 1689-1698 (wire
81+
value re-exports): RUNTIME blocks, must NOT enter type-only leaves.
82+
Final barrel = 2 value blocks + 4 export type blocks, named re-exports
83+
only, NO export * (would duplicate runtime names).
84+
- The 3 import type lines at 1-3 vanish with their consumers.
85+
- Barrel needs RefreshPolicy re-exported from ./provider (was ./config).
86+
87+
Corrected one-way graph: request -> {oauth, tools, provider};
88+
config -> {provider, accounts}; provider -> wire; accounts -> none.
89+
90+
Both auditors confirmed: no namespace imports, no runtime dynamic import of
91+
types.ts (all import("...types").X hits are erased type queries), no textual
92+
test pins, lab walker unaffected while value blocks stay in barrel,
93+
src/index.ts keeps resolving. AC4 corrected: 5 files under src.
94+
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# WP2a-1 — config provider-name leaf (cycle breaker; parallel PR off dev)
2+
3+
Branch codex/split-wp2a-config-names on dev@aaf04690e. NOT stacked on the
4+
types stack (disjoint files, DEV-STACK-01 'independent parts -> parallel PRs').
5+
Class C2 pure move + 2 consumer retargets. Risk basis 000_risk_assessment.md
6+
WP2a; highest-leverage low-risk config extraction: breaks the existing
7+
config <-> routing/profile import cycle.
8+
9+
## Loop spec
10+
11+
- Goal: isValidProviderName/hasOwnProvider live in a leaf with no heavy deps;
12+
routing/profile.ts and router.ts stop importing them through the 3900-line
13+
config barrel (which loads Zod + bun:sqlite + registry transitively).
14+
- Non-goals: no other config extraction this PR; management write-path
15+
callers keep importing from ./config (barrel re-export).
16+
- Verifier: typecheck + lidge full suite + core-lab-boundary.
17+
18+
## File change map
19+
20+
- ADD src/config/provider-name.ts: RESERVED_PROVIDER_NAMES,
21+
PROVIDER_NAME_PATTERN (both module-private consts, config.ts 738-750),
22+
isValidProviderName (762), hasOwnProvider (769). Zero imports.
23+
- EDIT src/config.ts: delete moved bodies; add
24+
`export { isValidProviderName, hasOwnProvider } from "./config/provider-name"`;
25+
internal call sites (1150, 1390, 1597 + others) need a local
26+
`import { ... } from "./config/provider-name"` since re-export binds nothing
27+
(WP1 lesson).
28+
- EDIT src/routing/profile.ts:16: import hasOwnProvider from
29+
../config/provider-name (cycle edge profile->config removed).
30+
- EDIT src/router.ts:11: split import — hasOwnProvider from
31+
./config/provider-name, resolveEnvValue stays from ./config.
32+
33+
## Accept criteria
34+
35+
1. typecheck exit 0. 2. lidge full suite 0 fail (baseline 13201 pass).
36+
3. core-lab-boundary green (router edge now reaches a leaf with no imports —
37+
protected graph shrinks).
38+
4. rg 'from "../config"' src/routing/profile.ts -> no hasOwnProvider import
39+
through the barrel (cycle gone; remaining profile imports from config: none
40+
expected — verify, else keep others intact).
41+
5. Source diff: exactly 4 files under src/.
42+
43+
## Risks
44+
45+
- config.ts superRefine calls isValidProviderName internally — the local
46+
import must land before schema evaluation (top of file, hoisted; ESM fine).
47+
- routing/profile.ts may import more than hasOwnProvider from ../config —
48+
verify and leave other names on the barrel.
49+
50+
51+
## Audit amendments (grok PASS / sol NEAR-PASS)
52+
53+
- Internal call sites are EXACTLY 3 (1150, 1390 isValidProviderName; 1597
54+
hasOwnProvider), all inside superRefine callbacks — no TDZ risk.
55+
- AC3 claim corrected: the protected graph does NOT shrink (router keeps the
56+
barrel edge for resolveEnvValue; the leaf adds one dead-end module). The
57+
real win is the config<->profile cycle break. core-lab-boundary stays
58+
green either way.
59+
- profile.ts imports nothing else from ../config — cycle fully gone.
60+
- Tests importing isValidProviderName via barrel: config.test.ts:13,
61+
policy-execution.test.ts:6 — barrel re-export preserves both.
62+

0 commit comments

Comments
 (0)