Skip to content

feat(openai): request a Daybreak cyber access program on supporting models - #1507

Open
RamenFast wants to merge 2 commits into
1jehuang:masterfrom
RamenFast:feat/openai-daybreak-access-program
Open

RamenFast wants to merge 2 commits into
1jehuang:masterfrom
RamenFast:feat/openai-daybreak-access-program

Conversation

@RamenFast

Copy link
Copy Markdown

Closes #1506

Change

  • parse_openai_model_catalog reads available_access_programs.cyber per model. The disk catalog cache stores it, with #[serde(default)] for old files.
  • New provider.openai_cyber_access_program (env JCODE_OPENAI_CYBER_ACCESS_PROGRAM, off/none clears it). It is unset by default, so default requests are unchanged.
  • When set, ChatGPT-mode Responses requests add access_programs: {"cyber": <program>} only if the model's catalog entry lists that program. Persistent WebSocket continuations copy the field, like service_tier.
  • Astra, API-key mode, and models without catalog data never get the field, so the Astra 403 can't be triggered.

Validation

  • Unit tests cover catalog parsing (listed, missing, empty), selection (supported, case and space variants, unsupported Astra, no catalog data, empty), and that the base request carries no access_programs.
  • jcode-provider-openai-runtime lib: 143 passed. Clippy adds no new warnings.
  • Live OAuth check of the wire contract is in OpenAI OAuth: support the Daybreak cyber access program on Sol models #1506. With daybreak_blue, gpt-6-sol and gpt-5.6-sol return 200. Astra returns 403, which this PR avoids by gating on the catalog.

@greptile-apps

greptile-apps Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 3/5

[Medium impact] Adds cyber access program selection to OpenAI requests.

Not ready to merge: account selection can silently remove the configured access program, and disabling the setting does not affect an existing provider.

Findings

  1. P1 Selected account loses Daybreak ▶
  2. P1 Program setting stays stale ▶
Fix with agent prompt
### Issue 1
crates/jcode-provider-openai-runtime/src/lib.rs:986-987
`reload_cached_reasoning_efforts` loads cyber programs for the globally active account, not the provider's selected account. Selecting another account through `set_oauth_account` therefore loads the wrong program list. If the active account has no cached programs, requests silently omit `access_programs` even when the selected account's catalog lists `daybreak_blue`.

Use `cached_openai_cyber_access_programs_for_scope(&self.catalog_scope())`, as the reasoning-effort lookup already does.

```suggestion
        let programs =
            jcode_base::provider::cached_openai_cyber_access_programs_for_scope(&self.catalog_scope())
                .unwrap_or_default();
```

### Issue 2
crates/jcode-provider-openai-runtime/src/lib.rs:862-867
When a user changes `openai_cyber_access_program` while the provider is running, config reloads but this value remains fixed at construction. Turning the setting `off` leaves subsequent OAuth request payloads sending the old program, and choosing a different program has no effect until the provider is rebuilt. Refresh the selection on reload or read it when building each request; this needs to be resolved before merging.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Adds an optional cyber access program to OpenAI OAuth requests:

  • OpenAI OAuth requests can ask for supported cyber programs.
  • The OpenAI model catalog tracks each model’s cyber programs.

Account-specific reloads still read programs from the globally active account instead of the selected account. The previously reported configuration-reload issue also remains: an existing provider keeps its original program setting, so turning the setting off does not stop it from sending that program. Both issues need to be fixed before merging.

T-Rex validation blocked

Evidence upload is unavailable because this session has no artifact-upload facility or authorized upload destination. The account-selection regression test executed, but its source, commands, and output could not be uploaded.

Reviews (21) · Last reviewed commit: "fix(catalog): refresh snapshots written ..." · Reviewed by Greptile

@RamenFast

Copy link
Copy Markdown
Author

Added a follow-up commit. A catalog cache written by an older build lacks the new field, and a recent one still counts as fresh, so the setting silently did nothing until the TTL expired. The persisted scope now carries a schema_version, and older snapshots hydrate as stale (keeping their real observed_at) so a live refresh runs right away. There's a unit test in model_catalog_service.

Note for reviewers: tests::persistent_failed_missing_tool_output_recovers_with_full_replay fails on clean master when run with an empty JCODE_HOME/XDG_CONFIG_HOME. It only passes when the real user catalog cache happens to be fresh, because otherwise the request path starts a background catalog refresh against the mock server. It's not caused by this PR, but it's easy to hit once old snapshots are treated as stale.

Comment on lines +871 to +876
let cyber_access_program = jcode_base::config::config()
.provider
.openai_cyber_access_program
.as_deref()
.map(|program| program.trim().to_ascii_lowercase())
.filter(|program| !program.is_empty() && program != "off" && program != "none");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Program setting stays stale

When a user changes openai_cyber_access_program while the provider is running, config reloads but this value remains fixed at construction. Turning the setting off leaves subsequent OAuth request payloads sending the old program, and choosing a different program has no effect until the provider is rebuilt. Refresh the selection on reload or read it when building each request; this needs to be resolved before merging.

Artifacts

Rust test source for config reload and OpenAI payload construction

  • The authored test constructs an existing provider, reloads config, and compares its payload with a fresh provider’s payload without contacting OpenAI.

Command script for the credential-free Rust test

  • The executed script copies the runtime crate to a temporary location, appends the test, runs Cargo, and removes the temporary copy.

Initial payload before config reload

  • The `before` command passed and captured the existing provider sending `daybreak_blue` under the initial config.

