Commit Graph

7 Commits

  • Move memory state to a dedicated SQLite DB (#24591)
    ## Summary
    
    Generated memory rows and their stage-one/stage-two job state currently
    live in `state_5.sqlite` alongside thread metadata. That makes memory
    cleanup and regeneration share the main state schema even though those
    rows are memory-pipeline data and can be rebuilt independently from the
    durable thread records.
    
    This PR moves the memory-owned tables into a dedicated
    `memories_1.sqlite` runtime database while keeping thread metadata in
    `state_5.sqlite`.
    
    ## Changes
    
    - Adds a separate memories DB runtime, migrator, path helpers, telemetry
    kind, and Bazel compile data for `state/memory_migrations`.
    - Introduces `MemoryStore` behind `StateRuntime::memories()` and moves
    memory table/job operations onto that store.
    - Drops the old memory tables from the state DB and recreates their
    schema in `state/memory_migrations/0001_memories.sql`.
    - Updates memory startup, citation usage tracking, rollout pollution
    handling, `debug clear-memories`, and app-server `memory/reset` to
    operate through the memories DB.
    - Preserves cross-DB behavior by hydrating thread metadata from the
    state DB when selecting visible memory outputs and checking stage-one
    staleness.
    
    ## Verification
    
    - Added/updated `codex-state` tests for deleted-thread memory visibility
    and already-polluted phase-two enqueue behavior.
    - Updated `debug clear-memories`, app-server `memory/reset`, and
    memories startup tests to seed and assert memory rows through
    `memories_1.sqlite`.
  • Add doctor thread inventory audit (#24305)
    ## Why
    
    Users have been reporting missing sessions in the app. The app server
    thread listing is backed by the SQLite state DB, but the durable source
    of truth for a thread still exists on disk as rollout JSONL. When the
    state DB is incomplete, doctor should be able to show the mismatch
    directly instead of leaving users with a generic state health result.
    
    ## What changed
    
    This adds a `threads` doctor check that compares active and archived
    rollout files under `CODEX_HOME` with rows in the SQLite `threads`
    table. The check reports missing rollout rows, stale DB rows, archive
    flag mismatches, duplicate rollout thread IDs, duplicate DB paths,
    source/provider summaries, and bounded samples of affected rollout
    paths.
    
    It also adds a read-only state audit helper in `codex-rs/state` so
    doctor can inspect thread rows without creating, migrating, or repairing
    the database.
    
    ## Sample output
    
    ```text
      ⚠ threads      rollout files are missing from the state DB
          default model provider   openai
          rollout DB active files  3910
          rollout DB archived files 2037
          rollout DB scan errors   0
          rollout DB malformed file names 0
          rollout DB scan cap reached false
          rollout DB rows          5499
          rollout DB active rows   3462
          rollout DB archived rows 2037
          rollout DB missing active rows 448
          rollout DB missing archived rows 0
          rollout DB stale rows    0
          rollout DB archive mismatches 0
          rollout DB duplicate rollout thread ids 0
          rollout DB duplicate DB paths 0
          rollout DB model providers openai=5359, lmstudio=35, mock_provider=33, lite_llm=26, proxy=26, ollama=15, lms=4, local-usage-limit=1
          rollout DB sources       vscode=2587, cli=1494, subagent:thread_spawn=577, subagent:other=502, exec=281, subagent:memory_consolidation=46, subagent:review=9, unknown=3
          rollout DB missing active sample ~/.codex/sessions/2026/0…857e-a923c712e066.jsonl
          rollout DB missing active sample ~/.codex/sessions/2025/0…877a-766dff25c68d.jsonl
          rollout DB missing active sample ~/.codex/sessions/2025/0…a8b1-7bbadc836f6e.jsonl
          rollout DB missing active sample ~/.codex/sessions/2025/0…a218-e6197f3f62f8.jsonl
          rollout DB missing active sample ~/.codex/sessions/2025/0…9011-7e30784f9932.jsonl
    ```
  • Report app-server version in codex doctor (#24311)
    ## Why
    
    We are seeing cases where users have an old background app-server still
    running. `codex doctor` already reports background server state, but
    without the running app-server version it is harder to diagnose
    behaviors that depend on the daemon build.
    
    ## What changed
    
    - Reused the app-server daemon's passive initialize probe through a
    narrow `probe_app_server_version` helper.
    - Updated the `codex doctor` Background Server section to report
    `app-server version: <version>` when the socket is reachable.
    - Preserved the not-running OK behavior and report `app-server version:
    unavailable (<short error>)` when a socket exists but the passive probe
    fails.
  • feat(doctor): add environment diagnostics (#24261)
    ## Why
    
    Issue #23031 was hard to diagnose from existing `codex doctor` output
    because support could not see the OS language, resolved Git install, Git
    repo metadata, Windows console mode/code page, or terminal-title inputs
    that affect the TUI startup path. This adds those read-only signals to
    `codex doctor` so Windows, Linux, and macOS reports carry the context
    needed to investigate similar terminal rendering regressions.
    
    Refs #23031
    
    ## What Changed
    
    - Add a `system.environment` check for OS type/version, OS language, and
    locale env vars.
    - Add a `git.environment` check for the selected Git executable, PATH
    Git candidates, version, exec path/build options, repository root,
    branch, `.git` entry, and `core.fsmonitor`.
    - Add Windows console code page and VT-processing mode details to
    terminal diagnostics.
    - Add a `terminal.title` check for configured/default title items and
    resolved project-title source/value.
    - Surface startup warning counts in config diagnostics and teach human
    output to render the new categories.
    
    ## How to Test
    
    1. On Windows, check out this branch and run `cargo run -p codex-cli --
    doctor --summary`.
    2. Confirm the Environment section includes `system`, `git`, `terminal`,
    and `title` rows.
    3. Run `cargo run -p codex-cli -- doctor --json`.
    4. Confirm the JSON contains `system.environment`, `git.environment`,
    and `terminal.title`; on Windows, confirm `terminal.env` details include
    console code pages and `VT processing` for stdout/stderr.
    5. From a non-git directory, run the same `doctor --json` command and
    confirm the Git check reports `repo detected: false` rather than
    warning.
    
    Targeted tests:
    
    - `cargo test -p codex-cli doctor`
    - `cargo test -p codex-cli`
  • runtime: detect Codex package layout (#23596)
    ## Why
    
    The package-builder stack now creates a canonical Codex package
    directory where the entrypoint lives under `bin/`, bundled helper
    resources live under `codex-resources/`, and bundled PATH-style tools
    live under `codex-path/`. That layout is not specific to the standalone
    installer: npm, brew, install scripts, and manually unpacked artifacts
    should all be able to use the same package shape.
    
    The Rust runtime still only knew about the legacy standalone release
    layout, where resources sit next to the executable. A packaged binary
    therefore would not identify its package root or prefer the bundled `rg`
    from `codex-path/`.
    
    ## What changed
    
    - Adds `CodexPackageLayout` to `codex-install-context` and detects it
    from an executable path shaped like `<package>/bin/<entrypoint>` when
    `<package>/codex-package.json` is present.
    - Splits `InstallContext` into an install `method` plus an optional
    package layout so the layout is shared across npm, bun, brew,
    standalone, and other launch contexts.
    - Stores package-layout paths as `AbsolutePathBuf` values.
    - Keeps `codex-resources/` and `codex-path/` optional so Codex can still
    run with degraded behavior if sidecar directories are missing.
    - Updates `InstallContext::rg_command()` to prefer bundled
    `codex-path/rg` or `rg.exe`, then fall back to the legacy standalone
    resources location, then system `rg`.
    - Updates `codex doctor` reporting so package installs show package,
    bin, resources, and path directories, and so bundled search detection
    recognizes `codex-path/` for any install method.
    
    ## Test plan
    
    - `cargo test -p codex-install-context`
    - `cargo test -p codex-cli`
    - `cargo test -p codex-tui
    update_action::tests::maps_install_context_to_update_action`
    - `just bazel-lock-check`
  • feat: dedicated goal DB (#23300)
    ## Why
    
    Thread goals are moving toward extension-owned runtime behavior, but
    their persisted state was still stored in the shared state database.
    This makes the goal store harder to isolate and keeps future storage
    splits tied to ad hoc runtime plumbing.
    
    This PR gives goals their own SQLite database while keeping the existing
    `StateRuntime` entry point. The goal is to make this the pattern for
    adding more dedicated runtime databases later.
    
    This also reduce load on existing DB and reduce contention
    
    ## Limitation
    Thread preview from goal is not supported anymore. I'm looking into this
    [EDIT]: solved
    
    ## What changed
    
    - Added a dedicated `goals_1.sqlite` database with its own
    `goals_migrations` directory.
    - Moved `thread_goals` creation into the goals DB migration set.
    - Dropped the old `thread_goals` table from the main state DB with a
    normal state migration. There is intentionally no backfill for existing
    goal rows.
    - Changed `GoalStore` to be backed only by the goals DB pool.
    - Removed the old goal-write side effect that filled empty
    `threads.preview` values from the goal objective.
    - Added shared runtime DB path metadata so startup, telemetry, `codex
    doctor`, and repair handling can include future DBs without bespoke path
    lists.
    - Updated Bazel compile data so the new goals migration directory is
    available to `sqlx::migrate!`.
    
    ## Verification
    
    - `cargo check --tests -p codex-state -p codex-cli -p codex-core -p
    codex-app-server`
    - `just fix -p codex-state`
    - `just fix -p codex-cli`
    - `just fix -p codex-app-server`
  • feat(cli): add codex doctor diagnostics (#22336)
    ## Why
    
    Users and support need a single command that captures the local Codex
    runtime, configuration, auth, terminal, network, and state shape without
    asking the user to know which diagnostic depth to choose first. `codex
    doctor` now runs the useful checks by default and makes the detailed
    human output the default because the command is usually run when someone
    already needs context.
    
    The command also targets concrete support failure modes we have seen
    while iterating on the design:
    
    - update-target mismatches like #21956, where the installed package
    manager target can differ from the running executable
    - terminal and multiplexer issues that depend on `TERM`, tmux/zellij
    state, color handling, and TTY metadata
    - provider-specific HTTP/WebSocket connectivity, including ChatGPT
    WebSocket handshakes and API-key/provider endpoint reachability
    - local state/log SQLite integrity problems and large rollout
    directories
    - feedback reports that need an attached, redacted diagnostic snapshot
    without asking the user to run a second command
    
    ## What Changed
    
    - Adds `codex doctor` as a grouped CLI diagnostic report with default
    detailed output and `--summary` for the compact view.
    - Adds stable report sections for Environment, Configuration, Updates,
    Connectivity, and Background Server, plus a top Notes block that
    promotes anomalies such as available updates, large rollout directories,
    optional MCP issues, and mixed auth signals.
    - Adds runtime provenance, install consistency, bundled/system search
    readiness, terminal/multiplexer metadata, `config.toml` parse status,
    auth mode details, sandbox details, feature flag summaries, update
    cache/latest-version state, app-server daemon state, SQLite integrity
    checks, rollout statistics, and provider-aware network diagnostics.
    - Adds ChatGPT WebSocket diagnostics that report the negotiated HTTP
    upgrade as `HTTP 101 Switching Protocols` and include timeout, DNS,
    auth, and provider context in detailed output.
    - Makes reachability provider-aware: API-key OpenAI setups check the API
    endpoint, ChatGPT auth checks the ChatGPT path, and custom/AWS/local
    providers check configured HTTP endpoints when available.
    - Adds structured, redacted JSON output where `checks` is keyed by check
    id and `details` is a key/value object for support tooling.
    - Integrates doctor with feedback uploads by attaching a best-effort
    `codex-doctor-report.json` report and adding derived Sentry tags for
    overall status and failing/warning checks.
    - Updates the TUI feedback consent copy so users can see that the doctor
    report is included when logs/diagnostics are uploaded.
    - Updates the CLI bug issue template to ask reporters for `codex doctor
    --json` and render pasted reports as JSON.
    
    ## Example Output
    
    The examples below are sanitized from local smoke runs with `--no-color`
    so the structure is reviewable in plain text.
    
    ### `codex doctor`
    
    ```text
    Codex Doctor v0.0.0 · macos-aarch64
    
    Notes
       ↑ updates      0.130.0 available (current 0.0.0, dismissed 0.128.0)
       ⚠ rollouts     1,526 active files · 2.53 GB on disk
       ⚠ mcp          MCP configuration has optional issues
       ⚠ auth         mixed auth signals: ChatGPT login plus API key env var; HTTP reachability uses API-key mode
    ─────────────────────────────────────────────────────────────
    
    Environment
      ✓ runtime      local debug build
          version                  0.0.0
          install method           other
          commit                   unknown
          executable               ~/code/codex.fcoury-doct…x-rs/target/debug/codex
      ✓ install      consistent
          context                  other
          managed by               npm: no · bun: no · package root —
          PATH entries (2)         ~/.local/share/mise/installs/node/24/bin/codex
                                   ~/.local/share/mise/shims/codex
      ✓ search       ripgrep 15.1.0 (system, `rg`)
      ✓ terminal     Ghostty 1.3.2-main-+b0f827665 · tmux 3.6a · TERM=xterm-256color
          terminal                 Ghostty
          TERM_PROGRAM             ghostty
          terminal version         1.3.2-main-+b0f827665
          TERM                     xterm-256color
          multiplexer              tmux 3.6a
          tmux extended-keys       on
          tmux allow-passthrough   on
          tmux set-clipboard       on
      ✓ state        databases healthy
          CODEX_HOME               ~/.codex (dir)
          state DB                 ~/.codex/state_5.sqlite (file) · integrity ok
          log DB                   ~/.codex/logs_2.sqlite (file) · integrity ok
          active rollouts          1,526 files · 2.53 GB (avg 1.70 MB)
          archived rollouts        8 files · 3.84 MB (avg 491.11 KB)
    
    Configuration
      ✓ config       loaded
          model                    gpt-5.5 · openai
          cwd                      ~/code/codex.fcoury-doctor/codex-rs
          config.toml              ~/.codex/config.toml
          config.toml parse        ok
          MCP servers              1
          feature flags            36 enabled · 7 overridden (full list with --all)
          overrides                code_mode, code_mode_only, memories, chronicle, goals, remote_control, prevent_idle_sleep
      ✓ auth         auth is configured
          auth storage mode        File
          auth file                ~/.codex/auth.json
          auth env vars present    OPENAI_API_KEY
          stored auth mode         chatgpt
          stored API key           false
          stored ChatGPT tokens    true
          stored agent identity    false
      ⚠ mcp          MCP configuration has optional issues — Set the missing MCP env vars or disable the affected server.
          configured servers       1
          disabled servers         0
          streamable_http servers  1
          optional reachability    openaiDeveloperDocs: https://developers.openai.com/mcp (HEAD connect failed; GET connect failed)
      ✓ sandbox      restricted fs + restricted network · approval OnRequest
          approval policy          OnRequest
          filesystem sandbox       restricted
          network sandbox          restricted
    
    Connectivity
      ✓ network      network-related environment looks readable
      ✓ websocket    connected (HTTP 101 Switching Protocols) · 15s timeout
          model provider           openai
          provider name            OpenAI
          wire API                 responses
          supports websockets      true
          connect timeout          15000 ms
          auth mode                chatgpt
          endpoint                 wss://chatgpt.com/backend-api/<redacted>
          DNS                      2 IPv4, 2 IPv6, first IPv6
          handshake result         HTTP 101 Switching Protocols
      ✗ reachability one or more required provider endpoints are unreachable over HTTP — Check proxy, VPN, firewall, DNS, and custom CA configuration.
          reachability mode        API key auth
          openai API               https://api.openai.com/v1 connect failed (required)
    
    Background Server
      ○ app-server   not running (ephemeral mode)
    
    ─────────────────────────────────────────────────────────────
    11 ok · 1 idle · 4 notes · 1 warn · 1 fail failed
    
    --summary compact output           --all expand truncated lists
    --json redacted report
    ```
    
    ### `codex doctor --summary`
    
    ```text
    Codex Doctor v0.0.0 · macos-aarch64
    
    Notes
       ↑ updates      0.130.0 available (current 0.0.0, dismissed 0.128.0)
       ⚠ rollouts     1,526 active files · 2.53 GB on disk
       ⚠ mcp          MCP configuration has optional issues
       ⚠ auth         mixed auth signals: ChatGPT login plus API key env var; HTTP reachability uses API-key mode
    ─────────────────────────────────────────────────────────────
    
    Environment
      ✓ runtime      local debug build
      ✓ install      consistent
      ✓ search       ripgrep 15.1.0 (system, `rg`)
      ✓ terminal     Ghostty 1.3.2-main-+b0f827665 · tmux 3.6a · TERM=xterm-256color
      ✓ state        databases healthy
    
    Configuration
      ✓ config       loaded
      ✓ auth         auth is configured
      ⚠ mcp          MCP configuration has optional issues — Set the missing MCP env vars or disable the affected server.
      ✓ sandbox      restricted fs + restricted network · approval OnRequest
    
    Updates
      ✓ updates      update configuration is locally consistent
    
    Connectivity
      ✓ network      network-related environment looks readable
      ✓ websocket    connected (HTTP 101 Switching Protocols) · 15s timeout
      ✗ reachability one or more required provider endpoints are unreachable over HTTP — Check proxy, VPN, firewall, DNS, and custom CA configuration.
    
    Background Server
      ○ app-server   not running (ephemeral mode)
    
    ─────────────────────────────────────────────────────────────
    11 ok · 1 idle · 4 notes · 1 warn · 1 fail failed
    
    Run codex doctor without --summary for detailed diagnostics.
    --all expand truncated lists       --json redacted report
    ```
    
    ### `codex doctor --json` shape
    
    ```json
    {
      "schema_version": 1,
      "overall_status": "fail",
      "checks": {
        "runtime.provenance": {
          "id": "runtime.provenance",
          "category": "Environment",
          "status": "ok",
          "summary": "local debug build",
          "details": {
            "version": "0.0.0",
            "install method": "other",
            "commit": "unknown"
          }
        },
        "sandbox.helpers": {
          "id": "sandbox.helpers",
          "category": "Configuration",
          "status": "ok",
          "summary": "restricted fs + restricted network · approval OnRequest",
          "details": {
            "approval policy": "OnRequest",
            "filesystem sandbox": "restricted",
            "network sandbox": "restricted"
          }
        }
      }
    }
    ```
    
    ### `/feedback` new sentry attachment
    
    <img width="938" height="798" alt="CleanShot 2026-05-13 at 15 36 14"
    src="https://github.com/user-attachments/assets/715e62e0-d7b4-4fea-a35a-fd5d5d33c4c0"
    />
    
    ### New section in CLI issue template
    
    <img width="1164" height="435" alt="CleanShot 2026-05-13 at 15 47 24"
    src="https://github.com/user-attachments/assets/9081dc25-a28c-4afa-8ba1-e299c2b4031d"
    />
    
    ## How to Test
    
    1. Run `cargo run --bin codex -- doctor --no-color`.
    2. Confirm the detailed report is the default and includes promoted
    Notes, grouped sections, terminal details, state DB integrity, rollout
    stats, provider reachability, WebSocket diagnostics, and app-server
    status.
    3. Run `cargo run --bin codex -- doctor --summary --no-color`.
    4. Confirm the compact view keeps the same sections and summary counts
    but omits detailed key/value rows.
    5. Run `cargo run --bin codex -- doctor --json`.
    6. Confirm the output is redacted JSON, `checks` is an object keyed by
    check id, and each check's `details` is a key/value object.
    7. Preview the CLI bug issue template and confirm the `Codex doctor
    report` field appears after the terminal field, asks for `codex doctor
    --json`, and renders pasted output as JSON.
    8. Start a feedback flow that includes logs.
    9. Confirm the upload consent copy lists `codex-doctor-report.json`
    alongside the log attachments.
    
    Targeted tests:
    
    - `cargo test -p codex-cli doctor`
    - `cargo test -p codex-app-server
    doctor_report_tags_summarize_status_counts`
    - `cargo test -p codex-feedback`
    - `cargo test -p codex-tui feedback_view`
    - `just argument-comment-lint`
    - `git diff --check`