| name | godmode |
| description | Orchestrator. Routes to skills, detects stack/phase,
dispatches multi-agent worktrees.
Triggers on: /godmode, /godmode:<skill>.
|
Activate When
/godmode without subcommand
/godmode:<skill> — read skills/<skill>/SKILL.md
- Natural language request → match to skill
Step 0a: Check Terse Mode
IF $GODMODE_TERSE is set OR /godmode:terse on was invoked this session:
compress all emitted output per skills/terse/SKILL.md. TSV rows, code blocks,
error messages, commit messages, and the final user-facing summary stay
verbose. Terse is an emit contract only — loops, decisions, commits, and
TSV writes are identical in both modes. See skills/terse/SKILL.md for the
full contract and the before/after examples.
Also check .godmode/session-state.json for auto-activation. If the file
exists and consecutive_rounds_without_human >= 2 AND
terse_user_opted_out != true: auto-enable terse for this round and emit
the activation message defined in skills/terse/SKILL.md § Auto-Activation.
The threshold was lowered from 5 to 2 in Phase E so that normal /godmode
commands get terse compression by round 2 instead of waiting 5 rounds —
first round stays verbose for human context, all subsequent rounds are terse.
This check runs at the START of every round, before the loop body. The
counter is incremented at the END of each round (immediately after DECIDE
and LOG) and reset to 0 at the START of any round that was triggered by a
new user prompt. A user-issued /godmode:terse off sets terse_user_opted_out
to true for the remainder of the session and disables auto-activation.
Step 0: Check for Resumable Session
Read .godmode/session-state.json if it exists.
IF stop_reason is null: resume the interrupted skill at the saved round.
IF stop_reason is set OR file missing: proceed with fresh detection.
Print resume status at start of every session.
Step 0b: Load Lessons
Read .godmode/lessons.md if it exists.
Surface relevant lessons for the detected skill.
After session: append 1-3 new lessons.
IF lessons.md exceeds 100 lines: compress before loading. Keep entries from
the last 30 days AND entries referenced (cited) more than twice. Mark stale
entries [OBSOLETE] rather than deleting — the file is append-only history.
After compression, re-read and continue. Target post-compression length: ≤60
lines. This keeps the lesson-loading context lean on long-running sessions
where the file would otherwise grow unbounded.
Step 0c: Enable Token Logging (default on)
Unless GODMODE_TOKENS=0 is set in the environment, token logging per
skills/tokens/SKILL.md is ON by default for this session. At the end of
every round (after DECIDE and LOG), append one row to .godmode/token-log.tsv
with the 10-column schema defined in the tokens skill. The logger uses the
chars / 4 heuristic documented there. Opt out with GODMODE_TOKENS=0 only
for privacy-sensitive workflows. This is part of Phase E Default Activations
(SKILL.md §14) — no explicit /godmode:tokens invocation needed.
Step 1: Detect Stack (once, cache)
ls package.json pyproject.toml Cargo.toml go.mod \
Gemfile pom.xml 2>/dev/null
ls yarn.lock pnpm-lock.yaml uv.lock \
package-lock.json 2>/dev/null
$test_cmd --version 2>/dev/null
$lint_cmd --version 2>/dev/null
STACK DETECTION:
| Files | Stack | test_cmd | lint_cmd | build_cmd |
|-------------------------------|------------|---------------|---------------|----------------|
| package.json + next.config.* | Next.js | npm test | eslint --fix | npm run build |
| package.json + tsconfig.json | TypeScript | npx vitest | eslint --fix | tsc --noEmit |
| pyproject.toml | Python | pytest | ruff check . | — |
| Cargo.toml | Rust | cargo test | cargo clippy | cargo build |
| go.mod | Go | go test ./... | golangci-lint | go build ./... |
IF no match: ask user for test/lint/build commands
IF lockfile found: use matching package manager
Step 2: Match Skill (Tier 1 routing)
Read ONLY Tier 1 of each skill file to match the user's request. Tier 1 =
frontmatter + the ## Activate When block. The Tier 1 boundary is the
first ## header that follows ## Activate When. Everything after that
boundary is Tier 2 (loaded only once a skill is matched) or Tier 3 (loaded
only on edge cases, marked by a literal tier-3 HTML comment).
for f in skills/*/SKILL.md; do
awk '
NR == 1 && $0 == "---" { in_fm = 1; print; next }
in_fm && $0 == "---" { in_fm = 0; print; next }
in_fm { print; next }
/^## Activate When/ { in_aw = 1; print; next }
in_aw && /^## / { exit }
in_aw { print }
' "$f"
done
Measured Tier 1 cost (via tests/token-bench.sh): about 4,000 tokens
across 135 skills, vs. about 54,000 tokens for full reads — roughly 92%
reduction. Stacks with skills/terse/ (output-side compression),
skills/stdio/ (input-side canonical commands), and rtk (if installed)
for compound context savings.
Match process:
- Scan all Tier 1 blocks for keyword hits in frontmatter
description:
plus ## Activate When bullets.
- Pick the skill with the most trigger hits. Tie-break: shorter
## Activate When list wins (more specific trigger).
- Once matched, read the FULL matched skill file up to the
tier-3 HTML comment marker if present (Tier 2 auto-included).
- If the skill has a Tier 3 section AND the loop hits a failure class
from
SKILL.md §8 (error recovery, quality target verification,
platform fallback), read past the marker.
Canonical trigger shortcuts (fastest path — if a request matches one of
these exactly, skip the Tier 1 scan):
| Trigger | Skill |
|--------------------------------------------------------------|-------------|
| "integration test", "integration testing" | integration |
| "end to end", "end-to-end", "e2e test" | e2e |
| "load test", "stress test" | loadtest |
| "docker image", "dockerfile", "container image" | docker |
| "rate limiting", "rate limit", "throttling" | ratelimit |
| "react component", "react hook", "jsx" | react |
| "vue page", "vue component", "composition api" | vue |
| "nextjs", "next.js", "app router" | nextjs |
| "django view", "django model", "django orm" | django |
| "fastapi route", "fastapi endpoint" | fastapi |
| "rails controller", "rails model", "active record" | rails |
| "openapi spec", "openapi schema", "rest api spec" | api |
| "design the architecture", "system architecture" | architect |
| "event sourcing", "event-driven architecture" | event |
| "make faster", "optimize", "slow", "response time", "p99", "latency" | optimize |
| "debug", "why is this", "leaking", "segfault", "trace this" | debug |
| "is red", "failing", "errored", "fix", "broken", "error" | fix |
| "secure", "vulnerabilities" | secure |
| "review", "check my code", "look over this pr", "pull request" | review |
| "research", "prior art" | research |
| "plan", "break down" | plan |
| "ship", "deploy" | ship |
| "finish", "done", "clean up", "wrap up" | finish |
| "terse", "compress output" | terse |
| "tokens", "token budget" | tokens |
| "stdio", "command patterns" | stdio |
| "team", "bundle" | team |
| "tutorial", "onboarding", "get started", "first run" | tutorial |
| "bench", "benchmark" | bench |
| "test", "coverage" | test |
| "build", "implement", "create" | build |
IF no match: fall through to phase detection (Step 3).
Skills whose Tier 1 block fails to parse (missing ## Activate When,
malformed frontmatter) are routing-invisible. The only skill without
## Activate When is skills/principles/SKILL.md, which is imported
directly as a prelude via @./skills/principles/SKILL.md and not
routable — this is intentional.
Step 3: Detect Phase (State Machine)
PHASE DETECTION:
non-trivial feature, no research → RESEARCH (see auto-dispatch below)
no spec, no plan → THINK
spec exists, no plan → PLAN
plan exists, tasks incomplete → BUILD
code exists, tests failing → FIX
tests passing, unreviewed → REVIEW
reviewed, metrics unoptimized → OPTIMIZE
all green → SHIP
THRESHOLDS:
Stuck recovery: > 5 consecutive discards
→ try opposite approach
→ if still stuck: escalate to previous phase
→ if still stuck: log reason, move to next task
Research auto-dispatch rule (Phase E Default Activations — SKILL.md §14).
Before routing to THINK, check whether the task is "non-trivial":
- Task mentions an external library, framework, or standard by name
- Task scope is >5 files (estimated from the user's phrasing)
- No
.godmode/research.md exists for the feature
If ANY of these is true AND the user did NOT pass --no-research: dispatch
skills/research/SKILL.md first. Research writes .godmode/research.md;
THINK then reads it at its own Step 2 (Scan Codebase) instead of rescanning.
Research auto-dispatch turns the "prior art gap" into a no-op for every
normal command. Skip for trivial tasks (one-line fixes, typos, renames).
Step 3b: Failure-Aware Routing
Before routing to any skill, check .godmode/<skill>-failures.tsv if it exists.
If the target skill has >10 consecutive failures: suggest an alternative skill or approach.
Surface failure patterns in the session summary: "optimize had 5 noise failures — metric may be non-deterministic."
Step 3c: Resolve Model Per Role (dispatch time)
Resolve each dispatched role's model at dispatch time. Zero-config = every
role inherits the session model; per-role model tiering is opt-in only.
Resolution order: GODMODE_MODEL_<ROLE> env -> godmode.models.json
(per-role merge: current project root file wins per-key over
~/.config/godmode/models.json) -> session model. Missing config = VALID
zero-config default; every role inherits the session model.
A model value is valid iff it fully matches
^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$ OR is the literal string session. An
INVALID value at ANY layer emits one stderr warning —
[models] warning: ignoring invalid model value for role <role> — and is
treated as absent (fall through to the next layer). Values are pasted into
agent dispatch text, never shell-eval'd; still validate.
Inline resolver — portable subset, NO adapters/ dependency (skills-only
installs never ship adapters/). Mirrors adapters/pi/models.sh, the full
reference implementation (doctor/selftest live there):
gm_route() {
local role name val f
role="${1:?usage: gm_route <role>}"
name="GODMODE_MODEL_$(printf '%s' "$role" | tr '[:lower:]._-' '[:upper:]___')"
val="$(printenv "$name" 2>/dev/null || true)"
case "$val" in *$'\n'*|*$'\r'*) val="" ;; esac
[ "${#val}" -le 128 ] || val=""
if [ "$val" = session ] || \
printf '%s' "$val" | grep -Eq '^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$'; then
printf '%s\tenv\n' "$val"; return 0
elif [ -n "$val" ]; then
printf '[models] warning: ignoring invalid model value for role %s\n' "$role" >&2
fi
for f in "/godmode.models.json" \
;
[ -f ] ||
-v python3 >/dev/null 2>&1 ||
val=rolessession^[A-Za-z0-9._-]+/[A-Za-z0-9._-]+$[models] warning: ignoring invalid model value role %s;
; 0
}
Dispatch table (godmode role -> pi-subagents child kind; the model param is
resolved at dispatch time):
| godmode role | pi child kind | model param |
|---|
| planner | planner | gm_route planner |
| builder | implementer | gm_route builder |
| reviewer | reviewer | gm_route reviewer |
| optimizer | implementer (worker also acceptable) | gm_route optimizer |
| explorer | scout | gm_route explorer |
| security | security | gm_route security |
| tester | tester | gm_route tester |
These are the canonical dispatch roles (AGENTS.md); verb aliases (plan,
build, review, optimize, explore, test, docs — the doctor's default sweep)
resolve identically because role keys are open-ended. Stamp the resolved
model on the dispatch via the optional DispatchContext model field
(model_profile for named profiles); unknown dispatch fields are logged,
never a hard fail.
Zero-config rule: when gm_route <role> resolves to session, OMIT the
model param entirely — the child inherits the session model. Example:
GODMODE_MODEL_REVIEW=vendor/strong stamps model: vendor/strong on review
dispatches only; every other role stays on the session model.
Roles are open-ended, not a fixed enum: unknown or custom roles resolve
through gm_route identically (unknown -> session). STRONG/FAST-style
names are user-defined aliases living in the user's own config — nothing
built-in.
Env normalization: role -> env name by uppercasing and turning every hyphen,
dot, and underscore into an underscore — exactly
tr '[:lower:]._-' '[:upper:]___' — then prefixing GODMODE_MODEL_
(code-review -> GODMODE_MODEL_CODE_REVIEW). Case-folded roles (Plan and
plan) collapse to one env var — document, do not special-case. A value that
is set but empty is NOT an override; fall through.
Step 4: Execute
Read skills/{skill}/SKILL.md. Follow it literally.
Pass: stack, test_cmd, lint_cmd, build_cmd.
Output Format
Print: Godmode: stack={stack}, skill={skill}, phase={phase}. Dispatching.
After: Godmode: {skill} complete. Next: {next}.
Quality Targets
- Skill routing: <2s to match and dispatch
- Stack detection: <5s for full project analysis
- Target: >95% correct skill match on natural language input
Hard Rules
Never ask to continue. Loop autonomously until done.
- Detect stack FIRST — cache result. Never guess.
- One skill at a time — read SKILL.md, follow it.
- Commit BEFORE verify — revert on failure.
- Log every invocation to
.godmode/session-log.tsv.
- Stuck recovery: > 5 discards triggers escalation.
Rules
- Iterative skills use WHILE loops with counter.
Iterations: N = run exactly N times then stop.
- Commit before verify. Revert:
git reset --hard HEAD~1.
- Log:
.godmode/<skill>-results.tsv (append only).
- Session:
.godmode/session-log.tsv with stop_reason:
target_reached | budget_exhausted |
diminishing_returns | stuck | user_interrupt
- KEEP/DISCARD: atomic — commit before verify,
revert if verify fails.
- Multi-agent: <= 5 agents/round, worktree isolation.
- Chain: think → plan → [predict] → build → test
→ fix → review → optimize → secure → ship.
- Model routing: resolve each role's model at dispatch time (Step 3c);
stamp a model param only when it resolves to something other than
session.
Keep/Discard Discipline
KEEP if: metric improved AND guard passed
(build_cmd && lint_cmd && test_cmd)
DISCARD if: metric worsened OR guard failed
On discard: git reset --hard HEAD~1. Log reason.
Meta-Loop (Outer Loop)
After each skill completes, analyze results and decide the next skill:
WHILE project_goal_not_met:
result = run_current_skill()
IF result.status == "DONE" AND result.findings > 0:
next_skill = route_findings(result) # e.g., optimize found security issue → secure
ELIF result.status == "DONE" AND result.findings == 0:
next_skill = advance_phase() # move to next phase in chain
ELIF result.status == "STUCK":
next_skill = escalate_or_skip() # try alternative skill
LOG to session-log.tsv
The meta-loop enables: optimize → review finds issue → fix → re-optimize → secure → ship.
Without it, each skill runs in isolation. With it, skills chain automatically.
Persistence
If session ends mid-loop, .godmode/session-state.json preserves state.
The stop hook notifies the user to run /godmode to resume.
For fully autonomous overnight runs: use Ralph Loop or /loop with godmode.
Stop Conditions
STOP when FIRST of:
- target_reached: spec/goal fully achieved
- budget_exhausted: max iterations hit
- diminishing_returns: last 3 iters each < 1%
- stuck: > 5 consecutive discards
TSV Logging
timestamp skill iterations kept discarded stop_reason outcome
Error Recovery
| Failure | Action |
|---|
| No stack match | Ask user for commands. Cache. |
| SKILL.md missing | List available, suggest closest. |
| Stuck in loop | Escalate to previous phase. |
| Merge conflict | Discard agent, re-queue narrower. |
ls package.json pyproject.toml Cargo.toml go.mod 2>/dev/null
git log --oneline -5
Model Routing Capability Matrix
| Platform | Per-child model | Routing resolution | Notes |
|---|
| pi | full — per-child model: param | resolves via Step 3c (gm_route) | Reference implementation for role routing |
| plugin-marketplace harness (commands + agents) | full — per-child model: param | resolves via Step 3c (gm_route) | Translate the Step 3c dispatch table to native spawn syntax |
| OpenCode | partial — env + config resolve, sequential dispatch, no per-child param | resolves via Step 3c (gm_route) | Roles run sequentially on one session |
| Codex | partial — same as OpenCode | resolves via Step 3c (gm_route) | Roles run sequentially on one session |
| Cursor | session-level degrade — routing resolves but all children share the session model | resolves via Step 3c (gm_route) | File scoping, not model params, is the isolation mechanism |
| Gemini | session-level degrade — same as Cursor | resolves via Step 3c (gm_route) | Sequential execution, session model only |