diff --git a/README.md b/README.md
index 111eee9161..824bc5bddd 100644
--- a/README.md
+++ b/README.md
@@ -1,652 +1,175 @@
-
-
# codex-lb
-**English** | [简体中文](./README.zh-CN.md)
+[English](README.md) | [简体中文](README.zh-CN.md)
+
+A local proxy and load balancer for ChatGPT accounts.
-Load balancer for ChatGPT accounts. Pool multiple accounts, track usage, manage API keys, view everything in a dashboard.
+codex-lb pools accounts behind OpenAI-compatible endpoints, keeps a Codex-native endpoint for Codex clients, tracks usage, and provides a browser dashboard for account, key, and routing controls.
-|  |  |
-|:---:|:---:|
+[](https://github.com/glopyglerky/codex-lb/commits/main)
+[](https://github.com/Soju06/codex-lb/releases/latest)
+[](LICENSE)
-
-More screenshots
+> This repository is a personal fork of [Soju06/codex-lb](https://github.com/Soju06/codex-lb). It does not publish its own release or container image. The quick start below runs the upstream image. Review this fork's changes before deploying its source.
-| Settings | Login |
-|:---:|:---:|
-|  |  |
+## What it does
-| Dashboard (dark) | Accounts (dark) | Settings (dark) |
-|:---:|:---:|:---:|
-|  |  |  |
+- Balances requests across eligible ChatGPT accounts while preserving sticky conversation routing.
+- Exposes `/v1` for OpenAI-compatible clients and `/backend-api/codex` for Codex-native traffic.
+- Tracks account usage, request history, costs, quota resets, and routing decisions.
+- Issues scoped API keys with model and rate limits.
+- Supports SQLite by default and PostgreSQL for shared deployments.
+- Provides dashboard password, TOTP, trusted-header, and explicitly disabled authentication modes.
+- Runs locally, in Docker, or through the included Helm chart.
-
+No routing strategy can guarantee account safety. Use normal request volumes, follow the applicable terms, and keep sticky routing enabled unless you have a specific reason to change it.
-## Features
+## How it works
-
-
-Account Pooling Load balance across multiple ChatGPT accounts |
-Usage Tracking Per-account tokens, cost, 28-day trends |
-API Keys Per-key rate limits by token, cost, window, model |
-
-
-Dashboard Auth Password + optional TOTP |
-OpenAI-compatible Codex CLI, OpenCode, any OpenAI client |
-Auto Model Sync Available models fetched from upstream |
-
-
+```text
+client -> authentication -> model and account eligibility -> sticky routing
+ -> upstream Codex session -> streamed response -> usage settlement
+```
-## Routing Strategy Guide
+The routing contract, retry rules, and session ownership live in [OpenSpec](openspec/specs/account-routing/spec.md). The dashboard exposes the supported strategies. Capacity weighted and relative availability are the sensible defaults for most pools.
-The dashboard setting **Routing strategy** controls how eligible accounts are selected for each request. No strategy can guarantee account-safety outcomes; conservative use still depends on staying within OpenAI terms, using normal request volumes, and avoiding traffic patterns that would be unusual for your accounts.
+## Current status
-For low-volume, policy-compliant personal use, start with **Capacity weighted** or **Relative availability** and keep sticky threads enabled. Those strategies preserve session locality while avoiding sudden all-traffic shifts to a single account.
+The fork's default branch is active development code and currently identifies itself as an alpha package. It has no fork-specific release. Use the live badges above for fork activity and the latest upstream release, and use `GET /v1/models` for the current model catalog. Copied model lists age badly.
-| Routing strategy | Behavior | Trade-offs and recommended use |
-|---|---|---|
-| Capacity weighted | Prefers accounts with more usable quota headroom. | Good default for mixed pools and normal compliant usage. |
-| Relative availability | Draws from the strongest available accounts with configurable weighting. | Smooths distribution while still preferring healthier accounts. |
-| Usage weighted | Reacts to observed recent usage. | Useful when usage history should influence selection, but less direct than capacity-based routing. |
-| Round robin | Cycles evenly through eligible accounts. | Simple and predictable, but ignores quota shape and reset timing. |
-| Fill first | Uses one account heavily before moving on. | Best for controlled drain tests; less conservative for everyday traffic. |
-| Sequential drain | Drains accounts in a fixed order. | Useful for maintenance or explicit account rotation, not a normal safety-first default. |
-| Reset drain | Prioritizes capacity near reset windows. | Helps consume expiring quota, but can create timing-shaped bursts. |
-| Single account | Pins all traffic to one selected active account. | Useful for isolation and debugging; no load balancing. |
+The normative behavior lives under [`openspec/specs/`](openspec/specs/). Configuration defaults come from [`.env.example`](.env.example). Those files are better authorities than a dated feature matrix in this README.
-## Quick Start
+## Quick start
```bash
-# Docker (recommended)
docker volume create codex-lb-data
docker run -d --name codex-lb \
-p 2455:2455 -p 1455:1455 \
-v codex-lb-data:/var/lib/codex-lb \
ghcr.io/soju06/codex-lb:latest
-
-# or uvx
-uvx codex-lb
```
-Open [localhost:2455](http://localhost:2455) → Add account → Done.
-
-## Remote Setup
-
-When accessing the dashboard remotely for the first time, a bootstrap token is required to set the initial password.
-
-**Auto-generated (default):** On first startup (no password configured), the server generates a one-time token and prints it to logs:
+Open [localhost:2455](http://localhost:2455), add an account, then check the live model catalog:
```bash
-docker logs codex-lb
-# ============================================
-# Dashboard bootstrap token (first-run):
-#
-# ============================================
+curl http://127.0.0.1:2455/v1/models
```
-Open the dashboard → enter the token + new password → done. The token is shared across replicas and remains valid until a password is set. In multi-replica setups, replicas must share the same encryption key (the Helm chart default) for restart recovery to work.
+You can also run the upstream Python package with `uvx codex-lb`.
-**Manual token:** To use a fixed token instead, set the env var before starting:
+### First remote login
+
+Local dashboard access bypasses first-run bootstrap. Remote access requires a one-time token when no password exists. The server prints the generated token at startup:
```bash
-docker run -d --name codex-lb \
- -e CODEX_LB_DASHBOARD_BOOTSTRAP_TOKEN=your-secret-token \
- -p 2455:2455 -p 1455:1455 \
- -v codex-lb-data:/var/lib/codex-lb \
- ghcr.io/soju06/codex-lb:latest
+docker logs codex-lb
```
-**Local access** (localhost) bypasses bootstrap entirely — no token needed.
-
-## Client Setup
-
-Point any OpenAI-compatible client at codex-lb. If [API key auth](#api-key-authentication) is enabled, pass a key from the dashboard as a Bearer token.
-
-Model availability is discovered from the upstream Codex model catalog and can vary by account plan, workspace, rollout, and upstream deprecation state. Prefer the live `GET /v1/models` or `GET /backend-api/codex/models` response over a copied static table when configuring clients or API-key model allowlists.
+Set `CODEX_LB_DASHBOARD_BOOTSTRAP_TOKEN` before startup if you need a fixed token. Replicas must share the same encryption key so first-run and session state survive restarts.
-| Logo | Client | Endpoint | Config |
-|---|--------|----------|--------|
-|
| **Codex CLI** | `http://127.0.0.1:2455/backend-api/codex` | `~/.codex/config.toml` |
-|
| **OpenCode** | `http://127.0.0.1:2455/v1` | `~/.config/opencode/opencode.json` |
-|
| **OpenClaw** | `http://127.0.0.1:2455/v1` | `~/.openclaw/openclaw.json` |
-|
| **OpenAI Python SDK** | `http://127.0.0.1:2455/v1` | Code |
+## Connect Codex
-
-
Codex CLI / IDE Extension
-
-
-`~/.codex/config.toml`:
+Pick a model from `/v1/models`, then add a provider to `~/.codex/config.toml`:
```toml
-model = "gpt-5.3-codex"
-model_reasoning_effort = "xhigh"
+model = "MODEL_ID"
model_provider = "codex-lb"
-[model_providers.codex-lb]
-name = "openai" # required — enables remote /responses/compact. Lowercase since Codex 2026-05-23; older "OpenAI" stops resolving gpt-5.5
-base_url = "http://127.0.0.1:2455/backend-api/codex"
-wire_api = "responses"
-supports_websockets = true
-requires_openai_auth = true # required for codex app
-```
-
-This documented `requires_openai_auth = true` setup uses Codex-backed
-authentication and does not need an `x-openai-actor-authorization` marker to be
-eligible for Codex's built-in `$imagegen` tool. Provider configurations that
-intentionally skip OpenAI login have a different eligibility path; see the
-[Images compatibility context](openspec/specs/images-api-compat/context.md#codex-provider-eligibility).
-
-Optional: enable native upstream WebSockets for Codex streaming while keeping `codex-lb` pooling:
-
-```bash
-export CODEX_LB_UPSTREAM_STREAM_TRANSPORT=websocket
-```
-
-`auto` is the default and uses native WebSockets for native Codex headers or models that prefer them.
-You can also switch this in the dashboard under Settings -> Routing -> Upstream stream transport.
-
-Note: Codex itself does not currently expose a stable documented `wire_api = "websocket"` provider mode.
-If you want to experiment on the Codex side, the current CLI exposes under-development feature flags:
-
-```toml
-[features]
-responses_websockets = true
-# or
-responses_websockets_v2 = true
-```
-
-These flags are experimental and do not replace `wire_api = "responses"`.
-
-Upstream websocket handshakes automatically honor standard proxy environment variables when they are
-present. `wss://` handshakes check `wss_proxy`, `socks_proxy`, `https_proxy`, and `all_proxy`;
-plain `ws://` handshakes also check `ws_proxy` and `http_proxy`. Set
-`CODEX_LB_UPSTREAM_WEBSOCKET_TRUST_ENV=false` only when websocket handshakes must bypass those
-environment proxies and connect directly.
-
-**With [API key auth](#api-key-authentication):**
-
-```toml
[model_providers.codex-lb]
name = "openai"
base_url = "http://127.0.0.1:2455/backend-api/codex"
wire_api = "responses"
-env_key = "CODEX_LB_API_KEY"
supports_websockets = true
-requires_openai_auth = true # required for codex app
-```
-
-```bash
-export CODEX_LB_API_KEY="sk-clb-..." # key from dashboard
-codex
+requires_openai_auth = true
```
-**Verify WebSocket transport**
-
-Use a one-off debug run:
-
-```bash
-RUST_LOG=debug codex exec "Reply with OK only."
-```
-
-Healthy websocket signals:
-
-- CLI logs contain `connecting to websocket` and `successfully connected to websocket`
-- `codex-lb` logs show `WebSocket /backend-api/codex/responses`
-- `codex-lb` logs do **not** show fallback `POST /backend-api/codex/responses` for the same run
-
-If you run `codex-lb` behind a reverse proxy, make sure it forwards WebSocket upgrades.
-
-**Migrating from direct OpenAI** — `codex resume` filters by `model_provider`;
-old sessions won't appear until you re-tag them. Use the built-in retag command
-instead of editing Codex files by hand; see
-[Codex session retagging](openspec/specs/runtime-portability/context.md#codex-session-retagging) for backups, Docker, WSL,
-and rollback details.
+If API key authentication is enabled, add `env_key = "CODEX_LB_API_KEY"` to the provider and export the key before starting Codex:
```bash
-# Preview what will change first.
-codex-lb codex-sessions retag --from openai --to codex-lb --dry-run
-
-# Then close Codex/Codex CLI and apply the retag.
-codex-lb codex-sessions retag --from openai --to codex-lb --yes
-```
-
-
-
-
-
OpenCode
-
-
-> **Important**: Use the built-in `openai` provider with `baseURL` override — not a custom provider with `@ai-sdk/openai-compatible`. Custom providers use the Chat Completions API which **drops reasoning/thinking content**. The built-in `openai` provider uses the Responses API, which properly preserves `encrypted_content` and multi-turn reasoning state.
-
-Before starting, please ensure that all existing OpenAI credentials is cleared in `~/.local/share/opencode/auth.json`
-You can clean the config by using this one-liner
-`jq 'del(.openai)' ~/.local/share/opencode/auth.json > auth.json.tmp && mv auth.json.tmp ~/.local/share/opencode/auth.json`
-
-`~/.config/opencode/opencode.json`:
-
-```jsonc
-{
- "$schema": "https://opencode.ai/config.json",
- "provider": {
- "openai": {
- "options": {
- "baseURL": "http://127.0.0.1:2455/v1",
- "apiKey": "{env:CODEX_LB_API_KEY}"
- },
- "models": {
- "gpt-5.4": {
- "name": "GPT-5.4",
- "reasoning": true,
- "options": { "reasoningEffort": "high", "reasoningSummary": "detailed" },
- "limit": { "context": 1050000, "output": 128000 }
- },
- "gpt-5.3-codex": {
- "name": "GPT-5.3 Codex",
- "reasoning": true,
- "options": { "reasoningEffort": "high", "reasoningSummary": "detailed" },
- "limit": { "context": 272000, "output": 65536 }
- },
- "gpt-5.1-codex-mini": {
- "name": "GPT-5.1 Codex Mini",
- "reasoning": true,
- "options": { "reasoningEffort": "high", "reasoningSummary": "detailed" },
- "limit": { "context": 272000, "output": 65536 }
- },
- "gpt-5.3-codex-spark": {
- "name": "GPT-5.3 Codex Spark",
- "reasoning": true,
- "options": { "reasoningEffort": "xhigh", "reasoningSummary": "detailed" },
- "limit": { "context": 128000, "output": 65536 }
- }
- }
- }
- },
- "model": "openai/gpt-5.3-codex"
-}
-```
-
-This overrides the built-in `openai` provider's endpoint to point at codex-lb while keeping the Responses API code path that handles reasoning properly.
-
-```bash
-export CODEX_LB_API_KEY="sk-clb-..." # key from dashboard
-opencode
-```
-
-
-
-
-
OpenClaw
-
-
-`~/.openclaw/openclaw.json`:
-
-```jsonc
-{
- "agents": {
- "defaults": {
- "model": { "primary": "codex-lb/gpt-5.4" },
- "models": {
- "codex-lb/gpt-5.4": { "params": { "cacheRetention": "short" } }
- "codex-lb/gpt-5.4-mini": { "params": { "cacheRetention": "short" } }
- "codex-lb/gpt-5.3-codex": { "params": { "cacheRetention": "short" } }
- }
- }
- },
- "models": {
- "mode": "merge",
- "providers": {
- "codex-lb": {
- "baseUrl": "http://127.0.0.1:2455/v1",
- "apiKey": "${CODEX_LB_API_KEY}", // or "dummy" if API key auth is disabled
- "api": "openai-responses",
- "models": [
- {
- "id": "gpt-5.4",
- "name": "gpt-5.4 (codex-lb)",
- "contextWindow": 1050000,
- "contextTokens": 272000,
- "maxTokens": 4096,
- "input": ["text"],
- "reasoning": false
- },
- {
- "id": "gpt-5.4-mini",
- "name": "gpt-5.4-mini (codex-lb)",
- "contextWindow": 400000,
- "contextTokens": 272000,
- "maxTokens": 4096,
- "input": ["text"],
- "reasoning": false
- },
- {
- "id": "gpt-5.3-codex",
- "name": "gpt-5.3-codex (codex-lb)",
- "contextWindow": 400000,
- "contextTokens": 272000,
- "maxTokens": 4096,
- "input": ["text"],
- "reasoning": false
- }
- ]
- }
- }
- }
-}
-```
-
-Set the env var or replace `${CODEX_LB_API_KEY}` with a key from the dashboard. If API key auth is disabled,
-local requests can omit the key, but non-local requests are still rejected until proxy authentication is configured.
-
-The `/v1` route is the simplest OpenAI-compatible setup. If your OpenClaw build uses a Codex-native provider path such as `openai-codex-responses` and needs Codex-style usage/accounting behavior, point that provider at `http://127.0.0.1:2455/backend-api/codex` instead. For third-party Codex-compatible backends, the client must allow opaque bearer-token passthrough and should only send `chatgpt-account-id` when it actually decoded one from an official ChatGPT/Codex token.
-
-
-
-
-
OpenAI Python SDK
-
-
-```python
-from openai import OpenAI
-
-client = OpenAI(
- base_url="http://127.0.0.1:2455/v1",
- api_key="sk-clb-...", # from dashboard, or any non-empty string if auth is disabled
-)
-
-response = client.chat.completions.create(
- model="gpt-5.3-codex",
- messages=[{"role": "user", "content": "Hello!"}],
-)
-print(response.choices[0].message.content)
+export CODEX_LB_API_KEY="sk-clb-..."
+codex
```
-
+The same proxy also supports OpenCode, OpenClaw, and the OpenAI SDK. Point Responses API clients at `/v1`. Client behavior and edge cases are documented in the [Responses API context](openspec/specs/responses-api-compat/context.md), [chat completions context](openspec/specs/chat-completions-compat/context.md), and [runtime portability context](openspec/specs/runtime-portability/context.md).
-## API Key Authentication
+## Authentication
-API key auth is **disabled by default**. In that mode, only local requests to the protected proxy routes can
-proceed without a key; non-local requests are rejected until proxy authentication is configured. Enable it in
-**Settings → API Key Auth** on the dashboard when clients connect remotely or through Docker, VM, or container
-networking that appears non-local to the service.
+Proxy API key authentication is disabled by default. Without it, protected proxy routes accept only local requests. Enable API key authentication in the dashboard before allowing remote clients, then send:
-When enabled, clients must pass a valid API key as a Bearer token:
-
-```
+```text
Authorization: Bearer sk-clb-...
```
-The protected proxy routes covered by this setting are:
-
-- `/v1/*` (except `/v1/usage`, which always requires a valid key)
-- `/backend-api/codex/*`
-- `/backend-api/transcribe`
+Dashboard authentication has three explicit modes:
-**Creating keys**: Dashboard → API Keys → Create. The full key is shown **only once** at creation. Keys support optional expiration, model restrictions, and rate limits (tokens / cost per day / week / month).
+- `standard` uses a password and optional TOTP.
+- `trusted_header` accepts an identity header only from configured proxy CIDRs.
+- `disabled` removes application-level dashboard authentication and should sit behind a separate access boundary.
-## Configuration
+See the [admin authentication context](openspec/specs/admin-auth/context.md) and [API key contract](openspec/specs/api-keys/spec.md) before exposing the service beyond localhost.
-Environment variables with `CODEX_LB_` prefix or `.env.local`. See [`.env.example`](.env.example).
-SQLite is the default database backend; PostgreSQL is optional via `CODEX_LB_DATABASE_URL` (for example `postgresql+asyncpg://...`).
+## Configuration and data
-The Docker Compose `postgres` profile uses the Postgres 18 image and mounts the named data volume at
-`/var/lib/postgresql`, the parent of the image's versioned `PGDATA` directory.
+Environment variables use the `CODEX_LB_` prefix. [`.env.example`](.env.example) is the complete configuration reference.
-Existing Postgres 16 compose volumes must be upgraded before the Postgres 18 container starts:
-
-```bash
-docker compose --profile postgres stop postgres
-docker run --rm -v codex-lb-postgres-data:/var/lib/postgresql -v "$PWD:/backup" alpine \
- tar -C /var/lib/postgresql -czf /backup/codex-lb-postgres-data-before-pg18.tgz .
-docker compose --profile postgres-upgrade run --rm postgres-upgrade
-docker compose --profile postgres up -d postgres
-```
-
-The `postgres-upgrade` profile runs `pg_upgrade` in one-shot mode against the same named volume and exits after the
-data directory has been upgraded to the Postgres 18 layout. Because that helper mounts and rewrites the operator's
-database volume, Compose pins the helper image by digest; refresh and review the digest deliberately when changing the
-helper image tag. Keep the backup until the application has started and `codex-lb-db check` succeeds against the
-upgraded database.
-
-The normal `postgres` service refuses to start when it detects the old root-level `PG_VERSION` file from a pre-18
-Compose volume. If that guard fires, run the `postgres-upgrade` profile above before starting Postgres again.
-It also refuses nested `/var/lib/postgresql/data` directories that still report a pre-18 major version, because those
-layouts need an explicit pg_upgrade before the Postgres 18 container can safely open them.
-
-### Dashboard authentication modes
-
-`codex-lb` supports three dashboard auth modes via environment variables:
+| Runtime | Data path |
+| --- | --- |
+| Local or `uvx` | `~/.codex-lb/` |
+| Docker | `/var/lib/codex-lb/` |
-- `CODEX_LB_DASHBOARD_AUTH_MODE=standard` — built-in dashboard password with optional TOTP from the Settings page.
-- `CODEX_LB_DASHBOARD_AUTH_MODE=trusted_header` — trust a reverse-proxy auth header such as Authelia's `Remote-User`, but only from `CODEX_LB_FIREWALL_TRUSTED_PROXY_CIDRS`. Built-in password/TOTP remain available as an optional fallback, and password/TOTP management still requires a fallback password session.
-- `CODEX_LB_DASHBOARD_AUTH_MODE=disabled` — fully bypass dashboard auth. Use only behind network restrictions or external auth. Built-in password/TOTP management is disabled in this mode.
+Back up that directory before upgrades. SQLite is the default. PostgreSQL setup and migration rules are in the [database context](openspec/specs/database-backends/context.md).
-`trusted_header` mode also requires:
+## Kubernetes
```bash
-CODEX_LB_FIREWALL_TRUST_PROXY_HEADERS=true
-CODEX_LB_FIREWALL_TRUSTED_PROXY_CIDRS=172.18.0.0/16
-CODEX_LB_DASHBOARD_AUTH_PROXY_HEADER=Remote-User
+helm install codex-lb oci://ghcr.io/soju06/charts/codex-lb \
+ --set postgresql.auth.password=changeme \
+ --set config.databaseMigrateOnStartup=true \
+ --set migration.schemaGate.enabled=false
+kubectl port-forward svc/codex-lb 2455:2455
```
-If the trusted header is missing and no fallback password is configured, the dashboard fails closed and shows a reverse-proxy-required message instead of loading the UI.
+The [Helm chart README](deploy/helm/codex-lb/README.md) covers external databases, ingress, authentication, observability, and multi-replica routing.
-### Docker examples
+## Development
-**Authelia / trusted header**
+This project requires Python 3.13 and uses `uv` for the locked environment.
```bash
-docker run -d --name codex-lb \
- -p 2455:2455 -p 1455:1455 \
- -e CODEX_LB_DASHBOARD_AUTH_MODE=trusted_header \
- -e CODEX_LB_DASHBOARD_AUTH_PROXY_HEADER=Remote-User \
- -e CODEX_LB_FIREWALL_TRUST_PROXY_HEADERS=true \
- -e CODEX_LB_FIREWALL_TRUSTED_PROXY_CIDRS=172.18.0.0/16 \
- -v codex-lb-data:/var/lib/codex-lb \
- ghcr.io/soju06/codex-lb:latest
-```
-
-**Hard override / no app-level dashboard auth**
+uv sync --frozen
+cd frontend && bun install && cd ..
-```bash
-docker run -d --name codex-lb \
- -p 2455:2455 -p 1455:1455 \
- -e CODEX_LB_DASHBOARD_AUTH_MODE=disabled \
- -v codex-lb-data:/var/lib/codex-lb \
- ghcr.io/soju06/codex-lb:latest
+uv run fastapi run app/main.py --reload
+cd frontend && bun run dev
```
-For Helm, pass the same values through `extraEnv`.
-
-## Data
-
-| Environment | Path |
-|-------------|------|
-| Local / uvx | `~/.codex-lb/` |
-| Docker | `/var/lib/codex-lb/` |
-
-Backup this directory to preserve your data.
-
-## Troubleshooting
-
-- [Usage and quota - why does codex-lb still say `rate_limited` when Codex Desktop says reset?](openspec/specs/usage-refresh-policy/context.md)
-
-## Kubernetes
+Run the focused checks before opening a change:
```bash
-helm install codex-lb oci://ghcr.io/soju06/charts/codex-lb \
- --set postgresql.auth.password=changeme \
- --set config.databaseMigrateOnStartup=true \
- --set migration.schemaGate.enabled=false
-kubectl port-forward svc/codex-lb 2455:2455
+uv run --frozen ruff check app tests
+uv run --frozen ruff format --check app tests
+uv run --frozen ty check app
+uv run --frozen pytest tests/unit -q
```
-Open [localhost:2455](http://localhost:2455) → Add account → Done.
+Behavior changes start in [`openspec/`](openspec/). Read [the contribution rules](.github/CONTRIBUTING.md) for the repository's merge gates.
-The Helm chart auto-configures HTTP `/responses` owner handoff for multi-replica installs using a headless-service DNS name per pod. The default cluster domain is `cluster.local`; set Helm `clusterDomain` if your cluster uses a different suffix. Override `config.sessionBridgeAdvertiseBaseUrl` only if pods must be reached through a different internal address.
+## Repository map
-For external database, production config, ingress, observability, and more see the [Helm chart README](deploy/helm/codex-lb/README.md).
+| Path | Contents |
+| --- | --- |
+| [`app/`](app/) | FastAPI service, routing, persistence, authentication, and proxy runtime |
+| [`frontend/`](frontend/) | Dashboard application |
+| [`openspec/`](openspec/) | Normative behavior and operating context |
+| [`deploy/helm/codex-lb/`](deploy/helm/codex-lb/) | Kubernetes chart and deployment guide |
+| [`tests/`](tests/) | Unit, integration, compatibility, and release checks |
-Fast Mode and service-tier behavior is documented in [Responses API compatibility context](openspec/specs/responses-api-compat/context.md#fast-mode-and-service-tiers).
+## Contributing and security
-## Development
+This fork retains the upstream project's history and contributors. See the [contributor graph](https://github.com/Soju06/codex-lb/graphs/contributors) and [upstream contribution guide](https://github.com/Soju06/codex-lb/blob/main/.github/CONTRIBUTING.md).
-```bash
-# Docker
-docker compose watch
+Report vulnerabilities through the [security policy](.github/SECURITY.md). Do not post secrets, account exports, access tokens, or production logs in public issues.
-# Local
-uv sync && cd frontend && bun install && cd ..
-uv run fastapi run app/main.py --reload # backend :2455
-cd frontend && bun run dev # frontend :5173
-```
+## License
-## Contributors ✨
-
-Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/en/reference/emoji-key/)):
-
-
-
-
-
-
-
-
-
-
-This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!
+codex-lb is licensed under the [MIT License](LICENSE). Copyright and attribution remain with the upstream authors and contributors.