Skip to content

hack-ink/decodex

Repository files navigation

Decodex

Repo-native agent orchestration, retained lanes, and local operator control.

License GitHub tag (latest by date) GitHub last commit GitHub code lines

Feature Highlights

  • Rust CLI and runtime for repo-native retained coding-agent lanes.
  • Natural-language-first loop-runtime contract with research/decision promotion, internal execution-program state, and normal Linear issue lanes.
  • Native macOS app for Decodex Codex account-pool management.
  • Explicit project registry under ~/.codex/decodex/projects/<service-id>/.
  • Local operator listener with a dashboard at / and /dashboard, WebSocket snapshot/control traffic at /dashboard/control, Decodex App snapshot/account APIs under /api/, and GET /livez for liveness.
  • Static Astro site for the public Decodex product surface and app download entry.
  • Installable agent plugins for Decodex lifecycle work, knowledge/docs workflows, repo-work contracts, and generic challenge/skeptic review.
  • Repository documentation split by question type into spec, runbook, reference, and decision lanes.

Status

Prototype / in active development.

This repository owns the Decodex runtime, native app, static site, and installable plugin. Upstream monitoring and public publishing automation are intentionally outside this repository.

Supported runtime host targets are macOS and Linux. Windows remains unsupported for the runtime.

App identity

  • Product display name: Decodex.
  • Runtime CLI binary: decodex.
  • Public site: https://decodex.space.
  • Lower-case decodex remains only for stable technical identifiers such as the repository slug, Cargo package name, CLI binary, plugin package, config keys, and schema names.

Workspace posture

  • apps/decodex/ owns the Rust package that builds the decodex CLI and runtime.
  • apps/decodex-app/ owns the native macOS app that manages Decodex Codex accounts through the bundled Rust app helper.
  • site/ owns the Astro static product site and app download entry.
  • plugins/decodex/ owns Decodex lifecycle skills.
  • plugins/knowledge/ owns docs, OKF/LLM Wiki, semantic drift, and repo-memory skills.
  • plugins/repo-work/ owns reusable repository command, task-runner, review, verification, debugging, and dependency-policy skills.
  • plugins/agent-method/ owns generic challenge/skeptic review.
  • docs/ remains the authoritative documentation surface.

Runtime authority stays in apps/decodex/src/, the registered project contracts under ~/.codex/decodex/projects/<service-id>/, and the governing specs under docs/spec/. Public site authority stays in site/ and the site specs.

Runtime platform support

  • The Decodex runtime contract is Unix-only: macOS and Linux.
  • Windows is outside the runtime contract.
  • Current Codex/app-server compatibility is capability-gated and recorded in docs/spec/app-server.md.
  • The public site is static and deploys through GitHub Pages.
  • Starting decodex serve without its --config option schedules enabled projects from the explicit registry only. Operator and App snapshots still expose active runtime DB-backed attempts for disabled projects, because disabling a project pauses future dispatch rather than deleting visibility or ownership. It does not scan Codex history, repo-local config files, or currently open worktrees to infer projects.

Usage

Runtime CLI

Use:

decodex --help
decodex app
decodex probe stdio://
decodex project list
decodex status
decodex status --live
decodex diagnose --json
decodex maintenance prune --dry-run
decodex lane steer <ISSUE> --run-id <RUN_ID> --expected-turn-id <TURN_ID> --message <TEXT>
decodex research compile --intent "research X"
decodex research compile --input research-design-run.json
decodex research promote <CONTRACT_ID>
decodex intake goal --project decodex <CONTRACT_ID> --dry-run
decodex intake goal --project decodex <CONTRACT_ID> --apply
decodex intake issues --project decodex XY-1 XY-2 --dry-run
decodex intake issues --project decodex XY-1 XY-2 --apply
decodex mcp serve --transport stdio
decodex mcp serve --transport streamable-http --listen-address 127.0.0.1:8193
decodex run --dry-run
decodex serve --listen-address 127.0.0.1:8192

