Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70dab84399
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Expose Codex during onboarding and add a guided Base URL plus API Key path alongside ChatGPT login. Generate a dedicated Responses API model provider while preserving unrelated Codex configuration. Model: gpt-5
Model: gpt-5
70dab84 to
566ef64
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 566ef646f0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Model: gpt-5
|
Second-round state-machine blockers addressed in In addition to the three inline threads, endpoint/key-changing edits no longer update the live Validation: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9f405022b7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Model: gpt-5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c3dca0036d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: df6eda4cb6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Model: gpt-5
df6eda4 to
68e0d45
Compare
Model: gpt-5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6f63cdbb61
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (getLodyCodexCustomProvider(config.env)) { | ||
| await deleteSetup({ | ||
| id: config.id, | ||
| machineId: config.machineId, | ||
| preservePublishedConfig: false, |
There was a problem hiding this comment.
Delete the config before pruning the optimistic cache
When deleting a custom Codex provider on an offline remote machine, awaiting deleteSetup first removes the agentConfig from the initiating client's optimistic rows because preservePublishedConfig is false; the subsequent deleteConfig(config.id) re-reads getAllAgentConfigAtom, finds no config, and skips the durable Flock deletion. Fresh evidence after the prior deletion fix is this call ordering together with deleteAgentConfigAtom's cache-dependent lookup, so until the daemon reconnects and applies the cancellation, a reload or another client reads the still-durable config and shows the deleted provider again. Delete using the captured config before pruning it from the cache.
AGENTS.md reference: packages/components/src/components/settings/AGENTS.md:L24-L26
Useful? React with 👍 / 👎.
Model: gpt-5
Model: gpt-5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a5442efd3e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ...config, | ||
| env: { ...config.env, [LODY_CODEX_API_KEY_ENV]: candidateApiKey }, | ||
| }; | ||
| provisioningRefresh = await verifyConfig(verifiedConfig, signal); |
There was a problem hiding this comment.
Defer capability cache writes until publication commits
When cancellation or a newer setup revision wins after the live probe succeeds, verifyConfig() has already persisted the staged endpoint's capability cache before commitCodexProviderCredential() rejects publication. The original AgentConfig remains active, but Codex's capability source version does not include the endpoint binding, so sessions and settings can continue using models/options discovered from the rejected endpoint. Stage the probe result without updating the shared cache, then publish it only after the setup commit succeeds.
AGENTS.md reference: apps/cli/src/agent/AGENTS.md:L81-L82
Useful? React with 👍 / 👎.
| const ids = new Set<AgentConfigId>([ | ||
| ...(Object.keys(configs) as AgentConfigId[]), | ||
| ...(Object.keys(setups) as AgentConfigId[]), | ||
| ...(Object.keys(cancellations) as AgentConfigId[]), | ||
| ]); |
There was a problem hiding this comment.
Reconcile credentials for direct agent-config deletions
When a custom Codex provider is removed through the shipped lody agent-config delete path (apps/cli/src/commands/agent-config.ts:834) or an older client, the generic deletion writes no providerSetupCancellation. This recovery scan only discovers IDs that still have a config, setup, or cancellation row, so the deleted ID is absent and its hashed provider-credential file remains on disk indefinitely. Ensure every deletion path emits the cleanup intent, or retain enough local indexing to reconcile credentials whose Flock rows have disappeared.
Useful? React with 👍 / 👎.
Drop the obsolete Electron release-workflow assertion after the base branch removed that workflow. Model: gpt-5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1faa68036f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export function providerSetupContainsCodexCredential(config: AgentConfigMeta): boolean { | ||
| return Boolean(config.env[LODY_CODEX_API_KEY_ENV]?.trim()); |
There was a problem hiding this comment.
Reject the local credential from AgentConfig rows
This guard is applied only to providerSetup rows, while the shipped lody agent-config create/update --env paths still accept arbitrary environment keys and directly upsert an AgentConfig (apps/cli/src/commands/agent-config.ts:680,790). Supplying LODY_CODEX_CUSTOM_ENDPOINT_API_KEY through either path therefore stores the raw API key in the synced Machine Flock—and agent-config show subsequently prints it—exposing a credential intended to remain machine-local to workspace readers. Reject this reserved key at every AgentConfig write/normalization boundary, not only inside setup drafts.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cd4f601d69
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| export function agentConfigContainsCodexCredential(config: AgentConfigEnvironment): boolean { | ||
| return Boolean( | ||
| config.env && Object.prototype.hasOwnProperty.call(config.env, LODY_CODEX_API_KEY_ENV) | ||
| ); |
There was a problem hiding this comment.
Reject reserved environment keys case-insensitively
On Windows, environment-variable names are case-insensitive, but this exact-case lookup lets an alias such as lody_codex_custom_endpoint_api_key pass every new AgentConfig guard. A user can therefore add that spelling through lody agent-config create/update --env; Codex can consume it as the generated uppercase env_key, while Machine Flock and agent-config show persist and reveal the raw credential. Fresh evidence after the earlier reserved-key fix is that the shared guard still compares literal casing; reject case-insensitive aliases on Windows (and filter them from credential bindings) as well.
Useful? React with 👍 / 👎.
| const provision = await provisionCodexCredential({ | ||
| machineId: config.machineId, | ||
| configId: config.id, | ||
| setupRevision: payload.setupRevision, | ||
| apiKey: payload.codexApiKey, | ||
| }); |
There was a problem hiding this comment.
Cancel provisioning when the dialog is dismissed
While this provisioning call is awaiting setup synchronization, input, or the live probe, the dialog can still be dismissed through its Radix close button, Escape, or backdrop, and the parent immediately unmounts AgentConfigDialog. The authentication hook is owned by the still-mounted settings/onboarding parent, so its cleanup does not send cancellation and this await can later publish the provider and store the key after the user closed the flow. Fresh evidence after the prior lifecycle fix is that dialog dismissal never reaches that cancellable backend lifecycle; prevent dismissal while submitting or explicitly cancel the request on dialog teardown.
Useful? React with 👍 / 👎.
| if (existingCancellation && !setup && (!config || cancellation.preservePublishedConfig)) { | ||
| return false; | ||
| } | ||
| if (!existingCancellation) { |
There was a problem hiding this comment.
Replace revision-scoped markers with the wildcard delete barrier
When lody agent-config delete removes a custom Codex provider while this key already contains a revision-scoped cancellation from an earlier attempt, the incoming revision-independent cancellation is not written because existingCancellation is truthy. In a multi-replica race, a different-revision provisioning request on a daemon that has not observed the deletion can therefore publish later and clear the stale exact marker, resurrecting the deleted provider; the retained exact marker also is not treated as the durable wildcard cleanup intent. An incoming explicit wildcard cancellation must replace an existing revision-scoped marker.
Useful? React with 👍 / 👎.
Remove redundant credential compatibility and response state, preserve committed setup outcomes, and harden secret filtering and cancellation barriers. Model: gpt-6
Cover case-insensitive reserved credential keys, wildcard cancellation upgrades across replicas, and dialog dismissal during provisioning. Model: gpt-6
Document case-insensitive credential filtering, wildcard cancellation precedence, and dialog behavior during provisioning. Model: gpt-6
Model: gpt-6
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: a9af4cdfbc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| ...(previousEntry && previousEntry.binding !== desiredBinding | ||
| ? { previous: previousEntry } | ||
| : {}), |
There was a problem hiding this comment.
Preserve the old key during same-binding staging
If the daemon exits after writeRecord() but before publishVerifiedConfig() commits a same-endpoint key rotation, this condition omits the previous key because both entries have the same binding digest. On restart, both the published config and pending setup reference that digest, so reconciliation retains the new current key; subsequently cancelling the still-pending setup cannot restore the old key. The replacement credential therefore becomes active and the prior credential is lost even though publication never committed, contrary to the rule that cancellation wins until that boundary; retain enough staged state to restore the prior same-binding secret after this crash cut.
AGENTS.md reference: apps/cli/src/agent/AGENTS.md:L81-L85
Useful? React with 👍 / 👎.
Model: gpt-5
Give same-endpoint key rotations distinct non-secret binding identities so crash recovery can select the key chosen by the Flock commit boundary. Model: gpt-5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5981cadf73
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // Nothing is read from the mirror before it, so the boundary is never delayed. | ||
| // The durable marker is the cancellation accept boundary. The target CLI applies | ||
| // the revision CAS and removes the affected rows; local projection only hides them. | ||
| await runtime.writer.flockRowPut(flockDocId, cancellationKey, cancellation); |
There was a problem hiding this comment.
Preserve the wildcard barrier when writing exact cancellations
When a stale client failure-compensates revision R1 after another client has deleted the provider and written a wildcard cancellation, its cached setup can pass the revision precheck and this unconditional put replaces the single cancellation row with the narrower R1 marker. The daemon then sees only the merged exact marker, so a concurrent R2 setup is no longer fenced and can republish the deleted provider. Fresh evidence after the prior wildcard-precedence fix is that the renderer writer still bypasses applyProviderSetupCancellationToFlock; merge this write transactionally so an existing wildcard always wins over an exact cancellation.
AGENTS.md reference: packages/components/src/AGENTS.md:L81-L83
Useful? React with 👍 / 👎.
Route renderer cancellation through the shared transactional merge and mark authentication committed only after Flock commit succeeds. Model: gpt-5
Model: gpt-5
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b01eb43ed7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (!setup || setup.setupRevision !== setupRevision) return undefined; | ||
| return setup.machineId === machineId && | ||
| isValidDaemonLaunchConfig(setup.config, agentConfigId, machineId) | ||
| ? setup.config |
There was a problem hiding this comment.
Bind the revision to the staged launch config
When another workspace writer rewrites the shared providerSetup.config while preserving its visible setupRevision, this check accepts the altered row solely because the revision string matches. Fresh evidence beyond the prior setup-visibility race is that no expected config or binding digest crosses the RPC: provisioning then probes the accepted config with the victim's one-shot key, so a collaborator racing base_url to an endpoint they control can exfiltrate it. Bind the request to the exact staged launch-config digest and verify it before requesting or using the secret.
AGENTS.md reference: apps/cli/src/agent/AGENTS.md:L83-L85
Useful? React with 👍 / 👎.
| agentType: config.agentType, | ||
| customAcp: config.customAcp, | ||
| runtimeOverrides: config.runtimeOverrides, | ||
| env: config.env ?? {}, |
There was a problem hiding this comment.
Hydrate credentials before adding GitHub session variables
When a custom-endpoint Codex session targets a GitHub repository, both the cold and prepared launch paths call prepareGitHubRepoSessionConfig before this method; that adds GH_TOKEN and per-session broker variables to config.env. The credential record's binding was computed from the persisted AgentConfig.env, while hydration hashes the entire augmented environment, so the binding no longer matches and the API key is omitted, causing Codex to contact the custom endpoint without authentication. Hydrate against the untouched AgentConfig launch fields before merging per-session variables.
AGENTS.md reference: apps/cli/src/agent/AGENTS.md:L83-L85
Useful? React with 👍 / 👎.
Model: gpt-5
|
Desktop PR regression failed on commit
Recordings not attached
The Actions artifact retains the complete trace, screenshots, logs, and runtime evidence. |
Related issue
Same-repository product request; no separate tracking issue.
Problem
Codex setup exposed only ChatGPT device login, so users of OpenAI-compatible relay services could not provide a Base URL and API Key during onboarding. The credential must remain machine-local while renderer Flock writes and target-daemon RPCs synchronize asynchronously.
Summary
State flow
Delete and custom-to-ChatGPT first write a wildcard setup cancellation. The renderer then deletes the captured AgentConfig durably. An offline daemon later consumes the same cancellation as credential cleanup intent. Re-enabling custom atomically replaces that barrier with the fresh setup revision, so no replica can observe a barrier-free state that still authorizes an older setup.
Security and consistency properties
The credential RPC retains the existing shared-machine provider-management authorization boundary; this PR does not introduce a separate machine-owner role.
Verification
pnpm formatpnpm format:checkpnpm checkpnpm run docs checkPOST /v1/responses,stream=true, the configured model, and a matching bearer credential; the relay recorded only a boolean match and returned an intentional 401.No external third-party credential was used. Bundled Codex HTTPS downgrade and cross-origin redirect handling remains an explicitly unverified integration boundary.
Context handoff
Instructions for reviewing agents
Authoring context