Repository navigation
Luna Reserve capability is bound to codexDesktopAuthless, a flag documented as controlling Codex app sign-in #4961
Description
Area
Catalog / models
What are you trying to accomplish?
I want to know, from the outside, whether Luna Reserve support is available on an install — and
I want that answer to depend on something that is about Luna Reserve.
Today it depends on codexDesktopAuthless, a switch whose entire documented purpose is
unrelated: "inject the dedicated opencodex provider with requires_openai_auth = false so
Desktop opens without a ChatGPT login"
(docs-site/src/content/docs/reference/configuration/server.md:32). Nothing in that sentence,
or in its ocx system settings --desktop-authless on spelling, tells an operator that it is
also the master switch for Reserve.
This is filed as a coupling defect, not a feature request. I am deliberately not proposing a
design; I think the problem should be recorded before anyone reaches for a fix.
What prevents this today?
Two capabilities ride one flag.
isCodexReserveRequestEligible (src/codex/loopback-target.ts:19-24) gates every Reserve
affordance on three conditions, of which the flag is one:
export function isCodexReserveRequestEligible(
config: Pick<OcxConfig, "codexDesktopAuthless" | "runtimeRole">,
admission: Pick<DataPlaneAdmission, "source"> | undefined,
): boolean {
return config.codexDesktopAuthless === true && config.runtimeRole !== "client"
&& admission?.source === "loopback";
}The catalog half is gated the same way through isEffectiveCodexDesktopAuthless
(src/codex/loopback-target.ts:93-98), which createReserveCatalogProjection consults first
(src/codex/catalog/reserve.ts:25).
Everything downstream inherits it: the Reserve catalog row; the main-credential substitution
customReserveForward (src/server/responses/compact.ts:672-674); the Reserve authorization
handshake via requiresReserveAuthorization (src/codex/auth-context.ts:552); the
vision-helper refusal (src/codex/loopback-target.ts:15); the reserveCompatibility settings
passed to web search and vision (src/web-search/index.ts:270, src/vision/plan.ts:246); and
the search path at src/server/search.ts:105.
What makes the coupling sharp rather than merely untidy is that on a default loopback install
the flag is the only remaining condition. isEffectiveCodexDesktopAuthless reduces to
codexDesktopAuthless === true && runtimeRole !== "client" && !shouldInjectApiAuthHeader(config),
and shouldInjectApiAuthHeader returns false for a loopback hostname with no dedicated
listener. A stock ocx ensure install therefore already satisfies every condition for Reserve
except an opt-in that is about something else.
What should OpenCodex do?
Observably: whether Luna Reserve is available should be decided by, and reported in terms of,
Reserve's own preconditions — not by a switch documented as controlling whether the Codex app
asks for a sign-in. An operator reading the configuration reference should be able to tell which
setting governs Reserve, and an operator who changes one of the two capabilities should be able
to predict what happens to the other.
I am explicitly not proposing how to get there, and I would rather this issue not acquire a
design before the problem is agreed. Splitting a shipped flag has migration consequences for
existing configurations that deserve their own discussion.
Example usage or interface
The coupling is what produced two separate bug reports, from two directions, within a day.
#4811 — flag on, Reserve still absent. Authless is effective, but the Reserve projection
is account-qualified and codexAccountNamespaces is empty on a fresh install, so
mainSelectors is empty and createReserveCatalogProjection returns undefined. The operator
turned on the switch they were told governs this and got nothing.
#4940 — flag off, Reserve inert and the failure is attributed upstream:
429 openai-<acct>/gpt-reserve 3915ms routeKind=native
errorCode=rate_limit_exceeded upstreamError="The usage limit has been reached"
That reporter is on a stock loopback install with codexDesktopAuthless unset. Because the flag
is off, isCodexReserveRequestEligible is false, no Reserve authorization is attempted, and
gpt-reserve is forwarded as an ordinary native model. Nothing in the error names the setting
that would have changed the outcome.
Both reports describe the same underlying shape: a capability whose availability is decided
somewhere the operator has no reason to look.
Alternatives or workarounds
An operator can set codexDesktopAuthless: true to obtain Reserve, but that also changes how
the Codex app authenticates, which is a separate decision they may not want to make. There is no
way to take one without the other, and no diagnostic that connects the two.
Additional context
- Luna Reserve catalog row is silently suppressed unless the undocumented account-picker map is populated #4811 — Reserve row suppressed with the flag on (the selector-map half).
- Codex Desktop hides all opencodex-routed models once Luna Reserve is active; gpt-reserve forwarded natively and rejected #4940 — Reserve inert with the flag off (the request-path half).
- Bare
gpt-reservegets no catalog row outside codexDesktopAuthless: tool_mode falls back to direct, ~250k tokens of inlined tool schemas at boot #3844 — closed not planned: a baregpt-reservecatalog row outsidecodexDesktopAuthless.
Recorded here because it is the boundary this report does not cross; nothing in this issue asks
to reopen that decision.
All references above were read at dev a0f611d4aceb9476d44268e43722273b7b211846. No runtime
evidence is claimed; every statement here is from source.
Checks
- I searched existing issues and documentation.
- This request describes a concrete OpenCodex workflow rather than merely naming a desired technology.
- I removed secrets and personal data.
Activity
lidge-jun commentedon Sep 27, 2026
Release train 4 (account-pool lane) confirmed that the coupling is still present on
dev:src/codex/loopback-target.tsandsrc/codex/catalog/reserve.tsgate every Reserve affordance oncodexDesktopAuthless. We are keeping this open and changing nothing this train, because removing the check would silently change existing operators' Reserve entitlement.A fix needs:
#5879 would make this more pressing, since it toggles the flag automatically.
lidge-jun commentedon Oct 6, 2026
Maintainer note (interview 2026-10-06): keeping open with needs-design.
Reserve is still coupled to
codexDesktopAuthlesson currentdev(~0% toward a separate capability). Needs a migration-preserving design before implementation.