Internal engineering docs
Oxagen Architecture Atlas
What the monorepo is made of and how a request, a run, a governed action and a record move through it. Every figure is either generated from a manifest or cites the source it depicts.
Overview
Oxagen governs agents; it does not run them. Every client surface calls one capability kernel through invoke(), and the kernel is the normal path to the stores.
System context
- The web app and the MCP server each bootstrap the kernel and call
invoke()in their own process. Only the CLI, wrapped agents and HTTP clients reach it throughapps/api. - Counts on this page are read from the tree at build time (package manifests, the storage manifest, the capability manifest, route and function sources). If a number here disagrees with the code, the atlas is stale: run
pnpm docs:architecture.
Workspace
A pnpm + Turborepo monorepo: 10 apps, 42 packages and 1 tool workspaces, one version for all of them.
Dependency graph
- Most depended-on:
config(48),oxagen(24),tenancy(17),database(16),recorder(16),telemetry(15),billing(12),crypto(11). - Deprecated and tool workspaces are listed in the table but left out of the drawing.
Workspaces
| Package | Directory | Kind | Workspace deps | External deps | Description |
|---|---|---|---|---|---|
@oxagen/agent | packages/agent | package | 19 | 7 | — |
@oxagen/ai | packages/ai | package | 6 | 8 | — |
@oxagen/api | apps/api | app | 23 | 8 | — |
@oxagen/app | apps/app | app | 18 | 12 | — |
@oxagen/auth | packages/auth | package | 7 | 7 | — |
@oxagen/billing | packages/billing | package | 8 | 4 | — |
@oxagen/brand | packages/brand | package | 0 | 0 | — |
@oxagen/cli | apps/cli | app | 9 | 5 | Oxagen governance CLI: spend, source tracking, grounding, credentials, and audit (agentic coding lives in the stella CLI) |
@oxagen/codegraph | packages/codegraph | package | 1 | 2 | — |
@oxagen/compliance | packages/compliance | package | 1 | 0 | — |
@oxagen/config | packages/config | package | 0 | 2 | — |
@oxagen/crypto | packages/crypto | package | 1 | 1 | — |
@oxagen/database | packages/database | package | 6 | 3 | — |
@oxagen/desktop | apps/desktop | app | 3 | 6 | The Oxagen desktop app: installs the CLI and the recorder for Claude Code and Codex, signs a machine in to an org, and lets the operator pick or change the workspace the host reports to. Spec: docs/specs/oxagen-desktop/spec.md. |
@oxagen/docs | apps/docs | app | 2 | 10 | — |
@oxagen/functions | packages/functions | package | 1 | 0 | — |
@oxagen/github | packages/github | package | 3 | 1 | — |
@oxagen/gitlab | packages/gitlab | package | 1 | 0 | — |
@oxagen/glob | packages/glob | package | 1 | 0 | — |
@oxagen/handlers | packages/handlers | package | 34 | 16 | — |
@oxagen/iam | packages/iam | package | 6 | 2 | — |
@oxagen/ingestion | packages/ingestion | package | 6 | 3 | — |
@oxagen/inngest-functions | packages/inngest-functions | package | 21 | 7 | — |
@oxagen/mcp | apps/mcp | app | 16 | 15 | — |
@oxagen/mcp-config | packages/mcp-config | package | 1 | 1 | — |
@oxagen/mcp-studio | packages/mcp-studio | package | 4 | 8 | MCP Studio's storage contract, operation model, and the compile, lint, and execute modules a server folder is built and run with (mcp-studio-spec). |
@oxagen/metrics-fleet | packages/metrics-fleet | package | 1 | 0 | — |
@oxagen/mockup | apps/mockup | app | 4 | 8 | — |
@oxagen/notifications | packages/notifications | package | 5 | 4 | — |
@oxagen/ontology | packages/ontology | package | 3 | 1 | — |
@oxagen/oxagen | packages/oxagen | package | 5 | 4 | — |
@oxagen/plugins | packages/plugins | package | 7 | 10 | — |
@oxagen/policy | packages/policy | package | 2 | 2 | Decides every tool call from the Cedar policies in the steering repo, and compiles and tests those policies (lane S12, #4445). |
@oxagen/recorder | packages/tacho | package | 1 | 4 | The Oxagen recorder: records, gates, and evidences the agents Oxagen does not run. The oxagen CLI runs it. Leaf package: no @oxagen/* runtime dependency. |
@oxagen/relay | apps/relay | app | 3 | 2 | — |
@oxagen/relay-broker | packages/relay-broker | package | 5 | 2 | Oxagen's side of the relay for servers and APIs in a private network: the broker, signed calls, tokens, and the relay protocol (mcp-studio-spec, Network paths). |
@oxagen/rules | packages/rules | package | 6 | 4 | — |
@oxagen/run-evidence | packages/run-evidence | package | 1 | 3 | — |
@oxagen/run-ledger | packages/run-ledger | package | 6 | 3 | The run frame shape and the transcript, context and body reads every run reader shares (ADR-5969). |
@oxagen/sandbox-host | apps/sandbox-host | app | 2 | 2 | — |
@oxagen/sandbox-modal | packages/sandbox-modal | package | 2 | 1 | — |
@oxagen/sandbox-provider | packages/sandbox-provider | package | 2 | 1 | — |
@oxagen/scripts | tools/scripts | tool | 14 | 6 | — |
@oxagen/steering-assembler | packages/steering-assembler | package | 2 | 1 | — |
@oxagen/steering-bundle | packages/steering-bundle | package | 7 | 1 | Publishes a merged steering repo as a version (bundle/v1) and renders the steering one model request receives. |
@oxagen/steering-check | packages/steering-check | package | 4 | 1 | The checks a steering pull request runs, as one pure package the server and the CLI share. It does no I/O. |
@oxagen/stella-engine-client | packages/stella-engine-client | package | 1 | 0 | — |
@oxagen/storage | packages/storage | package | 2 | 3 | — |
@oxagen/telemetry | packages/telemetry | package | 4 | 9 | — |
@oxagen/tenancy | packages/tenancy | package | 1 | 0 | — |
@oxagen/uikit | packages/uikit | package | 2 | 40 | — |
@oxagen/web-v2 | apps/web | app | 1 | 0 | Oxagen public website with a React home page and an MDX research library. |
@oxagen/work | packages/work | package | 4 | 2 | The work collector, source, triage, and work-dod schemas, the Phase 1 work records, the triage that drafts and corrects a suggestion, and the work order metrics fold. |
Request path
Identity → tenant scope → capability → row-level security. Nothing reaches a tenant table without the scope GUCs set, except through withSystemDb, which assumes the oxagen_system role, and nothing reaches a handler without passing the kernel's gates.
One org-scoped API request
- A Bearer header wins outright: the session cookie is never consulted, and the key's org scope, and its workspace when it is a workspace key, is copied onto the request. The org slug middleware returns early, and the org slug in the URL is not checked against the key. A workspace key also skips the workspace slug. An organisation key resolves it inside its own org.
- The browser app and the MCP server do not pass through this chain.
apps/appandapps/mcpeach bootstrap the kernel and callinvoke()in their own process. - The three GUCs are set with
set_config(name, value, true), which is transaction-local. No policy readsapp.rls_bypassany more (ADR-5879), so no setting turns RLS off.app.org_wideis'off'here and'on'only inwithOrgDb, or in a savepoint of an open tenant transaction throughwithTransactionOrgWideRead. Either unlocks the SELECT-onlytenant_org_wide_readpolicies. withSystemDbis the deliberate RLS bypass: it runsSET LOCAL ROLE oxagen_system, a NOLOGIN role every RLS table admits through itssystem_accesspolicy, and always runs on the shared plane. The app role may switch tooxagen_systembut does not inherit it, so a tenant transaction never matches that policy.withOrgPlaneSystemDbis the plane-aware variant for system writes to tenant-plane tables. A call made with no active tenant scope increments an in-process counter, written to a debug log line asdb.query.unscoped.
Source refs (11, verified at build)
apps/api/src/middleware/auth.ts#authMiddlewareapps/api/src/middleware/org.ts#orgMiddlewareapps/api/src/middleware/workspace.ts#workspaceMiddlewareapps/api/src/lib/context.ts#capabilityContextpackages/auth/src/resolvers/api-key.ts#resolveApiKeypackages/auth/src/resolvers/session.ts#resolveSessionpackages/tenancy/src/scope.ts#runInTenantScopepackages/database/src/tenant.ts#withTenantDbpackages/database/src/tenant.ts#withOrgPlaneSystemDbpackages/database/src/unscoped-meter.ts#recordIfUnscopedpackages/database/atlas/migrations/20260917120000_org_wide_read_mode.sql
Tenant data planes (ADR-042)
- The decrypted plane config never leaves the resolver except inside a binding handed to a store client; it is never logged, serialised into an error, or returned by a read capability.
- The resolver reads
org.data_planesthroughwithSystemDbon the shared plane, sowithSystemDbitself cannot be plane-aware without a cycle.withOrgPlaneSystemDbresolves the plane first, for system writes to tenant-plane tables.
Source refs (5, verified at build)
packages/tenancy/src/data-plane.ts#resolveDataPlanepackages/database/src/data-plane-resolver.ts#DATA_PLANE_CACHE_TTL_MSpackages/database/src/data-plane-pool.ts#MAX_DEDICATED_POOLSpackages/ontology/src/data-plane-driver.ts#MAX_DEDICATED_DRIVERSpackages/telemetry/src/data-plane-client.ts#MAX_DEDICATED_CLICKHOUSE_CLIENTS
Auth tiers in apps/api
Middleware registered per sub-router in apps/api/src/app.ts, in the order Hono runs it.
| Tier | Middleware chain |
|---|---|
| public | * → requestLogger* → corsMiddleware* → requestAdmission |
| user | * → authMiddleware |
| stella telemetry | * → authMiddleware* → requireDeviceSignature |
| recorder host | * → authMiddleware/bundle → tachoControlLimiter/commands → tachoControlLimiter |
| org+workspace | /chat/* → chatRateLimiter/assistant/ask → chatRateLimiter/assistant/draft → chatRateLimiter/assistant/rewrite → chatRateLimiter/conversation/chat → chatRateLimiter/status/summary → chatRateLimiter/spend/export → chatRateLimiter/assistant/attachments/* → assistantAttachmentRateLimiter/work/attachments/* → workAttachmentRateLimiter |
| org | * → authMiddleware, orgMiddleware, keyOrgScopeMatchesPath |
| Tier | Routes | Prefixes |
|---|---|---|
| org | 9 | /v1/:org_slug/audit · /v1/:org_slug/connections · /v1/:org_slug/join-requests · /v1/:org_slug/onboarding · /v1/:org_slug/workspaces |
| org+workspace | 562 | /v1/:org_slug/:workspace_slug |
| public | 33 | /health · /health/ready · /internal/codegraph/ci-runs · /internal/codegraph/gitlab · /v1/auth/cli · /v1/auth/clirequestId |
| user | 20 | /v1/assets/:publicId · /v1/assetsapiKeyId · /v1/assetsapiKeyScope · /v1/assetsrequestId · /v1/assetssessionAuthMethod · /v1/assetsuserId |
API routes
Each route file declares a relative path; the prefix comes from where app.ts mounts it. The capability column is the contract the route hands to invoke(), and a dash marks a route that invokes none.
| Method | Path | Tier | Capability | Route file |
|---|---|---|---|---|
| POST | /v1/:org_slug/audit/events/export | org | export_audit_events | v1/audit.events.export.ts |
| POST | /v1/:org_slug/connections/steering/gitlab | org | — | v1/gitlab-oauth.ts |
| GET | /v1/:org_slug/connections/steeringorgId | org | — | v1/gitlab-oauth.ts |
| GET | /v1/:org_slug/connections/steeringrequestId | org | — | v1/gitlab-oauth.ts |
| GET | /v1/:org_slug/connections/steeringuserId | org | — | v1/gitlab-oauth.ts |
| POST | /v1/:org_slug/join-requests | org | request_to_join_workspace | v1/workspace.join_request.create.ts |
| GET | /v1/:org_slug/join-requests/mine | org | get_my_join_request | v1/workspace.join_request.mine.ts |
| POST | /v1/:org_slug/onboarding/state | org | get_onboarding_state | v1/onboarding.state.get.ts |
| POST | /v1/:org_slug/workspaces | org | create_workspace | v1/workspace.create.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/approvals/list | org+workspace | list_approvals | v1/agent.approval.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/approvals/resolve | org+workspace | resolve_approval | v1/agent.approval.resolve.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/approvals/resolved | org+workspace | list_resolved_approvals | v1/agent.approval.list_resolved.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/attention/list | org+workspace | list_attention | v1/agent.attention.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/fleet/list | org+workspace | list_fleet | v1/agent.fleet.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/interjections/answer | org+workspace | answer_interjection | v1/agent.interjection.answer.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/interjections/draft | org+workspace | draft_interjection_answer | v1/agent.interjection.draft.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/interjections/list | org+workspace | list_interjections | v1/agent.interjection.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/interjections/reopen | org+workspace | reopen_interjection | v1/agent.interjection.reopen.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/mcp-consents | org+workspace | list_mcp_consents | v1/agent.mcp_consent.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/mcp-consents/resolve | org+workspace | resolve_mcp_consent | v1/agent.mcp_consent.resolve.ts |
| GET | /v1/:org_slug/:workspace_slug/agent/mcp-registry | org+workspace | search_mcp_registry | v1/agent.mcp.registry.search.ts |
| GET | /v1/:org_slug/:workspace_slug/agent/mcp-servers | org+workspace | list_mcp_servers | v1/agent.mcp.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/mcp-servers | org+workspace | register_mcp_server | v1/agent.mcp.register.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/mcp-servers/delete | org+workspace | delete_mcp_server | v1/agent.mcp.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/mcp-servers/set-enabled | org+workspace | set_mcp_enabled | v1/agent.mcp.set_enabled.ts |
| GET | /v1/:org_slug/:workspace_slug/agent/roles | org+workspace | list_agent_roles | v1/agent.role.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/roles/assign | org+workspace | assign_agent_role | v1/agent.role.assign.ts |
| GET | /v1/:org_slug/:workspace_slug/agent/roles/get | org+workspace | get_agent_role | v1/agent.role.get.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/roles/revoke | org+workspace | revoke_agent_role | v1/agent.role.revoke.ts |
| POST | /v1/:org_slug/:workspace_slug/agent/tools | org+workspace | list_agent_tools | v1/agent.tool.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agents | org+workspace | list_agents | v1/agent.list.ts |
| GET | /v1/:org_slug/:workspace_slug/agents/:agentId/run-accounts | org+workspace | list_run_accounts | v1/run-accounts.list.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/account-source/set | org+workspace | set_agent_account_source | v1/agent.account_source.set.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/budget/set | org+workspace | set_agent_budget | v1/agent.budget.set.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/cache-keep-alive/set | org+workspace | set_agent_cache_keep_alive | v1/agent.cache_keep_alive.set.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/credential/rotate | org+workspace | rotate_agent_credential | v1/agent.credential.rotate.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/display-name/set | org+workspace | set_agent_display_name | v1/agent.display_name.set.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/draft/cancel | org+workspace | cancel_agent_draft | v1/agent.draft.cancel.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/draft/finish | org+workspace | finish_agent_draft | v1/agent.draft.finish.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/draft/get | org+workspace | get_agent_draft | v1/agent.draft.get.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/draft/save | org+workspace | save_agent_draft | v1/agent.draft.save.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/get | org+workspace | get_agent | v1/agent.get.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/move | org+workspace | move_agent | v1/agent.move.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/register | org+workspace | register_agent | v1/agent.register.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/retire | org+workspace | retire_agent | v1/agent.retire.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/suspend | org+workspace | suspend_agent | v1/agent.suspend.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/toolbelt | org+workspace | get_agent_toolbelt | v1/agent.toolbelt.get.ts |
| POST | /v1/:org_slug/:workspace_slug/agents/toolbelt/assign | org+workspace | assign_agent_toolbelt | v1/agent.toolbelt.assign.ts |
| GET | /v1/:org_slug/:workspace_slug/api-keys | org+workspace | list_api_keys | v1/api.key.list.ts |
| POST | /v1/:org_slug/:workspace_slug/api-keys | org+workspace | create_api_key | v1/api.key.create.ts |
| DELETE | /v1/:org_slug/:workspace_slug/api-keys/revoke | org+workspace | revoke_api_key | v1/api.key.revoke.ts |
| POST | /v1/:org_slug/:workspace_slug/api-keys/rotate | org+workspace | rotate_api_key | v1/api.key.rotate.ts |
| POST | /v1/:org_slug/:workspace_slug/api-keys/rotate/acknowledge | org+workspace | acknowledge_api_key_rotation | v1/api.key.rotation.acknowledge.ts |
| POST | /v1/:org_slug/:workspace_slug/approval-rules/delete | org+workspace | delete_approval_rule | v1/approval_rule.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/approval-rules/enabled/set | org+workspace | set_approval_rule_enabled | v1/approval_rule.enabled.set.ts |
| POST | /v1/:org_slug/:workspace_slug/approval-rules/list | org+workspace | list_approval_rules | v1/approval_rule.list.ts |
| POST | /v1/:org_slug/:workspace_slug/approval-rules/set | org+workspace | set_approval_rules | v1/approval_rule.set.ts |
| POST | /v1/:org_slug/:workspace_slug/approvals/auto-eligibility | org+workspace | get_auto_eligibility | v1/approval.auto_eligibility.get.ts |
| POST | /v1/:org_slug/:workspace_slug/asset/upload | org+workspace | upload_asset | v1/asset.upload.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/ask | org+workspace | ask_assistant | v1/assistant.ask.ts |
| GET | /v1/:org_slug/:workspace_slug/assistant/attachments/:publicId | org+workspace | — | v1/assistant.attachment.get.ts |
| GET | /v1/:org_slug/:workspace_slug/assistant/attachmentsapiKeyId | org+workspace | — | v1/assistant.attachment.get.ts |
| GET | /v1/:org_slug/:workspace_slug/assistant/attachmentsapiKeyScope | org+workspace | — | v1/assistant.attachment.get.ts |
| GET | /v1/:org_slug/:workspace_slug/assistant/attachmentsrequestId | org+workspace | — | v1/assistant.attachment.get.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/briefing | org+workspace | get_briefing | v1/assistant.briefing.get.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/cards/resolve | org+workspace | resolve_assistant_card | v1/assistant.card.resolve.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/draft | org+workspace | draft_record | v1/assistant.record.draft.ts |
| GET | /v1/:org_slug/:workspace_slug/assistant/engine | org+workspace | get_assistant_engine | v1/assistant.engine.get.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/feedback | org+workspace | record_reply_feedback | v1/assistant.reply_feedback.record.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/question/answer | org+workspace | answer_assistant_question | v1/assistant.question.answer.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/reply | org+workspace | get_assistant_reply | v1/assistant.reply.get.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/rewrite | org+workspace | rewrite_field | v1/assistant.field.rewrite.ts |
| POST | /v1/:org_slug/:workspace_slug/assistant/turn/cancel | org+workspace | cancel_assistant_turn | v1/assistant.turn.cancel.ts |
| POST | /v1/:org_slug/:workspace_slug/audit/events/export | org+workspace | export_audit_events | v1/audit.events.export.ts |
| POST | /v1/:org_slug/:workspace_slug/audit/log/query | org+workspace | query_audit_log | v1/audit.log.query.ts |
| GET | /v1/:org_slug/:workspace_slug/billing/actions/estimate | org+workspace | preview_action_cost | v1/billing.action_estimate.ts |
| GET | /v1/:org_slug/:workspace_slug/billing/actions/rate-card | org+workspace | get_rate_card | v1/billing.action_rate_card.ts |
| GET | /v1/:org_slug/:workspace_slug/billing/budget | org+workspace | get_spend_budget | v1/billing.budget.get.ts |
| PUT | /v1/:org_slug/:workspace_slug/billing/budget | org+workspace | set_spend_budget | v1/billing.budget.set.ts |
| GET | /v1/:org_slug/:workspace_slug/billing/contract-rate | org+workspace | get_contract_rate | v1/billing.contract_rate.get.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/credits/purchase | org+workspace | purchase_credits | v1/billing.credits.purchase.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/credits/refund | org+workspace | refund_credits | v1/billing.credits.refund.ts |
| GET | /v1/:org_slug/:workspace_slug/billing/evidence/retention | org+workspace | get_evidence_retention | v1/billing.evidence_retention.ts |
| GET | /v1/:org_slug/:workspace_slug/billing/gau-bucket | org+workspace | get_gau_bucket | v1/billing.gau_bucket.get.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/gau-bucket/purchase | org+workspace | purchase_gau_bucket | v1/billing.gau_bucket.purchase.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/invoices | org+workspace | list_invoices | v1/billing.invoice.list.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/portal | org+workspace | open_billing_portal | v1/billing.portal_session.create.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/prepaid-orders | org+workspace | list_prepaid_orders | v1/billing.prepaid_order.list.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/sandbox-slots | org+workspace | set_sandbox_slots | v1/billing.sandbox_slots.set.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/statement | org+workspace | get_billing_statement | v1/billing.statement.get.ts |
| POST | /v1/:org_slug/:workspace_slug/billing/statement/export | org+workspace | export_billing_statement | v1/billing.statement.export.ts |
| GET | /v1/:org_slug/:workspace_slug/billing/subscription | org+workspace | get_subscription | v1/billing.subscription.read.ts |
| GET | /v1/:org_slug/:workspace_slug/billing/usage/breakdown | org+workspace | get_usage_breakdown | v1/billing.usage.breakdown.ts |
| GET | /v1/:org_slug/:workspace_slug/capability/registry/get | org+workspace | get_capability_registry | v1/capability.registry.get.ts |
| GET | /v1/:org_slug/:workspace_slug/capability/registry/list | org+workspace | list_capability_registry | v1/capability.registry.list.ts |
| POST | /v1/:org_slug/:workspace_slug/chat/messages | org+workspace | send_message | v1/chat.message.send.ts |
| POST | /v1/:org_slug/:workspace_slug/chat/stream | org+workspace | — | v1/chat.stream.ts |
| GET | /v1/:org_slug/:workspace_slug/chat/streamrequestId | org+workspace | ask_assistant | v1/chat.stream.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/check_change | org+workspace | check_change | v1/codegraph.check_change.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/create_work_items | org+workspace | create_work_items | v1/codegraph.create_work_items.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/find_definition | org+workspace | find_definition | v1/codegraph.find_definition.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/find_references | org+workspace | find_references | v1/codegraph.find_references.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/get_api_docs | org+workspace | get_api_docs | v1/codegraph.get_api_docs.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/get_blast_radius | org+workspace | get_blast_radius | v1/codegraph.get_blast_radius.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/get_domain_brief | org+workspace | get_domain_brief | v1/codegraph.get_domain_brief.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/get_env_vars | org+workspace | get_env_vars | v1/codegraph.get_env_vars.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/get_infra | org+workspace | get_infra | v1/codegraph.get_infra.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/get_repo_map | org+workspace | get_repo_map | v1/codegraph.get_repo_map.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/label_link | org+workspace | label_link | v1/codegraph.label_link.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/list_ci_jobs | org+workspace | list_ci_jobs | v1/codegraph.list_ci_jobs.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/list_co_changes | org+workspace | list_co_changes | v1/codegraph.list_co_changes.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/list_link_labels | org+workspace | list_link_labels | v1/codegraph.list_link_labels.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/list_link_reviews | org+workspace | list_link_reviews | v1/codegraph.list_link_reviews.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/list_neighbors | org+workspace | list_neighbors | v1/codegraph.list_neighbors.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/list_scripts | org+workspace | list_scripts | v1/codegraph.list_scripts.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/list_symbol_docs | org+workspace | list_symbol_docs | v1/codegraph.list_symbol_docs.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/list_unit_tests | org+workspace | list_unit_tests | v1/codegraph.list_unit_tests.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/localize_fault | org+workspace | localize_fault | v1/codegraph.localize_fault.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/propose_edge | org+workspace | propose_edge | v1/codegraph.propose_edge.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/rank_symbols | org+workspace | rank_symbols | v1/codegraph.rank_symbols.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/review_domain | org+workspace | review_domain | v1/codegraph.review_domain.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/review_link | org+workspace | review_link | v1/codegraph.review_link.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/search_code_graph | org+workspace | search_code_graph | v1/codegraph.search_code_graph.ts |
| POST | /v1/:org_slug/:workspace_slug/codegraph/trace_spec | org+workspace | trace_spec | v1/codegraph.trace_spec.ts |
| POST | /v1/:org_slug/:workspace_slug/command/menu/search | org+workspace | search_command_menu | v1/command.menu.search.ts |
| POST | /v1/:org_slug/:workspace_slug/command/menu/suggest | org+workspace | suggest_commands | v1/command.menu.suggest.ts |
| POST | /v1/:org_slug/:workspace_slug/commands | org+workspace | dispatch_command | v1/tacho.command.dispatch.ts |
| POST | /v1/:org_slug/:workspace_slug/commands/list | org+workspace | list_commands | v1/tacho.command.list.ts |
| POST | /v1/:org_slug/:workspace_slug/commands/pause-workspace | org+workspace | pause_workspace_runs | v1/tacho.workspace_runs.pause.ts |
| POST | /v1/:org_slug/:workspace_slug/commits/diff | org+workspace | get_commit_diff | v1/forge.commit.diff.get.ts |
| POST | /v1/:org_slug/:workspace_slug/configurations/clone | org+workspace | get_clone_draft | v1/configuration.clone.get.ts |
| GET | /v1/:org_slug/:workspace_slug/connections | org+workspace | list_connections | v1/connection.ts |
| POST | /v1/:org_slug/:workspace_slug/connections | org+workspace | create_connection | v1/connection.ts |
| DELETE | /v1/:org_slug/:workspace_slug/connections/:id | org+workspace | delete_connection | v1/connection.ts |
| GET | /v1/:org_slug/:workspace_slug/connections/:id | org+workspace | get_connection | v1/connection.ts |
| PATCH | /v1/:org_slug/:workspace_slug/connections/:id | org+workspace | update_connection | v1/connection.ts |
| GET | /v1/:org_slug/:workspace_slug/connections/:id/mappings | org+workspace | get_connection_mappings | v1/connection.ts |
| PUT | /v1/:org_slug/:workspace_slug/connections/:id/mappings | org+workspace | set_connection_mappings | v1/connection.ts |
| POST | /v1/:org_slug/:workspace_slug/connections/:id/pause | org+workspace | pause_connection | v1/connection.ts |
| GET | /v1/:org_slug/:workspace_slug/connections/:id/preview | org+workspace | preview_connection | v1/connection.ts |
| POST | /v1/:org_slug/:workspace_slug/connections/:id/resync | org+workspace | sync_integration | v1/connection.ts |
| POST | /v1/:org_slug/:workspace_slug/connections/:id/suggest-mappings | org+workspace | suggest_connection_mappings | v1/connection.ts |
| POST | /v1/:org_slug/:workspace_slug/connections/trackers/authorization/complete | org+workspace | authorize_connection | v1/connection.authorization.ts |
| POST | /v1/:org_slug/:workspace_slug/connections/trackers/authorization/start | org+workspace | start_connection_authorization | v1/connection.authorization.ts |
| POST | /v1/:org_slug/:workspace_slug/connections/trackers/token | org+workspace | add_token_connection | v1/connection.authorization.ts |
| POST | /v1/:org_slug/:workspace_slug/context/governance-mode | org+workspace | set_governance_mode | v1/context.governance_mode.set.ts |
| POST | /v1/:org_slug/:workspace_slug/context/steering/deliveries | org+workspace | get_steering_deliveries | v1/context.steering.deliveries.ts |
| GET | /v1/:org_slug/:workspace_slug/context/steering/index | org+workspace | get_steering_index | v1/context.steering.index.get.ts |
| POST | /v1/:org_slug/:workspace_slug/context/steering/layout | org+workspace | get_steering_layout | v1/context.steering.layout.ts |
| POST | /v1/:org_slug/:workspace_slug/context/steering/memories/get | org+workspace | get_workspace_memory | v1/steering.memories.get.ts |
| POST | /v1/:org_slug/:workspace_slug/context/steering/memories/list | org+workspace | list_workspace_memories | v1/steering.memories.list.ts |
| GET | /v1/:org_slug/:workspace_slug/context/steering/repo | org+workspace | get_steering_repo | v1/steering_repo.get.ts |
| POST | /v1/:org_slug/:workspace_slug/context/steering/repo/import | org+workspace | import_workspace_steering | v1/steering_repo.import.ts |
| POST | /v1/:org_slug/:workspace_slug/context/steering/repo/repair | org+workspace | repair_steering_repo | v1/steering_repo.repair.ts |
| POST | /v1/:org_slug/:workspace_slug/context/steering/sync-state | org+workspace | get_steering_sync_state | v1/context.steering.sync_state.ts |
| POST | /v1/:org_slug/:workspace_slug/conversation/chat | org+workspace | post_conversation_message | v1/conversation.chat.ts |
| GET | /v1/:org_slug/:workspace_slug/conversations | org+workspace | list_conversations | v1/conversation.list.ts |
| GET | /v1/:org_slug/:workspace_slug/conversations/:conversationId | org+workspace | get_conversation | v1/conversation.get.ts |
| GET | /v1/:org_slug/:workspace_slug/conversations/:conversationId/export | org+workspace | export_conversation | v1/conversation.export.ts |
| GET | /v1/:org_slug/:workspace_slug/conversations/:conversationId/files | org+workspace | list_conversation_files | v1/conversation.files.list.ts |
| POST | /v1/:org_slug/:workspace_slug/conversations/archive | org+workspace | archive_conversation | v1/conversation.archive.ts |
| POST | /v1/:org_slug/:workspace_slug/conversations/attachments | org+workspace | add_conversation_attachment | v1/conversation.attachment.add.ts |
| POST | /v1/:org_slug/:workspace_slug/conversations/clear | org+workspace | clear_conversation | v1/conversation.clear.ts |
| POST | /v1/:org_slug/:workspace_slug/conversations/delete | org+workspace | delete_conversation | v1/conversation.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/conversations/fork | org+workspace | fork_conversation | v1/conversation.fork.ts |
| POST | /v1/:org_slug/:workspace_slug/conversations/purge | org+workspace | purge_conversations | v1/conversation.purge.ts |
| PATCH | /v1/:org_slug/:workspace_slug/conversations/rename | org+workspace | rename_conversation | v1/conversation.rename.ts |
| POST | /v1/:org_slug/:workspace_slug/cost/price-entries | org+workspace | list_price_entries | v1/cost.price_entry.list.ts |
| POST | /v1/:org_slug/:workspace_slug/cost/price-entries/remove | org+workspace | remove_price_entry | v1/cost.price_entry.remove.ts |
| POST | /v1/:org_slug/:workspace_slug/cost/price-entries/set | org+workspace | set_price_entry | v1/cost.price_entry.set.ts |
| POST | /v1/:org_slug/:workspace_slug/cost/unpriced-models | org+workspace | list_unpriced_models | v1/cost.unpriced_model.list.ts |
| POST | /v1/:org_slug/:workspace_slug/credential-grants | org+workspace | list_credential_grants | v1/credential.grant.list.ts |
| POST | /v1/:org_slug/:workspace_slug/enrollment-requests | org+workspace | get_enrollment_request | v1/enrollment.request.get.ts |
| POST | /v1/:org_slug/:workspace_slug/environment/create | org+workspace | create_environment | v1/environment.create.ts |
| POST | /v1/:org_slug/:workspace_slug/environment/delete | org+workspace | delete_environment | v1/environment.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/environment/get | org+workspace | get_environment | v1/environment.get.ts |
| POST | /v1/:org_slug/:workspace_slug/environment/list | org+workspace | list_environments | v1/environment.list.ts |
| POST | /v1/:org_slug/:workspace_slug/environment/set-default | org+workspace | set_default_environment | v1/environment.set_default.ts |
| POST | /v1/:org_slug/:workspace_slug/environment/update | org+workspace | update_environment | v1/environment.update.ts |
| POST | /v1/:org_slug/:workspace_slug/forge/change-effort | org+workspace | get_change_effort | v1/forge.change_effort.get.ts |
| POST | /v1/:org_slug/:workspace_slug/forge/ci-runs | org+workspace | list_ci_runs | v1/forge.ci_runs.list.ts |
| POST | /v1/:org_slug/:workspace_slug/forge/defect-origin | org+workspace | set_defect_origin | v1/forge.defect_origin.set.ts |
| POST | /v1/:org_slug/:workspace_slug/forge/defects | org+workspace | list_defects | v1/forge.defects.list.ts |
| POST | /v1/:org_slug/:workspace_slug/forge/pull-requests | org+workspace | list_forge_pull_requests | v1/forge.pull_requests.list.ts |
| POST | /v1/:org_slug/:workspace_slug/forge/review-findings | org+workspace | list_review_findings | v1/forge.review_findings.list.ts |
| GET | /v1/:org_slug/:workspace_slug/graph/node/get/:nodeId | org+workspace | get_node | v1/graph.node.get.ts |
| POST | /v1/:org_slug/:workspace_slug/graph/node/search | org+workspace | search_nodes | v1/graph.node.search.ts |
| GET | /v1/:org_slug/:workspace_slug/graph/nodes | org+workspace | list_nodes | v1/graph.node.list.ts |
| POST | /v1/:org_slug/:workspace_slug/graph/rule/author | org+workspace | author_graph_rule | v1/graph.rule.author.ts |
| POST | /v1/:org_slug/:workspace_slug/graph/search | org+workspace | search_graph | v1/graph.search.ts |
| GET | /v1/:org_slug/:workspace_slug/graph/stats | org+workspace | get_graph_stats | v1/graph.stats.ts |
| POST | /v1/:org_slug/:workspace_slug/iam/roles | org+workspace | create_role | v1/iam.role.create.ts |
| POST | /v1/:org_slug/:workspace_slug/iam/roles/assign | org+workspace | assign_member_role | v1/iam.role.member.assign.ts |
| POST | /v1/:org_slug/:workspace_slug/iam/roles/delete | org+workspace | delete_role | v1/iam.role.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/iam/roles/grants | org+workspace | set_role_grants | v1/iam.role.grants.set.ts |
| GET | /v1/:org_slug/:workspace_slug/iam/roles/list | org+workspace | list_iam_roles | v1/iam.role.list.ts |
| POST | /v1/:org_slug/:workspace_slug/iam/roles/unassign | org+workspace | unassign_member_role | v1/iam.role.member.unassign.ts |
| GET | /v1/:org_slug/:workspace_slug/integrations | org+workspace | list_integrations | v1/integration.ts |
| POST | /v1/:org_slug/:workspace_slug/integrations | org+workspace | install_integration | v1/integration.ts |
| DELETE | /v1/:org_slug/:workspace_slug/integrations/:id | org+workspace | delete_integration | v1/integration.ts |
| GET | /v1/:org_slug/:workspace_slug/integrations/:id | org+workspace | get_integration | v1/integration.ts |
| PATCH | /v1/:org_slug/:workspace_slug/integrations/:id/configure | org+workspace | configure_integration | v1/integration.ts |
| GET | /v1/:org_slug/:workspace_slug/integrations/:id/metrics | org+workspace | get_integration_metrics | v1/integration.ts |
| POST | /v1/:org_slug/:workspace_slug/integrations/:id/sync | org+workspace | sync_integration | v1/integration.ts |
| PUT | /v1/:org_slug/:workspace_slug/kill-switches | org+workspace | set_kill_switch | v1/kill_switch.set.ts |
| POST | /v1/:org_slug/:workspace_slug/kill-switches/list | org+workspace | list_kill_switches | v1/kill_switch.list.ts |
| POST | /v1/:org_slug/:workspace_slug/kinds/archive | org+workspace | archive_kind | v1/kind.archive.ts |
| POST | /v1/:org_slug/:workspace_slug/kinds/delete | org+workspace | delete_kind | v1/kind.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/kinds/draft | org+workspace | draft_kind | v1/kind.draft.ts |
| POST | /v1/:org_slug/:workspace_slug/kinds/list | org+workspace | list_kinds | v1/kinds.list.ts |
| POST | /v1/:org_slug/:workspace_slug/kinds/restore | org+workspace | restore_kind | v1/kind.restore.ts |
| POST | /v1/:org_slug/:workspace_slug/kinds/save | org+workspace | save_kind | v1/kind.save.ts |
| POST | /v1/:org_slug/:workspace_slug/machines/register | org+workspace | register_machine | v1/machine.register.ts |
| POST | /v1/:org_slug/:workspace_slug/mandates/get | org+workspace | get_mandate | v1/mandate.get.ts |
| POST | /v1/:org_slug/:workspace_slug/mandates/grant | org+workspace | grant_mandate | v1/mandate.grant.ts |
| POST | /v1/:org_slug/:workspace_slug/mandates/limits/update | org+workspace | update_mandate_limits | v1/mandate.limits.update.ts |
| POST | /v1/:org_slug/:workspace_slug/mandates/list | org+workspace | list_mandates | v1/mandate.list.ts |
| POST | /v1/:org_slug/:workspace_slug/mandates/request | org+workspace | request_mandate | v1/mandate.request.ts |
| POST | /v1/:org_slug/:workspace_slug/mandates/revoke | org+workspace | revoke_mandate | v1/mandate.revoke.ts |
| POST | /v1/:org_slug/:workspace_slug/modal-account | org+workspace | get_modal_account | v1/modal-account.get.ts |
| POST | /v1/:org_slug/:workspace_slug/modal-account/connect | org+workspace | connect_modal_account | v1/modal-account.connect.ts |
| POST | /v1/:org_slug/:workspace_slug/modal-account/disconnect | org+workspace | disconnect_modal_account | v1/modal-account.disconnect.ts |
| POST | /v1/:org_slug/:workspace_slug/model-tiers | org+workspace | list_model_tiers | v1/model_tier.list.ts |
| POST | /v1/:org_slug/:workspace_slug/model-tiers/archive | org+workspace | archive_model_tier | v1/model_tier.archive.ts |
| POST | /v1/:org_slug/:workspace_slug/model-tiers/create | org+workspace | create_model_tier | v1/model_tier.create.ts |
| POST | /v1/:org_slug/:workspace_slug/model-tiers/models/set | org+workspace | set_model_tier_model | v1/model_tier.model.set.ts |
| POST | /v1/:org_slug/:workspace_slug/model-tiers/update | org+workspace | update_model_tier | v1/model_tier.update.ts |
| GET | /v1/:org_slug/:workspace_slug/model/capabilities | org+workspace | list_model_capabilities | v1/model.capability.list.ts |
| GET | /v1/:org_slug/:workspace_slug/notifications | org+workspace | list_notifications | v1/notification.list.ts |
| POST | /v1/:org_slug/:workspace_slug/notifications/mark | org+workspace | mark_notification | v1/notification.mark.ts |
| POST | /v1/:org_slug/:workspace_slug/notifications/mark-all | org+workspace | mark_notifications_read | v1/notification.mark_all.ts |
| POST | /v1/:org_slug/:workspace_slug/onboarding/advance | org+workspace | advance_onboarding | v1/onboarding.advance.ts |
| POST | /v1/:org_slug/:workspace_slug/onboarding/first-frame | org+workspace | get_first_frame | v1/onboarding.first_frame.get.ts |
| POST | /v1/:org_slug/:workspace_slug/ontology/neighbors | org+workspace | get_ontology_neighbors | v1/ontology.neighbors.ts |
| POST | /v1/:org_slug/:workspace_slug/ontology/query | org+workspace | query_ontology | v1/ontology.query.ts |
| POST | /v1/:org_slug/:workspace_slug/operator/status | org+workspace | get_operator_status | v1/operator.status.get.ts |
| GET | /v1/:org_slug/:workspace_slug/org/data-plane | org+workspace | get_data_plane | v1/org.data_plane.ts |
| PUT | /v1/:org_slug/:workspace_slug/org/data-plane | org+workspace | set_data_plane | v1/org.data_plane.ts |
| POST | /v1/:org_slug/:workspace_slug/org/invitations/accept | org+workspace | accept_member_invite | v1/org.member_invite.accept.ts |
| POST | /v1/:org_slug/:workspace_slug/org/invitations/decline | org+workspace | decline_member_invite | v1/org.member_invite.decline.ts |
| POST | /v1/:org_slug/:workspace_slug/org/invitations/resend | org+workspace | resend_member_invite | v1/org.member_invite.resend.ts |
| POST | /v1/:org_slug/:workspace_slug/org/invitations/revoke | org+workspace | revoke_member_invite | v1/org.member_invite.revoke.ts |
| POST | /v1/:org_slug/:workspace_slug/org/members | org+workspace | add_org_member | v1/org.member.add.ts |
| DELETE | /v1/:org_slug/:workspace_slug/org/members/remove | org+workspace | remove_org_member | v1/org.member.remove.ts |
| PATCH | /v1/:org_slug/:workspace_slug/org/members/role | org+workspace | change_member_role | v1/org.member_role.change.ts |
| DELETE | /v1/:org_slug/:workspace_slug/org/model-credential | org+workspace | delete_model_credential | v1/org.model_credential.ts |
| GET | /v1/:org_slug/:workspace_slug/org/model-credential | org+workspace | get_model_credential | v1/org.model_credential.ts |
| PUT | /v1/:org_slug/:workspace_slug/org/model-credential | org+workspace | set_model_credential | v1/org.model_credential.ts |
| POST | /v1/:org_slug/:workspace_slug/org/model-credential/verify | org+workspace | verify_model_credential | v1/org.model_credential.ts |
| GET | /v1/:org_slug/:workspace_slug/org/settings | org+workspace | get_org_settings | v1/org.settings.read.ts |
| PATCH | /v1/:org_slug/:workspace_slug/org/settings | org+workspace | update_org_settings | v1/org.settings.write.ts |
| GET | /v1/:org_slug/:workspace_slug/org/sso | org+workspace | list_sso_providers | v1/org.sso.ts |
| PUT | /v1/:org_slug/:workspace_slug/org/sso/policy | org+workspace | set_sso_policy | v1/org.sso.ts |
| POST | /v1/:org_slug/:workspace_slug/org/sso/providers | org+workspace | create_sso_provider | v1/org.sso.ts |
| DELETE | /v1/:org_slug/:workspace_slug/org/sso/providers/:providerId | org+workspace | delete_sso_provider | v1/org.sso.ts |
| PATCH | /v1/:org_slug/:workspace_slug/org/sso/providers/:providerId | org+workspace | update_sso_provider | v1/org.sso.ts |
| PUT | /v1/:org_slug/:workspace_slug/org/sso/providers/:providerId/group-roles | org+workspace | set_sso_group_roles | v1/org.sso.ts |
| POST | /v1/:org_slug/:workspace_slug/org/sso/providers/:providerId/verify-domain | org+workspace | verify_sso_domain | v1/org.sso.ts |
| DELETE | /v1/:org_slug/:workspace_slug/org/sso/scim-token | org+workspace | revoke_scim_token | v1/org.sso.ts |
| POST | /v1/:org_slug/:workspace_slug/org/sso/scim-token | org+workspace | create_scim_token | v1/org.sso.ts |
| POST | /v1/:org_slug/:workspace_slug/org/sso/scim-token/rotate | org+workspace | rotate_scim_token | v1/org.sso.ts |
| GET | /v1/:org_slug/:workspace_slug/org/teams | org+workspace | list_teams | v1/org.team.list.ts |
| POST | /v1/:org_slug/:workspace_slug/org/teams | org+workspace | create_team | v1/org.team.create.ts |
| POST | /v1/:org_slug/:workspace_slug/org/teams/delete | org+workspace | delete_team | v1/org.team.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/org/teams/members | org+workspace | set_team_members | v1/org.team.members.set.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/catalog/browse | org+workspace | browse_plugin_catalog | v1/plugin.catalog.browse.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/catalog/get | org+workspace | get_catalog_plugin | v1/plugin.catalog.get.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/catalog/sync | org+workspace | sync_plugin_catalog | v1/plugin.catalog.sync.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/credential/reauth | org+workspace | reauth_plugin_credential | v1/plugin.credential.reauth.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/credential/revoke | org+workspace | revoke_plugin_credential | v1/plugin.credential.revoke.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/org/install | org+workspace | install_plugin | v1/plugin.org.install.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/org/install-bulk | org+workspace | install_plugins_bulk | v1/plugin.org.install_bulk.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/org/list | org+workspace | list_plugins | v1/plugin.org.list.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/org/uninstall | org+workspace | uninstall_plugin | v1/plugin.org.uninstall.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/registries | org+workspace | list_plugin_registries | v1/plugin.registry.list.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/registries/add | org+workspace | add_plugin_registry | v1/plugin.registry.add.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/registries/remove | org+workspace | remove_plugin_registry | v1/plugin.registry.remove.ts |
| POST | /v1/:org_slug/:workspace_slug/plugin/set-enabled | org+workspace | set_plugin_enabled | v1/plugin.set_enabled.ts |
| POST | /v1/:org_slug/:workspace_slug/privacy/erase | org+workspace | erase_data | v1/privacy.data.erase.ts |
| POST | /v1/:org_slug/:workspace_slug/privacy/export | org+workspace | export_data | v1/privacy.data.export.ts |
| GET | /v1/:org_slug/:workspace_slug/privacy/export/:exportId | org+workspace | get_export_status | v1/privacy.data.export.ts |
| GET | /v1/:org_slug/:workspace_slug/privacy/export/:exportId/download | org+workspace | get_export_status | v1/privacy.data.export.ts |
| POST | /v1/:org_slug/:workspace_slug/pull-requests/changes | org+workspace | get_change_set | v1/forge.changes.get.ts |
| POST | /v1/:org_slug/:workspace_slug/pull-requests/revisions/diff | org+workspace | get_revision_diff | v1/forge.revision.diff.get.ts |
| POST | /v1/:org_slug/:workspace_slug/reference/search | org+workspace | search_references | v1/reference.search.ts |
| PATCH | /v1/:org_slug/:workspace_slug/repos/:id/configure | org+workspace | configure_repo | v1/repo.ts |
| GET | /v1/:org_slug/:workspace_slug/repos/:id/metrics | org+workspace | get_repo_metrics | v1/repo.ts |
| POST | /v1/:org_slug/:workspace_slug/repos/:id/pause | org+workspace | pause_repo | v1/repo.ts |
| POST | /v1/:org_slug/:workspace_slug/repos/:id/resume | org+workspace | resume_repo | v1/repo.ts |
| POST | /v1/:org_slug/:workspace_slug/repos/:id/sync | org+workspace | sync_repo | v1/repo.ts |
| GET | /v1/:org_slug/:workspace_slug/repos/branches | org+workspace | list_branches | v1/repo.ts |
| GET | /v1/:org_slug/:workspace_slug/repos/ci/status | org+workspace | get_ci_status | v1/repo.ts |
| GET | /v1/:org_slug/:workspace_slug/repos/pulls/:number | org+workspace | get_pr | v1/repo.ts |
| GET | /v1/:org_slug/:workspace_slug/repos/pulls/:number/diff | org+workspace | get_pr_diff | v1/repo.ts |
| GET | /v1/:org_slug/:workspace_slug/repositories | org+workspace | list_repositories | v1/repository.list.ts |
| PUT | /v1/:org_slug/:workspace_slug/repositories/set | org+workspace | set_workspace_repositories | v1/workspace.repositories.set.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/config/import | org+workspace | import_repository_config | v1/repository.config.import.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/config/parse | org+workspace | parse_repository_config | v1/repository.config.parse.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/config/scan | org+workspace | scan_repository_config | v1/repository.config.scan.ts |
| GET | /v1/:org_slug/:workspace_slug/repository/findings | org+workspace | list_code_repository_findings | v1/repository.findings.list.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/findings/promote | org+workspace | promote_instruction_to_steering | v1/repository.instruction.promote.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/gitlab/attach | org+workspace | attach_gitlab_project | v1/repository.gitlab.attach.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/init-pr | org+workspace | open_init_pr | v1/repository.init_pr.open.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/link | org+workspace | link_repository | v1/repository.link.ts |
| GET | /v1/:org_slug/:workspace_slug/repository/main | org+workspace | get_main_repository | v1/repository.main.get.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/tree | org+workspace | get_repository_tree | v1/repository.tree.get.ts |
| POST | /v1/:org_slug/:workspace_slug/repository/unlink | org+workspace | unlink_repository | v1/repository.unlink.ts |
| GET | /v1/:org_slug/:workspace_slug/router/policy | org+workspace | get_routing_policy | v1/router.policy.get.ts |
| POST | /v1/:org_slug/:workspace_slug/router/policy/set | org+workspace | set_routing_policy | v1/router.policy.set.ts |
| POST | /v1/:org_slug/:workspace_slug/router/preview | org+workspace | preview_routing_decision | v1/router.decision.preview.ts |
| POST | /v1/:org_slug/:workspace_slug/run-outcomes/settings/authorization/begin | org+workspace | start_issue_authorization | v1/run.outcomes.settings.ts |
| POST | /v1/:org_slug/:workspace_slug/run-outcomes/settings/authorization/complete | org+workspace | authorize_issue_provider | v1/run.outcomes.settings.ts |
| GET | /v1/:org_slug/:workspace_slug/run-outcomes/settings/providers | org+workspace | get_run_issue_providers | v1/run.outcomes.settings.ts |
| POST | /v1/:org_slug/:workspace_slug/runs | org+workspace | list_runs | v1/run.list.ts |
| GET | /v1/:org_slug/:workspace_slug/runs/:run_id/stream | org+workspace | get_run | v1/run.stream.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/chain | org+workspace | get_run_chain | v1/run.chain.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/checkpoints/post | org+workspace | post_run_checkpoint | v1/run.checkpoint.post.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/classification | org+workspace | set_run_classification | v1/run.classification.set.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/commits | org+workspace | list_run_commits | v1/forge.run.commits.list.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/context | org+workspace | get_run_context | v1/run.context.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/cost | org+workspace | get_run_cost | v1/run.cost.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/edit | org+workspace | edit_run | v1/run.edit.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/export | org+workspace | export_run | v1/run.export.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/export-status | org+workspace | get_run_export | v1/run.export.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/frame-body | org+workspace | get_run_frame_body | v1/run.frame_body.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/get | org+workspace | get_run | v1/run.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/issues | org+workspace | get_run_issues | v1/run.issues.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/outputs | org+workspace | get_run_outputs | v1/run.outputs.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/recent | org+workspace | list_recent_runs | v1/run.recent.list.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/report | org+workspace | get_run_report | v1/run.report.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/seal | org+workspace | seal_run | v1/run.seal.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/sensitive-detections | org+workspace | list_sensitive_detections | v1/run.sensitive_detections.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/summarize | org+workspace | summarize_run | v1/run.summarize.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/tasks | org+workspace | get_run_tasks | v1/run.tasks.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/transcript | org+workspace | get_run_transcript | v1/run.transcript.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/turns | org+workspace | get_run_turns | v1/run.turns.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runs/work | org+workspace | get_run_work | v1/run.work.get.ts |
| POST | /v1/:org_slug/:workspace_slug/runtimes | org+workspace | list_runtimes | v1/runtime.list.ts |
| POST | /v1/:org_slug/:workspace_slug/runtimes/create | org+workspace | create_runtime | v1/runtime.create.ts |
| POST | /v1/:org_slug/:workspace_slug/runtimes/delete | org+workspace | delete_runtime | v1/runtime.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/runtimes/update | org+workspace | update_runtime | v1/runtime.update.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runs/get | org+workspace | get_sandbox_run | v1/sandbox-run.get.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runs/launch | org+workspace | launch_sandbox_run | v1/sandbox-run.launch.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runs/list | org+workspace | list_sandbox_runs | v1/sandbox-run.list.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runs/review | org+workspace | start_sandbox_review | v1/sandbox-run.review.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runs/stop | org+workspace | stop_sandbox_run | v1/sandbox-run.stop.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runs/terminal/open | org+workspace | open_run_terminal | v1/sandbox-run.terminal.open.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runtimes | org+workspace | list_sandbox_runtimes | v1/sandbox-runtime.list.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runtimes/create | org+workspace | create_sandbox_runtime | v1/sandbox-runtime.create.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runtimes/setup | org+workspace | setup_sandbox_runtime | v1/sandbox-runtime.setup.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-runtimes/update | org+workspace | update_sandbox_runtime | v1/sandbox-runtime.update.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-templates/generate | org+workspace | generate_sandbox_template | v1/sandbox-template.generate.ts |
| POST | /v1/:org_slug/:workspace_slug/sandbox-templates/test | org+workspace | check_sandbox_template | v1/sandbox-template.test-build.ts |
| GET | /v1/:org_slug/:workspace_slug/schema | org+workspace | list_schemas | v1/schema.ts |
| DELETE | /v1/:org_slug/:workspace_slug/schema/:schemaName/labels/:labelName | org+workspace | delete_schema_label | v1/schema.ts |
| PUT | /v1/:org_slug/:workspace_slug/schema/:schemaName/labels/:labelName | org+workspace | upsert_schema_label | v1/schema.ts |
| DELETE | /v1/:org_slug/:workspace_slug/schema/:schemaName/properties/:ownerKind/:ownerName/:key | org+workspace | delete_schema_property | v1/schema.ts |
| PUT | /v1/:org_slug/:workspace_slug/schema/:schemaName/properties/:ownerKind/:ownerName/:key | org+workspace | upsert_schema_property | v1/schema.ts |
| DELETE | /v1/:org_slug/:workspace_slug/schema/:schemaName/relationships/:relationshipName | org+workspace | delete_schema_relationship | v1/schema.ts |
| PUT | /v1/:org_slug/:workspace_slug/schema/:schemaName/relationships/:relationshipName | org+workspace | upsert_schema_relationship | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/schema/:schemaName/toggle | org+workspace | toggle_schema | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/schema/chat | org+workspace | run_schema_chat | v1/schema.ts |
| GET | /v1/:org_slug/:workspace_slug/schema/export | org+workspace | export_schema | v1/schema.ts |
| GET | /v1/:org_slug/:workspace_slug/schema/recommend | org+workspace | recommend_schema | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/schema/reconcile/dispatch | org+workspace | dispatch_schema_reconcile | v1/schema.ts |
| GET | /v1/:org_slug/:workspace_slug/schema/reconcile/status | org+workspace | get_reconcile_status | v1/schema.ts |
| GET | /v1/:org_slug/:workspace_slug/schema/registry | org+workspace | get_schema_registry | v1/schema.ts |
| PUT | /v1/:org_slug/:workspace_slug/schema/registry/config | org+workspace | get_registry_config | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/schema/setup | org+workspace | setup_schema | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/schema/validate/node | org+workspace | validate_schema_node | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/schema/validate/relationship | org+workspace | validate_schema_relationship | v1/schema.ts |
| GET | /v1/:org_slug/:workspace_slug/schema/versions | org+workspace | list_schema_versions | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/schema/versions | org+workspace | create_schema_version | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/schema/versions/:versionId/pin | org+workspace | pin_schema_version | v1/schema.ts |
| GET | /v1/:org_slug/:workspace_slug/schema/versions/diff | org+workspace | diff_schema_versions | v1/schema.ts |
| POST | /v1/:org_slug/:workspace_slug/secret/export | org+workspace | export_secrets | v1/secret.export.ts |
| POST | /v1/:org_slug/:workspace_slug/secret/import-env | org+workspace | import_env_secrets | v1/secret.import_env.ts |
| POST | /v1/:org_slug/:workspace_slug/secret/key/delete | org+workspace | delete_secret_key | v1/secret.key.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/secret/key/list | org+workspace | list_secret_keys | v1/secret.key.list.ts |
| POST | /v1/:org_slug/:workspace_slug/secret/key/upsert | org+workspace | upsert_secret_key | v1/secret.key.upsert.ts |
| POST | /v1/:org_slug/:workspace_slug/secret/reveal | org+workspace | reveal_secret | v1/secret.reveal.ts |
| POST | /v1/:org_slug/:workspace_slug/secret/value/set | org+workspace | set_secret_value | v1/secret.value.set.ts |
| POST | /v1/:org_slug/:workspace_slug/secret/value/unset | org+workspace | unset_secret_value | v1/secret.value.unset.ts |
| GET | /v1/:org_slug/:workspace_slug/shell/nav-counts | org+workspace | get_nav_counts | v1/shell.nav_counts.get.ts |
| POST | /v1/:org_slug/:workspace_slug/skills | org+workspace | list_skills | v1/skill.list.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/config | org+workspace | get_skill_config | v1/skill.config.get.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/config/update | org+workspace | update_skill_config | v1/skill.config.update.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/impact | org+workspace | list_skill_impact | v1/skill.impact.list.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/propose | org+workspace | propose_skill | v1/skill.propose.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/registry | org+workspace | get_skill_registry | v1/skill.registry.get.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/registry/read | org+workspace | read_registry_skill | v1/skill.registry.read.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/registry/search | org+workspace | search_skill_registry | v1/skill.registry.search.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/registry/update | org+workspace | set_skill_registry | v1/skill.registry.set.ts |
| POST | /v1/:org_slug/:workspace_slug/skills/search/preview | org+workspace | preview_skill_search | v1/skill.search.preview.ts |
| POST | /v1/:org_slug/:workspace_slug/spend | org+workspace | get_spend | v1/spend.get.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/attribution | org+workspace | get_spend_attribution | v1/spend.attribution.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/code-share | org+workspace | get_code_share | v1/spend.code_share.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/context-quality | org+workspace | get_context_quality | v1/spend.context_quality.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/cost-centers | org+workspace | list_cost_centers | v1/cost_center.list.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/cost-centers/create | org+workspace | create_cost_center | v1/cost_center.create.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/cost-centers/delete | org+workspace | delete_cost_center | v1/cost_center.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/cost-centers/set | org+workspace | set_cost_center | v1/cost_center.set.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/drill | org+workspace | get_spend_drill | v1/spend.drill.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/export | org+workspace | export_spend | v1/spend.export.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/findings | org+workspace | list_findings | v1/finding.list.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/findings/calls | org+workspace | list_finding_calls | v1/finding.calls.list.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/findings/dismiss | org+workspace | dismiss_finding | v1/finding.dismiss.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/findings/drafted-fix | org+workspace | get_finding_fix | v1/finding.fix.get.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/findings/drafted-fix/answer | org+workspace | answer_finding_fix | v1/finding.fix.answer.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/findings/evidence | org+workspace | get_finding_evidence | v1/finding.evidence.get.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/findings/fix | org+workspace | record_finding_fix | v1/finding.fix.record.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/findings/replay | org+workspace | get_model_class_replay | v1/finding.model_class_replay.get.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/model-fit | org+workspace | get_spend_model_fit | v1/spend.model_fit.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/no-progress-limit | org+workspace | get_no_progress_limit | v1/spend.no_progress_limit.get.ts |
| PUT | /v1/:org_slug/:workspace_slug/spend/no-progress-limit | org+workspace | set_no_progress_limit | v1/spend.no_progress_limit.set.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/operator-scorecard | org+workspace | get_operator_scorecard | v1/spend.operator_scorecard.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/operators | org+workspace | get_operator_ranking | v1/spend.operator_ranking.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/per-merged-pr | org+workspace | get_spend_per_merged_pr | v1/spend.per_merged_pr.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/run-facts | org+workspace | list_run_facts | v1/spend.run_facts.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/run-rollup | org+workspace | get_run_rollup | v1/spend.run_rollup.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/sandboxes | org+workspace | get_sandbox_spend | v1/spend.sandbox.get.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/statement/export | org+workspace | export_statement | v1/spend.statement.export.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/unproductive | org+workspace | get_unproductive_spend | v1/spend.unproductive.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/waste | org+workspace | list_waste | v1/spend.waste.ts |
| POST | /v1/:org_slug/:workspace_slug/spend/work-order-metrics | org+workspace | get_work_order_metrics | v1/spend.work_order_metrics.ts |
| POST | /v1/:org_slug/:workspace_slug/status/summary | org+workspace | get_status_summary | v1/status.summary.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/proposals | org+workspace | list_proposals | v1/steering.proposal.list.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/proposals/create | org+workspace | propose_record | v1/steering.proposal.create.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/proposals/dismiss | org+workspace | dismiss_proposal | v1/steering.proposal.dismiss.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/prs/approve | org+workspace | approve_steering_pr | v1/steering.pr.approve.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/prs/diff | org+workspace | get_steering_pr_diff | v1/steering.pr.diff.get.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/prs/get | org+workspace | get_steering_pr | v1/steering.pr.get.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/prs/merge | org+workspace | merge_steering_pr | v1/steering.pr.merge.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/prs/open | org+workspace | open_steering_pr | v1/steering.pr.open.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/prs/refresh | org+workspace | refresh_steering_pr | v1/steering.pr.refresh.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/prs/revert | org+workspace | revert_steering_pr | v1/steering.pr.revert.ts |
| GET | /v1/:org_slug/:workspace_slug/steering/record/list | org+workspace | list_steering_records | v1/steering.record.list.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/record/promote | org+workspace | promote_steering_record | v1/steering.record.promote.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/record/revise | org+workspace | revise_steering_record | v1/steering.record.revise.ts |
| POST | /v1/:org_slug/:workspace_slug/steering/records/append | org+workspace | append_record | v1/steering.records.append.ts |
| GET | /v1/:org_slug/:workspace_slug/steering/settings | org+workspace | get_steering_settings | v1/workspace.steering_settings.ts |
| PUT | /v1/:org_slug/:workspace_slug/steering/settings | org+workspace | set_steering_settings | v1/workspace.steering_settings.ts |
| POST | /v1/:org_slug/:workspace_slug/stella/permissions | org+workspace | get_stella_permissions | v1/stella.permissions.get.ts |
| POST | /v1/:org_slug/:workspace_slug/stella/permissions/set | org+workspace | set_stella_permissions | v1/stella.permissions.set.ts |
| POST | /v1/:org_slug/:workspace_slug/system/install-instructions | org+workspace | get_install_instructions | v1/system.install.instructions.ts |
| POST | /v1/:org_slug/:workspace_slug/tacho/enrollment-tokens | org+workspace | create_enrollment_token | v1/tacho.enrollment_token.create.ts |
| POST | /v1/:org_slug/:workspace_slug/tacho/enrollments | org+workspace | create_tacho_enrollment | v1/tacho.enrollment.create.ts |
| POST | /v1/:org_slug/:workspace_slug/tacho/enrollments/revoke | org+workspace | revoke_tacho_enrollment | v1/tacho.enrollment.revoke.ts |
| POST | /v1/:org_slug/:workspace_slug/tacho/hosts | org+workspace | list_tacho_hosts | v1/tacho.host.list.ts |
| POST | /v1/:org_slug/:workspace_slug/tacho/incidents | org+workspace | list_incidents | v1/tacho.incident.list.ts |
| GET | /v1/:org_slug/:workspace_slug/tacho/session-policy | org+workspace | get_tacho_session_policy | v1/tacho.session_policy.read.ts |
| PATCH | /v1/:org_slug/:workspace_slug/tacho/session-policy | org+workspace | update_tacho_session_policy | v1/tacho.session_policy.write.ts |
| POST | /v1/:org_slug/:workspace_slug/tacho/sessions | org+workspace | list_tacho_sessions | v1/tacho.session.list.ts |
| POST | /v1/:org_slug/:workspace_slug/tacho/sessions/get | org+workspace | get_tacho_session | v1/tacho.session.get.ts |
| GET | /v1/:org_slug/:workspace_slug/telemetry/error/cluster | org+workspace | list_error_clusters | v1/telemetry.error.cluster.ts |
| POST | /v1/:org_slug/:workspace_slug/telemetry/stella/enrollments | org+workspace | create_stella_enrollment | v1/telemetry.stella.enroll.ts |
| GET | /v1/:org_slug/:workspace_slug/tool/declaration/list | org+workspace | list_tool_declarations | v1/tool.declaration.list.ts |
| POST | /v1/:org_slug/:workspace_slug/tool/declaration/publish | org+workspace | publish_tool_declaration | v1/tool.declaration.publish.ts |
| POST | /v1/:org_slug/:workspace_slug/toolbelts | org+workspace | list_toolbelts | v1/toolbelt.list.ts |
| POST | /v1/:org_slug/:workspace_slug/toolbelts/clone | org+workspace | clone_toolbelt | v1/toolbelt.clone.ts |
| POST | /v1/:org_slug/:workspace_slug/toolbelts/delete | org+workspace | delete_toolbelt | v1/toolbelt.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/toolbelts/get | org+workspace | get_toolbelt | v1/toolbelt.get.ts |
| POST | /v1/:org_slug/:workspace_slug/toolbelts/update | org+workspace | update_toolbelt | v1/toolbelt.update.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/import | org+workspace | import_tools | v1/tool.import.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/load | org+workspace | load_tools | v1/tools.load.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/relays | org+workspace | create_relay | v1/tool.relay.create.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/relays/revoke | org+workspace | revoke_relay | v1/tool.relay.revoke.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/search | org+workspace | search_tools | v1/tools.search.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/state | org+workspace | set_tool_state | v1/tool.state.set.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/steering/migrate | org+workspace | migrate_tools_to_steering | v1/tool.steering.migrate.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/credential | org+workspace | set_mcp_credential | v1/tool.studio.credential.set.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/description | org+workspace | draft_studio_description | v1/tool.studio.description.draft.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/discovery/get | org+workspace | get_studio_discovery | v1/tool.studio.discovery.get.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/discovery/start | org+workspace | start_studio_discovery | v1/tool.studio.discovery.start.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/draft | org+workspace | save_studio_draft | v1/tool.studio.draft.save.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/draft/get | org+workspace | get_studio_draft | v1/tool.studio.draft.get.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/findings | org+workspace | list_studio_findings | v1/tool.studio.findings.list.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/listing/get | org+workspace | get_studio_listing | v1/tool.studio.listing.get.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/listing/start | org+workspace | start_studio_listing | v1/tool.studio.listing.start.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/review | org+workspace | open_studio_review | v1/tool.studio.review.open.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/selection | org+workspace | run_studio_selection | v1/tool.studio.selection.run.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/server/get | org+workspace | get_studio_server | v1/tool.studio.server.get.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/tools/list | org+workspace | list_studio_tools | v1/tool.studio.tools.list.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/studio/try | org+workspace | try_studio_tool | v1/tool.studio.try.ts |
| POST | /v1/:org_slug/:workspace_slug/tools/versions | org+workspace | list_tool_versions | v1/tool.version.list.ts |
| PUT | /v1/:org_slug/:workspace_slug/tools/versions/classification | org+workspace | set_tool_classification | v1/tool.classification.set.ts |
| POST | /v1/:org_slug/:workspace_slug/work/attachments/remove | org+workspace | remove_work_item_attachment | v1/work.item.attachment.remove.ts |
| POST | /v1/:org_slug/:workspace_slug/work/attachments/upload | org+workspace | — | v1/work.item.attachment.upload.ts |
| GET | /v1/:org_slug/:workspace_slug/work/attachments/uploadapiKeyId | org+workspace | upload_work_item_attachment | v1/work.item.attachment.upload.ts |
| POST | /v1/:org_slug/:workspace_slug/work/autonomy/get | org+workspace | get_work_autonomy | v1/work.autonomy.get.ts |
| POST | /v1/:org_slug/:workspace_slug/work/batches/draft | org+workspace | draft_work_batch | v1/work.batch.draft.ts |
| POST | /v1/:org_slug/:workspace_slug/work/batches/send | org+workspace | send_work_batch | v1/work.batch.send.ts |
| POST | /v1/:org_slug/:workspace_slug/work/collectors/list | org+workspace | list_work_collectors | v1/work.collectors.list.ts |
| POST | /v1/:org_slug/:workspace_slug/work/collectors/set | org+workspace | set_work_collector | v1/work.collector.set.ts |
| POST | /v1/:org_slug/:workspace_slug/work/collectors/sync | org+workspace | sync_work_collector | v1/work.collector.sync.ts |
| POST | /v1/:org_slug/:workspace_slug/work/cost/forecast | org+workspace | forecast_work_cost | v1/work.cost.forecast.ts |
| POST | /v1/:org_slug/:workspace_slug/work/fields/get | org+workspace | get_work_fields | v1/work.fields.get.ts |
| POST | /v1/:org_slug/:workspace_slug/work/fields/set | org+workspace | set_work_field_mapping | v1/work.field_mapping.set.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/add | org+workspace | add_work_items | v1/work.items.add.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/close | org+workspace | close_work_item | v1/work.item.close.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/create | org+workspace | create_work_item | v1/work.item.create.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/delete | org+workspace | delete_work_items | v1/work.items.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/dod/approve | org+workspace | approve_definition_of_done | v1/work.dod.approve.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/dod/item | org+workspace | set_dod_item_done | v1/work.dod.item.done.set.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/dod/save | org+workspace | save_definition_of_done | v1/work.dod.save.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/get | org+workspace | get_work_item | v1/work.item.get.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/list | org+workspace | list_work_items | v1/work.items.list.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/reopen | org+workspace | reopen_work_item | v1/work.item.reopen.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/search | org+workspace | search_work_items | v1/work.items.search.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/source-comment | org+workspace | comment_on_source_issue | v1/work.item.source_comment.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/source/refresh | org+workspace | refresh_work_item_source | v1/work.item.source.refresh.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/start/decline | org+workspace | decline_work_item_start | v1/work.item.start.decline.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/status | org+workspace | set_work_item_status | v1/work.item.status.set.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/text-write/retry | org+workspace | retry_work_item_text_write | v1/work.item.text_write.retry.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/update | org+workspace | update_work_item | v1/work.item.update.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/update-many | org+workspace | update_work_items | v1/work.items.update.ts |
| POST | /v1/:org_slug/:workspace_slug/work/items/workstream | org+workspace | set_work_item_workstream | v1/work.item.workstream.set.ts |
| POST | /v1/:org_slug/:workspace_slug/work/labels/archive | org+workspace | archive_work_label | v1/work.label.archive.ts |
| POST | /v1/:org_slug/:workspace_slug/work/labels/delete | org+workspace | delete_work_label | v1/work.label.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/work/labels/draft | org+workspace | draft_work_label | v1/work.label.draft.ts |
| POST | /v1/:org_slug/:workspace_slug/work/labels/list | org+workspace | list_work_labels | v1/work.labels.list.ts |
| POST | /v1/:org_slug/:workspace_slug/work/labels/map-collector-label | org+workspace | map_work_collector_label | v1/work.collector_label.map.ts |
| POST | /v1/:org_slug/:workspace_slug/work/labels/save | org+workspace | save_work_label | v1/work.label.save.ts |
| POST | /v1/:org_slug/:workspace_slug/work/orders/accept | org+workspace | accept_work_order | v1/work.order.accept.ts |
| POST | /v1/:org_slug/:workspace_slug/work/orders/cancel | org+workspace | cancel_work_order | v1/work.order.cancel.ts |
| POST | /v1/:org_slug/:workspace_slug/work/orders/checks/refresh | org+workspace | refresh_work_order_checks | v1/work.order.checks.refresh.ts |
| POST | /v1/:org_slug/:workspace_slug/work/orders/criteria/claim | org+workspace | claim_work_criterion | v1/work.criterion.claim.ts |
| POST | /v1/:org_slug/:workspace_slug/work/orders/draft | org+workspace | draft_work_order | v1/work.order.draft.ts |
| POST | /v1/:org_slug/:workspace_slug/work/orders/return | org+workspace | return_work_order | v1/work.order.return.ts |
| POST | /v1/:org_slug/:workspace_slug/work/orders/send | org+workspace | send_work_order | v1/work.order.send.ts |
| POST | /v1/:org_slug/:workspace_slug/work/orders/stop | org+workspace | stop_work_order | v1/work.order.stop.ts |
| POST | /v1/:org_slug/:workspace_slug/work/outcomes/get | org+workspace | get_work_outcomes | v1/work.outcomes.get.ts |
| POST | /v1/:org_slug/:workspace_slug/work/priorities/get | org+workspace | get_work_priorities | v1/work.priorities.get.ts |
| POST | /v1/:org_slug/:workspace_slug/work/ready/list | org+workspace | list_ready_work | v1/work.ready.list.ts |
| POST | /v1/:org_slug/:workspace_slug/work/run-links/list | org+workspace | list_run_link_suggestions | v1/run.link_suggestions.list.ts |
| POST | /v1/:org_slug/:workspace_slug/work/run-links/review | org+workspace | review_run_link | v1/run.link.review.ts |
| POST | /v1/:org_slug/:workspace_slug/work/sandbox-batches/get | org+workspace | get_work_batch | v1/work.orders.get.ts |
| POST | /v1/:org_slug/:workspace_slug/work/sandbox-batches/items/resend | org+workspace | resend_work_batch_item | v1/work.orders.resend.ts |
| POST | /v1/:org_slug/:workspace_slug/work/sandbox-batches/send | org+workspace | send_work_orders | v1/work.orders.send.ts |
| POST | /v1/:org_slug/:workspace_slug/work/sandbox-batches/stop | org+workspace | stop_work_orders | v1/work.orders.stop.ts |
| POST | /v1/:org_slug/:workspace_slug/work/sources/list | org+workspace | list_work_sources | v1/work.sources.list.ts |
| POST | /v1/:org_slug/:workspace_slug/work/staffing/recommend | org+workspace | recommend_staffing | v1/work.staffing.recommend.ts |
| POST | /v1/:org_slug/:workspace_slug/work/statuses/delete | org+workspace | delete_work_status | v1/work.status.delete.ts |
| POST | /v1/:org_slug/:workspace_slug/work/statuses/draft | org+workspace | draft_work_status | v1/work.status.draft.ts |
| POST | /v1/:org_slug/:workspace_slug/work/statuses/list | org+workspace | list_work_statuses | v1/work.statuses.list.ts |
| POST | /v1/:org_slug/:workspace_slug/work/statuses/save | org+workspace | save_work_status | v1/work.status.save.ts |
| POST | /v1/:org_slug/:workspace_slug/work/targets/list | org+workspace | list_work_targets | v1/work.targets.list.ts |
| POST | /v1/:org_slug/:workspace_slug/work/task/classify | org+workspace | classify_task | v1/work.task.classify.ts |
| POST | /v1/:org_slug/:workspace_slug/work/triage/retriage-open | org+workspace | retriage_open_work | v1/work.triage.retriage-open.ts |
| POST | /v1/:org_slug/:workspace_slug/work/triage/retry | org+workspace | retry_work_triage | v1/work.triage.retry.ts |
| POST | /v1/:org_slug/:workspace_slug/work/triage/revise | org+workspace | revise_work_triage | v1/work.triage.revise.ts |
| POST | /v1/:org_slug/:workspace_slug/work/workstreams/list | org+workspace | list_workstreams | v1/work.workstreams.list.ts |
| GET | /v1/:org_slug/:workspace_slug/working-copies | org+workspace | list_working_copies | v1/repository.working_copy.list.ts |
| POST | /v1/:org_slug/:workspace_slug/working-copies | org+workspace | record_working_copy | v1/repository.working_copy.record.ts |
| POST | /v1/:org_slug/:workspace_slug/workspace/connect | org+workspace | connect_workspace | v1/workspace.connect.ts |
| GET | /v1/:org_slug/:workspace_slug/workspace/gateway-settings | org+workspace | get_gateway_settings | v1/workspace.gateway_settings.ts |
| PATCH | /v1/:org_slug/:workspace_slug/workspace/gateway-settings | org+workspace | update_gateway_settings | v1/workspace.gateway_settings.ts |
| POST | /v1/:org_slug/:workspace_slug/workspace/invite/send | org+workspace | send_workspace_invite | v1/workspace.invite.send.ts |
| GET | /v1/:org_slug/:workspace_slug/workspace/join-requests | org+workspace | list_join_requests | v1/workspace.join_request.list.ts |
| GET | /v1/:org_slug/:workspace_slug/workspace/member/list | org+workspace | list_members | v1/workspace.member.list.ts |
| POST | /v1/:org_slug/:workspace_slug/workspace/members/add | org+workspace | add_workspace_member | v1/workspace.member.add.ts |
| POST | /v1/:org_slug/:workspace_slug/workspace/members/remove | org+workspace | remove_workspace_member | v1/workspace.member.remove.ts |
| PUT | /v1/:org_slug/:workspace_slug/workspace/members/role | org+workspace | set_workspace_member_role | v1/workspace.member_role.set.ts |
| GET | /v1/:org_slug/:workspace_slug/workspace/model-settings | org+workspace | get_model_settings | v1/workspace.model_settings.read.ts |
| PATCH | /v1/:org_slug/:workspace_slug/workspace/model-settings | org+workspace | update_model_settings | v1/workspace.model_settings.write.ts |
| GET | /v1/:org_slug/:workspace_slug/workspace/prompt-settings | org+workspace | get_prompt_settings | v1/prompt.settings.read.ts |
| PATCH | /v1/:org_slug/:workspace_slug/workspace/prompt-settings | org+workspace | update_prompt_settings | v1/prompt.settings.write.ts |
| GET | /v1/:org_slug/:workspace_slug/workspace/settings | org+workspace | get_workspace_settings | v1/workspace.settings.read.ts |
| PATCH | /v1/:org_slug/:workspace_slug/workspace/settings | org+workspace | update_workspace_settings | v1/workspace.settings.write.ts |
| POST | /v1/:org_slug/:workspace_slug/workspaces | org+workspace | create_workspace | v1/workspace.create.ts |
| POST | /v1/:org_slug/:workspace_slug/workspaces/archive | org+workspace | archive_workspace | v1/workspace.archive.ts |
| GET | /health | public | — | health.ts |
| GET | /health/ready | public | — | health.ts |
| POST | /internal/codegraph/ci-runs | public | — | codegraph/ci-runs.ts |
| POST | /internal/codegraph/gitlab/token | public | — | codegraph/gitlab-token.ts |
| POST | /v1/auth/cli/token | public | — | v1/auth.cli.token.ts |
| GET | /v1/auth/clirequestId | public | — | v1/auth.cli.token.ts |
| POST | /v1/cms/book/redeem | public | — | v1/cms.ts |
| POST | /v1/cms/book/resend | public | — | v1/cms.ts |
| POST | /v1/cms/leads | public | — | v1/cms.ts |
| GET | /v1/cmsrequestId | public | — | v1/cms.ts |
| GET | /v1/enrollment/keys | public | get_enrollment_keys | v1/enrollment.keys.get.ts |
| POST | /v1/enrollment/request | public | preview_enrollment_request | v1/enrollment.request.ts |
| POST | /v1/enrollment/request/reject | public | reject_enrollment_request | v1/enrollment.request.ts |
| POST | /v1/gateway/run/continuation | public | — | v1/gateway/model.ts |
| GET | /v1/gatewaycontent-length | public | — | v1/gateway/model.ts |
| GET | /v1/notifications/unsubscribe | public | — | v1/notification.unsubscribe.ts |
| POST | /v1/notifications/unsubscribe | public | — | v1/notification.unsubscribe.ts |
| GET | /v1/run-exports/download | public | — | v1/run.export.download.ts |
| POST | /v1/sandbox/enroll | public | enroll_sandbox_daemon | v1/sandbox-daemon.enroll.ts |
| POST | /v1/tacho/enroll | public | enroll_host | v1/tacho.host.enroll.ts |
| POST | /v1/telemetry/usage | public | — | v1/telemetry.usage.ts |
| POST | /webhooks/:connectorId/:connectionId | public | — | v1/webhook.ts |
| GET | /webhooks/collectors/:provider/:subscription | public | — | v1/collector-webhook.ts |
| POST | /webhooks/collectors/:provider/:subscription | public | — | v1/collector-webhook.ts |
| POST | /webhooks/github/app | public | — | v1/github-webhook.ts |
| GET | /webhooks/github/apprequestId | public | — | v1/github-webhook.ts |
| POST | /webhooks/gitlab/:connectionId | public | — | v1/gitlab-webhook.ts |
| POST | /webhooks/gitlab/steering/:scopeKind/:scopeId | public | — | v1/gitlab-webhook.ts |
| GET | /webhooks/gitlabrequestId | public | — | v1/gitlab-webhook.ts |
| POST | /webhooks/linear | public | — | v1/linear-webhook.ts |
| POST | /webhooks/stripe | public | — | stripe.ts |
| GET | /webhooks/striperequestId | public | — | stripe.ts |
| GET | /webhooksrequestId | public | — | v1/webhook.ts |
| GET | /v1/assets/:publicId | user | — | v1/asset.get.ts |
| GET | /v1/assetsapiKeyId | user | — | v1/asset.get.ts |
| GET | /v1/assetsapiKeyScope | user | — | v1/asset.get.ts |
| GET | /v1/assetsrequestId | user | — | v1/asset.get.ts |
| GET | /v1/assetssessionAuthMethod | user | — | v1/asset.get.ts |
| GET | /v1/assetsuserId | user | — | v1/asset.get.ts |
| DELETE | /v1/auth/cli/session | user | — | v1/auth.cli.session.ts |
| GET | /v1/auth/cli/sessionapiKeyId | user | revoke_api_key | v1/auth.cli.session.ts |
| GET | /v1/auth/whoami | user | — | v1/auth.whoami.ts |
| GET | /v1/auth/whoamiapiKeyId | user | — | v1/auth.whoami.ts |
| GET | /v1/auth/whoamiorgId | user | — | v1/auth.whoami.ts |
| GET | /v1/auth/whoamiuserId | user | — | v1/auth.whoami.ts |
| GET | /v1/auth/whoamiworkspaceId | user | — | v1/auth.whoami.ts |
| POST | /v1/onboarding/state | user | get_onboarding_state | v1/onboarding.state.get.ts |
| POST | /v1/organizations | user | create_org | v1/org.create.ts |
| POST | /v1/user/organizations | user | list_orgs | v1/org.list.ts |
| PATCH | /v1/user/preferences | user | set_preferences | v1/user.preferences.set.ts |
| GET | /v1/user/preferences/read | user | get_user_preferences | v1/user.preferences.read.ts |
| PATCH | /v1/user/profile | user | update_profile | v1/user.profile.update.ts |
| POST | /v1/user/workspaces | user | list_workspaces | v1/workspace.list.ts |
Capability kernel
693 typed contracts, one registry, one invoke(). A contract's dotless snake_case name is its identity (ADR-025); the dotted filename is only where it lives.
How a surface reaches a handler
- 684 of 693 contracts bind a handler in
@oxagen/handlers; the rest register from@oxagen/agent/registeror run inline. - The registry lives on
globalThisunder a symbol so a bundler's double evaluation cannot register twice; a duplicate with a different signature keeps the first registration, with a warning outside production, instead of throwing.
Gate order inside invoke()
- The surface check runs only when the caller passes
opts.surface. The kernel enters the tenant scope when the contract is scoped or both tenant ids are uuids. A machine key whose scope does not cover the capability is refused beforecheckIAM. Apending_approvalresult also creates anaccess_requestsrow. A nested invoke skips the billing gate but not the budget gate. Stella's calls and the assistant's own contracts skip the budget and decision-rules gates (ADR-235). The decision-rules gate may reserve a settlement, which the audit step settles and the catch block releases. The replay-input check runs only on the approval-resume path. - The billing, budget and usage slots are empty until
bootstrapBillingRuntime()fills them, once per process. A surface that does not bootstrap runs those gates open.apps/api,apps/mcpandapps/appalso bootstrap IAM, decision rules and entitlement at startup. - IAM enforcement is always on:
bootstrapIAMRuntimeregisters the check with enforcement set totrue, and no setting turns it off (ADR-6171). An IAM throw fails closed. An agent-run invocation also fails closed when its IAM check returns no persisted authorization decision. - Every failure exits before the accrual step. Lookup, binding, platform-only, surface, input and replay-input refusals throw before the tenant scope opens. IAM, billing, budget, entitlement, rules and handler failures leave through the catch block, which releases any reserved settlement. An invalid output throws after that. This is how ADR-052's rule that denials are free is enforced by structure, not by policy.
Source refs (11, verified at build)
packages/oxagen/src/kernel.ts#_invokeCoreInnerpackages/oxagen/src/kernel.ts#setBillingAdmissionGatepackages/oxagen/src/kernel.ts#setUsageRecorderpackages/oxagen/src/kernel.ts#cap.platformOnlypackages/oxagen/src/kernel.ts#assertValidatedInputpackages/iam/src/bootstrap.ts#machineKeyDenialpackages/iam/src/check-iam.ts#checkIAMpackages/billing/src/gau-bucket.ts#assertGauAvailablepackages/billing/src/spend-budget-gate.ts#assertWithinSpendBudgetpackages/billing/src/bootstrap.ts#bootstrapBillingRuntimepackages/rules/src/gate.ts#decision_rule_denied
checkIAM decision order
- The audit row stores
payload_hash, a sha256 of the serialised validated input, never the input itself. Each row takes the nextchain_seqof its organization's chain under a per-org Postgres advisory lock (iam.audit_chain_heads), andchain_hash = sha256(prev_hash | chain_seq, event_id, capability, payload_hash, outcome and every other column), whereprev_hashis the hash of the row one seq before.verifyAuditChainreports an edited row, a missing seq, a replaced row, a fork, and rows cut from the end against the head (#2973). - The audit write is fire-and-forget until too many writes are in flight, when the caller waits for it. It makes up to three attempts. A failed emission is captured to the
error_eventstable. - A machine key whose scope does not cover the capability is refused before
checkIAMruns, so that refusal writes noaudit_eventsrow and no decision.
Source refs (10, verified at build)
packages/iam/src/bootstrap.ts#machineKeyDenialpackages/iam/src/check-iam.ts#checkIAMpackages/iam/src/check-iam.ts#checkBuiltInRolespackages/iam/src/check-iam.ts#MAX_PENDING_AUDIT_WRITESpackages/iam/src/fetch-authz.ts#withOrgDbpackages/iam/src/emit-audit.ts#AuditEventRowpackages/iam/src/audit-chain-head.ts#appendAuditChainLinkspackages/iam/src/audit-chain-verify.ts#verifyAuditChainpackages/oxagen/src/iam/index.tspackages/run-evidence/src/digest.ts#digestJcs
Domains × surfaces
How many contracts in each domain are exposed on each surface. Read from packages/oxagen/capabilities.manifest.json.
| Domain | Contracts | agent | api | cli | mcp | Handlers |
|---|---|---|---|---|---|---|
agent | 44 | 21 | 41 | 15 | 42 | 43 |
api_key | 6 | 5 | 6 | · | 5 | 6 |
approval_rule | 5 | 5 | 5 | · | 5 | 5 |
asset | 1 | · | 1 | · | 1 | 1 |
assistant | 16 | 5 | 14 | 4 | 10 | 11 |
audit | 2 | 1 | 2 | 1 | 2 | 2 |
auth | 1 | · | · | · | · | 1 |
billing | 23 | 16 | 20 | 4 | 20 | 23 |
capability | 2 | 2 | 2 | · | 2 | 2 |
chat | 1 | · | 1 | · | 1 | 1 |
codegraph | 48 | 45 | 48 | · | 45 | 48 |
command | 2 | 2 | 2 | · | · | 2 |
configuration | 2 | 2 | 2 | · | 2 | 2 |
connection | 13 | 8 | 13 | · | 10 | 13 |
context | 38 | 23 | 30 | 17 | 38 | 38 |
control | 6 | 3 | 6 | 3 | 3 | 6 |
conversation | 12 | 10 | 12 | · | 12 | 12 |
cost | 4 | 4 | 4 | 3 | 4 | 4 |
credential | 1 | 1 | 1 | · | 1 | 1 |
environment | 6 | · | 6 | · | 6 | 6 |
graph | 7 | 6 | 6 | 3 | 6 | 6 |
iam | 6 | 6 | 6 | · | 6 | 6 |
integration | 7 | 7 | 7 | 6 | 7 | 7 |
kill_switch | 2 | 2 | 2 | · | 2 | 2 |
mandate | 6 | 6 | 6 | · | 6 | 6 |
model | 1 | 1 | 1 | · | 1 | 1 |
notification | 3 | 3 | 3 | · | 3 | 3 |
onboarding | 3 | 3 | 3 | · | 2 | 3 |
ontology | 2 | 2 | 2 | 2 | 2 | 2 |
org | 53 | 22 | 46 | 5 | 39 | 53 |
plugin | 19 | · | 19 | · | 19 | 19 |
privacy | 3 | 3 | 3 | · | 3 | 3 |
reference | 1 | 1 | 1 | · | 1 | 1 |
repo | 9 | 8 | 9 | 4 | 9 | 9 |
repository | 30 | 24 | 30 | 10 | 27 | 30 |
router | 3 | 2 | 3 | 3 | 3 | 3 |
run | 29 | 26 | 29 | 7 | 29 | 29 |
runtime | 21 | 4 | 21 | 18 | 20 | 21 |
schema | 23 | 10 | 22 | 21 | 21 | 23 |
secret | 8 | 5 | 8 | · | 8 | 8 |
shell | 1 | 1 | 1 | · | 1 | 1 |
skill | 11 | 9 | 10 | · | 9 | 11 |
spend | 35 | 29 | 35 | 6 | 29 | 35 |
system | 1 | 1 | 1 | · | 1 | 1 |
tacho | 31 | 5 | 28 | 5 | 9 | 31 |
telemetry | 3 | 1 | 3 | · | 1 | 3 |
tool | 24 | 5 | 24 | 2 | 22 | 24 |
toolbelt | 5 | 5 | 5 | · | 5 | 5 |
tools | 2 | 2 | 2 | · | 2 | 0 |
user | 5 | 4 | 5 | · | 3 | 5 |
work | 73 | 26 | 69 | 1 | 71 | 73 |
workspace | 33 | 24 | 30 | 2 | 30 | 33 |
Capability catalog
| Name | Domain | Mode | Surfaces | Layers | Handler |
|---|---|---|---|---|---|
answer_interjection | agent | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | agent.interjection.answer.ts |
assign_agent_role | agent | sync | agent api mcp | api · mcp · unit · docs · app | agent.role.assign.ts |
assign_agent_toolbelt | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.toolbelt.assign.ts |
authorize_mcp_server | agent | sync | api mcp | schema · api · mcp · unit · docs · app | agent.mcp.authorize.complete.ts |
cancel_agent_draft | agent | sync | api cli mcp | schema · api · mcp · cli · docs · app | agent.draft.cancel.ts |
delete_mcp_server | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.mcp.delete.ts |
draft_interjection_answer | agent | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | agent.interjection.draft.ts |
finish_agent_draft | agent | sync | api cli mcp | schema · api · mcp · cli · docs · app | agent.draft.finish.ts |
get_agent | agent | sync | agent api cli mcp | schema · api · mcp · unit · docs · app | agent.get.ts |
get_agent_draft | agent | sync | api cli mcp | schema · api · mcp · cli · docs · app | agent.draft.get.ts |
get_agent_role | agent | sync | agent api mcp | api · mcp · unit · docs | agent.role.get.ts |
get_agent_toolbelt | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.toolbelt.get.ts |
list_agent_roles | agent | sync | agent api mcp | api · mcp · unit · docs · app | agent.role.list.ts |
list_agent_tools | agent | sync | agent api mcp | schema · api · mcp · unit · docs | @oxagen/agent or inline |
list_agents | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.list.ts |
list_approvals | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.approval.list.ts |
list_attention | agent | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | agent.attention.list.ts |
list_fleet | agent | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs | agent.fleet.list.ts |
list_interjections | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.interjection.list.ts |
list_mcp_consents | agent | sync | agent api mcp | schema · api · mcp · unit · docs | agent.mcp_consent.list.ts |
list_mcp_servers | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.mcp.list.ts |
list_resolved_approvals | agent | sync | agent api cli mcp | schema · api · mcp · unit · docs · app | agent.approval.list_resolved.ts |
list_run_accounts | agent | sync | api mcp | schema · api · mcp · unit · docs · app | run-accounts.list.ts |
move_agent | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.move.ts |
record_reflection | agent | sync | mcp | schema · mcp · unit · docs | agent.memory.reflection.record.ts |
register_agent | agent | sync | api cli mcp | schema · api · unit · docs · app · mcp | agent.register.ts |
register_mcp_server | agent | sync | api mcp | schema · api · mcp · unit · docs · app | agent.mcp.register.ts |
remember_lesson | agent | sync | mcp | schema · mcp · unit · docs | agent.memory.lesson.remember.ts |
reopen_interjection | agent | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | agent.interjection.reopen.ts |
resolve_approval | agent | sync | api mcp | schema · api · mcp · unit · docs · app | agent.approval.resolve.ts |
resolve_mcp_consent | agent | sync | api mcp | schema · api · mcp · unit · docs · app | agent.mcp_consent.resolve.ts |
resolve_mcp_servers | agent | sync | schema · unit | agent.mcp.resolve.ts | |
retire_agent | agent | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | agent.retire.ts |
revoke_agent_role | agent | sync | agent api mcp | api · mcp · unit · docs · app | agent.role.revoke.ts |
rotate_agent_credential | agent | sync | api | schema · api · unit · docs · app | agent.credential.rotate.ts |
save_agent_draft | agent | sync | api cli mcp | schema · api · mcp · cli · docs · app | agent.draft.save.ts |
search_mcp_registry | agent | sync | agent api mcp | schema · api · mcp · unit · docs · app | agent.mcp.registry.search.ts |
set_agent_account_source | agent | sync | api mcp | schema · api · mcp · unit · docs · app | agent.account_source.set.ts |
set_agent_budget | agent | sync | api mcp | schema · api · mcp · unit · docs · app | agent.budget.set.ts |
set_agent_cache_keep_alive | agent | sync | api mcp | schema · api · mcp · unit · docs · app | agent.cache_keep_alive.set.ts |
set_agent_display_name | agent | sync | api cli mcp | schema · api · mcp · cli · docs · app | agent.display_name.set.ts |
set_mcp_enabled | agent | sync | api mcp | schema · api · mcp · unit · docs | agent.mcp.set_enabled.ts |
start_mcp_authorization | agent | sync | api mcp | schema · api · mcp · unit · docs · app | agent.mcp.authorize.start.ts |
suspend_agent | agent | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | agent.suspend.ts |
acknowledge_api_key_rotation | api_key | sync | agent api mcp | api · docs · mcp · unit · app | api.key.rotation.acknowledge.ts |
create_api_key | api_key | sync | agent api mcp | api · docs · mcp · unit · app | api.key.create.ts |
list_api_keys | api_key | sync | agent api mcp | api · docs · mcp · unit · app | api.key.list.ts |
list_decision_capabilities | api_key | sync | api | schema · api · unit · docs · app | api.key.decision_capabilities.list.ts |
revoke_api_key | api_key | sync | agent api mcp | api · docs · mcp · unit · app | api.key.revoke.ts |
rotate_api_key | api_key | sync | agent api mcp | api · docs · mcp · unit · app | api.key.rotate.ts |
delete_approval_rule | approval_rule | sync | agent api mcp | schema · api · mcp · unit · docs · app | approval_rule.delete.ts |
get_auto_eligibility | approval_rule | sync | agent api mcp | schema · api · mcp · unit · docs · app | approval.auto_eligibility.get.ts |
list_approval_rules | approval_rule | sync | agent api mcp | schema · api · mcp · unit · docs · app | approval_rule.list.ts |
set_approval_rule_enabled | approval_rule | sync | agent api mcp | schema · api · mcp · unit · docs · app | approval_rule.enabled.set.ts |
set_approval_rules | approval_rule | sync | agent api mcp | schema · api · mcp · unit · docs · app | approval_rule.set.ts |
upload_asset | asset | sync | api mcp | schema · api · mcp · unit · docs | asset.upload.ts |
answer_assistant_question | assistant | sync | api | schema · api · unit · docs · app | @oxagen/agent or inline |
ask_assistant | assistant | async | api mcp | schema · api · mcp · unit · docs · app | @oxagen/agent or inline |
cancel_assistant_turn | assistant | sync | api | schema · api · unit · docs · app | @oxagen/agent or inline |
draft_record | assistant | sync | agent api cli mcp | schema · api · mcp · unit · docs · app · cli | stella/draft-record.ts |
get_assistant_engine | assistant | sync | api mcp | schema · api · mcp · unit · docs · app | @oxagen/agent or inline |
get_assistant_reply | assistant | sync | api | schema · api · unit · docs · app | @oxagen/agent or inline |
get_briefing | assistant | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs | stella/briefing.ts |
get_operator_status | assistant | sync | agent api mcp | schema · api · mcp · unit · docs · app | operator.status.get.ts |
get_stella_permissions | assistant | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | stella/permissions.get.ts |
record_reply_feedback | assistant | sync | api mcp | schema · api · mcp · unit · docs · app | assistant.reply_feedback.record.ts |
render_chart | assistant | sync | agent | schema · unit · docs · app | assistant.chart.render.ts |
resolve_assistant_card | assistant | sync | api | schema · api · unit · docs · app | assistant.card.resolve.ts |
rewrite_field | assistant | sync | api mcp | schema · api · mcp · unit · docs · app | stella/rewrite-field.ts |
set_assistant_switch | assistant | sync | schema · unit · docs | assistant.switch.set.ts | |
set_stella_permissions | assistant | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | stella/permissions.set.ts |
upload_assistant_attachment | assistant | sync | api mcp | schema · api · mcp · unit · docs · app | assistant.attachment.upload.ts |
export_audit_events | audit | sync | api mcp | schema · api · mcp · unit · docs · app | audit.events.export.ts |
query_audit_log | audit | sync | agent api cli mcp | schema · api · mcp · unit · docs · app | audit.log.query.ts |
authorize_cli | auth | sync | schema · unit · docs · app | auth.cli.authorize.ts | |
create_prepaid_invoice | billing | sync | schema · unit · docs | billing.prepaid_invoice.create.ts | |
export_billing_statement | billing | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | billing.statement.export.ts |
get_billing_statement | billing | sync | api cli mcp | schema · api · mcp · cli · unit · docs | billing.statement.get.ts |
get_contract_rate | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.contract_rate.get.ts |
get_evidence_retention | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.evidence_retention.ts |
get_gau_bucket | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.gau_bucket.get.ts |
get_rate_card | billing | sync | agent api mcp | schema · api · mcp · unit · docs | billing.action_rate_card.ts |
get_spend_budget | billing | sync | agent api cli mcp | schema · api · docs · mcp · unit · app | billing.budget.get.ts |
get_subscription | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.subscription.read.ts |
get_usage_breakdown | billing | sync | agent api mcp | schema · api · mcp · unit · docs | billing.usage.breakdown.ts |
list_invoices | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.invoice.list.ts |
list_prepaid_orders | billing | sync | api mcp | schema · api · mcp · unit · docs | billing.prepaid_order.list.ts |
open_billing_portal | billing | sync | api mcp | schema · api · mcp · unit · docs | billing.portal_session.create.ts |
preview_action_cost | billing | sync | agent api mcp | schema · api · mcp · unit · docs | billing.action_estimate.ts |
purchase_credits | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.credits.purchase.ts |
purchase_gau_bucket | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.gau_bucket.purchase.ts |
refund_credits | billing | sync | api mcp | schema · api · mcp · unit · docs | billing.credits.refund.ts |
set_contract_terms | billing | sync | schema · unit · docs | billing.contract_terms.set.ts | |
set_org_billing_terms | billing | sync | schema · unit · docs | billing.org_terms.set.ts | |
set_sandbox_slots | billing | sync | agent api mcp | schema · api · mcp · unit · docs | billing.sandbox_slots.set.ts |
set_spend_budget | billing | sync | agent api cli mcp | schema · api · docs · mcp · unit · app | billing.budget.set.ts |
set_subscription_seats | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.subscription_seats.set.ts |
start_subscription_upgrade | billing | sync | agent api mcp | schema · api · mcp · unit · docs · app | billing.subscription_upgrade.start.ts |
get_capability_registry | capability | sync | agent api mcp | api · mcp · unit · docs | capability.registry.get.ts |
list_capability_registry | capability | sync | agent api mcp | api · mcp · unit · docs | capability.registry.list.ts |
send_message | chat | async | api mcp | schema · api · mcp · unit · docs | chat.message.send.ts |
check_change | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.check_change.ts |
create_work_items | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.create_work_items.ts |
embed_code_graph_cards | codegraph | sync | api | schema · api · unit · docs | codegraph.embed_code_graph_cards.ts |
export_openapi_draft | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.export_openapi_draft.ts |
find_definition | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.find_definition.ts |
find_implementations | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.find_implementations.ts |
find_references | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.find_references.ts |
get_api_docs | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_api_docs.ts |
get_blast_radius | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_blast_radius.ts |
get_code_graph_base | codegraph | sync | api | schema · api · unit · docs | codegraph.get_code_graph_base.ts |
get_code_graph_embedding_key | codegraph | sync | api | schema · api · unit · docs | codegraph.get_code_graph_embedding_key.ts |
get_code_graph_settings | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs · app | codegraph.get_code_graph_settings.ts |
get_code_graph_spend | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs · app | codegraph.get_code_graph_spend.ts |
get_dataflow_slice | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_dataflow_slice.ts |
get_domain_brief | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_domain_brief.ts |
get_env_vars | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_env_vars.ts |
get_execution_flow | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_execution_flow.ts |
get_infra | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_infra.ts |
get_intended_behavior | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_intended_behavior.ts |
get_module_coupling | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_module_coupling.ts |
get_repair_context | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_repair_context.ts |
get_repo_map | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_repo_map.ts |
get_symbol_history | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.get_symbol_history.ts |
label_link | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.label_link.ts |
list_change_set_symbols | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_change_set_symbols.ts |
list_ci_jobs | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_ci_jobs.ts |
list_co_changes | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_co_changes.ts |
list_code_graph_releases | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_code_graph_releases.ts |
list_domain_reviews | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs · app | codegraph.list_domain_reviews.ts |
list_governing_decisions | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_governing_decisions.ts |
list_held_decisions | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_held_decisions.ts |
list_link_labels | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_link_labels.ts |
list_link_reviews | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs · app | codegraph.list_link_reviews.ts |
list_neighbors | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_neighbors.ts |
list_scripts | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_scripts.ts |
list_similar_symbols | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_similar_symbols.ts |
list_symbol_authorship | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_symbol_authorship.ts |
list_symbol_docs | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_symbol_docs.ts |
list_unit_tests | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.list_unit_tests.ts |
localize_fault | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.localize_fault.ts |
post_intent_question | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.post_intent_question.ts |
propose_code_graph_settings | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs · app | codegraph.propose_code_graph_settings.ts |
propose_edge | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.propose_edge.ts |
rank_symbols | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.rank_symbols.ts |
review_domain | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs · app | codegraph.review_domain.ts |
review_link | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs · app | codegraph.review_link.ts |
search_code_graph | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.search_code_graph.ts |
trace_spec | codegraph | sync | agent api mcp | schema · api · mcp · unit · docs | codegraph.trace_spec.ts |
search_command_menu | command | sync | agent api | schema · api · unit · docs | command.menu.search.ts |
suggest_commands | command | sync | agent api | schema · api · unit · docs | command.menu.suggest.ts |
get_clone_draft | configuration | sync | agent api mcp | schema · api · mcp · docs · app | configuration.clone.get.ts |
propose_configuration_clone | configuration | sync | agent api mcp | schema · api · mcp · docs · app | configuration.clone.propose.ts |
add_token_connection | connection | sync | api | schema · api · docs | connection.token.add.ts |
authorize_connection | connection | sync | api | schema · api · docs | connection.authorization.complete.ts |
create_connection | connection | sync | agent api mcp | schema · api · mcp · unit · docs · app | connection.create.ts |
delete_connection | connection | async | agent api mcp | schema · api · mcp · unit · docs | connection.delete.ts |
get_connection | connection | sync | api mcp | schema · api · mcp · unit · docs · app | connection.get.ts |
get_connection_mappings | connection | sync | api mcp | schema · api · mcp · unit · docs | connection.mappings.get.ts |
list_connections | connection | sync | agent api mcp | schema · api · mcp · unit · docs · app | connection.list.ts |
pause_connection | connection | sync | agent api mcp | schema · api · mcp · unit · docs | connection.pause.ts |
preview_connection | connection | sync | agent api mcp | schema · api · mcp · unit · docs | connection.preview.ts |
set_connection_mappings | connection | sync | agent api mcp | schema · api · mcp · unit · docs | connection.mappings.set.ts |
start_connection_authorization | connection | sync | api | schema · api · docs | connection.authorization.start.ts |
suggest_connection_mappings | connection | sync | agent api mcp | schema · api · mcp · unit · docs | connection.mappings.suggest.ts |
update_connection | connection | sync | agent api mcp | schema · api · mcp · unit · docs | connection.update.ts |
append_record | context | sync | agent api mcp | schema · api · mcp · unit · docs | steering.records.append.ts |
approve_steering_pr | context | sync | api mcp | schema · api · unit · docs · app · mcp | steering.pr.approve.ts |
commit_markdown_import | context | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | markdown-import/index.ts |
dismiss_memories | context | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | steering.memories.dismiss.ts |
dismiss_proposal | context | sync | agent api cli mcp | schema · api · unit · docs · app · mcp · cli | steering.proposal.dismiss.ts |
drop_memory_record | context | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | steering.memory_pr_records.drop.ts |
get_published_steering | context | sync | mcp | schema · mcp · unit · docs | context.steering.published.get.ts |
get_record | context | sync | agent mcp | schema · mcp · unit · docs · app | steering.records.get.ts |
get_steering_deliveries | context | sync | agent api mcp | schema · api · mcp · docs · app | context.steering.deliveries.ts |
get_steering_index | context | sync | api cli mcp | schema · api · cli · unit · docs · mcp | context.steering.index.get.ts |
get_steering_layout | context | sync | agent api mcp | schema · api · mcp · docs · app | context.steering.layout.ts |
get_steering_pr | context | sync | agent api cli mcp | schema · api · mcp · unit · docs · app · cli | steering.pr.get.ts |
get_steering_pr_diff | context | sync | agent api mcp | schema · api · mcp · unit · docs · app | steering.pr.diff.get.ts |
get_steering_skill | context | sync | agent mcp | schema · unit · docs · app · mcp | steering.skill.get.ts |
get_steering_sync_state | context | sync | agent api mcp | schema · api · mcp · app | context.steering.sync_state.ts |
get_workspace_memory | context | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | steering.memories.get.ts |
list_memory_pr_records | context | sync | api mcp | schema · api · mcp · unit · docs · app | steering.memory_pr_records.list.ts |
list_proposals | context | sync | agent api cli mcp | schema · api · mcp · unit · docs · app · cli | steering.proposal.list.ts |
list_records | context | sync | agent mcp | schema · mcp · unit · docs · app | steering.records.list.ts |
list_steering_record_deliveries | context | sync | agent api mcp | schema · api · mcp · unit · docs · app | context.steering.record_deliveries.ts |
list_steering_records | context | sync | agent api mcp | schema · api · docs · mcp · unit | steering.record.list.ts |
list_steering_skills | context | sync | mcp | schema · mcp · unit · docs · app | steering.skills.list.ts |
list_workspace_memories | context | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | steering.memories.list.ts |
merge_pr_without_review | context | sync | agent api mcp | schema · api · unit · docs · app · mcp | steering.pr.merge_without_review.ts |
merge_steering_pr | context | sync | agent api cli mcp | schema · api · unit · docs · app · mcp · cli | steering.pr.merge.ts |
open_steering_pr | context | sync | agent api cli mcp | schema · api · unit · docs · app · mcp · cli | steering.pr.open.ts |
parse_markdown_import | context | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | markdown-import/index.ts |
promote_memories | context | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | steering.memories.promote.ts |
promote_steering_record | context | sync | api mcp | schema · api · docs · unit · mcp | steering.record.promote.ts |
propose_record | context | sync | agent api cli mcp | schema · api · mcp · unit · docs · app · cli | steering.proposal.create.ts |
propose_steering | context | sync | mcp | schema · mcp · unit · docs | steering.propose.ts |
read_steering | context | sync | mcp | schema · mcp · unit · docs | steering.read.ts |
refresh_steering_pr | context | sync | agent api mcp | schema · api · unit · docs · app · mcp | steering.pr.refresh.ts |
restore_managed_block | context | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | steering.pr.restore_managed_block.ts |
revert_steering_pr | context | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | steering.pr.revert.ts |
revise_steering_record | context | sync | agent api mcp | schema · api · unit · docs · app · mcp | steering.record.revise.ts |
search_steering | context | sync | mcp | schema · mcp · unit · docs | steering.search.ts |
suggest_memory_drafts | context | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | steering.memories.suggest.ts |
dispatch_command | control | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | tacho.command.dispatch.ts |
fetch_commands | control | sync | api | schema · api · unit · docs | tacho.command.fetch.ts |
list_commands | control | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | tacho.command.list.ts |
pause_workspace_runs | control | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | tacho.workspace_runs.pause.ts |
redeem_workspace_connection | control | sync | api | schema · api · docs | workspace.connect.redeem.ts |
set_host_connection | control | sync | api | schema · api · unit · docs | host.connection.set.ts |
add_conversation_attachment | conversation | sync | agent api mcp | schema · api · mcp · unit · docs | conversation.attachment.add.ts |
archive_conversation | conversation | sync | agent api mcp | schema · api · mcp · unit · docs · app | conversation.archive.ts |
clear_conversation | conversation | sync | api mcp | schema · api · mcp · docs · app | conversation.clear.ts |
delete_conversation | conversation | sync | agent api mcp | schema · api · mcp · unit · docs · app | conversation.delete.ts |
export_conversation | conversation | sync | agent api mcp | schema · api · mcp · unit · docs · app | conversation.export.ts |
fork_conversation | conversation | sync | agent api mcp | schema · api · mcp · unit · docs · app | conversation.fork.ts |
get_conversation | conversation | sync | agent api mcp | schema · api · mcp · unit · docs · app | conversation.get.ts |
list_conversation_files | conversation | sync | agent api mcp | schema · api · mcp · unit · docs | conversation.files.list.ts |
list_conversations | conversation | sync | agent api mcp | schema · api · mcp · unit · docs · app | conversation.list.ts |
post_conversation_message | conversation | sync | api mcp | schema · api · docs · mcp | conversation.chat.ts |
purge_conversations | conversation | sync | agent api mcp | schema · api · docs · mcp · unit | conversation.purge.ts |
rename_conversation | conversation | sync | agent api mcp | schema · api · docs · mcp · unit | conversation.rename.ts |
list_price_entries | cost | sync | agent api cli mcp | schema · api · mcp · app · unit · docs | cost.price_entry.list.ts |
list_unpriced_models | cost | sync | agent api mcp | schema · api · mcp · app · unit · docs | cost.unpriced_model.list.ts |
remove_price_entry | cost | sync | agent api cli mcp | schema · api · mcp · cli · app · unit · docs | cost.price_entry.remove.ts |
set_price_entry | cost | sync | agent api cli mcp | schema · api · mcp · cli · app · unit · docs | cost.price_entry.set.ts |
list_credential_grants | credential | sync | agent api mcp | schema · api · mcp · unit · docs · app | credential.grant.list.ts |
create_environment | environment | sync | api mcp | api · mcp · unit · docs | environment.create.ts |
delete_environment | environment | sync | api mcp | api · mcp · unit · docs | environment.delete.ts |
get_environment | environment | sync | api mcp | api · mcp · unit · docs | environment.get.ts |
list_environments | environment | sync | api mcp | api · mcp · unit · docs | environment.list.ts |
set_default_environment | environment | sync | api mcp | api · mcp · unit · docs | environment.set_default.ts |
update_environment | environment | sync | api mcp | api · mcp · unit · docs | environment.update.ts |
author_graph_rule | graph | sync | api mcp | schema · api · mcp · unit · docs | @oxagen/agent or inline |
get_graph_stats | graph | sync | agent api mcp | schema · api · mcp · unit · docs | graph.stats.ts |
get_node | graph | sync | agent api cli mcp | schema · api · mcp · unit · docs | graph.node.get.ts |
get_node_labels | graph | sync | agent | schema · unit · docs | graph.node_label.get.ts |
list_nodes | graph | sync | agent api mcp | schema · api · mcp · unit · docs | graph.node.list.ts |
search_graph | graph | sync | agent api cli mcp | schema · api · mcp · unit · docs | graph.search.ts |
search_nodes | graph | sync | agent api cli mcp | schema · api · mcp · unit · docs | graph.node.search.ts |
assign_member_role | iam | sync | agent api mcp | schema · api · mcp · unit · docs · app | iam.role.member.assign.ts |
create_role | iam | sync | agent api mcp | schema · api · mcp · unit · docs · app | iam.role.create.ts |
delete_role | iam | sync | agent api mcp | schema · api · mcp · unit · docs · app | iam.role.delete.ts |
list_iam_roles | iam | sync | agent api mcp | schema · api · mcp · unit · docs · app | iam.role.list.ts |
set_role_grants | iam | sync | agent api mcp | schema · api · mcp · unit · docs · app | iam.role.grants.set.ts |
unassign_member_role | iam | sync | agent api mcp | schema · api · mcp · unit · docs · app | iam.role.member.unassign.ts |
configure_integration | integration | sync | agent api cli mcp | schema · api · mcp · unit · docs | integration.configure.ts |
delete_integration | integration | async | agent api cli mcp | schema · api · mcp · unit · docs | integration.delete.ts |
get_integration | integration | sync | agent api cli mcp | schema · api · mcp · unit · docs | integration.get.ts |
get_integration_metrics | integration | sync | agent api mcp | schema · api · mcp · unit · docs | integration.metrics.ts |
install_integration | integration | async | agent api cli mcp | schema · api · mcp · unit · docs | integration.install.ts |
list_integrations | integration | sync | agent api cli mcp | schema · api · mcp · unit · docs | integration.list.ts |
sync_integration | integration | async | agent api cli mcp | schema · api · mcp · unit · docs | integration.sync.ts |
list_kill_switches | kill_switch | sync | agent api mcp | schema · api · mcp · unit · docs · app | kill_switch.list.ts |
set_kill_switch | kill_switch | sync | agent api mcp | schema · api · mcp · unit · docs · app | kill_switch.set.ts |
get_mandate | mandate | sync | agent api mcp | schema · api · mcp · unit · docs · app | mandate.get.ts |
grant_mandate | mandate | sync | agent api mcp | schema · api · mcp · unit · docs · app | mandate.grant.ts |
list_mandates | mandate | sync | agent api mcp | schema · api · mcp · unit · docs · app | mandate.list.ts |
request_mandate | mandate | sync | agent api mcp | schema · api · mcp · unit · docs · app | mandate.request.ts |
revoke_mandate | mandate | sync | agent api mcp | schema · api · mcp · unit · docs · app | mandate.revoke.ts |
update_mandate_limits | mandate | sync | agent api mcp | schema · api · mcp · unit · docs · app | mandate.limits.update.ts |
list_model_capabilities | model | sync | agent api mcp | api · mcp · unit · docs | model.capability.list.ts |
list_notifications | notification | sync | agent api mcp | api · docs · mcp · unit · app | notification.list.ts |
mark_notification | notification | sync | agent api mcp | api · app · docs · mcp · unit | notification.mark.ts |
mark_notifications_read | notification | sync | agent api mcp | api · docs · mcp · unit · app | notification.mark_all.ts |
advance_onboarding | onboarding | sync | agent api | schema · api · unit · docs · app | onboarding.advance.ts |
get_first_frame | onboarding | sync | agent api mcp | schema · api · mcp · unit · docs · app | onboarding.first_frame.get.ts |
get_onboarding_state | onboarding | sync | agent api mcp | schema · api · mcp · unit · docs · app | onboarding.state.get.ts |
get_ontology_neighbors | ontology | sync | agent api cli mcp | schema · api · mcp · unit · docs | ontology.neighbors.ts |
query_ontology | ontology | sync | agent api cli mcp | schema · api · mcp · unit · docs | ontology.query.ts |
accept_member_invite | org | sync | agent api mcp | schema · api · mcp · unit · docs · app | org.member_invite.accept.ts |
add_model_credential | org | sync | api | schema · api · unit · docs · app | model-credential.add.ts |
add_org_member | org | sync | agent api mcp | schema · api · mcp · unit · docs | org.member.add.ts |
answer_credential_reauth | org | sync | api | schema · api · unit · docs · app | model-credential.reauth.answer.ts |
archive_model_tier | org | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | model_tier.archive.ts |
authorize_slack_connection | org | sync | schema · app · unit · docs | org.slack_connection.authorize.ts | |
change_member_role | org | sync | agent api mcp | api · docs · mcp · unit · app | org.member_role.change.ts |
check_model_credential | org | sync | api mcp | schema · api · mcp · unit · docs · app | model-credential.check.ts |
create_model_tier | org | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | model_tier.create.ts |
create_org | org | sync | agent api mcp | schema · api · mcp · unit · docs · app | org.create.ts |
create_scim_token | org | sync | api | schema · api · unit · docs · app | org.scim_token.create.ts |
create_sso_provider | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.sso.create.ts |
create_team | org | sync | agent api mcp | schema · api · mcp · unit · docs | org.team.create.ts |
decline_member_invite | org | sync | agent api mcp | schema · api · mcp · unit · docs · app | org.member_invite.decline.ts |
delete_model_credential | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.model_credential.delete.ts |
delete_slack_connection | org | sync | schema · app · unit · docs | org.slack_connection.delete.ts | |
delete_sso_provider | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.sso.delete.ts |
delete_team | org | sync | agent api mcp | schema · api · mcp · unit · docs | org.team.delete.ts |
execute_scim_request | org | sync | schema · unit · docs | scim.request.ts | |
get_credential_reauth | org | sync | api | schema · api · unit · docs · app | model-credential.reauth.get.ts |
get_data_plane | org | sync | agent api mcp | schema · api · mcp · unit · docs · app | org.data_plane.get.ts |
get_model_credential | org | sync | agent api mcp | schema · api · mcp · unit · docs · app | org.model_credential.get.ts |
get_org_settings | org | sync | api mcp | schema · api · mcp · unit · docs | org.settings.read.ts |
get_slack_connection | org | sync | schema · app · unit · docs | org.slack_connection.get.ts | |
list_members | org | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.member.list.ts |
list_model_credentials | org | sync | api mcp | schema · api · mcp · unit · docs · app | model-credential.list.ts |
list_model_tiers | org | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | model_tier.list.ts |
list_orgs | org | sync | agent api mcp | schema · api · mcp · unit · docs · app | org.list.ts |
list_slack_channels | org | sync | schema · app · unit · docs | org.slack_channels.list.ts | |
list_sso_providers | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.sso.list.ts |
list_teams | org | sync | agent api mcp | schema · api · mcp · unit · docs | org.team.list.ts |
remove_model_credential | org | sync | api mcp | schema · api · mcp · unit · docs · app | model-credential.remove.ts |
remove_org_member | org | sync | agent api mcp | api · docs · mcp · unit · app | org.member.remove.ts |
resend_member_invite | org | sync | agent api mcp | schema · api · mcp · docs · app | org.member_invite.resend.ts |
revoke_member_invite | org | sync | agent api mcp | schema · api · mcp · docs · app | org.member_invite.revoke.ts |
revoke_scim_token | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.scim_token.revoke.ts |
rotate_model_credential | org | sync | api | schema · api · unit · docs · app | model-credential.rotate.ts |
rotate_scim_token | org | sync | api | schema · api · unit · docs · app | org.scim_token.rotate.ts |
set_data_plane | org | sync | api mcp | schema · api · mcp · unit · docs | org.data_plane.set.ts |
set_model_credential | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.model_credential.set.ts |
set_model_tier_model | org | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | model_tier.model.set.ts |
set_slack_channel | org | sync | schema · app · unit · docs | org.slack_channel.set.ts | |
set_sso_group_roles | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.sso.group_roles.set.ts |
set_sso_policy | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.sso.policy.set.ts |
set_team_members | org | sync | agent api mcp | schema · api · mcp · unit · docs | org.team.members.set.ts |
start_credential_reauth | org | sync | api | schema · api · unit · docs · app | model-credential.reauth.start.ts |
start_slack_connection | org | sync | schema · app · unit · docs | org.slack_connection.start.ts | |
update_model_credential | org | sync | api mcp | schema · api · mcp · unit · docs · app | model-credential.update.ts |
update_model_tier | org | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | model_tier.update.ts |
update_org_settings | org | sync | agent api mcp | schema · api · mcp · unit · docs · app | org.settings.write.ts |
update_sso_provider | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.sso.update.ts |
verify_model_credential | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.model_credential.verify.ts |
verify_sso_domain | org | sync | api mcp | schema · api · mcp · unit · docs · app | org.sso.verify_domain.ts |
add_plugin_registry | plugin | sync | api mcp | api · docs · mcp · unit | plugin.registry.add.ts |
browse_plugin_catalog | plugin | sync | api mcp | api · docs · mcp · unit | plugin.catalog.browse.ts |
get_auth_alerts | plugin | sync | api mcp | api · docs · mcp · unit | plugin.settings.get_auth_alerts.ts |
get_catalog_plugin | plugin | sync | api mcp | api · docs · mcp · unit | plugin.catalog.get.ts |
get_plugin_schema | plugin | sync | api mcp | schema · api · mcp · unit · docs | plugin.schema.get.ts |
install_plugin | plugin | sync | api mcp | api · docs · mcp · unit | plugin.org.install.ts |
install_plugins_bulk | plugin | sync | api mcp | api · docs · mcp · unit | plugin.org.install_bulk.ts |
list_plugin_registries | plugin | sync | api mcp | api · docs · mcp · unit | plugin.registry.list.ts |
list_plugin_versions | plugin | sync | api mcp | schema · api · mcp · unit · docs | plugin.version.list.ts |
list_plugins | plugin | sync | api mcp | api · docs · mcp · unit | plugin.org.list.ts |
reauth_plugin_credential | plugin | sync | api mcp | api · docs · mcp · unit | plugin.credential.reauth.ts |
remove_plugin_registry | plugin | sync | api mcp | api · docs · mcp · unit | plugin.registry.remove.ts |
revoke_plugin_credential | plugin | sync | api mcp | api · docs · mcp · unit | plugin.credential.revoke.ts |
set_auth_alerts | plugin | sync | api mcp | api · docs · mcp · unit | plugin.settings.set_auth_alerts.ts |
set_plugin_enabled | plugin | sync | api mcp | api · docs · mcp · unit | plugin.set_enabled.ts |
set_plugin_secret | plugin | sync | api mcp | api · docs · mcp · unit | plugin.credential.set_secret.ts |
sync_plugin_catalog | plugin | sync | api mcp | api · mcp · unit · docs | plugin.catalog.sync.handler.ts |
uninstall_plugin | plugin | sync | api mcp | api · docs · mcp · unit | plugin.org.uninstall.ts |
validate_plugin_schema | plugin | sync | api mcp | schema · api · mcp · unit · docs | plugin.schema.validate.ts |
erase_data | privacy | async | agent api mcp | schema · api · mcp · unit · docs | privacy.data.erase.ts |
export_data | privacy | async | agent api mcp | schema · api · mcp · unit · docs · app | privacy.data.export.ts |
get_export_status | privacy | sync | agent api mcp | schema · api · mcp · unit · docs · app | privacy.data.export.status.ts |
search_references | reference | sync | agent api mcp | schema · api · mcp · docs | reference.search.ts |
configure_repo | repo | sync | agent api cli mcp | schema · api · mcp · unit · docs | repo.configure.ts |
get_ci_status | repo | sync | agent api mcp | api · mcp · docs | repo.ci.status.ts |
get_pr | repo | sync | agent api mcp | api · mcp · docs | repo.pr.get.ts |
get_pr_diff | repo | sync | agent api mcp | api · mcp · docs | repo.pr.diff.ts |
get_repo_metrics | repo | sync | agent api mcp | schema · api · mcp · unit · docs | repo.metrics.ts |
list_branches | repo | sync | api mcp | api · mcp · unit | repo.branch.list.ts |
pause_repo | repo | sync | agent api cli mcp | schema · api · mcp · unit · docs | repo.pause.ts |
resume_repo | repo | sync | agent api cli mcp | schema · api · mcp · unit · docs | repo.resume.ts |
sync_repo | repo | async | agent api cli mcp | schema · api · mcp · unit · docs | repo.sync.ts |
attach_github_installation | repository | sync | api | schema · api · unit · docs · app | repository.installation.attach.ts |
attach_gitlab_project | repository | sync | api | schema · api · unit · docs | repository.gitlab.attach.ts |
get_main_repository | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | repository.main.get.ts |
get_repository_tree | repository | sync | agent api cli mcp | schema · api · mcp · docs · app | repository.tree.get.ts |
get_steering_repo | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | steering_repo.read.ts |
import_repository_config | repository | sync | api mcp | schema · api · mcp · docs · app | repository.config.import.ts |
import_workspace_steering | repository | sync | api mcp | schema · api · mcp · unit · docs · app | steering_repo.import.ts |
link_repository | repository | sync | agent api cli mcp | schema · api · mcp · unit · docs · app | repository.link.ts |
list_ci_runs | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | forge.ci_runs.list.ts |
list_code_repository_findings | repository | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | code-repo-check/handlers.ts |
list_defects | repository | sync | agent api mcp | schema · api · mcp · unit · docs | forge.defects.list.ts |
list_forge_pull_requests | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | forge.pull_requests.list.ts |
list_github_installations | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | repository.installation.candidates.ts |
list_installation_repositories | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | repository.installation.list.ts |
list_org_installation_repositories | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | repository.org_installation.list.ts |
list_repositories | repository | sync | agent api cli mcp | schema · api · mcp · docs · app | repository.list.ts |
list_review_findings | repository | sync | agent api mcp | schema · api · mcp · unit · docs | forge.review_findings.list.ts |
list_steering_repo_destinations | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | steering_repo.destinations.list.ts |
list_working_copies | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | repository.working_copy.list.ts |
open_init_pr | repository | sync | agent api cli mcp | schema · api · mcp · docs | repository.init_pr.open.ts |
parse_repository_config | repository | sync | api mcp | schema · api · mcp · unit · docs · app | repository.config.parse.ts |
promote_instruction_to_steering | repository | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | code-repo-check/handlers.ts |
record_working_copy | repository | sync | api cli mcp | schema · api · cli · unit · docs · mcp | repository.working_copy.record.ts |
repair_steering_repo | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | steering_repo.repair.ts |
retry_steering_repo_provision | repository | sync | agent api | schema · api · unit · docs · app | steering_repo.provision.retry.ts |
scan_repository_config | repository | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs | repository.config.scan.ts |
set_defect_origin | repository | sync | agent api mcp | schema · api · mcp · unit · docs | forge.defect_origin.set.ts |
set_production_branch | repository | sync | agent api cli mcp | schema · api · mcp · docs · app | repository.production_branch.set.ts |
set_workspace_repositories | repository | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.repositories.set.ts |
unlink_repository | repository | sync | agent api cli mcp | schema · api · mcp · docs · app | repository.unlink.ts |
get_routing_policy | router | sync | agent api cli mcp | schema · api · mcp · docs | router.policy.get.ts |
preview_routing_decision | router | sync | api cli mcp | schema · api · mcp · docs | router.decision.preview.ts |
set_routing_policy | router | sync | agent api cli mcp | schema · api · mcp · docs | router.policy.set.ts |
authorize_issue_provider | run | sync | api mcp | schema · api · docs · mcp | run.issue.authorization.complete.ts |
edit_run | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | run.edit.ts |
export_run | run | async | agent api mcp | schema · api · unit · docs · app · mcp | run.export.ts |
get_change_set | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | forge.changes.get.ts |
get_commit_diff | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | forge.commit.diff.get.ts |
get_revision_diff | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | forge.revision.diff.get.ts |
get_run | run | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | run.get.ts |
get_run_chain | run | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | run.chain.get.ts |
get_run_context | run | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | run.context.get.ts |
get_run_cost | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | run.cost.ts |
get_run_export | run | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | run.export.get.ts |
get_run_frame_body | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | run.frame_body.get.ts |
get_run_issue_providers | run | sync | agent api mcp | schema · api · docs · mcp | run.issue.providers.get.ts |
get_run_issues | run | sync | agent api mcp | schema · api · mcp · app · unit · docs | run.issues.get.ts |
get_run_outputs | run | sync | agent api mcp | schema · api · unit · docs · mcp | run.outputs.get.ts |
get_run_report | run | sync | agent api mcp | schema · api · mcp · unit · docs | run.report.get.ts |
get_run_tasks | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | run.tasks.get.ts |
get_run_transcript | run | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | run.transcript.get.ts |
get_run_turns | run | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs | run.turns.get.ts |
get_run_work | run | sync | agent api mcp | schema · api · app · docs · mcp | run.work.get.ts |
list_recent_runs | run | sync | agent api mcp | schema · api · mcp · unit · docs | run.recent.list.ts |
list_run_commits | run | sync | agent api mcp | schema · api · mcp · unit · docs | forge.run.commits.list.ts |
list_runs | run | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | run.list.ts |
list_sensitive_detections | run | sync | agent api mcp | schema · api · mcp · unit · docs | run.sensitive_detections.ts |
post_run_checkpoint | run | sync | api mcp | schema · api · mcp · docs | run.checkpoint.post.ts |
seal_run | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | run.seal.ts |
set_run_classification | run | sync | agent api mcp | schema · api · mcp · unit · docs · app | run.classification.set.ts |
start_issue_authorization | run | sync | api mcp | schema · api · docs · mcp | run.issue.authorization.begin.ts |
summarize_run | run | async | agent api mcp | schema · api · unit · docs · app · mcp | run.summarize.ts |
check_sandbox_template | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-template.test-build.ts |
connect_modal_account | runtime | sync | api mcp | schema · api · mcp · unit · docs · app | modal-account.connect.ts |
create_runtime | runtime | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | runtime.create.ts |
create_sandbox_runtime | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-runtime.create.ts |
delete_runtime | runtime | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | runtime.delete.ts |
disconnect_modal_account | runtime | sync | api mcp | schema · api · mcp · docs · app | modal-account.disconnect.ts |
generate_sandbox_template | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-template.generate.ts |
get_modal_account | runtime | sync | api mcp | schema · api · mcp · docs · app | modal-account.get.ts |
get_sandbox_run | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-run.get.ts |
get_sandbox_template_build_log | runtime | sync | api cli mcp | schema · api · mcp · cli · docs · app | sandbox-template.build-log.get.ts |
get_sandbox_template_test | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-template.test-build.get.ts |
launch_sandbox_run | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-run.launch.ts |
list_runtimes | runtime | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | runtime.list.ts |
list_sandbox_runs | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-run.list.ts |
list_sandbox_runtimes | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-runtime.list.ts |
open_run_terminal | runtime | sync | api cli | schema · api · cli · unit · docs · app | run-terminal.open.ts |
setup_sandbox_runtime | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs | sandbox-runtime.setup.ts |
start_sandbox_review | runtime | sync | api cli mcp | schema · api · mcp · cli · docs | sandbox-run.review.ts |
stop_sandbox_run | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-run.stop.ts |
update_runtime | runtime | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | runtime.update.ts |
update_sandbox_runtime | runtime | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | sandbox-runtime.update.ts |
create_schema_version | schema | sync | api cli mcp | schema · api · mcp · docs | schema.version.create.ts |
delete_schema | schema | sync | agent | schema · docs | schema.delete.ts |
delete_schema_label | schema | sync | api cli mcp | schema · api · mcp · docs | schema.label.delete.ts |
delete_schema_property | schema | sync | api cli mcp | schema · api · mcp · docs | schema.property.delete.ts |
delete_schema_relationship | schema | sync | api cli mcp | schema · api · mcp · docs | schema.relationship.delete.ts |
diff_schema_versions | schema | sync | api cli mcp | schema · api · mcp · docs | schema.version.diff.ts |
dispatch_schema_reconcile | schema | async | api cli mcp | schema · api · mcp · docs | schema.reconcile.dispatch.ts |
export_schema | schema | sync | api cli mcp | schema · api · mcp · docs | schema.export.ts |
get_reconcile_status | schema | sync | api cli mcp | schema · api · mcp · docs | schema.reconcile.status.ts |
get_registry_config | schema | sync | api cli mcp | schema · api · mcp · docs | schema.registry.config.ts |
get_schema_registry | schema | sync | api cli mcp | schema · api · mcp · docs | schema.registry.get.ts |
list_schema_versions | schema | sync | api cli mcp | schema · api · mcp · docs | schema.version.list.ts |
list_schemas | schema | sync | agent api cli mcp | schema · api · mcp · docs | schema.list.ts |
pin_schema_version | schema | sync | api cli mcp | schema · api · mcp · docs | schema.version.pin.ts |
recommend_schema | schema | sync | agent api cli mcp | schema · api · mcp · docs | schema.recommend.ts |
run_schema_chat | schema | sync | agent api | schema · api · docs | schema.chat.ts |
setup_schema | schema | sync | agent api cli mcp | schema · api · mcp · docs | schema.setup.ts |
toggle_schema | schema | sync | api cli mcp | schema · api · mcp · docs | schema.toggle.ts |
upsert_schema_label | schema | sync | agent api cli mcp | schema · api · mcp · docs | schema.label.upsert.ts |
upsert_schema_property | schema | sync | agent api cli mcp | schema · api · mcp · docs | schema.property.upsert.ts |
upsert_schema_relationship | schema | sync | agent api cli mcp | schema · api · mcp · docs | schema.relationship.upsert.ts |
validate_schema_node | schema | sync | agent api cli mcp | schema · api · mcp · docs | schema.validate.node.ts |
validate_schema_relationship | schema | sync | agent api cli mcp | schema · api · mcp · docs | schema.validate.relationship.ts |
delete_secret_key | secret | sync | agent api mcp | api · mcp · unit · docs | secret.key.delete.ts |
export_secrets | secret | sync | api mcp | api · mcp · unit · docs | secret.export.ts |
import_env_secrets | secret | sync | api mcp | api · mcp · unit · docs | secret.import_env.ts |
list_secret_keys | secret | sync | agent api mcp | api · mcp · unit · docs | secret.key.list.ts |
reveal_secret | secret | sync | api mcp | api · mcp · unit · docs | secret.reveal.ts |
set_secret_value | secret | sync | agent api mcp | api · mcp · unit · docs | secret.value.set.ts |
unset_secret_value | secret | sync | agent api mcp | api · mcp · unit · docs | secret.value.unset.ts |
upsert_secret_key | secret | sync | agent api mcp | api · mcp · unit · docs | secret.key.upsert.ts |
get_nav_counts | shell | sync | agent api mcp | schema · api · mcp · unit · docs · app | shell.nav_counts.get.ts |
get_skill_config | skill | sync | agent api mcp | schema · api · mcp · docs | skill.config.get.ts |
get_skill_registry | skill | sync | agent api mcp | schema · api · mcp · unit · docs · app | skill.registry.get.ts |
list_skill_impact | skill | sync | agent api mcp | schema · api · mcp · unit · docs · app | skill.impact.list.ts |
list_skills | skill | sync | agent api mcp | schema · api · mcp · unit · docs | skill.list.ts |
preview_skill_search | skill | sync | api | schema · api · docs | skill.search.preview.ts |
propose_skill | skill | sync | agent api | schema · api · unit · docs · app | skill.propose.ts |
read_registry_skill | skill | sync | agent api mcp | schema · api · mcp · unit · docs · app | skill.registry.read.ts |
search_skill_registry | skill | sync | agent api mcp | schema · api · mcp · unit · docs · app | skill.registry.search.ts |
set_skill_registry | skill | sync | agent api mcp | schema · api · mcp · unit · docs · app | skill.registry.set.ts |
summarize_skill_search | skill | sync | mcp | schema · mcp · docs | skill.search.summarize.ts |
update_skill_config | skill | sync | agent api mcp | schema · api · mcp · unit · docs | skill.config.update.ts |
answer_finding_fix | spend | sync | api mcp | schema · api · mcp · unit · docs · app | finding.fix.answer.ts |
create_cost_center | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | cost_center.create.ts |
delete_cost_center | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | cost_center.delete.ts |
dismiss_finding | spend | sync | api mcp | schema · api · mcp · unit · docs · app | finding.dismiss.ts |
export_cost_center_statement | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | spend.cost_center_statement.export.ts |
export_spend | spend | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | spend.export.ts |
export_statement | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | spend.statement.export.ts |
get_change_effort | spend | sync | agent api mcp | schema · api · mcp · unit · docs | forge.change_effort.get.ts |
get_code_share | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | spend.code_share.ts |
get_context_quality | spend | sync | agent api | schema · api · unit · docs · app | spend.context_quality.ts |
get_finding_evidence | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | finding.evidence.get.ts |
get_finding_fix | spend | sync | api mcp | schema · api · mcp · unit · docs · app | finding.fix.get.ts |
get_model_class_replay | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | finding.model_class_replay.get.ts |
get_no_progress_limit | spend | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | spend.no_progress_limit.get.ts |
get_operator_ranking | spend | sync | agent api | schema · api · unit · docs · app | spend.operator_ranking.ts |
get_operator_scorecard | spend | sync | agent api mcp | schema · api · mcp · unit · docs | spend.operator_scorecard.ts |
get_run_rollup | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | spend.run_rollup.ts |
get_sandbox_spend | spend | sync | api mcp | schema · api · mcp · unit · docs | spend.sandbox.get.ts |
get_spend | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | spend.get.ts |
get_spend_attribution | spend | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | spend.attribution.ts |
get_spend_drill | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | spend.drill.ts |
get_spend_model_fit | spend | sync | agent api | schema · api · unit · docs · app | spend.model_fit.ts |
get_spend_per_merged_pr | spend | sync | agent api | schema · api · unit · docs · app | spend.per_merged_pr.ts |
get_status_summary | spend | sync | agent api cli mcp | schema · api · mcp · cli · docs · app | status.summary.ts |
get_unproductive_spend | spend | sync | agent api | schema · api · unit · docs · app | spend.unproductive.ts |
get_work_order_metrics | spend | sync | agent api | schema · api · unit · docs | spend.work_order_metrics.ts |
list_cost_centers | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | cost_center.list.ts |
list_finding_calls | spend | sync | api mcp | schema · api · mcp · unit · docs · app | finding.calls.list.ts |
list_findings | spend | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | finding.list.ts |
list_run_facts | spend | sync | agent api mcp | schema · api · mcp · unit · docs | spend.run_facts.ts |
list_waste | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | spend.waste.ts |
record_finding_fix | spend | sync | agent api mcp | schema · api · mcp · unit · docs | finding.fix.record.ts |
request_model_class_replay | spend | sync | api mcp | schema · api · mcp · unit · docs · app | finding.model_class_replay.request.ts |
set_cost_center | spend | sync | agent api mcp | schema · api · mcp · unit · docs · app | cost_center.set.ts |
set_no_progress_limit | spend | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | spend.no_progress_limit.set.ts |
get_install_instructions | system | sync | agent api mcp | schema · api · mcp · unit · docs · app | system.install.instructions.ts |
add_group_machine | tacho | sync | schema · unit · docs | mcp-studio/local-calls/machine-group.add.ts | |
create_enrollment_token | tacho | sync | api cli mcp | schema · api · cli · unit · docs · app · mcp | tacho.enrollment_token.create.ts |
create_github_token | tacho | sync | api | schema · api · unit · docs | tacho.github_token.issue.ts |
create_tacho_enrollment | tacho | sync | api | schema · api · unit · docs | tacho.enrollment.create.ts |
enroll_host | tacho | sync | api cli mcp | schema · api · unit · docs · mcp | tacho.host.enroll.ts |
enroll_sandbox_daemon | tacho | sync | api | schema · api · docs | sandbox-daemon.enroll.ts |
get_enrollment_keys | tacho | sync | api | schema · api · docs | enrollment.keys.get.ts |
get_enrollment_request | tacho | sync | api mcp | schema · api · unit · docs · mcp | enrollment.request.get.ts |
get_tacho_bundle | tacho | sync | api | schema · api · unit · docs | tacho.bundle.get.ts |
get_tacho_session | tacho | sync | api | schema · api · unit · docs | tacho.session.get.ts |
get_tacho_session_policy | tacho | sync | agent api mcp | schema · api · docs · mcp · unit · app | tacho.session_policy.read.ts |
ingest_tacho_events | tacho | sync | api | schema · api · unit · docs | tacho.events.ingest.ts |
ingest_tacho_memories | tacho | sync | api | schema · api · unit · docs | tacho.memories.ingest.ts |
list_host_model_credentials | tacho | sync | api | schema · api · unit · docs | tacho.host_model_credential.list.ts |
list_incidents | tacho | sync | agent api mcp | schema · api · mcp · unit · docs · app | tacho.incident.list.ts |
list_machine_groups | tacho | sync | schema · unit · docs | mcp-studio/local-calls/machine-group.list.ts | |
list_tacho_hosts | tacho | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | tacho.host.list.ts |
list_tacho_session_heads | tacho | sync | api | schema · api · unit · docs | tacho.session_heads.list.ts |
list_tacho_sessions | tacho | sync | api | schema · api · unit · docs | tacho.session.list.ts |
preview_enrollment_request | tacho | sync | api | schema · api · unit · docs | enrollment.request.preview.ts |
recall_tacho_memories | tacho | sync | api | schema · api · unit · docs | tacho.memories.recall.ts |
record_host_model_credential_state | tacho | sync | api | schema · api · unit · docs | tacho.host_model_credential.report.ts |
record_tacho_memory_uses | tacho | sync | api | schema · api · unit · docs | tacho.memories.uses.record.ts |
register_contained_launch | tacho | sync | api | schema · api · unit · docs | tacho.contained_launch.register.ts |
register_machine | tacho | sync | api cli mcp | schema · api · mcp · cli · unit · docs | machine.register.ts |
reject_enrollment_request | tacho | sync | api | schema · api · unit · docs | enrollment.request.reject.ts |
remove_group_machine | tacho | sync | schema · unit · docs | mcp-studio/local-calls/machine-group.remove.ts | |
render_tacho_steering | tacho | sync | api | schema · api · unit · docs | tacho.steering.render.ts |
renew_enrollment_certificate | tacho | sync | api | schema · api · docs | enrollment.certificate.renew.ts |
revoke_tacho_enrollment | tacho | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | tacho.enrollment.revoke.ts |
update_tacho_session_policy | tacho | sync | agent api mcp | schema · api · docs · mcp · unit · app | tacho.session_policy.write.ts |
create_stella_enrollment | telemetry | sync | api | schema · api | telemetry.stella.enroll.ts |
ingest_stella_operational_telemetry | telemetry | sync | api | schema · api · unit · docs | telemetry.stella.ingest.ts |
list_error_clusters | telemetry | sync | agent api mcp | schema · api · mcp · unit · docs | telemetry.error.cluster.ts |
approve_observed_schema | tool | sync | api cli mcp | schema · api · mcp · cli · unit · docs · app | tool.observed_schema.approve.ts |
create_relay | tool | sync | api | schema · api · unit · docs | mcp-studio/relays/create.ts |
draft_studio_description | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/import/description.draft.ts |
get_studio_discovery | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/discovery/discovery.get.ts |
get_studio_draft | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/import/draft.get.ts |
get_studio_listing | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/listing/listing.get.ts |
get_studio_server | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/discovery/server.get.ts |
import_tools | tool | sync | agent api mcp | schema · api · mcp · unit · docs · app | tool.import.ts |
list_studio_findings | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/import/findings.list.ts |
list_studio_tools | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/discovery/tools.list.ts |
list_tool_declarations | tool | sync | agent api mcp | schema · api · docs · mcp · unit | tool.declaration.list.ts |
list_tool_versions | tool | sync | agent api mcp | schema · api · mcp · unit · docs · app | tool.version.list.ts |
migrate_tools_to_steering | tool | sync | api cli mcp | schema · api · mcp · cli · unit · docs | tool.steering.migrate.ts |
open_studio_review | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/import/review.open.ts |
publish_tool_declaration | tool | sync | api | schema · api · docs · unit | tool.declaration.publish.ts |
revoke_relay | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/relays/revoke.ts |
run_studio_selection | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/selection/run.ts |
save_studio_draft | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/import/draft.save.ts |
set_mcp_credential | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/credentials/set.ts |
set_tool_classification | tool | sync | agent api mcp | schema · api · mcp · unit · docs · app | tool.classification.set.ts |
set_tool_state | tool | sync | agent api mcp | schema · api · mcp · unit · docs · app | tool.state.set.ts |
start_studio_discovery | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/discovery/discovery.start.ts |
start_studio_listing | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/listing/listing.start.ts |
try_studio_tool | tool | sync | api mcp | schema · api · mcp · unit · docs | mcp-studio/import/tool.try.ports.ts |
clone_toolbelt | toolbelt | sync | agent api mcp | schema · api · mcp · unit · docs · app | toolbelt.clone.ts |
delete_toolbelt | toolbelt | sync | agent api mcp | schema · api · mcp · unit · docs · app | toolbelt.delete.ts |
get_toolbelt | toolbelt | sync | agent api mcp | schema · api · mcp · unit · docs · app | toolbelt.get.ts |
list_toolbelts | toolbelt | sync | agent api mcp | schema · api · mcp · unit · docs · app | toolbelt.list.ts |
update_toolbelt | toolbelt | sync | agent api mcp | schema · api · mcp · unit · docs · app | toolbelt.update.ts |
load_tools | tools | sync | agent api mcp | schema · api · mcp · unit · docs | @oxagen/agent or inline |
search_tools | tools | sync | agent api mcp | schema · api · mcp · unit · docs · app | @oxagen/agent or inline |
get_user_preferences | user | sync | agent api mcp | schema · api · docs · mcp · unit · app | user.preferences.read.ts |
get_workspace_user_preferences | user | sync | agent api mcp | schema · api · docs · mcp · unit | user.workspace_preferences.read.ts |
set_preferences | user | sync | agent api mcp | schema · api · mcp · unit · docs · app | user.preferences.set.ts |
update_profile | user | sync | agent api | schema · api · unit · docs · app | user.profile.update.ts |
update_workspace_user_preferences | user | sync | api | schema · api · docs · unit | user.workspace_preferences.write.ts |
accept_work_order | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.order.accept.ts |
add_work_items | work | sync | agent api mcp | schema · api · mcp · unit · docs | work.items.add.ts |
approve_definition_of_done | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.dod.approve.ts |
archive_work_label | work | sync | api mcp | schema · api · docs · app · mcp | work.label.change.ts |
cancel_work_order | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.order.cancel.ts |
claim_work_criterion | work | sync | api mcp | schema · api · mcp · unit · docs | work.criterion.claim.ts |
claim_work_order | work | sync | api | schema · api · unit · docs | work.order.claim.ts |
classify_task | work | sync | agent api mcp | schema · api · mcp · unit · docs | work.task.classify.ts |
close_work_item | work | sync | agent api mcp | schema · api · unit · docs · app · mcp | work.item.close.ts |
comment_on_source_issue | work | sync | agent api mcp | schema · api · docs · mcp | work.item.source_comment.ts |
create_work_item | work | sync | agent api mcp | schema · api · mcp · unit · docs · app | work.item.create.ts |
decline_work_item_start | work | sync | agent api mcp | schema · api · unit · docs · app · mcp | work.item.start.decline.ts |
delete_work_items | work | sync | agent api mcp | schema · api · mcp · unit · docs | work.items.delete.ts |
delete_work_label | work | sync | api mcp | schema · api · docs · app · mcp | work.label.change.ts |
delete_work_status | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.status.delete.ts |
draft_work_batch | work | sync | agent api mcp | schema · api · mcp · unit · docs | work.batch.draft.ts |
draft_work_label | work | sync | api mcp | schema · api · unit · docs · app · mcp | stella/draft-work-label.ts |
draft_work_order | work | sync | agent api mcp | schema · api · mcp · unit · docs | work.order.draft.ts |
draft_work_status | work | sync | api mcp | schema · api · unit · docs · app · mcp | stella/draft-work-status.ts |
draft_work_triage_answers | work | sync | mcp | schema · mcp · unit · docs · app | work.triage.draft_answers.ts |
forecast_work_cost | work | sync | agent api mcp | schema · api · mcp · unit · docs · app | work.cost.forecast.ts |
get_my_work_stats | work | sync | mcp | schema · mcp · unit · docs · app | work.stats.mine.ts |
get_work_arrivals | work | sync | mcp | schema · mcp · unit · docs · app | work.arrivals.get.ts |
get_work_autonomy | work | sync | api mcp | schema · api · mcp · unit · docs · app | work.autonomy.get.ts |
get_work_batch | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.orders.get.ts |
get_work_fields | work | sync | api mcp | schema · api · mcp · unit · docs · app | work.fields.get.ts |
get_work_item | work | sync | agent api mcp | schema · api · mcp · unit · docs · app | work.item.get.ts |
get_work_outcomes | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.outcomes.get.ts |
get_work_priorities | work | sync | api mcp | schema · api · mcp · unit · docs · app | work.priorities.get.ts |
link_run_work_items | work | sync | agent mcp | schema · mcp · unit · docs | run.work_items.link.ts |
list_collector_scope_options | work | sync | api mcp | schema · api · docs · mcp | work.collector.scope_options.list.ts |
list_ready_work | work | sync | agent api mcp | schema · api · mcp · unit · docs · app | work.ready.list.ts |
list_run_link_suggestions | work | sync | agent api mcp | schema · api · mcp · docs | run.link_suggestions.list.ts |
list_work_collectors | work | sync | api mcp | schema · api · mcp · unit · docs · app | work.collectors.list.ts |
list_work_items | work | sync | agent api mcp | schema · api · mcp · unit · docs · app | work.items.list.ts |
list_work_labels | work | sync | api mcp | schema · api · mcp · unit · docs · app | work.labels.list.ts |
list_work_sources | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.sources.list.ts |
list_work_statuses | work | sync | api mcp | schema · api · mcp · unit · docs · app | work.statuses.list.ts |
list_work_targets | work | sync | agent api mcp | schema · api · unit · docs · app · mcp | work.targets.list.ts |
list_workstreams | work | sync | agent api mcp | schema · api · docs · mcp | work.workstreams.list.ts |
map_work_collector_label | work | sync | api mcp | schema · api · docs · app · mcp | work.label.change.ts |
recommend_staffing | work | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | work.staffing.recommend.ts |
refresh_work_item_source | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.item.source.refresh.ts |
refresh_work_order_checks | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.order.checks.refresh.ts |
reject_work_order | work | sync | api | schema · api · unit · docs | work.order.reject.ts |
remove_work_item_attachment | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.item.attachment.remove.ts |
reopen_work_item | work | sync | agent api mcp | schema · api · unit · docs · app · mcp | work.item.reopen.ts |
resend_work_batch_item | work | sync | api mcp | schema · api · docs · app · mcp | work.orders.resend.ts |
retriage_open_work | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.triage.retriage-open.ts |
retry_work_item_text_write | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.item.text_write.retry.ts |
retry_work_item_tracker_create | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.item.tracker_create.retry.ts |
retry_work_triage | work | sync | agent api mcp | schema · api · unit · docs · app · mcp | work.triage.retry.ts |
return_work_order | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.order.return.ts |
review_run_link | work | sync | agent api mcp | schema · api · mcp · unit · docs · app | run.link.review.ts |
revise_work_triage | work | sync | api mcp | schema · api · mcp · unit · docs · app | work.triage.revise.ts |
save_definition_of_done | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.dod.save.ts |
save_work_label | work | sync | api mcp | schema · api · docs · app · mcp | work.label.save.ts |
save_work_status | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.status.save.ts |
search_work_items | work | sync | agent api mcp | schema · api · mcp · unit · docs · app | work.items.search.ts |
send_work_batch | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.batch.send.ts |
send_work_order | work | sync | agent api mcp | schema · api · unit · docs · app · mcp | work.order.send.ts |
send_work_orders | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.orders.send.ts |
set_dod_item_done | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.dod.item.done.set.ts |
set_work_collector | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.collector.set.ts |
set_work_field_mapping | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.field_mapping.set.ts |
set_work_item_status | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.item.status.set.ts |
set_work_item_workstream | work | sync | agent api mcp | schema · api · unit · docs · mcp | work.item.workstream.set.ts |
stop_work_order | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.order.stop.ts |
stop_work_orders | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.orders.stop.ts |
sync_work_collector | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.collector.sync.ts |
update_work_item | work | sync | agent api mcp | schema · api · mcp · unit · docs · app | work.item.update.ts |
update_work_items | work | sync | agent api mcp | schema · api · mcp · unit · docs | work.items.update.ts |
upload_work_item_attachment | work | sync | api mcp | schema · api · unit · docs · app · mcp | work.item.attachment.upload.ts |
add_workspace_member | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.member.add.ts |
answer_join_request | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.join_request.answer.ts |
archive_kind | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | kind.change.ts |
archive_workspace | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.archive.ts |
connect_workspace | workspace | sync | api cli mcp | schema · api · mcp · cli · docs | workspace.connect.ts |
create_workspace | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.create.ts |
delete_kind | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | kind.change.ts |
draft_kind | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | stella/draft-kind.ts |
get_gateway_settings | workspace | sync | api mcp | schema · api · mcp · unit · docs · app | workspace.gateway_settings.read.ts |
get_model_settings | workspace | sync | agent api mcp | schema · api · docs · mcp · unit | workspace.model_settings.read.ts |
get_my_join_request | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.join_request.mine.ts |
get_prompt_settings | workspace | sync | api mcp | schema · api · docs · mcp · unit | prompt.settings.read.ts |
get_steering_settings | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.steering_settings.get.ts |
get_workspace_notifications | workspace | sync | schema · unit · docs | workspace.notifications.read.ts | |
get_workspace_settings | workspace | sync | api mcp | schema · api · mcp · unit · docs · app | workspace.settings.read.ts |
list_join_requests | workspace | sync | agent api mcp | schema · api · mcp · unit · docs | workspace.join_request.list.ts |
list_kinds | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | kinds.list.ts |
list_workspace_slack_channels | workspace | sync | schema · unit · docs | workspace.notifications.channels.ts | |
list_workspaces | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.list.ts |
remove_workspace_member | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.member.remove.ts |
request_to_join_workspace | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.join_request.create.ts |
restore_kind | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | kind.change.ts |
save_kind | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | kind.change.ts |
send_workspace_invite | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.invite.send.ts |
set_governance_mode | workspace | sync | agent api cli mcp | schema · api · mcp · cli · unit · docs · app | context.governance_mode.set.ts |
set_steering_settings | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.steering_settings.set.ts |
set_workspace_member_role | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.member_role.set.ts |
set_workspace_notifications | workspace | sync | schema · unit · docs | workspace.notifications.write.ts | |
update_gateway_settings | workspace | sync | api mcp | schema · api · mcp · unit · docs · app | workspace.gateway_settings.write.ts |
update_model_settings | workspace | sync | agent api mcp | schema · api · docs · mcp · unit | workspace.model_settings.write.ts |
update_prompt_settings | workspace | sync | api mcp | schema · api · docs · mcp · unit | prompt.settings.write.ts |
update_workspace_settings | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.settings.write.ts |
withdraw_join_request | workspace | sync | agent api mcp | schema · api · mcp · unit · docs · app | workspace.join_request.withdraw.ts |
The governed turn
The repo's one agent loop is runGovernedTurn on stella-serve. Its main caller is the in-app assistant, a governed, metered Q&A turn over the fleet record and the knowledge graph. Run enrichment also calls it for a one-step, tool-less account of a recorded run. Every completion and tool call comes back to Oxagen to answer.
The governed turn (in-app assistant)
- The same turn runs behind three adapters: the SSE route drawn here, which the app's shell flyout also reads through the
/api/v1/*rewrite;POST /assistant/ask; and the MCP tool. The last two return the whole reply rather than a stream. - stella-serve holds no key and runs no tool. Every completion comes back as a provider request answered through
streamAgentReply, and every tool call comes back as a tool request. Each request is written ahead as a frame on the turn's session, and the session is sealed when the engine reports its outcome (ADR-5969). - A write that needs approval is parked as a card in the reply, not awaited. Only the person who asked can answer it (ADR-235).
- There is no Inngest hop for messages:
assistant-turn.tswrites them inline insidewithTenantDb. Token usage alone goes through the usage outbox. Thechat.persist-streamfunction named in older codemaps has no sender and no file. - Role routing inside the provider port: verdict and judge calls run on the cheapest tier whose model is not the worker's:
fastfor abalancedworker,balancedfor afastorpreciseworker, andpreciseonly when every cheaper tier maps to the worker's model. Summarisation, reflection and domain inference usefast. Everything else runs on the turn's worker model. - The workspace does not govern or monitor this turn (ADR-235): no decision rule, steering record, workspace instruction, recalled memory, turn budget or spend ceiling reaches it. The one customer-set limit that does is the workspace's daily Stella budget (#5426), which the credit gate checks before the turn. The one volatile user message is the page context.
Source refs (19, verified at build)
apps/api/src/routes/v1/chat.stream.ts#chatStreamRouteapps/api/src/routes/v1/chat-stream-translator.ts#createApiStreamTranslatorpackages/agent/src/handlers/assistant.ask.ts#assistantAskHandlerpackages/agent/src/runtime/assistant-stream.ts#streamAssistantTurnpackages/agent/src/runtime/assistant-turn.ts#prepareAssistantTurnpackages/agent/src/runtime/assistant-turn.ts#HISTORY_LIMIT = 50packages/agent/src/runtime/assistant-session.ts#ASSISTANT_SESSION_RUNTIMEapps/app/src/features/shell/assistant-stream-client.tspackages/agent/src/runtime/assistant-run.ts#openAssistantRunpackages/ai/src/funding-source.ts#resolveModelFundingSourcepackages/billing/src/usage-outbox.ts#finalizeUsagepackages/billing/src/turn-credit-gate.ts#evaluateTurnCreditGatepackages/agent/src/runtime/governed-turn.ts#runGovernedTurnpackages/agent/src/runtime/materialize-tools.ts#materializeToolspackages/agent/src/runtime/tool-budget.ts#assertToolListFitsProviderpackages/agent/src/runtime/engine/provider.ts#createProviderPortpackages/agent/src/runtime/engine/tools.ts#executeToolRequestpackages/ai/src/stream.ts#streamAgentReplypackages/inngest-functions/src/functions/billing.usage-delivery.ts#billing.usage-delivery
Run evidence
Every run is one row in tacho.sessions (ADR-5969). Wrapped agents send hash-chained frames from their host's collector, and the in-app assistant records its turns as sessions in process. The control plane checks each chain, then seals and grades the session. It never runs or re-runs an agent (ADR-043).
Wrapping: evidencing an agent Oxagen does not run
- Four enforcement tiers.
observemeans the host only records.harnessmeans the hook enforces inside a process Oxagen does not own.gatewayneeds a verified chain that routed a model or MCP call through the host's loopback model proxy or local MCP gateway.containedalso needs a registered contained launch whose genesis hash matches. The tier is set at ingest, only rises while the session is live, and is final once sealed. - The ClickHouse DDL for
tacho_eventsis generated from the envelope schema. A test fails when the SQL and the schema disagree. - The session is sealed on
tacho.sessions, the one run table (ADR-5969). The ledger tables and their outside ingest (create_run_token,ingest_run_frames) are gone. The in-app assistant records its turns as sessions in process, with the same chain and seal code, not through this HTTP path.
Source refs (17, verified at build)
packages/tacho/src/envelope.ts#TACHO_ENVELOPE_VERSIONpackages/tacho/src/wire.ts#TACHO_BATCH_SCHEMApackages/tacho/src/wire.ts#TACHO_MAX_BATCHpackages/tacho/src/wire.ts#TACHO_MAX_REQUEST_BYTESpackages/tacho/src/wire.ts#WRAPPED_HARNESSESpackages/tacho/src/wire.ts#MODEL_HARNESS_ROUTESpackages/tacho/src/collector/hook-handler.ts#bundle_stalepackages/tacho/src/collector/model-proxy.tspackages/database/src/schema/tacho.ts#TACHO_ENFORCEMENT_TIERSpackages/database/src/schema/tacho.ts#TACHO_COMMANDSpackages/handlers/src/tacho.events.ingest.ts#sealTachoSessionpackages/handlers/src/tacho.events.ingest.ts#enforcementTierOfapps/api/src/routes/v1/tacho.events.ingest.tsapps/api/src/app.ts#TACHO_INGEST_PER_MINapps/api/src/middleware/distributed-rate-limit.ts#distributedRateLimiterpackages/telemetry/src/tacho-events-ddl.tspackages/agent/src/runtime/assistant-session.ts
Metering and billing
The governed action is the billable unit. Tokens are reported at full price and billed at zero, except when the platform key funds them, at list price plus 20%.
From governed action to GAU bucket debit (ADR-052, ADR-055)
- Stripe idempotency is three-phase: insert into
stripe_eventswithON CONFLICT DO NOTHING; treat as duplicate only if a processing row hasprocessed_at; dispatch, then record the outcome. A prior failed attempt re-dispatches, so a provider retry self-heals. It is not exactly-once. - Three billing crons run.
billing.dunning-sweep(02:00 UTC) moves orgs from grace to suspended once grace ends, then pages through active orgs for credit low-balance notifications.billing.gau-close(hourly at :10) closes ended months, invoices month-end overage, and resumes settlements still pending.billing.usage-delivery(every five minutes, concurrency 1) drainsbilling.usage_outboxinto ClickHouse. invoice.paidsyncs the subscription and the invoice throughgrantPlanCreditsForInvoicePaidand writes no credits: a seat's monthly credits are the bucket'scredits_granted, which model calls on Oxagen's key spend before the wallet.- The
stripe.sync-*events named in older inventories have no sender; the webhook route handles those events inline.
Source refs (19, verified at build)
packages/oxagen/src/kernel.ts#_usageRecorderpackages/billing/src/bootstrap.ts#setUsageRecorderpackages/billing/src/action-metering.ts#recordGovernedActionpackages/billing/src/contract-terms.ts#resolveGauEntitlementpackages/billing/src/billing-settings.ts#readOrgBillingSettingspackages/billing/src/gau-bucket.ts#bucketBasispackages/billing/src/gau-bucket.ts#ensureCurrentBucketpackages/billing/src/gau-ledger.ts#debitWithLedgerpackages/handlers/src/tacho.events.ingest.ts#recordGovernedActionspackages/billing/src/gau-bucket.ts#remainingGaupackages/billing/src/gau-settlements.ts#claimInterimInvoicepackages/billing/src/gau-settlements.ts#settleGauInvoicepackages/billing/src/gau-settlements.ts#settleGauPaidpackages/billing/src/gau-settlements.ts#grantGauPurchaseForCheckoutpackages/billing/src/webhooks.ts#processStripeEventapps/api/src/routes/stripe.tspackages/inngest-functions/src/functions/billing.dunning-sweep.tspackages/inngest-functions/src/functions/billing.gau-close.tspackages/inngest-functions/src/functions/billing.usage-delivery.ts
assertGauAvailable (governed-action admission)
- An org with no subscription is refused once its signup grant is spent (
signup_grant_used), past an expiring grant (signup_grant_expired), or with no grant (no_signup_grant). Each person gets one grant, so a second organisation they create starts with none. With the subscription rule cleared,monthly_allowance_usedapplies instead. Past the grant, or with none, the gate refuses without reading the bucket. A saved card alone unlocks nothing. - The spend-budget gate runs right after it in
kernel.invoke(). It also runs for nested invokes, and it skips Stella's calls and the in-app assistant's contracts (ADR-235). It checks the org and workspace ceilings inbilling.spend_budgetsagainstbilling.spend_counters. A breach throwsbudget_exceeded, and a database error fails open.
Source refs (3, verified at build)
packages/billing/src/gau-bucket.ts#assertGauAvailablepackages/billing/src/gau-bucket.ts#GauExhaustedErrorpackages/billing/src/spend-budget-gate.ts#assertWithinSpendBudget
assertCanStartTurn (platform-funded assistant turns)
- Auto-reload runs when it is enabled, the balance is below the threshold, and no reload completed in the last hour. It charges the saved card off-session, and a failure is logged.
evaluateTurnCreditGatecalls it for the in-app assistant, run enrichment and conversation titles. A refusal becomesAssistantTurnRefusedError, which the API maps to 402.
Source refs (7, verified at build)
packages/billing/src/metering.ts#assertCanStartTurnpackages/billing/src/charge-model-call.ts#readModelCallRoompackages/billing/src/charge-model-call.ts#chargeModelCallpackages/billing/src/turn-credit-gate.ts#evaluateTurnCreditGatepackages/billing/src/autoreload.ts#maybeAutoReloadpackages/billing/src/turn-credit-gate.ts#WorkspaceBudgetSpentErrorpackages/billing/src/metering.ts#assertUnderWorkspaceLaneBudget
Knowledge graph
Connectors dual-write: Postgres holds the cursor and health, Neo4j holds entities, embeddings and relationships, ClickHouse observes. The ontology is tenant data in the schema registry.
ingestion/entity.received → EntityNode
- Concurrency is capped at 5 per organisation (
concurrency: { key: event.data.orgId }). - Pass B queries
entity_node_embedding_indexand writes anALIAS_OFedge on a match. When the embedding backend is down, the entity becomes its own principal flaggedsimilarityDeferred. The embed step runs only when semantic inference is on for the record type. - A node with no vector is the backfill set:
MATCH (n:EntityNode) WHERE n.embedding IS NULL. - A node written without Pass B carries
similarityDeferredAt. Once the backfill gives it a vector,similarity/reconcileruns Pass B for it, links it to a match withALIAS_OF, and clears the mark. - Every tenant node also carries the anchor label
GraphNode; it exists to back indexes because Neo4j cannot parameterise labels. Relationship types are tenant data inschema_registry.relationship_types, not a static enum.
Source refs (10, verified at build)
packages/inngest-functions/src/functions/ingestion.pipeline.ts#schedule-change-eventpackages/inngest-functions/src/functions/ingestion.connection-poll.tspackages/ingestion/src/dedup/resolve.ts#entity_node_embedding_indexpackages/ingestion/src/dedup/resolve.ts#similarityDeferredpackages/ingestion/src/dedup/reconcile.ts#reconcileDeferredNodepackages/inngest-functions/src/functions/similarity.reconcile.ts#similarity/reconcilepackages/ingestion/src/mutations/upsert-entity.tspackages/ingestion/src/stages.tspackages/ontology/src/tenant.ts#scopedSessionpackages/ontology/src/schema.cypher
Neo4j labels
From packages/ontology/src/schema.cypher via the storage manifest. Relationship types are not static: each workspace declares them in a versioned schema in schema_registry.relationship_types. RELATED_TO is the fallback when a supplied type cannot be sanitised, and ingestion writes ALIAS_OF for deduplicated entities.
| Label | Domain | Key properties | Constraints / indexes | Org-scoped |
|---|---|---|---|---|
ContextManifest | agent | orgId, publicId | context_manifest_public_id | yes |
EntityNode | ingestion | connectionId, embedding, entityType, naturalKey, workspaceId | entity_node_connection,entity_node_natural_key,entity_node_workspace | yes |
Execution | agent | orgId, publicId | execution_public_id | yes |
GraphNode | graph | embedding, label, orgId, publicId, workspaceId | graph_node_public_id | yes |
SourceConnection | ingestion | id, orgId | source_connection_id | yes |
Tool | agent | orgId, publicId | tool_public_id | yes |
Vector indexes
All 1024-dimensional cosine, sized to voyage-4-large. graph_node_embedding_index is the universal one because every tenant node also carries the GraphNode anchor label.
| Index | Label | Property |
|---|---|---|
entity_node_embedding_index | EntityNode | embedding |
graph_node_embedding_index | GraphNode | embedding |
Datastores
Four stores, one storage manifest (ADR-031) that the gate keeps byte-stable. Postgres is transactional truth under forced row-level security; ClickHouse is append-only telemetry; Neo4j is the graph; Blob holds bytes the Postgres row points at.
| Store | Tables | Purpose | Domains |
|---|---|---|---|
postgres | 236 | Transactional state: users, orgs, permissions, billing, configs, durable application state. | agent ai auth billing chat cms codegraph content cost crm environments evidence forge iam ingestion mcp notification org plugin privacy ratelimit schema_registry security skills tacho tools work workspace |
clickhouse | 16 | Append-only runtime events: execution events, logs, metrics, traces, token analytics, telemetry. | billing chat codegraph iam mcp schema_registry tacho telemetry |
neo4j | 6 | Graph data: ontology/entity relationships, where workflow data came from, agent memory, semantic retrieval. | agent graph ingestion |
blob | 4 | Binary assets: avatars, generated media, uploads; the Postgres row (URL + metadata) is source of truth. | content |
Domains across stores
Rows are the platform's storage domains; a cell counts the tables (or labels) that domain owns in each store.
| Domain | postgres | clickhouse | neo4j | blob |
|---|---|---|---|---|
agent | 30 | · | 3 | · |
ai | 1 | · | · | · |
auth | 10 | · | · | · |
billing | 22 | 2 | · | · |
chat | 2 | 1 | · | · |
cms | 2 | · | · | · |
codegraph | 22 | 1 | · | · |
content | 1 | · | · | 4 |
cost | 14 | · | · | · |
crm | 2 | · | · | · |
environments | 4 | · | · | · |
evidence | 2 | · | · | · |
forge | 13 | · | · | · |
graph | · | · | 1 | · |
iam | 11 | 1 | · | · |
ingestion | 12 | · | 2 | · |
mcp | 11 | 1 | · | · |
notification | 3 | · | · | · |
org | 15 | · | · | · |
plugin | 1 | · | · | · |
privacy | 2 | · | · | · |
ratelimit | 1 | · | · | · |
schema_registry | 7 | 2 | · | · |
security | 3 | · | · | · |
skills | 1 | · | · | · |
tacho | 12 | 1 | · | · |
telemetry | · | 7 | · | · |
tools | 4 | · | · | · |
work | 20 | · | · | · |
workspace | 8 | · | · | · |
Postgres schemas
- Tenancy columns come from mixins (
orgScopeMixin,auditMixin,softDeleteMixin), so they are not literal in the table bodies but are present in every drawn card. - Tables without
org_idare isolated transitively through a policied parent or are shared catalogs; the RLS badge on each card names its policy class fromtenant-policy.manifest.ts.
Entity relationships by schema
◆ marks a primary key, → a referencing column, ? a nullable column. Composite primary keys are not visible to the manifest and show no ◆.
agent (30 tables)
ai (1 tables)
auth (10 tables)
billing (22 tables)
chat (2 tables)
cms (2 tables)
codegraph (22 tables)
content (1 tables)
cost (14 tables)
crm (2 tables)
environments (4 tables)
evidence (2 tables)
forge (13 tables)
iam (11 tables)
ingestion (12 tables)
mcp (11 tables)
notification (3 tables)
org (15 tables)
plugin (1 tables)
privacy (2 tables)
ratelimit (1 tables)
schema_registry (7 tables)
security (3 tables)
skills (1 tables)
tacho (12 tables)
tools (4 tables)
work (20 tables)
workspace (8 tables)
ClickHouse
Replayed the way packages/telemetry/src/migrate.ts does: schema.sql first, then every numbered migration, honouring drops. The storage manifest only sees schema.sql, so this list is the fuller one.
| Table | Engine | ORDER BY | Columns | Defined in |
|---|---|---|---|---|
assistant_reply_feedback | MergeTree() | (org_id, workspace_id, run_public_id, user_id, created_at) | 9 | migrations/0030_assistant_reply_feedback.sql |
audit_events | ReplacingMergeTree(occurred_at) | (org_id, occurred_at, event_id) | 18 | migrations/0003_iam_audit.sql |
codegraph_queries | MergeTree() | (org_id, workspace_id, capability, created_at) | 19 | migrations/0041_codegraph_queries.sql |
dev_logs | MergeTree() | (dev_session, service, ts) | 7 | schema.sql |
error_events | MergeTree() | (org_id, source, created_at) | 14 | migrations/0020_error_events.sql |
events | MergeTree() | (org_id, event_type, emitted_at) | 8 | schema.sql |
graph_observed_labels | MergeTree() | (org_id, workspace_id, target_kind, label_or_type, occurred_at) | 9 | migrations/0013_graph_observed_labels.sql |
router_outcomes | MergeTree() | (org_id, task_class, model, created_at) | 15 | migrations/0025_router_outcomes.sql |
schema_conformance_events | ReplacingMergeTree(occurred_at) | (org_id, workspace_id, version_id, node_label, event_id) | 16 | migrations/0021_schema_conformance_events_idempotency.sql |
served_tool_calls | MergeTree() | (org_id, workspace_id, server, tool, created_at) | 8 | migrations/0037_served_tool_calls.sql |
spend_attribution_runs | ReplacingMergeTree(version, is_deleted) | (org_id, workspace_id, started_at, session_uuid) | 22 | migrations/0057_spend_attribution_runs.sql |
stella_operational_events | ReplacingMergeTree(received_at) | (org_id, workspace_id, event_id) | 17 | migrations/0026_stella_operational_events.sql |
tacho_events | ReplacingMergeTree(received_at) | (org_id, workspace_id, session_uuid, seq) | 404 | migrations/0027_tacho_events.sql |
tool_invocations | MergeTree() | (org_id, capability_name, created_at) | 22 | schema.sql |
usage_events | MergeTree() | (command, timestamp) | 19 | migrations/0019_usage_events.sql |
Blob
| Asset kind | Description | Access | Driver |
|---|---|---|---|
avatar | Public profile/logo images; the blob URL is stored on the owning entity's avatar_url column (no attachments row). | public | vercel-blob |
evidence_body | Frame bodies: redacted, content-addressed, envelope-encrypted bytes under evidence/<org>/<workspace>/bodies/<key id>/<sha256>; ClickHouse tacho_events.bytes_ref holds the reference (ADR-058). | private | vercel-blob |
evidence_export | Run export bundles; run_exports.bundle_ref holds the reference (ADR-058). The ledger's archive segments went with its tables (ADR-5969). | private | vercel-blob |
generated_asset | Generated + uploaded media (chat attachments, exports, agent output); content.attachments is the source-of-truth reference row. | private | vercel-blob |
Background jobs
141 Inngest functions served at /api/jobs on apps/api, read from the functions array that registers them. Trigger events are parsed with the scanner the gate uses to prove every event has a sender, and event constants are resolved from their declarations.
Event → function → event
- Functions are declared through a local
createFunctionadapter that can return an on-failure companion, which is why some exports destructure two functions. The companions are served too and are not drawn.
Functions
| Id | Trigger | Sends | Retries | File |
|---|---|---|---|---|
agent/interjection-timeout | agent/interjection.raised | — | 3 | agent.interjection-timeout.ts |
agent/interjection-timeout-sweep | */5 * * * * | — | 2 | agent.interjection-timeout-sweep.ts |
approval/resume | * * * * * | — | 3 | approval.resume.ts |
assistant.attachment-sweep | 0 * * * * | — | 3 | assistant.attachment-sweep.ts |
auth/session-expiry-audit | 0 * * * * | — | 3 | auth.session-expiry-audit.ts |
auth/sso-reseal-daily | 30 3 * * * | — | 3 | auth.sso-reseal.ts |
auth/sso-reseal-requested | auth/sso-secrets.reseal.requested | — | 3 | auth.sso-reseal.ts |
backfill-status-reports | spend/status-reports.backfill | spend/status-reports.backfill | 2 | status-reports.ts |
billing.credit-expiry | 0 3 * * * | — | 3 | billing.credit-expiry.ts |
billing.dunning-sweep | 0 2 * * * | — | 3 | billing.dunning-sweep.ts |
billing.gau-close | 10 * * * * | — | 3 | billing.gau-close.ts |
billing.usage-delivery | */5 * * * * | — | 3 | billing.usage-delivery.ts |
billing.wallet-top-up | billing/wallet.top-up.requested | — | 3 | billing.wallet-top-up.ts |
code-repo/check | code-repo/check.requested | — | 3 | code-repo.check.ts |
codegraph/decisions-import | codegraph/workspace.run.requested | — | 4 | codegraph.decisions.ts |
codegraph/decisions-report | 0 4 * * * | — | 2 | codegraph.decisions.ts |
codegraph/decisions-report-workspace | codegraph/decisions.report.requested | — | 4 | codegraph.decisions.ts |
codegraph/domains-change | codegraph/domains.changed | — | 4 | codegraph.domains-change.ts |
codegraph/embed-batch | — | 4 | codegraph.embed.ts | |
codegraph/enrich-batch | — | 4 | codegraph.enrich.ts | |
codegraph/enrich-request | codegraph/revision.published | codegraph/enrich.v2.requested | 4 | codegraph.enrich-request.ts |
codegraph/freshness-check | codegraph/freshness.check.requested | — | 4 | codegraph.freshness.ts |
codegraph/freshness-intake | codegraph/intake.received | — | 4 | codegraph.freshness.ts |
codegraph/freshness-published | codegraph/revision.published | — | 4 | codegraph.freshness.ts |
codegraph/intake | codegraph/intake.received | — | 4 | codegraph.intake.ts |
codegraph/intake-build | codegraph/intake.build | — | 4 | codegraph.intake.ts |
codegraph/intake-debounce-pr | codegraph/intake.build.pr | — | 4 | codegraph.intake.ts |
codegraph/inventory-published | codegraph/revision.published | codegraph/inventory.requested | 4 | codegraph.inventory.ts |
codegraph/linker-round | — | 4 | codegraph.linker.ts | |
codegraph/linker-sample | 30 4 * * * | — | 2 | codegraph.linker-sample.ts |
codegraph/org-key-backfill | — | 2 | codegraph.org-key-backfill.ts | |
codegraph/release-gate | */5 * * * * | — | 2 | codegraph.release.ts |
codegraph/release-gate-workspace | codegraph/workspace.gate.requested | — | 4 | codegraph.release.ts |
codegraph/release-record-build | codegraph/intake.build | — | 4 | codegraph.release.ts |
codegraph/remove-on-gitlab-detach | ingestion/connection.delete | — | 4 | codegraph.intake-detach.ts |
codegraph/survival-record | codegraph/survival.measured | — | 4 | codegraph.survival.ts |
codegraph/survival-request | — | 2 | codegraph.survival.ts | |
context/labels-backfill | 0 * * * * | — | 3 | context.labels-backfill.ts |
conversation.title | chat/conversation.opened | — | 1 | conversation.title.ts |
cost.daily-rollup | 0 1 * * * | cost/price-book.backdated | 3 | cost.daily-rollup.ts |
cost.findings | cost/findings.requested | — | 3 | cost.findings.ts |
cost.findings-nightly | 0 2 * * * | — | 3 | cost.findings.ts |
cost.model-class-replay | cost/model-class-replay.approved | — | 2 | cost.model-class-replay.ts |
cost.model-class-replay-sweep | 23 * * * * | — | 2 | cost.model-class-replay.ts |
cost.price-book-reprice | cost/price-book.backdated | cost/findings.requestedcost/price-book.backdated | 3 | cost.price-book-reprice.ts |
cost.price-book-sync | 0 * * * * | cost/price-book.backdated | 3 | cost.price-book-sync.ts |
cost.price-snapshots | */5 * * * * | — | 0 | cost.price-snapshots.ts |
cost.run-pr-outcomes-delivery | ingestion/entity.received | — | 3 | cost.run-pr-outcomes.ts |
cost.run-pr-outcomes-hourly | 15 * * * * | — | 2 | cost.run-pr-outcomes.ts |
cost.run-progress | cost/run.progressed | — | 3 | cost.run-progress.ts |
cost.run-rollup | cost/run.sealed | cost/findings.requestedrun/fit.requested | 5 | cost.run-rollup.ts |
cost.work-order-send-back-hourly | 45 * * * * | — | 2 | cost.work-order-send-back.ts |
embeddings/backfill | embeddings/backfill.requested | — | 2 | embeddings.backfill.ts |
embeddings/backfill-schedule | */30 * * * * | embeddings/backfill.requested | 1 | embeddings.backfill.ts |
evidence.run-export | evidence/run-export.build | — | 2 | evidence.run-export.ts |
forge/commit-backfill | forge/commit-backfill.requested | forge/commit-backfill.requestedforge/revision-commits.ready | 2 | forge.commit-backfill.ts |
forge/finding-record | forge/finding-record.requested | ingestion/entity.received | 4 | forge.finding-record.ts |
forge/history-import | forge/repository.linked | forge/pull-request.observed | 2 | forge.history-import.ts |
forge/pull-request-backfill | */15 * * * * | forge/pull-request.observed | 1 | forge.pull-request-backfill.ts |
forge/pull-request-sync | forge/pull-request.observed | forge/pull-request-diff.readyforge/revision-commits.readyrun/infer-work | 4 | forge.pull-request-sync.ts |
forge/repository-linked | forge/repository.linked | forge/repository.linkedforge/revision-commits.ready | 2 | forge.repository-linked.ts |
forge/revision-attribution | forge/revision-commits.ready | — | 4 | forge.revision-attribution.ts |
github/pull-request-mention | github/pull-request.mentioned | — | 3 | github.pull-request-mention.ts |
ingestion-connection-poll | ingestion/connection.poll | ingestion/entity.received | 2 | ingestion.connection-poll.ts |
ingestion-delete-connection | ingestion/connection.delete | — | 2 | ingestion.delete.ts |
ingestion-github-initial-sync | ingestion/github.initial-sync | ingestion/entity.received | 3 | ingestion.github-initial-sync.ts |
ingestion-oauth-refresh | 0 * * * * | — | 2 | ingestion.oauth-refresh.ts |
ingestion-pipeline | ingestion/entity.received | ingestion/entity.createdingestion/entity.updated | 3 | ingestion.pipeline.ts |
ingestion-poll-scheduler | */5 * * * * | ingestion/connection.poll | 2 | ingestion.poll-scheduler.ts |
ingestion-sync-requested | ingestion/sync.requested | ingestion/github.initial-sync | 3 | ingestion.sync-requested.ts |
ingestion-webhook-provision | ingestion/webhook.provision | — | 3 | ingestion.webhook-provision.ts |
ingestion-webhook-renew | 0 * * * * | — | 2 | ingestion.webhook-renew.ts |
mandate/expiry | 0 * * * * | — | 3 | mandate.expiry.ts |
mcp-server/discover | mcp-server/discover.requested | — | 2 | mcp-server.discover.ts |
mcp-server/sync | 0 * * * * | — | 1 | mcp-server.sync.ts |
mcp.credential-grant-retention | 30 4 * * 0 | — | 3 | mcp.credential-grant-retention.ts |
mcp.tool-snapshot-retention | 0 4 2 * * | — | 3 | mcp.tool-snapshot-retention.ts |
memory.curate | memory/curate.requested | — | 3 | memory.curate.ts |
memory.curate-daily | 17 6 * * * | memory/curate.requested | 1 | memory.curate.ts |
notification/deliver | notification/event.raised | — | 4 | notification.deliver.ts |
notification/sweep | */5 * * * * | notification/event.raised | 1 | notification.deliver.ts |
observability.capture-failure | inngest/function.failed | — | 0 | observability.capture-failure.ts |
plugin.catalog-sync | 0 */6 * * * | — | 1 | plugin.catalog-sync.ts |
plugin.oauth-refresh-watcher | — | 0 | plugin.oauth-refresh-watcher.ts | |
privacy.erasure-execute | privacy/erasure.execute | — | 3 | privacy.erasure.execute.ts |
privacy.export-process | privacy/export.process | — | 2 | privacy.export.process.ts |
project-spend-attribution | spend/attribution.project | spend/attribution.project | 2 | spend-attribution-projection.ts |
prune-status-reports | 35 1 * * * | — | 2 | status-reports.ts |
repository-config/cleanup | repository-config/cleanup.requested | — | 3 | repository-config.cleanup.ts |
repository-config/rescan | repository-config/rescan.requested | — | 3 | repository-config.rescan.ts |
run.classify-kind | run/classify-kind | — | 2 | run.classify-kind.ts |
run.classify-kind-request | cost/run.sealed | — | 3 | run.classify-kind.ts |
run.classify-kind-sweep | */5 * * * * | — | 2 | run.classify-kind.ts |
run.enrich | run/enrich | — | 2 | run.enrich.ts |
run.enrich-scratch-expire | — | 3 | run.enrich-scratch-expire.ts | |
run.enrichment-sweep | */5 * * * * | run/enrich | 2 | run.enrich.ts |
run.fit | run/fit.requested | — | 3 | run.fit.ts |
run.reflect | cost/run.sealed | memory/curate.requested | 3 | run.reflect.ts |
run.residue | run/residue.requested | — | 3 | run.residue.ts |
run.residue-request | cost/run.sealed | — | 3 | run.residue.ts |
run.residue-sweep | 23 * * * * | — | 2 | run.residue.ts |
run/artifact-backfill | run/artifact.linked | — | 3 | run.artifact-backfill.ts |
run/infer-work | run/infer-work | — | 2 | run.infer-work.ts |
run/pull-request-backfill | run/pull-request.linked | — | 3 | run.pull-request-backfill.ts |
sandbox.template-build | sandbox/template.build.requested | — | 2 | sandbox.template-build.ts |
sandbox.template-build-sweep | */10 * * * * | sandbox/template.build.requested | 1 | sandbox.template-build.ts |
schedule-spend-attribution-projection | * * * * * | spend/attribution.project | 1 | spend-attribution-projection.ts |
schema-reconcile | schema/reconcile.start | — | 2 | schema.reconcile.ts |
security.audit-partition-rollover | 0 3 * * * | — | 3 | security.audit-partition-rollover.ts |
similarity/reconcile | 15,45 * * * * | — | 2 | similarity.reconcile.ts |
steer/repeated | 17 * * * * | — | 2 | steer.repeated.ts |
steering-repo/headless-backfill | */15 * * * * | steering-repo/provision.requested | 1 | steering-repo.backfill.ts |
steering-repo/health-check | steering-repo/health.requested | — | 3 | steering-repo.sweep.ts |
steering-repo/health-sweep | 0 * * * * | steering-repo/health.requested | 1 | steering-repo.sweep.ts |
steering-repo/provision | steering-repo/provision.requested | — | 4 | steering-repo.provision.ts |
steering/sync | steering/sync.requested | — | 3 | steering.sync.ts |
steering/sync-now | steering/sync.now | — | 3 | steering.sync.ts |
steering/sync-sweep | 0 * * * * | steering/sync.requested | 1 | steering.sync.ts |
stella.answer-from-rules | agent/question.raised | — | 2 | stella.answer-from-rules.ts |
stella.session-archive | 30 4 * * * | — | 3 | stella.session-archive.ts |
tacho.session-idle-close | */15 * * * * | cost/run.sealed | 3 | tacho.session-idle-close.ts |
work.attachments-sweep | 17 * * * * | — | 3 | work.attachments-sweep.ts |
work.classify-kind | work/classify-kind | — | 2 | work.classify-kind.ts |
work.classify-kind-sweep | */5 * * * * | — | 2 | work.classify-kind.ts |
work/base-advanced | work/base-advanced | — | 2 | work.order-results.ts |
work/intake-check | work/collector.check.requested | — | 2 | work.intake.ts |
work/intake-collect | work/event.received | work/collector.check.requested | 4 | work.intake.ts |
work/intake-count-sweep | 23 3 * * * | — | 1 | work.intake.ts |
work/intake-prune | 41 4 * * * | — | 1 | work.intake.ts |
work/intake-sweep | */15 * * * * | — | 1 | work.intake.ts |
work/intake-triage | work/item.received | — | — | work.intake.ts |
work/item-embed | work/item.embed-requested | — | 3 | work.item-embed.ts |
work/item-embed-sweep | 37 5 * * * | — | 1 | work.item-embed.ts |
work/order-pull-request-linked | run/pull-request.linked | — | 3 | work.order-results.ts |
work/order-results-sweep | 35 * * * * | — | 2 | work.order-results.ts |
work/order-run-ended | cost/run.sealed | — | 5 | work.order-results.ts |
work/status-sync | work/collector.check.requested | — | 2 | work.intake.ts |
work/triage-batch | work/triage.batch.requested | — | 2 | work.intake.ts |
work/triage-sweep | */15 * * * * | — | 1 | work.intake.ts |
workspace/join-request-expiry | 25 3 * * * | — | 3 | workspace.join-request-expiry.ts |
write-status-reports | 5 */3 * * * | — | 2 | status-reports.ts |
CLI and MCP surfaces
The CLI speaks HTTP to apps/api, typing responses from the contracts in @oxagen/oxagen where it imports them and by hand elsewhere; the MCP server exposes one tool per contract whose surfaces include mcp, named exactly after the contract.
MCP tools
606 tool files under apps/mcp/src/tools, 606 contracts declare the mcp surface. Every tool file matches a contract stem.
CLI commands
From apps/cli/src/program.ts, the side-effect-free Commander tree.
| Command | Description |
|---|---|
agent | Govern the workspace's registered agents |
agent backfill | Record the Claude Code sessions this machine ran before it enrolled, from the transcripts Claude Code kept |
agent connect | Connect this device to a new agent with the request the page shows, and report the device back to the page. Enrolls nothing until you confirm |
agent detect | Which harnesses this machine has (claude, codex, cursor-agent, stella) and which are enrolled |
agent draft | Save and finish agent setup |
agent draft cancel | — |
agent draft finish | — |
agent draft get | — |
agent draft save | Save an unfinished agent setup |
agent enroll | Wrap this machine: device key, host credential, collector service, harness hooks. A single-use enrollment token (oxe_1time_…) enrolls it as that registered agent's host; anything else uses a platform API token or the logged-in session |
agent enroll-token | Mint a single-use enrollment token for an agent, and print the command that enrolls a machine with it. Owner only |
agent export | Export a session from the local WAL |
agent hosts | Every machine enrolled in this workspace, with the enforcement tier each of its apps reaches |
agent label | — |
agent reassign | Point this host at another workspace (or org): revoke, then enroll again keeping the device key |
agent register | Register an agent: one harness on one runtime, carrying a toolbelt. Prints its credential once. Registers your own agent |
agent register-machine | Get a machine ready to wrap one harness: find or make its runtime and your agent, and mint an enrollment token. Prints the steps to run, or enrolls this machine with --enroll. Owner only |
agent resume | Let a suspended agent run again. Owner only |
agent retire | Retire an agent: archive it and revoke its credentials, hosts, and mandates. Its runs keep their identity. Owner only |
agent run | Run one agent session under Oxagen control: a custom agent by its own command (`oxagen agent run --name my-agent -- ./my-agent`), a wrapped harness through its hooks, or Claude Code or Codex in the contained launcher with --contained |
agent status | — |
agent suspend | Suspend an agent: no governed run starts for it, and its credentials, roles, and hosts stay. Owner only |
agent unenroll | — |
agent uninstall | Take Oxagen off this machine without the desktop app: unenroll every agent, then remove the app's per-user copy, PATH links, and shell profile lines, and ~/.config/oxagen, which holds your `oxagen login` session |
agent verify | Run one headless turn (Claude Code by default) and confirm it was chained |
api-key | Rotate a workspace API key and confirm the rotation |
api-key acknowledge | Confirm the new key arrived, which revokes the key it replaced at once |
api-key rotate | Issue a replacement key; the old key keeps working for 24 hours |
approvals | Read the workspace's approval ledger |
approvals resolved | List resolved approvals, most recently resolved first, including a call a decision rule auto-approved with no person |
asset | Ingest and manage binary assets in object storage |
asset upload | Ingest an asset from a public URL. With --conversation, records it as a |
attention | List what waits on you in this workspace: approvals and questions on your runs, work orders in review, ready work items assigned to you, and steering suggestions |
billing | The organization's billing statements |
billing statement | Read or export the billing statement for a week, month, quarter, year or custom period |
briefing | Read what changed since you last opened the Stella page: runs that ended, work orders that reached review, and how much waits on you |
budget | Hard period-to-date spend ceilings that gate agent runs (org + workspace) |
budget no-progress | The identical calls in a row that stop a run counting as progress |
budget no-progress set | Open a steering PR that changes the limit (org Owner or workspace Admin) |
budget no-progress show | Show the limit in force, its open steering PR, and the runs that reached it |
budget set | Set (create or replace) a spend ceiling (Owner/Admin/Billing only) |
budget show | Show configured spend ceilings with their live burn |
check | — |
config | Read or set the CLI's settings: default_workspace_id, api_url, app_url. With no flags, list them |
context | Steering: record a suggestion for a steering record, or revert a merged one |
context propose | Record a suggestion (the record it should become, why). Open and merge it with `oxagen steering open` and `oxagen steering merge`. |
context revert | Open a steering PR that undoes a merged one (revert_steering_pr); it merges after its own review |
conversation | Export and inspect chat conversations |
conversation export | Export a conversation's active branch as Markdown (stdout/file) or a |
cost | Project model cost from the baked-in rate card (observed spend: `budget show`) |
credentials | Manage your model credentials: API keys and Claude or ChatGPT logins. They belong to your account, so every workspace you work in can use them. The gateway attaches them to your runs and never puts one in a sandbox. Also named keys |
credentials check | Ask the provider whether a credential it refused works again, once you fixed the account. A pass continues the runs that waited on it. Exits 1 unless the check passed |
credentials create | Save a credential on your account. With --harness it runs the harness's own sign-in and saves the login. With --provider it saves an API key. Several for one harness or provider are fine. Also named add |
credentials list | List your credentials in the order the gateway uses them |
credentials reauth | Answer a sign-in request Oxagen sent this machine for a login the provider refused: confirm it, run the agent type's own login, and save the new login in place of the saved one |
credentials remove | Remove one of your credentials |
credentials rotate | Replace the key of one of your API keys in place. Asks first unless --yes. The new key comes from a hidden prompt or from standard input, never from an argument |
credentials update | Rename, pause, or resume one of your credentials |
env | Manage workspace environments |
env create | Create an environment |
env get | Show one environment |
env list | List environments in the active workspace |
env rm | Delete an environment (not the default) |
env set-default | Promote an environment to the workspace default |
env update | Update an environment |
findings | The workspace's costed findings and what each would save |
findings list | List the findings by the money at stake, 50 a page; with --run, only those citing the run, with the frames each cites |
fleet | List your work items by workstream, each with its runs and their subagents, and whether each one is working, waiting on you, failed, done or quiet |
graph | Search the knowledge graph, build code graphs on this machine, and upload CI reports to the code graph |
graph init | Give each agent on this machine Oxagen's MCP entry, then build the working tree's code graph here (default: the current folder). Needs an enrolled machine |
graph rebuild | Build the working tree's code graph again, even when it has not changed (default: the current folder) |
graph search | Semantic (vector) search across the customer context graph |
graph status | Show every code graph built on this machine |
graph stop | Stop the local code graph server. The next code graph call starts it again |
graph upload | Upload coverage, test reports, runtime profiles, schema dumps, infrastructure plans, and API specs from CI. Signs in with the CI provider's OIDC token, with no login |
hook | The command hook a wrapped harness runs: reads the payload on stdin and prints the answer |
init | Pick the Oxagen org + workspace the CLI works in, and report this directory to it. Writes no file here |
login | Authenticate the CLI. Opens a browser by default (interactive). Use --token for CI/headless. |
logout | Revoke this machine's sign-in on the server and clear it from ~/.config/oxagen/config.json. |
logs | See and debug the CLI's log (~/.oxagen/logs/cli.output). Captures each invocation, |
mcp | List and call the tools shipped by the MCP server |
mcp call | Call a tool and print its complete MCP result as JSON |
mcp describe | Print one tool's description and schemas as JSON |
mcp list | Print every available tool and its schemas as JSON |
memory | Review the memories agents wrote in their harnesses: list, show, promote into steering records, or dismiss |
memory dismiss | Dismiss memories so the curator does not propose them again, or restore them with --restore |
memory drop | Drop one proposed record from an open memory PR. When the PR merges, the record's statements are rejected and its memories wait again |
memory import | Read Markdown files into steering records with a kind and a force for each statement. Previews unless --yes. |
memory list | List the workspace's memories ranked by uses, one row per group of memories that say the same thing |
memory promote | Promote waiting memories into draft steering records on the open memory PR, or open one. One record per id. Oxagen suggests each record's kind and force unless you name them |
memory show | Show one memory with its full text, its source, the runs that used it, and its memory PR |
price | The organization's negotiated rates in the price book: what runs are billed at |
price list | Read current prices and optionally scheduled negotiated rates |
price remove | End a negotiated rate so the model returns to the list price (Owner/Admin/Billing only) |
price set | Set a negotiated rate for one model and token class (Owner/Admin/Billing only) |
repo | The workspace's repositories: one steering repository, which holds its steering record, and the linked ones its agents work on |
repo branch | Confirm or change a repository's production branch; the branch must exist on GitHub |
repo governance | Set the steering governance mode: who may merge a steering PR in this workspace |
repo link | Open the steering PR that links a GitHub repository the workspace's GitHub App installation reaches. The link follows the merge. |
repo list | Every repository the workspace binds, the steering repository first, with each one's approved default ref and binding id |
repo scan | List the agent harness files on a repository's default branch: instruction and rule files, skills, commands, subagent files, settings files and MCP configs. The repository need not be linked. |
repo tree | What the workspace's steering repository holds on its production branch, read from GitHub now |
repo unlink | Unlink a linked repository by its binding id. A repository workspace.toml lists is removed by a steering PR. The steering repository is refused. |
router | Verified-Outcome Market Router: learned, economic model routing |
router policy | Get or set the governed market-router policy |
router policy get | Show the effective policy and its provenance |
router policy set | Update the policy, which changes spend behavior (org Owner) |
router preview | Dry-run the routing decision for a prompt (changes nothing) |
run | Start an agent under the contained launcher (`oxagen run -- claude -p <task>`), start a run in its own sandbox (`oxagen run --harness claude --workspace-slug <slug> --repo <owner/name>`), or read a recorded run: its chain, Oxagen's lock on it, and its locked evidence export |
run answer | Answer the question a run paused to ask: --text for an agent's own question, --link or --create for a repository the workspace has not bound, --link --criterion or --deny for a residue item |
run chain | Show what makes a run's record tamper-evident: the hash rule, the root, the locks taken along the way, the gaps, and the replay ladder |
run context | Show what each of a run's model requests carried: the prompt tokens and each block's share of them |
run download | Download a ready run export and check its sha256 against the recorded hash |
run draft-answer | Show the answers stella drafted for an agent's question, the recommended one first |
run export | Queue the evidence export for a locked run. Oxagen locks the export so anyone can check it offline (Owner only) |
run export-status | Show where a run export stands and, once it is ready, its download link |
run list | List the workspace's runs, newest first |
run pause-all | Pause every live wrapped run in the workspace as one recorded decision. Org Owner, or workspace Admin |
run reopen | Take back an answer stella gave to an agent's question from one of your rules, so the question waits for you again |
run show | Show one run: its header, the pause in force, a page of its frames, and its subagent chains |
run transcript | Read one page of a run's transcript: its entries, the count per chip over the whole run, and a search of the kept bodies |
run turns | Show a run's cost turn by turn: each turn's model and tool steps, frames, cache hit, cost, and the cost so far |
runtime | List, create, change, or delete the runtimes agents run on, such as a laptop or a VM |
runtime create | Name a runtime in the workspace. Org Owner |
runtime list | List the workspace's runtimes with the agents and hosts on each |
runtime rm | Delete a runtime for good, once no agent, host, or sandbox uses it. Org Owner |
runtime update | Rename a runtime, change its slug, or change its containment. Org Owner |
sandbox | Start, list, show, attach to, or stop runs in their own sandboxes. Set up sandbox runtimes, and generate and test their templates |
sandbox attach | Open the terminal of one of your sandbox runs. Ctrl-] detaches and leaves the run going |
sandbox list | List your own sandbox runs in the workspace, live first and then the newest |
sandbox pin-hooks | Write the sandbox's hook files as the launcher does, and print their hash |
sandbox review | Ask another agent to review a sandbox's work (the server refuses this until #7100 ships) |
sandbox run | Start a run in its own sandbox. With no prompt and no work order it opens a terminal and attaches to it |
sandbox runtime | List, set up, change, or delete the workspace's sandbox runtimes. Each run on one gets its own sandbox in the workspace's Modal account |
sandbox runtime create | Set up a sandbox runtime on the workspace's Modal account and queue its template build. Modal bills the workspace for the build and every run. Org Owner |
sandbox runtime list | List the workspace's sandbox runtimes with each one's template state and size |
sandbox runtime rm | Delete a sandbox runtime for good, once no run on it is live and no build is running. Org Owner |
sandbox runtime setup | Give the workspace a cloud sandbox runtime with no settings to pick, or show the one it has. Modal bills the workspace for the template build and every run. Org Owner |
sandbox runtime update | Change a sandbox runtime's setup. A new template queues a build, which Modal bills the workspace for. Org Owner |
sandbox show | Show one sandbox run: its state, runtime, host, and estimated cost |
sandbox stop | Stop one of your sandbox runs and free its sandbox |
sandbox template | Generate the workspace's sandbox template into its steering repo, or test a sandbox runtime's template |
sandbox template generate | Write a sandbox template from the linked repositories, or from a starter, and open a steering PR. Org Owner, or workspace Admin |
sandbox template log | Print the stored log of one template build of a sandbox runtime, with credentials redacted. Org Owner, or workspace Admin |
sandbox template test | Start a short sandbox from a sandbox runtime's ready template and check each service and toolchain. Modal bills the workspace for it. Org Owner, or workspace Admin |
secret | Manage the workspace credential vault |
secret export | Export resolved secrets as .env (recorded to the access log) |
secret import | Import .env text (preview unless --yes) |
secret list | List vault keys (masked metadata) |
secret reveal | Reveal a secret's plaintext value (recorded to the access log) |
secret rm | Delete a key, or just an environment override with --env |
secret set | Set a secret's default value, or an override with --env |
spend | The organization's agent spend, split by dimension |
spend attribution | — |
spend export | Export Spend as CSV or a spreadsheet |
spend summary | Read the stored status briefing |
steer | Send a steer to one run, to every run of an agent, or to every run going in the workspace |
steer list | List the steers and commands sent to one run, newest first, with what became of each |
steering | Steering records: draft, save, merge, and dismiss suggestions, Markdown import, and instruction file findings |
steering dismiss | — |
steering draft | — |
steering findings | List the statements in linked repositories' instruction files that repeat or contradict a steering record |
steering import | — |
steering merge | — |
steering open | — |
steering promote | — |
steering restore-block | — |
steering save | Save a steering record's fields as a new suggestion, then open or merge its steering PR |
steering suggestions | List the open steering suggestions and the waiting memories |
stella | Read and change what stella may do alone for you |
stella permissions | List each switch for what stella may do alone for you in this workspace, and whether it asks first or acts alone |
stella set-permission | Set one switch to ask or alone: answer-from-rules, relaunch-failed-work, create-issues, update-source-issues or steer-agents |
telemetry | Inspect or control anonymous CLI usage telemetry (on by default; see TELEMETRY.md) |
tier | The organization's model tiers and the model each harness runs for them |
tier add | Add a model tier (organization Owner only) |
tier archive | Archive a tier (organization Owner only) |
tier list | List the model tiers in rank order, lightest first |
tier model | Set the model a harness runs for a tier, or none to clear it (organization Owner only) |
tier update | Rename a tier, rewrite its guidance, move it, make it the default, or choose who pays for its stella turns (organization Owner only) |
tools | The workspace's connected MCP servers and their tools |
tools approve-schema | Approve the output schema the gateway observed for a tool version whose server declares none |
tools migrate | Open the pull request that moves the workspace's MCP servers into its steering repo, or print the one already open |
verify | Check a run export or a claim export offline: each frame's hash and link, each lock, and for a claim export each timestamp, inclusion proof, gap, read, and recording path |
work | See and start the work orders Oxagen sent to the agents on this machine, claim an item of the Done Checklist or post a progress update from inside a run, and recommend a work item's model tier and effort |
work claim | From inside a work order's run, claim that the pushed head commit meets one item of the Done Checklist. A person still decides. |
work list | List the work orders waiting on this machine |
work progress | From inside a work order's run, post a progress update after a step of your plan. A question in --ask waits for a person's answer. |
work staffing | Recommend the model tier and effort for one work item from the runs similar work ran on |
work start | Claim a work order, then start the agent in this directory with the order's Done Checklist as its first prompt |
workspace | Choose the workspace the CLI works in, and connect this machine to one |
workspace | Choose the workspace the CLI works in, and connect this machine to one |
workspace connect | Connect this machine to a workspace: pick the installed harnesses to register, and each becomes an agent you own, such as anderson-claudecode-local |
workspace connect | Connect this machine to a workspace: pick the installed harnesses to register, and each becomes an agent you own, such as anderson-claudecode-local |
workspace current | Show the active workspace and how this machine reports to it |
workspace current | Show the active workspace and how this machine reports to it |
workspace link | Remember a workspace on this machine, and with --save make it the CLI's default, without changing the one it takes sends from |
workspace link | Remember a workspace on this machine, and with --save make it the CLI's default, without changing the one it takes sends from |
workspace list | List the workspaces you belong to as org/workspace, with the active one and the ones this machine reports to |
workspace list | List the workspaces you belong to as org/workspace, with the active one and the ones this machine reports to |
workspace switch | Ask one of your enrolled machines to take new runs from another workspace. The machine applies it when its recorder next checks in |
workspace switch | Ask one of your enrolled machines to take new runs from another workspace. The machine applies it when its recorder next checks in |
workspace use | Make a workspace the one the CLI works in and the one this machine takes sends from |
workspace use | Make a workspace the one the CLI works in and the one this machine takes sends from |
Deployment
One AWS account managed by OpenTofu stacks under infra/stacks-new. Production runs on one application node behind an ALB. Postgres and ClickHouse run in ClickHouse Cloud (ADR-295), and Neo4j runs on the node. Staging is a dormant copy of that shape under staging.oxagen.sh, and production deploys do not wait on it. GitHub Actions deploys over OIDC.
Production topology (AWS account 916294258235)
- For the node's hostnames only the ALB terminates TLS (ACM, DNS-validated). CloudFront terminates it for
oxagen.sh,www.oxagen.shanddownloads.oxagen.sh. The node has no public IP and no SSH key. Administration is SSM Session Manager, and Neo4j and ClickHouse bind to 127.0.0.1 only. deploy-noderuns twice on ARM runners aftermigration-gate. Wave 1 deploys api and stella-serve in parallel, beside the code graph's services.api-healthythen waits for 20 seconds of healthy answers before wave 2 deploys app, mcp and docs. Services in a wave restart at staggered times.deploy-guard.shends a job green without shipping when a newer push covers the commit or production's schema is newer.- On every push to
main,migration-gateapplies pending migrations beforedeploy-nodeships. Postgres goes throughinfra/tools/apply-postgres-migrations.sh, which runs Atlas on the node over SSM. ClickHouse and Neo4j go throughtools/scripts/db-migrate.tswhencheck-store-drift.shfinds them behind. The deploy proceeds only when every store then reads current. A store that is behind or unreadable blocks it.deploy-webdoes not wait on the gate. The manual DB Migrate and Store Migrate workflows cover the cases the gate refuses. - Every service log group is archived unfiltered through Kinesis Firehose to S3. Lines matching ERROR, WARN, FATAL, CRITICAL, incident or outage, or a pino level of 40 or above, reach an EventBridge bus through a Lambda publisher. The ingestion KMS key (
alias/oxagen-app/ingestion) wraps stored connector credentials and OAuth tokens.
Source refs (22, verified at build)
infra/stacks-new/oxagen/main.tfinfra/stacks-new/oxagen/data-services.tf#aws_rds_clusterinfra/stacks-new/oxagen/downloads.tfinfra/stacks-new/oxagen/observability.tf#publish-incidentsdocs/adr/ADR-295-clickhouse-and-postgres-run-in-clickhouse-cloud.mdinfra/modules/network/main.tf#aws_eiptools/ci/deploy-guard.shtools/ci/plan-main.shinfra/stacks-new/oxagen/crypto.tf#alias/oxagen-app/ingestioninfra/modules/app-node/main.tfinfra/modules/network/main.tfinfra/modules/static-site/main.tfinfra/tools/caddy/Caddyfile.alb#internal.oxagen.shinfra/stacks-new/ci-deploy/infra-apply.tfinfra/stacks-new/ci-deploy/ssm.tf#oxagen-deploy-service.github/actions/ship-to-node/action.yml.github/workflows/main.yml#migration-gate:tools/ci/ship-to-node.shinfra/tools/apply-postgres-migrations.shinfra/tools/check-store-drift.shtools/scripts/package-for-node.sh#127.0.0.1:4300tools/scripts/build-env.ts
Caddy host routing on the node
Read from infra/tools/caddy/Caddyfile.alb.
| Host | Upstream |
|---|---|
api.oxagen.sh | 127.0.0.1:4000 |
app.oxagen.sh | 127.0.0.1:3000 |
docs.oxagen.sh | 127.0.0.1:3002 |
gateway.oxagen.sh | 127.0.0.1:4000 |
internal.oxagen.sh | 127.0.0.1:3003 |
mcp.oxagen.sh | 127.0.0.1:4100 |
stella.oxagen.sh | 127.0.0.1:3001 |
CI job graph (main)
- Every deploy job starts with
tools/ci/deploy-guard.sh, which ends it green without shipping when a newer push covers the commit or production's schema is newer than the commit.
Workflows
| File | Name | Triggers | Jobs |
|---|---|---|---|
ci-image.yml | ci-image | workflow_dispatch schedule push | 2 |
codegraph.yml | codegraph | workflow_dispatch | 5 |
db-migrate.yml | DB Migrate (manual) | workflow_dispatch | 2 |
deploy-node.yml | deploy-node | workflow_call | 1 |
desktop.yml | Desktop | push release schedule workflow_dispatch | 4 |
infra.yml | infra | pull_request push workflow_dispatch | 3 |
main.yml | main | push | 9 |
npm.yml | npm | push workflow_dispatch | 1 |
oxagen-ci-mirror.yml | oxagen-ci mirror | push workflow_dispatch | 1 |
pr.yml | pr | pull_request | 7 |
release.yml | Release | workflow_dispatch push | 2 |
store-migrate.yml | Store Migrate (manual) | workflow_dispatch | 1 |
Local development stack
Services from docker-compose.dev.yml; Postgres is published on host port 5433 so it does not collide with another Postgres on 5432. stella-serve is published on 4300, the port app and api call.
| Service | Image |
|---|---|
postgres | postgres:16-alpine |
stella-serve | ghcr.io/macanderson/stella-serve:${STELLA_SERVE_IMAGE_TAG:-0.9.414} |
neo4j | neo4j:5.24-community |
clickhouse | clickhouse/clickhouse-server:24.8-alpine |
Configuration contract
Every deployable surface's environment, declared once and generated everywhere else.
239 variables from packages/config/src/registry.ts, the single source for .env.example, the build environment, pnpm env:pull, and the CI env checker. A dot marks a service that needs the variable. The required column gives the initial of each environment that requires it. Secrets and variables lists where each value is kept and how to refresh it.
Agent engine
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
STELLA_SERVE_TOKEN secret | ● | ● | · | · | · | · | P | manual | Bearer token the Stella engine was started with. The same value the engine's own container reads under its prefix; without it the assistant reports the engine as unavailable. |
STELLA_SERVE_URL | ● | ● | · | · | · | · | P | static | Where the Stella engine (stella-serve) listens. The in-app agent's turns run there; every model call and tool call comes back to this process to answer (ADR-053). Loopback on the node. |
AI providers
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
AI_GATEWAY_API_KEY secret | ● | ● | ● | · | · | · | — | manual | Vercel AI Gateway token for language models. @oxagen/ai routes text through the gateway only where OXAGEN_MODEL_PROVIDER is 'gateway', which is local development. Deployed environments run on OpenRouter and do not need it. Embeddings use VOYAGE_API_KEY instead. |
ANTHROPIC_API_KEY secret | · | · | · | · | · | · | — | manual | CLI-only BYOK fallback: when no AI_GATEWAY_API_KEY exists anywhere, the CLI runs anthropic/* models directly against the Anthropic API with this key (other vendors and embeddings stay unavailable). The gateway key always wins when both are set. Never read by deployed services, because platform AI is gateway-only. |
OPENROUTER_API_KEY secret | ● | ● | ● | · | · | · | P P | manual | OpenRouter token for language models in preview and production, where OXAGEN_MODEL_PROVIDER is 'openrouter'. Local development reads it only when it sets that provider too. |
OPENROUTER_MANAGEMENT_KEY secret | ● | ● | ● | · | · | · | — | manual | OpenRouter provisioning key, not an inference key (ADR-131). Mints one capped token per organisation so the vendor reports usage per customer. It can create, read, disable and delete every key in the account, so it is read in one module and never reaches a provider client or a log. Unset means no key is minted and every organisation serves on the shared key. Read only when OXAGEN_MODEL_PROVIDER=openrouter: a minted key cannot serve on a gateway deployment, so none is minted there (ADR-131 §9). |
OPENROUTER_ORG_KEY_DAILY_LIMIT_USD | ● | ● | ● | · | · | · | — | manual | Daily USD ceiling on each organisation's minted OpenRouter key. A blast radius, not a budget: the credit gate bounds what a customer may spend, and this stops one runaway loop draining the account every other customer's assistant depends on. A key that hits it stops answering until midnight UTC, so set it well above a heavy legitimate day. Unset falls back to 25, which is the ceiling ADR-131 reasons about. |
OPENROUTER_WORKSPACE_ID | ● | · | · | · | · | · | — | manual | The OpenRouter workspace the organizations' minted keys sit in. The code graph lists that workspace's batches to find one an earlier attempt sent before it sends again (ADR-310), so a batch runs only where this is set. Unset means code graph enrichment sends no batch and records the pass as not allowed (ADR-340). |
OXAGEN_LLM_BALANCED | ● | ● | ● | · | · | · | — | static | Balanced model: the gateway model id Oxagen's own calls run on when they ask for the balanced tier, and a call that names no model. A stella turn's own model comes from the organization's model tiers (#7197). |
OXAGEN_LLM_BATCH | ● | · | · | · | · | · | — | static | Batch model: the OpenRouter model id bulk triage sends through OpenRouter's batch API when the platform provider is OpenRouter. Its provider must take OpenRouter batches (ADR-309). |
OXAGEN_LLM_FAST | ● | ● | ● | · | · | · | — | static | Fast model: the gateway model id Oxagen's own quick calls run on, such as conversation titles, drafts and triage, and a stella turn's summaries and verdicts. A stella turn's own model comes from the organization's model tiers (#7197). |
OXAGEN_LLM_PRECISE | ● | ● | ● | · | · | · | — | static | Precise model: the gateway model id Oxagen's own calls run on when they ask for the precise tier, such as schema chat. A stella turn's own model comes from the organization's model tiers (#7197). |
OXAGEN_LLM_SUMMARY | ● | · | · | · | · | · | — | static | Summary model: the gateway model id run accounts (run names and summaries) are written on when Oxagen pays. A customer's own key keeps its fast tier. |
OXAGEN_MODEL_PROVIDER | ● | ● | ● | · | · | · | — | static | Which provider serves language models: 'openrouter' in preview and production, on OPENROUTER_API_KEY, and the Vercel AI Gateway in local development. Never an automatic fallback: a silent failover would move spend to another vendor's bill. Embeddings use Voyage either way. The per-organisation keys ADR-131 mints are OpenRouter keys, so they are minted and consulted only when this is 'openrouter' (ADR-131 §9). |
VOYAGE_API_KEY secret | ● | ● | ● | · | · | · | P | manual | Voyage AI key for every embedding (voyage-4-large, 1,024 dimensions). One platform key serves every organisation, and every embedding is billed. Without it, embedding calls answer 503 and ingestion stores records without vectors. |
Asana
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
ASANA_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Asana OAuth client ID for connecting Asana as a work tracker. Connecting Asana answers not configured until this and ASANA_OAUTH_CLIENT_SECRET are set. |
ASANA_OAUTH_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | Asana OAuth client secret, sent to Asana's token address when a person connects Asana and when its tokens refresh. |
Azure DevOps
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
AZURE_DEVOPS_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Azure DevOps OAuth client ID for connecting Azure DevOps as a work tracker. Connecting Azure DevOps answers not configured until this and AZURE_DEVOPS_OAUTH_CLIENT_SECRET are set. |
AZURE_DEVOPS_OAUTH_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | Azure DevOps OAuth client secret, sent to Azure DevOps's token address when a person connects Azure DevOps and when its tokens refresh. |
Basecamp
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
BASECAMP_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Basecamp OAuth client ID for connecting Basecamp as a work tracker. Connecting Basecamp answers not configured until this and BASECAMP_OAUTH_CLIENT_SECRET are set. |
BASECAMP_OAUTH_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | Basecamp OAuth client secret, sent to Basecamp's token address when a person connects Basecamp and when its tokens refresh. |
Better Auth
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
AUTH_TOKEN_ENCRYPTION_KEY secret | ● | ● | ● | · | · | · | P P | manual | Base64 256-bit KEK that wraps OAuth token encryption keys. Required in preview+production (enforced by the auth startup guard); blank locally disables it. Unset, every capability that encrypts a secret with it refuses rather than store the secret in plaintext. Generate with `openssl rand -base64 32`. |
BETTER_AUTH_SECRET secret | ● | ● | · | · | · | · | D P P | generate | Secret (≥32 chars) that locks sessions and cookies. Minted once per env and applied identically to api + app so sessions validate across both. |
BETTER_AUTH_TRUSTED_ORIGINS | ● | ● | · | · | · | · | — | static | Comma-separated origins allowed cross-origin access to the auth API. |
BETTER_AUTH_URL | ● | ● | · | · | · | · | D P P | static | Auth base URL (the app origin). |
OAUTH_PROXY_PRODUCTION_URL | ● | ● | · | · | · | · | — | static | Official production origin the shared social-login OAuth app's callback is registered against (OAuth Proxy productionURL). Preview deployments relay social login through this origin. Defaults to the production app URL when unset. |
OAUTH_PROXY_SECRET secret | ● | ● | · | · | · | · | — | manual | Dedicated secret the OAuth Proxy uses to encrypt/decrypt the relay payload between production and preview deployments. MUST be set to the SAME value in production AND preview for preview social login to work (production alone only passes through). Kept separate from BETTER_AUTH_SECRET to limit blast radius. Generate with `openssl rand -base64 32`. |
SSO_SECRET_KEY_ID | ● | ● | ● | · | · | · | — | manual | Key id written into every SSO provider secret encrypted under AUTH_TOKEN_ENCRYPTION_KEY. Unset means sso_v1. Give it a new value when you rotate that key, and list the old key in SSO_SECRET_PREVIOUS_KEYS under the old id (ADR-145). |
SSO_SECRET_PREVIOUS_KEYS secret | ● | ● | ● | · | · | · | — | manual | Retired SSO secret keys that still open existing tokens, as comma-separated <keyId>=<base64 32-byte key> entries. Remove an entry once an auth/sso-reseal run reports no failures (ADR-145). |
Billing
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
OXAGEN_ASSISTANT_MARKUP | ● | ● | ● | · | · | · | — | manual | Markup (>=1) on the provider's list price for the in-app assistant's model calls on Oxagen's key. Unset means 1.20, list price plus 20%. |
OXAGEN_PRICE_OVERRIDES secret | ● | ● | ● | · | · | · | — | manual | Negotiated model rates as inline JSON, in USD per one million tokens: {"claude-sonnet-5":{"inputPer1M":2.40,"outputPer1M":12.00,"cachedInputPer1M":0.24,"cacheWrite5mPer1M":3.00}}. Leave unset unless you have negotiated rates with a model provider. |
OXAGEN_PRICE_OVERRIDES_FILE | ● | ● | ● | · | · | · | — | manual | Path to a JSON file of negotiated model rates, same shape as OXAGEN_PRICE_OVERRIDES. Wins over the inline value when both are set, so a mounted secret does not need the variable cleared. |
Circuit breaker
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
CIRCUIT_BREAKER_FAILURE_THRESHOLD | ● | ● | ● | · | · | · | — | manual | Consecutive failures before a breaker opens for a wrapped dependency call (Neo4j / Stripe / ClickHouse). Optional. Defaults to 5 in packages/config/src/env.ts. |
CIRCUIT_BREAKER_RESET_TIMEOUT_MS | ● | ● | ● | · | · | · | — | manual | Milliseconds an open breaker waits before allowing a trial (half-open) request. Optional. Defaults to 30000 in packages/config/src/env.ts. |
CIRCUIT_BREAKER_SUCCESS_THRESHOLD | ● | ● | ● | · | · | · | — | manual | Consecutive successes required in the half-open state before a breaker closes. Optional. Defaults to 1 in packages/config/src/env.ts. |
CLI
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
DO_NOT_TRACK | · | · | · | · | · | · | — | manual | Cross-tool opt-out convention (https://consoledonottrack.com): set to '1' to disable CLI usage telemetry. Checked before OXAGEN_TELEMETRY and the persisted telemetry.enabled config. |
OXAGEN_ALLOW_STDIO_MCP | · | · | · | · | · | · | — | manual | Set to '1' or 'true' to allow stdio-transport MCP servers to be SPAWNED as child processes from workspace file-mcp plugin configs (packages/agent file-mcp.ts). Spawning is OFF by default because a workspace-scoped config could otherwise execute arbitrary commands on the API host. Enable only for a trusted local/CLI runtime, never on shared server deployments. HTTP MCP transports are unaffected and always processed. |
OXAGEN_API_TOKEN secret | · | · | · | · | · | · | — | manual | API token used by the CLI to authenticate requests; falls back to the value stored in ~/.oxagen/config.json. |
OXAGEN_API_URL | · | · | · | · | · | · | — | static | Base URL for the Oxagen REST API, consumed by the CLI. Falls back to the default production API URL when unset. |
OXAGEN_APP_URL | · | · | · | · | · | · | — | static | Base URL for the Oxagen web app, where `oxagen login` opens the browser authorize page. Falls back to the default production app URL when unset. |
OXAGEN_CLI_DEBUG | · | · | · | · | · | · | — | manual | Set to 1 or true to write the CLI's debug log to ~/.oxagen/logs (apps/cli/src/lib/debug-log.ts). Developer tooling, never set on a deployed service. |
OXAGEN_DEBUG | · | · | · | · | · | · | — | manual | When set, the CLI prints extra diagnostics (e.g. context-engine memory open failures) to stderr. |
OXAGEN_ORG_ID | · | · | · | · | · | · | — | manual | Default org slug for CLI commands; falls back to the value stored in ~/.oxagen/config.json. |
OXAGEN_TELEMETRY | · | · | · | · | · | · | — | manual | Set to '0' to disable CLI usage telemetry for this invocation (equivalent to `oxagen telemetry off`). DO_NOT_TRACK=1 also disables it and takes precedence. |
OXAGEN_WORKSPACE | · | · | · | · | · | · | — | manual | Workspace slug that `oxagen sandbox` and `oxagen credentials` address when --workspace-slug is absent. The CLI never infers it from a repository. |
OXAGEN_WORKSPACE_ID | · | · | · | · | · | · | — | manual | Default workspace slug for CLI commands; falls back to the value stored in ~/.oxagen/config.json. |
ClickHouse
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
CLICKHOUSE_DATABASE | ● | ● | ● | · | · | · | — | static | ClickHouse database name. |
CLICKHOUSE_PASSWORD secret | ● | ● | ● | · | · | · | — | manual | ClickHouse password (empty for local Docker). |
CLICKHOUSE_URL | ● | ● | ● | · | · | · | D P P | manual | ClickHouse HTTPS endpoint. |
CLICKHOUSE_USERNAME | ● | ● | ● | · | · | · | D P P | manual | ClickHouse user. |
ClickUp
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
CLICKUP_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | ClickUp OAuth client ID for connecting ClickUp as a work tracker. Connecting ClickUp answers not configured until this and CLICKUP_OAUTH_CLIENT_SECRET are set. |
CLICKUP_OAUTH_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | ClickUp OAuth client secret, sent to ClickUp's token address when a person connects ClickUp and when its tokens refresh. |
Code graph
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
CODEGRAPH_BLOB_PROVIDER | ● | · | · | · | · | · | — | manual | Code graph blob storage: s3 uses the existing AWS keys; gcs requires an active portable key and storage epoch. |
CODEGRAPH_BUCKET_REGION | ● | · | · | · | · | · | — | manual | The AWS region of the code graph's graph file bucket. The intake creates each organization's KMS key there, because a key encrypts objects in its own region only (ADR-306). Unset, the AWS SDK's own region chain decides. |
CODEGRAPH_QUERY_TOKEN secret | ● | ● | ● | · | · | · | — | manual | Bearer token the code graph query service was started with. Without it, the code graph capabilities report the service as unavailable. |
CODEGRAPH_QUERY_URL | ● | ● | ● | · | · | · | — | manual | Where the code graph query service (cg-query) listens on the private network. The code graph capabilities send their calls there (ADR-326). |
CODEGRAPH_WORKER_TOKEN secret | ● | · | · | · | · | · | — | manual | Bearer token the code graph worker presents to the API, one step at a time: for a GitLab project's access token (ADR-341), and for a GitHub repo's CI runs, which the API reads on the organization's own data plane. At least 32 characters. Unset, the API answers 503, GitLab projects do not build, and a GitHub repo's CI index has no run history. |
GOOGLE_CLOUD_PROJECT | ● | · | · | · | · | · | — | manual | The Google Cloud project allowed to hold portable code graph key versions. Required when code graph storage is gcs. |
GOOGLE_CLOUD_PROJECT_NUMBER | ● | · | · | · | · | · | — | manual | The explicit Google Cloud project number allowed in exact Secret Manager key references. Required for gcs code graph storage. |
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
SMTP_FROM_EMAIL | ● | ● | ● | · | · | · | — | static | Default sender address. Its domain must be verified at the provider. |
SMTP_FROM_NAME | ● | ● | ● | · | · | · | — | static | Default sender display name. |
SMTP_HOST | ● | ● | ● | · | · | · | — | static | SMTP server host (Resend: smtp.resend.com). |
SMTP_PASSWORD secret | ● | ● | ● | · | · | · | — | manual | SMTP password. For Resend this is an API key (re_…). |
SMTP_PORT | ● | ● | ● | · | · | · | — | static | SMTP port. 465 = implicit TLS; 587 = STARTTLS (TLS enforced). |
SMTP_USERNAME | ● | ● | ● | · | · | · | — | static | SMTP username (Resend: the literal "resend"). |
Error alerting
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
ALERT_WEBHOOK_URL secret | ● | ● | ● | · | · | · | — | manual | When set, high-severity/unhandled server errors are POSTed as a Slack-compatible `{ text, blocks }` JSON payload here (Slack/Mattermost/Discord incoming webhook, or any compatible endpoint). BYO webhook, with no vendor SDK. When unset, errors are still recorded to the ClickHouse error_events table; only the webhook alert is skipped. |
File storage
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
BLOB_READ_WRITE_TOKEN secret | ● | ● | · | · | · | · | — | manual | Vercel Blob read/write token. Authenticates the 'vercel-blob' storage driver, and lets a deployment on another driver delete files it wrote to Vercel Blob before it moved. |
PR_DIFF_BUCKET | ● | ● | ● | · | · | · | — | manual | The private bucket the pull request sync keeps each head commit's diff in (ADR-288). PR_DIFF_STORAGE_PROVIDER selects S3 or GCS. Unset, each revision keeps its file list and marks diff bytes unconfigured until a bucket is named. |
PR_DIFF_BUCKET_REGION | ● | ● | ● | · | · | · | — | manual | The AWS region of PR_DIFF_BUCKET when its provider is s3. Unset, the AWS SDK's region chain decides. GCS ignores this setting. |
PR_DIFF_STORAGE_PROVIDER | ● | ● | ● | · | · | · | — | manual | Private pull request diff provider: s3 or gcs. Defaults to s3. GCS uses STORAGE_GCS_SERVICE_ACCOUNT and the private PR_DIFF_BUCKET. |
SANDBOX_BUCKET | ● | · | ● | · | · | · | — | manual | The private S3 bucket of agent sandboxes (ADR-289): template root filesystems under templates/ and each run's launch prompt under sandboxes/. The control plane gives a sandbox host a download link for a template that expires soon, so a sandbox host never holds bucket credentials. Unset, launch_sandbox_run refuses every launch. |
SANDBOX_BUCKET_REGION | ● | · | ● | · | · | · | — | manual | The AWS region of SANDBOX_BUCKET. Unset, the AWS SDK's own region chain decides. |
SANDBOX_HOST_JOIN_TOKEN_PATH | ● | · | · | · | · | · | — | manual | The Parameter Store path that holds one join token per sandbox host (ADR-289). The control plane checks a joining host's token against the parameters under it and deletes the one that matched, so a token works once. Unset, it reads /oxagen/sandbox-hosts/join-tokens. |
SANDBOX_REQUIRED_HOSTS | ● | ● | ● | · | · | · | — | manual | The four host names every sandbox may reach whatever its sandbox runtime allows, comma separated: the cloud gateway, git custody, the terminal relay, and the Oxagen API (ADR-289). The control plane hashes them with the runtime's allowlist into the egress policy hash it sends a sandbox host, and the host's own settings name the same four. A sandbox on Modal may reach only the first, the cloud gateway, which relays its Git and tool calls, so its policy names the gateway alone as required (ADR-6116). Unset, no sandbox can start. |
STORAGE_DRIVER | ● | ● | ● | · | · | · | — | manual | Selects the @oxagen/storage backend: 'gcs' (Google Cloud Storage), 's3' (AWS buckets), 'vercel-blob' (the default when unset), or 'fs' (local files). |
STORAGE_FS_ROOT | ● | ● | · | · | · | · | — | manual | Root directory for the 'fs' storage driver. Only read when STORAGE_DRIVER=fs. Absolute path used as-is; a relative path is anchored at process.cwd(); unset falls back to an OS-tmp directory. |
STORAGE_GCS_BUCKET | ● | ● | ● | · | · | · | — | manual | Private Google Cloud Storage bucket. Required when STORAGE_DRIVER=gcs. |
STORAGE_GCS_PUBLIC_BUCKET | ● | ● | ● | · | · | · | — | manual | Private Google Cloud Storage bucket for public assets served through the application. Required when STORAGE_DRIVER=gcs. |
STORAGE_GCS_PUBLIC_URL | ● | ● | ● | · | · | · | — | manual | HTTPS origin that serves public assets. Required when STORAGE_DRIVER=gcs. Stored asset URLs retain this origin. |
STORAGE_GCS_SERVICE_ACCOUNT | ● | ● | ● | · | · | · | — | manual | Assigned Google Cloud service-account email used to request temporary metadata credentials. Required when STORAGE_DRIVER=gcs. |
STORAGE_S3_BUCKET | ● | ● | · | · | · | · | — | manual | The private S3 bucket the 's3' storage driver keeps every object in except avatars and pasted images. Read only when STORAGE_DRIVER=s3. |
STORAGE_S3_PUBLIC_BUCKET | ● | ● | · | · | · | · | — | manual | The S3 bucket the 's3' storage driver writes public objects to, avatars and pasted images, which CloudFront serves at STORAGE_S3_PUBLIC_URL. Read only when STORAGE_DRIVER=s3. |
STORAGE_S3_PUBLIC_URL | ● | ● | · | · | · | · | — | manual | The https origin CloudFront serves STORAGE_S3_PUBLIC_BUCKET from. A public object's URL is this origin and its key. Read only when STORAGE_DRIVER=s3. |
STORAGE_S3_REGION | ● | ● | · | · | · | · | — | manual | The AWS region of both storage buckets. Unset, the AWS SDK's own region chain decides. |
github
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
GITHUB_APP_CLIENT_ID | ● | ● | ● | · | · | · | — | manual | GitHub App OAuth client id, used for the data-connector OAuth flow. Also read in-process by apps/app's Workspace settings dialog and by apps/mcp's get_main_repository tool (envGithubUrls in packages/handlers/src/repository.main.get.ts, invoked through the kernel's invoke() rather than an HTTP call), so it must reach both of those services too, not only the callback route in api. |
GITHUB_APP_CLIENT_SECRET secret | ● | ● | ● | · | · | · | — | manual | GitHub App OAuth client secret: what the public callback in api exchanges the returned code with. envGithubUrls (see GITHUB_APP_CLIENT_ID) also checks this is set in app and mcp, before publishing a Connect URL that api's callback could not finish without it. |
GITHUB_APP_ID | ● | ● | ● | · | · | · | — | manual | GitHub App numeric ID. Required (with GITHUB_APP_PRIVATE_KEY) for the installation-token path in resolveGitHubToken(). Find it on the GitHub App settings page. Also required in-process by app: repository.binding-write.ts (behind link_repository) and repository.installation.list.ts mint installation tokens directly when the app invokes them, not only from api/mcp. Steering repos run on the same App (ADR-228): the steering repo provision job, repair, and health read mint their installation tokens with it. |
GITHUB_APP_INSTALL_STATE_SECRET secret | ● | ● | ● | · | · | · | — | manual | HMAC secret that locks the OAuth state parameter for GitHub App installs. api's callback locks and checks it, and envGithubUrls (see GITHUB_APP_CLIENT_ID) also locks it when app and mcp mint the same URLs in-process. |
GITHUB_APP_PRIVATE_KEY secret | ● | ● | ● | · | · | · | — | manual | PEM-encoded RSA private key for the GitHub App. Required (with GITHUB_APP_ID) for the installation-token path in resolveGitHubToken(). Generate in the GitHub App settings → Private keys. Also required in-process by app (see GITHUB_APP_ID). |
GITHUB_APP_SLUG | ● | ● | ● | · | · | · | — | manual | GitHub App public slug (the path segment in https://github.com/apps/<slug>). Used to deep-link users to GitHub's install/configure page so they can add or remove orgs and repos. Optional. When unset the connection dialog derives the slug from an existing installation. Also minted by envGithubUrls (see GITHUB_APP_CLIENT_ID) in-process from app and mcp. The steering connect in api sends an install to this slug, and the steering repo health read compares a check's app against it (ADR-228). Work orders treat a pull request merged by <slug>[bot] as the Oxagen GitHub App's own merge, so that send stays in review (merged_by_app). |
GITHUB_APP_WEBHOOK_SECRET secret | ● | · | · | · | · | · | — | manual | GitHub App webhook secret. It validates inbound webhook payloads. A verified delivery that can change a steering repo's health also asks for a health read (S2, ADR-228). |
GITHUB_PERSONAL_ACCESS_TOKEN secret | ● | · | · | · | · | · | — | manual | Personal access token (PAT) that resolveGitHubToken (packages/github/src/workspace-token.ts) falls back to, LOCAL/DEMO-ONLY, when a workspace has neither a GitHub App installation token nor its own KMS-encrypted OAuth token. It MUST NOT be set in production: a shared PAT bypasses per-workspace scoping. resolveGitHubToken refuses it and throws while NODE_ENV=production. |
OXAGEN_TACHO_GITHUB_BROKER | ● | ● | ● | · | · | · | — | manual | Set to 1 to let hosts and sandboxes request repository-scoped GitHub credentials for their Git proxies. Any other value refuses each request (github_broker_disabled). |
Infrastructure
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
AURORA_ENDPOINT | · | · | · | · | · | · | — | manual | Aurora writer endpoint for run-db-migrations.sh. Set it to skip the AWS lookup the script otherwise does. |
AURORA_PORT | · | · | · | · | · | · | — | manual | Port for AURORA_ENDPOINT. Defaults to 5432. |
DATA_NODE_NAME | · | · | · | · | · | · | — | manual | Name tag of the data-plane EC2 instance the DB-client tunnel scripts target. Defaults to oxagen-data. |
EVENT_BUS_NAME | · | · | · | · | · | · | — | manual | EventBridge bus the log-event-publisher Lambda puts events on. The stack sets it on the function; the handler refuses to import without it. |
NODE_NAME | · | · | · | · | · | · | — | manual | Name tag of the EC2 instance the infra/tools scripts target. Defaults to oxagen-app. |
Ingestion
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
AWS_KMS_INGESTION_KEY_ARN | ● | ● | ● | · | · | · | — | manual | AWS KMS key ARN for credential and private file encryption (INGESTION_CRYPTO_PROVIDER=kms). Also required in-process by app and mcp (see INGESTION_CRYPTO_PROVIDER). |
EVIDENCE_RECOVERY_ENCRYPTION_KEY secret | ● | ● | ● | · | · | · | — | manual | Pinned base64 32-byte key for explicit historical evidence recovery wrappers. Keep this key for every recovered body that names evidence:recovery:v1. |
INGESTION_CRYPTO_PROVIDER | ● | ● | ● | · | · | · | — | static | Encryption backend for ingestion credentials and private Vercel Blob files: 'env' (AES-256-GCM via INGESTION_ENCRYPTION_KEY) or 'kms' (AWS KMS). Also read in-process by app and mcp: resolveGitHubToken's stored-OAuth-token path (packages/github/src/workspace-token.ts) decrypts through resolveIngestionCryptoAdapterForKeyId whenever it falls back off the installation-token path, and resolveWorkspaceGithubUserToken opens the stored token that backs the list_github_installations tool. |
INGESTION_ENCRYPTION_KEY secret | ● | ● | ● | · | · | · | P P | manual | Base64-encoded 32-byte master key for AES-256-GCM credential and private file encryption (INGESTION_CRYPTO_PROVIDER=env). Also required in-process by app and mcp (see INGESTION_CRYPTO_PROVIDER). |
MICROSOFT_DATA_CLIENT_ID | ● | · | · | · | · | · | — | manual | Microsoft DATA OAuth client id for token refresh (ingestion cron; MS Graph offline_access). |
MICROSOFT_DATA_CLIENT_SECRET secret | ● | · | · | · | · | · | — | manual | Microsoft DATA OAuth client secret for token refresh (ingestion cron). |
SALESFORCE_DATA_CLIENT_ID | ● | · | · | · | · | · | — | manual | Salesforce DATA OAuth client id for token refresh (ingestion cron). |
SALESFORCE_DATA_CLIENT_SECRET secret | ● | · | · | · | · | · | — | manual | Salesforce DATA OAuth client secret for token refresh (ingestion cron). |
SLACK_DATA_CLIENT_ID | ● | · | · | · | · | · | — | manual | Slack DATA OAuth client id for token refresh (ingestion cron). Token rotation must be enabled in the Slack app. |
SLACK_DATA_CLIENT_SECRET secret | ● | · | · | · | · | · | — | manual | Slack DATA OAuth client secret for token refresh (ingestion cron). |
ZOOM_DATA_CLIENT_ID | ● | · | · | · | · | · | — | manual | Zoom DATA OAuth client id for token refresh (ingestion cron). Zoom rotates the refresh token on each use. |
ZOOM_DATA_CLIENT_SECRET secret | ● | · | · | · | · | · | — | manual | Zoom DATA OAuth client secret for token refresh (ingestion cron). |
Inngest
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
CURSOR_CONFIG_DIR | · | · | · | · | · | · | — | manual | Overrides where the recorder host writes Cursor's `hooks.json` and `mcp.json`. Read on the operator's machine, not the server, and never a deployment value: it exists because Cursor can be installed against a non-default config directory, and enrolling the wrong one leaves the session unwrapped and silently unrecorded. |
ENROLLMENT_SIGNING_PREVIOUS_PRIVATE_KEY secret | ● | · | · | · | · | · | — | manual | The Ed25519 key that locked enrollments before the current one (ADR-6604), set only while a rotation is in progress. The key set is locked with it as well, so a host that still pins it takes the set that carries the new key. Unset outside a rotation. |
ENROLLMENT_SIGNING_PRIVATE_KEY secret | ● | · | · | · | · | · | — | manual | Ed25519 private key (PKCS#8 PEM, newlines as \n) this deployment locks enrollment certificates with (create_tacho_enrollment, enroll_host, create_stella_enrollment, renew_enrollment_certificate; ADR-6604). Separate from the bundle key. Each recorder host and Stella install pins the public half, by key id, from the locked key set get_enrollment_keys serves, and checks its certificate offline at every start. Unset means every enrollment and renewal refuses. |
INNGEST_EVENT_KEY secret | ● | ● | · | · | · | · | P P | manual | Inngest event key. Required in preview+production. |
INNGEST_SIGNING_KEY secret | ● | ● | · | · | · | · | P P | manual | The key that locks the calls between Inngest and this deployment (Inngest names it the signing key). Required in preview+production. |
STELLA_TELEMETRY_INGEST_ENDPOINTS | ● | · | · | · | · | · | — | manual | Comma-separated HTTPS ingest endpoints this deployment serves for Stella operational telemetry. create_stella_enrollment refuses to lock an enrollment pointing anywhere else, so an operator cannot mint a valid document aiming a fleet of installs at a third party. Defaults to the public endpoint; plaintext entries are dropped. |
TACHO_BUNDLE_SIGNING_PRIVATE_KEY secret | ● | · | ● | · | · | · | — | manual | Ed25519 private key (PKCS#8 PEM, newlines as \n) this deployment locks recorder policy bundles with (get_tacho_bundle) and locks run exports with (export_run, ADR-058). The matching public key travels to each host at enrollment so the recorder's hook verifies a cached bundle offline and fails closed on one it cannot verify, and into every export bundle so its verifier runs offline. The MCP service locks relay envelopes and local server calls with it. Unset means enrollment, bundle, export, relay calls, and local calls refuse. A run's record still closes when the run ends, without Oxagen's lock (ADR-195). |
TACHO_INGEST_ENDPOINTS | ● | · | · | · | · | · | — | manual | Comma-separated HTTPS base URLs of this deployment's recorder machine endpoints (the /v1/tacho prefix). create_tacho_enrollment refuses to lock an enrollment pointing anywhere else, so an operator cannot aim a fleet of hosts at a third party. Defaults to the public endpoint; plaintext entries are dropped. |
TACHO_LOCAL_TOKEN secret | · | · | · | · | · | · | — | manual | The per-install bearer the recorder collector's loopback listener requires. Written into each wrapped harness's settings and into a connected app's MCP config by `oxagen agent enroll`, and read back by the hook and the `oxagen mcp-stdio` shim. Never set by hand and never a deployment value: it is minted per machine at enrollment and lives in host.json. |
TACHO_MCP_ENDPOINT | ● | · | · | · | · | · | — | manual | Overrides the workspace MCP endpoint the recorder collector's local gateway proxies to (ADR-078). Read on the host: it is how a local stack points the gateway at 127.0.0.1:4100 instead of the deployment's MCP host. Unset, the gateway uses the endpoints.mcp claim from the enrollment, then derives one from api_url. The API reads it too, for the claim it locks and as the upstream of the gateway's MCP relay for a sandbox daemon (ADR-6807); unset there, the relay forwards to /mcp on MCP_URL. |
XDG_CONFIG_HOME | · | · | · | · | · | · | — | manual | The XDG base directory the recorder host falls back to when locating Cursor's config on Linux, after CURSOR_CONFIG_DIR and before ~/.cursor. Set by the operator's own environment rather than by Oxagen, and ignored on macOS and Windows, which do not follow the XDG layout. |
Jira
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
JIRA_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Jira OAuth client ID for connecting Jira as a work tracker. Connecting Jira answers not configured until this and JIRA_OAUTH_CLIENT_SECRET are set. |
JIRA_OAUTH_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | Jira OAuth client secret, sent to Jira's token address when a person connects Jira and when its tokens refresh. The collector webhook route checks the lock on each Jira delivery with it, so a delivery is refused while it is unset. |
Lead alerts
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
LEAD_ALERT_EMAILS | ● | · | · | · | · | · | — | manual | Comma-separated addresses that receive each website lead submission. Delivery receipts and failures live on crm.lead_submissions. The API retries missing deliveries automatically. Production submissions remain pending when email delivery is unset. |
LEAD_ALERT_SLACK_BOT_TOKEN secret | ● | · | · | · | · | · | — | manual | Slack bot token (xoxb-) with channels:manage, channels:read, channels:join and chat:write scopes. The API posts each website submission to LEAD_ALERT_SLACK_CHANNEL and creates the channel if needed. Failed posts retry automatically. Production submissions remain pending when Slack is unset. |
LEAD_ALERT_SLACK_CHANNEL | ● | · | · | · | · | · | — | manual | The Slack channel that gets each website lead, by name, with or without the #. Unset means web-leads. The API creates the channel on the first lead when no channel has the name. Read only when LEAD_ALERT_SLACK_BOT_TOKEN is set. |
LEAD_SHEETS_SERVICE_ACCOUNT_EMAIL | ● | · | · | · | · | · | — | manual | Dedicated Google service account shared as a writer on the lead spreadsheet. The API runtime identity needs roles/iam.serviceAccountTokenCreator on this account. Delivery uses short-lived Sheets tokens through IAM impersonation. |
LEAD_SHEETS_SPREADSHEET_ID | ● | · | · | · | · | · | — | manual | Google spreadsheet ID for website submissions. The Leads tab uses columns A through P. Each submission writes to its database-assigned row with literal values. Keep physical rows in place so retries update the same submission. |
Linear
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
LINEAR_API_KEY secret | · | · | · | · | · | · | — | manual | Linear API key (tooling/provenance; not read by deployed apps). |
LINEAR_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Linear OAuth application client ID. Connecting Linear uses PKCE with the app callback URL, so no client secret is needed. |
LINEAR_PROJECT_ID | · | · | · | · | · | · | — | static | Linear project id for the oxagen-v2 project (tooling-only). |
LINEAR_WEBHOOK_SECRET secret | ● | · | · | · | · | · | — | manual | Shared secret of the Linear OAuth app's webhook (Linear names it the signing secret). POST /webhooks/linear checks the Linear-Signature header with it. |
MCP
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
OPENAI_APPS_VERIFICATION_TOKEN | · | · | ● | · | · | · | — | manual | Optional OpenAI Apps domain verification challenge. MCP serves this value publicly at /.well-known/openai-apps-challenge when set. |
Neo4j
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
NEO4J_DATABASE | ● | ● | ● | · | · | · | — | static | Neo4j database. |
NEO4J_ORG_PROVISIONER | ● | ● | ● | · | · | · | — | static | Graph provisioner for paid organisations (ADR-098): pooled (Community, dev, CI), cypher (self-managed Enterprise: CREATE DATABASE org-<namespace>), aura (not implemented; refused). |
NEO4J_PASSWORD secret | ● | ● | ● | · | · | · | — | manual | Neo4j password. Required when a Neo4j URI or username is set. |
NEO4J_URI | ● | ● | ● | · | · | · | — | manual | Optional Neo4j bolt(+s) URI. Set URI, username, and password together to enable the graph. |
NEO4J_USERNAME | ● | ● | ● | · | · | · | — | manual | Neo4j user. Required when a Neo4j URI or password is set. |
Next.js
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY secret | · | ● | · | · | · | · | P | generate | The key Next salts every server action id with and encrypts bound action arguments under. Without it each build makes a random key, every action id changes at a deploy, and every page left open breaks until it is reloaded (#5318). Next itself reads it at build and at run time, and writes it into the build's server manifest, as it did the random key. package-for-node.sh refuses to package the app without it. |
Node
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
NODE_ENV | · | · | · | · | · | · | — | static | Runtime mode. Next.js sets it itself at build and start. The Inngest verifier rejects test signing keys when this is production. |
OAuth providers
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
GITHUB_LOGIN_CLIENT_ID | ● | ● | · | · | · | · | P P | manual | GitHub LOGIN OAuth App client id (social sign-in; minimal scopes). Not the GitHub App. Checklist: docs/runbooks/social-login-oauth-apps.md. |
GITHUB_LOGIN_CLIENT_SECRET secret | ● | ● | · | · | · | · | P P | manual | GitHub LOGIN OAuth App client secret. Checklist: docs/runbooks/social-login-oauth-apps.md. |
GOOGLE_DATA_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Google DATA OAuth client id (Workspace data scopes; future connection). |
GOOGLE_DATA_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | Google DATA OAuth client secret. |
GOOGLE_LOGIN_CLIENT_ID | ● | ● | · | · | · | · | P P | manual | Google LOGIN OAuth client id (social sign-in; minimal scopes). Checklist: docs/runbooks/social-login-oauth-apps.md. |
GOOGLE_LOGIN_CLIENT_SECRET secret | ● | ● | · | · | · | · | P P | manual | Google LOGIN OAuth client secret. Checklist: docs/runbooks/social-login-oauth-apps.md. |
MCP_OAUTH_PREREGISTERED_CLIENTS secret | ● | ● | · | · | · | · | — | manual | Pre-registered OAuth clients for MCP authorization servers that do NOT support RFC 7591 dynamic client registration (GitHub MCP, notably). JSON object mapping the MCP server's endpoint HOST to the client registered with that provider, e.g. {"api.githubcopilot.com":{"client_id":"…","client_secret":"…","issuer":"https://github.com"}}. Each provider app must list <app-origin>/api/v1/mcp/oauth/callback as its callback URL. When a host is absent the flow falls back to dynamic client registration. Entries without a trusted authorization server issuer are ignored so discovery cannot redirect their secrets. |
Observability
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
KNOWLEDGE_GRAPH_ENABLED | ● | ● | ● | · | · | · | — | static | Feature flag. Set "false" to disable the Neo4j knowledge-graph writes. |
LOG_LEVEL | ● | ● | ● | · | · | · | — | static | Pino log level for service loggers. |
MCP_PORT | · | · | ● | · | · | · | — | manual | HTTP port for the xmcp server. |
OpenTelemetry
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | ● | ● | ● | · | · | · | — | manual | OTLP HTTP collector URL (e.g. https://otel.example.com/v1/traces). When unset the SDK does not start and all spans are no-ops, which is safe for all envs. Rollback = leave unset. |
OTEL_EXPORTER_OTLP_HEADERS secret | ● | ● | ● | · | · | · | — | manual | Standard OTEL comma-separated `key=value` header list sent to the collector (e.g. "authorization=Bearer xxx,x-tenant=oxagen"). Optional, for collectors that require auth headers. Parsed by packages/telemetry/src/tracer.ts. |
OTEL_SERVICE_NAME | ● | ● | ● | · | · | · | — | manual | Service name tag on OTEL span resources (default: oxagen). Optional. Leave unset to use the default. |
OXAGEN_REGION | · | ● | · | · | · | · | — | static | The region this process answers from, printed beside the trace id on a page's error line (#3841). Every deployed node runs in us-east-1, and the node manifest (tools/scripts/package-for-node.sh) sets it too. Unset locally, where the page says the region was not recorded. |
Operator scripts
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
ADMIN_DATABASE_URL secret | · | · | · | · | · | · | — | manual | Superuser Postgres connection used by provision-rls-role.ts to create the least-privilege app role. Kept separate from DATABASE_URL so the provisioning step cannot silently run through the restricted connection it is about to create. |
APPLE_SIGNING_IDENTITY | · | · | · | · | · | · | — | manual | The Developer ID tauri locks the macOS bundle with, so macOS can check it came from Oxagen unchanged. `-` locks it without a Developer ID, so macOS cannot tell who made it, which `pnpm dist:local` and desktop.yml use when no Developer ID is configured. |
BLOG_DRAFTS | · | · | · | · | · | · | — | manual | Set to 1 to include draft posts when building the static research blog (apps/web/scripts/build.mjs). Unset in every deploy, so drafts never ship. |
CI_SUPERSEDED_THRESHOLD | · | · | · | · | · | · | — | manual | How many superseded CI runs in a row make check-superseded-runs.mjs report a pull request, when the script is run by hand. Unset or below 2 reads as 3. |
CONTEXT_GRAPH_PROTOCOL_DIR | · | · | · | · | · | · | — | manual | Path to a local context-graph-protocol checkout. check-contextgraph-fixtures.ts verifies the vendored profile against it when set. |
DB_LINT_BASE_REF | · | · | · | · | · | · | — | manual | The ref `pnpm db:lint-migrations` compares new Atlas migrations against for its git-aware ordering check (#3387): a migration added since the merge base with this ref must sort after every migration already there. Defaults to origin/main. |
DB_LINT_HEAD_REF | · | · | · | · | · | · | — | manual | The ref `pnpm db:lint-migrations` treats as the branch's own tip for its git-aware ordering check (#3387). CI's pull_request checkout puts HEAD on GitHub's synthetic merge commit, not the PR branch itself, which collapses the merge-base fail/warn distinction into one tier. No workflow sets it today. Set it to the pull request's head commit to compare against the real PR head on such a checkout. Defaults to HEAD, which is correct everywhere else (a push checkout, a local branch). |
DB_MIGRATE_STORES | · | · | · | · | · | · | — | manual | Comma-separated stores `pnpm db:migrate` should migrate. Defaults to clickhouse,neo4j. Postgres is Atlas's job and is deliberately not in the list. |
DEFAULT_BRANCH | · | · | · | · | · | · | — | manual | The repository's default branch. rerun-lost-runner.mjs reruns a lost job on this branch even after newer commits land. rerun-lost-runner.yml sets it from the event's repository. Defaults to main. |
DEPLOY_SERVICE | · | · | · | · | · | · | — | manual | The service a deploy record names. check-deploy-tip.mjs reads it to find what is live for that service and to record what shipped (ADR-164). desktop.yml sets it to desktop on the step that records the installers' commit. |
DRY_RUN | · | · | · | · | · | · | — | manual | Set to 1 to make check-superseded-runs.mjs print what it would post instead of posting it, when the script is run by hand. |
FLEET_BUNDLE_PUBLIC_KEY_PEM | · | · | · | · | · | · | — | manual | Pinned staging policy-bundle public key for the fleet load rig. |
FLEET_CLICKHOUSE_HOST | · | · | · | · | · | · | — | manual | Independently pinned staging ClickHouse hostname for fleet reconciliation. |
FLEET_CLICKHOUSE_PASSWORD secret | · | · | · | · | · | · | — | manual | Read-only staging ClickHouse credential for fleet reconciliation. |
FLEET_CLICKHOUSE_URL | · | · | · | · | · | · | — | manual | Staging ClickHouse HTTPS endpoint for fleet reconciliation, without credentials. |
FLEET_CLICKHOUSE_USER | · | · | · | · | · | · | — | manual | Read-only staging ClickHouse user for fleet reconciliation. |
FLEET_DATABASE_HOST | · | · | · | · | · | · | — | manual | Independently pinned staging Postgres hostname for fleet reconciliation. |
FLEET_DATABASE_URL secret | · | · | · | · | · | · | — | manual | Read-only staging Postgres connection string for fleet reconciliation. |
FLEET_OPERATOR_TOKEN secret | · | · | · | · | · | · | — | manual | Staging operator credential used to enroll synthetic fleet hosts. |
FLEET_OUTPUT_ROOT | · | · | · | · | · | · | — | manual | Existing private persistent runner directory for fleet reports and credentials. |
FLEET_STAGING_ORIGIN | · | · | · | · | · | · | — | manual | Exact trusted HTTPS staging origin for the fleet load rig. |
GITLAB_PROJECT | · | · | · | · | · | · | — | manual | The gitlab.com project, `group/project`, that `tools/scripts/gitlab-steering-exercise.ts` publishes its exercise record to. Use a scratch project: a run with --merge adds a file to its default branch. |
GITLAB_TOKEN secret | · | · | · | · | · | · | — | manual | A gitlab.com project access token that `tools/scripts/gitlab-steering-exercise.ts` publishes one steering record with, as recorded evidence for #3762. Set it in the shell for one run only; the platform never reads it, and workspaces store their own tokens through attach_gitlab_project. |
HEAD_BRANCH | · | · | · | · | · | · | — | manual | The head branch of the CI run check-superseded-runs.mjs reports on, when the script is run by hand. It finds the pull request from this and HEAD_REPO when PR_NUMBER is unset. |
HEAD_REPO | · | · | · | · | · | · | — | manual | The head repository (owner/name) of the CI run check-superseded-runs.mjs reports on, when the script is run by hand. It finds the pull request from this and HEAD_BRANCH when PR_NUMBER is unset. |
INNGEST_DEV | · | · | · | · | · | · | — | manual | Set to 1 to point the Inngest SDK at a local dev server instead of Inngest Cloud. tools/scripts/inngest-dev.ts sets it for every child turbo spawns. |
MAIN_VERIFIED_COVER_MINUTES | · | · | · | · | · | · | — | manual | How long check-main-verified.mjs treats a commit whose run a newer push replaced as pending while a later run is still going. Pushes to main share one concurrency group, so a commit can wait about two run lengths. Defaults to 180. |
MAIN_VERIFIED_GRACE_MINUTES | · | · | · | · | · | · | — | manual | How long after a commit lands check-main-verified.mjs refuses to conclude it has no run. The workflow races the registration of the run it looks for. Defaults to 10. |
MAIN_VERIFIED_MAX_WAIT_MINUTES | · | · | · | · | · | · | — | manual | Upper bound on how long check-main-verified.mjs sleeps waiting the grace out before re-reading. Must stay below the workflow job's timeout-minutes. Defaults to 12. |
MAIN_VERIFIED_WINDOW | · | · | · | · | · | · | — | manual | How many recent commits on main check-main-verified.mjs asks about. Defaults to 10. |
NPM_TOKEN secret | · | · | · | · | · | · | — | manual | npm token used to publish the CLI package from a laptop. Unset skips the npm publish step of `pnpm release` rather than failing it. CI publishes with its own copy, the NPM_TOKEN repository secret (ADR-253). |
OXAGEN_INSTALL_BASE | · | · | · | · | · | · | — | manual | Base URL the published install.sh downloads the oxagen-<rust triple> executable and its .sha256 from. Set it to install a pinned version, such as https://downloads.oxagen.sh/desktop/<version>. |
OXAGEN_INSTALL_DIR | · | · | · | · | · | · | — | manual | Directory install.sh puts the oxagen binary in. Defaults to ~/.local/bin. |
PGSUPERPASS secret | · | · | · | · | · | · | — | manual | Password for PGSUPERUSER. |
PGSUPERUSER | · | · | · | · | · | · | — | manual | Superuser on the cluster tools/scripts/rds-sim-check.sh simulates RDS against. The script refuses to run without it. |
POLLS | · | · | · | · | · | · | — | manual | Number of five-second polls install-node-scripts.sh waits for its remote command. Defaults to 150. |
PR_CHANGED_FILES | · | · | · | · | · | · | — | manual | How many files the pull request a CI run tests changes, from the pull_request event. ci-pr-scope.mjs checks that it read every file before it calls a pull request docs-only (#4918). |
PR_DRAFT | · | · | · | · | · | · | — | manual | Whether the pull request a CI run tests is a draft (true or false). pipeline.yml sets it on the preflight job, and ci-pr-scope.mjs runs only the light lanes for a draft (#4918). |
PR_NUMBER | · | · | · | · | · | · | — | manual | The pull request number. pr.yml's records-lint job sets it, and check-adr-index.mjs reads it there. new-adr.mjs reads it to number a new ADR, and check-superseded-runs.mjs reads it as the pull request to report on when the script is run by hand. |
PRODUCTION_DATABASE_URL secret | · | · | · | · | · | · | — | manual | Migration connection for Atlas's `prod` env (packages/database/atlas.hcl), read by db-migrate.yml and no other workflow. Holds a role that may run DDL against pre-existing schemas: the app role may only CREATE in schemas it owns, so migrating through DATABASE_URL fails 42501 on billing and friends. |
RERUN_RUN_ID | · | · | · | · | · | · | — | manual | The failed CI run that rerun-lost-runner.mjs checks for jobs whose runner was lost. rerun-lost-runner.yml sets it from the workflow_run event, or from the run_id input on a manual dispatch. |
SCR_OWNER | · | · | · | · | · | · | — | manual | GitHub owner to read all five SCR corpus repos under, for a fork or a test organization. Unset, the check reads each repo where it lives. |
SOURCE_COMMIT | · | · | · | · | · | · | — | manual | The commit a manual app deploy ships, from the dispatch's source_commit input. check-deploy-tip.mjs --schema reads it in place of GITHUB_SHA, which is main's head on a dispatch, to refuse code older than production's schema (#5247). |
STALE_MERGE_BASE_REF | · | · | · | · | · | · | — | manual | Ref the stale-merge-base check (#3237) treats as main's current tip. Defaults to origin/main. |
STALE_MERGE_BRANCH_REF | · | · | · | · | · | · | — | manual | Ref the stale-merge-base check (#3237) treats as the branch under review. Defaults to HEAD. |
STANDALONE | · | · | · | · | · | · | — | manual | Set to 1 to build apps/app or apps/docs with Next's standalone output. tools/scripts/package-for-node.sh sets it for the self-hosted node bundle. Unset, Next.js writes its default output. |
TAURI_SIGNING_PRIVATE_KEY secret | · | · | · | · | · | · | — | manual | The key that locks the desktop app's updates (minisign; contents or a path). `pnpm dist:local` reads ~/.tauri/oxagen-desktop.key when this is unset; desktop.yml holds it as a secret. Unset builds carry no updater artifacts. |
TAURI_SIGNING_PRIVATE_KEY_PASSWORD secret | · | · | · | · | · | · | — | manual | Password of TAURI_SIGNING_PRIVATE_KEY. The key has none, so this is set to the empty string: an absent variable makes tauri prompt for one. |
VISION_GATE_BASE | · | · | · | · | · | · | — | manual | Ref the vision gate diffs against. Defaults to origin/main. |
VISION_GATE_MODEL | · | · | · | · | · | · | — | manual | Model the vision gate judges a diff with. |
VISION_GATE_STRICT | · | · | · | · | · | · | — | manual | Set to 1 to make a drifts verdict fail the vision gate instead of only printing it. |
WEB_PORT | · | · | · | · | · | · | — | manual | Port for the apps/web static dev server (apps/web/scripts/dev.mjs). Defaults to 5500; local convenience only, never read by a deploy. |
WRITE_MANIFEST_IMAGE | · | · | · | · | · | · | — | manual | Container image the packaged node bundle's run manifest names. Defaults to node:24.21.0-alpine. |
Postgres
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
DATABASE_URL secret | ● | ● | ● | · | · | · | D P P | manual | Postgres connection string. Deployed environments read it from Parameter Store (ADR-240); local dev points at the Docker container. |
Privacy
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
PRIVACY_ERASURE_GRACE_DAYS | ● | · | · | · | · | · | — | static | Grace period in days before a hard-delete erasure job runs (GDPR Art.17). Defaults to 30 when unset. Set to 0 for immediate erasure in test envs. |
Public URLs
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
APP_URL | ● | ● | ● | · | · | · | — | static | Server-side app origin used to build plugin OAuth authorize/callback URLs (falls back to NEXT_PUBLIC_APP_URL). Not browser-exposed. |
MARKETING_URL | ● | · | · | · | · | · | — | static | Public marketing website origin (oxagen.sh). The /v1/cms/* lead routes use it to build the emailed reader link and CORS allows it as a cross-origin caller. Not browser-exposed. |
MCP_URL | ● | ● | ● | · | · | · | — | static | MCP server origin used to build install instructions and client connections. |
NEXT_PUBLIC_API_URL client | ● | ● | ● | · | · | · | D P P | static | Public api origin (browser-exposed). The api and mcp read it too: the Inngest serve host, and the absolute download URL get_run_export mints. |
NEXT_PUBLIC_APP_URL client | · | ● | · | · | · | · | D P P | static | Public app origin (browser-exposed). |
WORK_ATTACHMENT_URL | ● | ● | · | · | · | · | — | manual | Origin that serves a work item attachment's public link (/work-attachments/<token>). It must be a cookieless origin that is not the app's. Tracker create writes a link into an issue only when this is set, and names each file without a link otherwise. Not browser-exposed. |
Rate limiting
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
RATE_LIMIT_CHAT_PER_MIN | ● | · | · | · | · | · | — | manual | Max chat send/stream requests per minute per workspace (fallback: per org, then per IP) on /v1/**/chat/*. Optional. Defaults to 60 in packages/config/src/env.ts. |
TRUST_EDGE_CLIENT_IP_HEADER | ● | ● | ● | · | · | · | — | manual | Whether the x-oxagen-client-ip header written by the edge is believed. Optional. Defaults to false. Set to "true" only AFTER the Caddy config that SETS that header (infra/tools/caddy/Caddyfile.alb) is uploaded and reloaded; until then the old config forwards a caller-supplied copy of it unchanged and the value would be attacker-controlled (ADR-083). Once that config is live it is what attributes the caller, because the same config rewrites x-forwarded-for to a single client address and leaves no proxy entry for TRUSTED_PROXY_CIDRS to vouch with. |
TRUSTED_PROXY_CIDRS | ● | ● | ● | · | · | · | — | manual | Comma-separated CIDRs or addresses of the proxies in front of apps/api. With the edge header (TRUST_EDGE_CLIENT_IP_HEADER) this is how a client address is attributed: the walk goes right through x-forwarded-for while each entry is a named proxy and stops at the first that is not, so a caller padding the header cannot move the result. NAME THE PROXIES' OWN SUBNETS, never an RFC1918 supernet like 10.0.0.0/8: a list wide enough to contain a caller makes the walk skip that caller as though it were a proxy and return an entry further left, which is one the caller wrote: the exact bypass this form exists to close. Once set it decides alone, and it returns nothing when no named proxy vouched for an entry, so it does not belong in a deployment whose edge rewrites x-forwarded-for to a single client address (ADR-083). Unset, no client address is derived at all, and the two things that read one both fail safe: the IAM ip_ranges / ip_allow conditions deny, and the pre-authentication IP ceilings on the recorder and Stella machine routes skip rather than pooling every caller into one bucket. Empty by default, which means those IP controls are OFF and say so in the log. |
Release / build metadata
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
PLATFORM_VERSION | ● | ● | ● | · | · | · | — | manual | Platform version string surfaced by @oxagen/config platformVersion(). Nothing sets it in production today: the release script's sync went with the Vercel deploy, and Parameter Store does not hold it, so platformVersion() falls back to "0.0.0". Declared in turbo.json globalEnv so a version change busts the build cache. Read via raw process.env and absent from baseEnvSchema on purpose: it is a release tag, not a service setting. |
Security
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
AUDIT_EXPORT_SIGNING_SECRET secret | ● | ● | ● | · | · | · | — | generate | HMAC-SHA256 secret that locks audit-log export tokens, so exported files can be verified as untampered. OPTIONAL: baseEnvSchema declares it `.optional()` and the audit export route falls back to BETTER_AUTH_SECRET when it is unset. A value shorter than 16 characters counts as unset. Setting a dedicated value changes the key that locks export tokens and invalidates outstanding export download URLs. Generate with `openssl rand -base64 32`. |
SERVER_ACTIONS_ALLOWED_ORIGINS | · | ● | · | · | · | · | — | manual | Extra hosts allowed to POST a Next server action to apps/app, comma-separated. Next rejects a server action whose Origin is not the deployment's own host, so a custom domain in front of the app has to be named here or every mutation 403s. |
TENANT_RLS_ENFORCEMENT_ENABLED | ● | ● | ● | · | · | · | — | manual | Gates the RLS startup checks only. Postgres RLS policies filter every tenant query whatever this says: no policy reads app.rls_bypass, and system paths assume the oxagen_system role (ADR-5879). When true, a service refuses to start if its database role is a superuser, has BYPASSRLS, or inherits oxagen_system (assertRlsConnectionSafe). When UNSET it defaults to true wherever NODE_ENV=production, staging included, unless VERCEL_ENV says otherwise, and to false in dev and test. A production process refuses to boot if this is forced to false (assertRlsEnforcedInProduction). Locally, false lets a service start on a superuser connection, which skips RLS. |
Slack app
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
SLACK_APP_CLIENT_ID | · | ● | · | · | · | · | — | manual | Oxagen Slack app OAuth client id. Organization settings uses it to start the Connect Slack flow. |
SLACK_APP_CLIENT_SECRET secret | · | ● | · | · | · | · | — | manual | Oxagen Slack app OAuth client secret. The callback sends it to oauth.v2.access to exchange the code. |
SLACK_APP_ID | · | ● | · | · | · | · | — | manual | Oxagen Slack app id. The callback rejects an oauth.v2.access answer for another app. Unset, the callback checks no app id. |
SLACK_APP_SIGNING_SECRET secret | · | · | · | · | · | · | — | manual | Shared secret of the Oxagen Slack app (Slack names it the signing secret), for checking Slack requests. Nothing reads it yet. The C8 collector will. |
Stripe
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
STRIPE_PUBLISHABLE_KEY | · | · | · | · | · | · | — | manual | Stripe publishable key. Every environment, production included, is the sandbox's pk_test_ key until the production cutover. Provisioning-only: no service reads it. The browser reads the NEXT_PUBLIC_ prefixed name. Keep the two equal. |
STRIPE_SECRET_KEY secret | ● | ● | · | · | · | · | D P P | manual | Stripe secret key. Every environment, production included, binds to the shared Stripe sandbox (sk_test_) until the maintainer cuts production over to live keys; see docs/ops/stripe-sandbox-mode.md. |
STRIPE_TAX_ENABLED | ● | ● | · | · | · | · | — | manual | When 'true', enables Stripe Tax automatic_tax on all checkout sessions. Ships dark; flip on only after Stripe Tax is registered/active in the dashboard. |
STRIPE_WEBHOOK_SECRET secret | ● | ● | · | · | · | · | D P P | manual | Stripe webhook secret (whsec_; Stripe names it the signing secret) of the endpoint registered on the shared sandbox for this environment's API URL; production's is the sandbox endpoint for https://api.oxagen.sh/webhooks/stripe until the cutover. |
Teamwork
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
TEAMWORK_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Teamwork OAuth client ID for connecting Teamwork as a work tracker. Connecting Teamwork answers not configured until this and TEAMWORK_OAUTH_CLIENT_SECRET are set. |
TEAMWORK_OAUTH_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | Teamwork OAuth client secret, sent to Teamwork's token address when a person connects Teamwork and when its tokens refresh. |
Testing / e2e
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
E2E_TEST | · | ● | · | · | · | · | — | manual | The exact string "true" on the e2e webServer (apps/app/playwright.config.ts) and the e2e seed (apps/app seed:e2e): packages/auth relaxes email verification and rate limiting on that value, only when VERCEL is unset and BETTER_AUTH_URL is a loopback origin (local-env.ts), so a leaked value on a deployed host relaxes nothing. Declared in turbo.json test:e2e env. Not for dev/preview/prod. NOTE: read via raw process.env, not in baseEnvSchema (test-only). |
OXAGEN_LOCAL_DEV | · | · | · | · | · | · | — | manual | Set to "1" by tools/scripts/dev.ts for the local dev stack. Consumed by packages/auth to make local-env detection deterministic instead of racing NODE_ENV at module-load time. Believed only when VERCEL is unset and BETTER_AUTH_URL is a loopback origin (local-env.ts), so it relaxes nothing on a deployed host. NOTE: read via raw process.env, not in baseEnvSchema (dev-tooling only). |
STRIPE_E2E | · | ● | · | · | · | · | — | manual | Whether the e2e job resolved a Stripe test key: "1" when STRIPE_TEST_SECRET_KEY was mapped into STRIPE_SECRET_KEY, "0" on a fork pull request without one (pay.spec.ts skips). Set by the e2e webServer env (apps/app/playwright.config.ts) and the CI job (WL-48). NOTE: read via raw process.env, not in baseEnvSchema (test-only). |
Trello
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
TRELLO_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Trello OAuth client ID for connecting Trello as a work tracker. Connecting Trello answers not configured until this and TRELLO_OAUTH_CLIENT_SECRET are set. |
TRELLO_OAUTH_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | Trello OAuth client secret, sent to Trello's token address when a person connects Trello and when its tokens refresh. |
Wrike
| Variable | api | app | mcp | docs | website | admin | Required | Origin | Description |
|---|---|---|---|---|---|---|---|---|---|
WRIKE_OAUTH_CLIENT_ID | ● | ● | · | · | · | · | — | manual | Wrike OAuth client ID for connecting Wrike as a work tracker. Connecting Wrike answers not configured until this and WRIKE_OAUTH_CLIENT_SECRET are set. |
WRIKE_OAUTH_CLIENT_SECRET secret | ● | ● | · | · | · | · | — | manual | Wrike OAuth client secret, sent to Wrike's token address when a person connects Wrike and when its tokens refresh. |
Secrets and variables
Where each secret and setting is kept and how to mint a new one.
SSM Parameter Store holds every value, in AWS account 916294258235 in us-east-1 (ADR-240). Run pnpm env:pull to write /oxagen/development into the four .env.local files: the root, apps/app, apps/api, and apps/mcp. Run pnpm env:push KEY --env <env> to save a new value, where <env> is development, staging, production, or operator. Parameter Store keeps a secret as a SecureString and any other value as a String.
Parameter prefixes
| Prefix | Holds | Read by |
|---|---|---|
/oxagen/production | Production values | The app node at container start and the production build |
/oxagen/staging | Staging values for the registry's preview environment | The staging node and the staging build |
/oxagen/development | Shared values for a laptop | pnpm env:pull |
/oxagen/operator | Secrets for maintainer tooling | pnpm env:pull --operator |
/oxagen/ci | CI secrets and variables (phase 3 of ADR-240: the prefix and its read roles exist, and no workflow reads it yet) | GitHub Actions through OIDC |
Environment values
A service reads each of these at build or start. Each one has a parameter in every environment, named by the prefix and the variable.
| Variable | Required | Parameter | Refresh |
|---|---|---|---|
AI_GATEWAY_API_KEY secret | none | /oxagen/{development,staging,production}/AI_GATEWAY_API_KEY | The script mints one key per environment through the Vercel API and saves each under that environment's prefix. Restart api, app, and mcp for staging and production, then delete the old keys in the Vercel dashboard under AI Gateway, API keys.pnpm vercel:rotate-ai-key oxagen-inc --env development,staging,productionSave with pnpm env:push AI_GATEWAY_API_KEY --env <env> |
ALERT_WEBHOOK_URL secret | none | /oxagen/{development,staging,production}/ALERT_WEBHOOK_URL | Create an incoming webhook in the chat tool that receives alerts (in Slack, the app's Incoming Webhooks page). Save the URL, restart, then remove the old webhook there. Save with pnpm env:push ALERT_WEBHOOK_URL --env <env> |
ASANA_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/ASANA_OAUTH_CLIENT_ID | Open the Asana developer console, My apps, the Oxagen app, OAuth. It changes only with the application. Save with pnpm env:push ASANA_OAUTH_CLIENT_ID --env <env> |
ASANA_OAUTH_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/ASANA_OAUTH_CLIENT_SECRET | Open the Asana developer console, My apps, the Oxagen app, OAuth, and make a new secret. Save it here and restart app and api in the same sitting, then delete the old secret at Asana. Save with pnpm env:push ASANA_OAUTH_CLIENT_SECRET --env <env> |
AUDIT_EXPORT_SIGNING_SECRET secret | none | /oxagen/{development,staging,production}/AUDIT_EXPORT_SIGNING_SECRET | Mint 32 random bytes. Outstanding export download links stop verifying.openssl rand -base64 32Save with pnpm env:push AUDIT_EXPORT_SIGNING_SECRET --env <env> |
AUTH_TOKEN_ENCRYPTION_KEY secret | P P | /oxagen/{development,staging,production}/AUTH_TOKEN_ENCRYPTION_KEY | Mint a 32-byte key. It encrypts SSO secrets, so change it together with SSO_SECRET_KEY_ID and SSO_SECRET_PREVIOUS_KEYS. Stored OAuth account tokens have no old-key fallback (TOKEN_KEY_ID in packages/auth/src/server/token-kms.ts), so people reconnect the accounts those tokens belong to.openssl rand -base64 32Save with pnpm env:push AUTH_TOKEN_ENCRYPTION_KEY --env <env> |
AWS_KMS_INGESTION_KEY_ARN | none | /oxagen/{development,staging,production}/AWS_KMS_INGESTION_KEY_ARN | Terraform owns the key (aws_kms_key.ingestion in infra/stacks-new/oxagen/crypto.tf) and this parameter. KMS rotates the key material yearly under the same ARN. Never point it at another key while credentials or private files encrypted with this one exist (docs/ops/ingestion-key-cutover.md).Save with pnpm env:push AWS_KMS_INGESTION_KEY_ARN --env <env> |
AZURE_DEVOPS_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/AZURE_DEVOPS_OAUTH_CLIENT_ID | Open the Microsoft Entra admin center, App registrations, the Oxagen Azure DevOps app, Certificates and secrets. It changes only with the application. Save with pnpm env:push AZURE_DEVOPS_OAUTH_CLIENT_ID --env <env> |
AZURE_DEVOPS_OAUTH_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/AZURE_DEVOPS_OAUTH_CLIENT_SECRET | Open the Microsoft Entra admin center, App registrations, the Oxagen Azure DevOps app, Certificates and secrets, and make a new secret. Save it here and restart app and api in the same sitting, then delete the old secret at Azure DevOps. Save with pnpm env:push AZURE_DEVOPS_OAUTH_CLIENT_SECRET --env <env> |
BASECAMP_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/BASECAMP_OAUTH_CLIENT_ID | Open the launchpad.37signals.com/integrations, the Oxagen app. It changes only with the application. Save with pnpm env:push BASECAMP_OAUTH_CLIENT_ID --env <env> |
BASECAMP_OAUTH_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/BASECAMP_OAUTH_CLIENT_SECRET | Open the launchpad.37signals.com/integrations, the Oxagen app, and make a new secret. Save it here and restart app and api in the same sitting, then delete the old secret at Basecamp. Save with pnpm env:push BASECAMP_OAUTH_CLIENT_SECRET --env <env> |
BETTER_AUTH_SECRET secret | D P P | /oxagen/{development,staging,production}/BETTER_AUTH_SECRET | Mint 32 random bytes. A new value signs out every session in that environment, so rotate in a quiet hour. api and app read the same parameter. AUDIT_EXPORT_SIGNING_SECRET falls back to this value when unset, so outstanding export links stop verifying too. Work order tokens are made under it as well, so a run already working a work order cannot post progress or claim checklist items until its work item is sent again.openssl rand -base64 32Save with pnpm env:push BETTER_AUTH_SECRET --env <env> |
BLOB_READ_WRITE_TOKEN secret | none | /oxagen/{development,staging,production}/BLOB_READ_WRITE_TOKEN | In the Vercel dashboard, open Storage, the Blob store, and create a read-write token. Save it, restart app and api, then revoke the old token. Save with pnpm env:push BLOB_READ_WRITE_TOKEN --env <env> |
CIRCUIT_BREAKER_FAILURE_THRESHOLD | none | /oxagen/{development,staging,production}/CIRCUIT_BREAKER_FAILURE_THRESHOLD | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push CIRCUIT_BREAKER_FAILURE_THRESHOLD --env <env> |
CIRCUIT_BREAKER_RESET_TIMEOUT_MS | none | /oxagen/{development,staging,production}/CIRCUIT_BREAKER_RESET_TIMEOUT_MS | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push CIRCUIT_BREAKER_RESET_TIMEOUT_MS --env <env> |
CIRCUIT_BREAKER_SUCCESS_THRESHOLD | none | /oxagen/{development,staging,production}/CIRCUIT_BREAKER_SUCCESS_THRESHOLD | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push CIRCUIT_BREAKER_SUCCESS_THRESHOLD --env <env> |
CLICKHOUSE_PASSWORD secret | none | /oxagen/{development,staging,production}/CLICKHOUSE_PASSWORD | Terraform generates it (random_password.clickhouse in infra/modules/app-node) and keeps it at /oxagen-app/clickhouse/password, or /oxagen-staging-app/clickhouse/password for staging. Copy that value here. A rotation replaces the Terraform resource, rewrites the node's ClickHouse env file, and restarts ClickHouse and the services in one window. Local Docker uses an empty password.aws ssm get-parameter --name /oxagen-app/clickhouse/password --with-decryption --query Parameter.Value --output textSave with pnpm env:push CLICKHOUSE_PASSWORD --env <env> |
CLICKHOUSE_URL | D P P | /oxagen/{development,staging,production}/CLICKHOUSE_URL | Changes only when ClickHouse moves. Production and staging run it on the app node (infra/modules/app-node). Locally it is the Docker container from docker-compose.dev.yml. Save with pnpm env:push CLICKHOUSE_URL --env <env> |
CLICKHOUSE_USERNAME | D P P | /oxagen/{development,staging,production}/CLICKHOUSE_USERNAME | Changes only with the ClickHouse user. The deployed nodes use the default user. Save with pnpm env:push CLICKHOUSE_USERNAME --env <env> |
CLICKUP_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/CLICKUP_OAUTH_CLIENT_ID | Open the ClickUp, Settings, Apps, the Oxagen app. It changes only with the application. Save with pnpm env:push CLICKUP_OAUTH_CLIENT_ID --env <env> |
CLICKUP_OAUTH_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/CLICKUP_OAUTH_CLIENT_SECRET | Open the ClickUp, Settings, Apps, the Oxagen app, and make a new secret. Save it here and restart app and api in the same sitting, then delete the old secret at ClickUp. Save with pnpm env:push CLICKUP_OAUTH_CLIENT_SECRET --env <env> |
CODEGRAPH_BLOB_PROVIDER | none | /oxagen/{development,staging,production}/CODEGRAPH_BLOB_PROVIDER | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push CODEGRAPH_BLOB_PROVIDER --env <env> |
CODEGRAPH_BUCKET_REGION | none | /oxagen/{development,staging,production}/CODEGRAPH_BUCKET_REGION | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push CODEGRAPH_BUCKET_REGION --env <env> |
CODEGRAPH_QUERY_TOKEN secret | none | /oxagen/{development,staging,production}/CODEGRAPH_QUERY_TOKEN | Production keeps one value at /oxagen/production/CODEGRAPH_QUERY_TOKEN, which the query service and api, app, and mcp all read. deploy-codegraph creates it with a random value when the parameter does not exist, and replaces a value shorter than 32 characters. OpenTofu does not manage it, so the token stays out of the state file. To rotate it, write a new value of at least 32 characters there, then restart the query service and the three services together.openssl rand -hex 32Save with pnpm env:push CODEGRAPH_QUERY_TOKEN --env <env> |
CODEGRAPH_QUERY_URL | none | /oxagen/{development,staging,production}/CODEGRAPH_QUERY_URL | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push CODEGRAPH_QUERY_URL --env <env> |
CODEGRAPH_WORKER_TOKEN secret | none | /oxagen/{development,staging,production}/CODEGRAPH_WORKER_TOKEN | Mint a value of at least 32 characters and save it under this name. The api node reads it at start, and the code graph worker's task definition reads the same parameter. Restart both together.openssl rand -hex 32Save with pnpm env:push CODEGRAPH_WORKER_TOKEN --env <env> |
DATABASE_URL secret | D P P | /oxagen/{development,staging,production}/DATABASE_URL | Production and staging connect to Aurora as the app role. Change that role's password on the database first, from the app node (Aurora admits connections from it alone), then save the new URL. The local value matches docker-compose.dev.yml and changes only with that file.openssl rand -hex 32Save with pnpm env:push DATABASE_URL --env <env> |
ENROLLMENT_SIGNING_PREVIOUS_PRIVATE_KEY secret | none | /oxagen/{development,staging,production}/ENROLLMENT_SIGNING_PREVIOUS_PRIVATE_KEY | Set during a rotation to the key ENROLLMENT_SIGNING_PRIVATE_KEY held before; clear once every host has renewed under the new key. Save with pnpm env:push ENROLLMENT_SIGNING_PREVIOUS_PRIVATE_KEY --env <env> |
ENROLLMENT_SIGNING_PRIVATE_KEY secret | none | /oxagen/{development,staging,production}/ENROLLMENT_SIGNING_PRIVATE_KEY | Rotate by moving the current key to ENROLLMENT_SIGNING_PREVIOUS_PRIVATE_KEY and saving the new key here. The key set is then locked with both, so a host that pins the old key takes the set that carries the new one at its next renewal. Clear the previous key once every host has renewed, within seven days. Save the PEM file as it is.openssl genpkey -algorithm ed25519 -out enrollment-signing.pemSave with pnpm env:push ENROLLMENT_SIGNING_PRIVATE_KEY --env <env> |
EVIDENCE_RECOVERY_ENCRYPTION_KEY secret | none | /oxagen/{development,staging,production}/EVIDENCE_RECOVERY_ENCRYPTION_KEY | Create a separate recovery key once and keep its secret version pinned. Replacing it makes recovered bodies unreadable.openssl rand -base64 32Save with pnpm env:push EVIDENCE_RECOVERY_ENCRYPTION_KEY --env <env> |
GITHUB_APP_CLIENT_ID | none | /oxagen/{development,staging,production}/GITHUB_APP_CLIENT_ID | On the GitHub App's settings page (Oxagen Connect, owned by the oxageninc organization). It changes only with the App. Save with pnpm env:push GITHUB_APP_CLIENT_ID --env <env> |
GITHUB_APP_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/GITHUB_APP_CLIENT_SECRET | On the GitHub App's settings page, generate a new client secret. Save it, restart api, app, and mcp, then delete the old secret. Save with pnpm env:push GITHUB_APP_CLIENT_SECRET --env <env> |
GITHUB_APP_ID | none | /oxagen/{development,staging,production}/GITHUB_APP_ID | The numeric id on the GitHub App's settings page. It changes only with the App. Save with pnpm env:push GITHUB_APP_ID --env <env> |
GITHUB_APP_INSTALL_STATE_SECRET secret | none | /oxagen/{development,staging,production}/GITHUB_APP_INSTALL_STATE_SECRET | Mint a value. An install that started before the change fails its state check and starts again.openssl rand -hex 32Save with pnpm env:push GITHUB_APP_INSTALL_STATE_SECRET --env <env> |
GITHUB_APP_PRIVATE_KEY secret | none | /oxagen/{development,staging,production}/GITHUB_APP_PRIVATE_KEY | On the GitHub App's settings page, generate a private key. GitHub allows several keys at once. Save the whole .pem from the file, restart, confirm a connected repository still syncs, then delete the old key on the same page.pnpm env:push GITHUB_APP_PRIVATE_KEY --env production < oxagen-connect.private-key.pemSave with pnpm env:push GITHUB_APP_PRIVATE_KEY --env <env> |
GITHUB_APP_SLUG | none | /oxagen/{development,staging,production}/GITHUB_APP_SLUG | The App's name in its public URL. It changes only if the App is renamed. Save with pnpm env:push GITHUB_APP_SLUG --env <env> |
GITHUB_APP_WEBHOOK_SECRET secret | none | /oxagen/{development,staging,production}/GITHUB_APP_WEBHOOK_SECRET | Mint a value. Set it on the GitHub App's settings page under Webhook secret and save it here in the same sitting. GitHub holds one secret, so deliveries between the two writes fail their check. Redeliver them from the App's Advanced tab.openssl rand -hex 32Save with pnpm env:push GITHUB_APP_WEBHOOK_SECRET --env <env> |
GITHUB_LOGIN_CLIENT_ID | P P | /oxagen/{development,staging,production}/GITHUB_LOGIN_CLIENT_ID | On the GitHub OAuth App's settings page (the organization's Developer settings, OAuth Apps). It changes only with a new app. Checklist: docs/runbooks/social-login-oauth-apps.md. Save with pnpm env:push GITHUB_LOGIN_CLIENT_ID --env <env> |
GITHUB_LOGIN_CLIENT_SECRET secret | P P | /oxagen/{development,staging,production}/GITHUB_LOGIN_CLIENT_SECRET | On the OAuth App's settings page, generate a new client secret. GitHub keeps both secrets valid until you delete one. Save the new one, restart api and app, then delete the old one. Save with pnpm env:push GITHUB_LOGIN_CLIENT_SECRET --env <env> |
GITHUB_PERSONAL_ACCESS_TOKEN secret | none | /oxagen/{development,staging,production}/GITHUB_PERSONAL_ACCESS_TOKEN | Local and demo only. Never set it in staging or production. Create a fine-grained token at github.com/settings/personal-access-tokens when you need it. Save with pnpm env:push GITHUB_PERSONAL_ACCESS_TOKEN --env <env> |
GOOGLE_CLOUD_PROJECT | none | /oxagen/{development,staging,production}/GOOGLE_CLOUD_PROJECT | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push GOOGLE_CLOUD_PROJECT --env <env> |
GOOGLE_CLOUD_PROJECT_NUMBER | none | /oxagen/{development,staging,production}/GOOGLE_CLOUD_PROJECT_NUMBER | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push GOOGLE_CLOUD_PROJECT_NUMBER --env <env> |
GOOGLE_DATA_CLIENT_ID | none | /oxagen/{development,staging,production}/GOOGLE_DATA_CLIENT_ID | In the Google Cloud console, open APIs and Services, Credentials, and the data OAuth client. It changes only with a new client. Save with pnpm env:push GOOGLE_DATA_CLIENT_ID --env <env> |
GOOGLE_DATA_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/GOOGLE_DATA_CLIENT_SECRET | In the Google Cloud console, open the data OAuth client and add a client secret. Save it, restart, then disable and delete the old secret. Save with pnpm env:push GOOGLE_DATA_CLIENT_SECRET --env <env> |
GOOGLE_LOGIN_CLIENT_ID | P P | /oxagen/{development,staging,production}/GOOGLE_LOGIN_CLIENT_ID | In the Google Cloud console, open APIs and Services, Credentials, and the login OAuth client. It changes only with a new client. Checklist: docs/runbooks/social-login-oauth-apps.md. Save with pnpm env:push GOOGLE_LOGIN_CLIENT_ID --env <env> |
GOOGLE_LOGIN_CLIENT_SECRET secret | P P | /oxagen/{development,staging,production}/GOOGLE_LOGIN_CLIENT_SECRET | In the Google Cloud console, open the login OAuth client and add a client secret. Save it, restart api and app, then disable and delete the old secret on the same page. Save with pnpm env:push GOOGLE_LOGIN_CLIENT_SECRET --env <env> |
INGESTION_ENCRYPTION_KEY secret | P P | /oxagen/{development,staging,production}/INGESTION_ENCRYPTION_KEY | Mint a 32-byte key. Production encrypts with KMS instead (INGESTION_CRYPTO_PROVIDER=kms). Credentials and private files encrypted under the old key cannot be opened with a new one. Keep the old key until a rewrap migration is complete; replacing or losing it can make attachments and exports unreadable and require connectors to reconnect.openssl rand -base64 32Save with pnpm env:push INGESTION_ENCRYPTION_KEY --env <env> |
INNGEST_EVENT_KEY secret | P P | /oxagen/{development,staging,production}/INNGEST_EVENT_KEY | In the Inngest dashboard, open the environment's Manage page, Event keys. Create a key, save it, restart api and app, then delete the old key. Save with pnpm env:push INNGEST_EVENT_KEY --env <env> |
INNGEST_SIGNING_KEY secret | P P | /oxagen/{development,staging,production}/INNGEST_SIGNING_KEY | In the Inngest dashboard, open the environment's Manage page, Signing key. Inngest's rotation issues a new key while the old one still works. Save the new key, restart api and app, then finish the rotation in the dashboard. Save with pnpm env:push INNGEST_SIGNING_KEY --env <env> |
JIRA_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/JIRA_OAUTH_CLIENT_ID | Open the Atlassian developer console, the OAuth 2.0 (3LO) app, Settings. It changes only with the application. Save with pnpm env:push JIRA_OAUTH_CLIENT_ID --env <env> |
JIRA_OAUTH_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/JIRA_OAUTH_CLIENT_SECRET | Open the Atlassian developer console, the OAuth 2.0 (3LO) app, Settings, and make a new secret. Save it here and restart app and api in the same sitting, then delete the old secret at Jira. Save with pnpm env:push JIRA_OAUTH_CLIENT_SECRET --env <env> |
LEAD_ALERT_EMAILS | none | /oxagen/{development,staging,production}/LEAD_ALERT_EMAILS | Save the addresses as a comma-separated list, then restart the api. The api reads the value when it starts. Save with pnpm env:push LEAD_ALERT_EMAILS --env <env> |
LEAD_ALERT_SLACK_BOT_TOKEN secret | none | /oxagen/{development,staging,production}/LEAD_ALERT_SLACK_BOT_TOKEN | At api.slack.com/apps, open the Oxagen leads app, OAuth & Permissions, and reinstall it to the workspace or rotate the bot token. Save the new token, restart the api, then revoke the old one there. Save with pnpm env:push LEAD_ALERT_SLACK_BOT_TOKEN --env <env> |
LEAD_ALERT_SLACK_CHANNEL | none | /oxagen/{development,staging,production}/LEAD_ALERT_SLACK_CHANNEL | Save the channel's name and restart the api. The api reads the value when it starts. Save with pnpm env:push LEAD_ALERT_SLACK_CHANNEL --env <env> |
LEAD_SHEETS_SERVICE_ACCOUNT_EMAIL | none | /oxagen/{development,staging,production}/LEAD_SHEETS_SERVICE_ACCOUNT_EMAIL | Save the service account email and restart the api. Save with pnpm env:push LEAD_SHEETS_SERVICE_ACCOUNT_EMAIL --env <env> |
LEAD_SHEETS_SPREADSHEET_ID | none | /oxagen/{development,staging,production}/LEAD_SHEETS_SPREADSHEET_ID | Save the spreadsheet ID and restart the api. Save with pnpm env:push LEAD_SHEETS_SPREADSHEET_ID --env <env> |
LINEAR_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/LINEAR_OAUTH_CLIENT_ID | In Linear, open Settings, API, and the OAuth application. It changes only with the application. Save with pnpm env:push LINEAR_OAUTH_CLIENT_ID --env <env> |
LINEAR_WEBHOOK_SECRET secret | none | /oxagen/{development,staging,production}/LINEAR_WEBHOOK_SECRET | In Linear, open Settings, API, the OAuth application, and its webhook. Linear shows the signing secret there. Save it and restart api in the same sitting, because deliveries locked with the new secret fail until api has it. Save with pnpm env:push LINEAR_WEBHOOK_SECRET --env <env> |
MCP_OAUTH_PREREGISTERED_CLIENTS secret | none | /oxagen/{development,staging,production}/MCP_OAUTH_PREREGISTERED_CLIENTS | JSON built from the client id and secret each MCP vendor issued for the callback <app-origin>/api/v1/mcp/oauth/callback. Roll a secret in that vendor's console, edit the JSON, and save the whole object.Save with pnpm env:push MCP_OAUTH_PREREGISTERED_CLIENTS --env <env> |
MICROSOFT_DATA_CLIENT_ID | none | /oxagen/{development,staging,production}/MICROSOFT_DATA_CLIENT_ID | In the Azure portal, open App registrations and the app. It is the application (client) id and changes only with the app. Save with pnpm env:push MICROSOFT_DATA_CLIENT_ID --env <env> |
MICROSOFT_DATA_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/MICROSOFT_DATA_CLIENT_SECRET | In the Azure portal, open the app registration, Certificates and secrets, and add a client secret. Save it, restart api, then delete the old secret. Azure secrets expire, so note the date. Save with pnpm env:push MICROSOFT_DATA_CLIENT_SECRET --env <env> |
NEO4J_PASSWORD secret | none | /oxagen/{development,staging,production}/NEO4J_PASSWORD | Terraform generates it (random_password.neo4j in infra/modules/app-node) and keeps it at /oxagen-app/neo4j/password, or /oxagen-staging-app/neo4j/password for staging. Copy that value here. A rotation replaces the Terraform resource, rewrites the node's Neo4j env file, and restarts Neo4j and the services in one window. Locally it is the password in docker-compose.dev.yml.aws ssm get-parameter --name /oxagen-app/neo4j/password --with-decryption --query Parameter.Value --output textSave with pnpm env:push NEO4J_PASSWORD --env <env> |
NEO4J_URI | none | /oxagen/{development,staging,production}/NEO4J_URI | Changes only when Neo4j moves. Production and staging run it on the app node (infra/modules/app-node). Locally it is the Docker container. Save with pnpm env:push NEO4J_URI --env <env> |
NEO4J_USERNAME | none | /oxagen/{development,staging,production}/NEO4J_USERNAME | Changes only with the Neo4j user. The deployed nodes use neo4j. Save with pnpm env:push NEO4J_USERNAME --env <env> |
NEXT_SERVER_ACTIONS_ENCRYPTION_KEY secret | P | /oxagen/{development,staging,production}/NEXT_SERVER_ACTIONS_ENCRYPTION_KEY | Mint 32 random bytes, base64. A new value changes every server action id, so every page open at the next app deploy breaks once and works after a reload. Keep production and staging (/oxagen/staging) on different values.openssl rand -base64 32Save with pnpm env:push NEXT_SERVER_ACTIONS_ENCRYPTION_KEY --env <env> |
OAUTH_PROXY_SECRET secret | none | /oxagen/{development,staging,production}/OAUTH_PROXY_SECRET | Mint 32 random bytes. Save the same value in production and staging in one sitting. Preview social sign-in fails until the two match.openssl rand -base64 32Save with pnpm env:push OAUTH_PROXY_SECRET --env <env> |
OPENAI_APPS_VERIFICATION_TOKEN | none | /oxagen/{development,staging,production}/OPENAI_APPS_VERIFICATION_TOKEN | OpenAI shows the challenge when you verify the domain for an app. Paste the value it shows. Save with pnpm env:push OPENAI_APPS_VERIFICATION_TOKEN --env <env> |
OPENROUTER_API_KEY secret | P P | /oxagen/{development,staging,production}/OPENROUTER_API_KEY | Create a key at openrouter.ai/settings/keys, or mint one with the management key. Save it, restart, then delete the old key.curl -s https://openrouter.ai/api/v1/keys -H "Authorization: Bearer $OPENROUTER_MANAGEMENT_KEY" -H 'Content-Type: application/json' -d '{"name":"oxagen-production"}'Save with pnpm env:push OPENROUTER_API_KEY --env <env> |
OPENROUTER_MANAGEMENT_KEY secret | none | /oxagen/{development,staging,production}/OPENROUTER_MANAGEMENT_KEY | In OpenRouter settings, open Provisioning keys. Create a key, save it, restart, then delete the old one. Keys it already minted keep working. Save with pnpm env:push OPENROUTER_MANAGEMENT_KEY --env <env> |
OPENROUTER_ORG_KEY_DAILY_LIMIT_USD | none | /oxagen/{development,staging,production}/OPENROUTER_ORG_KEY_DAILY_LIMIT_USD | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push OPENROUTER_ORG_KEY_DAILY_LIMIT_USD --env <env> |
OPENROUTER_WORKSPACE_ID | none | /oxagen/{development,staging,production}/OPENROUTER_WORKSPACE_ID | In OpenRouter settings, open the workspace that holds the minted keys and copy its ID. Save with pnpm env:push OPENROUTER_WORKSPACE_ID --env <env> |
OTEL_EXPORTER_OTLP_ENDPOINT | none | /oxagen/{development,staging,production}/OTEL_EXPORTER_OTLP_ENDPOINT | Your collector's OTLP HTTP traces URL. Delete the parameter to turn tracing off. Save with pnpm env:push OTEL_EXPORTER_OTLP_ENDPOINT --env <env> |
OTEL_EXPORTER_OTLP_HEADERS secret | none | /oxagen/{development,staging,production}/OTEL_EXPORTER_OTLP_HEADERS | The collector vendor issues the ingest token these headers carry. Create a new token there, save the whole header list, restart, then revoke the old token. Save with pnpm env:push OTEL_EXPORTER_OTLP_HEADERS --env <env> |
OTEL_SERVICE_NAME | none | /oxagen/{development,staging,production}/OTEL_SERVICE_NAME | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push OTEL_SERVICE_NAME --env <env> |
OXAGEN_ASSISTANT_MARKUP | none | /oxagen/{development,staging,production}/OXAGEN_ASSISTANT_MARKUP | A setting. Leave it unset unless pricing changes the assistant markup. Save with pnpm env:push OXAGEN_ASSISTANT_MARKUP --env <env> |
OXAGEN_PRICE_OVERRIDES secret | none | /oxagen/{development,staging,production}/OXAGEN_PRICE_OVERRIDES | Negotiated rates from a provider contract, as JSON. Edit the object and save it whole when a contract changes. Save with pnpm env:push OXAGEN_PRICE_OVERRIDES --env <env> |
OXAGEN_PRICE_OVERRIDES_FILE | none | /oxagen/{development,staging,production}/OXAGEN_PRICE_OVERRIDES_FILE | A path inside the container. Set it only when a rates file is mounted there. Save with pnpm env:push OXAGEN_PRICE_OVERRIDES_FILE --env <env> |
OXAGEN_TACHO_GITHUB_BROKER | none | /oxagen/{development,staging,production}/OXAGEN_TACHO_GITHUB_BROKER | A switch. Set it to 1 to turn the feature on, or delete the parameter to turn it off. Save with pnpm env:push OXAGEN_TACHO_GITHUB_BROKER --env <env> |
PR_DIFF_BUCKET | none | /oxagen/{development,staging,production}/PR_DIFF_BUCKET | Manage the private bucket through the selected infrastructure stack. Preserve its provider and bucket while revisions reference stored objects. The GCS setting must not name the public-assets bucket. Save with pnpm env:push PR_DIFF_BUCKET --env <env> |
PR_DIFF_BUCKET_REGION | none | /oxagen/{development,staging,production}/PR_DIFF_BUCKET_REGION | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push PR_DIFF_BUCKET_REGION --env <env> |
PR_DIFF_STORAGE_PROVIDER | none | /oxagen/{development,staging,production}/PR_DIFF_STORAGE_PROVIDER | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push PR_DIFF_STORAGE_PROVIDER --env <env> |
RATE_LIMIT_CHAT_PER_MIN | none | /oxagen/{development,staging,production}/RATE_LIMIT_CHAT_PER_MIN | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push RATE_LIMIT_CHAT_PER_MIN --env <env> |
SALESFORCE_DATA_CLIENT_ID | none | /oxagen/{development,staging,production}/SALESFORCE_DATA_CLIENT_ID | In Salesforce Setup, open App Manager, the connected app, Manage Consumer Details. It changes only with the app. Save with pnpm env:push SALESFORCE_DATA_CLIENT_ID --env <env> |
SALESFORCE_DATA_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/SALESFORCE_DATA_CLIENT_SECRET | In Salesforce Setup, open the connected app, Manage Consumer Details, and generate a new consumer secret. Save it and restart api. Save with pnpm env:push SALESFORCE_DATA_CLIENT_SECRET --env <env> |
SANDBOX_BUCKET | none | /oxagen/{development,staging,production}/SANDBOX_BUCKET | The sandbox-hosts stack owns the bucket (infra/stacks-new/sandbox-hosts/storage.tf). Never point it at another bucket while templates and runs name objects in this one. Save with pnpm env:push SANDBOX_BUCKET --env <env> |
SANDBOX_BUCKET_REGION | none | /oxagen/{development,staging,production}/SANDBOX_BUCKET_REGION | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push SANDBOX_BUCKET_REGION --env <env> |
SANDBOX_HOST_JOIN_TOKEN_PATH | none | /oxagen/{development,staging,production}/SANDBOX_HOST_JOIN_TOKEN_PATH | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push SANDBOX_HOST_JOIN_TOKEN_PATH --env <env> |
SANDBOX_REQUIRED_HOSTS | none | /oxagen/{development,staging,production}/SANDBOX_REQUIRED_HOSTS | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push SANDBOX_REQUIRED_HOSTS --env <env> |
SERVER_ACTIONS_ALLOWED_ORIGINS | none | /oxagen/{development,staging,production}/SERVER_ACTIONS_ALLOWED_ORIGINS | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push SERVER_ACTIONS_ALLOWED_ORIGINS --env <env> |
SLACK_APP_CLIENT_ID | none | /oxagen/{development,staging,production}/SLACK_APP_CLIENT_ID | At api.slack.com/apps, open the Oxagen app, Basic Information. It changes only with the app. Save with pnpm env:push SLACK_APP_CLIENT_ID --env <env> |
SLACK_APP_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/SLACK_APP_CLIENT_SECRET | At api.slack.com/apps, open the Oxagen app, Basic Information, App Credentials, and regenerate the client secret. Slack retires the old one at once, so save and restart app in the same sitting. Save with pnpm env:push SLACK_APP_CLIENT_SECRET --env <env> |
SLACK_APP_ID | none | /oxagen/{development,staging,production}/SLACK_APP_ID | At api.slack.com/apps, open the Oxagen app, Basic Information. It changes only with the app. Save with pnpm env:push SLACK_APP_ID --env <env> |
SLACK_APP_SIGNING_SECRET secret | none | /oxagen/{development,staging,production}/SLACK_APP_SIGNING_SECRET | At api.slack.com/apps, open the Oxagen app, Basic Information, and regenerate the signing secret. Nothing reads it yet. Save with pnpm env:push SLACK_APP_SIGNING_SECRET --env <env> |
SLACK_DATA_CLIENT_ID | none | /oxagen/{development,staging,production}/SLACK_DATA_CLIENT_ID | At api.slack.com/apps, open the data app, Basic Information. It changes only with the app. Save with pnpm env:push SLACK_DATA_CLIENT_ID --env <env> |
SLACK_DATA_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/SLACK_DATA_CLIENT_SECRET | At api.slack.com/apps, open the data app, Basic Information, App Credentials, and regenerate the client secret. Slack retires the old one at once, so save and restart in the same sitting. Save with pnpm env:push SLACK_DATA_CLIENT_SECRET --env <env> |
SMTP_PASSWORD secret | none | /oxagen/{development,staging,production}/SMTP_PASSWORD | A Resend API key with sending access. Create one in the Resend dashboard under API keys, save it, restart, then delete the old key. Save with pnpm env:push SMTP_PASSWORD --env <env> |
SSO_SECRET_KEY_ID | none | /oxagen/{development,staging,production}/SSO_SECRET_KEY_ID | A label. Give it a new value, such as sso_v2, each time AUTH_TOKEN_ENCRYPTION_KEY changes (ADR-145 describes the rotation). Save with pnpm env:push SSO_SECRET_KEY_ID --env <env> |
SSO_SECRET_PREVIOUS_KEYS secret | none | /oxagen/{development,staging,production}/SSO_SECRET_PREVIOUS_KEYS | When AUTH_TOKEN_ENCRYPTION_KEY changes, add <old key id>=<old key>. Remove the entry once an auth/sso-reseal run reports failed: [] and resealed: 0 (ADR-145 describes the rotation).Save with pnpm env:push SSO_SECRET_PREVIOUS_KEYS --env <env> |
STELLA_SERVE_TOKEN secret | P | /oxagen/{development,staging,production}/STELLA_SERVE_TOKEN | Mint a value and save it at both /oxagen/production/STELLA_SERVE_TOKEN and /oxagen/production/stella-serve/STELLA_SERVE_TOKEN. pnpm env:push writes the first. Write the second with aws ssm put-parameter. Then restart stella-serve, app, and api together (infra/tools/node/README.md, The engine service).openssl rand -hex 32Save with pnpm env:push STELLA_SERVE_TOKEN --env <env> |
STELLA_TELEMETRY_INGEST_ENDPOINTS | none | /oxagen/{development,staging,production}/STELLA_TELEMETRY_INGEST_ENDPOINTS | A setting. List the HTTPS endpoints this deployment serves for Stella telemetry. Save with pnpm env:push STELLA_TELEMETRY_INGEST_ENDPOINTS --env <env> |
STORAGE_DRIVER | none | /oxagen/{development,staging,production}/STORAGE_DRIVER | Terraform owns the production value (infra/stacks-new/oxagen/blob-storage.tf). Restart app and api after it changes. Files written to the old store stay there and read as missing. Save with pnpm env:push STORAGE_DRIVER --env <env> |
STORAGE_FS_ROOT | none | /oxagen/{development,staging,production}/STORAGE_FS_ROOT | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push STORAGE_FS_ROOT --env <env> |
STORAGE_GCS_BUCKET | none | /oxagen/{development,staging,production}/STORAGE_GCS_BUCKET | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push STORAGE_GCS_BUCKET --env <env> |
STORAGE_GCS_PUBLIC_BUCKET | none | /oxagen/{development,staging,production}/STORAGE_GCS_PUBLIC_BUCKET | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push STORAGE_GCS_PUBLIC_BUCKET --env <env> |
STORAGE_GCS_PUBLIC_URL | none | /oxagen/{development,staging,production}/STORAGE_GCS_PUBLIC_URL | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push STORAGE_GCS_PUBLIC_URL --env <env> |
STORAGE_GCS_SERVICE_ACCOUNT | none | /oxagen/{development,staging,production}/STORAGE_GCS_SERVICE_ACCOUNT | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push STORAGE_GCS_SERVICE_ACCOUNT --env <env> |
STORAGE_S3_BUCKET | none | /oxagen/{development,staging,production}/STORAGE_S3_BUCKET | Terraform owns the bucket and this parameter (infra/stacks-new/oxagen/blob-storage.tf). Never point it at another bucket while rows name objects in this one. Save with pnpm env:push STORAGE_S3_BUCKET --env <env> |
STORAGE_S3_PUBLIC_BUCKET | none | /oxagen/{development,staging,production}/STORAGE_S3_PUBLIC_BUCKET | Terraform owns the bucket and this parameter (infra/stacks-new/oxagen/blob-storage.tf). Save with pnpm env:push STORAGE_S3_PUBLIC_BUCKET --env <env> |
STORAGE_S3_PUBLIC_URL | none | /oxagen/{development,staging,production}/STORAGE_S3_PUBLIC_URL | Terraform owns the distribution and this parameter (infra/stacks-new/oxagen/blob-storage.tf). A stored public URL keeps the origin it was written with. Save with pnpm env:push STORAGE_S3_PUBLIC_URL --env <env> |
STORAGE_S3_REGION | none | /oxagen/{development,staging,production}/STORAGE_S3_REGION | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push STORAGE_S3_REGION --env <env> |
STRIPE_PUBLISHABLE_KEY | none | /oxagen/{development,staging,production}/STRIPE_PUBLISHABLE_KEY | In the Stripe dashboard, open Developers, API keys. It changes when the account does, at the live cutover. Save with pnpm env:push STRIPE_PUBLISHABLE_KEY --env <env> |
STRIPE_SECRET_KEY secret | D P P | /oxagen/{development,staging,production}/STRIPE_SECRET_KEY | In the Stripe dashboard, open Developers, API keys, and roll the secret key. Every environment uses the shared sandbox until the live cutover (docs/ops/stripe-sandbox-mode.md). Stripe keeps the old key alive for the period you pick, so save and restart inside it. Production's value is also the GitHub secret STRIPE_SECRET_KEY in the production environment. Save with pnpm env:push STRIPE_SECRET_KEY --env <env> |
STRIPE_TAX_ENABLED | none | /oxagen/{development,staging,production}/STRIPE_TAX_ENABLED | A switch. Turn it on only after Stripe Tax is active in the dashboard. Save with pnpm env:push STRIPE_TAX_ENABLED --env <env> |
STRIPE_WEBHOOK_SECRET secret | D P P | /oxagen/{development,staging,production}/STRIPE_WEBHOOK_SECRET | In the Stripe dashboard, open Developers, Webhooks, the endpoint for this environment's API URL, and roll the signing secret. Save the new whsec_ value and restart inside the overlap Stripe offers. Save with pnpm env:push STRIPE_WEBHOOK_SECRET --env <env> |
TACHO_BUNDLE_SIGNING_PRIVATE_KEY secret | none | /oxagen/{development,staging,production}/TACHO_BUNDLE_SIGNING_PRIVATE_KEY | Rotate only on a leak. Hosts received the public key at enrollment and refuse bundles a new key locks, so every host enrolls again after the change. Run exports locked before the change verify only with the old public key. Save the PEM file as it is.openssl genpkey -algorithm ed25519 -out tacho-bundle.pemSave with pnpm env:push TACHO_BUNDLE_SIGNING_PRIVATE_KEY --env <env> |
TACHO_INGEST_ENDPOINTS | none | /oxagen/{development,staging,production}/TACHO_INGEST_ENDPOINTS | A setting. List the HTTPS base URLs of this deployment's recorder endpoints. Save with pnpm env:push TACHO_INGEST_ENDPOINTS --env <env> |
TACHO_MCP_ENDPOINT | none | /oxagen/{development,staging,production}/TACHO_MCP_ENDPOINT | A setting. Change it in the environment that needs it. Services read it when they start. Save with pnpm env:push TACHO_MCP_ENDPOINT --env <env> |
TEAMWORK_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/TEAMWORK_OAUTH_CLIENT_ID | Open the Teamwork developer portal, the Oxagen app. It changes only with the application. Save with pnpm env:push TEAMWORK_OAUTH_CLIENT_ID --env <env> |
TEAMWORK_OAUTH_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/TEAMWORK_OAUTH_CLIENT_SECRET | Open the Teamwork developer portal, the Oxagen app, and make a new secret. Save it here and restart app and api in the same sitting, then delete the old secret at Teamwork. Save with pnpm env:push TEAMWORK_OAUTH_CLIENT_SECRET --env <env> |
TENANT_RLS_ENFORCEMENT_ENABLED | none | /oxagen/{development,staging,production}/TENANT_RLS_ENFORCEMENT_ENABLED | A switch. Leave it unset in production, where it defaults on and false refuses to boot. Save with pnpm env:push TENANT_RLS_ENFORCEMENT_ENABLED --env <env> |
TRELLO_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/TRELLO_OAUTH_CLIENT_ID | Open the Atlassian developer console, the Oxagen Trello app, Settings. It changes only with the application. Save with pnpm env:push TRELLO_OAUTH_CLIENT_ID --env <env> |
TRELLO_OAUTH_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/TRELLO_OAUTH_CLIENT_SECRET | Open the Atlassian developer console, the Oxagen Trello app, Settings, and make a new secret. Save it here and restart app and api in the same sitting, then delete the old secret at Trello. Save with pnpm env:push TRELLO_OAUTH_CLIENT_SECRET --env <env> |
TRUST_EDGE_CLIENT_IP_HEADER | none | /oxagen/{development,staging,production}/TRUST_EDGE_CLIENT_IP_HEADER | A switch. Set it to true only after the Caddy config that writes the header is live (ADR-083). Save with pnpm env:push TRUST_EDGE_CLIENT_IP_HEADER --env <env> |
TRUSTED_PROXY_CIDRS | none | /oxagen/{development,staging,production}/TRUSTED_PROXY_CIDRS | A setting. Name the subnets of the proxies in front of the services, from infra/modules/network. Read ADR-083 before you change it. Save with pnpm env:push TRUSTED_PROXY_CIDRS --env <env> |
VOYAGE_API_KEY secret | P | /oxagen/{development,staging,production}/VOYAGE_API_KEY | In the Voyage AI dashboard, open API keys. Create a key, save it, restart, then revoke the old key. Save with pnpm env:push VOYAGE_API_KEY --env <env> |
WORK_ATTACHMENT_URL | none | /oxagen/{development,staging,production}/WORK_ATTACHMENT_URL | Set to the origin that serves work attachment links. Changes only when that origin moves. Save with pnpm env:push WORK_ATTACHMENT_URL --env <env> |
WRIKE_OAUTH_CLIENT_ID | none | /oxagen/{development,staging,production}/WRIKE_OAUTH_CLIENT_ID | Open the Wrike, Apps and integrations, API, the Oxagen app. It changes only with the application. Save with pnpm env:push WRIKE_OAUTH_CLIENT_ID --env <env> |
WRIKE_OAUTH_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/WRIKE_OAUTH_CLIENT_SECRET | Open the Wrike, Apps and integrations, API, the Oxagen app, and make a new secret. Save it here and restart app and api in the same sitting, then delete the old secret at Wrike. Save with pnpm env:push WRIKE_OAUTH_CLIENT_SECRET --env <env> |
ZOOM_DATA_CLIENT_ID | none | /oxagen/{development,staging,production}/ZOOM_DATA_CLIENT_ID | In the Zoom App Marketplace, open the OAuth app, App Credentials. It changes only with the app. Save with pnpm env:push ZOOM_DATA_CLIENT_ID --env <env> |
ZOOM_DATA_CLIENT_SECRET secret | none | /oxagen/{development,staging,production}/ZOOM_DATA_CLIENT_SECRET | In the Zoom App Marketplace, open the OAuth app, App Credentials, and regenerate the client secret. Save it and restart api in the same sitting. Save with pnpm env:push ZOOM_DATA_CLIENT_SECRET --env <env> |
Operator values
Only maintainer tooling reads these. One parameter holds each one for every environment.
| Variable | Required | Parameter | Refresh |
|---|---|---|---|
LINEAR_API_KEY secret | none | /oxagen/operator/LINEAR_API_KEY | In Linear, open Settings, Security and access, Personal API keys. Create a key, save it here and as the GitHub secret LINEAR_API_KEY, then revoke the old key. Save with pnpm env:push LINEAR_API_KEY --env operator |
NPM_TOKEN secret | none | /oxagen/operator/NPM_TOKEN | On npmjs.com, open Access Tokens and generate a granular token with read and write on @oxagen/cli. It expires within 90 days. Save it here and as the GitHub secret NPM_TOKEN, then delete the old token once npm.yml publishes with the new one. Save with pnpm env:push NPM_TOKEN --env operator |
TAURI_SIGNING_PRIVATE_KEY secret | none | /oxagen/operator/TAURI_SIGNING_PRIVATE_KEY | Rotate only on a leak. Installed apps check updates against the public key in apps/desktop/src-tauri/tauri.conf.json, so a new key needs a release, locked with the old key, that ships the new public key first. Save the private key here and as the GitHub secret of the same name.pnpm --filter @oxagen/desktop exec tauri signer generate -w ~/.tauri/oxagen-desktop.keySave with pnpm env:push TAURI_SIGNING_PRIVATE_KEY --env operator |
TAURI_SIGNING_PRIVATE_KEY_PASSWORD secret | none | /oxagen/operator/TAURI_SIGNING_PRIVATE_KEY_PASSWORD | Changes only with TAURI_SIGNING_PRIVATE_KEY. The key has none, so the value is the empty string. Save with pnpm env:push TAURI_SIGNING_PRIVATE_KEY_PASSWORD --env operator |
CI secrets and variables
21 values from packages/config/src/ci-registry.ts. Each one is a GitHub Actions secret or variable on the repository, or on the GitHub environment named under its kind. pnpm env:check fails when a workflow reads a value the registry does not list, reads one as the wrong kind, or the registry lists one no workflow reads. Phase 3 of ADR-240 moves the secrets to /oxagen/ci. That prefix and its OIDC read roles exist, and no workflow reads it yet.
| Name | Kind | Description | Read by | Refresh |
|---|---|---|---|---|
AI_GATEWAY_API_KEY | secret | Vercel AI Gateway key that release.yml uses to write the release notes. | release.yml | Create a key in the Vercel dashboard under AI Gateway, API keys. Save it here, then delete the old key on the same page. Save with gh secret set AI_GATEWAY_API_KEY |
APPLE_CERTIFICATE | secret | Base64 of the Developer ID Application certificate and its private key, exported as a .p12. desktop.yml locks the macOS build with it, so macOS can check the build came from Oxagen unchanged. Unset, the build is locked without a Developer ID, so macOS cannot tell who made it. | desktop.yml | Apple issues the certificate at developer.apple.com under Certificates. Export it with its private key from Keychain Access as a .p12, and save the base64 of the file. Save APPLE_CERTIFICATE_PASSWORD in the same change.base64 -i developer-id.p12Save with gh secret set APPLE_CERTIFICATE |
APPLE_CERTIFICATE_PASSWORD | secret | Export password of the .p12 in APPLE_CERTIFICATE. | desktop.yml | You choose it when you export the .p12. Change it only with APPLE_CERTIFICATE. Save with gh secret set APPLE_CERTIFICATE_PASSWORD |
APPLE_ID | secret | Apple ID email desktop.yml notarizes the macOS build with. | desktop.yml | The email of the Apple developer account. It changes only when the account does. Save with gh secret set APPLE_ID |
APPLE_PASSWORD | secret | App-specific password for APPLE_ID, used by notarization in desktop.yml. | desktop.yml | Generate one at account.apple.com under Sign-In and Security, App-Specific Passwords. Revoke the old one there after the next desktop build notarizes. Save with gh secret set APPLE_PASSWORD |
APPLE_SIGNING_IDENTITY | secret | Name of the Developer ID certificate desktop.yml locks the macOS build with, as Keychain shows it. | desktop.yml | Read it from the certificate in APPLE_CERTIFICATE. It changes when that certificate does.security find-identity -v -p codesigningSave with gh secret set APPLE_SIGNING_IDENTITY |
APPLE_TEAM_ID | secret | Apple developer team id, used by notarization in desktop.yml. | desktop.yml | Read it at developer.apple.com under Membership details. It changes only with the team. Save with gh secret set APPLE_TEAM_ID |
CI_FILES_PER_SHARD | variable | Changed code files per unit shard in pr.yml. The plan starts one shard for each block of this many files in a lane, up to the lane's ceiling. Unset, 8. | pr.yml | A setting. Change it with gh variable set, and the next pull request run reads it. tools/scripts/github-ci-secrets.md gives the cost of each value. Save with gh variable set CI_FILES_PER_SHARD --body '<value>' |
CI_IMAGE_REGISTRY | variable | Registry the CI toolchain and service images come from, such as an ECR Public alias. Unset, jobs use public.ecr.aws/z5z6u7g2. | main.ymlpr.yml | A setting. Point it at the ECR Public registry ci-image.yml publishes to (docs/runbooks/ci-runners.md). Save with gh variable set CI_IMAGE_REGISTRY --body '<value>' |
CI_RUNNER_UNIT | variable | Runner label the pr.yml unit lanes run on. Unset, linux-arm64-16core from the github-hosted-arm64 group. linux-arm64-4core costs less and runs slower. | pr.yml | A setting. Change it with gh variable set, and the next pull request run reads it. tools/scripts/github-ci-secrets.md gives the cost of each value. Save with gh variable set CI_RUNNER_UNIT --body '<value>' |
CI_SHARDS_APP | variable | Most shards the pr.yml unit-app lane starts. Unset, 4. | pr.yml | A setting. Change it with gh variable set, and the next pull request run reads it. tools/scripts/github-ci-secrets.md gives the cost of each value. Save with gh variable set CI_SHARDS_APP --body '<value>' |
CI_SHARDS_PLAIN | variable | Most shards the pr.yml unit-related lane starts. Unset, 2. | pr.yml | A setting. Change it with gh variable set, and the next pull request run reads it. tools/scripts/github-ci-secrets.md gives the cost of each value. Save with gh variable set CI_SHARDS_PLAIN --body '<value>' |
CI_SHARDS_STORES | variable | Most shards the pr.yml unit-related-stores lane starts. Unset, 4. | pr.yml | A setting. Change it with gh variable set, and the next pull request run reads it. tools/scripts/github-ci-secrets.md gives the cost of each value. Save with gh variable set CI_SHARDS_STORES --body '<value>' |
CI_UNIT_MAX_WORKERS | variable | vitest workers per unit shard in pr.yml. Unset, 8, which fits a 16-core runner. Set 3 with linux-arm64-4core. | pr.yml | A setting. Change it with gh variable set, and the next pull request run reads it. tools/scripts/github-ci-secrets.md gives the cost of each value. Save with gh variable set CI_UNIT_MAX_WORKERS --body '<value>' |
NPM_TOKEN | secret | npm token npm.yml publishes @oxagen/cli with, after every production deploy and every release tag. It expires within 90 days. | npm.yml | On npmjs.com, signed in as the account that owns @oxagen, open Access Tokens and generate a granular token with read and write on @oxagen/cli and the longest expiry npm allows (90 days). If the account requires two-factor authentication for writes, let the token bypass it. Save it with gh secret set NPM_TOKEN, which reads the value from a prompt. Dispatch npm.yml with no inputs, or wait for the next deploy, and check its run publishes or reports the version already on npm. Then delete the old token. Mac rotates it on a scheduled routine.Save with gh secret set NPM_TOKEN |
OXAGEN_CI_DEPLOY_KEY | secret | Private half of a deploy key with write access on oxageninc/oxagen-ci. oxagen-ci-mirror.yml pushes tools/oxagen-ci there with it. Unset, the job ends with a notice and mirrors nothing. | oxagen-ci-mirror.yml | Run ssh-keygen -t ed25519 -N '' -f oxagen-ci-deploy. Add oxagen-ci-deploy.pub as a deploy key with write access under oxageninc/oxagen-ci Settings, Deploy keys. Save the private key with gh secret set OXAGEN_CI_DEPLOY_KEY < oxagen-ci-deploy, dispatch oxagen-ci mirror, and check its run pushes. Then delete the old deploy key and both local files.Save with gh secret set OXAGEN_CI_DEPLOY_KEY |
OXAGEN_LLM_BALANCED | variable | Model release.yml writes release notes with. Unset, the script uses the registry's balanced tier. | release.yml | A gateway model id. Change it to move release notes to another model. Save with gh variable set OXAGEN_LLM_BALANCED --body '<value>' |
PREVIEW_DATABASE_URL | secret | Postgres URL db-migrate.yml applies migrations to when dispatched with target preview. | db-migrate.yml | Compose it from the preview database's endpoint, user, and password. Rotate the password on the database first, then save the new URL here. Save with gh secret set PREVIEW_DATABASE_URL |
RELEASE_TOKEN | secret | Fine-grained personal access token for oxageninc/product. Both jobs in release.yml check out with it, push the release branch and tags with it, and open the release pull request with it. A push with GITHUB_TOKEN starts no workflow, so the release would not deploy. A token scoped to any other repository, such as the old macanderson/oxagen, fails checkout with a 403 and stops every release (#5127). | release.yml | At github.com/settings/personal-access-tokens, create a fine-grained token with oxageninc as the resource owner and access to the oxageninc/product repository only. Set contents, pull requests, and workflows to read and write. If the oxageninc organization asks to approve the token, approve it. Give it an expiry and replace it before that date. Save it with gh secret set RELEASE_TOKEN --repo oxageninc/product, then run Release with dry_run off and check that the release pull request opens.Save with gh secret set RELEASE_TOKEN |
TAURI_SIGNING_PRIVATE_KEY | secret | Minisign private key desktop.yml locks updater artifacts with. Installed apps check updates against the matching public key in apps/desktop/src-tauri/tauri.conf.json. | desktop.yml | Rotate only on a leak. A new key needs a release, locked with the old key, that ships the new public key first, or installed apps reject every later update. Generate the pair, put the public key in tauri.conf.json, and save the private key here and at /oxagen/operator/TAURI_SIGNING_PRIVATE_KEY.pnpm --filter @oxagen/desktop exec tauri signer generate -w ~/.tauri/oxagen-desktop.keySave with gh secret set TAURI_SIGNING_PRIVATE_KEY |
TAURI_SIGNING_PRIVATE_KEY_PASSWORD | secret | Password of TAURI_SIGNING_PRIVATE_KEY. The key has none, so the secret holds the empty string. | desktop.yml | Changes only with TAURI_SIGNING_PRIVATE_KEY. Keep it empty unless the new key has a password. Save with gh secret set TAURI_SIGNING_PRIVATE_KEY_PASSWORD |
Values no store holds
No parameter holds these: each one is a literal in registry.ts, or the shell sets it for one run.
| Variable | Value source | Description |
|---|---|---|
ADMIN_DATABASE_URL | Shell or script | Superuser Postgres connection used by provision-rls-role.ts to create the least-privilege app role. Kept separate from DATABASE_URL so the provisioning step cannot silently run through the restricted connection it is about to create. |
ANTHROPIC_API_KEY | Shell or script | CLI-only BYOK fallback: when no AI_GATEWAY_API_KEY exists anywhere, the CLI runs anthropic/* models directly against the Anthropic API with this key (other vendors and embeddings stay unavailable). The gateway key always wins when both are set. Never read by deployed services, because platform AI is gateway-only. |
APP_URL | Registry static value | Server-side app origin used to build plugin OAuth authorize/callback URLs (falls back to NEXT_PUBLIC_APP_URL). Not browser-exposed. |
AURORA_ENDPOINT | Shell or script | Aurora writer endpoint for run-db-migrations.sh. Set it to skip the AWS lookup the script otherwise does. |
AURORA_PORT | Shell or script | Port for AURORA_ENDPOINT. Defaults to 5432. |
BETTER_AUTH_TRUSTED_ORIGINS | Registry static value | Comma-separated origins allowed cross-origin access to the auth API. |
BETTER_AUTH_URL | Registry static value | Auth base URL (the app origin). |
BLOG_DRAFTS | Shell or script | Set to 1 to include draft posts when building the static research blog (apps/web/scripts/build.mjs). Unset in every deploy, so drafts never ship. |
CI_SUPERSEDED_THRESHOLD | Shell or script | How many superseded CI runs in a row make check-superseded-runs.mjs report a pull request, when the script is run by hand. Unset or below 2 reads as 3. |
CLICKHOUSE_DATABASE | Registry static value | ClickHouse database name. |
CONTEXT_GRAPH_PROTOCOL_DIR | Shell or script | Path to a local context-graph-protocol checkout. check-contextgraph-fixtures.ts verifies the vendored profile against it when set. |
CURSOR_CONFIG_DIR | Shell or script | Overrides where the recorder host writes Cursor's `hooks.json` and `mcp.json`. Read on the operator's machine, not the server, and never a deployment value: it exists because Cursor can be installed against a non-default config directory, and enrolling the wrong one leaves the session unwrapped and silently unrecorded. |
DATA_NODE_NAME | Shell or script | Name tag of the data-plane EC2 instance the DB-client tunnel scripts target. Defaults to oxagen-data. |
DB_LINT_BASE_REF | Shell or script | The ref `pnpm db:lint-migrations` compares new Atlas migrations against for its git-aware ordering check (#3387): a migration added since the merge base with this ref must sort after every migration already there. Defaults to origin/main. |
DB_LINT_HEAD_REF | Shell or script | The ref `pnpm db:lint-migrations` treats as the branch's own tip for its git-aware ordering check (#3387). CI's pull_request checkout puts HEAD on GitHub's synthetic merge commit, not the PR branch itself, which collapses the merge-base fail/warn distinction into one tier. No workflow sets it today. Set it to the pull request's head commit to compare against the real PR head on such a checkout. Defaults to HEAD, which is correct everywhere else (a push checkout, a local branch). |
DB_MIGRATE_STORES | Shell or script | Comma-separated stores `pnpm db:migrate` should migrate. Defaults to clickhouse,neo4j. Postgres is Atlas's job and is deliberately not in the list. |
DEFAULT_BRANCH | Shell or script | The repository's default branch. rerun-lost-runner.mjs reruns a lost job on this branch even after newer commits land. rerun-lost-runner.yml sets it from the event's repository. Defaults to main. |
DEPLOY_SERVICE | Shell or script | The service a deploy record names. check-deploy-tip.mjs reads it to find what is live for that service and to record what shipped (ADR-164). desktop.yml sets it to desktop on the step that records the installers' commit. |
DO_NOT_TRACK | Shell or script | Cross-tool opt-out convention (https://consoledonottrack.com): set to '1' to disable CLI usage telemetry. Checked before OXAGEN_TELEMETRY and the persisted telemetry.enabled config. |
DRY_RUN | Shell or script | Set to 1 to make check-superseded-runs.mjs print what it would post instead of posting it, when the script is run by hand. |
E2E_TEST | Shell or script | The exact string "true" on the e2e webServer (apps/app/playwright.config.ts) and the e2e seed (apps/app seed:e2e): packages/auth relaxes email verification and rate limiting on that value, only when VERCEL is unset and BETTER_AUTH_URL is a loopback origin (local-env.ts), so a leaked value on a deployed host relaxes nothing. Declared in turbo.json test:e2e env. Not for dev/preview/prod. NOTE: read via raw process.env, not in baseEnvSchema (test-only). |
EVENT_BUS_NAME | Shell or script | EventBridge bus the log-event-publisher Lambda puts events on. The stack sets it on the function; the handler refuses to import without it. |
FLEET_BUNDLE_PUBLIC_KEY_PEM | Shell or script | Pinned staging policy-bundle public key for the fleet load rig. |
FLEET_CLICKHOUSE_HOST | Shell or script | Independently pinned staging ClickHouse hostname for fleet reconciliation. |
FLEET_CLICKHOUSE_PASSWORD | Shell or script | Read-only staging ClickHouse credential for fleet reconciliation. |
FLEET_CLICKHOUSE_URL | Shell or script | Staging ClickHouse HTTPS endpoint for fleet reconciliation, without credentials. |
FLEET_CLICKHOUSE_USER | Shell or script | Read-only staging ClickHouse user for fleet reconciliation. |
FLEET_DATABASE_HOST | Shell or script | Independently pinned staging Postgres hostname for fleet reconciliation. |
FLEET_DATABASE_URL | Shell or script | Read-only staging Postgres connection string for fleet reconciliation. |
FLEET_OPERATOR_TOKEN | Shell or script | Staging operator credential used to enroll synthetic fleet hosts. |
FLEET_OUTPUT_ROOT | Shell or script | Existing private persistent runner directory for fleet reports and credentials. |
FLEET_STAGING_ORIGIN | Shell or script | Exact trusted HTTPS staging origin for the fleet load rig. |
GITLAB_PROJECT | Shell or script | The gitlab.com project, `group/project`, that `tools/scripts/gitlab-steering-exercise.ts` publishes its exercise record to. Use a scratch project: a run with --merge adds a file to its default branch. |
GITLAB_TOKEN | Shell or script | A gitlab.com project access token that `tools/scripts/gitlab-steering-exercise.ts` publishes one steering record with, as recorded evidence for #3762. Set it in the shell for one run only; the platform never reads it, and workspaces store their own tokens through attach_gitlab_project. |
HEAD_BRANCH | Shell or script | The head branch of the CI run check-superseded-runs.mjs reports on, when the script is run by hand. It finds the pull request from this and HEAD_REPO when PR_NUMBER is unset. |
HEAD_REPO | Shell or script | The head repository (owner/name) of the CI run check-superseded-runs.mjs reports on, when the script is run by hand. It finds the pull request from this and HEAD_BRANCH when PR_NUMBER is unset. |
INGESTION_CRYPTO_PROVIDER | Registry static value | Encryption backend for ingestion credentials and private Vercel Blob files: 'env' (AES-256-GCM via INGESTION_ENCRYPTION_KEY) or 'kms' (AWS KMS). Also read in-process by app and mcp: resolveGitHubToken's stored-OAuth-token path (packages/github/src/workspace-token.ts) decrypts through resolveIngestionCryptoAdapterForKeyId whenever it falls back off the installation-token path, and resolveWorkspaceGithubUserToken opens the stored token that backs the list_github_installations tool. |
INNGEST_DEV | Shell or script | Set to 1 to point the Inngest SDK at a local dev server instead of Inngest Cloud. tools/scripts/inngest-dev.ts sets it for every child turbo spawns. |
KNOWLEDGE_GRAPH_ENABLED | Registry static value | Feature flag. Set "false" to disable the Neo4j knowledge-graph writes. |
LINEAR_PROJECT_ID | Registry static value | Linear project id for the oxagen-v2 project (tooling-only). |
LOG_LEVEL | Registry static value | Pino log level for service loggers. |
MAIN_VERIFIED_COVER_MINUTES | Shell or script | How long check-main-verified.mjs treats a commit whose run a newer push replaced as pending while a later run is still going. Pushes to main share one concurrency group, so a commit can wait about two run lengths. Defaults to 180. |
MAIN_VERIFIED_GRACE_MINUTES | Shell or script | How long after a commit lands check-main-verified.mjs refuses to conclude it has no run. The workflow races the registration of the run it looks for. Defaults to 10. |
MAIN_VERIFIED_MAX_WAIT_MINUTES | Shell or script | Upper bound on how long check-main-verified.mjs sleeps waiting the grace out before re-reading. Must stay below the workflow job's timeout-minutes. Defaults to 12. |
MAIN_VERIFIED_WINDOW | Shell or script | How many recent commits on main check-main-verified.mjs asks about. Defaults to 10. |
MARKETING_URL | Registry static value | Public marketing website origin (oxagen.sh). The /v1/cms/* lead routes use it to build the emailed reader link and CORS allows it as a cross-origin caller. Not browser-exposed. |
MCP_PORT | Shell or script | HTTP port for the xmcp server. |
MCP_URL | Registry static value | MCP server origin used to build install instructions and client connections. |
NEO4J_DATABASE | Registry static value | Neo4j database. |
NEO4J_ORG_PROVISIONER | Registry static value | Graph provisioner for paid organisations (ADR-098): pooled (Community, dev, CI), cypher (self-managed Enterprise: CREATE DATABASE org-<namespace>), aura (not implemented; refused). |
NEXT_PUBLIC_API_URL | Registry static value | Public api origin (browser-exposed). The api and mcp read it too: the Inngest serve host, and the absolute download URL get_run_export mints. |
NEXT_PUBLIC_APP_URL | Registry static value | Public app origin (browser-exposed). |
NODE_ENV | Registry static value | Runtime mode. Next.js sets it itself at build and start. The Inngest verifier rejects test signing keys when this is production. |
NODE_NAME | Shell or script | Name tag of the EC2 instance the infra/tools scripts target. Defaults to oxagen-app. |
OAUTH_PROXY_PRODUCTION_URL | Registry static value | Official production origin the shared social-login OAuth app's callback is registered against (OAuth Proxy productionURL). Preview deployments relay social login through this origin. Defaults to the production app URL when unset. |
OXAGEN_ALLOW_STDIO_MCP | Shell or script | Set to '1' or 'true' to allow stdio-transport MCP servers to be SPAWNED as child processes from workspace file-mcp plugin configs (packages/agent file-mcp.ts). Spawning is OFF by default because a workspace-scoped config could otherwise execute arbitrary commands on the API host. Enable only for a trusted local/CLI runtime, never on shared server deployments. HTTP MCP transports are unaffected and always processed. |
OXAGEN_API_TOKEN | Shell or script | API token used by the CLI to authenticate requests; falls back to the value stored in ~/.oxagen/config.json. |
OXAGEN_API_URL | Registry static value | Base URL for the Oxagen REST API, consumed by the CLI. Falls back to the default production API URL when unset. |
OXAGEN_APP_URL | Registry static value | Base URL for the Oxagen web app, where `oxagen login` opens the browser authorize page. Falls back to the default production app URL when unset. |
OXAGEN_CLI_DEBUG | Shell or script | Set to 1 or true to write the CLI's debug log to ~/.oxagen/logs (apps/cli/src/lib/debug-log.ts). Developer tooling, never set on a deployed service. |
OXAGEN_DEBUG | Shell or script | When set, the CLI prints extra diagnostics (e.g. context-engine memory open failures) to stderr. |
OXAGEN_INSTALL_BASE | Shell or script | Base URL the published install.sh downloads the oxagen-<rust triple> executable and its .sha256 from. Set it to install a pinned version, such as https://downloads.oxagen.sh/desktop/<version>. |
OXAGEN_INSTALL_DIR | Shell or script | Directory install.sh puts the oxagen binary in. Defaults to ~/.local/bin. |
OXAGEN_LLM_BALANCED | Registry static value | Balanced model: the gateway model id Oxagen's own calls run on when they ask for the balanced tier, and a call that names no model. A stella turn's own model comes from the organization's model tiers (#7197). |
OXAGEN_LLM_BATCH | Registry static value | Batch model: the OpenRouter model id bulk triage sends through OpenRouter's batch API when the platform provider is OpenRouter. Its provider must take OpenRouter batches (ADR-309). |
OXAGEN_LLM_FAST | Registry static value | Fast model: the gateway model id Oxagen's own quick calls run on, such as conversation titles, drafts and triage, and a stella turn's summaries and verdicts. A stella turn's own model comes from the organization's model tiers (#7197). |
OXAGEN_LLM_PRECISE | Registry static value | Precise model: the gateway model id Oxagen's own calls run on when they ask for the precise tier, such as schema chat. A stella turn's own model comes from the organization's model tiers (#7197). |
OXAGEN_LLM_SUMMARY | Registry static value | Summary model: the gateway model id run accounts (run names and summaries) are written on when Oxagen pays. A customer's own key keeps its fast tier. |
OXAGEN_LOCAL_DEV | Shell or script | Set to "1" by tools/scripts/dev.ts for the local dev stack. Consumed by packages/auth to make local-env detection deterministic instead of racing NODE_ENV at module-load time. Believed only when VERCEL is unset and BETTER_AUTH_URL is a loopback origin (local-env.ts), so it relaxes nothing on a deployed host. NOTE: read via raw process.env, not in baseEnvSchema (dev-tooling only). |
OXAGEN_MODEL_PROVIDER | Registry static value | Which provider serves language models: 'openrouter' in preview and production, on OPENROUTER_API_KEY, and the Vercel AI Gateway in local development. Never an automatic fallback: a silent failover would move spend to another vendor's bill. Embeddings use Voyage either way. The per-organisation keys ADR-131 mints are OpenRouter keys, so they are minted and consulted only when this is 'openrouter' (ADR-131 §9). |
OXAGEN_ORG_ID | Shell or script | Default org slug for CLI commands; falls back to the value stored in ~/.oxagen/config.json. |
OXAGEN_REGION | Registry static value | The region this process answers from, printed beside the trace id on a page's error line (#3841). Every deployed node runs in us-east-1, and the node manifest (tools/scripts/package-for-node.sh) sets it too. Unset locally, where the page says the region was not recorded. |
OXAGEN_TELEMETRY | Shell or script | Set to '0' to disable CLI usage telemetry for this invocation (equivalent to `oxagen telemetry off`). DO_NOT_TRACK=1 also disables it and takes precedence. |
OXAGEN_WORKSPACE | Shell or script | Workspace slug that `oxagen sandbox` and `oxagen credentials` address when --workspace-slug is absent. The CLI never infers it from a repository. |
OXAGEN_WORKSPACE_ID | Shell or script | Default workspace slug for CLI commands; falls back to the value stored in ~/.oxagen/config.json. |
PGSUPERPASS | Shell or script | Password for PGSUPERUSER. |
PGSUPERUSER | Shell or script | Superuser on the cluster tools/scripts/rds-sim-check.sh simulates RDS against. The script refuses to run without it. |
PLATFORM_VERSION | Shell or script | Platform version string surfaced by @oxagen/config platformVersion(). Nothing sets it in production today: the release script's sync went with the Vercel deploy, and Parameter Store does not hold it, so platformVersion() falls back to "0.0.0". Declared in turbo.json globalEnv so a version change busts the build cache. Read via raw process.env and absent from baseEnvSchema on purpose: it is a release tag, not a service setting. |
POLLS | Shell or script | Number of five-second polls install-node-scripts.sh waits for its remote command. Defaults to 150. |
PR_CHANGED_FILES | Shell or script | How many files the pull request a CI run tests changes, from the pull_request event. ci-pr-scope.mjs checks that it read every file before it calls a pull request docs-only (#4918). |
PR_DRAFT | Shell or script | Whether the pull request a CI run tests is a draft (true or false). pipeline.yml sets it on the preflight job, and ci-pr-scope.mjs runs only the light lanes for a draft (#4918). |
PR_NUMBER | Shell or script | The pull request number. pr.yml's records-lint job sets it, and check-adr-index.mjs reads it there. new-adr.mjs reads it to number a new ADR, and check-superseded-runs.mjs reads it as the pull request to report on when the script is run by hand. |
PRIVACY_ERASURE_GRACE_DAYS | Registry static value | Grace period in days before a hard-delete erasure job runs (GDPR Art.17). Defaults to 30 when unset. Set to 0 for immediate erasure in test envs. |
PRODUCTION_DATABASE_URL | Shell or script | Migration connection for Atlas's `prod` env (packages/database/atlas.hcl), read by db-migrate.yml and no other workflow. Holds a role that may run DDL against pre-existing schemas: the app role may only CREATE in schemas it owns, so migrating through DATABASE_URL fails 42501 on billing and friends. |
RERUN_RUN_ID | Shell or script | The failed CI run that rerun-lost-runner.mjs checks for jobs whose runner was lost. rerun-lost-runner.yml sets it from the workflow_run event, or from the run_id input on a manual dispatch. |
SCR_OWNER | Shell or script | GitHub owner to read all five SCR corpus repos under, for a fork or a test organization. Unset, the check reads each repo where it lives. |
SMTP_FROM_EMAIL | Registry static value | Default sender address. Its domain must be verified at the provider. |
SMTP_FROM_NAME | Registry static value | Default sender display name. |
SMTP_HOST | Registry static value | SMTP server host (Resend: smtp.resend.com). |
SMTP_PORT | Registry static value | SMTP port. 465 = implicit TLS; 587 = STARTTLS (TLS enforced). |
SMTP_USERNAME | Registry static value | SMTP username (Resend: the literal "resend"). |
SOURCE_COMMIT | Shell or script | The commit a manual app deploy ships, from the dispatch's source_commit input. check-deploy-tip.mjs --schema reads it in place of GITHUB_SHA, which is main's head on a dispatch, to refuse code older than production's schema (#5247). |
STALE_MERGE_BASE_REF | Shell or script | Ref the stale-merge-base check (#3237) treats as main's current tip. Defaults to origin/main. |
STALE_MERGE_BRANCH_REF | Shell or script | Ref the stale-merge-base check (#3237) treats as the branch under review. Defaults to HEAD. |
STANDALONE | Shell or script | Set to 1 to build apps/app or apps/docs with Next's standalone output. tools/scripts/package-for-node.sh sets it for the self-hosted node bundle. Unset, Next.js writes its default output. |
STELLA_SERVE_URL | Registry static value | Where the Stella engine (stella-serve) listens. The in-app agent's turns run there; every model call and tool call comes back to this process to answer (ADR-053). Loopback on the node. |
STRIPE_E2E | Shell or script | Whether the e2e job resolved a Stripe test key: "1" when STRIPE_TEST_SECRET_KEY was mapped into STRIPE_SECRET_KEY, "0" on a fork pull request without one (pay.spec.ts skips). Set by the e2e webServer env (apps/app/playwright.config.ts) and the CI job (WL-48). NOTE: read via raw process.env, not in baseEnvSchema (test-only). |
TACHO_LOCAL_TOKEN | Shell or script | The per-install bearer the recorder collector's loopback listener requires. Written into each wrapped harness's settings and into a connected app's MCP config by `oxagen agent enroll`, and read back by the hook and the `oxagen mcp-stdio` shim. Never set by hand and never a deployment value: it is minted per machine at enrollment and lives in host.json. |
VISION_GATE_BASE | Shell or script | Ref the vision gate diffs against. Defaults to origin/main. |
VISION_GATE_MODEL | Shell or script | Model the vision gate judges a diff with. |
VISION_GATE_STRICT | Shell or script | Set to 1 to make a drifts verdict fail the vision gate instead of only printing it. |
WEB_PORT | Shell or script | Port for the apps/web static dev server (apps/web/scripts/dev.mjs). Defaults to 5500; local convenience only, never read by a deploy. |
WRITE_MANIFEST_IMAGE | Shell or script | Container image the packaged node bundle's run manifest names. Defaults to node:24.21.0-alpine. |
XDG_CONFIG_HOME | Shell or script | The XDG base directory the recorder host falls back to when locating Cursor's config on Linux, after CURSOR_CONFIG_DIR and before ~/.cursor. Set by the operator's own environment rather than by Oxagen, and ignored on macOS and Windows, which do not follow the XDG layout. |
Decisions
The architecture decision records. ADR-001 to ADR-016 are grouped by the epic that produced them. Every later record is listed under Unfiled, because the README index stopped growing and ADRs numbered by pull request (ADR-5864) never enter it.
577 records under docs/adr. ADRs are immutable once accepted; a change of mind is a new ADR that supersedes the old one, which is why superseded entries stay listed.
Foundations
| # | Title | Status | Date |
|---|---|---|---|
| ADR-001 | — Drizzle as Postgres ORM | Accepted | 2026-05-27 |
| ADR-002 | — Inngest as job orchestration | Accepted | 2026-05-27 |
| ADR-003 | — Neo4j as vector store | Accepted | 2026-05-27 |
| ADR-004 | — Environment variables, not Google Secret Manager | Superseded by ADR-240 | 2026-05-28 |
| ADR-005 | — Single-version monorepo via Changesets | Accepted | 2026-05-27 |
| ADR-006 | — Better Auth bound to canonical `auth.users` | Accepted | 2026-05-27 |
Agent Runtime
| # | Title | Status | Date |
|---|---|---|---|
| ADR-007 | — Docker as vendor-neutral code sandbox | Accepted | 2026-05-28 |
| ADR-008 | — Skills as filesystem-first with DB augmentation | Accepted | 2026-05-28 |
| ADR-009 | — Unified capability/tool model via `surfaces` | Accepted | 2026-05-28 |
| ADR-010 | — Subagent fanout via Inngest invoke | Accepted | 2026-05-28 |
| ADR-011 | — Vercel Sandbox driver for Vercel Functions | Accepted | 2026-05-31 |
Marketplace
| # | Title | Status | Date |
|---|---|---|---|
| ADR-012 | — Connector dual-write pattern: Postgres (durability) + Neo4j (index) | Accepted | 2026-06-09 |
| ADR-013 | — Oxagen Plugins: first-party capability packs as a fourth plugin type | Accepted | 2026-06-12 |
| ADR-014 | — Workspace-scoped MCP registries with a single-default state machine | Accepted | 2026-06-17 |
Developer workflow
| # | Title | Status | Date |
|---|---|---|---|
| ADR-015 | — Graph-edge-driven git hooks (Vitest import-graph) + Biome formatting | Superseded in part | 2026-06-21 |
CLI & Local Agent Runtime
| # | Title | Status | Date |
|---|---|---|---|
| ADR-016 | — Oxagen CLI daemon: a live code-graph memory fed by coding-agent hooks | Proposed | 2026-06-24 |
Unfiled
| # | Title | Status | Date |
|---|---|---|---|
| ADR-017 | — OpenTelemetry Distributed Tracing | Accepted | 2026-06-26 |
| ADR-018 | CLI ↔ Workspace Graph Bidirectional Sync | Superseded | 2026-06-27 |
| ADR-019 | Unified agent engine — one brain across CLI and platform | Accepted | 2026-06-27 |
| ADR-020 | Per-workspace GitHub write credentials | Accepted | 2026-06-28 |
| ADR-021 | Inference doctrine — deterministic-first, cache-aligned, structured-tool agentic coding | Proposed | 2026-07-06 |
| ADR-022 | Capability & tool naming standard | Accepted | 2026-07-06 |
| ADR-023 | — CLI fleet: sessions as append-only event logs, views as renderers | Accepted | 2026-07-06 |
| ADR-024 | — Namespaced, immutable agent identity (`org_ns.workspace_ns.agent_slug`) | Accepted | 2026-07-07 |
| ADR-025 | Verb-first snake_case capability naming | Accepted | 2026-07-08 |
| ADR-026 | — Mobile feature parity is law, enforced by a manifest gate | Accepted | 2026-07-08 |
| ADR-027 | Multi-tenant GitHub App connect (identity leg + installation registry) | Accepted | 2026-07-09 |
| ADR-028 | — Time-travel replay: deterministic session records, bisect, resume, and failure→eval distillation | Accepted | 2026-07-11 |
| ADR-029 | The mutation verifier gate — every green turn must prove its tests catch the fix | Accepted | 2026-07-10 |
| ADR-030 | Speculative tool execution — prefetch the model's next reads while it thinks | Accepted | 2026-07-11 |
| ADR-031 | Platform Storage Ontology — a drift-aware, machine-readable self-model of the platform's storage layer | Accepted | 2026-07-13 |
| ADR-032 | — Unified chat session state (chat_ux_v2) | Accepted | 2026-07-14 |
| ADR-033 | Adopt the Stella Rust engine as the platform agent core | Proposed | 2026-07-18 |
| ADR-034 | Customer-built capability packages (`.cap`) | Proposed | 2026-07-18 |
| ADR-035 | Consume the Context Graph Protocol directly via pinned conformance fixtures | Accepted | 2026-07-22 |
| ADR-036 | Adopt the official CGP TypeScript SDK as the canonical type source | Accepted | 2026-07-23 |
| ADR-037 | A test double must fail when the thing it doubles moves | Accepted | 2026-08-24 |
| ADR-038 | Adopt org standing decisions as a Steering Context Record corpus | Accepted | 2026-09-22 |
| ADR-039 | Centralize SCR enforcement in oxagen rather than replicating it | Accepted | 2026-10-02 |
| ADR-040 | Refocus Oxagen as an engine-agnostic governance plane | Accepted | 2026-08-29 |
| ADR-041 | Canonical JSON — one rule, not one implementation | Accepted | 2026-09-06 |
| ADR-042 | Organisation-scoped data planes — every store switches at the tenant | Accepted | 2026-09-07 |
| ADR-043 | Excise the agent runtime — Oxagen governs agents, it does not run them | Accepted | 2026-09-18 |
| ADR-044 | Every field of a memory record has a merge rule | Accepted | 2026-09-07 |
| ADR-045 | Cross-repo reusable workflows are pinned to a commit | Accepted | 2026-09-07 |
| ADR-046 | A push to main gets its own CI concurrency group | Superseded by ADR-287 | 2026-10-02 |
| ADR-047 | No provider-posture matrix; handle divergence at the gateway | Accepted | 2026-09-07 |
| ADR-048 | One path glob, in a package with no dependencies | Accepted | 2026-09-07 |
| ADR-049 | The DoD recheck re-runs the old run rather than reporting a new check | Accepted | 2026-09-07 |
| ADR-050 | Privileged secret access is recorded in the main audit log, not only beside it | Accepted | 2026-09-07 |
| ADR-051 | A workspace's context records enter the turn as volatile policy, not as prefix | Superseded by ADR-043 | 2026-09-18 |
| ADR-052 | The governed action is the billable unit; tokens are reported, never billed | Accepted | 2026-10-02 |
| ADR-053 | The in-app agent runs on Stella's headless engine, and a token is billed only when Oxagen paid for it | Accepted | 2026-10-13 |
| ADR-054 | The migration connection carries the RLS bypass; the policy is not changed | Accepted | 2026-09-11 |
| ADR-055 | Subscriptions carry monthly buckets of governed action units, bought in unit quantities at a per-customer contracted rate | Accepted | 2026-11-03 |
| ADR-056 | Run control connection points and the model-proxy decision | Accepted | 2026-09-15 |
| ADR-057 | Agents: the definition of record, budgets in micros, enrollment | Accepted | 2026-09-14 |
| ADR-058 | Run record placement, retention default and `digest_only` | Accepted | 2026-10-07 |
| ADR-059 | Mandates: consequence roles, the decision seam and the ledger | Accepted | 2026-09-14 |
| ADR-060 | Spend: the price book as data, the rollup store, budgets in micros | Accepted | 2026-09-14 |
| ADR-061 | Steering: governance mode, thresholds, the reflector | Accepted | 2026-09-15 |
| ADR-062 | Findings: providers, fix application, the counterfactual rule | Accepted | 2026-09-15 |
| ADR-063 | Organization: the permission catalogue | Accepted | 2026-09-15 |
| ADR-065 | Onboarding: gate shape, installer path, provisional workspace | Accepted | 2026-09-15 |
| ADR-066 | Oxagen has two names, the agent control plane and agent fleet management, and the agent asks for the keys | Accepted | 2026-09-15 |
| ADR-067 | Mission Control leads, the agent control plane is the category, and every claim states its scope | Accepted | 2026-09-15 |
| ADR-068 | One org-only workspace sentinel, shared by every surface | Accepted | 2026-09-15 |
| ADR-069 | Roles are editable on every tier | Accepted | 2026-09-15 |
| ADR-070 | Auto-approval rules: the policy matrix, the rule store, standing approvals | Accepted | 2026-09-16 |
| ADR-071 | A kill switch outlives its target — deleting what it names is refused | Accepted | 2026-09-16 |
| ADR-072 | Tools: classification vocabulary, assurance hosting, observed-schema source | Accepted | 2026-09-15 |
| ADR-073 | An API key names a workspace, and so does the page that mints it | Accepted | 2026-09-16 |
| ADR-074 | A read under the org-only workspace sentinel is checked against the policy manifest | Accepted | 2026-09-17 |
| ADR-075 | — One writer for the account preference row | Accepted | 2026-09-16 |
| ADR-076 | — A general run's spec states what the run did | Accepted | 2026-09-16 |
| ADR-077 | Attribution columns are `<verb>_by_id` | Accepted | 2026-09-15 |
| ADR-078 | Wrapped and connected are two enforcement tiers, and neither dominates the other | Accepted | 2026-09-18 |
| ADR-079 | An `oxagen login` key acts for its creator on Tacho host enrollment | Accepted | 2026-09-15 |
| ADR-080 | Stella is wrapped through its hooks until it speaks the Tacho contract natively | Accepted | 2026-09-15 |
| ADR-081 | The `app` layer is retired at the Mission Control cutover for every capability rev1 does not surface | Accepted | 2026-09-16 |
| ADR-082 | A rate limiter that cannot reach its counters degrades rather than denies | Accepted | 2026-09-17 |
| ADR-083 | One client-IP derivation, and the edge rewrites the header it is not allowed to trust | Accepted | 2026-09-17 |
| ADR-084 | The person behind a Tacho session is a principal Oxagen issues, and nothing derived from the reported address is stored | Accepted | 2026-09-17 |
| ADR-085 | A refunded or disputed GAU purchase withdraws what is left, and records what it could not recover | Accepted | 2026-09-17 |
| ADR-086 | An org-only read of a workspace-scoped table raises, and the static check retires | Accepted | 2026-09-17 |
| ADR-087 | The Neo4j tenancy seam constructs scoping rather than validating it | Proposed | 2026-09-17 |
| ADR-088 | A credential follows the service that reads it, and `apps/app` reads the GitHub App's private key | Accepted | 2026-09-18 |
| ADR-089 | An on-demand read lives in a `"use server"` module, beside the write | Accepted | 2026-09-17 |
| ADR-090 | Oxagen governs skill resolution, and the 2026-09-15 narrowing is reversed | Accepted | 2026-09-15 |
| ADR-091 | One record steers one agent — steering rides the bundle's `context.system` | Accepted | 2026-09-18 |
| ADR-092 | An abandoned assistant turn is owned to completion, not cancelled | Accepted | 2026-09-18 |
| ADR-093 | One assembler decides what reaches the agent, and records what it cut | Accepted | 2026-09-25 |
| ADR-094 | tachod grows into the gateway: a loopback model proxy and an MCP aggregator | Accepted | 2026-09-18 |
| ADR-095 | The tier ladder is four words, computed from what was routed | Accepted | 2026-09-18 |
| ADR-096 | Oxagen may contain the process that runs turns: the contained tier | Accepted | 2026-10-02 |
| ADR-097 | Steering and gating are two planes, authored on one surface and compiled twice | Accepted | 2026-09-18 |
| ADR-098 | Organisation graphs are placed by one provisioning interface, and pooled is the default | Accepted | 2026-09-18 |
| ADR-099 | A workspace is born with its main repository, and a repository is main for at most one workspace | Accepted | 2026-10-03 |
| ADR-100 | Frame bodies are captured by default, redacted where they are produced, capped, and released by retention | Accepted | 2026-09-18 |
| ADR-101 | Claude Code, Codex, Cursor and Stella are the four first-class harnesses | Accepted | 2026-09-18 |
| ADR-102 | A limit change merges under the mandate's row lock, and replacement stays for callers that hold the record | Accepted | 2026-09-19 |
| ADR-103 | The price book records its own initialization | Accepted | 2026-09-19 |
| ADR-104 | A harness label round-trips whatever it holds | Accepted | 2026-09-19 |
| ADR-105 | An archived workspace accepts no machine credential | Accepted | 2026-09-19 |
| ADR-106 | Retirement revokes what it scoped, rather than refusing while it exists | Accepted | 2026-09-19 |
| ADR-107 | `list_mandates` and `get_mandate` admit the roles `request_mandate` admits | Accepted | — |
| ADR-108 | A mandate limit carries its own measure kind, worked out once at write time | Accepted | 2026-09-19 |
| ADR-109 | A resolved approval is read back through a sibling capability, not the security event stream | Accepted | — |
| ADR-110 | Review main integrations and report stale-base overlap | Accepted | 2026-09-19 |
| ADR-111 | An amount measure's unit is refused at declaration, not widened at `Money` | Accepted | 2026-09-19 |
| ADR-112 | The two §2.1 renames land on the surfaces, behind aliases, in phases | Accepted | 2026-09-19 |
| ADR-113 | Workforce management leads, and Mission Control is retired as a product name | Accepted | 2026-09-19 |
| ADR-114 | One version across every manifest, and a publish flow that runs from a laptop | Accepted | 2026-09-19 |
| ADR-115 | `resolve_approval` is the one billed action of the approvals surface | Accepted | 2026-09-19 |
| ADR-116 | ClickHouse reads scope the source and migrations share a lock | Accepted | 2026-09-20 |
| ADR-117 | Bound GitHub retries and use managed graph transactions | Proposed | — |
| ADR-118 | Approved built-in calls resume once | Accepted | 2026-09-19 |
| ADR-119 | Tool changes invalidate approval rules | Accepted | 2026-09-19 |
| ADR-120 | Shared organization rows require organization scope to write | Accepted | 2026-09-19 |
| ADR-121 | Preserve GitHub record identity across repositories | Accepted | 2026-09-19 |
| ADR-122 | External MCP calls enter the decision-rules gate | Accepted | 2026-09-19 |
| ADR-123 | Production migrations run platform seeds | Accepted | 2026-09-19 |
| ADR-125 | Audit partition maintenance and telemetry boundaries | Accepted | — |
| ADR-126 | Keep frame bodies in the WAL and record bounded redaction details | Accepted | 2026-09-25 |
| ADR-127 | Keep sealed events when body storage fails | Accepted | 2026-09-25 |
| ADR-128 | Source identifiers determine draft filenames | Accepted | 2026-09-19 |
| ADR-130 | Spend and operator feedback lead the app | Superseded | 2026-09-20 |
| ADR-131 | One OpenRouter key per organisation, and funding is decided with the model | Accepted | 2026-09-20 |
| ADR-132 | The mockup's CSS is the app's design of record | Superseded | 2026-09-20 |
| ADR-133 | The governance mode in force decides how it may be changed | Accepted | 2026-09-21 |
| ADR-134 | Durable AI usage settlement | Accepted | — |
| ADR-135 | Rev1 console scope and cutover evidence | Accepted | 2026-09-20 |
| ADR-136 | Clone and retire immutable configuration identities | Accepted | 2026-09-20 |
| ADR-137 | Standing decisions are workspace context records, stored once | Accepted | 2026-09-22 |
| ADR-138 | An external tool's identity is case-folded at the decision gate | Accepted | 2026-09-22 |
| ADR-139 | One store for a run's content on the host | Accepted | 2026-09-22 |
| ADR-140 | One tool call seals one frame, sealed by the source that reports it first | Accepted | 2026-09-25 |
| ADR-141 | What counts as an installed Cursor, and where a Cursor steer lands | Accepted | 2026-09-25 |
| ADR-142 | Cost-center chargeback on Spend | Accepted | 2026-09-22 |
| ADR-143 | The gateway brokers the vendor credential: a wrapped harness holds a run token | Accepted | 2026-10-07 |
| ADR-144 | The assembler has its own package, and the two memory packages are deleted | Accepted | 2026-09-22 |
| ADR-145 | Enterprise SSO behind Better Auth | Accepted | 2026-09-22 |
| ADR-147 | A merge queue runs the full gate before a PR lands on main | Accepted | 2026-09-23 |
| ADR-149 | Independent model policy | Accepted | 2026-09-22 |
| ADR-150 | Isolated staging before production | Accepted | 2026-09-23 |
| ADR-151 | Git custody keeps installation tokens in the host proxy | Accepted | 2026-09-23 |
| ADR-152 | The contained launcher measures a Docker container, and the server decides the tier | Accepted | 2026-09-23 |
| ADR-153 | Automatic run accounts use Stella | Accepted | 2026-09-23 |
| ADR-154 | Restore the marketing ebook lead gate | Accepted | 2026-09-19 |
| ADR-155 | The book has one manuscript, and its editions and migration are generated | Accepted | 2026-09-19 |
| ADR-156 | Website leads sync to Attio after the row commits, with the outcome on the row | Superseded | 2026-10-26 |
| ADR-157 | Local ARP checkpoints prepare external runs | Accepted | 2026-09-19 |
| ADR-158 | Every production deploy publishes the desktop installers | Accepted | 2026-10-01 |
| ADR-159 | A run is costed while it runs, and the control plane closes a silent session | Accepted | 2026-09-24 |
| ADR-160 | An agent's day is a UTC calendar day | Proposed | 2026-09-24 |
| ADR-161 | Backfilled runs are rebuilt from local transcripts and claim no governance | Accepted | 2026-09-23 |
| ADR-162 | A run resolves an issue when dispatch, PR link and merge agree | Accepted | 2026-09-23 |
| ADR-163 | Operator controls do not depend on the policy tier | Accepted | 2026-10-07 |
| ADR-164 | Every green commit ships unless a newer one is already live | Accepted | 2026-09-24 |
| ADR-165 | Every billed governed action is a ledger row, wrapped tool calls bill, and statements and prepaid orders read from the ledger | Accepted | 2026-09-23 |
| ADR-166 | The Run page draws every panel of the mockup, and a figure the record lacks reads not recorded | Accepted | 2026-09-24 |
| ADR-167 | A record picker reads its options through the port | Accepted | 2026-09-24 |
| ADR-168 | A session and its subagents share one model-call ledger and one tool-call ledger | Accepted | 2026-09-24 |
| ADR-169 | An operator seals a run, and its agent is killed | Accepted | 2026-09-24 |
| ADR-170 | A panel header sits on a grey band, and the dark page is ink | Superseded | 2026-09-24 |
| ADR-171 | A chain break is reported beside a run's facts | Accepted | 2026-09-24 |
| ADR-172 | A host's seal reopens when the host starts the chain again | Accepted | 2026-09-24 |
| ADR-173 | An assistant run that stops recording is sealed abandoned | Accepted | 2026-09-25 |
| ADR-174 | The assistant summarises the messages its history window drops | Accepted | 2026-09-25 |
| ADR-175 | Approvals and consent requests are off the agent surface | Accepted | 2026-09-25 |
| ADR-176 | The flyout streams a turn over the API's chat stream | Accepted | 2026-09-25 |
| ADR-177 | A goal-shaped assistant turn is judged on another tier, and each verdict is on the run | Accepted | 2026-09-25 |
| ADR-178 | A context record is named by its label | Accepted | 2026-09-24 |
| ADR-179 | A re-enrolled host carries on its predecessor's sessions | Accepted | 2026-09-24 |
| ADR-180 | The control plane seals a silent ledger attempt abandoned | Accepted | 2026-09-24 |
| ADR-181 | ClickHouse on the app node keeps two system logs | Accepted | 2026-09-25 |
| ADR-182 | The server is the only place a run's transcript is folded | Accepted | 2026-09-25 |
| ADR-183 | Claude Code email addresses in ClickHouse and Postgres | Accepted | 2026-10-02 |
| ADR-184 | The context registry follows the production branch | Accepted | 2026-09-25 |
| ADR-185 | A failed WAL body write rolls back the seal | Accepted | 2026-09-25 |
| ADR-186 | Rule authoring is a capability that builds its goal on the server | Accepted | 2026-09-25 |
| ADR-187 | Two gateways carry every customer agent's traffic, and Oxagen holds the keys | Accepted | 2026-10-02 |
| ADR-188 | A reconciliation reports what the session changed | Accepted | 2026-09-25 |
| ADR-189 | A gateway call a hooked session makes seals one frame on that session's chain | Accepted | 2026-09-25 |
| ADR-190 | A failed WAL write leaves every file as it found it | Accepted | 2026-09-25 |
| ADR-191 | A wrapped run's turn steps are counted by the fold's rules in SQL | Accepted | 2026-09-25 |
| ADR-192 | Pull request state is stored per run and kept current by forge webhooks | Superseded by ADR-5994 | 2026-09-25 |
| ADR-193 | Paused and compacted are recorded facts beside run status | Accepted | 2026-09-25 |
| ADR-194 | Every embedding is voyage-4-large on one platform key | Accepted | 2026-09-26 |
| ADR-195 | A seal signs its run attestation when it is written | Accepted | 2026-09-26 |
| ADR-196 | A run's images are frame bodies in the evidence store | Accepted | 2026-09-26 |
| ADR-197 | A run stamps its own circumstances and reads the tracker on load | Accepted | 2026-09-26 |
| ADR-198 | An agent is one operator on one runtime with one harness | Accepted | 2026-10-02 |
| ADR-199 | Run steps are graded from recorded outcomes and set beside the agent's last 30 days | Accepted | 2026-09-26 |
| ADR-200 | The context window is recorded on the model-call frame | Accepted | 2026-09-26 |
| ADR-201 | A run's fit reading is computed from the record and its effort is read from the request | Accepted | 2026-09-26 |
| ADR-202 | The macOS desktop app installs updates without asking | Accepted | 2026-10-01 |
| ADR-203 | A machine holds one tacho enrollment per agent | Accepted | 2026-09-26 |
| ADR-204 | Containment is a setting of the runtime | Accepted | 2026-10-02 |
| ADR-205 | A run's reads cover every chain it recorded | Accepted | 2026-09-26 |
| ADR-206 | Memories wait in Oxagen and reach a repository by a memory PR | Accepted | 2026-10-02 |
| ADR-207 | CI runs its own turbo cache on S3 | Accepted | 2026-09-26 |
| ADR-208 | Unproductive spend counts each model-call frame once | Accepted | 2026-09-26 |
| ADR-209 | A migrated workspace's tool registry is written from its steering repo | Accepted | 2026-09-27 |
| ADR-210 | The findings pass reads frames for up to 200 runs and counts the rest | Proposed | 2026-09-27 |
| ADR-211 | Review refuses the HTTP+SSE transport | Accepted | 2026-09-27 |
| ADR-212 | A workspace links a code repository by a steering PR | Accepted | 2026-10-03 |
| ADR-213 | Merge without review is a grantable permission | Accepted | 2026-09-27 |
| ADR-214 | Server-built code graph copies hold symbols, chunks, and embeddings | Accepted | 2026-09-28 |
| ADR-215 | The production app moves to oxagen.app | Superseded | 2026-09-30 |
| ADR-216 | Generated files commit no value derived from the whole set | Accepted | 2026-09-28 |
| ADR-217 | A search-mode server ranks its tools by the workspace's embedding provider | Accepted | 2026-09-28 |
| ADR-218 | A pull request whose CI runs keep getting cancelled is reported | Accepted | 2026-09-28 |
| ADR-219 | An existing workspace imports its .oxagen/ steering by steering PRs | Accepted | 2026-09-28 |
| ADR-220 | The code graph builds on the operator's machine, and a workspace may name its embedding endpoint | Accepted | 2026-10-10 |
| ADR-221 | The app takes shadcn's base-maia style on Base UI | Accepted | 2026-09-28 |
| ADR-222 | The in-app assistant reads attached files | Proposed | 2026-09-28 |
| ADR-224 | Studio keeps a draft, and Review opens a steering PR for one server folder | Accepted | 2026-09-28 |
| ADR-225 | A private-network relay dials out to the MCP service and acts only on signed calls | Proposed | 2026-09-28 |
| ADR-226 | The v3 mockup and the brand kit are the design of record | Accepted | 2026-09-28 |
| ADR-227 | The shell frame owns the main landmark | Accepted | 2026-09-29 |
| ADR-228 | One GitHub App serves code and steering repositories | Accepted | 2026-09-29 |
| ADR-229 | Request admission and bounded run processing | Accepted | 2026-09-30 |
| ADR-230 | Enrollment names a versioned per-user copy of the sidecars | Accepted | 2026-09-30 |
| ADR-231 | tachod queues hooks per session and reads outside the queues | Accepted | 2026-09-30 |
| ADR-232 | A steering repository's governance mode changes through a steering PR | Accepted | 2026-09-30 |
| ADR-233 | A machine-run server is pinned before it first runs | Accepted | 2026-09-30 |
| ADR-234 | Served calls are recorded per tool for agent feedback | Accepted | 2026-09-30 |
| ADR-235 | Workspaces do not govern or monitor Stella | Accepted | 2026-10-01 |
| ADR-236 | The production app stays on oxagen.sh | Accepted | 2026-09-30 |
| ADR-237 | Steering repositories support GitHub Free | Accepted | 2026-10-01 |
| ADR-238 | Oxagen collects harness memories and recalls none of them | Accepted | 2026-09-30 |
| ADR-239 | The Neo4j memory import loses its adapters and its deprecated upload | Accepted | 2026-10-01 |
| ADR-240 | Parameter Store holds every secret and setting | Accepted | 2026-09-30 |
| ADR-241 | A new organization gets one grant of governed actions, then subscribes | Accepted | 2026-10-01 |
| ADR-242 | One model reply is one step, however many parts it arrives in | Accepted | 2026-10-01 |
| ADR-243 | A row of route tabs is a tab widget | Accepted | 2026-10-01 |
| ADR-244 | Phase 1 work records are facts, and the state is reduced from them | Accepted | 2026-10-01 |
| ADR-245 | A workspace's tool migration starts on provisioning and on request | Accepted | 2026-10-01 |
| ADR-246 | CI runs on ephemeral runners in our AWS account | Superseded | 2026-10-01 |
| ADR-247 | Every desktop release file is served from downloads.oxagen.sh | Accepted | 2026-10-01 |
| ADR-248 | Memories keep their rows and rank by use | Accepted | 2026-09-30 |
| ADR-249 | `oxagen memory` reads workspace memories | Accepted | 2026-10-01 |
| ADR-250 | Phase 1 work intake reads GitHub through the GitHub App, and triage cites a steering record | Accepted | 2026-10-02 |
| ADR-251 | A work order reaches its runtime on the command channel, and the runtime claims it | Accepted | 2026-10-02 |
| ADR-252 | A wrapped agent's pull request carries the Oxagen badge and label | Accepted | 2026-10-02 |
| ADR-253 | Every production deploy publishes the CLI to npm | Accepted | 2026-10-02 |
| ADR-254 | A contained run reaches GitHub through Git custody, and the operator holds no token | Accepted | 2026-10-02 |
| ADR-255 | The Work pages are walked in a real browser by a CI-only script outside the e2e suite | Accepted | 2026-10-02 |
| ADR-256 | A model call the gateway does not forward seals an error frame | Accepted | 2026-10-02 |
| ADR-260 | Ingest stores the collector's signed checkpoints it can verify | Accepted | 2026-10-02 |
| ADR-261 | The WAL drops a stalled session's bodies past a ceiling | Accepted | 2026-10-02 |
| ADR-262 | A Codex rollout seals one llm_call per completed response | Accepted | 2026-10-02 |
| ADR-263 | Code repository findings are stored when the check runs | Accepted | 2026-10-02 |
| ADR-264 | Issue creators file issues complete, and the triage guard is retired | Accepted | 2026-10-02 |
| ADR-265 | Every steering PR Oxagen opens carries a proposal row | Accepted | 2026-10-02 |
| ADR-266 | Enrollment proposes the runtime's agent file | Accepted | 2026-10-15 |
| ADR-267 | A steering PR approval is stored in Oxagen | Accepted | 2026-10-02 |
| ADR-277 | Per-turn budgets for the in-app assistant are deleted | Accepted | 2026-10-02 |
| ADR-278 | A steering PR may change a server's lock when Oxagen wrote it | Accepted | 2026-10-02 |
| ADR-286 | The Phase 1 pilot is measured from the work records, and a person decides it | Accepted | 2026-10-02 |
| ADR-287 | Pushes to main share one CI concurrency group | Accepted | 2026-10-02 |
| ADR-288 | Pull requests and their diffs are stored in the forge schema and S3 | Accepted | 2026-10-03 |
| ADR-289 | Oxagen may operate the compute a contained process runs on, and bills it by the running hour | Accepted | 2026-10-08 |
| ADR-292 | Every pull request read comes from the forge store | Accepted | 2026-10-03 |
| ADR-293 | Any workspace may link any repository its installation can see | Accepted | 2026-10-03 |
| ADR-295 | ClickHouse and Postgres run in ClickHouse Cloud | Accepted | 2026-10-03 |
| ADR-296 | A pull request merged on GitHub publishes like one Oxagen merged | Accepted | 2026-10-03 |
| ADR-297 | A run is credited with the commits it made | Accepted | 2026-10-03 |
| ADR-298 | A text class follows the kit's type role, not the mockup's pixel size | Accepted | 2026-10-03 |
| ADR-299 | The code graph's code lives in services/codegraph and packages/codegraph | Accepted | 2026-10-10 |
| ADR-300 | get_memory_policy loses its route and its MCP tool | Accepted | 2026-10-03 |
| ADR-301 | Code graph settings are checked files that Settings writers change | Accepted | 2026-10-03 |
| ADR-302 | Code graph IDs and the deployable seed row | Accepted | 2026-10-03 |
| ADR-303 | The code graph tables are hash-partitioned and embeddings are shared per organization | Accepted | 2026-10-04 |
| ADR-304 | Decision and declassification records carry their fields in a map named for the kind | Accepted | 2026-10-03 |
| ADR-305 | SCIP indexers run in Fargate tasks behind a registry proxy | Proposed | 2026-10-04 |
| ADR-306 | The code graph runs on Fargate and each organization gets its own key | Accepted | 2026-10-10 |
| ADR-307 | Code graph extraction links its query grammars and names files, tests, and comments | Accepted | 2026-10-04 |
| ADR-308 | One secret pattern set for the code graph | Accepted | 2026-10-04 |
| ADR-309 | Bulk triage runs on OpenRouter's batch API with a Google model | Accepted | 2026-10-04 |
| ADR-310 | Code graph batches carry their request ID in custom IDs and recover before they resubmit | Accepted | 2026-10-04 |
| ADR-311 | Code graph intake keeps the retired repo row and hands file deletion to the worker | Accepted | 2026-10-04 |
| ADR-313 | The local code graph maps the Postgres tables into one SQLite file per repo | Accepted | 2026-10-04 |
| ADR-314 | Code graph grammars load from the pinned pack at run time | Accepted | 2026-10-04 |
| ADR-315 | The code graph link step resolves names in one language family | Accepted | 2026-10-04 |
| ADR-316 | Code graph dependency readers, Package URLs, and build target labels | Accepted | 2026-10-04 |
| ADR-317 | A Tier 1 symbol keeps its cg ID and SCIP is compared by reference | Accepted | 2026-10-04 |
| ADR-318 | The schema graph uses the replayed schema and names data nodes under db | Accepted | 2026-10-04 |
| ADR-320 | Code graph environment variables join by name and keep setters on the node | Accepted | 2026-10-04 |
| ADR-321 | Code graph scripts are named by file and task, and code tasks stay unknown | Accepted | 2026-10-04 |
| ADR-322 | The code graph tests index reads tests by rule and turns CI uploads into observations | Accepted | 2026-10-04 |
| ADR-323 | The code graph call step replaces link call edges and names entry points by hash | Accepted | 2026-10-04 |
| ADR-324 | Code graph comments and docs are step code in cg-core | Accepted | 2026-10-04 |
| ADR-325 | Tier 2 Swift and Elixir resolve by module, and markup files read their script blocks | Accepted | 2026-10-04 |
| ADR-326 | The code graph query service reads a workspace manifest and takes the caller's readable repos | Accepted | 2026-10-04 |
| ADR-327 | apps/app_deprecated is deleted | Accepted | 2026-10-05 |
| ADR-328 | The code graph publish step layers stages and keeps rows by revision kind | Accepted | 2026-10-04 |
| ADR-329 | Code graph PageRank runs a fixed 50 iterations, and the query service ranks unannotated files | Accepted | 2026-10-05 |
| ADR-330 | The code graph panel sits on Repositories and shows no local-graph copy | Accepted | 2026-10-04 |
| ADR-331 | The code graph parse step targets 10 seconds and the M1 gate scores agreement by reference | Accepted | 2026-10-04 |
| ADR-332 | The local code graph host keys every build to one worktree ref and counts its own heap | Accepted | 2026-10-05 |
| ADR-333 | Code graph CI uploads bind to the CI token and land on the observation row | Accepted | 2026-10-05 |
| ADR-334 | A linked repository's harness files become steering records through one steering PR | Accepted | 2026-10-05 |
| ADR-335 | Code graph CI workflows are nodes by pipeline file, and run history comes from the host | Accepted | 2026-10-05 |
| ADR-336 | The code graph index calls answer from the graph file, and the tests index carries measured coverage on the test node | Accepted | 2026-10-05 |
| ADR-337 | Code graph history walks the first parent, and stores each co-change direction with its own confidence | Accepted | 2026-10-05 |
| ADR-338 | The freshness check starts its window at the commit and reads GitHub for what is open | Accepted | 2026-10-05 |
| ADR-339 | The code graph resolves `at` in the handler, records every build request, and gates the workspace run by cron | Accepted | 2026-10-05 |
| ADR-340 | Code graph enrichment exchanges batches through Postgres and pauses on a refused reservation | Accepted | 2026-10-05 |
| ADR-341 | The code graph reads a GitLab project through the workspace's connection | Accepted | 2026-10-05 |
| ADR-342 | The code graph workspace stage joins current repo revisions and publishes a checked workspace revision | Accepted | 2026-10-05 |
| ADR-343 | Work status sync uses durable provider writes | Accepted | 2026-10-05 |
| ADR-344 | A person names a run, and no automatic account replaces it | Accepted | 2026-10-05 |
| ADR-345 | The code graph structure stage runs after the last shard and saves each index under the link step | Accepted | 2026-10-05 |
| ADR-346 | The code graph infrastructure index shares IDs with the CI index and keeps connection facts on the node | Accepted | 2026-10-05 |
| ADR-347 | Code graph runtime counts ride on the caller node per observation, and attach after the commit's copy publishes | Accepted | 2026-10-05 |
| ADR-348 | Python scope links follow annotations to fields and keywords | Accepted | 2026-10-05 |
| ADR-349 | Graph file format v2 carries each edge's facts, and the blast radius walks by path confidence | Accepted | 2026-10-05 |
| ADR-350 | A run's steering is assembled for its repository under its harness's hook limit | Accepted | 2026-10-05 |
| ADR-351 | The code graph settings read the approved commit and change through a codegraph branch | Accepted | 2026-10-05 |
| ADR-352 | Code graph cards embed in passes 6a and 6b, and the organization's vector table is their only cache | Accepted | 2026-10-05 |
| ADR-353 | Imported ADRs are indexed in their source repo and copied to the steering repo under the publication rule | Accepted | 2026-10-05 |
| ADR-354 | PHP names resolve by namespace and PSR-4, and Laravel routes and migrations are read from their files | Accepted | 2026-10-06 |
| ADR-355 | C and C++ resolve includes by folder and index with scip-clang in the sandbox | Accepted | 2026-10-05 |
| ADR-356 | Go names resolve by package folder and module path, and methods by receiver type | Accepted | 2026-10-05 |
| ADR-357 | JVM names resolve by package, scip-java indexes whole Gradle and Maven builds, and Spring and JPA are read from annotations | Accepted | 2026-10-05 |
| ADR-358 | Code graph domains keep opaque stable IDs per workspace, and approved changes name only those IDs | Accepted | 2026-10-05 |
| ADR-359 | Dart names resolve by pubspec package and URI, and Dart projects index with scip-dart | Accepted | 2026-10-05 |
| ADR-360 | Rust paths follow the mod tree, Ruby constants resolve by nesting, and .NET names resolve by namespace | Accepted | 2026-10-05 |
| ADR-361 | The code graph M2 gate replays squash-merged pull requests with the worker's own build | Accepted | 2026-10-05 |
| ADR-362 | Code graph search ranks words in the query service and takes meaning from the handler | Accepted | 2026-10-06 |
| ADR-363 | Floating surfaces are glass | Accepted | 2026-10-06 |
| ADR-364 | Code graph live inventory reads AWS Config through an opt-in role, and publishes drift as one layer per account | Accepted | 2026-10-05 |
| ADR-365 | The code graph M5 gate checks call flows, plans, and CI jobs against what ran | Accepted | 2026-10-05 |
| ADR-366 | The code graph M6 gate runs the M1 and M2 harnesses on pinned public repos, one or more per language | Accepted | 2026-10-05 |
| ADR-367 | Linker rounds run from an Inngest function, and one checker serves propose_edge and the batch | Accepted | 2026-10-06 |
| ADR-368 | Code graph embeddings run through one gateway, and only the cloud build host writes the vector table | Accepted | 2026-10-06 |
| ADR-369 | Code graph boundaries are decided at question time, and conventions are mined by count with a template rule | Accepted | 2026-10-06 |
| ADR-370 | The code graph M3 gate scores search on pinned benchmark tasks and domain tags on two folds of labels | Accepted | 2026-10-06 |
| ADR-371 | Spec status is worked out once per workspace revision, and trace_spec reads it from the specs file | Accepted | 2026-10-06 |
| ADR-372 | Pull requests run light lanes, and main runs the full gate | Accepted | 2026-10-06 |
| ADR-373 | Linker rounds per node are a workspace setting | Accepted | 2026-10-06 |
| ADR-374 | packages/ui is the one component library: shadcn on Base UI, in glass | Accepted | 2026-10-06 |
| ADR-375 | CI status goes to Slack, and no workflow files a P0 | Accepted | 2026-10-06 |
| ADR-5864 | ADRs take their merge request's number, and atlas.sum is generated | Accepted | 2026-10-06 |
| ADR-5876 | The weekly price and unpriced-model report are precomputed every five minutes | Accepted | 2026-10-06 |
| ADR-5878 | Session succession requires a device key proof | Accepted | 2026-10-06 |
| ADR-5879 | System paths assume a role, and no policy reads app.rls_bypass | Accepted | 2026-10-06 |
| ADR-5882 | Design documents live in the roadmap repository | Accepted | 2026-10-06 |
| ADR-5929 | A model the price book has never priced is priced from the floor | Proposed | 2026-10-07 |
| ADR-5939 | Command reasons are a workspace setting, off by default and enforced by dispatch_command | Accepted | 2026-10-07 |
| ADR-5945 | A host starts a sent work order itself | Accepted | 2026-10-07 |
| ADR-5965 | A pause holds the session's model calls at the host gateway | Accepted | 2026-10-07 |
| ADR-5969 | One run table: tacho.sessions holds every run | Accepted | 2026-10-07 |
| ADR-5986 | One billing customer per organization, stored under provider-neutral names | Accepted | 2026-10-07 |
| ADR-5989 | Agent memories live in Postgres alone, and the Neo4j memory tools are deleted | Accepted | 2026-10-07 |
| ADR-5992 | The MCP server row holds its connection | Accepted | 2026-10-07 |
| ADR-5994 | A pull request's state is kept only in the forge store | Accepted | 2026-10-07 |
| ADR-6028 | Dispatched work is accepted only when its pull request can merge | Accepted | 2026-10-07 |
| ADR-6058 | A local code graph uses the workspace's own embedding key and talks to Oxagen only to fetch it | Accepted | 2026-10-07 |
| ADR-6080 | Operator presence, away time and the output measures | Accepted | 2026-10-07 |
| ADR-6082 | A pull request mention steers or redispatches the agent that opened it | Accepted | 2026-10-08 |
| ADR-6107 | A rotated API key keeps working for 24 hours | Accepted | 2026-10-08 |
| ADR-6116 | Sandbox runtimes run only in the customer's own Modal account in phase 2 | Accepted | 2026-10-08 |
| ADR-6120 | Every issue and comment a wrapped run writes carries the run badge | Accepted | 2026-10-08 |
| ADR-6126 | Oxagen returns a send whose pull request cannot merge | Accepted | 2026-10-08 |
| ADR-6154 | Beta pricing lives in data and can change without a deploy | Accepted | 2026-11-03 |
| ADR-6170 | A prompt that names an issue claims its work item | Accepted | 2026-10-15 |
| ADR-6171 | Decisions made finishing the issues #6153 advanced | Accepted | 2026-11-05 |
| ADR-6203 | Production logs go to Datadog through the archive Firehose | Accepted | 2026-10-09 |
| ADR-6293 | Every list table follows one anatomy | Accepted | 2026-10-09 |
| ADR-6563 | An operator keeps many model credentials per harness, and the gateway moves to the next when one runs out of usage | Accepted | 2026-10-09 |
| ADR-6574 | Oxagen adopts the Oxide design system | Accepted | 2026-10-10 |
| ADR-6588 | Every create flow runs on one record wizard that stella drafts | Accepted | 2026-10-10 |
| ADR-6603 | A local code graph builds what the cloud builds, from the same Rust step code and a cloud copy of its base | Accepted | 2026-10-10 |
| ADR-6604 | Enrollment is an Ed25519 certificate signed by the control plane and proved by the host's device key | Accepted | 2026-10-10 |
| ADR-6606 | A local tool discovery travels in a signed envelope | Accepted | 2026-10-10 |
| ADR-6608 | The kernel decisions of issue 2971: typed refusals, the agent approval matrix, reads and the billing gate, and the rows closed by removal | Accepted | 2026-10-10 |
| ADR-6622 | Every figure and chart is drawn by the dashboard kit | Accepted | 2026-10-17 |
| ADR-6625 | Durable jobs are served on /api/jobs through a provider contract | Accepted | 2026-10-10 |
| ADR-6629 | Sandbox providers plug in by host operator | Accepted | 2026-10-10 |
| ADR-6672 | The def-use layer is built per file when a call first needs it, and fault localization fuses seven signals | Proposed | 2026-10-10 |
| ADR-6742 | The code graph link step builds on the commit before it and records moved files | Accepted | 2026-10-11 |
| ADR-6746 | A required check passes as GitHub counts it, and a merge settles the review gate | Accepted | 2026-10-10 |
| ADR-6750 | A workspace hears about its work and runs on Slack and by email | Accepted | 2026-10-11 |
| ADR-6753 | A work collector connects to any issue tracker through one framework and syncs both ways | Accepted | 2026-10-11 |
| ADR-6754 | A work item is written in Oxagen's editor and creates its tracker issue on save | Accepted | 2026-10-11 |
| ADR-6765 | A sandbox runtime names its run environment and the workspace default is the fallback | Accepted | 2026-10-11 |
| ADR-6776 | Every MCP credential is an mcp row of the vault | Accepted | 2026-10-11 |
| ADR-6780 | A sandbox's daemon enrolls by exchanging its run token for a certificate the control plane signs | Accepted | 2026-10-11 |
| ADR-6791 | Go values take the types their declarations state, and another module of the repo is outside unless replaced | Accepted | 2026-10-11 |
| ADR-6796 | The def-use layer is one JSON file per file content, built by the host that holds the source | Accepted | 2026-10-11 |
| ADR-6805 | A batch of work orders is one row, and a sandbox batch runs one sandbox per order | Accepted | 2026-10-11 |
| ADR-6807 | The cloud gateway relays Git and tool calls for the daemon inside a sandbox | Accepted | 2026-10-11 |
| ADR-6926 | The registry follows the steering directory in a steering repository | Accepted | 2026-10-12 |
| ADR-6932 | A model credential change from a CLI session key is refused by key purpose, recorded with the key and address, and told to the person | Accepted | 2026-10-13 |
| ADR-6940 | Memories rank by whether they steer agents well | Accepted | 2026-10-12 |
| ADR-6943 | The cloud gateway relays a sandbox run's GitLab project to gitlab.com | Accepted | 2026-10-13 |
| ADR-6947 | Memories come only from the workspace's repositories and personal folders | Accepted | 2026-10-13 |
| ADR-6955 | Sandbox reads that a page opens answer released false and record no denial | Accepted | 2026-10-13 |
| ADR-6967 | A table's column order and visibility live in one cookie per table | Accepted | 2026-10-13 |
| ADR-6968 | A page tab awaits only the reads its body draws | Accepted | 2026-10-13 |
| ADR-7039 | The Stella console and the count of what waits on the operator | Accepted | 2026-10-13 |
| ADR-7046 | A runtime is deleted for good once nothing live uses it | Accepted | 2026-10-13 |
| ADR-7054 | A sandbox runtime's egress hosts and services take effect on Modal | Accepted | 2026-10-13 |
| ADR-7069 | Oxagen generates a workspace's sandbox template into its steering repo | Accepted | 2026-10-13 |
| ADR-7073 | A settings area lists its pages in one grouped settings nav | Accepted | 2026-10-13 |
| ADR-7097 | One agent runs any number of sandboxes at once, each with a host of its own | Accepted | 2026-10-13 |
| ADR-7098 | Run link inference tries the run's own record before a semantic match | Accepted | 2026-10-13 |
| ADR-7107 | Every surface draws shared components from one package through its own components folder | Accepted | 2026-10-13 |
| ADR-7129 | A repeated instruction reaches a person only as a rule stella judged | Accepted | 2026-10-14 |
| ADR-7134 | A steering draft reaches a person only when the agent that would receive it asks for it | Accepted | 2026-10-14 |
| ADR-7155 | Stella raises what an agent says it left undone | Accepted | 2026-10-14 |
| ADR-7157 | A steering record draft comes from a person's corrections, and every draft passes the agent test | Accepted | 2026-10-14 |
| ADR-7185 | Full transcript mode keeps every tool body, cut rather than dropped | Accepted | 2026-10-14 |
| ADR-7187 | A pull request merged on GitHub counts in Oxagen | Accepted | 2026-10-14 |
| ADR-7200 | stella runs a published skill only when the person names it with a slash command | Accepted | 2026-10-14 |
| ADR-7206 | A local code graph build embeds through a loopback relay on tachod and bills the operator | Accepted | 2026-10-14 |
| ADR-7207 | A memory reaches Oxagen when it is written, and the host's copy wins | Accepted | 2026-10-14 |
| ADR-7216 | Deleting a stella conversation removes it and its files for good | Accepted | 2026-10-14 |
| ADR-7226 | stella runs on the organization's model tiers, and each tier says who pays | Accepted | 2026-10-14 |
| ADR-7229 | A re-enrolled machine takes its revoked enrollment's open runs at once | Accepted | 2026-10-14 |
| ADR-7237 | Private blob encryption | Accepted | 2026-10-14 |
| ADR-7249 | Durable send-back delivery | Accepted | 2026-10-14 |
| ADR-7261 | A re-enrolled machine takes a run only on its daemon's proof | Accepted | 2026-10-14 |
| ADR-7362 | Cedar tool policies and enforcement failures | Accepted | 2026-10-15 |
| ADR-7373 | Steering tokens name one repository, and recall may send the prompt under `digest_only` | Accepted | 2026-10-14 |
| ADR-7374 | A rejected primary moves its run's spend to the next confirmed item or back to unassigned | Accepted | 2026-10-15 |
| ADR-7378 | Both gateways add run steering before each model call | Accepted | 2026-10-15 |
| ADR-7385 | Reports live in one section and each report read checks its scope | Accepted | 2026-10-15 |
| ADR-7391 | Each operator is decided on their own agent file | Accepted | 2026-10-15 |
| ADR-7419 | The shared component package holds every component the design system draws | Accepted | 2026-10-16 |
| ADR-7449 | CI runs on our own GitHub App and AWS boxes | Accepted | 2026-10-17 |
| ADR-7450 | A price book row can price only prompts past a size | Accepted | 2026-10-17 |
| ADR-7451 | A default model tier names one of the organization's tiers | Accepted | 2026-10-17 |
| ADR-7454 | Every surface draws its components from @oxagen/uikit, and packages/ui is deleted | Accepted | 2026-10-17 |
| ADR-7460 | Graph nodes carry a durable public id that cloud and local graphs share | Accepted | 2026-10-17 |
| ADR-7493 | A person declines a suggested work item with a start_declined work fact | Accepted | 2026-10-18 |
| ADR-7494 | The brief becomes the Definition of Done with two fields per item | Accepted | 2026-10-18 |
| ADR-7495 | The app, the docs site and Storybook draw one uikit stylesheet | Accepted | 2026-10-20 |
| ADR-7504 | Built-in role grants come from contracts at read time | Accepted | 2026-10-18 |
| ADR-7506 | Tacho is now the recorder | Accepted | 2026-10-18 |
| ADR-7543 | Billing has four entry points and keeps its root as their union | Accepted | 2026-10-17 |
| ADR-7551 | The code graph spend ledger belongs to billing and the model package root lists only model calls | Accepted | 2026-10-18 |
| ADR-7554 | Background jobs read their parts from one object the API installs | Accepted | 2026-10-18 |
| ADR-7555 | The agent package holds the runtime and names its entry points | Accepted | 2026-10-18 |
| ADR-7571 | The durable ingestion job is the one runner of the graph ingestion stages | Accepted | 2026-10-18 |
| ADR-7575 | Capability handlers are bound in one typed table per contract domain | Accepted | 2026-10-18 |
| ADR-7598 | A mention pins the record version the person picked, and one chip draws it | Accepted | 2026-10-19 |
| ADR-7606 | One table holds every steering record mention outside a work item | Accepted | 2026-10-20 |
| ADR-7608 | Charts draw quiet colors and the gold marks one emphasized series | Accepted | 2026-10-22 |
| ADR-7642 | Skill registries share the registries table and default to skills.sh | Accepted | 2026-10-20 |
| ADR-7647 | Every design-system component lives in the shared component package, the run family included | Accepted | 2026-10-21 |
| ADR-7658 | The mockup draws every component from the shared library and is where new designs are tried first | Accepted | 2026-10-21 |
| ADR-7671 | Steering lists records, suggestions and skills | Accepted | 2026-10-21 |
| ADR-7678 | A skill's folder opens and edits in place | Accepted | 2026-10-21 |
| ADR-7685 | File storage runs on S3 in Oxagen's AWS account | Accepted | 2026-10-21 |
| ADR-7690 | stella asks a decision on the ticket it blocks | Accepted | 2026-10-21 |
| ADR-7706 | Every question to the operator is multiple choice with the recommended answer first | Accepted | 2026-10-21 |
| ADR-7719 | The design system draws one dialog component | Accepted | 2026-10-21 |
| ADR-7721 | The Run page draws PageHeader and the Work panel holds the pull request | Accepted | 2026-10-21 |
| ADR-7742 | The Run page header holds the title, the status and a two-line summary | Accepted | 2026-10-21 |
| ADR-7755 | The Work panel shows the work a run created and closed, and Changes holds the pull request | Accepted | 2026-10-21 |
| ADR-7775 | Agent minutes, staffing and decisions on work items | Accepted | 2026-10-22 |
| ADR-7777 | Work item statuses map to fixed stages | Accepted | 2026-10-22 |
| ADR-7779 | A person's return records its feedback cluster on the fact | Accepted | 2026-10-22 |
| ADR-7780 | Work item labels have a workspace look and one mapping table | Accepted | 2026-10-22 |
| ADR-7783 | Oxagen scores and ranks each person from the record | Accepted | 2026-10-22 |
| ADR-7788 | A run stores the sums its report needs and the report works out the rest | Accepted | 2026-10-22 |
| ADR-7809 | Pages show the least that answers their question and reveal the rest on request | Accepted | 2026-10-22 |
| ADR-7818 | The phone's top bar holds three controls and a three-dot button opens the full navigation | Superseded | 2026-10-22 |
| ADR-7819 | The work item page draws as one scroll, as the mockup draws it | Accepted | 2026-10-22 |
| ADR-7823 | The app's Run page takes the mockup's two columns and leaves unread figures out | Accepted | 2026-10-22 |
| ADR-7838 | A work order session starts with Oxagen's own progress note, and the agent records progress with the host key | Accepted | 2026-10-22 |
| ADR-7906 | The app draws its frame from the design system's inset dual-rail shell | Accepted | 2026-10-22 |
| ADR-7910 | Charts draw in one gold family | Accepted | 2026-10-22 |
| ADR-7916 | Work item labels are renamed, archived and deleted without rewriting items | Accepted | 2026-10-22 |
| ADR-7923 | A work order's run proves itself with a token Oxagen makes from the claim | Accepted | 2026-10-22 |
| ADR-7935 | A decision stands alone and each option names what stella does next | Accepted | 2026-10-22 |
| ADR-7936 | A person ticks Done Checklist items with an item fact | Accepted | 2026-10-22 |
| ADR-7954 | Triage runs again on its own when its failure passes | Accepted | 2026-10-23 |
| ADR-7967 | Residue that files an issue is FYI, and housekeeping is never residue | Accepted | 2026-10-22 |
| ADR-7989 | Work, Agents and Steering draw their tabs on the page and the shell has one rail | Accepted | 2026-10-23 |
| ADR-8004 | The work item page folds every section and shows four facts | Accepted | 2026-10-24 |
| ADR-8006 | The plan line item is found by its price kind and the sandbox slot add-on owns its grant | Accepted | 2026-10-24 |
| ADR-8018 | The run transcript hides model calls the provider refused | Accepted | 2026-10-24 |
| ADR-8020 | Stella widgets draw from one chart kit with pixel hit targets | Accepted | 2026-10-24 |
| ADR-8031 | A run's context score is the share of three recorded signals it carries | Accepted | 2026-10-24 |
| ADR-8042 | Stella's widget data comes from recorded runs and settled vocabularies | Accepted | 2026-10-24 |
| ADR-8102 | Stella keeps every item a run lists as left undone | Accepted | 2026-10-24 |
| ADR-8108 | An action stella takes alone answers the item and can be undone | Accepted | 2026-10-24 |
| ADR-8111 | The Run page drops the issue connections panel | Accepted | 2026-10-24 |
| ADR-8112 | The Console shows what needs you and what stella did alone in one card stack | Accepted | 2026-10-24 |
| ADR-8120 | A run's report reaches the Console as one questionnaire and one update | Accepted | 2026-10-24 |
| ADR-8123 | Triage questions wait on the Console as multiple choice, and their answers reach the agent | Accepted | 2026-10-24 |
| ADR-8125 | The Run page has a sticky header with a chip row, an independent side column and a live bar | Accepted | 2026-10-25 |
| ADR-8149 | A run linked to a work item becomes the item's send | Accepted | 2026-10-25 |
| ADR-8156 | The stella widgets reach the app as uikit cards read through one port and shown by a widget card | Accepted | 2026-10-25 |
| ADR-8175 | The browser gets the message catalogue from a static module | Accepted | 2026-10-25 |
| ADR-8207 | Dashboards list the stella widgets as cards under an Analytics section | Accepted | 2026-10-25 |
| ADR-8209 | The main deploy publishes the node tools from the orchestrator | Accepted | 2026-10-25 |
| ADR-8211 | A run's frames are read in pages of 1,000 | Accepted | 2026-10-25 |
| ADR-8221 | The Dashboards page draws the stella widget index | Accepted | 2026-10-25 |
| ADR-8224 | The run lists page from an index on the start at UTC | Accepted | 2026-10-25 |
| ADR-8225 | A request memo on the capability context shares one request's reads | Accepted | 2026-10-25 |
| ADR-8242 | Explicit delegated work decisions and CLI MCP parity | Accepted | 2026-10-25 |
| ADR-8253 | The run header lists a repository only for a branch the run committed to | Accepted | 2026-10-25 |
| ADR-8265 | The Run page's side column puts Tasks under Run details and above Changes | Accepted | 2026-10-25 |
| ADR-8290 | The app draws each stella dashboard from the mockup's widget card and a live read | Accepted | 2026-10-25 |
| ADR-8324 | The sidebar groups workspace, organization and analytics pages, and Spend becomes a Reports dashboard | Accepted | 2026-10-26 |
| ADR-8329 | The Work items and Runs tables draw as a spreadsheet grid | Accepted | 2026-10-26 |
| ADR-8352 | A machine registers through a token bound to its runtime and agent | Accepted | 2026-10-26 |
| ADR-8353 | Each workspace keeps its own run kinds and work item kinds, and a model picks one | Accepted | 2026-10-26 |
| ADR-8355 | Work item writes from every surface, in lists, and what a deleted item reaches | Accepted | 2026-10-26 |
| ADR-8361 | A work item's cost is read from its runs and its owner sits in owner_id | Accepted | 2026-10-26 |
| ADR-8367 | Run and work item panels fold by section and draw nothing when empty | Accepted | 2026-10-26 |
| ADR-8395 | Website leads alert by email and Slack and none go to Attio | Accepted | 2026-10-26 |
| ADR-8400 | Agent claims of done are checked by a deterministic engine over oracle reports | Accepted | 2026-10-26 |
| ADR-8401 | Issue titles carry the initiative key and the statement | Accepted | 2026-10-26 |
| ADR-8405 | Plans carry agent sandboxes and a sandbox runtime limit, and a plan can differ from its tier | Accepted | 2026-10-26 |
| ADR-8422 | The agent evidence bundle is a SCITT profile published as an Internet-Draft | Accepted | 2026-10-26 |
| ADR-8431 | A run's Console card starts with no answer picked | Accepted | 2026-10-27 |
| ADR-8447 | Geist Mono sets code and nothing else, and a run's cost is a price badge | Accepted | 2026-10-27 |
| ADR-8451 | A phone draws its own Work items list from one stats read that replays the work facts | Accepted | 2026-10-27 |
| ADR-8481 | Plans limit how many workspaces an organization holds | Accepted | 2026-10-27 |
| ADR-8491 | Stored status reports feed the Spend briefing | Accepted | 2026-10-28 |
| ADR-8545 | The brand lives in packages/brand, in cool tones | Accepted | 2026-10-28 |
| ADR-8546 | Steering has no stale state, and a connected repository holds no steering | Accepted | 2026-10-28 |
| ADR-8549 | Spend reads stored per-run rows that triggers keep current | Accepted | 2026-10-28 |
| ADR-8550 | Spend briefings read the organization's reports and a model writes every scope | Accepted | 2026-10-28 |
| ADR-8556 | A work item's theme comes from its issue | Accepted | 2026-10-28 |
| ADR-8562 | A machine's agents are named after the operator, the harness, and local | Accepted | 2026-10-28 |
| ADR-8582 | The run terminal pauses the run before anyone types | Accepted | 2026-10-28 |
| ADR-8586 | A steering repo's main is served however a commit reached it | Accepted | 2026-10-28 |
| ADR-8595 | An organization on its own database keeps its sandbox work and workspace notifications there | Accepted | 2026-10-28 |
| ADR-8596 | A sandbox template's setup command runs once at build time | Accepted | 2026-10-28 |
| ADR-8604 | Every sandbox run checks out every linked repository | Accepted | 2026-10-28 |
| ADR-8616 | A workspace account is a model credential the workspace holds, and a run's account source says who pays | Accepted | 2026-10-29 |
| ADR-8617 | A person's model credentials belong to the person, not to an organization | Accepted | 2026-10-28 |
| ADR-8623 | A run on a person's own machine rotates through their saved credentials | Accepted | 2026-10-28 |
| ADR-8631 | Transcript Reader turns run problems into fixes | Accepted | 2026-10-29 |
| ADR-8634 | A device serves one workspace at a time, with a connection generation on each enrollment | Accepted | 2026-10-29 |
| ADR-8644 | A device connection request is the enrollment token, and a device is the machine id on each host | Accepted | 2026-11-02 |
| ADR-8645 | A sandbox run waits out its model accounts' limits and its launcher continues the harness | Accepted | 2026-11-02 |
| ADR-8648 | The brand gold is the metal D4AF37 and darker on the light ground | Accepted | 2026-11-02 |
| ADR-8667 | Steering reads answer only wrapped runs | Accepted | 2026-11-02 |
| ADR-8669 | Website leads post to Slack through a bot token and the channel opens itself | Accepted | 2026-11-02 |
| ADR-8692 | A refused model account is a Console card that its owner or the workspace's admins repair and check | Accepted | 2026-11-02 |
| ADR-8720 | The prepaid wallet extends the billing tables Oxagen already has | Accepted | 2026-11-03 |
| ADR-8725 | CI/CD runs and merged pull requests reach the Console as read-once notices | Accepted | 2026-11-02 |
| ADR-8726 | A failed run's card is a Console notice read once | Accepted | 2026-11-03 |
| ADR-8732 | The wallet's lots hold the balance only while it is zero or more | Accepted | 2026-11-03 |
| ADR-8733 | A refused model login is signed in again on the person's own enrolled machine through a reauth command | Accepted | 2026-11-03 |
| ADR-8734 | Paid action units carry over, seat changes move the month by the share left, and the month close charges unpaid blocks | Accepted | 2026-11-04 |
| ADR-8754 | Google Cloud infrastructure | Accepted | 2026-11-03 |
| ADR-8774 | Main gates without deploying on Google Cloud until the deploy bridge lands | Accepted | 2026-11-03 |
| ADR-8777 | Production pulls each passed main release from the CI bucket | Accepted | 2026-11-04 |
| ADR-8786 | A result in review is accepted on the person's word | Accepted | 2026-11-04 |
| ADR-8788 | A host's Codex keeps its ChatGPT login and the gateway records its calls | Accepted | 2026-11-04 |
| ADR-8799 | The agent action gate runs the auto top-up before it refuses | Superseded by ADR-8819 | 2026-11-04 |
| ADR-8800 | Portable code graph storage | Accepted | 2026-11-04 |
| ADR-8819 | Billing holds new runs at run start and the recorder asks a job for the auto top-up | Accepted | 2026-11-04 |
| ADR-8870 | A person carries a work item to approval by hand, and approves many at once | Accepted | 2026-11-04 |
| ADR-8876 | Stella runs in a sandbox on its own route with every harness's hooks pinned | Accepted | 2026-11-04 |
| ADR-8886 | Infrastructure pull requests merge without waiting for Mac's review | Accepted | 2026-11-04 |
| ADR-8889 | A run that bills the workspace's model accounts needs no second confirmation | Accepted | 2026-11-04 |
| ADR-8890 | One cloud environment installs many harnesses | Accepted | 2026-11-04 |
| ADR-8894 | Sandbox pushes to recorded repositories | Proposed | 2026-11-04 |
| ADR-8897 | Device workspace connections | Proposed | 2026-11-05 |
| ADR-8898 | Empty-credit sandbox retries | Proposed | 2026-11-05 |
| ADR-8901 | Agent drafts finish with one permanent identity | Accepted | 2026-11-05 |
| ADR-8907 | Several agents take turns in one sandbox | Proposed | 2026-11-04 |
| ADR-8953 | Website leads live in the crm schema with first-touch UTM columns | Accepted | 2026-11-05 |
| ADR-8978 | A workspace chooses what a model call does when required steering does not fit | Accepted | 2026-11-06 |
| ADR-8989 | Each organization's IAM audit rows form one chain under a Postgres lock | Accepted | 2026-11-05 |
| ADR-8994 | Unproductive spend is read from finding claims, and the step grade counts steps | Accepted | 2026-11-05 |
About this atlas
Generated, not written. The docs build regenerates it from the tree; pnpm docs:architecture --check proves the cited sources still exist and the output is deterministic.
Inputs
apps/*/package.json,packages/*/package.json,tools/*/package.json: the workspace graph.packages/database/storage-manifest.json: the ADR-031 platform storage ontology (content hash37268951ee69c62e…), kept byte-stable bypnpm schema:manifest:check.packages/database/src/relations.ts,schema/_schemas.ts,tenant-policy.manifest.ts: logical edges, schema namespaces, RLS classes.packages/telemetry/src/schema.sql+migrations/*.sql: ClickHouse, replayed in order.packages/ontology/src/schema.cypher: Neo4j vector indexes (labels arrive via the manifest).packages/oxagen/capabilities.manifest.jsonandpackages/handlers/src/bindings/: contracts and handler bindings.apps/api/src/app.ts+routes/**: mounted routes, tiers, middleware chains.apps/mcp/src/tools,apps/cli/src/program.ts: the other two surfaces.packages/inngest-functions/src/functions.tsandfunctions/*.ts: the served array, each declaration scanned with the exported helpers ofcheck-inngest-senders.ts.packages/config/src/registry.ts:ENV_REGISTRYand the Parameter Store prefixes, imported directly.packages/config/src/ci-registry.ts:CI_REGISTRY, joined to thesecrets.andvars.names each workflow and each.github/actions/**/action.ymlreads..github/workflows/*.yml,docs/adr/*.md,infra/tools/caddy/Caddyfile.alb,docker-compose.dev.yml.
Curated flows
11 mechanism diagrams are hand-described in tools/scripts/lib/archdocs/flows.ts because they encode order, which no manifest records. Each cites the files and symbols it depicts (134 references); the generator fails when any cited file or symbol is missing, so a flow cannot outlive the code it draws.
Determinism
No timestamps, no random ids, no network. Two builds of the same tree produce identical bytes. The output is not committed: apps/docs regenerates it as a prebuild step, so the published atlas always matches the tree it shipped with, and pnpm docs:architecture --check, part of pnpm gate, guards the two things that can rot, cited sources and determinism. The docs build's own generation step also fails when a cited file or symbol is gone.