Commit Graph
5234 Commits
Author SHA1 Message Date
rhan-oai 6e17b89587 merge commit for archive created by Sapling 2026-04-06 12:28:06 -07:00
rhan-oai f3bafdcad9 [codex-analytics] add protocol-native turn timestamps 2026-04-06 12:26:33 -07:00
Owen Lin 9bb813353e fix(sqlite): don't hard fail migrator if DB is newer (#16924)
## Description

This PR makes the SQLite state runtime tolerate databases that have
already been migrated by a newer Codex binary.

Today, if an older CLI sees migration versions in `_sqlx_migrations`
that it doesn't know about, startup fails. This change relaxes that
check for the runtime migrators we use in `codex-state` so older
binaries can keep opening the DB in that case.

## Why

We can end up with mixed-version CLIs running against the same local
state DB. In that setup, treating "the database is ahead of me" as a
hard error is unnecessarily strict and breaks the older client even when
the migration history is otherwise fine.

## Follow-up

We still clean up versioned `state_*.sqlite` and `logs_*.sqlite` files
during init, so older binaries can treat newer DB files as legacy. That
should probably be tightened separately if we want mixed-version local
usage to be fully safe.
2026-04-06 12:16:31 -07:00
Owen Lin bd30bad96f fix(guardian): fix ordering of guardian events (#16462)
Guardian events were emitted a bit out of order for CommandExecution
items. This would make it hard for the frontend to render a guardian
auto-review, which has this payload:
```
pub struct ItemGuardianApprovalReviewStartedNotification {
    pub thread_id: String,
    pub turn_id: String,
    pub target_item_id: String,
    pub review: GuardianApprovalReview,
    // FYI this is no longer a json blob
    pub action: Option<JsonValue>,
}
```

There is a `target_item_id` the auto-approval review is referring to,
but the actual item had not been emitted yet.

Before this PR:
- `item/autoApprovalReview/started`
- `item/autoApprovalReview/completed`, and if approved...
- `item/started`
- `item/completed`

After this PR:
- `item/started`
- `item/autoApprovalReview/started`
- `item/autoApprovalReview/completed`
- `item/completed`

This lines up much better with existing patterns (i.e. human review in
`Default mode`, where app-server would send a server request to prompt
for user approval after `item/started`), and makes it easier for clients
to render what guardian is actually reviewing.

We do this following a similar pattern as `FileChange` (aka apply patch)
items, where we create a FileChange item and emit `item/started` if we
see the apply patch approval request, before the actual apply patch call
runs.
2026-04-06 19:14:27 +00:00
rhan-oai cc2c57d57c merge commit for archive created by Sapling 2026-04-06 12:07:51 -07:00
Ruslan Nigmatullin 4eabc3dcb1 bazel: Enable --experimental_remote_downloader (#16928)
This should allow bazel to properly cache external deps.
2026-04-06 12:07:19 -07:00
Ruslan Nigmatullin 0225479f0d bazel: Always save bazel repository cache (#16926)
This should improve the cache hit ratio for external deps and such
2026-04-06 12:06:58 -07:00
Owen Lin 2b4cc221df fix(bazel): fix simdutf (#16925)
## Summary

This changes our V8 Bazel wiring so `simdutf` no longer comes from a
live `git_repository` fetch against Chromium's Googlesource host.

Instead, we pull `simdutf` from a pinned GitHub release archive and keep
the V8 `simdutf` target wired through the external repo. The
archive-backed target is set up to match the way V8 consumes `simdutf`
today, including the amalgamated `src/simdutf.cpp` entrypoint and the
internal files it includes.

## Why

CI was intermittently failing while Bazel tried to fetch:

`https://chromium.googlesource.com/chromium/src/third_party/simdutf/`

That fetch was returning HTTP 429s, which then fan out into failures in
the Bazel jobs, the SDK job, and the argument-comment lint jobs since
they all go through the same dependency resolution path.

## What changed

- replaced the `simdutf` `git_repository` in the patched V8 module deps
with a pinned `http_archive`
- pointed that archive at `simdutf` `v7.7.0` on GitHub
- added the archive hash so the fetch is deterministic
- kept the V8 BUILD patch pointing `:simdutf` at the external
`@simdutf//:simdutf` target
- configured the Bazel `cc_library` for the archive to use the
amalgamated `src/simdutf.cpp` source plus the internal headers / textual
includes it depends on

## Validation

- ran `bazel build @v8//:simdutf`
- confirmed the target builds successfully with the new archive-backed
wiring
2026-04-06 11:56:54 -07:00
rhan-oai 40945d497f [codex-analytics] add protocol-native turn timestamps 2026-04-06 11:55:09 -07:00
rhan-oai 14476dd0e5 merge commit for archive created by Sapling 2026-04-06 11:23:18 -07:00
rhan-oai 00b893b76c [codex-analytics] denormalize thread metadata onto turn events 2026-04-06 11:21:17 -07:00
rhan-oai b68ec54eb3 [codex-analytics] add steering metadata 2026-04-06 11:21:17 -07:00
rhan-oai a47c5b2ab8 [codex-analytics] add queued submission metadata 2026-04-06 11:21:17 -07:00
rhan-oai 888236ec85 [codex-analytics] add token usage metadata 2026-04-06 11:21:17 -07:00
rhan-oai 9743b13634 [codex-analytics] feature plumbing and emittance 2026-04-06 11:21:17 -07:00
rhan-oai 12d351fff9 [codex-analytics] add protocol-native turn timestamps 2026-04-06 11:21:17 -07:00
Owen Lin ded559680d feat(requirements): support allowed_approval_reviewers (#16701)
## Description

Add requirements.toml support for `allowed_approvals_reviewers =
["user", "guardian_subagent"]`, so admins can now restrict the use of
guardian mode.

Note: If a user sets a reviewer that isn’t allowed by requirements.toml,
config loading falls back to the first allowed reviewer and emits a
startup warning.

The table below describes the possible admin controls.
| Admin intent | `requirements.toml` | User `config.toml` | End result |
|---|---|---|---|
| Leave Guardian optional | omit `allowed_approvals_reviewers` or set
`["user", "guardian_subagent"]` | user chooses `approvals_reviewer =
"user"` or `"guardian_subagent"` | Guardian off for `user`, on for
`guardian_subagent` + `approval_policy = "on-request"` |
| Force Guardian off | `allowed_approvals_reviewers = ["user"]` | any
user value | Effective reviewer is `user`; Guardian off |
| Force Guardian on | `allowed_approvals_reviewers =
["guardian_subagent"]` and usually `allowed_approval_policies =
["on-request"]` | any user reviewer value; user should also have
`approval_policy = "on-request"` unless policy is forced | Effective
reviewer is `guardian_subagent`; Guardian on when effective approval
policy is `on-request` |
| Allow both, but default to manual if user does nothing |
`allowed_approvals_reviewers = ["user", "guardian_subagent"]` | omit
`approvals_reviewer` | Effective reviewer is `user`; Guardian off |
| Allow both, and user explicitly opts into Guardian |
`allowed_approvals_reviewers = ["user", "guardian_subagent"]` |
`approvals_reviewer = "guardian_subagent"` and `approval_policy =
"on-request"` | Guardian on |
| Invalid admin config | `allowed_approvals_reviewers = []` | anything |
Config load error |
2026-04-06 11:11:44 -07:00
rhan-oai e25689bbed merge commit for archive created by Sapling 2026-04-06 11:11:39 -07:00
rhan-oai 1865f543ab [codex-analytics] denormalize thread metadata onto turn events 2026-04-06 11:08:39 -07:00
rhan-oai d256ae0602 [codex-analytics] add steering metadata 2026-04-06 11:08:39 -07:00
rhan-oai c1b77ebb69 [codex-analytics] add queued submission metadata 2026-04-06 11:08:39 -07:00
rhan-oai 0d9875fe53 [codex-analytics] add token usage metadata 2026-04-06 11:08:39 -07:00
rhan-oai 389ad76a24 [codex-analytics] feature plumbing and emittance 2026-04-06 11:08:39 -07:00
rhan-oai bbb42eb94f [codex-analytics] add protocol-native turn timestamps 2026-04-06 11:08:39 -07:00
rhan-oai eae5b6bb06 merge commit for archive created by Sapling 2026-04-06 10:23:02 -07:00
rhan-oai 065c840299 [codex-analytics] denormalize thread metadata onto turn events 2026-04-06 10:20:07 -07:00
rhan-oai aa6b3938e4 [codex-analytics] add steering metadata 2026-04-06 10:20:07 -07:00
rhan-oai 17575bdcb5 [codex-analytics] add queued submission metadata 2026-04-06 10:20:07 -07:00
rhan-oai 204abb4d5c [codex-analytics] add token usage metadata 2026-04-06 10:20:07 -07:00
rhan-oai ff81c834f9 [codex-analytics] feature plumbing and emittance 2026-04-06 10:20:07 -07:00
rhan-oai 577abcf681 [codex-analytics] add protocol-native turn timestamps 2026-04-06 10:20:07 -07:00
joeytrasatti-openai 4ce97cef02 [codex-backend] Make thread metadata updates tolerate pending backfill (#16877)
### Summary
Fix `thread/metadata/update` so it can still patch stored thread
metadata when the list/backfill-gated `get_state_db(...)` path is
unavailable.

What was happening:
- The app logs showed `thread/metadata/update` failing with `sqlite
state db unavailable for thread ...`.
- This was not isolated to one bad thread. Once the failure started for
a user, branch metadata updates failed 100% of the time for that user.
- Reports were staggered across users, which points at local app-server
/ local SQLite state rather than one global server-side failure.
- Turns could still start immediately after the metadata update failed,
which suggests the thread itself was valid and the failure was in the
metadata endpoint DB-handle path.

The fix:
- Keep using the loaded thread state DB and the normal
`get_state_db(...)` fallback first.
- If that still returns `None`, open `StateRuntime::init(...)` directly
for this targeted metadata update path.
- Log the direct state runtime init error if that final fallback also
fails, so future reports have the real DB-open cause instead of only the
generic unavailable error.
- Add a regression test where the DB exists but backfill is not
complete, and verify `thread/metadata/update` can still repair the
stored rollout thread and patch `gitInfo`.

Relevant context / suspect PRs:
- #16434 changed state DB startup to run auto-vacuum / incremental
vacuum. This is the most suspicious timing match for per-user, staggered
local SQLite availability failures.
- #16433 dropped the old log table from the state DB, also near the
timing window.
- #13280 introduced this endpoint and made it rely on SQLite for git
metadata without resuming the thread.
- #14859 and #14888 added/consumed persisted model + reasoning effort
metadata. I checked these because of the new thread metadata fields, but
this failure happens before the endpoint reaches thread-row update/load
logic, so they seem less likely as the direct cause.

### Testing
- `cargo fmt -- --config imports_granularity=Item` completed; local
stable rustfmt emitted warnings that `imports_granularity` is unstable
- `cargo test -p codex-app-server thread_metadata_update`
- `git diff --check`
2026-04-06 13:07:19 -04:00
rhan-oai 590e3b4f8b merge commit for archive created by Sapling 2026-04-06 09:47:21 -07:00
rhan-oai 8d1b68fce5 [codex-analytics] denormalize thread metadata onto turn events 2026-04-06 09:47:08 -07:00
Eric Traut 54dbbb839e (tui): Decode percent-escaped bare local file links (#16810)
Addresses #16622

Problem: bare local file links in TUI markdown render percent-encoded
path bytes literally, unlike file:// links.

Solution: decode bare path targets before local-path expansion and add
regression coverage for spaces and Unicode.
2026-04-06 08:52:18 -07:00
Eric Traut f44eb29181 Annotate skill doc reads with skill names (#16813)
Addresses #16303

Problem: Skill doc reads render as plain `Read SKILL.md`, so the TUI
hides which skill was opened.

Solution: Best-effort annotate exact `SKILL.md` reads with the matching
loaded skill name from `skills_all` before rendering exec cells.

Before:
```
• Explored
  └ Read SKILL.md
```

After:
```
• Explored
  └ Read SKILL.md (pr-babysitter skill)
```
2026-04-06 08:51:34 -07:00
Eric Traut 4294031a93 Fix resume picker timestamp labels and stability (#16822)
Problem: The resume picker used awkward "Created at" and "Updated at"
headers, and its relative timestamps changed while navigating because
they were recomputed on each redraw.

Solution: Rename the headers to "Created" and "Updated", and anchor
relative timestamp formatting to the picker load time so the displayed
ages stay stable while browsing.
2026-04-06 08:51:13 -07:00
Eric Traut fb41a79f37 [regression] Fix ephemeral turn backfill in exec (#16795)
Addresses #16781

Problem: `codex exec --ephemeral` backfilled empty `turn/completed`
items with `thread/read(includeTurns=true)`, which app-server rejects
for ephemeral threads.

This is a regression introduced in the recent conversion of "exec" to
use app server rather than call the core directly.

Solution: Skip turn-item backfill for ephemeral exec threads while
preserving the existing recovery path for non-ephemeral sessions.
2026-04-06 08:45:58 -07:00
Eric Traut ab58141e22 Fix TUI fast mode toggle regression (#16833)
Addresses #16832

Problem: After `/fast on`, the TUI omitted an explicit service-tier
clear on later turns, so `/fast off` left app-server sessions stuck on
`priority` until restart.

Solution: Always submit the current service tier with user turns,
including an explicit clear when Fast mode is off, and add a regression
test for the `/fast on` -> `/fast off` flow.
2026-04-06 08:43:35 -07:00
Eric Traut 82b061afb2 Fix CJK word navigation in the TUI composer (#16829)
Addresses #16584

Problem: TUI word-wise cursor movement treated entire CJK runs as a
single word, so Option/Alt+Left and Right skipped too far when editing
East Asian text.

Solution: Use Unicode word-boundary segments within each non-whitespace
run so CJK text advances one segment at a time while preserving
separator and delete-word behavior, and add regression coverage for CJK
and mixed-script navigation.

Testing: Manually tested solution by pasting text that includes CJK
characters into the composer and confirmed that keyboard navigation
worked correctly (after confirming it didn't prior to the change).
2026-04-06 08:37:42 -07:00
Thibault Sottiaux 624c69e840 [codex] add response proxy subagent header test (#16876)
This adds end-to-end coverage for `responses-api-proxy` request dumps
when Codex spawns a subagent and validates that the `x-codex-window-id`
and `x-openai-subagent` are properly set.
2026-04-06 08:18:46 -07:00
Eric Traut e65ee38579 Clarify codex exec approval help (#16888)
Addresses #13614

Problem: `codex exec --help` implied that `--full-auto` also changed
exec approval mode, even though non-interactive exec stays headless and
does not support interactive approval prompts.

Solution: clarify the `--full-auto` help text so it only describes the
sandbox behavior it actually enables for `codex exec`.
2026-04-05 23:31:15 -07:00
Eric Traut d9b899309d Fix misleading codex exec help usage (#16881)
Addresses #15535

Problem: `codex exec --help` advertised a second positional `[COMMAND]`
even though `exec` only accepts a prompt or a subcommand.

Solution: Override the `exec` usage string so the help output shows the
two supported invocation forms instead of the phantom positional.
2026-04-05 22:09:19 -07:00
rhan-oai c4d63a79c5 merge commit for archive created by Sapling 2026-04-05 18:23:39 -07:00
rhan-oai 01aa292c4f [codex-analytics] denormalize thread metadata onto turn events 2026-04-05 17:04:36 -07:00
rhan-oai 9b94ed7395 [codex-analytics] add steering metadata 2026-04-05 16:08:29 -07:00
rhan-oai ad50902d2c [codex-analytics] add queued submission metadata 2026-04-05 16:08:29 -07:00
rhan-oai 5faf7cfe4f [codex-analytics] add token usage metadata 2026-04-05 16:08:28 -07:00
rhan-oai 4570e5d894 [codex-analytics] feature plumbing and emittance 2026-04-05 16:08:28 -07:00
rhan-oai 9098a3fb8c [codex-analytics] add protocol-native turn timestamps 2026-04-05 16:08:28 -07:00