Skip to content

feat(sdk): expose model profiles as synthetic gajae-code/<profile> models - #24

Open
snowykr wants to merge 8 commits into
devfrom
preset-to-model
Open

feat(sdk): expose model profiles as synthetic gajae-code/<profile> models#24
snowykr wants to merge 8 commits into
devfrom
preset-to-model

Conversation

@snowykr

@snowykr snowykr commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Problem

External ACP/SDK clients (notably the Paseo TUI, registered as a generic ACP provider) can discover GJC's model catalog through the ACP Model select, but model presets were only reachable through the session-scoped startup --mpreset/Q27 Preset select — never as ordinary model choices — and there was no way for a client to persist a preset as the global default. Users of paseo-style clients had to fall back to the TUI for preset configuration.

Change

The SDK models.list/current (Q10) catalog now lists model profiles as logical synthetic models under the reserved namespace gajae-code/<profile> (e.g. gajae-code/codex-eco, displayed as "Codex Eco"). Selecting one through model.set (or the ACP Model picker) activates the profile in the live session and persists it to the global modelProfile.default, mirroring gjc --mpreset <name> --default — with the same credential preflight, role clearing, settings flush, and rollback as the CLI path.

Key semantics:

  • Surface scope: the facade lives only in the Q10 projection and a shared resolver (sdk/model-profile-model.ts). No fake Model registry entries; no TUI /model, --list-models, auth-gateway /v1/models, coordinator MCP, or Q29 provider-row changes. Verified non-leakage: gjc --list-models shows no gajae-code rows.
  • Current-state invariant: Q10 current / config.list/get model derive exclusively from the in-session active-profile marker (session.getActiveModelProfile()), never the persisted default; the marker is cleared only on successful concrete user/startup-override materialization (incl. setModelTemporaryForControl) and never on internal fallback/restore/rollback (activation's own profile-activation cause never self-clears). A persisted-but-inactive default never creates a synthetic current row.
  • Availability: synthetic rows use the same authenticated-provider derivation as Q27 (strict + alternative groups); an active-but-unavailable profile stays visible as the current readback; registry/join errors degrade fail-closed to the concrete catalog plus the active-marker fallback (never a whole-Q10 failure).
  • Selection routing: model.set with gajae-code/* validates/canonicalizes the suffix (lossless after the first slash, legacy alias support), rejects non-off thinking levels as invalid_input before admission, and routes through activateModelProfile({ persistDefault: true }) inside the shared session admission queue. config.patch is serialized through the same admission boundary so a patch racing an activation is never lost or clobbered.
  • Reserved namespace: a user-defined models.yml provider named gajae-code fails closed (rows omitted, selection rejected) instead of being silently shadowed.
  • Errors: unknown/empty/ambiguous synthetic ids → SDK invalid_input (ACP invalidParams via the existing mapping); missing profile credentials → authentication_failed (authRequired); the no-thinking result envelope is exactly { changed: true }, the typed result is { provider: "gajae-code", modelId, thinkingLevel }.

User-visible behavior

  • ACP/SDK clients can now list and select presets exactly like models, and the selection becomes the global default for future launches.
  • While a preset is active, Q10/config.list/get report the synthetic id as current (gajae-code/<profile>, currentThinkingLevel: "inherit"); the existing ACP startup --mpreset/Q27 Preset select stays session-scoped and unchanged.
  • Docs updated: docs/sdk.md, docs/external-control-readiness.md (Paseo section), docs/sdk-app-guide.md, docs/models.md; CHANGELOG.md entry added.

Validation

  • Tests: 233/233 across the directly affected suites (new sdk-model-profile-model.test.ts; extended sdk-q10-models, sdk-control-dispatch, sdk-host-wiring, sdk-default-model-selection-e2e), including concurrency races (two concurrent selections FIFO, config.patch racing a selection) and registry-error fail-closed.
  • Typecheck: bun --cwd=packages/coding-agent run check:types clean; package check (biome + tsc) clean.
  • Repo gates: verify-g002-gates.ts, rebrand-inventory.ts --strict, check-visible-definitions.ts, default-gjc-definitions.test.ts all pass; check:schemas clean; docs-index regenerated in sync.
  • ACP conformance: pinned acp-core-v1 corpus (acpx 0.13.0) 21/21.
  • Real-process e2e (paseo-shaped): a live smoke drives the production gjc acp process with an ACP client (same protocol paseo uses): the Model config options contain gajae-code/custom-eco; session/set_config_option switches the session; a prompt turn runs on the profile's default model; modelProfile.default is persisted in the real config.yml; a fresh gjc acp launch reapplies it; --list-models shows no gajae-code rows.

Related work

No existing open PR targets this surface (checked gh pr list --head preset-to-model). This is additive to the ACP preset-catalog work (Yeachan-Heo#3922) — it extends the same Q10/ACP pipeline from "filter the model catalog" to "offer presets as selectable models that persist globally". No duplicate; complements the existing startup Preset mode rather than replacing it.

Checklist

  • Repository contribution guidelines (CONTRIBUTING.md) followed — targets dev
  • Problem and motivation clearly described
  • Scope focused (SDK/ACP surface only; no TUI//v1-models/coordinator changes)
  • User-visible behavior documented (docs + CHANGELOG)
  • Failure handling and recovery considered (fail-closed availability, rollback, reserved-namespace collision)
  • Commits organized into one coherent unit (squashed; no temp/fixup commits)
  • Commit message explains purpose
  • Appropriate tests added/updated (unit + integration + real-process e2e)
  • Validation results included (233/233, typecheck, gates, conformance 21/21, smoke)
  • CI will run on the final head commit

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8da5d1bf73

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1a4c255480

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/bus/index.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66a79385f4

ℹ️ 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".

Comment thread packages/coding-agent/src/session/agent-session.ts
Comment thread packages/coding-agent/src/modes/runtime-init.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1fd84c54f8

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4673b585d0

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated
Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f82475bdb0

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated
Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 92fa873412

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated
Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated
Comment thread packages/coding-agent/src/session/agent-session.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bd550ac40a

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/bus/index.ts
Comment thread packages/coding-agent/src/sdk/host/session-runtime.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9a215d53d6

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/host/session-runtime.ts
Comment thread packages/coding-agent/src/session/agent-session.ts Outdated
Comment thread packages/coding-agent/src/extensibility/extensions/compact-handler.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 38ff34a185

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/host/session-runtime.ts Outdated
Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a6067c473

ℹ️ 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".

Comment thread packages/coding-agent/src/session/agent-session.ts Outdated
Comment thread packages/coding-agent/src/sdk/host/session-runtime.ts Outdated
@snowykr
snowykr force-pushed the preset-to-model branch 4 times, most recently from 7c4943a to 94c4f1c Compare August 7, 2026 06:34

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94c4f1c6ea

ℹ️ 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".

Comment thread packages/coding-agent/src/session/agent-session.ts Outdated
Comment thread packages/coding-agent/src/modes/runtime-init.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f9557f176

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 55f77b37e1

ℹ️ 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".

Comment thread packages/coding-agent/src/extensibility/extensions/compact-handler.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0dcd3e9a0d

ℹ️ 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".

Comment thread packages/coding-agent/src/modes/runtime-init.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2ce26fdb2b

ℹ️ 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".

Comment thread packages/coding-agent/src/session/agent-session.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4c870c84de

ℹ️ 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".

Comment thread packages/coding-agent/src/session/agent-session.ts
@snowykr
snowykr force-pushed the preset-to-model branch 2 times, most recently from 0f49a3e to 2f2e5df Compare August 7, 2026 07:31
@snowykr
snowykr force-pushed the preset-to-model branch 2 times, most recently from d11aefa to 109fa8b Compare August 7, 2026 08:22

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d11aefa993

ℹ️ 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".

Comment thread packages/coding-agent/CHANGELOG.md Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7b38026923

ℹ️ 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".

Comment thread packages/coding-agent/src/sdk/host/session-runtime.ts
@snowykr
snowykr force-pushed the preset-to-model branch 2 times, most recently from aeda94c to ebb3808 Compare August 7, 2026 08:40

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ebb380887e

ℹ️ 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".

Comment thread packages/coding-agent/src/session/agent-session.ts Outdated
Comment thread packages/coding-agent/src/sdk/bus/index.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 40bd86ac60

ℹ️ 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".

Comment thread packages/coding-agent/src/config/model-profile-activation.ts Outdated
Comment thread packages/coding-agent/src/session/agent-session.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 962b35cf0d

ℹ️ 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".

Comment thread packages/coding-agent/src/modes/runtime-init.ts Outdated
@snowykr
snowykr force-pushed the preset-to-model branch 2 times, most recently from e4de5d3 to 3cd7353 Compare August 7, 2026 09:20

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3cd7353c58

ℹ️ 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".

Comment thread packages/coding-agent/src/modes/runtime-init.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8491f2cbf7

ℹ️ 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".

Comment thread packages/coding-agent/src/session/agent-session.ts
Comment thread packages/coding-agent/src/session/agent-session.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1f83d2d614

ℹ️ 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".

Comment on lines +10857 to +10861
if (this.#activeProfileInstalledRoles.has(role)) continue;
const bindingValue = bindings?.modelRoles?.[role];
this.#activeProfileInstalledRoles.set(
role,
bindingValue ?? this.settings.getGlobal("modelRoles")?.[role as never],

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restore current durable roles when dropping a profile

When a session-scoped profile owns a role, this first-activation snapshot is never updated. If config.patch durably changes that same modelRoles entry while the profile remains active, a later concrete selection or session transition restores the old snapshot into the runtime override, masking the newly persisted value until restart; the agent-override loop has the same behavior. Remove the profile-owned key so the current lower settings layer becomes visible, then reapply configured bindings, rather than restoring a stale baseline.

Useful? React with 👍 / 👎.

…dels

External ACP/SDK clients (notably the paseo TUI) could only use presets via
the session-scoped startup Preset select, never as ordinary model choices,
and could not persist a preset as the global default. Selecting a preset
now behaves exactly like picking a model: Q10 models.list/current lists
every availability-filtered profile as a logical gajae-code/<profile> row,
and model.set on that namespace activates the profile live AND persists it
to global modelProfile.default (mirror of `gjc --mpreset <name> --default`),
with the same credential preflight, role clearing, flush, and rollback as
the CLI path.

The facade lives only in the Q10 projection and a shared resolver: no fake
Model registry entries, no TUI / --list-models / /v1-models / coordinator /
Q29 surface changes. Logical current derives exclusively from the in-session
active-profile marker (never the persisted default), cleared only on
successful concrete user/startup-override materialization (including the
scoped, unscoped, and role cycle paths and the interactive setModel
bindings); config.patch and activation serialize through the shared session
admission boundary, with a structurally-compared shadow that invalidates
profile-owned keys after activation while preserving unrelated patches;
availability uses the Q27 authenticated-provider derivation with
pattern-aware, managed-fallback-eligible default resolution, and degrades
fail-closed on registry, join, or per-profile resolution errors. gajae-code
is a reserved namespace with deterministic collision handling.

Planned via ralplan (run 20260806-201255; Architect CLEAR pass 3, Critic
OKAY pass 3) and executed under ultragoal with boundary-cohort gate and
terminal critic OKAY. Verified: 247/247 affected tests, package typecheck,
ACP core-v1 conformance 21/21, the four repo gates, and a live real-process
ACP smoke (paseo-shaped) proving selection, global persistence, fresh-launch
reapply, prompt execution on the profile default model, and non-leakage
into --list-models.

Lore-id: preset-to-model-sdk-facade
Directive: keep gajae-code reserved; document any future namespace change
Tested: Q10 synthetic projection, marker lifecycle, concurrency races,
  config.patch shadow freshness, registry-error fail-closed, ACP corpus,
  live ACP smoke
Not-tested: manual paseo picker render on a real device
@snowykr

snowykr commented Aug 7, 2026

Copy link
Copy Markdown
Owner Author

Re: the profile-chain and role-free-binding threads — fixed in 5a7aed9. Dropping a session-only profile clears the profile-owned default fallback chain, and configured modelBindings are force-reapplied whenever a profile was active (including role-free default-only ones). Verified: package check and 263 focused tests pass.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5a7aed9934

ℹ️ 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".

Comment on lines +10862 to +10864
const defaultChain = getSessionContextForInternalRead(this.sessionManager).configuredModelChains.default;
if (defaultChain && defaultChain.identity !== undefined) {
this.setConfiguredModelChain("default", [], "user-selection");

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve the successor session's fallback chain

When switching away from a session-scoped profile, switchSession() invokes this reset after setSessionFile() has loaded and resolved the successor session. This lookup therefore reads the successor's configuredModelChains.default, and any successor saved with its own profile-owned chain has that chain cleared and subsequently persisted by ensureOnDisk(), disabling its retries/fallbacks. Clear the chain before replacing the session context, or only clear it when its identity matches the profile marker being dropped.

Useful? React with 👍 / 👎.

Comment on lines +3882 to +3885
if (
definition.valueSchema.type === "model-selector-value" &&
!(typeof entry === "string" || (Array.isArray(entry) && entry.every(item => typeof item === "string")))
) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject empty model-selector values in config patches

For an SDK patch such as { modelRoles: { default: [] } } or { modelRoles: { default: "" } }, this check accepts the value because an empty array vacuously contains only strings and strings are not checked for blank content. The newly enabled SDK-only config.patch path then persists a value that violates the model-selector contract; downstream normalization treats it as no selector, silently disabling the configured default routing. Validate these entries with the existing isModelSelectorValue() predicate, which enforces nonblank strings and nonempty chains.

Useful? React with 👍 / 👎.

lightofjeju and others added 6 commits August 7, 2026 10:25
The canonical replacement-receipt ENOENT guard had no regression at the exact readdir-to-open window, while the legacy test deleted its receipt before enumeration and never exercised the catch.

Inject disappearance from openSync so both canonical and legacy tests prove mutation continues only for benign absence.

Lore-id: canonical-receipt-preopen-enoent

Constraint: preserve fail-closed handling for identity mismatch and non-ENOENT failures

Confidence: high

Scope-risk: narrow

Reversibility: trivial

Tested: bun test packages/coding-agent/test/session-storage.test.ts -t replacement cleanup receipt reconcile TOCTOU resilience (4 pass)

Tested: bun --cwd=packages/coding-agent run check

Not-tested: full session-storage file clean; 4 unrelated writer-security failures remain in the local native build
Yeachan-Heo#3994)

A managed session scope is snapshotted in full on every session start, and
the snapshot fails closed once the tree exceeds the managed byte budget. The
scope is filled by GJC's own session records — tool logs, subagent
transcripts, artifacts — so a working directory in sustained use crosses the
budget without the operator doing anything unusual.

There is no signal before that happens. The first symptom is a launch that
aborts, and `gjc gc` (the command that already reports state the operator
cannot otherwise see) says nothing about it. On the machine this was found,
the scope reached 577 MiB against a 512 MiB budget with no prior warning.

Report scope usage from `gjc gc` once a scope is at or past 75% of the
budget. The probe only measures; nothing in the prune path acts on it, and
`gc` still reclaims no session records.

Deliberately conservative so existing runs are unaffected:
- Scopes below the threshold are omitted, so output is byte-identical for
  anyone not near the budget.
- Absent / non-directory / unreadable scopes report `unavailable` rather
  than failing the run.
- An unreadable subtree is skipped and the walk continues, because a partial
  total still answers "am I near the budget?".
- The walk is bounded, and a truncated walk is marked so the total is read
  as a floor rather than a measurement.

Refs Yeachan-Heo#3959. The capacity problem itself — no retention policy, and `gjc gc`
unable to reclaim session records — needs a maintainer decision and is left
out of this change.

Tests: packages/coding-agent/test/gc-session-scope.test.ts (6 new)
…ssion

Review of Yeachan-Heo#3988 found the advertised session-scoped guarantee did not hold
when no durable modelRoles.default exists -- the default state for the
ACP-only clients this feature targets. resolveConfiguredDefaultModel()
resolves with currentModel=undefined, so it returns undefined and the
restore guard in #initializeNewSessionState was a no-op, leaving /new to
record the profile's model as the successor's. Two sibling gates read the
merged settings layer where they authorize durable global writes.

Lore-id: 3f9c21ab
Constraint: the pre-profile model must be snapshotted by the caller -- activation replaces the runtime model before noteProfileInstalledOverrides runs
Constraint: first activation wins so chained session-only profiles restore the original selection, not the previous profile's
Rejected: read this.model inside noteProfileInstalledOverrides | setModelTemporary already overwrote it, so it captures the profile's own model
Rejected: change resolveConfiguredDefaultModel to accept a current model | the TUI resume flow depends on its current semantics
Confidence: high
Scope-risk: narrow
Reversibility: easy
Tested: /new after a session-only profile with no durable default restores the pre-profile model and writes no modelRoles
Not-tested: rollback promotion under a concurrent project-config write
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants