# OMS Conductor-First Live Delivery Roadmap

Status: approved on 2026-07-11; implementation pending

Baseline: commit `066777f`; the local file-backed control plane, schemas, hooks, queue, worktrees, reconciliation, HUD, and negative-only release assessment are implemented and verified.

## Outcome

A human runs interactive bare `oms`, which performs any one-time repository-scoped confirmation, then creates or resumes a persistent read-only Claude Opus conductor in the OMS tmux session. The human types a freeform goal. The conductor normalizes it into durable OMS goal state and then uses typed OMS commands to route tickets, start isolated Claude or Codex workers, observe immediate provider events, react to GitHub events, verify results, and prepare review-ready pull requests. The explicit `oms conductor start` form remains only for advanced recovery or state-root selection.

OMS v1 stops at `READY_FOR_HUMAN`. It never merges, tags, publishes, releases, or claims stability.

## Simplicity contract

Use the smallest existing primitive that works:

1. Native features: interactive Claude/Codex CLIs, Codex Goal and exec, Claude local stdio MCP tools and `asyncRewake` hooks, provider hooks, tmux, git worktrees, `gh`, and user-owned schedulers.
2. Skills: conductor routing, executor protocol, advisor, grader, bounded reflection, quota handling, scheduling, and team behavior.
3. Small Node.js/TypeScript commands: a session-scoped seven-tool conductor bridge, durable state, typed dispatch, provider delivery, event synchronization, reconciliation, deterministic verification, evidence, and process lifecycle.
4. No v1 framework layer: no daemon, database, webhook server, custom mux library, general workflow engine, or tracked shell automation.

Review remains deliberately simple: deterministic verification is the final vote; one fresh cross-engine structured grade is supplemental. Reflection occurs only after failure and is bounded by the configured attempt limit.

## Non-negotiable boundaries

- The human starts only the persistent conductor. Claude print mode and the Agent SDK are forbidden.
- The conductor has no Edit/Write tool and cannot invoke raw tmux. Goal,
  ticket preparation, pre-dispatch advice, and approved dispatch cross four schema-bound data tools;
  worker lifecycle, executor grouping, and protected result processing use three
  fixed controls with opaque canonical IDs.
- `oms` is the only shipped orchestration surface. Product code, generated instructions, and public docs must not require another orchestration CLI.
- All provider/model/auth/billing combinations are explicit configuration. Unknown or ineligible combinations fail closed. Credit-billed models remain disabled by default.
- The conductor may make routing decisions only inside configured roles, budgets, capabilities, attempts, and stopping conditions.
- Raw issue, review, model, hook, and pane text are untrusted content. They never become commands or authority.
- Deterministic OMS state owns goals, tickets, leases, dispatches, sessions, events, verification, evidence, attempts, audit, and human holds.
- Workers may change only their isolated ticket worktrees. They never own goal, verification, trust, merge, or release authority.
- A worker reporting `done` moves its ticket to `verifying`, not `completed`.
- Provider hooks are immediate. GitHub polling defaults to 60 seconds. The 15-minute watchdog is recovery-only.
- Merge, automatic merge, tag, publish, release, and positive stability remain human-held or absent.

## Operator flow

```text
human: oms
  -> OMS preflight + create/resume tmux session
  -> interactive read-only Claude Opus conductor

human types freeform goal
  -> conductor calls mcp__oms__propose_goal with structured JSON
  -> session-scoped OMS bridge validates and commits it
  -> durable canonical goal before first dispatch

conductor loop
  -> read canonical queue/events/status
  -> choose an eligible ticket and configured role
  -> call mcp__oms__prepare_dispatch with expected_ticket_version and exact content digest
  -> OMS proves current GitHub eligibility, journals the selection, and returns the leased intent
  -> call mcp__oms__advise_dispatch with the exact structured intent
  -> fresh Codex advice must approve that exact digest
  -> call mcp__oms__propose_dispatch with the unchanged intent + evidence
  -> OMS validates and starts isolated worker pane/worktree
  -> provider hooks publish immediate lifecycle/quota/completion observations
  -> GitHub sync publishes deduplicated issue/PR/review/check events
  -> deterministic verify
  -> one fresh cross-engine grade
  -> completed + READY_FOR_HUMAN, retry, park, or block

watchdog
  -> every 15 minutes, recover only stale panes/sessions/leases/outbox work
```

