Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
151 commits
Select commit Hold shift + click to select a range
2dd7b43
chore(release): open dev at 2.47.0 before releasing 2.46.0
github-actions[bot] Sep 7, 2026
6cf38b5
Merge pull request #3850 from lidge-jun/codex/dev-version-2.47.0
lidge-jun Sep 7, 2026
ec799db
docs(devlog): plan code-mode host contract for routed models
lidge-jun Sep 7, 2026
041aec0
docs(devlog): fold audit round 1 into the code-mode host contract roa…
lidge-jun Sep 7, 2026
d375916
docs(devlog): fold audit round 2 into the code-mode host contract roa…
lidge-jun Sep 7, 2026
3bcb9aa
docs(devlog): fold audit round 3 into the code-mode host contract roa…
lidge-jun Sep 7, 2026
5b70ddd
docs(devlog): record live Codex host probe evidence for the code-mode…
lidge-jun Sep 7, 2026
adafd12
fix(code-mode): state the host contract for nested helpers before the…
lidge-jun Sep 7, 2026
1633780
fix(code-mode): name the broken host rule on exec results that carry …
lidge-jun Sep 7, 2026
6bdcba5
docs: record the routed code-mode host contract
lidge-jun Sep 7, 2026
ece556a
Merge pull request #3854 from lidge-jun/codex/code-mode-host-contract
lidge-jun Sep 7, 2026
f1604c6
docs(devlog): make CI completion check fail closed [skip ci]
Ingwannu Sep 4, 2026
3e4a01c
fix(kiro): gate request diagnostics behind the debug check [skip ci]
luvs01 Sep 7, 2026
98564bd
fix(copilot): route Responses-only GPT, Grok and MAI models correctly…
invalid-email-address Sep 7, 2026
6061dcc
test(kiro): isolate and restore every debug setting the diagnostics g…
invalid-email-address Sep 7, 2026
25689e1
fix(responses): bound the streaming citation marker span [skip ci]
luvs01 Sep 7, 2026
00b74c7
fix(responses): keep an oversized citation span verbatim before a lat…
invalid-email-address Sep 7, 2026
924b657
fix(providers): refuse keychain restore across provider ownership [sk…
luvs01 Sep 7, 2026
6eadb16
fix(management): expose the effective web-search sidecar enabled state
invalid-email-address Sep 7, 2026
7f2fb92
Merge pull request #3865: release-train M layer 1 [skip ci]
lidge-jun Sep 7, 2026
dcec717
Merge pull request #3866: release-train M layer 2 [skip ci]
lidge-jun Sep 7, 2026
0ef7d29
Merge pull request #3867: release-train M layer 3 [skip ci]
lidge-jun Sep 7, 2026
99451df
Merge pull request #3868: release-train M layer 4 [skip ci]
lidge-jun Sep 7, 2026
0719457
Merge pull request #3869: release-train M layer 5 [skip ci]
lidge-jun Sep 7, 2026
d00615d
Merge pull request #3870: release-train M layer 6 [skip ci]
lidge-jun Sep 7, 2026
61a775c
docs: record lane B manual delivery roadmap [skip ci]
invalid-email-address Sep 7, 2026
1386e3d
fix(codex): sustain quota window activation [skip ci]
terrytan95 Sep 7, 2026
c386770
test(codex): cover quota activation regressions [skip ci]
terrytan95 Sep 7, 2026
6bcf864
fix(transport): admit Mihomo IPv6 fake-IP under TUN transparency exce…
hualiny Sep 7, 2026
bdd4e46
fix(transport): retain IPv6 pinning across proxy mismatches [skip ci]
invalid-email-address Sep 7, 2026
a814dd3
test(transport): run DNS fixture in the Bun test loader [skip ci]
invalid-email-address Sep 7, 2026
3955e10
fix(codex): fence main quota activation recovery [skip ci]
invalid-email-address Sep 7, 2026
b67f452
test(transport): pass the test-run lease to the child fixture [skip ci]
invalid-email-address Sep 7, 2026
62fe747
Merge pull request #3871: sustain Codex quota window activation (carr…
lidge-jun Sep 7, 2026
ddee5e8
Merge pull request #3872: admit Mihomo IPv6 fake-IP under TUN (carry …
lidge-jun Sep 7, 2026
edd396c
fix(opencode-go): carry session affinity through Pi native chat [skip…
makesomethingshit Sep 7, 2026
effba4c
test(opencode-go): define inbound opaque session identity contract [s…
makesomethingshit Sep 7, 2026
5b3df2e
fix: admit reasoning envelope allocations before materialization [ski…
Ingwannu Sep 7, 2026
eb8cc9a
fix(pi): scope generated session affinity to the Pi client [skip ci]
makesomethingshit Sep 7, 2026
7541517
fix: admit final Claude request copies before serialization [skip ci]
lidge-jun Sep 7, 2026
697a500
test: pin Go affinity identity and header precedence [skip ci]
lidge-jun Sep 7, 2026
e0e8d26
fix: fall back from native compact 404 to routed compaction [skip ci]
lidge-jun Sep 7, 2026
d8b18b1
fix: share envelope admission budgets and release transient request c…
lidge-jun Sep 7, 2026
feb1855
docs: include Pi session affinity in every guide example [skip ci]
lidge-jun Sep 7, 2026
c84cc3b
docs: describe native compact 404 fallback in route table [skip ci]
lidge-jun Sep 7, 2026
b0bcb4b
Merge pull request #3879: admit reasoning-envelope allocations before…
lidge-jun Sep 7, 2026
dac7e28
Merge pull request #3880: carry Pi/OpenCode Go session affinity throu…
lidge-jun Sep 7, 2026
76436a3
Merge pull request #3881: routed compaction fallback for native compa…
lidge-jun Sep 7, 2026
e96b5c5
fix(responses): make whole-string citation stripping agree with the s…
invalid-email-address Sep 7, 2026
413600d
docs(providers): describe OpenCode Go session affinity and the Pi com…
invalid-email-address Sep 7, 2026
6389787
Merge pull request #3882: align whole-string citation stripping with …
lidge-jun Sep 7, 2026
522ce5f
Merge pull request #3888: providers guide OpenCode Go affinity docs […
lidge-jun Sep 7, 2026
451fbff
feat gui: expose subagent fallback settings [skip ci]
x3M3x Sep 1, 2026
2e6ef45
docs: record lane C manual-chain roadmap [skip ci]
invalid-email-address Sep 7, 2026
eb5ff6c
feat(gui): add opt-in Codex Desktop sign-in toggle [skip ci]
RobinBially Sep 7, 2026
2b14053
docs: add subagent fallback settings screenshot [skip ci]
x3M3x Sep 2, 2026
a815f23
fix(web-search): bound the Anthropic sidecar SSE and error bodies [sk…
luvs01 Sep 7, 2026
c1f96f0
fix(gui): retain pending Desktop preference when sync is skipped [ski…
invalid-email-address Sep 7, 2026
f8d3545
fix(gui): preserve fallback choices and explain native-parent V2 comp…
invalid-email-address Sep 7, 2026
7131528
docs: pin lane C health wiring handoff [skip ci]
invalid-email-address Sep 7, 2026
2b158e9
fix(vision): bound the Anthropic vision sidecar SSE and error bodies …
luvs01 Sep 7, 2026
9d8d11a
fix(service): carry startup-health cache portion of #3863 [skip ci]
x3M3x Sep 7, 2026
734d41c
fix(gui): retain unapplied Desktop status across settings polls [skip…
invalid-email-address Sep 7, 2026
ffcd7ab
fix(gui): guard fallback hydration races and preserve row focus [skip…
invalid-email-address Sep 7, 2026
51b4437
test(web-search): cover bounded partial frames and detached cancellat…
invalid-email-address Sep 7, 2026
8eaa564
test(vision): pin capped descriptions and non-settling error-body can…
invalid-email-address Sep 7, 2026
91b54b7
fix(service): preserve fresh health and contain detached probe failur…
invalid-email-address Sep 7, 2026
abbdb22
docs: translate code-mode host rules; docs handoff from lane E [skip ci]
invalid-email-address Sep 7, 2026
f1b8f2d
fix(gui): keep fallback render identities in state [skip ci]
invalid-email-address Sep 7, 2026
f46a7f4
Merge pull request #3873: bound Anthropic web-search sidecar bodies (…
lidge-jun Sep 7, 2026
3f07e09
Merge pull request #3874: bound Anthropic vision sidecar bodies (carr…
lidge-jun Sep 7, 2026
686cb12
Merge pull request #3875: unblock settings load from the Windows heal…
lidge-jun Sep 7, 2026
2eec04f
Merge pull request #3876: default-off Codex Desktop sign-in preferenc…
lidge-jun Sep 7, 2026
d0fca4a
Merge pull request #3878: sub-agent fallback settings GUI with V2 com…
lidge-jun Sep 7, 2026
1ca1a56
fix(release): recover registry reads after acknowledged publication […
invalid-email-address Sep 7, 2026
56f356d
fix(release): bind registry checks to package metadata [skip ci]
invalid-email-address Sep 7, 2026
f4a4b46
Merge pull request #3864: recover release registry smoke after an acc…
lidge-jun Sep 7, 2026
609105c
docs: plan lane D manual release chain [skip ci]
invalid-email-address Sep 7, 2026
b462cc5
docs: record lane D roadmap audit decisions [skip ci]
invalid-email-address Sep 7, 2026
bf15366
fix(usage): resolve account prices through provider identity [skip ci]
invalid-email-address Sep 7, 2026
c35b5a6
fix(claude): preserve legacy thinking block order [skip ci]
invalid-email-address Sep 7, 2026
c5fb7e3
fix(models): guard edits during unknown receipt recovery [skip ci]
invalid-email-address Sep 7, 2026
c44c6de
test(usage): use approved synthetic email domains [skip ci]
invalid-email-address Sep 7, 2026
341d71d
feat(models): edit manual token prices and preserve explicit zero [sk…
invalid-email-address Sep 7, 2026
062e9cb
fix(models): validate price receipts and redact CLI failures [skip ci]
invalid-email-address Sep 7, 2026
a6e1227
fix(models): start price reload state from user actions [skip ci]
invalid-email-address Sep 7, 2026
568a3e8
docs: record code-mode delivery and qualify Desktop model switching […
invalid-email-address Sep 7, 2026
e0a1a88
docs: complete Raycast status and model-name recovery guidance [skip ci]
invalid-email-address Sep 7, 2026
f8c8f6d
docs: qualify Desktop model switching in translated guides [skip ci]
invalid-email-address Sep 7, 2026
209c88b
fix(models): isolate async price-read state callbacks [skip ci]
invalid-email-address Sep 7, 2026
c492474
feat(usage): add inclusive custom time windows [skip ci]
invalid-email-address Sep 7, 2026
089320e
docs: define lane D verification and handoff [skip ci]
invalid-email-address Sep 7, 2026
e346d7a
fix(usage): preserve dates across timezone calendar gaps [skip ci]
invalid-email-address Sep 7, 2026
5669413
test(models): scope price errors to their dialog [skip ci]
invalid-email-address Sep 7, 2026
fe94603
fix(usage): encode custom report identity as a tuple [skip ci]
invalid-email-address Sep 7, 2026
4fe4ad8
Merge pull request #3877: preserve signed and redacted thinking order…
lidge-jun Sep 7, 2026
d05250d
Merge pull request #3902: guard unknown display-name receipt recovery…
lidge-jun Sep 7, 2026
cb1113f
Merge pull request #3903: resolve account labels through pricing iden…
lidge-jun Sep 7, 2026
29405d3
Merge pull request #3904: edit manual prices and honor explicit zero …
lidge-jun Sep 7, 2026
da707cc
Merge pull request #3905: select inclusive custom usage time windows …
lidge-jun Sep 7, 2026
1649247
Merge pull request #3883: release-246 docs follow-ups (Raycast copy, …
lidge-jun Sep 7, 2026
74089fd
Merge pull request #3884: code-mode delivery record, Desktop /model c…
lidge-jun Sep 7, 2026
8ecf91f
feat(gui): add guarded routed model picker drag ordering [skip ci]
invalid-email-address Sep 7, 2026
dd8fb50
fix(gui): reconcile picker lifecycle outside synchronous effects [ski…
invalid-email-address Sep 7, 2026
3fb08ec
test(gui): preserve read-after-write picker fixture state [skip ci]
invalid-email-address Sep 7, 2026
1e188b7
Merge pull request #3887: drag-and-drop model picker ordering (#3774 …
lidge-jun Sep 7, 2026
524985f
feat(router): add per-model pinned reasoning effort overrides [skip ci]
Sep 3, 2026
331e68f
fix(router): unify effort validation with isDeclaredReasoningEffort, …
Sep 3, 2026
24149f3
fix(router): enforce effort cap after pin in native chat and normaliz…
Sep 3, 2026
5865367
fix: adapt pinned effort carry to current config and wire contracts […
invalid-email-address Sep 7, 2026
c145a70
fix: preserve price writes across concurrent provider replacement [sk…
invalid-email-address Sep 7, 2026
eeb5501
test: use a valid provider config for effort-cap API fixtures [skip ci]
invalid-email-address Sep 7, 2026
f802f71
Merge pull request #3892: per-model pinned reasoning effort overrides…
lidge-jun Sep 7, 2026
8bc9e4e
docs: publish the sponsorship rule set (SPONSORS.md + README section)…
lidge-jun Sep 7, 2026
6744571
docs(devlog): rank 27 next-release landing recommendations for dev af…
invalid-email-address Sep 7, 2026
93abd0f
docs(devlog): plan release train 260907 lanes and merge protocol [ski…
invalid-email-address Sep 7, 2026
0fbfcf8
docs(devlog): amend release-train ownership for i18n and how-it-works…
invalid-email-address Sep 7, 2026
8c5cf59
docs(devlog): record release-train wp1 dispatch and main chain [skip ci]
invalid-email-address Sep 7, 2026
c1419de
docs(devlog): record M chain landing on dev [skip ci]
invalid-email-address Sep 7, 2026
6415f4d
docs(devlog): record B landing and CI serialization policy [skip ci]
invalid-email-address Sep 7, 2026
0d419a2
docs(devlog): record A and M7/M8 landings [skip ci]
invalid-email-address Sep 7, 2026
6a788c6
docs(devlog): record C and E#3864 landings [skip ci]
invalid-email-address Sep 7, 2026
d79e6e7
docs(devlog): record D landing [skip ci]
invalid-email-address Sep 7, 2026
2fbaf48
docs(devlog): record E docs landing [skip ci]
invalid-email-address Sep 7, 2026
4c0f46e
docs(devlog): record #3887 landing [skip ci]
invalid-email-address Sep 7, 2026
768c7d1
docs(devlog): record final chain landing and train-head CI [skip ci]
invalid-email-address Sep 7, 2026
f502afd
docs(devlog): release-train readiness record for dev after v2.46.0 [s…
invalid-email-address Sep 7, 2026
273a3ab
Merge pull request #3913: 260907 release-train devlog record [skip ci]
lidge-jun Sep 7, 2026
aeefb3a
docs(readme): one-line Sponsors slot, sponsorship summary and contact…
lidge-jun Sep 7, 2026
c41232a
feat(providers): OrcaRouter PKCE account login and live catalog (carr…
lidge-jun Sep 7, 2026
17d2a17
docs(readme): one sponsor line pointing at SPONSORS.md (#3923)
lidge-jun Sep 7, 2026
c4725b2
fix(pricing): preserve concurrent rates when resetting the last live …
invalid-email-address Sep 7, 2026
0aef26c
fix(adapters): require host error context before recovery guidance
invalid-email-address Sep 7, 2026
e9d72e0
fix(oauth): accept documented Orca key grants and clarify private end…
invalid-email-address Sep 7, 2026
cb24485
fix(gui): serialize OAuth restarts behind pending cancellation
invalid-email-address Sep 7, 2026
09f669a
chore(release): open dev at 2.48.0 before releasing 2.47.0 (#3925)
github-actions[bot] Sep 7, 2026
7768800
fix(cursor): preserve tool results outside verified code-mode errors
invalid-email-address Sep 7, 2026
e7173ed
fix(gui): retain unapplied Desktop preference state across refreshes
invalid-email-address Sep 7, 2026
3baad73
fix(usage): reject custom reports with missing or mismatched window r…
invalid-email-address Sep 7, 2026
7d8082c
fix(gui): keep subagent roster usable when fallback settings fail
invalid-email-address Sep 7, 2026
ba5e4e8
docs: record release regression persistence and response contracts
invalid-email-address Sep 7, 2026
7df1b9e
Merge remote-tracking branch 'origin/dev' into codex/release-247-regr…
invalid-email-address Sep 7, 2026
18b8890
docs: explain custom report confirmation and price reset scope
invalid-email-address Sep 7, 2026
713be5c
refactor(gui): chain cancellation barriers without an await loop
invalid-email-address Sep 7, 2026
4437cd8
test(gui): observe dashboard hook state after React commits
invalid-email-address Sep 7, 2026
3d53e5f
release: prepare 2.47.0 from audited regression candidate
invalid-email-address Sep 7, 2026
42f2afd
refactor(gui): give settings polling and mutation explicit reducer ow…
invalid-email-address Sep 7, 2026
48ab3e1
fix(gui): guard polling input and precompute model membership
invalid-email-address Sep 7, 2026
eda8754
Merge commit '48ab3e1e66cfa6e0c873de2fafa4540ac61d6c7d' into codex/re…
invalid-email-address Sep 7, 2026
5725219
test(gui): follow the shared OAuth cancellation request owner
invalid-email-address Sep 7, 2026
f9e3515
Merge commit '57252193b' into codex/release-247-main
invalid-email-address Sep 7, 2026
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
41 changes: 29 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -334,40 +334,57 @@ jobs:
}

- name: Publish (or dry-run)
id: publication
env:
DRY_RUN: ${{ inputs.dry-run }}
NPM_DIST_TAG: ${{ inputs.tag }}
run: |
set -euo pipefail
if [ "$DRY_RUN" = "true" ]; then
echo "::notice::DRY RUN — building + packing, not publishing"
npm run prepublishOnly
npm pack --dry-run
else
npm publish --tag "$NPM_DIST_TAG" --access public
echo "published=true" >> "$GITHUB_OUTPUT"
fi

# Confirm the registry actually has the new version (real publishes only).
# Publication is acknowledged before registry reads, which can lag or fail.
# Recover only observation failures in this run; never retry npm publish.
- name: Post-publish registry smoke
if: ${{ inputs.dry-run != true }}
id: registry-smoke
if: ${{ inputs.dry-run != true && steps.publication.outputs.published == 'true' }}
env:
RELEASE_VERSION: ${{ inputs.version }}
PUBLISHED: ${{ steps.publication.outputs.published }}
run: |
for attempt in $(seq 1 30); do
if VERSION=$(npm view "@bitkyc08/opencodex@${RELEASE_VERSION}" version 2>/dev/null); then
set -euo pipefail
test "$PUBLISHED" = "true" || {
echo "::error::No successful publication receipt; refusing registry recovery"
exit 1
}
pkg_name="$(node -p "require('./package.json').name")"
for attempt in $(seq 1 6); do
if VERSION=$(timeout --kill-after=2s 10s npm view "${pkg_name}@${RELEASE_VERSION}" version --fetch-retries=0 --fetch-timeout=8000 2>/dev/null); then
if [ "$VERSION" != "$RELEASE_VERSION" ]; then
echo "::error::Registry returned an unexpected version; refusing to create a release"
exit 1
fi
echo "registry version=$VERSION"
test "$VERSION" = "$RELEASE_VERSION"
npm dist-tag ls @bitkyc08/opencodex
echo "verification=verified" >> "$GITHUB_OUTPUT"
echo "Registry verified ${pkg_name}@${RELEASE_VERSION}." >> "$GITHUB_STEP_SUMMARY"
timeout --kill-after=2s 10s npm dist-tag ls "$pkg_name" --fetch-retries=0 --fetch-timeout=8000 || echo "::warning::Could not read npm dist-tags; exact version was verified"
exit 0
fi
echo "::notice::@bitkyc08/opencodex@${RELEASE_VERSION} not visible in npm registry yet (attempt $attempt/30)"
sleep 10
echo "::notice::Registry lookup not confirmed (attempt $attempt/6)"
if [ "$attempt" -lt 6 ]; then sleep 5; fi
done
echo "::error::npm registry smoke failed after 30 attempts"
npm view @bitkyc08/opencodex versions dist-tags --json || true
exit 1
echo "verification=pending" >> "$GITHUB_OUTPUT"
echo "::warning::npm publish succeeded, but registry verification remains pending; continuing GitHub release creation without republishing"
echo "Publication acknowledged for ${pkg_name}@${RELEASE_VERSION}; registry verification pending after bounded reads. Inspect the registry before announcing availability. Do not republish this version." >> "$GITHUB_STEP_SUMMARY"

- name: Create GitHub release
if: ${{ inputs.dry-run != true }}
if: ${{ inputs.dry-run != true && steps.publication.outputs.published == 'true' }}
env:
GH_TOKEN: ${{ github.token }}
RELEASE_VERSION: ${{ inputs.version }}
Expand Down
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,26 @@ account exclusion, affinity expiry, or 401/403 and 429 recovery can rebind them.
selection order when one of them — usually your Codex Desktop login — should only be reached for
once the others are drained.

### Sponsors

Sponsors keep opencodex maintained across every upstream protocol change. Interested?
See [SPONSORS.md](./SPONSORS.md).

<!-- sponsors:main — one banner, model developers only; empty until a Main sponsor signs -->

<!-- sponsors:standard — one row per sponsor, in order of signing. Uncomment the table with the first row:
<table>
<tbody>
<tr>
<td width="180"><a href="SPONSOR_URL"><img src="https://raw.githubusercontent.com/lidge-jun/opencodex/main/assets/sponsors/SPONSOR.png" alt="SPONSOR" width="150"></a></td>
<td>Thanks to SPONSOR for sponsoring this project! BLURB</td>
</tr>
</tbody>
</table>
-->

---

<details>
<summary>Docker Compose</summary>

Expand Down Expand Up @@ -211,6 +231,7 @@ see the [installation docs](https://opencodex.me/getting-started/installation/).
- **Sub-agents on any model** — feature routed models in Codex's sub-agent picker, with v1/v2
surface control and fallback chains. See the
[sub-agent guide](https://opencodex.me/guides/sub-agent-surface/).
<!-- sponsors:main-first-mention -->
- **Log in once, skip the API key** — OAuth for xAI, Anthropic, and Kimi; or forward
`codex login`, paste a key, or use `${ENV_VAR}` references.
- **Web search & vision sidecars** — non-OpenAI models get real web search and image understanding
Expand Down Expand Up @@ -263,6 +284,7 @@ full-slash form keeps working too. Details: [model routing docs](https://opencod

## Providers & adapters

<!-- sponsors:main-first-mention -->
OpenAI (ChatGPT login or API key), Anthropic, Google Gemini, xAI, Kimi, Azure OpenAI, Ollama
(local + Cloud), Cursor (experimental), and every OpenAI-compatible endpoint — plus DeepSeek,
Groq, OpenRouter, Together, Fireworks, Cerebras, Mistral, Hugging Face, NVIDIA NIM, MiniMax,
Expand Down
105 changes: 105 additions & 0 deletions SPONSORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Sponsors

opencodex is an independent, MIT-licensed project maintained without company backing. Provider
sponsorships fund maintenance and keep the proxy current with every upstream protocol change.
This page is the public rule set: what a sponsor gets, who qualifies for which tier, and how to
ask. It is written so that a sponsor, a contributor, and a user reading the README all see the
same terms.

"Sponsor" here means a paying provider sponsor. It is unrelated to the `maintainer-sponsored`
label in [`MAINTAINERS.md`](./MAINTAINERS.md), which is about a maintainer vouching for a
contributor's change to a restricted surface.

Sponsorship buys placement and maintenance attention. It never buys a change in routing behavior,
a default model, a weaker security default, or an exception to the review policy in
[`MAINTAINERS.md`](./MAINTAINERS.md). A sponsored preset goes through the same registry
pattern, typecheck, tests, and review as any other provider.

## Tiers

Two tiers, split by what the sponsor is.

### Main — model developers

Reserved for organizations that train or host their own foundation models (the OpenAI,
Anthropic, Google, Moonshot, MiniMax class). API relays and gateways are never sold Main
regardless of budget.

Every model developer is supported as a first-class provider whether or not it sponsors; that
part does not change. A Main sponsor additionally receives:

- The single banner slot above the sponsor table in the README (one at a time; see
[Placement](#placement)).
- First mention in the README login and provider lines (the "Log in once" OAuth paragraph and
the Providers & adapters summary, both marked with a `sponsors:main-first-mention` comment)
and priority ordering in the built-in provider picker.
- Everything in the Standard tier below.

### Standard — relays, gateways, and API resellers

For OpenAI-compatible relays, routers, gateways, and other resellers of model access. A Standard
sponsor receives:

- One row in the sponsor table: logo (about 150px wide, linking to the sponsor URL), a
"Thanks to X for sponsoring this project!" line, and a blurb of up to about 80 English words
supplied by the sponsor and published verbatim. The maintainer may decline or require edits to
text that is false, misleading, disparages third parties, or breaches applicable law or GitHub
policy. A second-language blurb (for example Chinese) may run alongside the English one.
- A built-in provider preset (`ocx provider select <id>`) shipped in a public npm release,
listed near the top of the provider picker in the dashboard and CLI and marked as a sponsor
there. (The registry field and picker ordering that back this land with the first sponsor
preset; today the picker follows registry order.)
- A detailed entry on the [providers page](https://opencodex.me/guides/providers/) of the docs
site.
- Maintenance: if a release breaks the preset or its adapter, the maintainer fixes it; issues
filed against that provider are triaged first. There is no response-time SLA.

## Placement

The README sponsor section sits directly under **Quick start**, before the Docker Compose
details, so it is on screen before a first-time visitor scrolls. It carries one line of context
and the placements themselves:

1. One Main banner (empty until a Main sponsor signs).
2. The Standard table, one row per sponsor, in order of signing date.

The README says nothing else about sponsorship; tiers, pricing, and contact channels live only on
this page.

The translated READMEs under [`readme/`](./readme) carry one linking line right after their
own quick-start block instead of duplicating the section, so a sponsor change is one edit in
English.

## Pricing

Pricing is by inquiry; there is no public rate card. Sponsors who sign before the repository
reaches 20,000 GitHub stars lock in their rate for the length of their agreement. Rates rise
once that mark is passed.

Agreements are integration-scoped: they name the deliverables above, anchor the term to the npm
release that ships them, and carry no marketing obligations on either side. Both sides can walk
away with a pro-rated refund of unused months if the integration cannot be delivered.

## How to ask

- X: DM [@claudeebum](https://x.com/claudeebum)
- Discord: [discord.gg/JEaPEtkHwh](https://discord.gg/JEaPEtkHwh), channel `#sponsors`
- Email: jun@lidgeai.com

Send what you are (model developer or relay), the base URL and model list of your
OpenAI-compatible endpoint, and the tier you want. The maintainer replies with terms and a
draft agreement.

## What sponsors do not get

- No influence on routing defaults, failover order, quota policy, or which provider a user's
request reaches.
- No relaxation of the [security review](./MAINTAINERS.md) that applies to authentication,
credentials, or workflow changes.
- No access to user data, request logs, or telemetry; opencodex does not collect any.
- No say over unrelated issues, pull requests, or the release schedule.

## Current sponsors

Listed in the README sponsor section. This page carries the rules; the README carries the
names.
2 changes: 1 addition & 1 deletion devlog/_fin/260905_always_on_429_failover/090_outcome.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ the tree rather than against the plan — the plan's own criteria were satisfied
Two were defects the fix itself created (#3499, #3503), three were surfaces still describing the
old contract (#3517, #3520, #3523), one closed the structural gap that let this unit ship two
subset-rotator loops (#3512), and one cleaned up after a collision with concurrent maintainer
work (#3526). All are recorded in `091`.
work (#3526). The runtime post-merge findings and CI lessons are recorded in `091`.

## What changed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,37 @@ The post-merge run on `dev` then showed `ci failure`, which was a genuinely alar
out. It turned out to be cancellation by the maintainer's next merge two minutes later, not a
real failure — every job read `cancelled`, not `failure`.

**Rule:** verify with the check-runs API and require zero `null` conclusions, not a pass count:
**Rule:** use the exact head SHA, require every expected aggregate or policy gate by name, and
also require zero non-terminal check runs. A missing check is not success. Paginate before treating
the returned set as complete:

```bash
gh api repos/<owner>/<repo>/commits/<sha>/check-runs \
--jq '[.check_runs[] | .conclusion] | group_by(.) | map({(.[0]//"null"): length}) | add'
set -o pipefail
gh api --paginate repos/<owner>/<repo>/commits/<sha>/check-runs \
| jq -se '
[.[].check_runs[]] as $runs
| ["ci", "enforce-target", "hygiene", "react-doctor"] as $expected
| ($expected - [
$runs[]
| select(.status == "completed" and .conclusion == "success")
| .name
]) as $missing
| [
$runs[]
| select(.status != "completed" or .conclusion == null)
| .name
] as $pending
| if ($missing | length) == 0 and ($pending | length) == 0
then {ready: true, expected: $expected}
else error("missing=\($missing) pending=\($pending)")
end'
```

A clean result looks like `{"skipped":3,"success":24}` — no `null` key at all.
A clean result is `{"ready":true,...}` with exit status 0. This does not replace review-policy
checks such as confirming the approval belongs to the same head. Every `$expected` value is an
exact Checks API `.check_runs[].name`, not a workflow title or workflow-run name. If those required
check-run names change, update this list with the policy; silently accepting an absent name
recreates the original bug.

The near-miss paid for itself: sweeping `dev` afterwards found a real defect. #3511 and #3513
landed concurrently, one moving `anthropic-quorum-cache.test.ts` into `tests/routing/` and the
Expand Down
Loading
Loading