Files
codex-proxy-rs/docs/implementation-status.md
T
2026-06-14 01:26:18 +08:00

28 KiB

Implementation Status

Update this file before each feature commit.

Area Status Commit Verification Notes
Scaffold Completed fc47967 cargo fmt --check; cargo test; cargo clippy --all-targets --all-features --locked -- -D warnings Rust crate, lint policy, pinned TLS-sensitive dependencies, .gitignore, and minimal entry points are in place.
API contract docs Completed fc47967 cargo fmt --check; cargo test; cargo clippy --all-targets --all-features --locked -- -D warnings /v1/* OpenAI-compatible body, /admin/* frontend envelope, body codes, camelCase, and request ID policy are documented.
Configuration Completed 9ed8579 + e0680bf + cfec8ba cargo test default_config_keeps_only_codex_backend; cargo test config_loader_merges_config_and_local_yaml; full fmt/test/clippy before commit Defines Codex-only config, root config.yaml plus optional local YAML loading, Arc<AppServices> state shell, gpt-5.5 default model, and in-scope model/auth/quota/usage/logging settings fields without proxy/Ollama/provider/OpenAI-key knobs.
Admin settings Completed 7424a47 cargo test --test admin_settings_route_test admin_settings_patch; cargo test --test admin_settings_route_test Adds admin-session-gated PATCH /admin/settings for retained model/auth/quota/logging/usage settings. Mutations validate retained fields, reject removed proxy/Ollama/provider/OpenAI-key/Electron settings with admin error envelopes, write a root local.yaml overlay, and update the same-process settings view. Already constructed runtime services still use their construction-time config until a later runtime reconfiguration task or service restart.
SQLite storage Completed ffec8b5 + b0c10f2 cargo test sqlite_schema_creates_accounts_and_event_tables; cargo test connect_sqlite_creates_parent_directory_for_file_database; full fmt/test/clippy before commit Creates SQLite WAL connector, parent directory bootstrap, sqlx-managed schema for accounts/API keys/sessions/cookies/fingerprints/events, and event/account indexes.
Admin auth and client API keys Partial 24d5799 + 4e0d1e5 + e9fdea0 + 8af350d + 960bbb2 cargo test client_api_key_has_proxy_prefix_and_verifies_against_hash; cargo test admin_password_hash_is_not_a_client_api_key; cargo test --test admin_login_route_test; cargo test --test admin_api_keys_route_test; cargo fmt --check; cargo test; cargo clippy --all-targets --all-features --locked -- -D warnings; full fmt/test/clippy before 8af350d; full fmt/test/clippy before 960bbb2; current local key import/export targeted cargo test --test admin_api_keys_route_test Admin passwords use Argon2id, client API keys use cpr_ prefix plus HMAC-SHA256 with server-side pepper; /admin/login issues HttpOnly sessions and rejects client API keys as admin credentials. /admin/api-keys can create/list local client keys, status-enable/status-disable local client keys, label local client keys, delete local client keys, batch-delete local client keys, export local client key metadata, import metadata by rotating to new local cpr_ keys, and /v1/* verifies only enabled keys against SQLite instead of accepting any cpr_ string. These routes are Rust-local client auth utilities, not TypeScript third-party provider API-key parity. Provider API key pools and provider key import/export remain out of scope; local cpr_ key plaintext and key hashes are not exportable after HMAC storage, and import returns newly generated plaintext values only once.
Secret encryption Completed 105aa58 + 228febd cargo test secret_box_encrypts_and_decrypts_without_storing_plaintext; cargo test secret_box_load_or_create_should_reuse_existing_master_key_file; full fmt/test/clippy before commit AES-256-GCM SecretBox stores upstream secrets as v1:<nonce>:<ciphertext> without plaintext and can load/create the runtime master key file used by repositories.
Logging and pagination Completed eb0341e + fc16c48 + b0c10f2 + ee0ed90 + fdb9374 + 5bf012c + 8645b93 + 35f9b80 + bae084b cargo test event_logs_are_cursor_paginated; cargo test admin_logs_are_cursor_paginated_and_include_request_id; cargo test --test admin_logs_route_test admin_logs_state_patch; cargo test --test admin_logs_route_test admin_logs_should_filter; cargo test --test admin_logs_route_test admin_logs_; cargo test rotating_writer_splits_files_when_size_limit_is_reached; cargo test --test admin_usage_stats_route_test; cargo test --test v1_upstream_route_test; full fmt/test/clippy before commit Adds cursor pagination, Page<T> camelCase serialization, admin /admin/logs query/detail/state/update/clear APIs, admin /admin/logs filters for kind/level/requestId/accountId/route/model/statusCode/search, admin /admin/usage-stats and /admin/usage-stats/summary, event log repository, runtime tracing initialization, HTTP trace layer, date/size-based file rotation, v1 response lifecycle events with request/account/route/model/status/latency/non-secret metadata, and non-secret account.refresh events for upstream-401 refresh failures. Runtime log state updates are in-process only; persistent config changes remain under /admin/settings.
Diagnostics Completed 4a91dea + 924e6f8 + bb143e7 + 689a514 cargo test --test diagnostics_route_test admin_diagnostics; cargo test --test diagnostics_route_test debug_upstream; cargo test --test diagnostics_route_test Adds admin-session-gated GET /admin/diagnostics plus local-only GET /debug/diagnostics, GET /debug/fingerprint, and GET /debug/upstream with runtime package metadata, config/database/log/security paths, Codex backend transport settings, static Desktop fingerprint summary and standalone fingerprint debug output, account repository/pool state, runtime capacity summary, retained settings summary, and a Codex models endpoint connectivity probe without tokens or upstream bodies. Remote forwarded debug requests are rejected with 403.
TLS headers and fingerprint Completed 1bdd08c cargo test codex_headers_include_desktop_identity_and_turn_state; cargo tree | rg 'reqwest|rustls'; full fmt/test/clippy before commit Adds Codex Desktop fingerprint model, exact identity/request headers, and pinned reqwest/rustls client builder.
Cookie persistence Completed 4710926 + 5d3cc6e + 203270f cargo test cookie_jar_captures_and_replays_account_scoped_cookies; cargo test cookie_repository_encrypts_and_replays_account_scoped_cookies; full fmt/test/clippy before 203270f Adds account-scoped in-memory Cookie jar and encrypted SQLite Cookie repository; Cookies are replayed only for the same account/domain. Admin-pasted browser Cookie headers are stored encrypted and can be cleared per account.
Account pool and refresh Partial 0f97c5c + 2f25db8 + 4dc0c9a + c2cf7a6 + 636fa79 + fdb9374 + 3ecd5b6 + 3960a35 + db6cb98 + 93cfee3 + 6d18d2c + a32a53c + 1d6c301 + a3b4d2b + 0daa96b cargo test account_pool_skips_expired_disabled_banned_and_quota_exhausted_accounts; cargo test --test account_pool_scheduling_test; cargo test --test account_refresh_test; cargo test --test oauth_refresh_test; cargo test --test v1_upstream_route_test; cargo test --test account_pool_startup_test; cargo test --test account_pool_startup_test app_state_should_restore_persisted_cooldowns_into_runtime_pool; cargo test --test codex_websocket_test; Task 5 targeted cargo test --test v1_upstream_route_test, cargo test --test chat_completions_route_test, cargo test --test account_pool_scheduling_test, and WebSocket fallback route tests; Task 7 targeted cargo test --test admin_accounts_route_test; auth status/logout targeted cargo test --test admin_accounts_route_test; device login targeted cargo test --test admin_accounts_route_test admin_auth_device, cargo test --test oauth_refresh_test, and cargo test --test admin_accounts_route_test; PKCE auth-flow targeted cargo test --test admin_accounts_route_test admin_auth_, cargo test --test oauth_refresh_test, and cargo test --test admin_accounts_route_test; full fmt/test/clippy before db6cb98 Implements base account status filtering, refresh scheduler semantics, real OpenAI OAuth refresh-token exchange, OpenAI OAuth device-code polling into the shared validated account import path, OpenAI OAuth PKCE authorization-code exchange into the same path, 401-triggered refresh and single retry, max concurrent slots, stale slot cleanup, least-used/round-robin/sticky strategies, tier priority, quota-cache filtering, Cloudflare cooldown skip, request staggering metadata, preferred account selection, exclude IDs, capacity summary, settings-backed pool construction, same-process manual/import/CLI/device/PKCE import-to-pool sync, startup pool snapshots from SQLite with usage-based last-used metadata and persisted quota/Cloudflare cooldown state, SQLite-backed 429 quota cooldown marking, Cloudflare cooldown mutation, pool status mutation for upstream fallback, admin label/status/delete/runtime refresh synchronization, admin reset-usage last-used clearing, runtime pool clearing on logout, shared fallback acquisition for non-streaming Responses, HTTP SSE Responses setup, Chat Completions, and non-history WebSocket handshakes before request body send. previous_response_id WebSocket requests remain account-affine on classified failures. Still missing durable release-time slot state.
Account repository Completed 14fe706 + db6cb98 + 72438c6 + 869b6f8 + 93cfee3 + a32a53c + b879dd6 + 0daa96b cargo test --test account_repository_test; cargo test --test admin_accounts_route_test; cargo test --test admin_accounts_cookies_quota_test; cargo test --test account_pool_startup_test app_state_should_restore_persisted_cooldowns_into_runtime_pool; cargo test --test v1_upstream_fallback_test v1_responses_should_; cargo fmt --check; cargo clippy --all-targets --all-features --locked -- -D warnings; cargo test; full fmt/test/clippy before db6cb98; full fmt/test/clippy before 72438c6; auth status/logout targeted cargo test --test admin_accounts_route_test; quota warnings targeted and full gate before b879dd6 Adds encrypted SQLite account token storage, decrypting reads, metadata-only reads for auth status, cursor pagination, full export reads, status/label updates, account deletion, account-wide delete for logout, release-time usage counter persistence, refresh-token-preserving token updates, ChatGPT account/user identity lookup, JWT-claim metadata/token updates that preserve existing labels, quota JSON caching, quota warning snapshot reads, persisted quota/Cloudflare cooldown fields for runtime pool restore, and per-account local usage counter reset.
Translation Completed eff182e + b9c30ba cargo test --test routes_chat_test; cargo test --test chat_completions_route_test; full cargo fmt --check && cargo test && cargo clippy --all-targets --all-features --locked -- -D warnings before b9c30ba Adds OpenAI Chat request types, expanded Codex Responses request type, OpenAI Chat to Codex translation for system/developer instructions, multimodal content, tool/function calls, response formats, reasoning effort, service tier, and parallel tool calls. Codex SSE now converts back to OpenAI chat completions and chat chunks with text deltas, reasoning content, tool calls, usage details, and OpenAI-compatible error bodies.
HTTP routes Partial ab0ad8f + 3830b21 + 6179d44 + cfec8ba + 6341336 + 228febd + c2cf7a6 + e9fdea0 + ee0ed90 + fdb9374 + 9ca5c7d + b9c30ba + 350ffbe + 3ecd5b6 + 3960a35 + 1738f24 + 0b6cc7e + f75db60 + 4b19846 + db6cb98 + 16eb4ed + 8af350d + 203270f + 960bbb2 + 72438c6 + 16938e6 + 869b6f8 + e1f35e0 + 93cfee3 + bfe561d + cf5ff0b + 6d18d2c + a32a53c + 1d6c301 + a3b4d2b + 7424a47 + 8645b93 + 35f9b80 + 4a91dea + 924e6f8 + bb143e7 + 689a514 + b879dd6 + 0daa96b + efbbe8a + bae084b cargo test v1_requires_client_api_key_not_admin_cookie; cargo test models_route_returns_openai_compatible_codex_model_list; cargo test --test admin_settings_route_test; cargo test --test model_catalog_test; cargo test --test admin_accounts_route_test; cargo test --test cli_auth_import_test; cargo test --test admin_api_keys_route_test; cargo test --test admin_usage_stats_route_test; cargo test --test admin_accounts_cookies_quota_test; cargo test --test v1_upstream_route_test; cargo test --test chat_completions_route_test; cargo test --test codex_websocket_test; targeted HTTP SSE error tests before bfe561d; targeted local API key import/export tests before cf5ff0b; WebSocket fallback targeted route tests; auth status/logout targeted cargo test --test admin_accounts_route_test; device login targeted cargo test --test admin_accounts_route_test admin_auth_device, cargo test --test oauth_refresh_test, and cargo test --test admin_accounts_route_test; PKCE auth-flow targeted cargo test --test admin_accounts_route_test admin_auth_, cargo test --test oauth_refresh_test, and cargo test --test admin_accounts_route_test; full cargo fmt --check && cargo test && cargo clippy --all-targets --all-features --locked -- -D warnings before b9c30ba and 350ffbe; Task 5 targeted verification before 3ecd5b6 and 3960a35; full fmt/test/clippy before 1738f24; full fmt/test/clippy plus real-file smoke before 0b6cc7e; full fmt/test/clippy before f75db60; full fmt/test/clippy before 4b19846; full fmt/test/clippy before db6cb98; full fmt/test/clippy before 16eb4ed; full fmt/test/clippy before 8af350d; full fmt/test/clippy before 203270f; full fmt/test/clippy before 960bbb2; full fmt/test/clippy before 72438c6; full fmt/test/clippy before 16938e6; admin settings targeted tests before 7424a47; log state/filter targeted tests before 35f9b80 and bae084b; diagnostics route tests before 689a514; quota warnings targeted tests before b879dd6; cooldown restore and Cloudflare Cookie clearing targeted tests before 0daa96b and efbbe8a Adds Axum router, health route, /v1/models, /v1/models/catalog, /v1/models/{id}, /v1/models/{id}/info, /debug/models, /debug/diagnostics, /debug/fingerprint, /debug/upstream, /admin/diagnostics, /admin/auth/status, /admin/auth/logout, /admin/auth/login-start, /admin/auth/code-relay, /admin/auth/callback, /auth/callback, /admin/auth/device-login, /admin/auth/device-poll/{device_code}, /admin/accounts, /admin/accounts/quota-warnings, /admin/accounts/export, /admin/accounts/batch-delete, /admin/accounts/batch-status, /admin/accounts/health-check, /admin/accounts/{id}, /admin/accounts/{id}/label, /admin/accounts/{id}/status, /admin/accounts/{id}/refresh, /admin/accounts/{id}/reset-usage, /admin/accounts/{id}/quota, /admin/accounts/{id}/cookies, /admin/accounts/import, /admin/accounts/import-cli, /admin/api-keys, /admin/api-keys/export, /admin/api-keys/import, /admin/api-keys/batch-delete, /admin/api-keys/{id}, /admin/api-keys/{id}/label, /admin/api-keys/{id}/status, /admin/logs, /admin/logs/state, /admin/logs/{id}, /admin/usage-stats, /admin/usage-stats/summary, /admin/settings, /admin/refresh-models, /v1/responses HTTP SSE collection with output item/delta reconstruction plus output_text sync for non-streaming clients, default streaming Responses passthrough when stream is omitted, WebSocket-backed Responses for previous_response_id, explicit non-history WebSocket Responses via use_websocket/useWebSocket, non-streaming and HTTP SSE setup fallback to another imported account after 429/402/403 account-state failures, WebSocket setup fallback after classified handshake failures when no previous_response_id is present, Responses field parity for service tier, tool choice, parallel tool calls, text format, prompt cache key, include, client metadata, reasoning include default, and Codex context headers, plus a dedicated /v1/chat/completions route backed by imported Codex accounts with fallback for buffered non-streaming and client-streaming output conversion. /v1 unauthorized and model errors remain OpenAI-compatible, cached backend model snapshots are used by /v1/models* when present, global request-id response headers are preserved, gpt-5.5 remains the default/test model baseline, and /admin/settings supports admin-session-gated read/write access with lower camelCase envelopes. /admin/auth/status returns sanitized authenticated state, first account metadata, and pool summary without decrypting or returning tokens. /admin/auth/logout clears all account rows and the runtime pool while relying on SQLite foreign-key cascades for usage/cookies. /admin/auth/login-start creates a short-lived in-memory PKCE session and returns the OpenAI authorization URL; /admin/auth/code-relay, /admin/auth/callback, and the registered /auth/callback redirect path exchange returned authorization codes and import tokens through the same JWT-claim validated path. /admin/auth/device-login starts the OpenAI OAuth device-code flow, and /admin/auth/device-poll/{device_code} handles authorization_pending/slow_down states or imports returned tokens without returning secrets. /admin/accounts reads metadata only and does not decrypt tokens for list views. Manual POST /admin/accounts accepts only token and/or refreshToken, rejects invalid/expired JWTs and missing ChatGPT account claims, derives metadata from JWT claims, ignores caller metadata/status/label, exchanges refresh-token-only inputs through AppState's OpenAI token refresher, preserves or rotates refresh tokens, stores secrets encrypted, synchronizes the runtime account pool, updates existing accounts by chatgpt_account_id + chatgpt_user_id, and never echoes tokens. /admin/accounts/quota-warnings returns active warning/critical quota windows computed from cached SQLite quota JSON without contacting upstream. /admin/accounts/import accepts native and Sub2API OpenAI OAuth account exports, returns sourceFormat, and ignores proxy-only metadata. /admin/accounts/import-cli reads Codex CLI auth.json from $CODEX_HOME or an explicit admin fixture path, uses the same validated JWT-claim account import path as manual add, ignores caller metadata, and returns only sanitized import counts. /admin/accounts/export returns native or Sub2API OpenAI OAuth exports without proxy fields. /admin/accounts/{id}/label, /status, /refresh, /reset-usage, /quota, delete, batch-delete, batch-status, and /admin/accounts/health-check mutate or inspect SQLite plus runtime account pool without returning secrets; health/quota call Codex backend usage endpoints through imported account tokens and classify invalid/quota/banned/Cloudflare responses into account state or cooldown. /admin/accounts/{id}/cookies stores/reads/deletes encrypted per-account browser cookies. /admin/api-keys/{id}/label, /status, delete, and batch-delete mutate local client key rows used by /v1 auth; /admin/api-keys/export returns metadata only without plaintext/keyHash/pepper, and /admin/api-keys/import rotates metadata into new local keys with plaintext returned once. These are local auth utilities, not TS provider key pool parity. /admin/refresh-models fetches backend model lists through imported accounts only, stores plan snapshots, and syncs runtime model-plan allowlists. Still missing live Chat streaming transform.
Admin quota warnings Completed b879dd6 cargo test --test admin_accounts_cookies_quota_test quota_warnings; cargo test --test admin_accounts_cookies_quota_test; cargo fmt --check; cargo test; cargo clippy --all-targets --all-features --locked -- -D warnings Adds /admin/accounts/quota-warnings, backed by cached SQLite quota snapshots and configured warning thresholds. The route is admin-session gated, returns lower camelCase admin envelopes, and does not call upstream Codex while listing active warnings.
Admin/frontend response contract Completed 1c34ea7 + b0c10f2 cargo test admin_envelope_serializes_lower_camel_case_request_id; cargo test admin_logs_reject_missing_admin_session_cookie; cargo test v1_response_has_request_id_header_without_admin_body_field; full fmt/test/clippy before commit Adds reusable admin envelopes with body codes, lower camelCase JSON, paginated list shape, requestId bodies, admin session cookie enforcement, and keeps /v1/* OpenAI-compatible.
HTTP auth boundary Completed cec4607 + e9fdea0 cargo test --test http_auth_test; cargo test --test routes_responses_test; cargo test --test admin_api_keys_route_test; cargo test --test admin_logs_route_test; cargo fmt --check; cargo clippy --all-targets --all-features --locked -- -D warnings; cargo test Adds a real src/http/auth.rs boundary for client API key and admin session cookie parsing. /v1/* accepts only enabled local Bearer cpr_... client API keys verified from SQLite, admin session parsing ignores client API keys, and route handlers no longer own ad hoc credential parsing.
Model catalog Partial 6341336 + 1738f24 + f75db60 + 4b19846 cargo test --test model_catalog_test; cargo test model_catalog_route_returns_codex_metadata_without_alias_entries; cargo test --test storage_schema_test; cargo test --test routes_responses_test model_catalog_route_returns_cached_backend_models; cargo test --test admin_models_route_test; full fmt/test/clippy before 1738f24; full fmt/test/clippy before f75db60; full fmt/test/clippy before 4b19846 Adds a native static Codex model catalog with gpt-5.5 default, configured aliases, reasoning/service-tier suffix parsing including none and minimal, OpenAI-compatible /v1/models, extended catalog/detail/info routes, debug summary, SQLite-backed backend model snapshots by plan, cached backend catalog merge, model-to-plan allowlist derivation, and an admin refresh route that probes Codex model endpoints with one imported account per plan and syncs the runtime account-pool allowlist. Still missing full model metadata parity.
Upstream lifecycle Partial 88cad87 + 225fbff + c2cf7a6 + 636fa79 + ee0ed90 + fdb9374 + 5bf012c + 9ca5c7d + b9c30ba + 350ffbe + 3ecd5b6 + 3960a35 + bfe561d + 6d18d2c + 0daa96b + efbbe8a cargo test responses_route_rejects_non_codex_provider_models; cargo test v1_requires_client_api_key_not_admin_cookie; cargo test --test codex_sse_usage_test; cargo test --test codex_client_test; cargo test --test oauth_refresh_test; cargo test --test v1_upstream_route_test; cargo test --test v1_upstream_fallback_test v1_responses_should_; cargo test --test v1_upstream_fallback_test v1_responses_should_cool_down_cloudflare_403_and_retry_next_account; cargo test --test account_pool_startup_test; cargo test --test account_pool_startup_test app_state_should_restore_persisted_cooldowns_into_runtime_pool; cargo test --test codex_websocket_test; cargo test --test admin_accounts_route_test; Task 5 targeted cargo test --test v1_upstream_route_test, cargo test --test chat_completions_route_test, cargo test --test account_pool_scheduling_test, and WebSocket fallback route tests; HTTP SSE error mapping targeted cargo test --test v1_upstream_route_test v1_responses_non_stream_should_return_upstream_error and cargo test --test v1_upstream_route_test v1_responses_stream_should_passthrough; full cargo fmt --check && cargo test && cargo clippy --all-targets --all-features --locked -- -D warnings before b9c30ba and 350ffbe /v1 enforces client API key shape, rejects non-Codex provider models through the model catalog, returns OpenAI-compatible errors, includes reusable SSE/usage helpers, sends Codex Desktop HTTP SSE requests through imported accounts, sends WebSocket response.create requests when previous_response_id requires upstream history, keeps previous_response_id requests account-affine on classified WebSocket handshake failures for streaming and non-streaming clients, replays/captures encrypted Cookies, clears Cloudflare-blocked account Cookies, captures successful WebSocket rate-limit headers, forwards Codex request context headers, fetches Codex usage/quota through imported account tokens for admin health/quota operations, normalizes service_tier: fast to upstream priority, collects response.completed, reconstructs missing assistant output from response.output_item.done or text deltas, synchronizes output_text for non-streaming clients, maps non-streaming HTTP SSE error and response.failed terminal frames to OpenAI-compatible upstream_error bodies, passes through Responses streaming SSE by default while marking error and response.failed terminal frames as failed lifecycle logs, adapts Chat Completions responses/chunks, refreshes and retries once after upstream 401 when a refresh token is stored, parses Retry-After plus Codex reset metadata from upstream errors, records 429 request attempts, persists 429 quota cooldowns and Cloudflare cooldowns to SQLite, classifies upstream 429/402/403 into account cooldown/quota/banned/Cloudflare state changes, retries non-streaming /v1/responses, HTTP SSE /v1/responses setup, non-history WebSocket setup, and /v1/chat/completions with another imported account when available, records token usage, writes v1 lifecycle event logs, records refresh failure classification for upstream 401, and restores the account pool from SQLite on startup. Still missing richer OpenAI-compatible error mapping and live Chat streaming transform.
Codex WebSocket boundary Completed cc0516d + b9c30ba + 350ffbe + 6d18d2c cargo test --test codex_websocket_test; cargo test --test v1_responses_websocket_test v1_responses_should_use_websocket_for_previous_response_id_streaming; WebSocket route fallback tests; full cargo fmt --check && cargo test && cargo clippy --all-targets --all-features --locked -- -D warnings before b9c30ba and 350ffbe Adds src/codex/transport/websocket.rs with tested transport classification for HTTP SSE versus WebSocket-only requests. previous_response_id and explicit WebSocket requests use typed transport selection, local-only use_websocket is not serialized into upstream JSON, WebSocket response.create carries Codex headers and parity fields, incoming WebSocket messages are emitted as SSE-compatible events, handshake HTTP failures surface as upstream errors before request body send, successful handshake headers capture turn state, cookies, and rate-limit headers, non-history WebSocket setup can fallback to another imported account, and previous_response_id WebSocket failures remain on the original account.
Fingerprint updates Partial dd26d31 + e32220a cargo test update_manifest_updates_app_version_and_build_number; cargo test fingerprint_updater_fetches_manifest_and_persists_history; full fmt/test/clippy before commit Parses a JSON update manifest and persists app version/build number history to SQLite. Still missing original appcast XML polling, update-state persistence, runtime header fingerprint selection from the latest stored fingerprint, and optional local Codex.app Chromium extraction.
Runtime docs and packaging Completed 33b63f3 cargo fmt --check; cargo clippy --all-targets --all-features --locked -- -D warnings; cargo test; cargo run; curl -s -i http://127.0.0.1:8080/health README scope, root runtime config, Dockerfile, compose file, and health smoke test are complete.
Background scheduler lifecycle Completed 5fcd408 + 7370799 + 10714de cargo test; cargo fmt --check; cargo clippy --all-targets --all-features --locked -- -D warnings Fully implemented and integrated all core schedulers: RefreshScheduler (JWT exp-margin timers, crash recovery, exponential backoff, 401-triggered refresh), SessionCleanupScheduler (configurable interval, graceful shutdown), QuotaRefresher (actively unlocks limit_reached accounts every 15min, 30min minimum per account), ModelRefresher (background model refresh every 1h with retry logic), SessionAffinityMap (previous_response_id support with 4h TTL). All integrated into main.rs with graceful shutdown on Ctrl+C. Optional: SnapshotTimer for usage history, quotaVerifyRequired field support.