## Canonical state model

### Goal

The conductor normalizes the human request into a record containing:

- goal ID and version;
- objective;
- repository and queue scope;
- stopping condition;
- runtime horizon: `until-empty`, `12h`, or `24h`;
- budget and policy profile.

Every ticket, dispatch, attempt, event decision, result, and evidence record references the goal ID. Restarts re-read the record; conductor memory is never authoritative.

### Agent

- Activity: `idle | working | blocked | done`
- Health overlay: `healthy | parked | stalled | stopped`

### Ticket

`pending | leased | running | verifying | completed | retryable | parked | blocked`

Agent activity and ticket lifecycle are separate. A terminal worker result cannot bypass verification.

### Dispatch

Each accepted dispatch binds:

- goal, ticket, lease, attempt, and dispatch IDs;
- worker, configured role/model, provider mode, and worktree;
- capability set, budget snapshot, acceptance criteria, and evidence requirements;
- freeform agentic task body and operation nonce.
- canonical dispatch-intent digest and immutable advisor-evidence reference.

OMS validates and persists the envelope before a provider adapter delivers it. The worker acknowledges and returns typed receipts referencing the dispatch ID.

### Structured conductor ingress

Goal, advice, dispatch, and bounded controls use one native, session-scoped tool boundary:

1. Interactive bare `oms` (or the explicit `oms conductor start` form) generates a strict local stdio MCP configuration whose only server command is the installed `oms conductor bridge` TypeScript entrypoint bound to the exact workspace/state root.
2. CD-01 begins with `mcp__oms__propose_goal` and an inert `mcp__oms__propose_dispatch`; later slices activate dispatch and add version-bound `mcp__oms__prepare_dispatch` plus mandatory `mcp__oms__advise_dispatch` over a distinct exact-intent schema.
3. CD-03 adds `mcp__oms__manage_worker` for observe/park/resume/stop and `mcp__oms__start_team` for grouping already accepted dispatch IDs. CD-05 adds `mcp__oms__process_result` for the protected result and fixed review-delivery path. The complete bridge exposes exactly seven schema-bound tools: four data tools and three fixed controls.
4. Claude starts with `--strict-mcp-config`, `dontAsk`, those seven exact tool permissions, reviewed fixed OMS/read-only diagnostic rules, and no Edit/Write or raw tmux permission.
5. The bridge has no generic filesystem, shell, provider, GitHub, verification, merge, or release tool. Proposal tools validate current goal/ticket/lease/policy/budget authority; control tools accept only canonical IDs and bounded lifecycle fields. `process_result` can invoke only the installed deterministic gate and fixed human-held review delivery.
6. Tool calls are operation-nonce bound and replay-safe; tool output contains only bounded status and opaque canonical IDs.

The bridge is a local stdio child of the interactive conductor session, not a daemon, network listener, framework, or separate orchestrator. Freeform model text travels only through schema-bound goal, preparation, advice, and dispatch JSON and never enters argv or a shell. Because MCP subprocess capabilities are enforced inside OMS rather than by the Bash sandbox, the bridge must expose no ambient authority beyond those four data validators and three fixed-action controls.

## Events and clocks

Three mechanisms have distinct jobs:

1. Provider hooks immediately emit bounded session, activity, completion-observed, and quota observations. Hooks never provide the terminal result authority described below.
2. `oms events sync github` is a one-shot TypeScript command. A user-owned schedule runs it every 60 seconds by default. Durable watermarks and stable event keys deduplicate issue, comment/label, branch, PR, review, and check events.
3. `oms reconcile watchdog` runs every 15 minutes by default and handles only recovery and stall detection.

After successful event projection and pending-ticket materialization, OMS appends one deduplicated conductor-notification batch containing only opaque event IDs. A session-scoped `oms conductor wait-event` command is armed by Claude `SessionStart`/`Stop` command hooks with `asyncRewake`; it waits for the next batch, emits only its opaque notification ID, and exits with the documented wake code so an idle conductor re-reads canonical state. One durable waiter-generation record is bound to the conductor session and process identity with `armed | notified | failed | superseded` state plus expected-version/nonce transitions. The conductor consumes the notification only through the matching route/read operation. No raw GitHub/provider text is injected into the session.

