Codex-led task dispatch and review for local CLI coding agents.
">https://img.shields.io/badge/node-%3E%3D22-339933.svg">
Quickstart | How It Works | MCP Tools | Security | Roadmap
TaskMarshal turns Codex into a technical lead for local AI coding agents. Codex decides when delegation is worth it, writes a bounded task spec, sends work to a worker, observes progress, gates permissions, and reviews the result before accepting it.
The first worker providers are DeepSeek-Reasonix and Claude Code. The provider layer is intentionally generic so future adapters can target Gemini CLI, Codex CLI, or other local coding agents.
User -> Codex -> TaskMarshal Skill -> taskmarshal-mcp -> Provider Adapter -> CLI Worker
Coding agents are useful executors, but architecture ownership should stay with the lead agent. TaskMarshal keeps that boundary explicit.
| Problem | TaskMarshal's answer |
|---|---|
| "Should I delegate this?" | A Codex Skill scores the task and skips workers for simple work. |
| "How do I control another CLI agent?" | An MCP server exposes structured worker tools instead of TUI scraping. |
| "Who approves risky actions?" | Codex keeps the permission gate and can approve, deny, or cancel worker turns. |
| "How do I review worker output?" | Codex treats worker results as proposed patches and verifies them locally. |
| "Can this support more than Reasonix?" | Providers are named explicitly; reasonix is the first adapter, not the whole system. |
- Provider-neutral MCP tools:
worker_* - Optional Reasonix compatibility tools:
reasonix_* - Provider-neutral CLI:
taskmarshalctl.js;reasonixctl.jsis a shim - Persistent Reasonix ACP sessions
- DeepSeek v4
flash/proselection for Reasonix - Claude Code one-shot and resumable logical sessions
- Manual approval gate for worker permissions
- Event observation through JSONL session logs
- Compact observation modes for token-sensitive supervision
- Session summaries with lightweight task metrics
- Cross-session metrics reports for routing and token-efficiency tuning
- Compact task ledger reports for closeout and verification hygiene
- Token-firewall task gates with short control packets and task keys
- Merged
worker_task_gatefor route/create/checkpoint/verify/finalize/closeout control - Batch task gate calls for fewer MCP round trips
- Minimal and ultra-minimal MCP tool profiles plus compact tool text mode
- Incremental observation cursors and compact metrics reports
- Tail-limited metrics scans for lower filesystem and context overhead
- Default worker output contract with 1200-character final-output cap
- Compact repo context query with optional CodeGraph backend
- Pro second-pass review planning for higher-risk verification
- Codex Skill for autonomous delegation decisions
- TaskSpec and worker yield templates for bounded delegation
- Secret-free repository: no API keys, transcripts, or local state
Reasonix:
npm install -g reasonix
reasonix setup
reasonix doctorReasonix stores its DeepSeek API key in your local user config:
~/.reasonix/config.json
TaskMarshal does not need this key in the repository.
Claude Code:
claude --version
claude authgit clone https://github.com/BRCOO/TaskMarshal.git
cd TaskMarshal
npm install
npm run check
npm run mcp:smoke
npm run eval
npm run eval:tokens
npm run eval:quality
npm run eval:codex-ab
npm run eval:skilloptRecommended token-saving config:
node taskmarshalctl.js install-codex-config --write-user
codex mcp listThis writes a taskmarshal-mcp server entry to ~/.codex/config.toml with
TASKMARSHAL_TOOL_PROFILE=minimal and
TASKMARSHAL_COMPACT_TOOL_TEXT=1. It also enables the default worker output
contract with TASKMARSHAL_WORKER_OUTPUT_CONTRACT=1 and
TASKMARSHAL_WORKER_OUTPUT_MAX_CHARS=1200. Restart Codex after changing MCP
config.
For the smallest MCP tool list, use:
node taskmarshalctl.js install-codex-config --write-user --profile ultra-minimalultra-minimal keeps the active orchestration path, including
worker_context_query, persistent session controls, observation,
approval/denial, stop, and the merged worker_task_gate.
Manual registration is also supported.
Windows:
codex mcp add taskmarshal-mcp -- node C:\\path\\to\\TaskMarshal\\mcp-server.js
codex mcp listmacOS/Linux:
codex mcp add taskmarshal-mcp -- node /path/to/TaskMarshal/mcp-server.js
codex mcp listWindows PowerShell:
Copy-Item -Recurse .\skills\taskmarshal "$env:USERPROFILE\.codex\skills\taskmarshal" -ForcemacOS/Linux:
mkdir -p ~/.codex/skills
cp -R skills/taskmarshal ~/.codex/skills/taskmarshalRestart Codex or open a fresh Codex thread if newly registered MCP tools or skills do not appear immediately.
Codex Skills are recalled by metadata, not as guaranteed global hooks. If you want Codex to consider TaskMarshal on every request, copy the global instruction template into your Codex home:
Windows PowerShell:
Copy-Item .\examples\codex-AGENTS.md "$env:USERPROFILE\.codex\AGENTS.md" -ForcemacOS/Linux:
cp examples/codex-AGENTS.md ~/.codex/AGENTS.mdThis does not force every task into Reasonix. It only makes Codex run a silent routing check first, then choose Local Mode, Light Mode, or Full Marshal Mode.
User
|
v
Codex -- decides whether delegation is worth it --> Local Mode
|
| uses TaskMarshal Skill
v
taskmarshal-mcp
|
| worker_* tools
v
taskmarshalctl adapter -- current provider --> Reasonix / DeepSeek
|
| ACP JSON-RPC
v
session events/logs --> Codex observes, approves, denies, and reviews
The TaskMarshal Skill chooses between:
- Local Mode: Codex handles simple work directly.
- Light Mode: one bounded worker prompt.
- Full Marshal Mode: Codex plans, dispatches, observes, approves, reviews, and verifies.
TaskMarshal includes a read-only context adapter for repository understanding
without exposing raw graph/search logs to Codex. worker_context_query is the
only MCP surface Codex needs. It returns a compact packet with relevant files,
symbols, impact hints, risks, confidence, and hard size limits.
The default backend is auto:
- If
@colbymchenry/codegraphis installed and the target repo has a local.codegraph/index, TaskMarshal uses CodeGraph's CLI JSON context output. - Otherwise it falls back to
local-static, which scans bounded local text files and ranks relevant paths and symbols.
This keeps CodeGraph hidden behind TaskMarshal instead of registering external CodeGraph MCP tools directly, so Codex gets one small context packet rather than a larger tool list.
npm install --save-optional @colbymchenry/codegraph
npx codegraph init .
npx codegraph sync .
node taskmarshalctl.js context query --goal "fix worker observe summary" --scope "mcp-server.js,taskmarshalctl.js"
node taskmarshalctl.js context query --goal "fix worker observe summary" --backend local-staticCodeGraph writes its local index to .codegraph/, which is gitignored. The
context query does not initialize or sync indexes automatically because the MCP
tool is read-only. If the index has pending changes, the packet includes a risk
hint telling the operator to run codegraph sync.
TaskMarshal keeps worker handoffs small by default. Reasonix and Claude Code
prompts receive a short output contract, and final worker text is capped before
it is persisted for later observe final or summary reads.
Default final labels:
changedFiles / commands / verification / risks / next
Default cap: 1200 characters. Full event/transcript logs remain local for
debugging, but Codex should not read them during normal supervision.
Controls:
TASKMARSHAL_WORKER_OUTPUT_CONTRACT=0
TASKMARSHAL_WORKER_OUTPUT_MAX_CHARS=2000
node taskmarshalctl.js send SESSION --output-max-chars 2000 "task"
node taskmarshalctl.js send SESSION --no-output-contract "task"To quantify token-saving regressions, run:
npm run eval:tokens
npm run eval:quality
npm run eval:codex-ab
npm run eval:skilloptThe benchmark compares standard, minimal, and ultra-minimal MCP tool-list size, event observation vs summary/final observation size, and normal vs compact metrics output. It reports exact character counts plus an approximate token estimate, and fails if compact paths exceed fixed budgets.
The quality benchmark uses deterministic local fixtures to exercise the same compact metrics path used by routing. It checks worker success rate, task verification pass rate, unknown-verification rate, redo count, average compact assistant output size, output-contract coverage, and compact metrics payload size. It is a regression gate for telemetry quality; live worker A/B quality still needs real task verification records.
The Codex A/B benchmark compares Codex-only, Codex+TaskMarshal, and
Codex+TaskMarshal+codegraph-style context runs. It reports Codex input/output
token savings separately from worker token usage, then checks quality with
pass-rate, severe-issue, and redo-count non-inferiority budgets. The third
variant is named taskmarshal+codegraph and is used to measure whether compact
repo context packets add savings beyond the TaskMarshal baseline. The default
run uses synthetic records so CI can verify the math. Real run records can be
passed as JSONL:
npm run eval:codex-ab -- --input runs/codex-ab.jsonlEach record should include:
{
"taskId": "large-debug-001",
"size": "large",
"variant": "taskmarshal+codegraph",
"codexInputTokens": 12000,
"codexOutputTokens": 2800,
"workerInputTokens": 9500,
"workerOutputTokens": 12000,
"passed": true,
"qualityScore": 0.95,
"severeIssues": 0,
"redoCount": 0,
"elapsedSec": 420
}TaskMarshal can use microsoft/SkillOpt
as an offline optimizer for skills/taskmarshal/SKILL.md. SkillOpt is not part
of the MCP runtime path and does not add tools or model calls during normal
Codex use.
The stable integration point is a local acceptance gate:
npm run eval:skillopt
npm run eval:skillopt -- --candidate runs/skillopt/best_skill.mdThe gate checks candidate skill length, required TaskMarshal routing policies,
secret-shaped text, and expected routes from
examples/skillopt/taskmarshal-routing-cases.jsonl. Candidate runs and rollout
logs should stay under ignored paths such as runs/skillopt/. See
docs/SKILLOPT_INTEGRATION.md for the full workflow.
| Provider | Status | Persistent sessions | Observe | Manual approval | Cancel | Model selection | Cost info | Notes |
|---|---|---|---|---|---|---|---|---|
| Reasonix / DeepSeek | Implemented | Yes | Yes | Yes | Yes | Yes (flash/pro) |
No | Uses reasonix acp through taskmarshalctl; supports DeepSeek v4 flash and pro. |
| Claude Code | Implemented | Logical session | Yes | No | No | Yes | Yes, when Claude CLI reports it | Uses claude -p --output-format json; permissions stay inside Claude Code. |
| Gemini CLI | Planned | TBD | TBD | TBD | TBD | TBD | TBD | Future adapter. |
| Codex CLI | Planned | TBD | TBD | TBD | TBD | TBD | TBD | Future adapter. |
Provider-neutral tools:
| Tool | Purpose |
|---|---|
worker_list_providers |
List available worker providers. |
worker_doctor |
Check provider installation/configuration. |
worker_context_query |
Return compact repository context for a task goal. |
worker_ask |
Run one prompt with a worker. |
worker_start_session |
Start a persistent worker session. |
worker_list_sessions |
List known worker sessions. |
worker_status |
Inspect one worker session. |
worker_send_task |
Send a bounded task to a session. |
worker_observe |
Read compact worker state by default; pass mode: "events" only for raw event tails. |
worker_summarize_session |
Return a compact session digest and lightweight metrics. |
worker_metrics_report |
Return a compact cross-session metrics report for routing and token-efficiency decisions. |
worker_task_gate |
Merged token-firewall gate for route, create, checkpoint, verify, finalize, close-verified/read-only, and ordered batches. |
worker_route_decision |
Return a short deterministic Local/flash/pro routing decision. |
worker_create_task |
Create a local token-firewall task ledger and return a short control packet. |
worker_checkpoint_step |
Mark one task step done. |
worker_record_verification |
Record pass/fail/skip verification. |
worker_finalize_task |
Return a taskKey proof when gates pass. |
worker_plan_pro_review |
Build a bounded DeepSeek v4 pro second-pass review task. |
worker_approve |
Approve a pending permission request. |
worker_deny |
Deny a pending permission request. |
worker_cancel |
Cancel the current worker turn. |
worker_stop |
Stop a worker session. |
For Reasonix, worker_ask and worker_start_session accept:
| Option | Values | Notes |
|---|---|---|
model |
flash, pro, deepseek-v4-flash, deepseek-v4-pro |
flash maps to deepseek-v4-flash; pro maps to deepseek-v4-pro. |
preset |
auto, flash, pro |
Passed through to Reasonix preset selection. |
Use flash for quick exploration, routine implementation, and low-cost long sessions. Use pro for hard architecture, tricky debugging, final review, or higher-stakes verification.
For broad audits or slow investigations, avoid worker_ask / reasonix_ask. Those one-shot tools block until the worker finishes and can hit the host MCP timeout. Use persistent sessions instead:
worker_start_session(provider: "reasonix", id: "audit", approve: "manual", model: "flash")
worker_send_task(provider: "reasonix", id: "audit", taskId: "task", prompt: "Read-only audit ...")
worker_observe(provider: "reasonix", id: "audit", mode: "summary", maxChars: 4000)
Codex should continue local work while the worker runs and treat the result as a later second pass.
Observation modes:
| Mode | Purpose |
|---|---|
summary |
Compact session state, last turn, pending permission, and recent event types. |
final |
Final assistant text or latest assistant preview. |
permission |
Pending permission state only. |
events |
Full recent event tail for debugging worker behavior. |
worker_observe defaults to summary mode. Use maxChars to cap large text
fields before they enter Codex context.
Use the returned cursor.cursor as since on the next worker_observe call
to read only new events.
Reasonix compatibility aliases are also available:
reasonix_doctor
reasonix_ask
reasonix_start_session
reasonix_list_sessions
reasonix_status
reasonix_send_task
reasonix_observe
reasonix_summarize_session
reasonix_metrics_report
reasonix_approve
reasonix_deny
reasonix_cancel
reasonix_stop
Set TASKMARSHAL_HIDE_LEGACY_REASONIX_TOOLS=1 before launching
taskmarshal-mcp to hide the reasonix_* compatibility tools and reduce the
MCP tool list. The provider-neutral worker_* tools remain available.
For a small Codex tool-list and tool-result footprint, launch the MCP server with:
TASKMARSHAL_TOOL_PROFILE=minimal
TASKMARSHAL_COMPACT_TOOL_TEXT=1minimal exposes the core provider tools plus worker_task_gate and hides
legacy Reasonix aliases automatically. TASKMARSHAL_COMPACT_TOOL_TEXT=1 keeps
full structuredContent for clients, but reduces the visible text result to a
one-line control summary.
For the smallest practical tool list, use:
TASKMARSHAL_TOOL_PROFILE=ultra-minimal
TASKMARSHAL_COMPACT_TOOL_TEXT=1ultra-minimal exposes only worker_context_query, worker_start_session,
worker_send_task, worker_observe, worker_task_gate, worker_approve,
worker_deny, and worker_stop. Routing still uses compact metrics internally
through worker_task_gate(action: "route"), but direct provider listing,
doctor, metrics, one-shot ask, compatibility aliases, and separate gate helper
tools are hidden to reduce Codex input tokens.
To install that setup into Codex user config:
node taskmarshalctl.js install-codex-config --write-user
node taskmarshalctl.js install-codex-config --write-user --profile ultra-minimalBy default, install-codex-config only prints the TOML snippet. With
--write-user, it updates ~/.codex/config.toml and writes a timestamped
backup before changing an existing file.
Use the Reasonix adapter without MCP:
node taskmarshalctl.js doctor
node taskmarshalctl.js models
node taskmarshalctl.js smoke
node taskmarshalctl.js metrics --limit 10 --compact
node taskmarshalctl.js ask "Summarize this repository. Do not edit files." --approve cancel
node taskmarshalctl.js ask "Review this design for risks." --approve cancel --model proPersistent session:
node taskmarshalctl.js start --id architect --dir C:\\path\\to\\repo --approve manual
node taskmarshalctl.js start --id reviewer --dir C:\\path\\to\\repo --approve manual --model pro
node taskmarshalctl.js send architect "Analyze the repo. Do not edit files."
node taskmarshalctl.js observe architect --mode summary --max-chars 4000
node taskmarshalctl.js observe architect --mode summary --since 120 --max-chars 4000
node taskmarshalctl.js summarize architect --max-chars 6000
node taskmarshalctl.js approve architect
node taskmarshalctl.js deny architect
node taskmarshalctl.js stop architectUse --approve manual when Codex should gate worker permissions. Use
--approve cancel for read-only one-shot analysis. reasonixctl.js remains as
a compatibility shim for older scripts.
Claude Code provider through MCP:
worker_ask(provider: "claude-code", prompt: "Analyze this repo in plan mode", approve: "cancel")
worker_start_session(provider: "claude-code", id: "claude-review", approve: "cancel")
worker_send_task(provider: "claude-code", id: "claude-review", taskId: "task", prompt: "Review these files")
worker_observe(provider: "claude-code", id: "claude-review", mode: "summary", tail: 20)
Claude Code does not expose an external permission callback to TaskMarshal. worker_approve, worker_deny, and worker_cancel return unsupported for claude-code; use Claude Code permission modes for safety.
The economical TaskMarshal loop is:
- Codex calls
worker_task_gate(action: "route")for a short Local/flash/pro decision. - Codex calls
worker_task_gate(action: "create")with only short fields. - Worker returns a short plan before edits for Full Marshal tasks.
- Codex observes with
mode: "summary"ormode: "permission". - Codex asks
worker_summarize_sessionfor a compact digest and metrics when the worker finishes. - Codex checks
worker_metrics_reportwhen routing quality or token cost needs evidence. - Codex records verification with
worker_task_gate(action: "verify"). - Codex finalizes with
worker_task_gate(action: "close-verified")when all remaining steps are already evidenced, orworker_task_gate(action: "finalize")after explicit checkpoints. Accept only with a taskKey.
For read-only audits, Codex can close all remaining ledger steps, record verification, and finalize in one compact call:
worker_task_gate(action: "close-readonly", id: "TASK_ID", status: "pass", command: "read-only audit")
For implementation tasks that already have a pass/skip verification but still show pending ledger steps, close them in one compact call:
worker_task_gate(action: "close-verified", id: "TASK_ID", note: "verified by npm test")
To inspect ledger health without loading task files or worker logs, use:
worker_task_gate(action: "tasks")
When several gate operations are ready at once, Codex can use
worker_task_gate(batch: [...]) to reduce MCP round trips. For long worker
sessions, Codex should observe once, store the returned cursor, then pass it as
since on the next observation to avoid re-reading old event tails.
Task ledgers are written under local .taskmarshal/tasks/ and are gitignored.
MCP tools return short control packets by default; large task artifacts stay on
disk unless explicitly inspected.
Keep tasks local to Codex when the relevant evidence is user-specific local
state outside the repository, such as installed Codex skills, ~/.codex,
~/.agents, MCP config, provider API-key config, or shell profiles. Workers may
not share the same permissions. If a worker audit is already running and hits a
permission boundary, stop or ignore it, state the limitation, and continue from
local evidence instead of waiting for an independent opinion it cannot produce.
Use flash for exploration, routine implementation, and low-risk long
sessions. Use pro only for architecture decisions, tricky debugging,
security-sensitive changes, uncertain flash results, or final verification
where a stronger second pass is worth the cost. worker_plan_pro_review returns
a bounded read-only review prompt and recommended pro session settings.
Reasonix session summaries are also written to
~/.reasonixctl/sessions/<id>/session-summary.json. New persistent Reasonix
turns append lightweight metrics to metrics.jsonl, including model, elapsed
time, prompt/assistant character counts, permission counts, errors, and
verification placeholders for future routing feedback.
Use worker_metrics_report(compact: true) or
taskmarshalctl metrics --limit 20 --compact to inspect
recent turns without loading raw events.jsonl or transcripts into Codex
context. Verification records from task gates are included in the metrics
report, so routing quality can be judged from local pass/fail/skip evidence.
Compact metrics reads only recent metric tails per session and omits long task
verification detail lists.
Use worker_task_gate(action: "tasks") or
taskmarshalctl tasks --compact --limit 20 when the problem is ledger hygiene:
open tasks, pass-but-not-finalized tasks, stale read-only audits, or malformed
task records. This keeps Codex from reading .taskmarshal/tasks/**/task.json
one file at a time.
taskmarshalctl route uses compact metrics evidence when available. It keeps
small tasks local, tightens worker output budgets when recent worker output is
large, and can upgrade a flash route to pro when recent verification or
failure history shows that the cheaper path is not reliable enough.
When dispatching a token-firewall task to a worker, pass the task id to
worker_send_task or taskmarshalctl send --task-id TASK_ID. The worker turn
metric keeps that task id, and worker_metrics_report automatically merges the
later task-gate verification by task id. taskmarshalctl verify also patches
the newest matching unknown worker metric by task id when no session/turn id is
provided.
If a worker turn was sent without a task id, pass both --session SESSION_ID
and --turn-id TURN_ID when recording verification to patch the matching metric
directly:
taskmarshalctl send audit --task-id TASK_ID "implement the bounded task"
taskmarshalctl verify --id TASK_ID --status pass --command "npm test" --session audit --turn-id TURN_IDTemplates:
| Template | Purpose |
|---|---|
examples/task-spec.yaml |
Structured delegation packet. |
examples/worker-yield-summary.md |
Compact worker handoff format. |
examples/worker-self-review.md |
Worker pre-handoff checklist. |
docs/ORCHESTRATION_GUIDE.md |
Detailed lead/worker operating model. |
TaskMarshal is not meant to run for every coding request.
Good fits:
- multi-file implementation
- broad repository investigation
- long-running debugging
- independent verification
- planner/executor/reviewer workflows
Poor fits:
- quick Q&A
- simple terminal checks
- tiny one-file patches
- formatting or typo fixes
- routine documentation edits
The Skill's scoring rule is intentionally simple. It loads for tasks that look delegation-worthy, then may still choose Local Mode if the overhead is not justified.
TaskMarshal should never contain your provider API keys or private transcripts.
Ignored by default:
.env.reasonix/.reasonixctl/runs/sessions/transcripts/events/*.jsonl- private key formats such as
*.pem,*.key,*.p12,*.pfx
Recommended pre-push checks:
git status --short
npm run check
npm run mcp:smoke
npm run eval
git grep -n -E "sk-[A-Za-z0-9_-]{20,}|api[_-]?key|token|secret|password" -- .The grep may match documentation or source identifiers. Review matches before committing.
.
|-- mcp-server.js # TaskMarshal MCP server
|-- taskmarshalctl.js # Provider-neutral TaskMarshal CLI
|-- reasonixctl.js # Compatibility shim
|-- lib/acp-client.js # ACP JSON-RPC client
|-- skills/taskmarshal/ # Codex Skill
|-- scripts/mcp-smoke.js # MCP smoke test
|-- scripts/taskmarshal-eval.js # Local routing and task-gate evals
|-- scripts/skillopt-gate.js # Offline SkillOpt candidate gate
`-- examples/ # Example config and worker prompt
- Provider adapter interface
- Gemini CLI provider
- Claude Code CLI provider
- Provider capability scoring
- Task spec persistence
- Better transcript summarization and metrics-based routing
- Offline SkillOpt-driven skill compression and routing improvement
- Packaged Codex plugin
Issues and pull requests are welcome. Keep provider adapters scoped, keep secrets out of fixtures, and add a smoke test path whenever a provider exposes new MCP tools.
MIT