Payloads after off and standard config reloads

  • The `after` command passed and captured the existing provider retaining `daybreak_blue` while fresh providers reflected each reloaded selection.

View artifacts

T-Rex Ran code and verified through T-Rex

Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/jcode-provider-openai-runtime/src/lib.rs
Line: 871-876

Comment:
**Program setting stays stale**

When a user changes `openai_cyber_access_program` while the provider is running, config reloads but this value remains fixed at construction. Turning the setting `off` leaves subsequent OAuth request payloads sending the old program, and choosing a different program has no effect until the provider is rebuilt. Refresh the selection on reload or read it when building each request; this needs to be resolved before merging.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@greptile-apps

greptile-apps Bot commented Sep 25, 2026 •

Copy link
Copy Markdown

Comments Outside Diff

These findings could not be posted inline.

  • P1 Previous model budget persists crates/jcode-tui/src/tui/app/model_context.rs:657 ▶

    If an older server omits context_window when a remote client switches to an unrecognized model, this fallback retains the previous model’s limit. The panel displays that stale limit and compaction uses it: a 1M-token budget remained after the switch, suppressing a reactive compaction decision that a 128K-token budget would trigger.

  • P1 Legacy catalog crosses endpoints crates/jcode-provider-antigravity/src/lib.rs:114 ▶

    When a user upgrades with an Antigravity catalog written before endpoint stamps existed, this branch accepts it even though requests now target the daily host. Its models enter the picker and its cached default can be selected. If the daily host does not serve one of those models, selecting it sends a request for an unavailable model. Fetch a new catalog before trusting models whose originating host is unknown.

  • P2 Invalidated list reaches disk crates/jcode-tui/src/tui/session_picker/loading.rs:1943 ▶

    If sessions change during a background scan, invalidation keeps the old result out of memory, but the scan still returns it and the grouped loader writes it to disk. The next picker can initially show deleted sessions or omit newly saved ones until it refreshes.

@RamenFast
RamenFast force-pushed the feat/openai-daybreak-access-program branch from 81c647e to cedc3a9 Compare September 26, 2026 11:44
@RamenFast
RamenFast force-pushed the feat/openai-daybreak-access-program branch 7 times, most recently from 7641a7d to 5891b50 Compare October 3, 2026 11:47
@RamenFast
RamenFast force-pushed the feat/openai-daybreak-access-program branch 7 times, most recently from aa40447 to 8c666d2 Compare October 9, 2026 11:47
Comment thread crates/jcode-provider-openai-runtime/src/lib.rs
@RamenFast
RamenFast force-pushed the feat/openai-daybreak-access-program branch 4 times, most recently from 580a400 to 779f101 Compare October 15, 2026 11:41
…odels

ChatGPT/Codex accounts approved for OpenAI's Daybreak program select it
per request with `access_programs: {"cyber": "daybreak_blue"}`, as the
Codex CLI does. The model catalog lists the programs each model accepts
in `available_access_programs.cyber` (gpt-6-sol, gpt-6-luna and the
gpt-5.6 family list daybreak_blue, gpt-6-astra does not, and
gpt-daybreak-blue-latest lists only daybreak_blue).

Parse and cache those per-model programs, and add
`provider.openai_cyber_access_program` (env
JCODE_OPENAI_CYBER_ACCESS_PROGRAM). When set, ChatGPT-mode requests and
persistent WebSocket continuations carry the program only for models
whose catalog entry lists it. Astra and models without catalog data are
unchanged, avoiding the backend's 403 for Astra. Default is unset.
…were persisted

A catalog cache written by an older build has no cyber_access_programs, and
a recent one counts as fresh, so the configured program would not be sent
until the TTL expired. Version the persisted scope and hydrate older
snapshots as stale (keeping their real observed_at) so a live refresh runs at
once.
@RamenFast
RamenFast force-pushed the feat/openai-daybreak-access-program branch from 779f101 to d3ab903 Compare October 16, 2026 11:44
Comment on lines +986 to +987
let programs =
jcode_base::provider::cached_openai_cyber_access_programs().unwrap_or_default();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Selected account loses Daybreak

reload_cached_reasoning_efforts loads cyber programs for the globally active account, not the provider's selected account. Selecting another account through set_oauth_account therefore loads the wrong program list. If the active account has no cached programs, requests silently omit access_programs even when the selected account's catalog lists daybreak_blue.

Use cached_openai_cyber_access_programs_for_scope(&self.catalog_scope()), as the reasoning-effort lookup already does.

Suggested change
let programs =
jcode_base::provider::cached_openai_cyber_access_programs().unwrap_or_default();
let programs =
jcode_base::provider::cached_openai_cyber_access_programs_for_scope(&self.catalog_scope())
.unwrap_or_default();
Prompt To Fix With AI
This is a comment left during a code review.
Path: crates/jcode-provider-openai-runtime/src/lib.rs
Line: 986-987

Comment:
**Selected account loses Daybreak**

`reload_cached_reasoning_efforts` loads cyber programs for the globally active account, not the provider's selected account. Selecting another account through `set_oauth_account` therefore loads the wrong program list. If the active account has no cached programs, requests silently omit `access_programs` even when the selected account's catalog lists `daybreak_blue`.

Use `cached_openai_cyber_access_programs_for_scope(&self.catalog_scope())`, as the reasoning-effort lookup already does.

```suggestion
        let programs =
            jcode_base::provider::cached_openai_cyber_access_programs_for_scope(&self.catalog_scope())
                .unwrap_or_default();
```

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

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.

OpenAI OAuth: support the Daybreak cyber access program on Sol models

1 participant