The existing one-shot 15-minute watchdog is the sole dead-waiter recovery owner. After proving the waiter dead, it may CAS-claim one recovery generation only when the conductor is idle or dead, then resume/respawn the same conductor session so `SessionStart` arms a replacement. It never interrupts an active conductor; the next normal `Stop` re-arms instead. Unsafe or failed resume becomes visible `stalled`/`blocked` state while the notification remains pending. PID reuse, duplicate watchdog passes, and restarts cannot create two waiter generations.

Normal state progression is event-driven. The watchdog must not become a second scheduler or repeat valid work. OMS may install, inspect, and remove only the exact generated user-scoped schedule after the human explicitly starts the conductor; it does not ship an always-running daemon.

## Provider policy

- Claude conductor and ticket executors use supported interactive CLI sessions in tmux. No `claude -p` or Agent SDK path exists.
- Codex exec remains the fresh, schema-validated read-only advisor/grader surface when its configured auth/billing policy is eligible.
- Codex Goal is a resumable interactive worker lane for long tickets, not a headless-service promise.
- When Codex executes, one fresh Claude grade is mandatory; when Claude executes, one fresh Codex grade is mandatory. If the opposite engine is unavailable or ineligible, the ticket parks or blocks visibly—there is no same-engine fallback or skipped grade.
- Provider hooks authoritatively update provider session/activity/health observations within their documented local boundary. Only one schema-valid result receipt bound to the current goal/dispatch/attempt/lease/session/worktree/commit may set `agent=done` and move a ticket to `verifying`. Completion hooks alone cannot. Pane capture and sentinels are diagnostics only.

Official provider evidence was checked on 2026-07-11:

- https://code.claude.com/docs/en/authentication
- https://code.claude.com/docs/en/cli-usage
- https://code.claude.com/docs/en/headless
- https://code.claude.com/docs/en/legal-and-compliance
- https://code.claude.com/docs/en/hooks
- https://code.claude.com/docs/en/mcp
- https://code.claude.com/docs/en/permissions
- https://developers.openai.com/codex/cli/reference
- https://developers.openai.com/codex/auth
- https://developers.openai.com/codex/use-cases/follow-goals

## Delivery slices

### CD-01 — Conductor-first bootstrap and durable goal

Add the human-started interactive bare `oms` path, its explicit `oms conductor start` authorization/state override, repository-read-only permission/profile projection, session-scoped two-tool OMS bridge, conductor session resume, and freeform-to-canonical goal normalization. Promote the conductor-first ADR.

Acceptance:

- One human command creates or resumes the named tmux session and attaches to an interactive Claude Opus conductor.
- CD-01 begins with a pinned Claude Code compatibility proof (initial target: installed v2.1.207): the interactive subscription session loads only the generated local stdio OMS server, commits a goal through the goal tool, receives deterministic `dispatch-not-enabled` with no mutation from the dispatch tool, and cannot access Edit, Write, raw tmux, an unlisted MCP tool, or an unapproved shell command. Failure stops CD-01 and requires an ADR revision; permissions are never widened.
- The conductor cannot edit/write product files or canonical state, mutate policy directly, or invoke raw tmux. It can call only the two allowlisted structured proposal tools, fixed typed OMS commands with opaque IDs, and read-only diagnostics.
- Goal text crosses only JSON tool input and is committed only after exact schema/size/current-authority validation; shell metacharacters remain inert.
- No print mode, Agent SDK, provider proxy, or default credit-billed model appears in launch arguments or configuration.
- A canonical goal is durable before the first dispatch and is recovered after conductor restart.
- Unknown auth, billing, CLI version, permission profile, or repository scope blocks launch.

Blocked by: none.

### CD-02 — Typed dispatch and separated runtime states

Add canonical dispatch records, worker records, acceptance/result schemas, and deterministic transitions for agent activity, health, and ticket lifecycle.

Acceptance:

- OMS validates and persists a dispatch before delivery.
- CD-02 replaces the inert dispatch handler with exact canonical validation/commit while preserving the same tool name, input schema boundary, and conductor permission set.
- Dispatch freeform content crosses only the schema-bound
  `mcp__oms__advise_dispatch` and `mcp__oms__propose_dispatch` tools; it never
  enters a command argument or file Write.