Project-scoped commands accept --config <PROJECT_DIR> after the subcommand when the operator wants to override registry-based project resolution for that command. decodex status first tries to reuse the default local operator listener's published GET /api/operator-snapshot when the snapshot is recent, covers the requested project, and has at least the requested --limit. JSON output marks this as "status_source": "operator_snapshot_cache" and includes snapshot_age_seconds. If that cache is missing, stale, mismatched, or too small, the command falls back to a direct local runtime snapshot and reports status_cached_snapshot_unavailable in warning_details. Use decodex status --live when the operator needs fresh Linear/GitHub readback before acting; --live bypasses the cached snapshot path and marks JSON output as "status_source": "live_observers". Use the Accounts API refresh path, such as GET /api/accounts?refresh=1, when the operator needs fresh ChatGPT account usage probes. decodex serve uses hardcoded scheduler cadences: the local control-plane loop publishes snapshots every 15 seconds, and Linear-backed queue/status scans run at most every 5 minutes per project unless an operator or agent requests an explicit scan with POST /api/linear-scan. Persisted Execution Programs do not wait for that ordinary queue-label scan: the runtime keeps the Program graph in local state, refreshes only the mapped Linear issue facts needed for readiness, and directly dispatches ready DAG nodes with program dispatch mode.

decodex research compile is the native Decodex research/design entrypoint. It accepts minimal natural-language intake or a structured research/design JSON packet, then persists a contract-first decodex.decision_contract/1 payload in local runtime SQLite. The Decodex research method frames the question first, records an evidence ledger, compares realistic options, forms a challenge-ready judgment, resolves challenge objections, and then ends as decision_ready, not_decision_ready, blocked, or needs_human_decision. New Decodex research may use docs/research/ only for Markdown OKF research concepts; checked-in research JSON event logs are no longer a valid docs shape. A compiled contract is latent and cannot queue work, mutate tracker state, set goals, or authorize implementation. decodex research promote records explicit acceptance for a stored contract; only promoted contracts may later feed issue shaping or internal Execution Program readiness.

decodex intake goal materializes a promoted Decision Contract. --dry-run prints the proposed normal Linear issues, dependencies, conflict domains, and dispatch plan without mutating Linear or local Program Intake rows. --apply creates or updates the generated normal Linear issue briefs and persists the internal Execution Program plus contract/program links in runtime SQLite. Apply does not run implementation or apply queue labels; the persisted Program becomes eligible for direct graph dispatch on the next scheduler pass. If the contract is still latent, needs a decision, or lacks issue-shaping authority, intake stops before creating executable work.

decodex intake issues materializes a supplied batch of existing Linear issues into local Program Intake state. --dry-run prints the deterministic ready/held/blocked report without mutation. --apply persists the local Program Intake Plan, Execution Program, and issue mappings. It never applies or removes service queue labels; ready mapped nodes are dispatched directly by the Program scheduler instead of being converted into queued-label work.

decodex mcp serve --transport stdio starts the local MCP gateway for desktop and CLI clients. decodex mcp serve --transport streamable-http serves the same gateway over the Streamable HTTP POST /mcp endpoint, bound to 127.0.0.1:8193 by default for operator-chosen local, tunnel, or relay access. Streamable HTTP validates browser Origin headers against loopback or repeated --allow-origin <ORIGIN> values, issues Mcp-Session-Id response headers on initialize, requires a known session for later requests, returns ordinary JSON-RPC JSON responses, and switches to text/event-stream framing when the client sends Accept: text/event-stream. The session header is protocol state, not authorization. --allow-origin is CORS trust, not authentication. Use --bearer-token-env <ENV_VAR> when a Streamable HTTP listener is reachable beyond loopback or when exposing any profile above observe; Decodex validates Authorization: Bearer <token> for POST and DELETE while still allowing unauthenticated CORS preflight. Direct non-loopback listeners require both --allow-origin and --bearer-token-env. The built-in bearer guard is Decodex's minimum direct-listener boundary, not OAuth Protected Resource Metadata; OAuth or a managed relay can still sit in front for broader MCP client interoperability. The gateway advertises resources, resource templates, prompts, tools, logging compatibility, and progress notifications. Resources expose checked-in documentation, checked-in Markdown research concepts, runtime Decision Contract readback, local status snapshots, remote-safe live status/activity projections, current/recent status-window run event/protocol/child-agent activity/progress diagnostics, PR/review-state readback, lane-inspect aliases, and lane-control readback. The tool catalog is schema-bound and deliberately small. Local stdio defaults to the admin capability profile; Streamable HTTP defaults to observe. Both can be set with --capability-profile observe|plan|operate|admin; tools/list filters by the active profile and tools/call returns structured refusals for tools above it. Observe is read-only. Plan exposes research_compile, research_promote, and intake_goal: dry-run modes validate or preview without tracker or Program Intake mutation, while apply/promote modes require explicit authority fields and return structured refusals when authority or project context is missing. Operate exposes decodex_lane_control as an inspect-first lane-control facade: inspect returns current preconditions, steer and interrupt delegate through existing lane-control guards only with current run/turn authority, and manual_attention or retained_resume refuse back to their canonical tracker/runtime paths. Admin exposes decodex_project_control for project status plus future-dispatch-only pause/resume with explicit authority; scan refuses to the operator control loop. Stdio stdout is reserved for MCP JSON-RPC messages; diagnostics and logs stay off stdout.

