Mythify Design Specification
August 4, 2026 ยท View on GitHub
This document is the single source of truth for Mythify's contracts: the CLI command
surface, the MCP tool surface, the on-disk state formats, and the output conventions.
The Python CLI (scripts/mythify.py) and the MCP server (mcp-server/src/index.js)
are independent implementations of the same contracts and must interoperate on the
same state directory.
Goals
- Real verification. Completion claims are checked by executing commands and reading exit codes, not by self-report. Self-attested claims are allowed but are recorded and displayed as second-class evidence.
- Per-project state. Each project owns a
.mythify/directory. The only global state is the cross-project lessons store. - Proportional ceremony. Protocol overhead scales with task size. Trivial tasks pay zero overhead.
- Durability. Atomic writes, corrupt-file recovery, and no crashes on bad state.
Writing rules (every file in this repository)
- No emojis. Use ASCII markers:
[OK],[FAIL],[WARN]. - No em dashes (U+2014) and no en dashes (U+2013). Use commas, colons, parentheses, or plain hyphens instead.
- No pending-work markers, no placeholder content. Every file ships complete.
- Documentation is imperative and concise.
- Exception:
docs/research-report.mdis preserved legacy content, copied verbatim, and is exempt from these character rules.
Repository layout (contract-bearing files)
This tree names the public contract files and load-bearing runtime boundaries. It is not an exhaustive inventory of every helper or test file.
mythify/
|-- README.md
|-- LICENSE MIT, holder "Mythify contributors", year 2026
|-- .gitignore
|-- CLAUDE.md generated from protocol/PROTOCOL.md
|-- AGENTS.md generated from protocol/PROTOCOL.md
|-- .cursorrules generated from protocol/PROTOCOL.md
|-- protocol/
| |-- PROTOCOL.md canonical protocol source
| |-- classification-rules.json deterministic classifier keywords
| |-- model-capabilities.json shared model profile and provider mappings
| |-- operation-registry.json shared operation metadata
| |-- release-gates.json exact-command release readiness gates
| |-- workflow-router.json shared workflow route metadata
| `-- surface-manifest.json shared public surface metadata
|-- scripts/
| |-- mythify.py zero-dependency CLI orchestrator
| |-- mythify_classification.py deterministic classification helper
| |-- mythify_evidence_guard.py advisory evidence-quality guards
| |-- mythify_godfiles.py godplans PLAN.mdx and godaudits AUDIT.mdx reader
| |-- mythify_host_model.py host model switch record helper
| |-- mythify_io.py durable IO helper
| |-- mythify_log_compaction.py verification-log compaction helper
| |-- mythify_loopfit.py loop-worthiness analysis helper
| |-- mythify_map_parser.py wayfinding map subcommand parser
| |-- mythify_maps.py wayfinding decision map store and gates
| |-- mythify_memory.py memory and lesson helper
| |-- mythify_model_policy.py model policy and triage helper
| |-- mythify_model_routing.py provider-neutral topology and review helper
| |-- mythify_outcomes.py outcome loop helper
| |-- mythify_parser.py CLI argument parser construction
| |-- mythify_plan_import.py godplans and godaudits plan import helper
| |-- mythify_protocol.py protocol handshake and frozen-manifest checks
| |-- mythify_provenance.py verification provenance helper
| |-- mythify_router.py prompt packet and workflow route helper
| |-- mythify_runtime_helpers.py shared CLI runtime helpers
| |-- mythify_trace.py trace analysis and playbook helper
| |-- mythify_views.py read-only dashboard and progress helper
| |-- mythify_views_status.py readiness and status view helper
| |-- mythify_workflows.py research and campaign workflow helper
| |-- build_variants.py generates CLAUDE.md, AGENTS.md, .cursorrules
| |-- build_registry_docs.mjs generates registry-backed docs
| |-- check_surface_manifest.mjs checks public surface metadata drift
| |-- check_runtime_source_size.py recursive runtime size guard
| |-- install_user.sh user-local CLI and MCP launcher installer
| |-- local_model_eval.py local bare-vs-Mythify comparison harness
| |-- package_cli.py builds deterministic standalone CLI tarball
| `-- package_skill.py builds dist/mythify.skill from skills/mythify/
|-- mcp-server/
| |-- package.json
| |-- mcp-config.example.json
| |-- client-configs/
| |-- src/capability-registry.js
| |-- src/classification.js
| |-- src/evidence-guard.js JS mirror of mythify_evidence_guard.py
| |-- src/execution-adapter.js
| |-- src/fanout.js
| |-- src/fanout-prompt.js
| |-- src/godfiles-core.js JS mirror of mythify_godfiles.py
| |-- src/host-model.js
| |-- src/host-cli.js
| |-- src/index.js
| |-- src/lifecycle-adapter.js
| |-- src/map-tools.js wayfinding map tools and shared map helpers
| |-- src/model-policy.js
| |-- src/model-provider.js
| |-- src/operation-registry.js
| |-- src/plan-tools.js
| |-- src/prompt-packets.js prompt packet builders shared by route and prompt
| |-- src/provider-defaults.js
| |-- src/surface-manifest.js
| |-- src/verification-provenance.js
| |-- protocol/classification-rules.json package copy of classifier keywords
| |-- protocol/model-capabilities.json package copy of model profile policy
| |-- protocol/operation-registry.json package copy of operation metadata
| |-- protocol/release-gates.json package copy of readiness gates
| |-- protocol/workflow-router.json package copy of route metadata
| |-- protocol/surface-manifest.json package copy of public surface metadata
| |-- test/capability-registry.test.js
| |-- test/execution-probe.test.js
| |-- test/execution-adapter.test.js
| |-- test/host-cli-probe.test.js
| |-- test/host-cli-run.test.js
| |-- test/host-cli.test.js
| |-- test/lifecycle-adapter.test.js
| |-- test/lifecycle-probe.test.js
| |-- test/local-model-run.test.js
| |-- test/map-tools.test.js
| |-- test/model-policy.test.js
| |-- test/model-provider.test.js
| |-- test/provider-defaults.test.js
| |-- test/provider-probe.test.js
| |-- test/smoke.test.js
| `-- test/fanout.test.js
|-- skills/
| `-- mythify/
| |-- SKILL.md
| `-- references/
| |-- autonomy-loop.md
| |-- self-verification.md
| |-- memory-system.md
| |-- meta-prompts.md
| `-- godplans-godaudits.mdx
|-- tests/
| |-- test_mythify.py CLI unit and end-to-end tests (stdlib unittest)
| |-- test_godfiles.py god artifact parser, plan import, routing, views
| |-- test_maps.py wayfinding map gates, promotion, and surfaces
| |-- test_routes.py workflow router decision-tree coverage
| |-- test_campaign_discipline.py campaign verifier gate and hygiene tests
| |-- test_interop.py CLI and MCP server against the same state dir
| |-- test_local_model_eval.py offline test for the local comparison harness
| `-- fixtures/godfiles/ shared PLAN.mdx and AUDIT.mdx parity fixtures
`-- docs/
|-- design.md this document
|-- codex-integrations.md Codex Desktop, CLI, MCP, and benchmark setup
|-- claude-integrations.md Claude Desktop and Claude Code guide
|-- adapter-candidates.md generated from the capability registry
|-- antigravity-mcp-setup.md Antigravity CLI probe and MCP setup guide
|-- agents-cli-adk-spike-plan.md Google Agents CLI and ADK probe plan
|-- colab-cli-spike-plan.md Google Colab CLI non-billable spike plan
`-- research-report.md preserved research report
dist/ (built skill packages) and node_modules/ are build outputs, ignored by git.
One-core architecture decision
Decision: Mythify will move toward one shared contract core, but it will not do a whole-runtime rewrite yet. The Python CLI and Node MCP server stay as separate host adapters. Shared behavior moves behind small, checked contract artifacts only after duplication has produced drift or maintenance pressure.
Evidence for the decision:
- The CLI and MCP already duplicate state I/O, JSONL reads, atomic writes,
shell verification, plan updates, outcome loops, model policy, host-model
records, and dashboard formatting. Examples include
build_dashboardinscripts/mythify.pyandbuildWorkflowDashboardinmcp-server/src/index.js, plus parallelrun_shell_captureandrunShellCaptureimplementations. - The shared registries are working where the duplicated facts are narrow:
protocol/operation-registry.jsonowns memory operation metadata, andprotocol/classification-rules.jsonowns deterministic classifier keyword metadata.protocol/workflow-router.jsonowns route ids, prompt mapping, and output field metadata.mcp-server/src/capability-registry.jsowns host, provider, execution, and lifecycle capability metadata. - Drift is still easy to create in prose and copied surface metadata. The dashboard slice raised the MCP tool contract to 30 tools, while the README component summary still said 29 until this decision pass.
tests/test_interop.pyproves the two runtimes can share one.mythifystate directory for mutating state families, so migration can be incremental without breaking existing users.
Policy:
- Keep Python CLI command handling, Node MCP handler wiring, host CLI process execution, and MCP fanout runtime code in their native adapters for now.
- Put shared facts into explicit artifacts first: protocol files, operation registries, capability registries, generated docs, schemas, or manifests.
- Add or expand a shared artifact only when a focused drift test protects the generated or shared output.
- Prefer data contracts and generation over a cross-language runtime dependency until at least two more duplicated surfaces demonstrate recurring drift.
- Every migration slice must preserve the on-disk state contract, evidence boundaries, no-mutation guarantees, and CLI/MCP interop tests.
Migration guardrails:
docs/design.mdleads. The contract changes before implementation.- One surface per slice. Do not combine a registry move with unrelated feature work.
- Each shared artifact needs an executable check, not reviewer memory.
- Generated files must carry either a source hash or a check command.
- Runtime output remains material unless an executed verifier records it.
- Rollback must be simple: adapters can keep their local implementation while the shared artifact is corrected.
Dual-runtime parity discipline
The remaining architecture risk is not an open refactor task. It is the ongoing discipline of keeping the Python CLI and Node MCP server aligned while they remain separate native runtimes.
Rules:
- If a behavior is exposed by both the CLI and MCP server, update both implementations or document the intentional asymmetry in this design spec.
- Every shared behavior change must include at least one parity anchor: a
shared manifest or registry update, a cross-runtime fixture, or an interop
assertion in
tests/test_interop.py. - Shared facts should move into protocol files, registries, generated docs, schemas, or manifests before any cross-language runtime dependency is added.
- Do not refactor only to remove duplication. Extract shared artifacts when drift has occurred, when a focused drift test can prove the contract, or when maintenance pressure is visible in repeated edits across both runtimes.
- Keep Python CLI command handling, Node MCP handler wiring, host process execution, and fanout runtime code in their native adapters until at least two more duplicated surfaces show recurring drift.
Required parity gates:
- Python suite:
python3 -m unittest discover -s tests -v. - MCP suite:
npm test --prefix mcp-server. - Interop suite, with MCP dependencies installed:
python3 -m unittest tests.test_interop -v. - Surface manifest check:
node scripts/check_surface_manifest.mjs. - Classification and operation registry mirror check:
node scripts/check_classification_rules_manifest.mjs.
Capability registry
The MCP server keeps host, provider, execution, and lifecycle capability metadata in
mcp-server/src/capability-registry.js. The registry is a contract boundary, not a
router. Listing a candidate adapter does not make it a supported public input.
Registry rules:
- Existing public enums stay stable until this design document changes.
- Candidate adapters can be tracked before
classify_task,host_model_switch, orfanout_startaccept them. - A
truecapability means Mythify has a documented or locally probed path for that adapter. Unknown capabilities default tofalse. - Runtime tools must still verify adapter availability before claiming that anything was applied.
- Generated docs, schemas, and fixtures may be derived from the registry only after a drift test protects the generated output.
- The first generated registry-backed document is
docs/adapter-candidates.md, built frommcp-server/src/capability-registry.jsbynode scripts/build_registry_docs.mjs. - The generated adapter document is informational. It must not become a public input schema, router, or behavior switch.
- The drift gate is byte-for-byte equality between the generated output and
docs/adapter-candidates.md. The Node registry test also compares the generated text against the committed file.
Adapter kinds:
host: host CLI or app-backed coding agents used for bounded worker output.desktop_agent: local desktop agent surface without a stable automation contract.model_provider: local OpenAI-compatible model backends for reader and triage roles.api_provider: hosted model APIs that need explicit billing and data movement posture before execution.custom_adapter: user-defined command or future HTTP adapters.execution_substrate: runtime that executes remote or local jobs and returns logs, files, or artifacts.agent_lifecycle: scaffold, test, deploy, or observe tools for agents.
Stable adapter interface v1:
All candidates can be normalized to the same metadata fields: id, kind,
status, locality, openai_compatible, probe_supported,
run_supported, execution_enabled, writes_state, evidence_status,
material_not_evidence, billing, roles, and guardrails.
This interface is descriptive only. It does not add hidden provider fallback,
does not turn metadata-only candidates into runnable adapters, and does not
grant permission for workers to write state.
The current public host platforms remain auto, unknown, codex-desktop,
codex-cli, claude-desktop, claude-code, cursor-desktop, and
cursor-agent. Adapter profiles such as generic OpenAI-compatible local
providers, Ollama, LM Studio, llama.cpp, vLLM, Kimi Code, OpenCode,
Antigravity, Kimi Work, OpenCode Desktop, Google Colab CLI, Google Agents CLI,
and Google ADK CLI live in the registry instead of the host platform enum.
Kimi Work and OpenCode Desktop are metadata-only desktop_agent candidates
until a documented or locally probeable automation surface exists. New
candidates must enter the registry first, then earn public schema support in a
separate verified slice.
Operation registry
Shared operation metadata lives in protocol/operation-registry.json. This is a
runtime contract for duplicated operation facts that have already caused drift,
not a broad router or code generation layer.
Prototype scope:
- The first registered surface is
memory. - The registry owns memory categories, the default category, the memory state
filename, and the no-target
memory_clearrefusal strings for CLI and MCP. - The Python CLI and Node MCP server both load the registry at runtime.
- Tests compare runtime behavior against the registry before any generated docs or schemas are allowed to depend on it.
Keep new surfaces out of the registry until duplication has been observed and a focused drift test proves the shared contract reduces maintenance risk.
Surface manifest
Shared public surface metadata lives in protocol/surface-manifest.json. The
manifest owns duplicated metadata that is easy to drift across prose, tests, and
runtime registrations.
Current scope:
- Top-level CLI command names and command count.
- MCP core tool names, fanout tool names, and the 44 core plus 3 fanout count split.
- Front door, workflow, advanced, and labs tier membership for the CLI and MCP surfaces.
Rules:
- The manifest is not a runtime router. It does not generate tool handlers, command parsers, schemas, or behavior.
mcp-server/src/surface-manifest.jsexposes the manifest to Node tests.- Python tests may read the JSON file directly.
scripts/check_surface_manifest.mjsverifies manifest counts, tier partitions, runtime MCP registrations, public doc count phrases, documented tool names, and CLI--helpoutput.- CI hygiene runs the check so README, design, protocol notes, tests, and runtime registrations cannot quietly disagree about public surface metadata.
- Add a new surface only after drift has been observed and the check can prove the shared metadata reduces maintenance risk.
Classification rules manifest
Shared deterministic task-classification keyword rules live in
protocol/classification-rules.json. The Python CLI and Node MCP server both
load this manifest at startup, so keyword additions such as review wording only
need one data edit.
Rules:
- The manifest owns keyword matching data only. It does not own classification scoring, risk policy, ceremony policy, model policy, fanout policy, or verification hints.
- Keep runtime behavior in the native CLI and MCP adapters unless duplication has already caused drift.
- Python and Node tests must cover any newly added terms that affect public classification behavior.
mcp-server/protocol/classification-rules.json,mcp-server/protocol/model-capabilities.json,mcp-server/protocol/operation-registry.json,mcp-server/protocol/workflow-router.json, andmcp-server/protocol/surface-manifest.jsonare package-local mirrors so the npm tarball can run without access to repository-root files. Runnode scripts/check_classification_rules_manifest.mjs, the MCP smoke suite, andnode scripts/check_surface_manifest.mjsto verify the mirrors.
Model capability manifest
Shared model routing policy lives in protocol/model-capabilities.json. The
Python CLI and Node MCP server load it at startup. Its package-local mirror is
mcp-server/protocol/model-capabilities.json.
The manifest owns:
- The provider-neutral profiles
utility,balanced,strong, andmax. - Legacy input aliases:
fasttoutility,standardtobalanced, andfrontiertostrong. - Task-type defaults, high-risk overrides, and bounded failure escalation.
- OpenAI and Anthropic model mappings plus Cursor runtime catalog preferences.
- The native
claude-ultracodeadapter contract for dynamic-workflow candidates. - The no-implicit-cross-provider-fallback rule and the command-first verifier boundary.
It does not change user authority, host permissions, or verification rules.
Automatic escalation moves one profile for each supplied executed-verifier
failure and stops at strong. max is never selected automatically and
requires an explicit profile request. Cursor mappings intentionally contain no
fixed model id; the worker reads cursor-agent models or cursor agent models,
selects the first matching preferred term for the requested capability profile,
and falls back to Cursor auto only when that id is present. The host still
owns the current chat model.
Run node scripts/check_classification_rules_manifest.mjs to verify both the
classification and model capability mirrors.
Workflow router manifest
Shared workflow route metadata lives in protocol/workflow-router.json. The
Python CLI route command and Node MCP workflow_route tool both load this
manifest at startup.
Rules:
- The manifest owns route ids, route priority metadata, prompt-packet mapping, and the public output field list.
- The manifest is not an execution engine. It does not run checks, mutate state, spawn workers, or complete tasks.
- Route behavior remains native in the CLI and MCP adapters: read active state, inspect the latest executed verification, classify the task, and return a structured route packet.
- Route output is material for the initiating host chat. It keeps the host as executor unless the user explicitly hands work elsewhere.
Experience surface tiers
The router lets Mythify reduce the surface users have to think about without removing compatibility for scripts, MCP hosts, or power users.
Default front door:
- CLI
route,report,verify run, andstatus. - MCP
workflow_route,work_report,verify_run, andworkflow_status.
Workflow primitives:
plan,outcome,campaign,research, andpromptin the CLI.plan_create,plan_add_step,plan_update_step,outcome_start,outcome_check,campaign_next_prompt, andprompt_packetin MCP.
Advanced surfaces:
- Dashboards, history, background, evidence harness, readiness, timeline, phase, trace, memory, lessons, logs, fanout, reflections, summaries, and protocol checks.
Labs surfaces:
- Host-model state, provider probes, local model runs, host CLI workers, execution substrate probes/runs, and lifecycle probes. These surfaces are explicit, material-only, and adapter-facing. They should not be presented as the default product path until they can perform and confirm host actions.
Public help, docs, skills, and MCP tool descriptions should present the default
front door first, then workflow primitives, then advanced surfaces, then labs.
Primitive commands stay available, but broad or ambiguous prompts should route
through route or workflow_route before selecting a lower-level tool.
Background task view
The background task view is a read-only orientation surface for durable long running work:
- CLI command:
background [--recent N] [--json]. - MCP tool:
background_status. - State sources:
.mythify/outcomes/*/goal.json,.mythify/outcomes/*/iterations.jsonl, and.mythify/fanout/<job_id>/job.json. - Output: outcome counts, active outcome, recent outcome loops, fanout job counts, fanout task counts, recent fanout jobs, and each recent job's task statuses.
- Evidence boundary: the view reports recorded verifier iterations and durable task statuses. It must not infer progress from model confidence, host UI state, or whether an MCP server process is currently alive.
- Mutation boundary: the normal path must not create, edit, interrupt, stop, or otherwise mutate outcome or fanout records. It is an orientation view, not a control surface.
Evidence harness view
The evidence harness view is a read-only control surface for autonomous agent work:
- CLI command:
harness [--recent N] [--json]. - MCP tool:
evidence_harness. - State sources: the active plan,
.mythify/verifications.jsonl,.mythify/reflections.jsonl, durable outcome loop state, durable fanout job state, release readiness state, read-only git status for the project root, and godplans and godaudits artifacts when present. - Output: harness status, active plan and outcome, evidence mix, attention
items, outcome and fanout counts, release readiness summary, recent
reflections, and the next control action. Present god artifacts appear under
god_artifactswith status lines; open Critical findings and counter drift become attention items, and with no active plan the next action points atplan import. Advisory evidence-quality watchers add attention items for: recent trivial passes (a green run whose command can never fail or whose output reports zero tests), active legacy gate opt-outs (MYTHIFY_REQUIRE_VERIFIED_STEP=0,MYTHIFY_REQUIRE_HUMAN_INPUT=0,MYTHIFY_DISABLE_RUN=1), steps completed under a waived strict gate, ledger chain breaks, outcome verifier drift (iterations recording different verify commands), and outcomes whose audit recheck failed. All are advisory: they never block completion or downgrade recorded evidence. - Evidence boundary: the view reports durable evidence and durable worker state. Worker output remains material, not verification evidence, until an executed verifier records proof for the merged work.
- Mutation boundary: the normal path must not create, edit, complete, stop, interrupt, retry, tag, publish, push, or otherwise mutate project or Mythify state. It is a control view, not an execution surface.
Outcome progress view
The outcome progress view is a read-only progress surface for verifier-backed outcome loops:
- CLI command:
progress [--recent N] [--json]. - MCP tool:
outcome_progress. - State sources:
.mythify/outcomes/*/goal.json,.mythify/outcomes/*/iterations.jsonl, and the active outcome pointer. - Output: outcome counts, active outcome, recent outcome loops, iteration budget, remaining iterations, last verifier exit, last verifier verdict, metric exit and score when present, and the recorded next action.
- Evidence boundary: the view reports recorded
outcome checkandoutcome_checkverifier iterations. Notes, model prose, and host UI state must not become verification evidence by appearing in the progress view. - Mutation boundary: the normal path must not run checks, make attempts, stop loops, change active outcomes, or edit goal or iteration records. It is a progress display, not a control surface.
Release readiness view
The release readiness view is a read-only release-review surface:
- CLI command:
readiness [--json]. - MCP tool:
release_readiness. - State sources:
.mythify/verifications.jsonl, the exact-command gate inventory inprotocol/release-gates.json,roadmap.md, read-only git status for the project root, and godplans and godaudits artifacts (.godplans/PLAN.mdxand.godaudits/AUDIT.mdx, with.mdfallbacks). - Output: release-review status, required gate rows, each gate's latest
matching executed verifier record, its
freshnessstatus and reason, source file references, top-levelcurrent_provenancewith the current Git commit and Mythify version, gate counts includingstale, project git status, active roadmap slice, andproject_state.godplansandproject_state.godauditssummaries (statusmissingwhen absent; text output prints their lines only when an artifact is present, so projects without god artifacts render byte-identically to before). - Required gates: the shared manifest is authoritative for ids, labels, source paths, and exact normalized commands. The source manifest and packaged MCP mirror must be identical. Current gates cover Python, Node, CLI and MCP interoperability, distribution artifacts, public surface and runtime manifests, generated registry docs, runtime source size, protocol variants, whitespace, dependency audit, release tag binding, and flat release assets.
- Evidence boundary: the view only summarizes recorded executed verifier
records whose normalized
commandexactly matches a manifest command. Claims and output text never select a gate. A passing record satisfies a gate only whenverifiedis true,exit_codeis zero, and itsprovenance.git_commit,provenance.worktree_clean, andprovenance.mythify_versionmatch the clean current checkout. Legacy records without provenance stay readable but report freshnesslegacy, gate statusstale, and do not satisfy release readiness. Missing rows stay missing, failed rows stay failed, and attested claims do not satisfy release gates. If the current Git commit is unavailable, freshness fails closed with reasoncurrent_git_commit_unavailable. Current or recorded dirty worktrees are stale withcurrent_worktree_dirtyorrecorded_worktree_dirty; unavailable recorded cleanliness is stale withrecorded_worktree_cleanliness_unavailable. - Mutation boundary: the normal path must not append, edit, compact, or remove Mythify state, must not rerun release gates, and must not tag, publish, push, or declare the release safe.
Verification history
The verification history is a read-only evidence surface for recorded checks:
- CLI command:
history [--recent N] [--json]. - MCP tool:
verification_history. - State source:
.mythify/verifications.jsonl. - Record kinds: executed records from
verify runandverify_run, plus attested records fromverify claimandverify_claim. - Output: total counts, executed passed count, executed failed count, attested count, recent records, verdicts, command or evidence fields, exit code, duration, output-tail byte counts, and plan or step context when present.
- Evidence boundary: executed records are machine-checked evidence. Attested records remain self-reported and must not be upgraded by appearing in the history view.
- Mutation boundary: the normal path must not append, compact, edit, remove, rerun, or reclassify verification records. It is a history view, not a verifier or log maintenance command.
Work report
The work report is a chat-ready progress surface for visible live narration:
- CLI command:
report [--since last|start] [--format chat|json] [--recent N] [--cursor NAME] [--peek] [--mark]. - MCP tool:
work_report. - State sources: active and inactive plan files,
.mythify/verifications.jsonl,.mythify/reflections.jsonl, and.mythify/reports/<cursor>.json. - Output: an
Attentionsection for failed verification, failed step, failure reflection, and attested warning events, followed by chronological plan creation, step updates, verification verdicts, and reflection events.chatoutput is intended to be pasted or summarized in the host conversation. - Cursor behavior: by default the selected cursor advances to the newest known
event so later
--since lastreports show only new events.--peekleaves the cursor unchanged.--markadvances the cursor to the newest known event without showing old events and is incompatible with--since. - Evidence boundary: the report does not rerun checks, does not upgrade attested claims, and does not prove work beyond recorded Mythify evidence.
- Mutation boundary: the only normal mutation is the cursor file. It must not edit plans, verifications, reflections, memory, lessons, outcomes, fanout jobs, git state, or project files.
Fanout worker timeline
The fanout worker timeline is a read-only orientation surface for delegated worker history:
- CLI command:
timeline [--recent N] [--json]. - MCP tool:
fanout_timeline. - State sources:
.mythify/fanout/<job_id>/job.json, including jobcreated, joblast_updated, taskstarted_at, taskfinished_at, taskduration_seconds, taskstatus, taskerror, and output metadata. - Output: fanout job counts, fanout task counts, recent job records, and chronological events for job creation, task starts, task finishes, failures, interruptions, and pending tasks.
- Evidence boundary: the timeline reports durable worker state. Worker output remains material, not verification evidence, until the orchestrator verifies merged work with an executed check.
- Mutation boundary: the normal path must not create, edit, interrupt, retry, stop, or otherwise mutate fanout jobs or worker tasks. It is a timeline, not a process-control surface.
Phase view
The phase view is a read-only orientation surface for the current workflow shape:
- CLI command:
phase [--recent N] [--json]. - MCP tool:
phase_status. - Phase buckets: Understand, Design, Build, Judge, and Verify.
- State sources: the active plan in
.mythify/plans/, recent verification records, recent reflection records, durable outcome loop state, durable fanout job state, memory counts, and lesson counts. - Output: active plan, goal, each phase's plan steps, each phase's derived step status, evidence count summaries, and the next recorded plan action for that phase.
- Evidence boundary: the view summarizes durable state and executed evidence
counts. It must not grade confidence, infer success from prose, or replace
verify run,verify_run, oroutcome_check. - Mutation boundary: the normal path must not create, edit, complete, fail, archive, interrupt, stop, or otherwise mutate any plan, verification, reflection, outcome, fanout, memory, or lesson state.
State model (shared contract)
State directory resolution
- If the
MYTHIFY_DIRenvironment variable is set, use that path directly as the state directory. Create it (and subdirectories) on demand. - Otherwise walk from the current working directory upward; the first directory
containing a
.mythify/folder wins, and that.mythify/is the state directory. - Otherwise:
- Python CLI:
initcreates./.mythifyand adds.mythify/to the project.gitignorefor the default in-repo state directory. Every other command prints[FAIL] No .mythify workspace found. Run: mythify initand exits 1. - MCP server: lazily creates
<cwd>/.mythifyon first write. Reads with no state respond gracefully (for example "No memory entries yet."), never with a crash.
- Python CLI:
Global lessons live in ~/.mythify/lessons/ and are independent of project state.
Both implementations must resolve the home directory through the HOME environment
variable when it is set (Python Path.home(), Node os.homedir() both already do).
Layout of a state directory
.mythify/
|-- memory.json
|-- host-model.json optional recorded host chat model request
|-- plans/
| |-- active text file containing the slug of the active plan
| |-- <slug>.json
| `-- archive/
| `-- <slug>.json
|-- lessons/
| `-- <slug>.json
|-- outcomes/
| |-- active
| `-- <slug>/
| |-- goal.json
| `-- iterations.jsonl
|-- research/
| |-- active
| `-- <slug>.json
|-- campaigns/
| |-- active
| `-- <slug>.json
|-- maps/
| |-- active
| `-- <slug>.json
|-- reports/
| `-- <cursor>.json
|-- fanout/
| `-- <job-id>/
| |-- job.json
| `-- task-<id>-output.md
|-- logs/
| `-- archive/
| `-- <log-stem>-<YYYYMMDDHHMMSS>.jsonl
|-- locks/
| `-- jsonl-<digest>.lock/
|-- tmp/
| `-- fanout worker prompt files
|-- provider-audit.jsonl
|-- verifications.jsonl
`-- reflections.jsonl
File formats (exact field names; both implementations identical)
memory.json:
{
"entries": [
{"key": "str", "value": "str", "category": "fact|decision|discovery|state", "timestamp": "ISO-8601"}
],
"metadata": {"created": "ISO-8601", "last_updated": "ISO-8601", "total_entries": 0}
}
Keys are unique; set on an existing key overwrites the entry.
host-model.json:
{
"platform": "codex-desktop|codex-cli|claude-desktop|claude-code|cursor-desktop|cursor-agent|unknown",
"requested_platform": "auto|unknown|codex-desktop|codex-cli|claude-desktop|claude-code|cursor-desktop|cursor-agent",
"target_model": "str",
"current_model": "str",
"target_model_tier": "unknown|small|fast|standard|strong|frontier",
"thinking": "auto|low|medium|high|xhigh|max",
"speed": "auto|standard|fast",
"reason": "str",
"status": "recorded_requires_host_action",
"control": "host_selected",
"can_apply_current_chat": false,
"host_capability": {
"kind": "host",
"status": "supported|unknown|unsupported",
"can_switch_current_thread": false,
"can_set_new_thread_model": true,
"can_set_worker_model": true,
"can_set_thinking": true,
"can_list_models": false,
"can_confirm_current_model": false
},
"switch_result": {
"status": "manual",
"requested_model": "str",
"requested_thinking": "auto|low|medium|high|xhigh|max",
"requested_speed": "auto|standard|fast",
"current_model": "str",
"current_thinking": "",
"current_chat_supported": false,
"current_chat_confirmed": false,
"manual_action_required": true,
"applied_by": "none",
"reason": "host_current_chat_unconfirmed"
},
"host_confirmation": {
"requested_model": "str",
"user_reported_current_model": "str",
"user_reported_current_thinking": "",
"current_model_confirmed": false,
"confirmed_current_model": "",
"confirmed_current_thinking": "",
"confirmation_status": "unsupported|unconfirmed|confirmed|blocked",
"confirmation_source": "none|host_adapter",
"confirmation_checked_at": "ISO-8601",
"confirmed_at": "",
"unsupported_reason": "host_capability_cannot_confirm_current_model"
},
"adapter_proof_scan": {
"status": "metadata_only",
"platform": "codex-desktop",
"proof_source": "host_capability_registry",
"checked_at": "ISO-8601",
"host_state_mutated": false,
"writes_state": false,
"verification_recorded": false,
"material_not_evidence": true,
"guardrail": "current_chat_apply_or_confirm_requires_executed_host_evidence",
"paths": {
"current_chat_model_apply": {"status": "supported|unsupported|unknown"},
"current_chat_model_confirm": {"status": "supported|unsupported|unknown"},
"new_thread_model_apply": {"status": "supported|unsupported|unknown"},
"worker_model_apply": {"status": "supported|unsupported|unknown"},
"thinking_apply": {"status": "supported|unsupported|unknown"}
}
},
"updated": "ISO-8601",
"host_actions": ["str"]
}
host-model.json is optional. Explicit session_model and
MYTHIFY_SESSION_MODEL beat it; otherwise it supplies the default session model
for classify_task and fanout_start.
Host model switch status rules:
switch_result.statusismanualwhen Mythify recorded a target model but no host adapter applied or confirmed the current chat.switch_result.statusisrequestedonly when a future host adapter accepts a request but cannot yet confirm the current chat.switch_result.statusisappliedonly when a host adapter confirms the current chat model or thinking changed.switch_result.statusisblockedonly when an adapter proves the requested change cannot be requested or applied.current_chat_confirmedmust stayfalseunlesshost_capabilityhascan_confirm_current_model: trueand the host returns positive evidence.host_confirmation.current_model_confirmedmust stayfalseunless a host adapter returns positive current-chat evidence. User-suppliedcurrent_modelis recorded asuser_reported_current_model, not proof.host_confirmation.confirmation_statusisunsupportedwhen the capability registry cannot confirm the current model,unconfirmedwhen a future adapter can check but has not produced evidence,confirmedonly after positive host evidence, andblockedonly after adapter evidence proves confirmation cannot be performed.adapter_proof_scanis a non-mutating metadata scan. Its path statuses aresupported,unsupported, orunknown, andhost_state_mutatedmust stayfalse. A supported path means the registry or probe found a possible path; it is not proof that the host changed.- CLI and MCP status output must expose
host_capability,can_apply_current_chat,switch_result,host_confirmation, andadapter_proof_scanso callers can distinguish desired state, user-reported state, host-confirmed state, and future apply or confirm paths. docs/host-apply-confirm-proof-watchlist.mdnames the proof gates for current-chat apply, current-chat confirm, worker model override, and thinking override before any host mutation path can be enabled.
outcomes/<slug>/goal.json:
{
"id": "slug",
"goal": "str",
"success_criteria": "str",
"verify_command": "str",
"metric_command": "str (empty when absent)",
"metric_floor": "number or null (requires metric_command)",
"agent_command": "str (CLI self-driving loop; empty when supervised)",
"max_iterations": 3,
"iteration_count": 0,
"max_cost": "number or null (CLI self-driving loop)",
"cost_spent": 0.0,
"escalate_after": "integer or null (CLI self-driving loop)",
"allowed_paths": ["str"],
"frozen_paths": ["str"],
"scope_baseline": "Git commit or absent (CLI self-driving scoped loop)",
"visibility": "auto|quiet|summary|verbose|threaded",
"status": "active|succeeded|failed|stopped",
"created": "ISO-8601",
"updated": "ISO-8601",
"last_verified": "boolean or null",
"best_metric_score": "number or null",
"stop_reason": "str or null",
"supersedes": "slug or null",
"superseded_by": "slug or absent",
"evidence_stale": "boolean or absent (set by outcome check --audit)",
"last_audit": "ISO-8601 or absent"
}
allowed_paths are not a sandbox. The supervised CLI and MCP outcome check
paths report available Git scope hints without blocking. CLI outcome run
enforces the same list after each agent attempt. frozen_paths is the
opposite contract: an enforced deny-list in every mode, supervised checks
included. It is the held-out set the loop must never touch (tests are the
canonical case, so a scoped agent cannot rewrite its own verifier); a change
under a frozen prefix stops the loop, and the .mythify/ exemption does not
apply to it. metric_floor turns the optional metric into a counter-watcher:
a green verifier whose parsed score is missing or below the floor does not
succeed, and a score below best_metric_score stamps metric_regressed on
the iteration. Starting a second outcome while one is active is refused
unless --supersede REASON retires the old loop, which records
superseded_by and the reason on the old goal and supersedes on the new
one. A success on iteration 1, before any recorded failed attempt, carries a
vacuity caution in next_action: confirm the verifier can fail.
outcome check --audit re-runs a finished outcome's verifier without
mutating iteration_count or status, appends the run flagged audit, and
sets evidence_stale to whether the run failed; audits are the loop whose
only job is checking that a recorded result still touches reality. A scoped self-driving run
requires a clean Git worktree before the first agent executes, records the
current commit as scope_baseline, and compares the baseline commit plus the
working tree against every allowed path. Rename and copy checks include both
source and destination paths. A non-Git directory, dirty starting worktree,
diverged baseline, or failed Git inspection stops the loop before unsafe work
can continue.
outcomes/<slug>/iterations.jsonl, one JSON object per verifier attempt:
{
"iteration": 1,
"timestamp": "ISO-8601",
"notes": "str",
"agent": "object or null (CLI self-driving attempt)",
"cost": 0.0,
"cost_spent": 0.0,
"verify": {"command": "str", "exit_code": 0, "duration_seconds": 0.03, "stdout_tail": "str", "stderr_tail": "str", "verified": true},
"metric": "result object or null",
"verified": true,
"scope_violations": ["str"],
"frozen_violations": ["str"],
"metric_regressed": false,
"metric_floor_unmet": false,
"status_after": "succeeded|active|failed|stopped",
"next_action": "str"
}
outcomes/active stores the active outcome slug. Outcome loops are supervised:
the host chat acts between outcome check calls, while Mythify records the
verifier result, optional metric, iteration budget, and next action. Every
check also appends an executed verification record tagged with the outcome
slug and iteration number. Its top-level verdict is the combined verifier and
metric result, while outcome_verify and outcome_metric preserve the
individual command results.
plans/<slug>.json:
{
"name": "slug",
"goal": "str",
"steps": [
{"id": 1, "title": "str", "success_criteria": "str", "verify_command": "str (optional and absent unless supplied)", "verification_cursor": "nonnegative integer (present once started)", "status": "pending|in_progress|completed|failed|skipped", "result": null, "updated_at": "ISO-8601 (present once updated)"}
],
"created": "ISO-8601",
"last_updated": "ISO-8601"
}
Step ids are 1-based integers assigned in order. success_criteria defaults to
an empty string. verify_command is absent unless supplied; plan create and
plan add-step both persist a supplied verifier. Every transition to
in_progress stores verification_cursor, the count of verification records
that existed before the step started. Completion considers only records after
that cursor, which prevents old same-second evidence from being reused.
result is a string or null.
Plans created by plan import carry additional optional fields; all views read
step fields with tolerant lookups, so their absence on legacy plans is safe:
- Plan level:
strict_context: true(step completion accepts only verifications recorded with explicit matching plan and step context, closing the legacy context-free acceptance for bulk-imported plans) andsource: {kind: "godplans"|"godaudits", path, version, imported_at}(provenance; re-import of the same artifact path is refused while the plan exists). - Step level:
source_id(the GP or GA task id), the imported task's exactverify_commandechoed byplan showand the next-pending line,wave,phase(artifact phase title; the phase view prefers it over keyword guessing), and optionaldepends_onandfixeslists.
lessons/<slug>.json:
{"title": "str", "detail": "str", "tags": ["str"], "created": "ISO-8601"}
Lesson filename: slugify(title) truncated to 50 chars, then -YYYYMMDDHHMMSS,
then .json. This makes same-title lessons collision-free.
verifications.jsonl, one JSON object per line. Two kinds:
{"kind": "executed", "claim": "str or null", "command": "str", "exit_code": 0, "duration_seconds": 0.03, "stdout_tail": "str", "stderr_tail": "str", "verified": true, "timestamp": "ISO-8601", "provenance": {"git_commit": "hex string or null", "worktree_clean": "boolean or null", "mythify_version": "semver string"}, "plan": "slug or null", "step_id": 1, "step_title": "str or null", "step_status": "in_progress or null", "prev_sha256": "hex string or null"}
{"kind": "attested", "claim": "str", "evidence": "str", "verified": null, "timestamp": "ISO-8601", "plan": "slug or null", "step_id": 1, "step_title": "str or null", "step_status": "in_progress or null", "prev_sha256": "hex string or null"}
verified is a boolean only for executed verifications (true when exit_code == 0).
Attested entries always have verified: null: a self-report is never marked verified.
On timeout, record exit_code: -1, verified: false, and append
"(timed out after N seconds)" to stderr_tail. Output tails keep the last 4000
characters of each stream.
Outcome-generated executed records add outcome, iteration,
outcome_verify, and outcome_metric. Their top-level verified and
exit_code describe the combined verifier and metric gate. The nested objects
retain each command's independent exit code, duration, and redacted tails.
Every new executed verification record also captures best-effort source
provenance and active step context. provenance.mythify_version is always the
runtime version; provenance.git_commit is the project HEAD or null when
Git provenance is unavailable; provenance.worktree_clean reports whether
Git found no tracked or untracked changes, or is null when Git inspection is
unavailable. If an active plan exists and exactly the first
currently in_progress step can be found, record plan, step_id,
step_title, and step_status. If no active plan or in-progress step exists,
write those fields with null. Readers must tolerate older verification
records that do not contain provenance or step context, but readiness must not
silently upgrade a legacy record to fresh evidence.
Every new verification record is chained: prev_sha256 is the sha256 of the
raw line preceding it in the file, or null for the first record. The chain
is tamper evidence, not cryptography: an edited, inserted, or deleted line
breaks the next record's link, and the evidence harness flags the break as an
attention item. The first line of the active file is never judged (its
predecessor may live in a compaction archive), and legacy records without
prev_sha256 stay silent.
reflections.jsonl, one JSON object per line:
{"action": "str", "outcome": "success|partial|failure", "observation": "str", "root_cause": "str or null", "next": "str", "lesson": "str or null", "timestamp": "ISO-8601"}
logs/archive/*.jsonl:
- Raw snapshots created by
logs compact. - Names are
<log-stem>-<YYYYMMDDHHMMSS>.jsonl, with a numeric suffix on collision. - The first compacted logs are the top-level
verifications.jsonlandreflections.jsonlfiles. Outcome iteration logs stay in their outcome directories. - Archives preserve the original bytes of the active log before compaction, including unparseable lines. The compacted active log keeps only the most recent valid JSONL records.
Durability rules
- All JSON file writes are atomic: write to a temp file in the same directory, then
rename over the target (Python
os.replace, Nodefs.renameSync). - Corrupt JSON on read: rename the bad file to
<filename>.corrupt-<YYYYMMDDHHMMSS>, print[WARN]to stderr, and continue with a fresh default. Never crash. - jsonl logs are plain appends.
logs compact [--keep N] [--dry-run] [--json]is maintenance, not verification evidence. Default--keepis 1000. When a target log has more thanNvalid records, write a raw archive first, then atomically replace the active log with the most recentNvalid records, preserved as their original raw line bytes so retainedprev_sha256links survive compaction.--dry-runreports candidates and counts without writing files.
Slugs
slugify(text): lowercase, replace runs of non-alphanumeric characters with -,
strip leading and trailing -, truncate to 40 characters. For plan slugs, on
collision with an existing plan file append -2, -3, and so on.
Output conventions (both implementations)
- Event markers:
[OK],[FAIL],[WARN]. - Step status icons: pending
[ ], in_progress[>], completed[x], failed[!], skipped[~]. - Verification verdict lines:
[OK] VERIFIED: <claim or command> (exit 0, 0.03s)[FAIL] UNVERIFIED: <claim or command> (exit 2, 0.10s)followed by--- stdout (tail) ---and--- stderr (tail) ---blocks when non-empty.[WARN] ATTESTED: <claim> (self-reported, not machine-checked; prefer verify run)
- ASCII only in all program output.
CLI: scripts/mythify.py
Modular Python 3.9+ CLI using only the standard library. scripts/mythify.py
owns the public entry point and delegates cohesive command families to sibling
scripts/mythify_*.py modules. Subcommand grammar:
| Command | Behavior | Exit code |
|---|---|---|
init | Create ./.mythify with subdirectories and empty memory.json, and add .mythify/ to the project .gitignore for the default in-repo state directory. If already inside a workspace, print [WARN] and exit 0. | 0 |
protocol check [PATH ...] [--json] | Verify copied protocol files match the CLI's embedded source protocol hash. With no paths, check source protocol when present and local CLAUDE.md, AGENTS.md, and .cursorrules files. Every invocation also pins any present protocol/release-gates.json (and its packaged mirror) against the embedded RELEASE_GATES_SHA256. | 0 if every checked file matches; 1 on missing metadata or drift |
status | Orientation: active plan with step icons, next pending step and its criteria, one-line counts (memory, lessons, verifications, reflections). | 0; 1 if no workspace |
dashboard [--recent N] [--json] | Read-only workflow dashboard: active plan, current and next step, active outcome, memory and lesson counts, verification totals, recent verification records, and recent reflections. It does not mutate state or report model confidence. | 0; 1 if no workspace |
harness [--recent N] [--json] | Read-only evidence harness: active steering state, evidence mix, attention items, delegated work counts, release readiness, and the next control action from durable state. It does not mutate state or treat worker output as verification. | 0; 1 if no workspace |
history [--recent N] [--json] | Read-only verification history: executed and attested records, verdicts, commands, exit codes, duration, and plan or step context from durable state. It does not mutate state, rerun checks, or upgrade attested claims. | 0; 1 if no workspace |
report [--since last|start] [--format chat|json] [--recent N] [--cursor NAME] [--peek] [--mark] | Chat-ready live work report over durable plan, step, verification, and reflection events, with an Attention section for failed checks, failed steps, failure reflections, and attested warnings. By default it advances a cursor so repeated calls show only new events; --peek leaves the cursor unchanged; --mark advances the cursor to the latest event without showing old events and cannot be combined with --since. | 0; 1 if no workspace, invalid recent value, or incompatible flags |
route TASK [--json] [--triage never|auto|always] [--platform P] [--effort E] [--speed S] [--session-model M] [--model-profile P] [--failure-count N] [--spawn-ceiling C] [--reviewer-strength R] | Read-only workflow router. It classifies the task, selects the capability profile and topology, inspects durable state and the latest executed verification, then returns a route, reason, a loop-collision note naming every active loop family and which one steers when more than one is live, next command, prompt packet, verification strategy, chat policy, pause rules, expected state writes, and evidence. It must not mutate state or move execution out of the initiating host unless the user explicitly asks. | 0; 1 if no workspace |
prompt KIND [NAME] [--goal TEXT] [--verify COMMAND] [--json] | Render a read-only workflow prompt packet. Kinds are research, analysis, failure, handoff, review, campaign, map, and next; packet output is steering material for the host, not verification evidence. next selects failure recovery only when the latest executed check is red, then campaign, map, research, handoff, or analysis based on active state. | 0; 1 if no workspace or named state is missing |
background [--recent N] [--json] | Read-only background task view: outcome loops, fanout jobs, task counts, current statuses, and next actions from durable state. It does not mutate state or report model confidence as progress. | 0; 1 if no workspace |
progress [--recent N] [--json] | Read-only outcome loop progress: active and recent outcomes, iteration budget, verifier exit details, metric score when present, and next action from durable state. It does not mutate state, run checks, stop loops, or treat notes as verification. | 0; 1 if no workspace |
readiness [--json] | Read-only release readiness: recorded verification gates, project git state, roadmap state, and release-review status without rerunning gates or declaring the release safe. | 0; 1 if no workspace |
timeline [--recent N] [--json] | Read-only fanout worker timeline: recent fanout jobs, task start and finish events, duration, status, errors, and output metadata from durable state. It does not mutate state or report worker output as verification evidence. | 0; 1 if no workspace |
phase [--recent N] [--json] | Read-only phase view: active plan steps grouped into Understand, Design, Build, Judge, and Verify, with supporting evidence counts from durable state. It does not mutate state or report model confidence as progress. | 0; 1 if no workspace |
outcome start GOAL --success TEXT --verify COMMAND [--metric COMMAND] [--metric-floor N] [--agent COMMAND] [--max-iterations N] [--max-cost N] [--escalate-after N] [--allowed-paths CSV] [--frozen-paths CSV] [--supersede REASON] [--visibility MODE] [--name NAME] [--json] | Start an outcome loop, set it active, and record the verifier, optional metric and metric floor, optional self-driving agent_command?: string, iteration and cost budgets, escalation threshold, Git-enforced allowed paths, the enforced frozen-path deny-list, and visibility policy. A second start while another outcome is active requires --supersede REASON, which stops the old loop with recorded lineage. | 0; 1 if no workspace, invalid budget, a floor without a metric, or an unsuperseded active loop |
outcome check [NAME] [--notes TEXT] [--audit] [--timeout N] [--json] | Run the verifier and optional metric for the active or named outcome, append an iteration record, append executed verification evidence, and return the next action. --audit re-runs a finished outcome's verifier without mutating its iteration count or status and sets evidence_stale from the result. | 0 if verified, 2 if still unmet or failed, 1 if not found or auditing an active loop |
outcome run [NAME] [--notes TEXT] [--timeout N] | Drive a self-driving loop started with --agent: run the bounded agent command, execute the verifier and optional metric, record evidence, enforce iteration, cost, path, and escalation limits, and stop on success or a guard. CLI-only. | 0 if verified; 2 if still unmet, blocked, or budget-exhausted; 1 if not found or not self-driving |
outcome status [NAME] [--json] | Show outcome status, verifier, metric, iteration budget, and latest next action. | 0; 1 if not found |
outcome results [NAME] [--json] | Show every recorded verifier iteration plus final state. | 0 if succeeded, 2 otherwise, 1 if not found |
outcome stop [NAME] --reason TEXT [--json] | Mark an active or named outcome stopped and clear the active pointer when it matches. | 0; 1 if not found |
map create DESTINATION [--name NAME] [--notes TEXT] [--fog TEXT] [--json] | Chart a wayfinding decision map and set it active. --fog is repeatable and seeds the Not-yet-specified register. | 0; 1 if no workspace |
map list [--json] | List maps with active marker, open and frontier counts, decisions, fog, and status. | 0; 1 if no workspace |
map show [NAME] [--json] | Show the map at low resolution: destination, notes, decisions so far, frontier, claimed, blocked, fog, out of scope, and the next action. Read-only. | 0; 1 if not found |
map ticket TITLE --type research|prototype|grilling|task [--question TEXT] [--mode afk|hitl] [--blocked-by IDS] [--verify COMMAND] [--from-fog ID] [--map NAME] | Add a decision ticket (id = T + next number). The type fixes the mode: research and task are afk, prototype and grilling are hitl; --mode is accepted only for task. --blocked-by accepts repeated or comma-separated ids that must already exist. --from-fog graduates a fog patch exactly once. | 0; 1 on unknown blocker, unknown or already-graduated fog, or a mode override on a non-task ticket |
map claim ID [--by WHO] [--map NAME] | Claim an open, unblocked ticket and record a verification cursor. Refuses a blocked ticket, a ticket claimed by someone else, and a second non-research ticket held by the same claimant. Defaults to MYTHIFY_MAP_CLAIMANT or session. | 0; 1 if refused |
map verify ID [--map NAME] [--timeout N] | Run the ticket's verify_command and record the executed verification stamped with map, ticket_id, ticket_title, and ticket_type, satisfying the ticket's resolution gate. Requires a prior claim. CLI-only. | 0 verified; 2 command failed or run disabled; 1 usage error |
map resolve ID --answer TEXT [--gist TEXT] [--human-input TEXT] [--out-of-scope] [--fog TEXT] [--scope-out TEXT] [--map NAME] | Close a claimed ticket. --answer is required. A hitl ticket REQUIRES --human-input unless MYTHIFY_REQUIRE_HUMAN_INPUT=0. A ticket storing verify_command requires a passing executed record with exit code 0 and a matching normalized command at or after the claim cursor. --out-of-scope closes the ticket into the Out-of-scope register instead of Decisions and skips the claim, block, and verifier gates, but never the human-input gate: ruling a human's question out of scope is itself the human's call. | 0; 1 if refused |
map fog NOTE [--map NAME] | Record an in-scope question too dim to ticket. Reopens a clear map to charting. | 0; 1 if no map |
map scope-out NOTE --reason TEXT [--map NAME] | Record work ruled past the destination. Out-of-scope work never graduates. | 0; 1 if no map |
map promote [NAME] [--plan NAME] [--steps JSON] [--horizon N] | Create a plan from a map with no open tickets and no ungraduated fog. The plan's goal is the destination and its source block carries {kind: "map", map, destination, decisions, out_of_scope}. Marks the map promoted, records promoted_plan, and clears the active map pointer. | 0; 1 if the map is unclear, missing, or already promoted |
plan create GOAL [--steps JSON] [--horizon N] [--name NAME] | Create plan, set it active. --steps is a JSON array of {"title": str, "success_criteria": str (optional), "verify_command": str (optional)}. --horizon N creates N default lookahead steps when --steps is omitted. MYTHIFY_PLAN_HORIZON sets the direct plan default. Without any of those, create an empty plan and suggest plan add-step. Invalid JSON: [FAIL], exit 1. | 0 |
plan import [PATH] [--source godplans|godaudits] [--name NAME] | Convert godplans PLAN.mdx or godaudits AUDIT.mdx checkbox tasks into a plan and set it active. Discovers the artifact at the project root when PATH is omitted; both present without --source is an error. Live tasks import in document order (superseded strikethrough tasks skipped, checked boxes import completed); each step keeps source_id, verify_command, wave, phase, plus depends_on and fixes when present. Sets strict_context and a source provenance block; re-importing the same artifact path is refused while the imported plan exists. Warns on frontmatter counter drift. Never edits the artifact. | 0; 1 on missing, ambiguous, unrecognized, or already-imported artifacts |
plan add-step TITLE [--criteria TEXT] [--verify COMMAND] [--plan NAME] | Append a step (id = max + 1) to the named or active plan, optionally with an executable verify_command. | 0; 1 if plan not found |
plan verify ID [--plan NAME] [--timeout N] | Run the step's verify_command, mark the step in progress, and record the executed verification scoped to that step so the strict-evidence gate is satisfied. CLI-only. | 0 verified; 2 command failed; 1 usage error |
plan list | List plans with active marker and per-plan progress, plus archived count. | 0 |
plan show [NAME] | Full detail of the named or active plan. | 0; 1 if not found |
plan switch NAME | Set the active plan pointer. | 0; 1 if not found |
plan archive [NAME] | Move plan file to plans/archive/; clear the active pointer if it pointed there. On filename conflict in archive, append a timestamp. | 0; 1 if plan not found |
step ID STATUS [RESULT] [--plan NAME] | Update step status. STATUS must be one of the five enum values, otherwise [FAIL], exit 1. completed and failed REQUIRE the RESULT argument (evidence or failure description); without it print [FAIL] Evidence required: pass a RESULT describing what proves this status. and exit 1. By default, completed ALSO requires an executed verification with verified: true, exit_code: 0, and a timestamp after the step began. When the step stores verify_command, the record's normalized command must match. Otherwise print the verified-evidence refusal and exit 1 without modifying the plan. Set MYTHIFY_REQUIRE_VERIFIED_STEP=0 to opt out. After updating, print the next pending step. | 0 |
memory set KEY VALUE [--category C] | Category one of fact, decision, discovery, state; default fact. | 0 |
memory get [QUERY] [--category C] | Case-insensitive substring match over keys and values; optional category filter. | 0 |
memory clear [KEY] [--all] | KEY removes one entry. --all clears everything. Neither: [FAIL] explaining the guard, exit 1. | 0 |
lesson add TITLE DETAIL [--tags a,b] [--global] | Record a lesson in the project store, or the global store with --global. | 0 |
lesson list [--tag TAG] [--scope project|global|all] | Default scope all; label each lesson (project) or (global); --tag filters. | 0 |
logs compact [--keep N] [--dry-run] [--json] | Archive raw top-level verification and reflection logs, then keep the most recent valid records in active logs. Default keep is 1000. --dry-run writes nothing. | 0; 1 if keep is invalid |
verify run COMMAND [--claim TEXT] [--timeout N] | Execute COMMAND through the shell, capture exit code, duration, and redacted output tails, append an executed record, print the verdict. Default timeout 300 seconds. If MYTHIFY_DISABLE_RUN=1, refuse: execute nothing, record nothing, print [FAIL] verify run is disabled: MYTHIFY_DISABLE_RUN=1 is set. No command was executed and nothing was recorded. Unset it to enable execution, or use verify claim to record a self-reported attestation. and exit 2 (the unverified code, so callers branching on verify run treat a disabled run as not verified). | 0 if verified, 2 if unverified or disabled |
verify claim CLAIM EVIDENCE | Append an attested record and print the [WARN] ATTESTED line. | 0 |
reflect [JSON] or reflect --action A --outcome O --observation OBS --next N [--root-cause R] [--lesson L] | Record a structured reflection. Required keys: action, outcome (enum success, partial, failure), observation, next. A provided lesson is auto-recorded as a project lesson tagged auto-reflected. JSON positional takes precedence over flags. Missing keys or bad outcome: [FAIL], exit 1. | 0 |
classify TASK [--json] [--triage never|auto|always] [--platform auto|unknown|codex-desktop|codex-cli|claude-desktop|claude-code|cursor-desktop|cursor-agent] [--effort auto|low|medium|high] [--speed auto|standard|fast] [--session-model MODEL] [--model-profile auto|utility|balanced|strong|max|fast|standard|frontier] [--failure-count N] [--spawn-ceiling auto|lower_only|same_or_lower|allow_stronger] [--reviewer-strength auto|same_or_lower|allow_stronger] | Classify a task before planning. Returns task type, risk, ambiguity, ceremony level, execution profile, verification strategy, fanout recommendation, fast model triage fit, capability-profile router, host-aware model policy, signals, and next action. --failure-count accepts a nonnegative executed-verifier failure count and cannot escalate beyond strong; max must be explicit. --triage auto runs one utility model only when the gate is recommended or required. Does not require .mythify state unless the selected local model command does. | 0 |
loop-fit TASK [--json] | Read-only loop-fit advisory. Assess a task against ordered gates: is there a machine-checkable done-condition, does the work recur, is there a reproduction environment (git repo), does it need human judgment. Recommend loop (bounded outcome run), supervised (verifier-gated plan or outcome check), or direct, with the criteria, matched signals, and a suggested next command. Runs nothing, records no evidence, and needs no .mythify workspace. | 0 |
summary | Full session report: plans and progress, memory count, project and global lesson counts, verification stats (executed passed, executed failed, attested count), reflection count. | 0 |
Implementation notes:
verify runexecutes the command through the shell, streams stdout and stderr to temporary files, enforces timeout and output-size caps, and redacts common secret patterns before persisting or printing output tails.init,protocol check,traceanalysis commands,classify, andloop-fitdo not require a workspace.routetreats the workspace as optional and uses durable state when it is present. Other commands require a resolvable state directory, orMYTHIFY_DIR, which is created on demand.--helpoutput for the top level and each subcommand must be accurate.
MCP server: mcp-server/
Node 20+, ESM ("type": "module"). Dependencies: @modelcontextprotocol/sdk
(current 1.x) and zod (4.x). package.json: name mythify-mcp, version 5.2.0,
scripts {"start": "node src/index.js", "test": "node --test test/*.test.js"}
(the glob form, because modern Node treats a bare directory argument to --test as
a literal file and fails), engines node >= 20. Use the registration API that the
installed SDK version supports (prefer registerTool); verify against the
installed package, not from memory.
Exactly 47 tools: the 44 core tools below plus the 3 fanout tools defined in the "Fanout: parallel delegation" section. Tool descriptions must state what the tool does AND when to use it, since descriptions drive tool selection.
| Tool | Input schema | Behavior |
|---|---|---|
classify_task | {task: string, format?: enum(text, json), triage?: enum(never, auto, always), triage_engine?: enum(claude-cli, codex-cli, cursor-agent, command), triage_model?: string, triage_timeout_seconds?: number, platform?: enum(auto, unknown, codex-desktop, codex-cli, claude-desktop, claude-code, cursor-desktop, cursor-agent), effort?: enum(auto, low, medium, high), speed?: enum(auto, standard, fast), session_model?: string, model_profile?: enum(auto, utility, balanced, strong, max, fast, standard, frontier), failure_count?: nonnegative integer, spawn_ceiling?: enum(auto, lower_only, same_or_lower, allow_stronger), reviewer_strength?: enum(auto, same_or_lower, allow_stronger)} | Classify a task before planning. Returns task type, risk, ambiguity, ceremony level, execution profile, verification strategy, fanout recommendation, utility model triage fit, capability-profile router, host-aware model policy, signals, and next action. failure_count supports bounded escalation through strong; max must be explicit. With triage: auto, run one utility local model only when the deterministic gate recommends it. |
host_model_switch | {action?: enum(switch, status, clear), platform?: enum(auto, unknown, codex-desktop, codex-cli, claude-desktop, claude-code, cursor-desktop, cursor-agent), target_model?: string, current_model?: string, thinking?: enum(auto, low, medium, high, xhigh, max), speed?: enum(auto, standard, fast), reason?: string, format?: enum(text, json)} | Record, show, or clear a requested host chat model switch. switch writes .mythify/host-model.json, returns platform-specific switch guidance, registry-backed host_capability, switch_result, host_confirmation, and adapter_proof_scan, and makes later classify_task and fanout_start calls use the recorded target as the session model when no explicit or env session model is supplied. It does not claim to mutate or confirm the current host chat unless a future host integration exposes that capability and confirms the result. |
provider_probe | {provider?: enum(generic-openai-compatible, ollama, lm-studio, llama-cpp, vllm), base_url?: string, model?: string, check?: enum(models, chat, both), api_key_env?: string, timeout_seconds?: number, prompt?: string, format?: enum(text, json)} | Probe an OpenAI-compatible provider by calling /v1/models and, when requested, /v1/chat/completions. Generic defaults: MYTHIFY_OPENAI_COMPAT_BASE_URL, MYTHIFY_OPENAI_COMPAT_MODEL, and MYTHIFY_OPENAI_COMPAT_API_KEY. api_key_env is restricted to the fixed allowlist containing MYTHIFY_OPENAI_COMPAT_API_KEY; arbitrary process variables are rejected before any request. provider: "ollama" defaults to MYTHIFY_OLLAMA_BASE_URL or http://localhost:11434/v1; provider: "lm-studio" defaults to MYTHIFY_LM_STUDIO_BASE_URL or http://localhost:1234/v1; provider: "llama-cpp" defaults to MYTHIFY_LLAMA_CPP_BASE_URL or http://localhost:8080/v1; provider: "vllm" defaults to MYTHIFY_VLLM_BASE_URL or http://localhost:8000/v1. Local profiles use provider-specific model env vars and no auth header by default. Returns provider availability, model presence, chat response tail, and material_not_evidence: true. It does not write state, spawn workers, or count as verification evidence. |
local_model_run | {provider?: enum(generic-openai-compatible, ollama, lm-studio, llama-cpp, vllm), role?: enum(reader, triage), base_url?: string, model?: string, prompt: string, api_key_env?: string, timeout_seconds?: number, max_tokens?: number, format?: enum(text, json)} | Run a role-limited prompt against a localhost OpenAI-compatible provider. Generic defaults: MYTHIFY_OPENAI_COMPAT_BASE_URL, MYTHIFY_OPENAI_COMPAT_MODEL, and MYTHIFY_OPENAI_COMPAT_API_KEY. api_key_env uses the same fixed allowlist as provider_probe. provider: "ollama", provider: "lm-studio", provider: "llama-cpp", and provider: "vllm" default to local profiles. The base URL must be localhost, 127.0.0.1, ::1, or 0.0.0.0. Returns model output with material_not_evidence: true, evidence_status: "model_output_not_verification", writes_state: false, and verification_recorded: false. It does not edit files, run commands, write state, or count model output as verification evidence. |
host_cli_probe | {host?: enum(kimi-code, opencode, antigravity), bin?: string, timeout_seconds?: number, format?: enum(text, json)} | Probe Kimi Code, OpenCode, or Antigravity CLI availability by running only version and help commands. Explicit bin basenames must match the selected host family. Defaults to MYTHIFY_KIMI_BIN, MYTHIFY_OPENCODE_BIN, or MYTHIFY_ANTIGRAVITY_BIN, then PATH and common install paths. Returns binary resolution, feature evidence, proof statuses for current-chat apply, current-chat confirm, worker model override, and thinking override, plus material_not_evidence: true. It does not execute a prompt, write state, spawn workers, or count as verification evidence. Antigravity MCP setup guidance lives in docs/antigravity-mcp-setup.md; the probe does not install or mutate MCP config. |
host_cli_run | {host?: enum(kimi-code, opencode, antigravity), bin?: string, prompt: string, cwd?: string, timeout_seconds?: number, model?: string, agent?: string, format?: enum(text, json)} | Run a bounded non-interactive prompt through Kimi Code, OpenCode, or Antigravity. Kimi uses kimi --print -p PROMPT --final-message-only. OpenCode uses opencode run --format json [--model MODEL] [--agent AGENT] PROMPT. Antigravity uses agy [--model MODEL] -p PROMPT, requires explicit cwd, and never passes permission-bypass flags. Explicit bin basenames must match the selected host family. Defaults to MYTHIFY_KIMI_BIN, MYTHIFY_OPENCODE_BIN, or MYTHIFY_ANTIGRAVITY_BIN, then PATH and common install paths. Returns stdout and stderr tails, timeout and exit metadata, trust_policy, permission_policy, material_not_evidence: true, evidence_status: "worker_output_not_verification", writes_state: false, and verification_recorded: false. It does not edit files directly, write Mythify state, or count worker output as verification evidence; merged work must still be verified with verify_run. |
execution_probe | {adapter?: enum(google-colab-cli), bin?: string, timeout_seconds?: number, format?: enum(text, json)} | Probe Google Colab CLI availability by running only version and help commands. Defaults to MYTHIFY_COLAB_BIN, then PATH and common install paths. Returns binary resolution, feature evidence, non_billable: true, job_execution_enabled: false, and material_not_evidence: true. It does not provision a runtime, request an accelerator, execute notebooks, upload data, write state, or count as verification evidence. |
execution_run | {adapter?: enum(google-colab-cli), bin?: string, cwd?: string, script_path: string, script_args?: string[], accelerator_type?: enum(cpu, gpu, tpu), accelerator?: enum(T4, L4, G4, H100, A100, v5e1, v6e1), billing_ack?: boolean, data_movement_ack?: boolean, cleanup_ack?: boolean, timeout_seconds?: number, format?: enum(text, json)} | Run a guarded Google Colab CLI ephemeral job through colab run. Defaults to MYTHIFY_COLAB_BIN, then PATH and common install paths. It requires billing_ack: true, data_movement_ack: true, and cleanup_ack: true before invoking the CLI, resolves script_path locally, supports CPU by default or explicit GPU/TPU accelerator flags, never passes --keep, and returns stdout and stderr tails plus exit metadata. It writes no Mythify state and returns material_not_evidence: true, evidence_status: "remote_output_not_verification", and verification_recorded: false; remote logs or artifacts must be consumed by a separate verifier before any completion claim is verified. |
lifecycle_probe | {adapter?: enum(google-agents-cli, google-adk-cli), bin?: string, timeout_seconds?: number, format?: enum(text, json)} | Probe Google Agents CLI or ADK CLI availability by running only version, help, and eval-help commands. Defaults to MYTHIFY_AGENTS_CLI_BIN or MYTHIFY_ADK_BIN, then PATH and common install paths. Returns binary resolution, feature evidence, can_probe_eval: true, eval_execution_enabled: false, deployment_enabled: false, material_not_evidence: true, and lifecycle_lane_contract with allowed probe commands, disabled lifecycle actions, future guarded actions, eval and deployment prerequisites, mutation policy, and material-only evidence status. It does not scaffold projects, run agents, execute evals, deploy, publish, mutate cloud resources, write project state, or count as verification evidence. |
workflow_status | {recent?: number, format?: enum(text, json)} | Show a read-only dashboard of active plan, current step, next step, active outcome, memory and lesson counts, verification totals, recent verification records, and recent reflections. It must not mutate state and must not report model confidence as evidence. |
verification_history | {recent?: number, format?: enum(text, json)} | Show a read-only history of executed and attested verification records, including verdict, command or evidence, exit code, duration, and plan or step context. It must not mutate state, rerun checks, or upgrade attested claims. |
work_report | {since?: enum(last, start), recent?: number, cursor?: string, peek?: boolean, mark?: boolean, format?: enum(chat, json)} | Show a chat-ready live work report over durable plan, step, verification, and reflection events, with an Attention section for failed checks, failed steps, failure reflections, and attested warnings. By default it advances a cursor so repeated calls show only new events; peek leaves the cursor unchanged; mark advances the cursor to the latest event without showing old events and cannot be combined with since. |
background_status | {recent?: number, format?: enum(text, json)} | Show a read-only background task view of durable outcome loops and fanout jobs, including task counts, statuses, and next actions. It must not mutate state and must not report model confidence as progress. |
evidence_harness | {recent?: number, format?: enum(text, json)} | Show a read-only control view for autonomous agent work, including active steering state, evidence mix, attention items, delegated work counts, release readiness, and the next control action. It must not mutate state and must not treat worker output as verification. |
outcome_progress | {recent?: number, format?: enum(text, json)} | Show a read-only progress view of active and recent outcome loops, including iteration budget, verifier exit details, metric score when present, and next action. It must not run checks, make attempts, stop loops, or treat notes as verification. |
release_readiness | {format?: enum(text, json)} | Show a read-only release readiness view from recorded verification gates, project git state, and roadmap state. It must not rerun gates, mutate state, tag, publish, push, or declare the release safe. |
fanout_timeline | {recent?: number, format?: enum(text, json)} | Show a read-only timeline of fanout job creation, task starts, task finishes, duration, status, errors, and output metadata. It must not mutate state and must not treat worker output as verification evidence. |
phase_status | {recent?: number, format?: enum(text, json)} | Show a read-only Understand, Design, Build, Judge, Verify phase view of active plan steps and durable evidence counts. It must not mutate state and must not report model confidence as progress. |
campaign_next_prompt | {name?: string, format?: enum(text, json)} | Render a chat-ready next prompt for the active or named campaign's current task and phase. It must not mutate state, run checks, advance a phase, or treat prompt output as verification evidence. Hosts may display or inject the returned prompt, then the host agent does the work and advances the campaign with evidence. |
prompt_packet | {kind?: enum(research, analysis, failure, handoff, review, campaign, next), name?: string, goal?: string, verify_command?: string, format?: enum(text, json)} | Render a chat-ready prompt packet for research to implementation, analysis to plan, failure recovery, handoff, review, campaign, or the next useful workflow move. It must not mutate state, run checks, advance work, or treat prompt output as verification evidence. Hosts may display or inject the returned prompt, then the host agent does the work and records evidence. |
workflow_route | {task: string, format?: enum(text, json), triage?: enum(never, auto, always), triage_engine?: enum(claude-cli, codex-cli, cursor-agent, command), triage_model?: string, triage_timeout_seconds?: number, platform?: enum(auto, unknown, codex-desktop, codex-cli, claude-desktop, claude-code, cursor-desktop, cursor-agent), effort?: enum(auto, low, medium, high), speed?: enum(auto, standard, fast), session_model?: string, model_profile?: enum(auto, utility, balanced, strong, max, fast, standard, frontier), failure_count?: nonnegative integer, spawn_ceiling?: enum(auto, lower_only, same_or_lower, allow_stronger), reviewer_strength?: enum(auto, same_or_lower, allow_stronger)} | Choose the next workflow route from prompt text, capability-profile policy, and durable state. It returns route, reason, loop_collision (the active loop families and which one steers, or null), next_command, prompt_packet, verification_strategy, chat_policy, pause_rules, state_writes, and evidence. It must not mutate state, run checks, advance work, or move execution out of the initiating host unless the user explicitly asks. |
outcome_start | {goal: string, success: string, verify_command: string, metric_command?: string, metric_floor?: number, max_iterations?: number, allowed_paths?: string[], frozen_paths?: string[], supersede?: string, visibility?: enum(auto, quiet, summary, verbose, threaded), name?: string, format?: enum(text, json)} | Start a supervised outcome loop and set it active. The host agent acts between checks; Mythify records the verifier, metric, budget, and visibility policy. allowed_paths supplies advisory Git scope reporting to supervised checks. CLI outcome run enforces it against a clean Git baseline and stops on violations or inspection failures. The self-driving outcome run loop, --agent, --max-cost, and --escalate-after are CLI-only, like plan verify and plan import. |
outcome_check | {name?: string, notes?: string, audit?: boolean, timeout_seconds?: number, format?: enum(text, json)} | Run the verifier and optional metric for the active or named outcome, append an iteration, append executed verification evidence, and return success, retry, or budget-exhausted guidance. audit: true re-runs a finished outcome's verifier without mutating its history and sets evidence_stale from the result. If MYTHIFY_DISABLE_RUN=1, refuse and record nothing. |
outcome_status | {name?: string, format?: enum(text, json)} | Show active or named outcome status, verifier, metric, iteration budget, and next action. |
outcome_results | {name?: string, format?: enum(text, json)} | Show all recorded verifier iterations and final state. |
outcome_stop | {name?: string, reason: string, format?: enum(text, json)} | Mark an outcome stopped and clear the active pointer when it matches. |
memory_store | {key: string, value: string, category: enum(fact, decision, discovery, state) = "fact"} | Upsert by key. Returns [OK] summary. |
memory_recall | {query?: string, category?: enum(fact, decision, discovery, state, all)} | Substring search as in the CLI. |
memory_clear | {key?: string, confirm_clear_all?: boolean} | With key: remove one. Without key and without confirm_clear_all: true: refuse with an explanation, do not clear. |
lesson_record | {title: string, detail: string, tags?: string[], scope: enum(project, global) = "project"} | Write a lesson file per the format. |
lesson_recall | {tag?: string, scope: enum(project, global, all) = "all"} | List lessons, labeled by scope. |
plan_create | {goal: string, name?: string, steps?: [{title: string, success_criteria?: string, verify_command?: string}], horizon?: number} | Ids auto-assigned 1-based. Sets active plan. horizon creates default lookahead steps when steps is omitted. |
plan_add_step | {title: string, success_criteria?: string, verify_command?: string, plan?: string} | Append to named or active plan. |
plan_update_step | {step_id: number, status: enum(pending, in_progress, completed, failed, skipped), result?: string, plan?: string} | Enforce the evidence rule: completed or failed without result returns [FAIL] Evidence required ... and does NOT modify the plan. Every in_progress transition records a verification cursor. By default, completed also requires a later recorded executed verification with verified: true, exit_code: 0, and any stored verify_command matched exactly after normalization (see "Verified-step gate"). Otherwise it returns the same [FAIL] Verified evidence required ... text the CLI uses, without modifying the plan. Set MYTHIFY_REQUIRE_VERIFIED_STEP=0 to opt out. On success, include the next pending step in the response. |
plan_status | {plan?: string} | Goal, progress count, step list with icons. |
map_create | {destination: string, name?: string, notes?: string, fog?: string[]} | Chart a wayfinding decision map and set it active. Fog entries become F-prefixed Not-yet-specified patches. |
map_add_ticket | {title: string, type: enum(research, prototype, grilling, task), question?: string, mode?: enum(afk, hitl), blocked_by?: string[], verify_command?: string, from_fog?: string, map?: string} | Add a decision ticket. The type fixes the mode (research and task afk, prototype and grilling hitl); mode is accepted only for task and otherwise returns [FAIL] Mode is fixed for .... Unknown blockers and already-graduated fog patches are refused. |
map_claim | {ticket_id: string, by?: string, map?: string} | Claim an open, unblocked ticket and record a verification cursor. Refuses blocked tickets, tickets claimed by another party, and a second non-research ticket held by the same claimant. |
map_resolve | {ticket_id: string, answer: string, gist?: string, human_input?: string, out_of_scope?: boolean, fog?: string[], scope_out?: string[], map?: string} | Close a claimed ticket. A hitl ticket without human_input returns the human-input refusal and does NOT modify the map, unless MYTHIFY_REQUIRE_HUMAN_INPUT=0. A ticket storing verify_command requires a passing executed record with exit code 0 and a matching normalized command at or after the claim cursor. out_of_scope: true files the ticket under Out of scope instead of Decisions. |
map_status | {map?: string} | Read-only low-resolution map: destination, notes, decisions so far, frontier, claimed, blocked, fog, out of scope, and next action. |
map_promote | {map?: string, plan?: string, steps?: [{title: string, success_criteria?: string, verify_command?: string}], horizon?: number} | Create a plan from a map with no open tickets and no ungraduated fog. The plan carries source: {kind: "map", ...} with the decisions and out-of-scope register. Refuses an unclear or already-promoted map. |
verify_run | {command: string, claim?: string, timeout_seconds?: number = 300} | Execute through the shell, record an executed verification, return the verdict with output tails. If env MYTHIFY_DISABLE_RUN=1, refuse with an explanation and record nothing. |
verify_claim | {claim: string, evidence: string} | Record an attested entry, return the [WARN] ATTESTED line. |
reflect | {action_taken: string, outcome: enum(success, partial, failure), observation: string, root_cause?: string, next_action: string, lesson?: string} | Append reflection; auto-record lesson if provided (project scope, tag auto-reflected). Note: jsonl field names follow the file format (action, next), not the tool parameter names. |
All tool results are text content prefixed with [OK], [FAIL], or [WARN].
Handlers never throw on bad state; they return explanatory text.
mcp-config.example.json: a complete example client configuration using a local
absolute path placeholder like /absolute/path/to/mythify/mcp-server/src/index.js
and a MYTHIFY_DIR env entry. This is the one allowed "placeholder", since the
install path is genuinely user-specific.
Classification, execution profiles, and fast model triage
Classification is two-stage:
- Deterministic gate.
classifyandclassify_taskalways compute task type, risk, ambiguity, ceremony, execution profile, verification hint, fanout fit, andmodel_triage. - Optional fast model pass. The caller must opt in with
--triage auto,--triage always, or the matching MCPtriageargument.autoruns only whenmodel_triageisrecommendedorrequired.
execution_profile may be direct, fast, standard, or full:
direct: answer or make one reversible edit with no protocol state.fast: focused low-risk work skips plan state but still requires an executedverify runbefore completion is claimed.standard: create a plan with verifiable steps, act step by step, and runverify runbefore completion.full: use plan, memory, step updates, executed verification, reflection on failures, and summary.
Classification always returns model_policy. It separates:
model_router: provider-neutral routing across six independent axes: autonomy policy, execution topology, model profile, reasoning effort, review policy, and verification gate. Task classification selectsutility,balanced, orstrong. An explicitmodel_profilemay also selectmax.failure_countmoves one tier per supplied executed-verifier failure and is capped atstrong. For independently parallel work, the router may recommend the MCP-onlyclaude-ultracodeadapter. The initiating host launches one native Claude workflow throughfanout_start, monitors it withfanout_status, and ingests its material withfanout_results. Its autonomy policy inherits the user's request, its permissions remain host-owned, and its verifier is always deterministic-command-first.provider_defaults: advisory provider defaults for each role. These are policy metadata only and do not route work by themselves. Precedence is future explicit role input,MYTHIFY_ROLE_<ROLE>_PROVIDER, then built-in defaults. Invalid env values are ignored withstatus: "invalid_env_ignored". Every role usesfallback_policy: "no_implicit_cross_provider_fallback". The object also declarestimeout_metadata_fieldsandcost_metadata_fieldsso hosts know which fields are intentionally standardized.provider_defaults.provider_catalog: provider-specific posture metadata forhost,host_cli,local_openai_compatible,api_provider,command, andlocal_command. It records allowed roles, default roles, billing posture, execution boundary, evidence status, state-write posture, and fallback policy. Each resolved role also includes its selectedprovider_profile.provider_defaults.adapter_interface_contract: stable metadata shape shared by the registry-backed adapter lanes. It records version, fields, lanes, fallback policy, and an execution policy ofmetadata_shape_only_no_runtime_change. MCP also includes a normalized candidate catalog from the capability registry; CLI exposes the same contract fields without using them as a router.provider_defaults.role_assignment_contract: stable role-to-lane metadata for session, triage, reader, fanout worker, reviewer, verifier, remote execution, and agent lifecycle roles. It records default and selected providers, eligible adapter-interface lanes, evidence boundaries, state-write posture, and no-hidden-fallback guardrails. MCP additionally lists eligible candidate IDs from the adapter registry. The contract keepsruntime_routing_changed: false; role metadata never enables hidden fallback, remote execution, evals, deployments, or new state writes.provider_defaults.api_provider_contract: metadata for hosted providers before Mythify can spend API credits. It currently covers OpenAI, Anthropic, and hosted OpenAI-compatible endpoints. It records auth env names, billing posture, timeout metadata fields, cost metadata fields, pricing URLs, andexecution_enabled: falsefor general provider role routing. The explicit fanout API path is recorded separately withfanout_execution_enabled: true, enginesanthropicandopenai, required acknowledgement fields,.mythify/provider-audit.jsonl, andfanout_output_material_status: "material_not_verification".provider_defaults.custom_adapter_contract: metadata for user-defined adapter paths. Thecommandadapter is enabled only throughMYTHIFY_TRIAGE_COMMANDandMYTHIFY_FANOUT_COMMAND, reads prompts on stdin, obeys role timeouts, writes no Mythify state, and returns material, not verification evidence. Thehttpadapter is metadata-only withexecution_enabled: false; it records env names for a future custom HTTP worker and lists the execution blockers that must be solved first.- Resolved role records include
timeoutandcostobjects.timeoutrecordstimeout_seconds,timeout_source,timeout_enforced_by, andcan_override.costrecords billing posture,cost_estimate_supported: false,cost_estimate_status: "not_estimated",cost_estimate_cents: null, pricing references, and usage metadata field names. Pricing URLs are advisory references only. session: host-selected current conversation model, model source, rough tier, effort policy, spawn ceiling, andrecommendation.host_model_switchrecords intended host model changes in.mythify/host-model.json; the host still owns the actual current chat model switch. The optionalhost_confirmationrecord separates user-reported current model input from host-confirmed current model evidence. Theadapter_proof_scanrecord reports supported, unsupported, or unknown apply and confirm paths without mutating host state.session.recommendation: task-based host settings withaction, legacytarget_profile, canonicalcapability_profile,target_provider,target_model,target_api_model,target_model_source,target_model_status,target_model_tier,thinking,speed, resolution metadata, andreason. The action is one ofkeep,downgrade,upgrade,recommend_set, orrecommend_discover.spawn_ceiling: policy object withpolicy,source,session_model,session_model_source,session_model_tier, default, and opt-in rule.reader: optional read-only model role for inspecting supplied material. It defaults to the localhost OpenAI-compatible provider path and can use the explicit Ollama profile. It returns material, not verification evidence.triage: spawned problem-framing worker, engine, spawned model policy, model tier, relation to the session model, provider default, effort, timeout, max turns, and sandbox.fanout_worker: default policy for independent fanout tasks, including canonical capability profile, provider-specific recommended model and effort, plus chat visibility (quiet,summary,verbose, orthreaded).reviewer: whether a separate reviewer worker is useful, its effort, and its independently selected capability profile and explicit stronger-model policy. Reviewers default to same-or-lower than the initiating session;reviewer_strength: "allow_stronger"records classifier policy. Actual fanout still requiresrole: "reviewer"plusreviewer_allow_stronger: truebefore reviewer fanout may exceed the session without the broaderspawn_ceiling: "allow_stronger"escape hatch.verifier: command-first verification policy, no model when an executable check exists.
Built-in role provider defaults:
| Role | Default provider | Allowed provider values |
|---|---|---|
session | host | host |
triage | host_cli | host_cli, local_openai_compatible, command |
reader | local_openai_compatible | local_openai_compatible, host |
fanout_worker | host_cli | host_cli, api_provider, command |
reviewer | host_cli | host_cli, api_provider, command |
verifier | local_command | local_command |
Built-in role provider catalog:
| Provider | Default roles | Allowed roles | Execution boundary | Evidence |
|---|---|---|---|---|
host | session | session, reader | Host-selected current conversation | Host output is not verification |
host_cli | triage, fanout_worker, reviewer | triage, fanout_worker, reviewer | Bounded local host CLI worker | Worker output is material, not verification |
local_openai_compatible | reader | triage, reader | Localhost OpenAI-compatible model provider | Model output is material, not verification |
api_provider | none | fanout_worker, reviewer | Guarded fanout API execution with explicit hosted provider acknowledgements | Provider output is material, not verification |
command | none | triage, fanout_worker, reviewer | Explicit user command | Command output is material, not verification |
local_command | verifier | verifier | Local executed verifier | Exit code is verification evidence |
--platform and MCP platform may be auto, unknown, codex-desktop,
codex-cli, claude-desktop, claude-code, cursor-desktop, or
cursor-agent. --effort and MCP effort may be auto, low, medium,
or high. --speed and MCP speed may be auto, standard, or fast.
--model-profile, MCP model_profile, and MYTHIFY_MODEL_PROFILE may be
auto, utility, balanced, strong, max, or the compatibility aliases
fast, standard, and frontier. --failure-count, MCP failure_count, and
MYTHIFY_FAILURE_COUNT accept a nonnegative count derived from executed
verifier failures. Automatic escalation is capped at strong; max requires
an explicit request.
Auto speed preserves the host or CLI default; fast maps to Codex fast mode
where supported; standard explicitly disables Codex fast mode for that spawned
worker. --session-model, MCP session_model, and
MYTHIFY_SESSION_MODEL provide the initiating model when the host can name it;
if neither is set, Mythify uses .mythify/host-model.json when present.
--spawn-ceiling, MCP spawn_ceiling, and MYTHIFY_SPAWN_CEILING may be
auto, lower_only, same_or_lower, or allow_stronger; auto defaults to
same_or_lower. --reviewer-strength, MCP reviewer_strength, and
MYTHIFY_REVIEWER_STRENGTH may be auto, same_or_lower, or
allow_stronger; auto defaults to same_or_lower. Auto effort keeps triage
cheap and scales fanout or reviewer effort by risk and ceremony.
Host recommendations are capability-profile based, then resolved within the
selected host provider. Direct low-risk prompts use utility; normal
implementation, debugging, review, and docs use balanced; research,
benchmark, design, security, release, and migration use strong; and max
is explicit only.
| Profile | OpenAI | Claude | Cursor |
|---|---|---|---|
utility | gpt-5.6-luna, low | haiku (claude-haiku-4-5), low | Discover Luna, Haiku, Mini, Flash, or Composer |
balanced | gpt-5.6-terra, medium | sonnet (claude-sonnet-5), high | Discover Terra, Sonnet, Composer, or auto |
strong | gpt-5.6-sol, high | opus (claude-opus-4-8), xhigh | Discover Opus, Sol, or Gemini 3.1 Pro |
max | gpt-5.6-sol, max or pro mode | fable (claude-fable-5), max | Discover Fable, Opus, or Sol |
Cursor discovery reads the installed runtime catalog. If no preferred match is
available, it uses auto only when the catalog lists it; otherwise it leaves
the model unset for the Cursor default. It never crosses to another provider.
Canonical model overrides use MYTHIFY_HOST_UTILITY_MODEL,
MYTHIFY_HOST_BALANCED_MODEL, MYTHIFY_HOST_STRONG_MODEL, and
MYTHIFY_HOST_MAX_MODEL. Legacy MYTHIFY_HOST_FAST_MODEL and
MYTHIFY_HOST_STANDARD_MODEL remain accepted after their canonical forms.
The fast model pass is not verification. It returns a problem frame that the main agent may use before planning. The required JSON shape is:
{
"primary_type": "string",
"secondary_types": ["string"],
"ambiguity": "low|medium|high",
"hidden_questions": ["string"],
"likely_files_or_surfaces": ["string"],
"verification_plan": ["string"],
"fanout_plan": ["string"],
"risk_notes": ["string"],
"recommended_first_step": "string"
}
Supported fast triage engines are local-first and API-free:
claude-cli, codex-cli, cursor-agent, and command. Selection order is
explicit argument, MYTHIFY_TRIAGE_ENGINE, codex-cli when available,
local CLI auto-detection, then MYTHIFY_TRIAGE_COMMAND. Fanout binary env vars
are accepted as fallbacks for CLI paths. claude-cli defaults to model
haiku; codex-cli and cursor-agent use their local defaults unless
MYTHIFY_TRIAGE_MODEL or an explicit model is set. The command engine reads
the triage prompt on stdin
and must print JSON. It is the custom command adapter path for triage only;
its output is material, not verification evidence.
Trace analysis
trace analyze is a CLI-only read-only surface for turning exported agent
traces into Mythify product and eval signals. It intentionally has no hard
runtime dependency on Hugging Face or datasets; callers export bounded JSONL
or JSON slices first, then pass local files to Mythify.
Supported row shapes:
- session traces: rows with
trace,messages,metadata, and optionalnum_tool_calls - action rows: rows with
context,completion,output_type, and anoutputobject such as{ "tool": "Bash", "input": { "command": "..." } } - scenario rows: rows with
instruction,input,output, andprompt
The analyzer records counts for formats, sessions, models, harnesses, output types, trace event types, tool names, repeated shell commands, verifier-like command signals, verifier-like text signals, and error or recovery language. It then emits recommendations such as classifier scenario evals, action-first runtime behavior, automatic evidence detection, background monitoring, visual verification, and context-limit recovery.
The trace surface also has a playbook layer:
trace distillfilters one model slice and renders a Markdown behavior profile.trace comparefilters target and baseline slices, compares visible metrics, and renders target-minus-baseline guidance.trace playbookcompresses a target slice into session-start operating rules for chat-native agent work.trace install-playbookinstalls generated Markdown as a local Code or Codex skill with overwrite protection.
The measured signals are intentionally visible and reproducible: tool density, command density, read/edit rhythm, test/edit rhythm, verify/edit rhythm, top tools, verifier-like commands, and recovery language. Mythify does not attempt to extract private reasoning. The output is a practical behavior scaffold for agents that already run inside a host chat.
Guardrail: trace analysis is material, not verification. A Fable or Mythos
trace can suggest what Mythify should do, but it cannot prove local work is
complete. Completion claims still require verify run, verify_run, or an
explicit attested warning when no executable check exists.
Research workflow
research is a CLI state surface for source-backed inquiry:
research start QUESTION [--name NAME] [--json]research list [--json]research add-source TITLE [--url URL] [--note TEXT] [--credibility C]research add-claim CLAIM --evidence TEXT [--source ID] [--confidence C]research add-question QUESTIONresearch summary [NAME] [--json]research close [NAME] --decision TEXT
State lives under .mythify/research/:
active: current research record pointer.<slug>.json: question, status, sources, claims, open questions, decision, created timestamp, and updated timestamp.
Research records are deliberately material-only. A claim inside a research record can guide a design or product decision, but it does not prove that local implementation work is complete. When research turns into code or docs, the host must move through a plan, outcome, or campaign and record executable verification where available.
Wayfinding map workflow
map is the state surface for the phase before a plan exists: work too big for
one session whose route to the destination is not visible yet. A map holds
questions to settle, not slices to build. The shape is adapted from the
wayfinder skill (https://github.com/mattpocock/skills); the evidence gates are
Mythify's.
State lives under .mythify/maps/:
active: current map pointer, cleared when a map is promoted.<slug>.json:id,destination,notes,status(charting,clear,promoted),tickets,fog,out_of_scope,decisions,created,updated, andpromoted_planonce promoted.
A ticket carries id (T-prefixed), title, question, type, mode,
status (open, closed, out_of_scope), blocked_by, claimed_by,
claimed_at, verification_cursor, optional verify_command and
verified_command, resolution, human_input, resolved_at, and created.
A fog patch carries id (F-prefixed), note, graduated_to, and created.
An out-of-scope entry carries id (X-prefixed), note, reason,
ticket_id, and created.
Four ticket types, each fixing whether a human is in the loop:
| Type | Mode | Resolution requirement |
|---|---|---|
research | afk | an answer; exempt from the one-ticket rule and runs in parallel |
task | afk by default, hitl on request | an answer, plus a passing executed run matching verify_command when one is stored |
prototype | hitl | an answer and human_input |
grilling | hitl | an answer and human_input |
--mode and the MCP mode field are accepted only for task. A mode override
on any other type is refused, so a conversation cannot be quietly downgraded
into something the agent answers by itself.
Four gates make a map Mythify rather than a decision board, and each refuses without mutating state:
- Claim before work.
map claimrefuses a blocked ticket, a ticket already claimed by someone else, and a second non-research ticket held by the same claimant. Claiming recordsverification_cursor, the append position ofverifications.jsonlat claim time. - Human input for HITL.
map resolverefuses ahitlticket without--human-inputunlessMYTHIFY_REQUIRE_HUMAN_INPUT=0, the explicit legacy opt-out that mirrorsMYTHIFY_REQUIRE_VERIFIED_STEP. This is the attested claim rule applied to decisions: an agent's own words never settle a question that belongs to a human. The gate covers every resolution path, including--out-of-scope, because ruling a human's question out of scope is itself the human's call. Resolving under the opt-out stampshuman_input_waivedon the ticket and prints a[WARN], so a thawed gate always leaves a trace. - Executed evidence for verifiable tasks. A ticket storing
verify_commandrequires an executed record withverified: true,exit_code: 0, and a normalized command equal to the stored one, at or after the claim cursor.map verifyruns that command and stamps the record withmap,ticket_id,ticket_title, andticket_type. Evidence recorded before the claim can never be reused. - A clear way before handoff.
map promoterefuses a map with any open ticket or ungraduated fog patch.
--out-of-scope is the scoping escape hatch, not a bypass: it closes the ticket
into the Out-of-scope register with its reason, leaves Decisions untouched, and
skips the claim, block, human-input, and verifier gates because nothing is being
decided. Out-of-scope work never graduates.
map promote calls the same plan-writing helper as plan create
(create_plan_record in the CLI, createPlanRecord in the MCP runtime), so a
promoted plan is byte-shaped like a hand-written one plus a source block of
{kind: "map", map, destination, decisions, out_of_scope}. plan show renders
that block as the decisions carried from the map and the plan's scope boundary.
map verify is CLI-only, like plan verify and plan import: it executes a
command, so it stays on the surface that owns execution ergonomics.
Prompt packet workflow
prompt is a CLI read-only surface for chat-native reprompting:
prompt research [NAME] [--goal TEXT] [--verify COMMAND] [--json]prompt analysis [--goal TEXT] [--verify COMMAND] [--json]prompt failure [--goal TEXT] [--verify COMMAND] [--json]prompt handoff [--goal TEXT] [--verify COMMAND] [--json]prompt review [--goal TEXT] [--verify COMMAND] [--json]prompt campaign [NAME] [--goal TEXT] [--verify COMMAND] [--json]prompt map [NAME] [--goal TEXT] [--verify COMMAND] [--json]prompt next [--goal TEXT] [--verify COMMAND] [--json]
Each packet returns:
kind: the requested kind.selected_kind: the packet type actually rendered.title: human-readable packet label.source: the durable state source, such as research, campaign, verification, workflow state, or git state.context: structured context for hosts that want JSON.next_prompt: the chat-ready prompt to display or inject.guardrail: material-only warning.
prompt next chooses the packet from durable state. It routes to failure
recovery only when the latest executed verification is red, then to an active
campaign, active research, active plan handoff, and finally analysis. MCP
clients use prompt_packet for the same contract. Both surfaces must be
read-only and must not convert prompt text into verification evidence.
Workflow router
route is the CLI decision-tree surface for choosing the next workflow shape
without performing it:
route TASK [--json]- MCP clients use
workflow_routewith the same contract. - For broad or ambiguous prompts, chat hosts should call this before lower-level
primitives such as
classify,plan,outcome,campaign,prompt, or fanout.
The router combines deterministic classification, the active durable state, the
latest executed verification, and protocol/workflow-router.json. It returns a
route packet with the route id, reason, suggested next command, prompt packet
kind, verification strategy, chat policy, pause rules, expected state writes,
and evidence. It is read-only: the host chat still executes edits, runs checks,
reports issues, and records evidence.
Priority order favors recovery and durable loops:
- latest executed verification is red:
failure; - full-send language such as "one shot", "in one go", "address all", or
"yolo":
campaign; - active campaign or outcome with continue language:
campaignoroutcome; - explicit wayfinding language, or an active map with continue language:
map; - explicit godaudits or godplans language:
revieworplan; - explicit research or review language:
researchorreview; - active plan continuation:
handoff; - direct low-risk prompts:
direct; - otherwise:
plan.
Full-send language keeps its higher priority, so a prompt that asks for
execution routes to campaign even when it also sounds foggy. A map that has
been promoted stops steering: its state view is null and routing falls through
to the plan it produced. When a map is active and already clear, the next
command becomes map promote rather than another ticket.
The route state view also carries godplans_plan and godaudits_audit
summaries (null when the artifact is absent), read from .godplans/PLAN.mdx
and .godaudits/AUDIT.mdx (with .md fallbacks) at the project root via
mythify_godfiles.py and its JS mirror godfiles-core.js. When the routed
shape is plan or review and the matching artifact has open tasks, the
reason names the artifact and the next command becomes
plan import --source godplans|godaudits so the artifact's own tasks and
verify commands drive the work. Without god artifacts, route output is
byte-identical to the pre-integration behavior. The CLI route command works
without a .mythify workspace (needs_state is optional), so a fresh
godplans project can be routed before init.
Campaign workflow
campaign is a CLI state surface for long-running "one-shot a project" work:
campaign start GOAL [--tasks JSON] [--name NAME] [--success TEXT] [--verify COMMAND]campaign list [--json]campaign status [NAME] [--json]campaign prompt [NAME] [--json]campaign watch [NAME] [--interval N] [--max-iterations N] [--json]campaign add-task TITLE [--criteria TEXT]campaign advance [NAME] --result TEXTcampaign task ID STATUS [RESULT]campaign learn LESSON [--task ID] [--apply-next]campaign stop [NAME] --reason TEXT
State lives under .mythify/campaigns/:
active: current campaign pointer.<slug>.json: goal, success criteria, optional campaign verifier, current task id, generated or explicit tasks, phase events, learnings, status, created timestamp, and updated timestamp.
Each campaign task moves through the same loop:
- understand
- design
- build
- judge
- verify
- reflect
Advancing from reflect completes the current task and moves the frontier to
the next pending task. campaign learn records a small improvement that should
shape later tasks. This is the productized version of the long-horizon loop:
durable task frontier, visible phase, verification slot, reflection, and
learning carried forward.
When the campaign was started with --verify COMMAND, advancing from the
verify phase executes that command, appends an executed record to
verifications.jsonl (claim campaign <slug> task <id> verifier), and stamps
the verifier exit onto the phase event. A failing verifier blocks the advance:
the task stays in verify until the cause is fixed. Campaigns without a
verifier keep the legacy prose-only advance. MYTHIFY_DISABLE_RUN=1 skips
execution, consistent with verify run. Failed tasks display phase failed
with explicit recovery guidance instead of silently rendering as understand,
and skipping the final task releases the active pointer the same way
completing it does.
Campaigns do not execute arbitrary project work by themselves. The host agent
does the work, runs checks, and calls campaign advance or campaign task
with the result. This keeps Mythify as the evidence and control layer rather
than a hidden executor.
campaign prompt renders the current task and phase as a host prompt without
mutating state. campaign watch repeats that read-only render on an interval so
a host-managed background loop can pick up the next prompt after an external
advance. MCP clients use the read-only campaign_next_prompt tool for the same
contract, workflow_route when they need Mythify to choose the next workflow
path, or prompt_packet when they need the shared packet contract across
research, analysis, failure recovery, handoff, review, campaign, and next.
The failure packet carries failed_command_streak: the count of consecutive
failed executed runs of the latest failed command. At a streak of two or more,
the packet adds a question-the-reference instruction: ask whether the success
criterion itself is right, route that doubt to a human with a grilling ticket,
and never weaken the verifier to pass. Repeated failure is the one moment the
reference is most likely wrong, and reference doubt belongs to the surface
that already requires outside judgment.
Smoke test: mcp-server/test/smoke.test.js
Uses node:test and the SDK Client with StdioClientTransport, spawning the
server with MYTHIFY_DIR and HOME pointed at fresh temp directories. Assertions:
tools/listreturns exactly the manifest tool names (set equality), the 44 core tools plusfanout_start,fanout_status,fanout_results.classify_taskreturns a benchmark classification in text form with execution profilefull, a question classification in JSON form with execution profiledirect, and a command-backed fast triage result when requested.memory_storethenmemory_recallround-trips a value.plan_createwith one step, thenplan_update_stepto completed without a result returns the evidence refusal and leaves the step pending. A result alone does not satisfy strict completion; a passing step-scopedverify_runrecorded after the step starts is also required by default.verify_runwithnode -e "process.exit(0)"reports VERIFIED; withnode -e "process.exit(3)"reports UNVERIFIED.memory_clearwith no arguments refuses.- Outcome tools start a loop, run a successful verifier, record iteration evidence, and fail cleanly when the retry budget is exhausted.
- After the calls, read
memory.jsonand the plan file from the temp dir and assert the exact field names from the format contract (this enforces interop at the byte level).
Protocol: protocol/PROTOCOL.md
The canonical behavioral protocol is generated and hash-checked across host copies. Its size follows the behavior required by the current public surface; compactness is preferred, but no stale fixed line ceiling overrides contract completeness. It is written to steer a model, not to document the project. Required structure:
- Title and one-paragraph identity: "You are operating under the Mythify Protocol", an operational discipline layer; it changes how reliably the model works, not what it can do.
- Core rules, always active: act don't ask; lead with outcome; ground every claim (a completion claim requires an executed verification); bounded autonomy (pause only for destructive or irreversible actions, real scope changes, or input only the user can provide); anti-overengineering; persist state outside the context window on long tasks.
- Proportional ceremony table: trivial task (single edit or question) uses no
protocol commands; focused low-risk fix or test tasks use the fast profile
with
verify runbut no plan state; multi-step single-session task uses a plan plus executed verification of completion claims; long-horizon or multi-session work uses the full loop with memory and lessons. - The autonomy loop: PLAN, ACT, VERIFY, REFLECT, then CORRECT or ADVANCE, with the exact CLI commands for each stage.
- Verification doctrine: executed beats attested;
verify runwhenever anything executable exists (tests, builds, linters, a curl, a file check);verify claimonly when nothing executable exists, and it never counts as verified. - Memory and lessons: what to store, when to recall (before architectural decisions, at session start), project vs global lessons.
- Command quick reference matching the CLI table exactly.
- A short MCP note listing the 38 tool names for clients using the server instead of the CLI, with delegation discipline for the fanout tools.
Protocol handshake
The CLI embeds the SHA-256 hash of protocol/PROTOCOL.md in
PROTOCOL_SOURCE_SHA256. Generated protocol variants include the same hash in a
metadata header:
<!-- Mythify protocol-sha256: HASH -->
python3 scripts/mythify.py protocol check [PATH ...] [--json] compares the
embedded CLI hash with explicit protocol copy paths. With no paths, it checks
the source repo protocol when present and any CLAUDE.md, AGENTS.md, and
.cursorrules files in the current working directory. Every invocation also
hash-pins any present protocol/release-gates.json and its packaged mirror
against the embedded RELEASE_GATES_SHA256: the gate list an optimizer is
graded against is a frozen node, so a legitimate change must also update the
constant in scripts/mythify_protocol.py. A missing manifest is skipped, not
failed; release readiness already surfaces its absence.
Failure modes:
- Missing metadata header: print
[FAIL], name the path, and exit 1. - Hash mismatch: print
[FAIL], show the expected and actual short hashes, and exit 1. - Source protocol mismatch in a source checkout: print
[FAIL], nameprotocol/PROTOCOL.md, and exit 1.
The command reads files only; it does not create .mythify state. A copied
install can therefore verify that its protocol file and CLI came from the same
source protocol before an agent trusts either one.
scripts/build_variants.py
Reads protocol/PROTOCOL.md, writes three files at the repo root: CLAUDE.md,
AGENTS.md, .cursorrules. Each begins with the header line:
<!-- Generated from protocol/PROTOCOL.md by scripts/build_variants.py. Edit the source, then rebuild. -->
followed by the protocol hash metadata header, a blank line, and the protocol body
verbatim. Idempotent. Zero dependencies. Exit 0 on success with an [OK] line
listing the files written.
Skill surfaces
skills/mythify/ is the Manus-style skill package. SKILL.md starts with YAML
frontmatter:
---
name: mythify
description: Operational discipline protocol that gives any AI agent Mythos-class autonomy patterns, including planning loops, executed verification, persistent memory, and structured reflection. Use when executing multi-step or long-horizon tasks, when work spans sessions, when progress claims need grounding in evidence, or when the user asks for mythify or mythos-style autonomous execution.
---
Body: condensed protocol with pointers describing when to read each reference file. References, each under 100 lines, v2 semantics throughout:
references/autonomy-loop.md: the loop, proportional ceremony, step lifecycle.references/self-verification.md: executed vs attested, evidence rule, examples.references/memory-system.md: memory categories, project vs global lessons, read-before-decide discipline.references/meta-prompts.md: the injectable behavioral constraints (act over ask, lead with outcome, grounding, bounded autonomy, anti-overengineering, persistence).references/chat-experience.md: report cadence and visible-progress rules for chat hosts.references/godplans-godaudits.mdx: the godplans and godaudits bridge contract (plan import mapping, strict step context, artifact ownership, MDX safety rules). GFM-safe MDX, kept.mdxto match the artifacts it documents.
Dual-runtime chat front doors ($name in Codex, /name in Claude Code) live
beside the package skill:
skills/mythify-work/: visible multi-step work loop. It keeps execution in the initiating chat, marks the report cursor, and surfaces a report after steps and verifiers.skills/mythify-route/: visible router. It shows the route decision, reason, and next action before mutating state.skills/mythify-verify/: visible verifier. It turns a claim into executed evidence, reports the verdict, and completes the active step when applicable.
These focused skills exist because chat experience is an execution-model problem, not a Node-versus-Python problem. Godpowers-style visibility comes from in-band Markdown skills and report cadence. The CLI and MCP server remain the evidence ledger behind that chat surface.
scripts/package_skill.py
Zips skills/mythify/ contents so SKILL.md sits at the zip root with references/
beside it. Output: dist/mythify.skill. Stdlib zipfile only. Prints the entry
list and [OK] on success.
scripts/install_user.sh
Installs a versioned, self-contained CLI under
$XDG_DATA_HOME/mythify/VERSION/cli or
$HOME/.local/share/mythify/VERSION/cli. The mythify and
mythify-uninstall launchers do not point back to the source checkout, so the
checkout can be moved or deleted after installation. The optional MCP server
is staged under the same version root and exposed through mythify-mcp.
The installer is one transaction across the CLI, MCP server, launchers, chat hook, skills, and ownership metadata. It preflights and stages components before publication. Any later failure restores the byte-for-byte prior installation on update, or removes the partial version on first install. Rerunning the installer is the supported update path.
The self-hosted uninstaller removes only components named by the installation
ownership manifest. File ownership is bound by content hashes and directory
ownership by private markers. Missing or changed evidence makes uninstall fail
closed before deletion. Project .mythify/ state, skipped components,
unrelated files, and other installed versions are preserved.
By default, installation copies skills/mythify* directories into both the
Codex skills root ($CODEX_HOME/skills or $HOME/.codex/skills) and Claude
Code skills root ($CLAUDE_HOME/skills or $HOME/.claude/skills).
--skip-skills disables both copies, --skills-root PATH overrides the Codex
destination, --skip-claude-skills skips only the Claude copy,
--claude-skills-root PATH overrides the Claude destination, and
--install-chat-hook installs the optional report helper. The helper only
prints report --since last --cursor chat --format chat output and never
mutates host config.
scripts/package_cli.py
Builds dist/mythify-cli-VERSION.tar.gz, a deterministic standalone archive
containing the Python runtime, protocol manifests, chat skills, and installer.
Installing from the archive uses --skip-mcp because the Node package is a
separate release asset. Stable entry ordering, metadata, and gzip headers make
identical source trees produce identical bytes.
README.md
The README is the beginner product guide, not an exhaustive duplicate of this specification. It must keep these contracts visible:
- Explain that Mythify improves the agent harness, not the underlying model.
- Lead with the self-contained user installer and standalone CLI artifact.
- Teach the minimal plan, execute, verify, and complete loop before advanced routing, outcome, campaign, and fanout surfaces.
- State that CLI and MCP share one state directory and are kept aligned through checked manifests and interop tests. Never promise that independent runtimes cannot drift.
- Link the committed efficacy smoke evidence with its small-sample, fixed-order, unpinned-model, no-speed-claim, and no-monetary-cost caveats.
- Keep the complete command and tool reference here in
docs/design.md. - State the actual distribution contract: checkout or standalone local install, GitHub release assets, and no npm registry publication.
- Keep development gates and the MIT license discoverable.
The README also links docs/cli-to-model-runtime-migration.md, which explains
the opt-in path from CLI-only usage to host, local model, API provider,
execution substrate, and lifecycle lanes without hidden routing, automatic
spending, or deployment.
Document only what exists. No npx instructions, no badges for services not set up.
Local Evaluation Harness
scripts/local_model_eval.py is the built-in bare-vs-Mythify smoke harness.
It creates paired task workspaces, runs the selected local CLI or command
engine, then verifies each workspace with python3 -m unittest. The model
output is material; the evaluation metric comes from verifier exit codes.
Mythify evidence success is stricter than line presence: the harness parses
verifications.jsonl and requires an executed record with verified: true,
exit_code: 0, and the exact expected verifier command. Attested, failed,
malformed, and different-command records do not satisfy --require-pass.
The JSON report must include:
summary: per-mode attempts, model success, verified success, Mythify evidence success, success rates, average model duration, and the winner by verified success rate.verified_task_success: the direct answer to the product question. It recordsmetric: "verified_success_rate",comparison: "mythify_vs_bare",evidence_source: "per-workspace python3 -m unittest exit code", bare and Mythify rates, the rate delta, winner, conclusion, Mythify evidence rate, duration delta, andstatistical_strength: "local_smoke".false_completion_claims: the direct answer to the false-completion question. It recordsmetric: "false_completion_rate",completion_signal: "model_exit_code_0", the evidence source, per-mode completion signals, verifier-backed claims, false completion claims, false-completion rates, rate delta, lower-rate winner, conclusion, and the local smoke-test caveat. The harness must not classify tone or confidence in model prose as evidence.profile_overhead: the direct answer to the profile-overhead question. It recordsmetric: "avg_model_duration_seconds",comparison: "mythify_profile_vs_bare", measured duration evidence source, bare and Mythify average model durations, delta, ratio, lower-duration winner, conclusion, per-profile attempts, per-profile duration deltas, speed fields, and the local smoke-test caveat. The harness must not estimate timing or use model-reported timing as evidence.local_model_benefit: the direct answer to the local-model task-fit question. It recordsmetric: "local_model_candidate_task_categories", supported local roles, per-scenario task categories, local reader or triage candidate roles, fit reasons, observed verifier-backed success rates, Mythify evidence rates, category summaries, and the local smoke-test caveat. The harness must not claim provider-specific local model benefit unless the report came from a local-model-backed command or provider check.fanout_value: the direct answer to the fanout-value question. It recordsmetric: "fanout_value_fit", helpful and waste-prone task shapes, policy rows, per-scenario fanout-fit metadata, observed verifier-backed success rates, Mythify evidence rates, single-worker sufficiency counts, and the local smoke-test caveat. The harness must not treat parallelism, worker enthusiasm, or worker output alone as value; proving real fanout value requires independent worker outputs, a merged artifact, and a verifier run after the merge.role_strength: the direct answer to the stronger-model role question. It recordsmetric: "stronger_model_role_requirement", default spawn ceiling, required stronger roles, scoped reviewer opt-in roles, broad stronger opt-in roles, per-role policy rows, observed harness rates, and the local smoke-test caveat. The harness must not claim bigger models are generally better; stronger-model benefit requires a paired run with the role isolated.runs: per-workspace model exit details, verifier exit details, output tails, and Mythify evidence counts including the secret-safepassing_expected_verificationscount.
The built-in scenarios are a rerunnable smoke signal, not a large benchmark.
Do not upgrade verified_task_success.conclusion into a release claim without
recording the exact harness command and its JSON output as evidence.
The committed July 13, 2026 Codex smoke result is linked from
docs/evidence/efficacy-reproduction.md. It contains two paired trials of one
small scenario. It is evidence of that run only, not a general efficacy or
speed claim. The model was not pinned, pair order was fixed, monetary cost and
subscription quota were not measured, and the raw report is not committed.
Housekeeping
.gitignore:
.DS_Store
.mythify/
.mcp.json
__pycache__/
*.pyc
node_modules/
dist/
*.corrupt-*
*.tgz
npm-debug.log*
LICENSE: MIT, copyright 2026 Mythify contributors.
Tests
tests/test_mythify.py
Stdlib unittest. Invoke the CLI as a subprocess with sys.executable, a scrubbed
environment (MYTHIFY_DIR removed, HOME pointed at a per-test temp directory so
the real global lessons store is never touched), and cwd inside a temp project
directory. Required coverage:
- init creates the documented layout, adds the default state directory to
.gitignore, preserves existing ignore rules, and re-init warns and exits 0. - Commands without a workspace fail with exit 1 and the documented message.
- State discovery walks up: a command run from a nested subdirectory finds the
project
.mythify. MYTHIFY_DIRoverrides discovery and is created on demand.- Plan lifecycle: create with steps, create without steps, add-step, list, show,
switch, archive; slug collision produces
-2. - Step updates: valid transitions; invalid status rejected with exit 1; completed and failed without RESULT rejected with exit 1 and do not modify the plan; completed with RESULT persists result and prints the next pending step.
- Memory: set, overwrite, get with query and category filter, clear KEY, clear without args fails with exit 1, clear --all empties.
- Lessons: project add and list; global add and list (under the temp HOME); tag filter; scope filter.
- verify run:
true-like command verified with exit 0;false-like command unverified with exit 2; timeout case (--timeout 1on a 5-second sleep) records exit_code -1 and exits 2; the jsonl record matches the executed format. - verify claim: exits 0, prints ATTESTED warning, jsonl record has verified null.
- reflect: JSON form, flags form, missing required key fails, lesson auto-recording creates a project lesson tagged auto-reflected.
- summary and status: run without error and include the expected counts.
- Corrupt recovery: write garbage into memory.json, run
memory get, expect[WARN]on stderr, exit 0, and amemory.json.corrupt-*file.
tests/test_maps.py
Stdlib unittest over the CLI as a subprocess, with the same scrubbed
environment as tests/test_mythify.py plus MYTHIFY_REQUIRE_HUMAN_INPUT and
MYTHIFY_MAP_CLAIMANT removed. Required coverage:
- Charting:
map createrecords destination, notes, and fog; ticket type fixes the mode; a mode override on a non-task ticket is refused and the map is left unmodified; unknown blockers are refused; a fog patch graduates exactly once. - Claim discipline: blocked tickets cannot be claimed; one claimant holds one non-research decision ticket at a time while research claims stay parallel; a ticket claimed elsewhere is refused; resolving an unclaimed ticket is refused.
- Resolution evidence: a HITL ticket refuses a self-authored resolution and
leaves the ticket open; it resolves with
--human-input;MYTHIFY_REQUIRE_HUMAN_INPUT=0is the explicit legacy opt-out; an AFK ticket needs no human input; an empty answer is refused; a task ticket with a verifier refuses resolution untilmap verifypasses; a failing verifier does not satisfy the gate; evidence recorded before the claim cannot be reused; themap verifyrecord carries the ticket context. - Scope and fog: an out-of-scope ticket stays out of the decision index; a
resolution can surface fresh fog and scope boundaries;
map scope-outrecords a standalone boundary; new fog reopens a clear map. - Promotion: refused while any ticket or fog remains; carries decisions and the
out-of-scope register into the plan's
sourceblock; accepts explicit steps; clears the active pointer and refuses a second promotion. - Surfaces:
statusreports the active map,map showrefers to tickets by name,map listmarks the active map,prompt maprenders the wayfinding rules, andprompt nextselects the map while one is active.
mcp-server/test/map-tools.test.js
An in-memory registrar harness (the same shape as plan-tools.test.js) asserts
that the MCP runtime enforces the identical gates: the registrar wires every
MAP_TOOL_NAMES handler with a title and description, mode overrides on
conversation tickets are refused, blocked tickets stay off the frontier, one
decision ticket is held at a time, map_resolve refuses a HITL ticket without
human_input, a verifier-bearing task ticket needs a passing exit-0 record at
or after the claim cursor, fog graduates once, out-of-scope work skips the
decision index, map_promote refuses an unclear or already-promoted map, and
map_status never mutates.
tests/test_local_model_eval.py
Offline command-engine tests verify the local benchmark harness without real
model accounts. The default --mythify-profile auto resolves built-in focused
bugfix scenarios to fast, requiring executed verification evidence but no
plan record. --mythify-profile standard keeps the older plan-plus-verify
behavior and requires both plan and verification evidence.
tests/test_interop.py
Stdlib only. Skips (unittest skip, not failure) unless node is on PATH and
mcp-server/node_modules exists. It runs the Python CLI and the Node MCP server
against one temp .mythify directory and covers the shared mutating state
surface, not probes or MCP-only fanout.
Coverage matrix:
- CLI writes, MCP reads:
host-model switch,plan create,step in_progress,memory set,lesson add, andoutcome start. - MCP writes, CLI reads:
host_model_switch,plan_add_step,plan_update_step,memory_store,memory_clear,lesson_record,outcome_check,outcome_start,outcome_stop,verify_run,verify_claim, andreflect. - CLI writes after MCP writes, MCP reads:
host-model clearis checked so the host model state contract is bidirectional. - Verification records and reflection records are checked on disk because both APIs intentionally append logs rather than exposing a read tool for individual log entries.
Whole-state refusal no-mutation checks
Refusal paths that promise "nothing was recorded", "nothing was cleared", or
"the plan was not modified" must be tested with whole-state snapshots. A
snapshot includes every regular file under the active .mythify directory,
keyed by relative path and content hash. Representative CLI and MCP refusal
tests must compare the full snapshot before and after the refused operation so
new files, removed files, and unrelated file rewrites are all caught.
Representative refusal paths:
- CLI:
step completedwithout RESULT,step completedblocked by strict step evidence,memory clearwith no target, andverify runwithMYTHIFY_DISABLE_RUN=1. - MCP:
plan_update_stepwithoutresult,memory_clearwith no target, andverify_runwithMYTHIFY_DISABLE_RUN=1.
Fanout: parallel delegation (MCP only)
Fanout gives the orchestrating model parallel sub-workers through one-shot
declarative jobs: the model emits a task list once, and the server does the
spawning, sequencing, and collecting. This avoids requiring turn-by-turn
worker orchestration from the initiating host, without making a model-tier
capability claim. Fanout is MCP-only; the CLI
does not implement it (a CLI host has shell access and usually its own
parallelism), and docs/design.md is explicit about that divergence.
Implementation lives in mcp-server/src/fanout.js, wired into the server in
mcp-server/src/index.js.
Engines
A worker is one fresh model invocation with no memory of the conversation.
Seven engines, selected by MYTHIFY_FANOUT_ENGINE or auto-detected in this
order: explicit env value, else codex-cli if a codex binary resolves,
regardless of the initiating host, else claude-cli if a claude binary
resolves, else cursor-agent if Cursor Agent resolves, else anthropic if
ANTHROPIC_API_KEY is set, else command if MYTHIFY_FANOUT_COMMAND is set,
else fanout_start refuses with a message listing all seven options. openai
and claude-ultracode are explicit-only. OpenAI needs an endpoint and model;
UltraCode needs a supported Claude CLI and an independently parallel objective.
| Engine | Mechanism | Billing | Models |
|---|---|---|---|
claude-cli | Spawn <bin> -p --output-format json --model <model> --max-turns <N> with the assembled prompt on stdin, cwd = project root (parent of .mythify/). Parse the JSON output: result is the text, is_error true or a non-zero exit means failure. | Claude subscription (or whatever auth the claude CLI resolves) | Aliases haiku, sonnet, opus, fable, or any full model ID |
claude-ultracode | Probe claude --version and claude --help, require Claude Code 2.1.203 or newer with UltraCode support, then spawn one <bin> -p --output-format json --model <model> --effort ultracode --max-turns <N> workflow. Reuses the fanout job, status, result, timeout, redaction, audit, and worktree lifecycle. | Claude subscription or enabled usage credits | Defaults to opus; explicit models remain subject to the spawn ceiling |
codex-cli | Spawn <bin> --ask-for-approval never exec --cd <project> --sandbox <mode> --skip-git-repo-check --ephemeral --color never --output-last-message <tmp> [-m <model>] - with the assembled prompt on stdin. Exit 0 means success; the worker output is the output-last-message file, falling back to stdout. | Codex CLI local login, usually ChatGPT/Codex subscription auth | Any model the local Codex CLI supports; empty model means the CLI default |
cursor-agent | Spawn cursor-agent --print --output-format text --trust --workspace <project> [--mode <mode>] [--model <model>] <prompt-file-instruction>, or cursor agent ... when the configured binary is cursor. The assembled prompt is written to a temporary file under .mythify/tmp/; stdout is the worker output. | Cursor Agent local login, usually Cursor subscription auth | Any model Cursor Agent exposes; empty model means the agent default |
anthropic | POST https://api.anthropic.com/v1/messages (anthropic-version 2023-06-01) with max_tokens from env. Aliases map: haiku to claude-haiku-4-5, sonnet to claude-sonnet-5, opus to claude-opus-4-8, fable to claude-fable-5. Join text blocks. | API key (ANTHROPIC_API_KEY) | Any Claude model ID |
openai | POST <MYTHIFY_FANOUT_BASE_URL>/chat/completions with MYTHIFY_FANOUT_API_KEY. | Provider API key | Any model the endpoint serves |
command | Run the MYTHIFY_FANOUT_COMMAND shell template; prompt on stdin; stdout is the output; exit 0 is success. | Whatever the command does | Anything (generic CLI agents; also used by CI to test the job machinery with no network) |
The command engine is the supported custom command adapter path for fanout.
It is bounded by fanout validation, worker timeout, context byte caps, and the
depth guard. Its output is still material for the orchestrator, never final
verification evidence.
Selecting claude-cli invokes Claude Code through claude -p. That is
token-cost-sensitive usage: included usage applies only within plan limits, and
if usage credits are enabled and included limits are reached, continued usage
can be billed at standard API pricing. Fanout start output, job metadata, task
metadata, and provider audit cost metadata include a warning for claude-cli.
claude-ultracode adds a stronger warning because xhigh reasoning and dynamic
workflow subagents can consume substantially more quota. It accepts exactly one
task per job, forces effort: ultracode, records execution_mode: ultracode,
and refuses before job creation when the installed Claude CLI is too old or
does not advertise UltraCode support.
The hosted provider engines, anthropic and openai, require
hosted_provider_billing_ack: true, hosted_provider_data_ack: true, and
hosted_provider_material_ack: true before the job is created. The guard
acknowledges metered external billing, remote prompt and context transmission,
and the material-only status of provider output. Refusal happens before any
fanout job directory or provider audit row is written.
claude-cli binary resolution (Claude Desktop launches MCP servers with a
minimal PATH): MYTHIFY_FANOUT_CLAUDE_BIN if set, else claude on PATH, else
the first existing of ~/.claude/local/claude, /opt/homebrew/bin/claude,
/usr/local/bin/claude. Resolution failure names the env var in the error.
codex-cli binary resolution: MYTHIFY_FANOUT_CODEX_BIN if set, else codex
on PATH, else the first existing of ~/.local/bin/codex,
/opt/homebrew/bin/codex, /usr/local/bin/codex. Resolution failure names
the env var in the error. Workers run with HOME, TERM=dumb, an augmented
PATH, CODEX_HOME when set, XDG_CONFIG_HOME when set, and the fanout
guards. They do not inherit OPENAI_API_KEY; the intended path is local
codex login.
cursor-agent binary resolution: MYTHIFY_FANOUT_CURSOR_BIN if set, else
MYTHIFY_FANOUT_CURSOR_AGENT_BIN, else cursor-agent on PATH and common
locations, else cursor on PATH and common locations. When the resolved
binary name is cursor, Mythify prepends the agent subcommand. Workers run
with HOME, TERM=dumb, an augmented PATH, XDG_CONFIG_HOME when set, and
the fanout guards. They do not inherit CURSOR_API_KEY; the intended path is
local cursor-agent login or cursor agent login.
claude-cli worker environment is curated, not inherited: HOME, TERM=dumb,
PATH (server PATH augmented with ~/.local/bin, /opt/homebrew/bin, and
/usr/local/bin), plus CLAUDE_CODE_OAUTH_TOKEN when present in the server
environment, plus the guards below. Harness variables (CLAUDECODE,
CLAUDE_CODE_*,
ANTHROPIC_BASE_URL) are NOT passed through: a server spawned by Claude Code
inherits harness routing that breaks nested workers. Subscription auth setup
is documented as: run claude /login once in a terminal, or run
claude setup-token and set CLAUDE_CODE_OAUTH_TOKEN in the MCP client's
env block. A worker failure whose output contains Not logged in or
401 is reported with exactly that remediation.
Model, ceiling, and effort selection
Most specific wins: per-task model overrides per-job model overrides
MYTHIFY_FANOUT_MODEL overrides the engine default (haiku for claude-cli,
opus for claude-ultracode,
claude-haiku-4-5 for anthropic, empty string for codex-cli and
cursor-agent, which means each local CLI uses its configured default). The
same precedence applies to engine, so one job may mix engines and models
across tasks (for example five haiku drafters and one sonnet reviewer; the
reviewer task is still independent and reviews material supplied in its
prompt, not other tasks' outputs).
Spawn ceiling is checked after model resolution. session_model comes from the
tool call, MYTHIFY_SESSION_MODEL, or .mythify/host-model.json; spawn_ceiling
comes from the tool call or MYTHIFY_SPAWN_CEILING, defaulting to
same_or_lower. Mythify classifies known model names into rough tiers:
small, fast, standard, strong, frontier, or unknown. If both the
session model and spawned model have known tiers, fanout_start refuses
stronger spawned models unless the ceiling is allow_stronger. A safer narrow
path exists for review: a task with role: "reviewer" may exceed the session
under same_or_lower only when the job also sets
reviewer_allow_stronger: true. That reviewer opt-in does not affect worker
tasks and does not override lower_only. Unknown tiers are recorded as
uncheckable; Mythify does not guess blank local CLI defaults.
Effort is a separate field with the same precedence: per-task effort
overrides per-job effort, which overrides MYTHIFY_FANOUT_EFFORT, which
falls back to a model-derived default. The resolved effort and
effort_source are stored on both the job and task records, shown in status
and result output, and included in the assembled worker prompt as
Requested effort: <level>.
Speed is tracked separately from effort. Per-task speed overrides per-job
speed, which overrides MYTHIFY_FANOUT_SPEED, which otherwise stays auto.
auto preserves the platform default.
Platform mapping:
codex-cli:fastaddsservice_tier = "fast"andfeatures.fast_mode = true;standardaddsfeatures.fast_mode = false.claude-cli: resolvedeffortis passed as--effort;speedis recorded and included in the worker prompt because Claude Code exposes no separate speed flag.claude-ultracode: effort is fixed toultracode; the engine requires one task, launches one native dynamic workflow, and uses the same status and result lifecycle as other fanout jobs.cursor-agent:model,effort, andspeedare resolved against the localcursor-agent modelslist. For example,model: "gpt-5.6-sol",effort: "high", andspeed: "fast"resolves togpt-5.6-sol-high-fastwhen that id is available. If no matching encoded id is found, Mythify leaves the requested model unchanged.
Tools (3, total 47)
| Tool | Input schema | Behavior |
|---|---|---|
fanout_start | {tasks: [{title: string, prompt: string, context_paths?: string[], role?: enum(worker, reviewer), isolation?: enum(none, worktree), model?: string, engine?: string, effort?: enum(auto, low, medium, high), speed?: enum(auto, standard, fast)}], purpose?: string, model?: string, engine?: string, effort?: enum(auto, low, medium, high), speed?: enum(auto, standard, fast), visibility?: enum(auto, quiet, summary, verbose, threaded), session_model?: string, spawn_ceiling?: enum(auto, lower_only, same_or_lower, allow_stronger), reviewer_allow_stronger?: boolean, hosted_provider_billing_ack?: boolean, hosted_provider_data_ack?: boolean, hosted_provider_material_ack?: boolean, timeout_seconds?: number} | Validate 1 to MYTHIFY_FANOUT_MAX_TASKS independent tasks, resolvable engines, context containment, model ceilings, kill switch, depth guard, and hosted-provider acknowledgements. engine: claude-ultracode requires exactly one task and a supported Claude CLI. Each task receives the full self-contained instruction for this worker; the worker sees only that prompt plus readable context_paths content. isolation: worktree gives a writing task a fresh Git worktree and branch; changed work is committed for host merge, while an unchanged branch is removed. Non-Git setup falls back to the shared root with recorded metadata. Create .mythify/fanout/<job_id>/job.json, return the job id immediately, and run workers with a concurrency pool. Each task is a fresh model call that costs real money, subscription quota, or local compute. Visibility defaults to summary unless visibility, purpose, or task prompts request quiet, verbose, or threaded reporting. |
fanout_status | {job_id?: string} | Default: most recent job. Per-task lines with the step icon convention plus counts, engine, execution mode, model, model tier, effort, speed, visibility, and elapsed. This is also the monitoring surface for native UltraCode jobs. Quiet jobs show aggregate progress and failures only. If the job is marked running on disk but unknown to the in-memory registry (server restarted), mark its running tasks interrupted and say so. |
fanout_results | {job_id?: string, task_id?: number} | Return outputs of completed and failed tasks (failures include the error and remediation). For UltraCode, this ingests the native workflow's final response as material, not verification evidence. Per-task text in the tool result is capped at 20000 characters with a note pointing at the task output file. Warns when tasks are still running. |
Job ids: fo-<YYYYMMDDHHMMSS>-<4 random hex>. Worker prompt assembly:
fixed preamble (you are a delegated worker; the task is self-contained; do not
ask questions; return only the deliverable), then each context file as a
labeled fenced block, then the task prompt. context_paths resolve within
the project root; absolute paths are accepted only when they still resolve
inside that root. Total inlined context per task is capped at
MYTHIFY_FANOUT_CONTEXT_BYTES with an explicit truncation marker; an unreadable
path fails the task at validation time with a clear error.
Fanout visibility controls what the host should surface in the main chat.
Modes are quiet, summary, verbose, and threaded; auto is accepted
on input only. summary is the resolved default and should show worker titles,
status counts, and notable findings. quiet suppresses per-task status lines
except failures. verbose permits detailed worker output in the chat.
threaded asks the host to create visible worker chats only when the host has
native thread support; otherwise hosts should fall back to summary. Auto
visibility infers from purpose and task prompts, then defaults to summary.
On-disk format
.mythify/fanout/<job_id>/
|-- job.json
`-- task-<id>-output.md
.mythify/provider-audit.jsonl
job.json (atomic writes on every transition):
{
"id": "fo-...", "created": "ISO-8601", "engine": "str", "model": "str",
"billing": "str", "cost_tracking": "metadata_only_no_estimate",
"cost_estimate_status": "not_estimated", "cost_estimate_cents": null,
"pricing_url": "str",
"model_source": "str", "model_tier": "str", "model_ceiling_status": "str",
"session_model": "str", "session_model_source": "str",
"session_model_tier": "str", "spawn_ceiling": "str",
"spawn_ceiling_source": "str", "reviewer_allow_stronger": false,
"hosted_provider_engines": ["anthropic|openai"],
"hosted_provider_billing_acknowledged": false,
"hosted_provider_data_acknowledged": false,
"hosted_provider_material_acknowledged": false,
"effort": "low|medium|high",
"effort_source": "str", "speed": "auto|standard|fast",
"speed_source": "str", "visibility": "quiet|summary|verbose|threaded",
"visibility_source": "explicit|env|prompt|default",
"visibility_requested": "auto|quiet|summary|verbose|threaded",
"visibility_reason": "str", "purpose": "str",
"timeout_seconds": 600,
"timeout_source": "explicit|env:MYTHIFY_FANOUT_TIMEOUT_SECONDS|default|default_invalid_env_ignored",
"last_updated": "ISO-8601",
"tasks": [
{"id": 1, "title": "str", "status": "pending|running|completed|failed|interrupted",
"role": "worker|reviewer", "isolation": "none|worktree",
"worktree": "absent or object with isolated, branch, path, changed, committed, cleanup_failed, and note fields",
"engine": "str", "model": "str", "model_source": "str",
"billing": "str", "cost_tracking": "metadata_only_no_estimate",
"cost_estimate_status": "not_estimated", "cost_estimate_cents": null,
"pricing_url": "str",
"model_tier": "str", "model_ceiling_status": "str",
"stronger_reviewer_opt_in": false,
"effort": "low|medium|high", "effort_source": "str",
"speed": "auto|standard|fast", "speed_source": "str",
"timeout_seconds": 600,
"timeout_source": "explicit|env:MYTHIFY_FANOUT_TIMEOUT_SECONDS|default|default_invalid_env_ignored",
"started_at": "ISO-8601 or null",
"finished_at": "ISO-8601 or null", "duration_seconds": 0.0,
"error": "str or null", "output_file": "task-1-output.md", "output_bytes": 0}
]
}
Worktree metadata is written when an isolated task starts. A completed writing
task keeps its branch name and records changed: true, committed: true; the
temporary path is null after successful cleanup. An unchanged isolated task
records null branch and path after cleanup. Setup fallback records
isolated: false plus a note. Interrupted-task recovery removes only an exact
job-owned temporary worktree and branch that Git still registers together. It
records cleaned_on_recovery: true only when both cleanup commands succeed;
otherwise it retains the surviving identifiers, records the original pair,
and marks cleanup_failed: true.
provider-audit.jsonl is append-only and receives one start event and one
finish event per spawned fanout task. Each row records:
surface: "fanout_worker", provider class, engine, model, role, effort, speed, job id, task id, and task title.- Billing and cost metadata fields: billing posture,
cost_tracking,cost_estimate_status,cost_estimate_cents, andpricing_url. - Redacted request metadata: prompt SHA-256, prompt byte count, timeout
seconds, timeout source, and
prompt_redacted: true. - Hosted provider acknowledgement metadata: whether the task required hosted provider acknowledgements, the required acknowledgement fields, and whether billing, data transmission, and material-only output were acknowledged.
- Redacted output metadata on finish: output file, output byte count,
output_redacted: true, and whether an error was present. output_material_status: "material_not_verification",records_verification_evidence: false, and the verifier boundary: worker output must be merged by the orchestrator and verified withverify_runoroutcome_check.
The audit log must never store raw prompts, raw context blocks, API keys, authorization headers, or worker output. It audits existing fanout worker execution only; it does not enable any separate hosted provider execution path or upgrade provider output into evidence.
Configuration
| Env | Default | Meaning |
|---|---|---|
MYTHIFY_DISABLE_FANOUT | unset | 1 disables all three tools (they refuse with an explanation). |
MYTHIFY_HOST_PLATFORM | auto | Declares the initiating host for session policy. Worker engine selection still defaults to codex-cli when available unless explicitly overridden. |
MYTHIFY_FANOUT_ENGINE | auto | claude-cli, claude-ultracode, codex-cli, cursor-agent, anthropic, openai, command. |
MYTHIFY_FANOUT_MODEL | engine default | Default worker model. |
MYTHIFY_SESSION_MODEL | recorded host model or unknown | Current host session model used for spawn ceiling checks. Beats .mythify/host-model.json when set. |
MYTHIFY_MODEL_PROFILE | auto | Capability profile for classification and routing: auto, utility, balanced, strong, max, or a legacy alias. |
MYTHIFY_FAILURE_COUNT | 0 | Nonnegative executed-verifier failure count used for bounded one-tier escalation capped at strong. |
MYTHIFY_SPAWN_CEILING | same_or_lower | Spawn ceiling: auto, lower_only, same_or_lower, or allow_stronger. |
MYTHIFY_REVIEWER_STRENGTH | same_or_lower | Reviewer strength policy: auto, same_or_lower, or allow_stronger. |
MYTHIFY_OLLAMA_BASE_URL | http://localhost:11434/v1 | Local Ollama OpenAI-compatible /v1 endpoint for provider: "ollama". |
MYTHIFY_OLLAMA_MODEL | unset | Ollama model id for probe chat checks and local reader or triage runs. |
MYTHIFY_LM_STUDIO_BASE_URL | http://localhost:1234/v1 | Local LM Studio OpenAI-compatible /v1 endpoint for provider: "lm-studio". |
MYTHIFY_LM_STUDIO_MODEL | unset | LM Studio model id for probe chat checks and local reader or triage runs. |
MYTHIFY_LLAMA_CPP_BASE_URL | http://localhost:8080/v1 | Local llama.cpp OpenAI-compatible /v1 endpoint for provider: "llama-cpp". |
MYTHIFY_LLAMA_CPP_MODEL | unset | llama.cpp model id for probe chat checks and local reader or triage runs. |
MYTHIFY_VLLM_BASE_URL | http://localhost:8000/v1 | Local vLLM OpenAI-compatible /v1 endpoint for provider: "vllm". |
MYTHIFY_VLLM_MODEL | unset | vLLM model id for probe chat checks and local reader or triage runs. |
OPENAI_API_KEY | unset | OpenAI API key env name recorded in hosted provider metadata. Fanout's OpenAI-compatible engine uses MYTHIFY_FANOUT_API_KEY instead. |
MYTHIFY_OPENAI_API_MODEL | unset | OpenAI API model id env name recorded in hosted provider metadata. |
ANTHROPIC_API_KEY | unset | Anthropic API key env name recorded in hosted provider metadata and used by the guarded anthropic fanout engine after hosted provider acknowledgements. |
MYTHIFY_ANTHROPIC_API_MODEL | unset | Anthropic API model id env name recorded in hosted provider metadata. |
MYTHIFY_HOSTED_OPENAI_COMPAT_BASE_URL | unset | Hosted OpenAI-compatible /v1 endpoint env name recorded in provider metadata. |
MYTHIFY_HOSTED_OPENAI_COMPAT_API_KEY | unset | Hosted OpenAI-compatible API key env name recorded in provider metadata. |
MYTHIFY_HOSTED_OPENAI_COMPAT_MODEL | unset | Hosted OpenAI-compatible model id env name recorded in provider metadata. |
MYTHIFY_HOSTED_OPENAI_COMPAT_PROVIDER | unset | Optional hosted OpenAI-compatible provider label env name recorded in provider metadata. |
MYTHIFY_HOSTED_OPENAI_COMPAT_PRICING_URL | unset | Optional hosted OpenAI-compatible pricing URL env name recorded in provider metadata. |
MYTHIFY_HOST_UTILITY_MODEL | provider mapping | Canonical host recommendation override for utility work. |
MYTHIFY_HOST_BALANCED_MODEL | provider mapping | Canonical host recommendation override for balanced work. |
MYTHIFY_HOST_STRONG_MODEL | provider mapping | Canonical host recommendation override for strong work. |
MYTHIFY_HOST_MAX_MODEL | provider mapping | Canonical host recommendation override for explicitly selected max work. |
MYTHIFY_HOST_FAST_MODEL | canonical utility mapping | Compatibility override used after MYTHIFY_HOST_UTILITY_MODEL. |
MYTHIFY_HOST_STANDARD_MODEL | canonical balanced mapping | Compatibility override used after MYTHIFY_HOST_BALANCED_MODEL. |
MYTHIFY_ROLE_SESSION_PROVIDER | host | Advisory provider default for the session role. Invalid values are ignored. |
MYTHIFY_ROLE_TRIAGE_PROVIDER | host_cli | Advisory provider default for the triage role. Invalid values are ignored. |
MYTHIFY_ROLE_READER_PROVIDER | local_openai_compatible | Advisory provider default for the reader role. Invalid values are ignored. |
MYTHIFY_ROLE_WORKER_PROVIDER | host_cli | Advisory provider default for the fanout worker role. Invalid values are ignored. |
MYTHIFY_ROLE_REVIEWER_PROVIDER | host_cli | Advisory provider default for the reviewer role. Invalid values are ignored. |
MYTHIFY_ROLE_VERIFIER_PROVIDER | local_command | Advisory provider default for the verifier role. Invalid values are ignored. |
MYTHIFY_FANOUT_EFFORT | model-derived | Default worker effort: auto, low, medium, or high. |
MYTHIFY_FANOUT_SPEED | auto | Default worker speed: auto, standard, or fast. Auto preserves platform defaults; fast enables Codex fast mode where supported. |
MYTHIFY_FANOUT_VISIBILITY | auto | Worker visibility mode: auto, quiet, summary, verbose, or threaded. Auto infers from purpose and task prompts, then defaults to summary. |
MYTHIFY_FANOUT_CONCURRENCY | 3 | Parallel workers per job. |
MYTHIFY_FANOUT_MAX_TASKS | 16 | Max tasks per job. |
MYTHIFY_FANOUT_MAX_TOKENS | 8000 | API engines' max_tokens. |
MYTHIFY_FANOUT_MAX_TURNS | 25 | claude-cli --max-turns. |
MYTHIFY_FANOUT_TIMEOUT_SECONDS | 600 | Per-worker timeout; on expiry the worker is killed and the task fails with a timeout error. |
MYTHIFY_FANOUT_PRICING_URL | unset | Optional pricing reference recorded for openai fanout engine cost metadata. No estimates are computed. |
MYTHIFY_FANOUT_CONTEXT_BYTES | 200000 | Total inlined context per task. |
MYTHIFY_FANOUT_OUTPUT_BYTES | 1048576 | Total captured stdout plus stderr per local CLI or command worker; on overflow the worker is killed and the task fails with retained diagnostic output. |
MYTHIFY_FANOUT_CLAUDE_BIN | resolved | Path to the claude binary. |
MYTHIFY_FANOUT_CLAUDE_ARGS | empty | Extra claude args, for example --allowedTools "Bash". |
MYTHIFY_FANOUT_CODEX_BIN | resolved | Path to the codex binary. |
MYTHIFY_FANOUT_CODEX_SANDBOX | read-only | Codex worker sandbox mode. |
MYTHIFY_FANOUT_CODEX_ARGS | empty | Extra codex exec args. |
MYTHIFY_FANOUT_CURSOR_BIN | resolved | Path to cursor-agent or cursor. |
MYTHIFY_FANOUT_CURSOR_AGENT_BIN | resolved | Path to cursor-agent, used only when MYTHIFY_FANOUT_CURSOR_BIN is not set. |
MYTHIFY_FANOUT_CURSOR_MODELS | auto-list | Optional whitespace or comma-separated Cursor model id list. When unset, Mythify runs cursor-agent models or cursor agent models to resolve encoded model ids. |
MYTHIFY_FANOUT_CURSOR_MODE | ask | Cursor Agent worker mode. Empty string omits --mode. |
MYTHIFY_FANOUT_CURSOR_FORCE | unset | 1 adds --force to Cursor Agent workers. |
MYTHIFY_FANOUT_CURSOR_ARGS | empty | Extra Cursor Agent args. |
MYTHIFY_FANOUT_BASE_URL, MYTHIFY_FANOUT_API_KEY | unset | openai engine endpoint and key. |
MYTHIFY_FANOUT_COMMAND | unset | command engine shell template. |
Guards
- Depth limit of one: workers are spawned with
MYTHIFY_FANOUT_DEPTH=1andMYTHIFY_DISABLE_FANOUT=1in their environment, andfanout_startrefuses whenMYTHIFY_FANOUT_DEPTHis already set in the server's own environment. - Fanout results are material, not verification: the orchestrator merges them
and then verifies the merged work with
verify_run. The protocol text says this explicitly. - Server lifetime caveat (documented): background workers live in the MCP
server process; if the client disconnects or the server dies, running tasks
die with it, and
fanout_statusreports them as interrupted afterward.
Smoke coverage (mcp-server/test/, runs in CI with no network)
Using the command engine with a deterministic local template and stub local
CLI binaries: 47-tool set equality; a 3-task command job runs to completion
and fanout_results returns the outputs; context_paths content demonstrably
reaches the worker prompt; the kill switch refuses; the depth guard refuses; a
failing command produces a failed task with captured stderr; job.json matches
the format contract field by field; stub claude-cli, codex-cli, and
cursor-agent workers prove argv, prompt delivery, environment guards, and
auth remediation behavior without network access.
Verified-step gate
Strict step evidence is enabled by default. Marking a step completed requires
both a non-empty RESULT string and evidence of a passing executed verification,
so that a "completed" step is backed by a real exit code rather than only a
prose claim. MYTHIFY_REQUIRE_VERIFIED_STEP=0 is the legacy opt-out; values
0, false, no, and off disable the gate for compatibility.
The rule, identical in the CLI step command and the MCP plan_update_step
tool:
- The gate applies ONLY to status
completed.failed,in_progress,skipped, andpendingare never blocked by it (you must always be able to record a failure or a state change). - The RESULT argument is still required first; the verified-step check runs after the non-empty-RESULT check.
- Evidence is satisfied when
verifications.jsonlcontains at least one record after the step'sverification_cursorwithkind == "executed",verified == true, andexit_code == 0. New records with non-nullplanorstep_idfields must match the target plan slug and step id. Older records without step-bound fields, and new records with null step context, remain compatible only when they were appended after the cursor. Attested records (kind == "attested") never satisfy the gate. When the step stores a non-emptyverify_command, the verification record's normalized command must match it exactly. - Every transition to
in_progressstores the current verification record count asverification_cursor.plan verifysets the cursor before running the command. Legacy steps without a cursor fall back to the step'supdated_at, or the parent plan'screatedtimestamp when the step was never updated. - When a satisfying record exists, the gate also compares the latest one's
recorded provenance against the present. Visible movement between the run
and the completion claim (the commit changed, or a clean-at-run worktree is
now dirty) prints a
[WARN]by default and refuses understrict_context; the indeterminate dev-loop case (dirty at run, dirty now) stays silent. - Completing a step while
MYTHIFY_REQUIRE_VERIFIED_STEP=0disables the gate stampsstrict_gate_waivedon the step and prints a[WARN]. The opt-out keeps working; it never works silently, and the harness surfaces waived completions as attention items. - On failure the plan is NOT modified and the command prints
[FAIL] Verified evidence required: strict evidence mode is enabled by default, but no passing executed 'verify run' with exit code 0 was recorded since this step started. When the step stores a verify_command, the recorded command must match it. Run the step's verifier first, or set MYTHIFY_REQUIRE_VERIFIED_STEP=0 to use legacy prose-only completion.The CLI exits 1; the MCP tool returns that text.
This is the honest-evidence upgrade: with the gate on, the autonomy loop's ACT
step (step ID in_progress) sets the lower bound, the VERIFY step
(verify run) records the passing check, and only then does
step ID completed succeed.
Versioning
This is Mythify v5.0.0. Fanout was added in 2.1.0; 2.2.0 added local
subscription-backed codex-cli and cursor-agent engines; 2.3.0 added
task classification; 2.4.0 added optional fast model triage after
classification, execution profiles, platform-aware model policy,
initiating-model awareness, spawn ceiling checks, and additive fanout model and
effort metadata; 2.5.0 makes the CLI verify run honor MYTHIFY_DISABLE_RUN
for parity with the MCP server, and adds the MYTHIFY_REQUIRE_VERIFIED_STEP
gate to both the CLI step command and the MCP plan_update_step tool; 3.0.0
aligns the model-runtime orchestration surface, local model lane, host CLI
worker lane, hosted provider fanout guardrails, execution substrate lane, agent
lifecycle lane, registry-generated adapter docs, and release-readiness surfaces
under the v3 roadmap; 3.0.1 fixes standalone MCP tarball startup by packaging
all runtime manifests under mcp-server/protocol/; 3.1.0 adds quick-start
installation and live work reports; 3.2.0 and 3.2.1 refine report mark mode;
3.2.2 rejects mark-plus-since report calls that would otherwise hide expected
events; 3.2.3 releases the follow-up documentation hygiene fixes from the
continuous audit loop; 3.3.0 adds chat-visible report attention summaries for
failures and warnings plus packaged skill guidance for chat-first Mythify use;
3.4.0 adds trace analysis and playbook generation; 3.5.0 adds research records,
campaigns, and campaign reprompt surfaces; 3.6.0 adds workflow prompt packets
for research, analysis, failure recovery, handoff, review, campaign, and
next-prompt routing, plus read-only workflow route surfaces for CLI and MCP
hosts; 3.6.1 makes the router the default front door in CLI help, docs, skill
instructions, and MCP descriptions while keeping primitive commands available;
3.6.2 makes strict step evidence the default and divides non-core surfaces into
workflow, advanced, and labs tiers backed by the checked surface manifest;
3.6.3 adds Codex-style chat front-door skills and installer support for a
Godpowers-style visible Mythify experience; 3.6.4 fixes strict step evidence
so explicit null-context verification records cannot complete steps while
older records without context keys remain compatible; 3.6.5 fixes
cross-runtime timestamp comparison in the strict evidence gate and makes CLI
outcome check honor the execution kill-switch; 3.6.6 adds cross-runtime
classification and verification record-shape conformance coverage; 3.6.7 caps
captured subprocess output for local CLI and command fanout workers; 3.6.8
adds default .mythify/ .gitignore coverage during CLI init; 3.6.9 adds the
MCP server dependency audit gate to the Node CI matrix; 3.6.10 marks MCP
[FAIL] tool results with isError: true; 3.6.11 adds CLI --version and
makes the MCP server read its reported version from package.json; 3.6.12
refreshes the roadmap release status after the DOC-001 audit slice; 3.6.13
clarifies README architecture wording for the DOC-002 audit slice; 3.6.14
adds stable empty-state coverage for the read-only workflow views; 3.6.15
slugifies explicit state lookup names before filesystem access; 3.6.16 labels
outcome allowed_paths as advisory host-edit hints; 3.6.17 warns when malformed
JSONL evidence records are skipped; 3.6.18 adds strict gate-decision conformance
tests; 3.6.19 aligns CLI and MCP verifier output-cap and no-exit evidence
semantics; 3.6.20 adds shared JSONL locks for appends and log compaction;
3.6.21 redacts obvious secret patterns from stored verifier output tails;
3.6.22 contains fanout context_paths to the project root; 3.6.23 restricts
explicit host CLI bin overrides to selected-host binary names; 3.6.24 fsyncs
atomic state-file temp files before rename and best-effort fsyncs parent
directories after rename; 3.6.25 kills fanout subprocess process groups on
timeout and output-cap failures; 3.6.26 uses bounded JSONL tail reads for
recent strict gates and cursor-based reports; 3.6.27 moves classification
policy facts into the shared classification manifest; 3.6.28 extracts
deterministic classification into direct-import CLI and MCP modules; 3.6.29
extracts host model switch record helpers into direct-import CLI and MCP
modules; 3.6.30 extracts trace analysis and playbook formatting into a
direct-import CLI helper module; 3.6.31 extracts MCP provider probing and local
model role-runner helpers into a direct-import MCP helper module; 3.6.32
extracts MCP host CLI probe and worker helpers into a direct-import MCP helper
module; 3.6.33 extracts MCP execution adapter probe and run helpers into a
direct-import MCP helper module; 3.6.34 extracts MCP lifecycle probe helpers
into a direct-import MCP helper module; 3.6.35 extracts MCP provider defaults,
adapter contracts, and role assignment metadata into a direct-import MCP helper
module; 3.6.36 extracts MCP model policy construction and model triage runner
helpers into a direct-import MCP helper module; 3.6.37 extracts Python model
policy construction, provider-default metadata, and model triage runner helpers
into a direct-import CLI helper module; 3.6.38 extracts Python durable IO
helpers into a direct-import CLI helper module; 3.6.39 extracts Python
research and campaign workflow stores into a direct-import CLI helper module;
3.6.40 extracts Python prompt packet and workflow route helpers into a
direct-import CLI helper module; 3.6.41 extracts Python outcome loop store and
command handlers into a direct-import CLI helper module; 3.6.42 extracts
Python read-only dashboard, history, report, background, progress, readiness,
timeline, and phase view helpers into a direct-import CLI helper module; 3.6.43
moves Python trace command handlers into the direct-import trace helper module;
3.6.44 extracts Python memory and lesson stores plus command handlers into a
direct-import CLI helper module; 3.6.45 moves Python host-model state helpers
and command handlers into the direct-import host-model helper module; 3.6.46
extracts MCP adapter and host integration tool registrations into a
direct-import MCP helper module; 3.6.47 extracts MCP read-only view tool
registrations into a direct-import MCP helper module; 3.6.48 extracts MCP
memory and lesson tool registrations into a direct-import MCP helper module;
3.6.49 extracts MCP outcome loop tool registrations; 3.6.50 extracts MCP plan
tool registrations; 3.6.51 extracts MCP verification and reflection tool
registrations; 3.6.52 extracts Python parser, model triage, and status view
helpers plus MCP workflow tools, view builders, status views, fanout policy,
and fanout registration helpers; 3.6.53 adds the dual-runtime parity CI gate
and documents the parity discipline for shared CLI and MCP behavior changes;
3.6.54 adds default planning horizon support, Codex-first worker selection,
and Claude CLI worker cost warnings; 3.6.55 makes the Mythify chat skills
dual-runtime invocable (/name in Claude Code, $name in Codex) and installs
them into both the Codex and Claude Code skills roots; 3.6.56 adds the CLI
harness command and MCP evidence_harness tool as a read-only control view
for autonomous agent work; 3.6.57 adds godplans and godaudits artifact
awareness with the CLI plan import command, artifact-gated routing and
readiness and harness surfacing, an executed campaign verifier, and the
mythify_godfiles.py and godfiles-core.js shared parsers; 4.0.0 unifies the
evidence spine with per-step verify_command and plan verify, adds the
bounded self-driving outcome run loop with a cost budget ledger, git scope
enforcement, and consecutive-failure escalation, adds git-worktree isolation
for parallel writing fanout workers, and routes all recorded output through a
single secret-redaction choke point (redact.js); 4.1.0 adds the read-only
loop-fit advisory that recommends a bounded loop, a supervised loop, or doing
a task directly, assessed against the loop-worthiness gates; 4.2.0 adds
interrogative-anchored freshness routing to research, a research provenance
advisory that flags uncited claims as material, verification-drift and
long-run reminders in the evidence harness, a high-stakes labeled-variants
prompt for hard-to-reverse fixes, and the tool-use-contract doc.
4.3.0 hardens evidence provenance, release gates, scoped self-driving loops,
standalone distribution, and deterministic release assets. 5.0.0 adds shared
provider-neutral capability profiles, bounded verifier-failure escalation,
live Cursor catalog discovery, and a native Claude UltraCode adapter over the
existing fanout lifecycle. The CLI reports 5.0.0 through --version; the MCP
server reads package.json and reports the package version through server info.