- The envelope binds the exact goal, ticket, lease, attempt, worker, role/model, worktree, capabilities, budget, acceptance/evidence requirements, and nonce.
- `agent=done` can move a ticket only to `verifying`.
- Stale leases, replayed nonces, exhausted attempts, unconfigured roles/models, or expanded capabilities fail closed without mutation.
- The conductor cannot use dispatch to edit policy, expand goal scope, verify its own work, or grant merge/release authority.

Blocked by: CD-01.

### CD-03 — OMS-owned worker panes, provider adapters, and teams

Implement OMS-native worker delivery and pane lifecycle behind typed commands. A team is only a group of executor dispatches with isolated worktrees; all results later use the same deterministic gate and single cross-engine grade from CD-05.

Acceptance:

- OMS starts, observes, parks, resumes, and stops one or N isolated worker panes from accepted dispatches.
- Provider CLIs start directly; no public raw `tmux send-keys` command or pane text authority is exposed.
- Workers acknowledge dispatch IDs and return typed result receipts bound to the exact session and worktree commit.
- Claude remains interactive; Codex Goal remains resumable; Codex exec remains schema-validated and read-only for its configured role.
- Replace the current per-worker `human_attended` / `human_started_native` assumptions with one explicitly reviewed `operator_originated_oms_managed_interactive` session policy. It remains distinct from headless/unattended eligibility and must fail closed when current provider policy or version preflight cannot support it.
- Unknown provider eligibility blocks launch; capabilities cannot grant verification, trust, merge, or release authority.
- Teams add no verifier agent or second model-review lane; team outputs flow into CD-05.
- Product code, generated skills, tests, and docs contain no runtime dependency on an external orchestration CLI.

Blocked by: CD-02.

### CD-04 — Immediate events, GitHub sync, scheduling, and recovery

Extend the existing event/outbox path with provider session/activity/completion-observed events, typed GitHub events, durable sync watermarks, schedule lifecycle, and pane-aware recovery.

Acceptance:

- Provider hooks immediately publish bounded session, activity, completion-observed, and quota observations.
- Completion hooks can record `completion-observed` but cannot set `agent=done` or move a ticket to `verifying`; only the dispatch-bound typed result receipt can do that.
- `oms events sync github` emits deduplicated typed issue, comment/label, branch, PR, review, and check events; default schedule is 60 seconds and configurable.
- Each projected event batch creates one durable opaque conductor notification. The version-pinned `asyncRewake` waiter wakes an idle conductor, which re-reads canonical state and consumes the matching notification. Projection/notify/wake/consume is replay-safe.
- Waiter state is generation/CAS bound to the exact conductor session/process. The watchdog is the sole recovery writer: it resumes/respawns only a proven idle/dead conductor, never interrupts an active one, and otherwise records visible stalled/blocked state with the notification retained.
- `oms reconcile watchdog` runs every 15 minutes by default and only recovers or reports dead panes, stalled sessions/outbox work, expired leases, and resumable quota state.
- Generated user-scoped schedules can be installed, inspected, and removed idempotently; no daemon or webhook listener is introduced.
- Expired auth parks the lane for human login. Recovery never starts a duplicate worker or silently widens credentials.
- Raw provider/GitHub content never becomes a command, branch, path, or authority.

Blocked by: CD-03.

### CD-05 — Protected verification, cross-engine grade, and bounded retry

Connect typed worker results to the protected live deterministic verifier, then run exactly one fresh configured opposite-engine grade. On failure, store one bounded reflection and retry within the configured attempt limit.

Acceptance:

- A result binds the exact goal, dispatch, ticket, attempt, lease, session, worktree, and commit.
- The installed OMS runner and frozen verification plan produce immutable deterministic evidence outside the candidate's authority.
- Failed or incomplete deterministic verification is final and cannot be overridden by conductor, grader, trust, or operator text.
- Exactly one fresh schema-validated opposite-engine grade is mandatory and supplemental; it consumes raw bounded check output plus immutable diff/evidence references. Unavailable/ineligible opposite-engine grading parks or blocks visibly.
- State follows `agent done -> ticket verifying -> completed | retryable | blocked`; max attempts produce a visible block.
- Completed tickets remain `human_hold`, and trust input can originate only from the protected verdict.