Project contracts

Project contracts are managed outside checkouts under ~/.codex/decodex/projects/<service-id>/ with fixed filenames:

  • project.toml for service paths and credential environment-variable names
  • WORKFLOW.md for execution policy

The redacted template for a project config lives at decodex.example.toml. Phase-scoped app-server goals are mandatory for retained lane execution. Decodex rejects a connected Codex app-server that lacks required thread/goal/* methods instead of falling back to ordinary continuation. When a project enables [codex.accounts], the shared ChatGPT account pool is ~/.codex/decodex/accounts.jsonl; it is global Decodex state, not a project-local file, and project configs do not own an account-pool path override. Set [codex.accounts].fixed_account in ~/.codex/decodex/config.toml to pin all new account-pool runs to one account. When that global selector is absent, Decodex balances new runs across the pool. The operator dashboard Accounts UI writes and clears the same global selector; project configs do not pin specific accounts. Account display-name rerolls are also global Decodex state under [codex.account_names.offsets] in ~/.codex/decodex/config.toml so the operator dashboard and Decodex App show the same privacy-preserving names. Client-only presentation preferences such as theme, sorting, and whether identities are hidden remain local to each UI. Usage probes also read Codex profile token stats for local Accounts displays. Bounded seven-day account usage estimates are kept in ~/.codex/decodex/account-usage-history.jsonl; the file stores daily percentage snapshots plus non-secret capacity weights for local display and no token material. Refresh authentication failures mark the account auth_failed in accounts.jsonl; Decodex will not select or manually activate that account again until it is re-logged or replaced. To switch the account used by the Codex CLI itself, run decodex account use <selector> or use the Decodex App row action; this overwrites $CODEX_HOME/auth.json or ~/.codex/auth.json from the matching accounts.jsonl entry. Later account-pool token refreshes also update that Codex auth target when it currently contains the same account id.

decodex diagnose --json writes the local agent evidence index under ~/.codex/decodex/agent-evidence/<service-id>/ and prints the same handoff index for repair agents.

decodex maintenance prune defaults to the same read-only report as decodex maintenance prune --dry-run. Add --apply to rotate oversized local logs and agent-evidence event streams, prune old backup files, delete legacy Git askpass helper files older than one day from registered project worktree roots, compact old terminal-run protocol events after preserving their summary, and checkpoint the SQLite WAL. decodex serve also runs the auto-safe subset at startup and periodically while it is polling, including 14-day retention for rotated logs and agent-evidence event streams plus 14-day protocol-event compaction for terminal unowned runs after the compact summary is preserved. If the runtime database is busy or candidate detection fails, serve logs a warning and continues polling.

Static Site

The public site is an Astro static site under site/. It renders the public Decodex product surface and app download entry. External Codex automation owns publication to GitHub Pages.

The public site owns:

  • homepage rendering
  • public static assets
  • appcast download widget
  • Astro build and type-check behavior

The public site does not own:

  • retained-lane scheduling
  • tracker writes
  • local operator state
  • app-server orchestration
  • the operator dashboard served by decodex serve
  • upstream monitoring or public publishing automation

The static-site boundary is recorded in docs/decisions/static-public-site.md. GitHub Pages setup for https://decodex.space, including the external automation boundary, lives in docs/runbook/github-pages-deploy.md.

Operator Dashboard

decodex serve owns the local operator listener. It serves the operator dashboard from GET / and GET /dashboard; published snapshots, current-lane updates, and local dashboard controls flow through the /dashboard/control WebSocket. The HTTP surface is kept to dashboard pages/assets, GET /livez, and the local account-control API used by Decodex App.

For dashboard UI development, use one mock operator dashboard server for both the browser dashboard and Decodex App preview:

node dev/operator-dashboard-mock.mjs --listen-address 127.0.0.1:57399
node dev/operator-dashboard-mock.mjs --listen-address 127.0.0.1:57399 --use-codex-auth

That single mock listener serves GET /dashboard, GET /api/accounts, and the dashboard authority WebSocket at ws://127.0.0.1:57399/dashboard/control. When previewing Decodex App against the mock, point the App at the same base URL with DECODEX_APP_SERVER_URL=http://127.0.0.1:57399; do not start a second mock server for the App. This environment variable is authoritative: when it is set, Decodex App connects only to that server and reports an error instead of falling back to the default 127.0.0.1:8192 runtime.

DECODEX_APP_SERVER_URL=http://127.0.0.1:57399 open -n target/decodex-app/Decodex.app
DECODEX_APP_SERVER_URL=http://127.0.0.1:57399 decodex app \
  --bundle target/decodex-app/Decodex.app --new

Use hidden decodex serve --dev --listen-address <ADDR> only when developing local account/app snapshot APIs against real runtime state while explicitly avoiding scheduler activity. Dev mode deliberately does not register projects, poll Linear, dispatch work, or accept --config. Decodex App's normal fallback server is ordinary decodex serve --listen-address 127.0.0.1:8192; the CLI owns the default scheduler cadences. App launch connects to an existing live default listener instead of starting a duplicate server only when DECODEX_APP_SERVER_URL is unset. decodex app opens the installed Decodex App by default and preserves the caller's environment, including any explicit DECODEX_APP_SERVER_URL override. Use --bundle <APP_BUNDLE> and --new when previewing a staged app. For dashboard and App preview UI work, prefer the single mock server above.

The dashboard semantics and local-vs-external state boundary live in docs/reference/operator-control-plane.md.

Development

Repo-native validation is owned by Makefile.toml.

Runtime checks follow the Decodex task structure:

cargo make check
cargo make fmt
cargo make lint
cargo make lint-fix
cargo make test

Use lint for the read-only lint gate and lint-fix for the canonicalizing lint path used by registered Decodex workflow gates.

Node package type checks and builds are available separately:

cargo make check-node
cargo make build-node

Workspace Layout

The tracked workspace currently keeps:

  • apps/decodex/ as the Rust package that builds the decodex CLI and runtime
  • site/ as the Astro static site for the public Decodex product surface
  • plugins/decodex/ as the canonical installable Decodex plugin source
  • docs/spec/ as the normative runtime, workflow, site, and content contract lane
  • docs/runbook/ as the operator procedures, validation sequences, deployment steps, and maintenance workflow lane
  • docs/reference/ as the current repository and artifact surface map lane
  • docs/decisions/ as the durable design-rationale lane
  • docs/research/ as Markdown OKF research concepts and supporting evidence, not runtime authority
  • dev/ as local development helpers, such as the operator dashboard mock server
  • assets/ as generated Decodex App icon source notes, Icon Composer foreground, generated .icns, and menu bar template assets

Generated or local-only directories such as target/, site/dist/, site/.astro/, .worktrees/, .workspaces/, and .codex/ are not part of the tracked repository structure. For the authoritative layout and ownership map, read docs/reference/workspace-layout.md.

Documentation

  • Product and development overview: this README.md
  • Unified documentation router: docs/index.md
  • Natural-language loop-runtime contract: docs/spec/loop-runtime.md
  • Normative specs: docs/spec/index.md
  • Procedural runbooks: docs/runbook/index.md
  • Current implementation references: docs/reference/index.md
  • Durable design rationale: docs/decisions/index.md
  • Documentation policy and placement rules: docs/policy.md

Support Me

If you find this project helpful and would like to support its development, you can buy me a coffee!

Your support is greatly appreciated and motivates me to keep improving this project.

  • Fiat
  • Crypto
    • Bitcoin
      • bc1pedlrf67ss52md29qqkzr2avma6ghyrt4jx9ecp9457qsl75x247sqcp43c
    • Ethereum
      • 0x3e25247CfF03F99a7D83b28F207112234feE73a6
    • Polkadot
      • 156HGo9setPcU2qhFMVWLkcmtCEGySLwNqa3DaEiYSWtte4Y

Thank you for your support!

Appreciation

We would like to extend our heartfelt gratitude to the following projects and contributors:

  • The Rust community for their continuous support and development of the Rust ecosystem.

Additional Acknowledgements

  • TODO

License

Licensed under GPL-3.0.

About

A signal layer for Codex — tracking updates, shifts, and community feedback.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Generated from hack-ink/vibe-mono