{
  "markdown": "<div align=\"center\">\n\n# Decodex\n\nLocal agent factory above Codex app-server.\n\n[![License](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)\n[![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/acg-box/decodex)](https://github.com/acg-box/decodex/tags)\n\n</div>\n\nDecodex is not another coding model or a replacement for Codex. Codex app-server is the\nexecution kernel for one thread. Decodex adds the durable product state and coordination\nneeded when one engineer manages many conversations, accounts, dependencies, gates, and\nfollow-up actions.\n\nThe current milestone is intentionally small: one real local Conversation can select an\naccount, start or continue a Codex thread, persist its execution facts, survive a service\nrestart, and continue without duplicate dispatch.\n\n## Current architecture\n\n- `decodex serve` is the sole product-state and side-effect owner. The same `decodex`\n  executable also provides the short-lived CLI commands.\n- A bundled SQLite database at `~/.decodex/server/decodex.sqlite3` is the only normal\n  product store.\n- `database/` owns migrations, schema verification, storage APIs, transfer tooling, and\n  restart tests.\n- Account credentials are stored in a narrow owner-private SQLite table. They are\n  available only to the service credential adapter and never enter protocol output.\n- Codex app-server remains the provider runtime. One RuntimeSession binds one exact\n  account and Codex thread.\n- GPUI and ordinary CLI commands are same-UID Unix WebSocket clients. They do not open SQLite, credential\n  files, or Codex authentication files.\n- The GPUI product is the sole macOS GUI and is packaged as `Decodex.app`. The bundle\n  contains a signed `Contents/Helpers/decodex` for local profiles and the native Swift menu-bar\n  presentation as an in-process dynamic library. It contains no second app or UI process.\n- A local app session starts `Contents/Helpers/decodex serve --parent-fd ...` when no\n  service is available. It reuses an exact-version service and reports\n  `service_version_mismatch` for any other version. The app-user command at\n  `~/.local/bin/decodex` is a symlink to the bundled helper, never a copied second binary.\n  The standalone local-service installer instead places one regular `decodex` executable at\n  that path for pure CLI and LaunchAgent operation. These installation modes are mutually\n  exclusive; neither installer adds coexistence machinery. Running `decodex` without a\n  subcommand displays help, and serving is always explicit.\n- **Show Decodex in the menu bar** is a service-owned product preference. **Launch Decodex\n  at login** is an independent macOS `SMAppService.mainApp` preference and is not stored in\n  SQLite. Closing the main window hides Decodex and retains the protocol session, native\n  menu bar, and app-owned service. **Quit Decodex** stops the app and only its owned service.\n\nNormal startup does not require a separate database server, redb, or Keychain. A one-shot tool\ncan import the existing account pool from the retired redb vault during upgrade. It opens\nthe source read only and leaves all rollback sources intact.\n\n## Supported product slice\n\n```text\nGPUI Conversation action                    apps/decodex-gpui/src/conversations.rs\n-> exact-current Conversation protocol      crates/decodex-protocol/src/{conversation,wire}.rs\n-> Decodex Conversation service             crates/decodex-runtime/src/{application,conversation}.rs\n-> SQLite revision/idempotency authority    database/src/{conversations,command}.rs\n-> RuntimeSession + ProcessGeneration       database/src/{runtime_sessions,process_generations}.rs\n-> ProviderAttempt safety                   database/src/provider_attempts.rs\n-> Codex app-server thread/start + turn/start\n                                            crates/decodex-codex/src/conversation.rs\n-> exact thread/history/event readback      runtime + protocol + GPUI\n```\n\nThe Program path has no second execution engine. `database/src/program_cycles.rs` owns the\npersisted Program aggregate and its Conversation binding. The service derives the Program graph\nand timeline, and `apps/decodex-gpui/src/{programs,program_graph,factory_surface}.rs` presents\nthem. A Codex link is absent until SQLite readback supplies the exact provider thread ID; a\nDecodex Conversation UUID is never substituted. Provider thread identities are opaque, limited\nto the SQLite-compatible 512-byte boundary, and percent-encoded as exactly one deep-link path\nsegment.\n\nThe database persists account lifecycle and routing state, credentials, quota facts,\nConversation and Turn history, runtime-session binding, process-generation fences,\nprovider attempts, positive evidence, and command receipts.\n\nMissing or stale quota evidence means unknown capacity, not exhaustion. A current known\ndepleted observation still blocks that account. Fixed routing keeps the selected account;\nbalanced routing prefers known available capacity and then follows configured order\nthrough unknown accounts.\n\nAccount Route is one synchronous, fail-fast operation under one service-local mutex. It\nreturns `codex_is_running` immediately, without changing authentication or routing, when\nChatGPT or Codex is open. Otherwise it validates the target credential, safely persists any\nrequired refresh successor, rechecks process and source state, atomically replaces\n`~/.codex/auth.json`, verifies exact readback, and only then commits the fixed account in\nSQLite. It never creates Pending state, waits for an app to exit, or hot-switches a running\nCodex process. Refresh ambiguity becomes `credential_needs_login`; it is never blind retry\nauthority. Startup can reconcile only the narrow case in which the auth write completed but\nthe SQLite active-account commit did not.\n\nAccount affinity is conversation-scoped. The first route binds one account to the\nRuntimeSession and Codex thread. Later turns keep that account even if the global routing\ndefault changes. A different conversation can select a different account. If the bound\naccount is depleted, this milestone stops for explicit recovery; it does not silently\nreplace the account and discard provider cache affinity.\n\n## Removed and deferred surfaces\n\nThe unsupported WorkItem board protocol and UI, and the static Coordinator/Agent/Review/Replay\nFactory preview, are deleted. Their old command names are not part of protocol 2.15 and fail\ndecoding. The fake Execution Decision query and projection are also removed from the protocol and\nruntime. ManagedRepository, Reset Card execution, automation, ManagedRun, remote workers, and\nmulti-machine coordination remain deferred without a public fake workflow or legacy storage\nfallback.\n\nOntology and graph engineering remain central to the direction of Decodex. They will be\nprojections over proven Goals, tasks, threads, artifacts, claims, dependencies, gates,\nand evidence. They are not a second speculative execution engine.\n\n## Persistence compatibility\n\nThis cutover adds one ordered migration that terminalizes legacy reserved `route_account`\nreceipts as `interrupted_by_upgrade` and removes their replayable request/progress state. It\npreserves accounts, credentials, routing data, conversations, and immutable Program Pack bindings.\nThe local protocol accepts one exact version; build commit and package version remain diagnostics,\nnot a second compatibility scheme.\nThe compatibility allowlist is limited to persisted/internal bytes that existing databases or\nPack digests already own:\n\n- the `quick_task_requests` table, `quick_task_admission_key` column, and migration identity/file\n  `quick_task_execution_controls` / `0003_quick_task_execution_controls.sql`;\n- persisted command-operation discriminators containing `quick_task` in existing receipts and\n  process-generation evidence;\n- the immutable built-in Pack capability literal `codex.quick_task`.\n\nThese names are not product, UI, protocol, or Rust API concepts.\n\n## Workspace\n\n- `database/`: SQLite authority and one-shot account transfer.\n- `crates/decodex-core/`: mechanism-neutral domain types and fixed local paths.\n- `crates/decodex-codex/`: Codex app-server contracts.\n- `crates/decodex-runtime/`: service composition and Conversation orchestration.\n- `crates/decodex-protocol/`: bounded same-UID protocol.\n- `apps/decodex-cli/`: the `decodex` composition root, explicit service command, diagnostics,\n  and product command client.\n- `apps/decodex-gpui/`: the only desktop GUI and `Decodex.app` packaging source.\n- `openwiki/`: current product, architecture, operations, and evidence authority.\n\n## Development\n\nThe active Rust toolchain is stable. The repository uses a separately pinned formatter\nbecause its style options are newer than stable rustfmt.\n\n```sh\npython3 scripts/vnext/local_database_gate.py\npython3 -m unittest tests/scripts/test_vnext_architecture.py\ncargo test -p decodex-database --all-targets\ncargo test -p decodex-database-transfer\ncargo test -p decodex-cli --all-targets\nDECODEX_APP_SIGN_IDENTITY=\"4EBCADF6B4D513E45CE33EC6934C08DBB0F03D7F\" \\\nDECODEX_APP_SIGN_TEAM_IDENTIFIER=\"4N949UKQ55\" \\\n  scripts/macos/test_decodex_app_stage.sh\ncargo make check\n```\n\nThese checks run locally. This repository does not keep a tracked GitHub Actions CI\nworkflow; future Actions are limited to tag/release publication. The active vNext CLI\ndoes not provide repository commit, landing, or Git-hook commands. Use the reviewed\nGit/GitHub workflow for those actions, with exact base/head object IDs and authoritative\nmerge readback where required.\n\nOn the current macOS development host, use the Xcode beta developer directory for the\ncomplete GPUI gate because the default Command Line Tools selection does not include the\nMetal compiler:\n\n```sh\nDEVELOPER_DIR=/Applications/Xcode-beta.app/Contents/Developer cargo make check\n```\n\nStart with the [OpenWiki quickstart](openwiki/quickstart.md) for the normative contract,\noperations, safety rules, and current evidence.\n\n## License\n\nDecodex is licensed under GPLv3. See [LICENSE](LICENSE).\n",
  "bytes": 10053,
  "sha": "4b4e377c69e20076a2d9231af4bd8b386e29bc369061c6acd79b85a622f18026",
  "repo_slug": "acg-box/decodex",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_acg_box_decodex_openwiki_index_md_4a4c5145/readme"
}