Blocked by: CD-03.

### CD-06 — Real GitHub backlog-to-PR tracer

Use the normal GitHub event path to complete one small ready issue through conductor routing, execution, verification, grade, branch push, and a draft review-ready PR.

Implementation is present locally: human-start authorization, pre-notification
ticket admission, pinned secret scanning, non-force branch/draft-PR delivery,
typed-event waiting, and immutable review proof. CD-06 remains open until the
real provider/GitHub run and exact remote branch/PR/check evidence are captured.

Acceptance:

- One exact issue-to-goal-to-dispatch-to-session-to-commit-to-check-to-grade-to-PR evidence chain is independently replayable.
- OMS may create/update the isolated branch and draft PR, attach evidence, and report `READY_FOR_HUMAN`; no merge, auto-merge, tag, publish, or release command exists.
- Fresh GitHub read-back confirms the exact remote branch and draft PR still point at the verified commit; a typed event confirms the named deterministic check passed.
- A PR/check/review update becomes one deduplicated typed event and causes only a legal state transition.
- Secrets and raw credentials are absent from argv, tracked files, logs, evidence, and GitHub content.
- `release status` remains `not_stable`.

Blocked by: CD-04 and CD-05.

### CD-07 — Real elapsed 12-hour canary

Run a same-boot 12-hour goal with multiple short workers, at least one Codex long-goal lane, a grouped team delivery processed by the normal deterministic gate and single grade, quota park/resume, worker failure, conductor resume, GitHub polling, and recovery observation.

Acceptance:

- Wall and same-boot monotonic evidence both reach 12 hours; labels or simulated time do not count.
- There are no duplicate dispatches, active leases, provider sessions, unverified completions, hidden recoveries, or manual state repairs.
- A recoverable fault resolves within two watchdog intervals or becomes explicit blocked evidence with no active owner.
- Independent verification accepts the exact evidence set; PR merge and release remain human-held.

Blocked by: CD-06.

### CD-08 — Fresh elapsed 24-hour canary and closeout

After independent acceptance of CD-07, start a new goal/run/ticket set and execute the same invariants for 24 elapsed hours.

Acceptance:

- The 24-hour run uses fresh goal, run, ticket, dispatch, session, process, and evidence identities.
- Every CD-07 invariant holds for 24 real elapsed hours.
- GitHub event, team-delivery, deterministic-verification, and grade evidence are refreshed.
- Closeout lists proven and unproven obligations without adding a positive release state or automatic merge.

Blocked by: CD-07.

## Dependency graph

```text
CD-01 conductor + goal
  -> CD-02 dispatch + states
    -> CD-03 workers + teams
      -> CD-04 events + recovery ----+
      -> CD-05 verify + grade -------+-> CD-06 live GitHub PR
                                          -> CD-07 12h canary
                                            -> CD-08 fresh 24h canary
```

## Removed from the previous roadmap

- Per-ticket human launch ceremonies: the human starts only the conductor.
- Product-facing external team/goal workflow commands: OMS owns its team and long-worker adapters.
- Raw conductor tmux commands: provider adapters encapsulate transport.
- Separate quota, long-goal, and team-proof implementation tracks: each now lands in the vertical slice that consumes it.
- Custom shell scripts: all tracked deterministic automation remains TypeScript.
- Separate team-verifier/model-review layers: executor groups feed the same deterministic gate plus one fresh cross-engine grade used by every ticket.

## Global verification gate

Every implementation issue must run targeted tests first, then:

```text
npm run typecheck
npm test
npm run build
node dist/src/cli.js verify
git diff --check
```

Also verify no tracked runtime state or secrets, no tracked shell automation, no product/runtime dependency on another orchestration CLI, and no claim beyond the evidence class.

## Stop conditions

Stop and preserve evidence on unknown provider eligibility or billing, failed auth/version/tool-permission preflight, unavailable mandatory opposite-engine grading, invalid/replayed structured proposal, stale goal/ticket/lease/dispatch/result authority, completion without a valid result receipt, lost/contradictory notification authority, capability expansion, candidate-tree drift, deterministic failure, duplicate owner/start, continuity gap, exhausted attempts, secret finding, branch mismatch, or attempted merge/release authority. Recovery may choose only a path already allowed by the durable policy.
