codex/skills/st/SKILL.md
Manage durable task plans in `.step/st-plan.jsonl`, including first-use choice between repo-committed storage and local-only `.git/info/exclude`, so state survives turns/sessions and can stay reviewable. Use for `use $st`, resume/export/import plan state, checkpoint milestones, track dependencies/blocked work, show ready next tasks, keep shared TODO state on disk, store backlog tasks off `update_plan`, select durable tasks for the mirror, map a `$select` plan into durable state, prove `$st` implementation tracking, mirror durable plan into Codex `update_plan` or OpenCode `TodoWrite`, or diagnose/repair `st-plan.jsonl` semantics, lock-file ignore policy, or seq/checkpoint integrity.
npx skillsauth add tkersey/dotfiles stInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Maintain a durable task inventory in the repo worktree (default: .step/st-plan.jsonl) using in-place JSONL v3/v4 persistence with dual lanes:
event lane for mutationscheckpoint lane for periodic full-state snapshotsItems use typed dependency edges (deps: [{id,type}]) plus notes, comments, in_plan, and optional execution metadata (related_to, scope, location, validation, source, claim, runtime, proof).
in_plan=true projects an item into the mirrored Codex/OpenCode plan; in_plan=false keeps it on disk as durable backlog only.
Graph mode adds durable intent atoms, waivers, polish fingerprints, and contracted task capsules. The full graph remains in $st; native plan tools receive only a bounded execution aperture.
.step/st-plan.jsonl.update_plan.in_plan=false.in_plan=true.Rules:
update_plan while Codex is in Plan Mode.st before execution with st import-proposed-plan --file .step/st-plan.jsonl --input .step/proposed-plan.md.st prime --file .step/st-plan.jsonl or use a fresh mutation-emitted plan_sync.plan_sync.codex.plan is non-empty, immediately mirror it with Codex update_plan.st mutation, mirror the new codex.plan..step/st-plan.jsonl as source of truth.update_plan as a display/projection.[st-id] as the first token in every Codex-visible step.in_progress step.update_plan payloads just to satisfy a hook.Use graph planning mode when the user provides a material implementation plan, asks for graph planning, requires durable dependencies/proof, or asks for iterative polish before implementation.
Mental model:
source plan / AGENTS.md / README.md / code observations
-> intent atoms
-> contracted task capsules
-> typed dependency + coverage graph
-> graph audit + polish fixed point
-> ranked execution aperture
-> plan_sync.codex.plan / opencode.todos projection
-> proof receipts
Rules:
.step/st-plan.jsonl.update_plan while Codex is in Plan Mode.$st first.st graph apply, st compile intent, st compile graph, st aperture select, st compile aperture, or proof commands.plan_sync.codex.plan into Codex. Never mirror the graph envelope.st complete; do not mark them done without proof or an explicit waiver.For a source plan, first read the full plan plus relevant AGENTS.md, README, and code paths. Produce:
.step/st-intent.json: every material requirement, constraint, non-goal, risk, validation expectation, compatibility obligation, migration expectation, and user-visible behavior..step/st-graph.patch.json: contracted $st capsules with dependencies, hierarchy, links, intent coverage, acceptance criteria, validation/proof obligations, locations, and lock roots where known.Then run:
st compile intent --file .step/st-plan.jsonl --input .step/st-intent.json
st compile graph --file .step/st-plan.jsonl --input .step/st-graph.patch.json --gate draft
st graph audit --file .step/st-plan.jsonl --gate implementation-ready --format markdown
st graph insights --file .step/st-plan.jsonl --format markdown
Do not import external graph-runtime state or shell out to non-st graph CLIs as the $st graph runtime.
Intent atoms are durable statements of what must not be lost from the source plan. Covered intent must be referenced by at least one item. Deferred, rejected, duplicate, and non-goal intent needs a reason or waiver. unknown intent is allowed only before implementation-ready.
Graph-mode executable items should carry:
item_type, parent_id, deps, and nonblocking links.intent_refs for coverage.acceptance, validation, location, scope, and lock_roots.contract with objective, background, implementation approach, success criteria, proof obligations, and risks.epic and decision are context/organization by default and should not be projected as executable aperture work unless explicitly selected by policy.
Use patches for planning mutations:
st graph schema --format json
st graph apply --file .step/st-plan.jsonl --input .step/st-graph.patch.json --dry-run
st graph apply --file .step/st-plan.jsonl --input .step/st-graph.patch.json --gate implementation-ready
Successful graph mutations emit plan_sync:, graph_delta:, and audit_summary:. If a gate fails, treat the findings as the next mechanical planning work unless a first-class waiver is appropriate.
Polish before implementation when the graph is nontrivial:
st graph polish begin --file .step/st-plan.jsonl --name initial-plan
st graph polish snapshot --file .step/st-plan.jsonl --pass 1
st graph polish status --file .step/st-plan.jsonl --format markdown
st graph polish gate --file .step/st-plan.jsonl --min-stable-passes 2 --gate implementation-ready
The fixed point is the CLI gate: implementation-ready audit passes and structure/coverage fingerprints are stable for the configured consecutive passes.
Compile the native execution slice:
st compile aperture --file .step/st-plan.jsonl --limit 7
st prime --file .step/st-plan.jsonl --mode aperture --limit 7
Mirror only plan_sync.codex.plan to Codex or plan_sync.opencode.todos to OpenCode. The full graph stays durable-only in $st.
Complete graph work with proof:
st complete --file .step/st-plan.jsonl --id st-001 \
--command "zig build test-st" \
--evidence-ref .step/proof/st-001.log
st proof audit --file .step/st-plan.jsonl --id st-001 --format json
Forced completion requires:
st complete --file .step/st-plan.jsonl --id st-001 --allow-unproven --reason "..."
That creates a waiver and should be rare.
Use these gates as the planning compiler:
st graph audit --file .step/st-plan.jsonl --gate draft --format json
st graph audit --file .step/st-plan.jsonl --gate implementation-ready --format markdown
st graph audit --file .step/st-plan.jsonl --gate execution-ready --format json
st graph audit --file .step/st-plan.jsonl --gate proof-complete --format json
Hard failures include unknown refs, dependency/parent cycles, uncovered intent, missing contracts/acceptance/proof, selected blocked work, terminal selected work, and completed work missing required proof.
Plan-to-graph prompt:
Read ALL of [PLAN].md, AGENTS.md, README.md, and relevant code paths. Do not edit .step/st-plan.jsonl directly. Produce .step/st-intent.json and .step/st-graph.patch.json for st. Enumerate every material intent atom, then create contracted capsules with dependencies, hierarchy, links, coverage, acceptance, validation/proof, locations, and lock roots. Apply only through st compile intent and st compile graph.
Polish prompt:
Reread source context and current st graph through graph audit, graph insights, and graph polish status. Prepare a graph patch that improves structure, granularity, acceptance, validation/proof, lock roots, and risk handling. Continue until graph polish gate passes.
Execution prompt:
Run st compile aperture --file .step/st-plan.jsonl --limit 7. Mirror only plan_sync.codex.plan. Execute the selected aperture. Record proof through st complete. Recompile aperture after each completed item.
When iterating on the Zig-backed st helper CLI path, use these two repos:
skills-zig ($HOME/workspace/tk/skills-zig): source for the st Zig binary, build/test wiring, and release tags.homebrew-tap ($HOME/workspace/tk/homebrew-tap): Homebrew formula updates/checksum bumps for released st binaries.run_st_tool() {
install_st_direct() {
local repo="${SKILLS_ZIG_REPO:-$HOME/workspace/tk/skills-zig}"
if ! command -v zig >/dev/null 2>&1; then
echo "zig not found. Install Zig from https://ziglang.org/download/ and retry." >&2
return 1
fi
if [ ! -d "$repo" ]; then
echo "skills-zig repo not found at $repo." >&2
echo "clone it with: git clone https://github.com/tkersey/skills-zig \"$repo\"" >&2
return 1
fi
if ! (cd "$repo" && zig build -Doptimize=ReleaseSafe); then
echo "direct Zig build failed in $repo." >&2
return 1
fi
if [ ! -x "$repo/zig-out/bin/st" ]; then
echo "direct Zig build did not produce $repo/zig-out/bin/st." >&2
return 1
fi
mkdir -p "$HOME/.local/bin"
install -m 0755 "$repo/zig-out/bin/st" "$HOME/.local/bin/st"
}
local os="$(uname -s)"
if command -v st >/dev/null 2>&1 && st --help 2>&1 | grep -q "st.zig"; then
st "$@"
return
fi
if [ "$os" = "Darwin" ]; then
if ! command -v brew >/dev/null 2>&1; then
echo "homebrew is required on macOS: https://brew.sh/" >&2
return 1
fi
if ! brew install tkersey/tap/st; then
echo "brew install tkersey/tap/st failed." >&2
return 1
fi
elif ! (command -v st >/dev/null 2>&1 && st --help 2>&1 | grep -q "st.zig"); then
if ! install_st_direct; then
return 1
fi
fi
if command -v st >/dev/null 2>&1 && st --help 2>&1 | grep -q "st.zig"; then
st "$@"
return
fi
echo "st binary missing or incompatible after install attempt." >&2
if [ "$os" = "Darwin" ]; then
echo "expected install path: brew install tkersey/tap/st" >&2
else
echo "expected direct path: SKILLS_ZIG_REPO=<skills-zig-path> zig build -Doptimize=ReleaseSafe" >&2
fi
return 1
}
run_st_tool --help
run_st_tool once per shell session to bootstrap/install st.update_plan in Codex or TodoWrite in OpenCode), adopt $st as the durable source of truth before editing.st init or mutation in a repo, determine the plan-file storage policy.
.step/st-plan.jsonl is already tracked, or already ignored by repo policy, respect that existing choice and do not re-ask..step/st-plan.jsonl be committed to the repo, or kept local by adding it to .git/info/exclude?.step/st-plan.jsonl tracked and make sure only the lock sidecar is ignored..step/st-plan.jsonl and .step/st-plan.jsonl.lock to .git/info/exclude before first mutation.$select, import the OrchPlan into $st and claim the first safe wave before execution starts.
st import-orchplan --file .step/st-plan.jsonl --input .step/orchplan.yamlst claim --file .step/st-plan.jsonl --wave w1 --executor codex--wave is the canonical selector and there is no public same-turn non-$st handoff.st init if missing.st show (or focused views via ready / blocked).
plan.--surface all to inspect the full durable inventory.--surface backlog to inspect durable tasks not currently mirrored into the plan.doctor when ingesting an existing plan file or when integrity is in doubt.add, select, deselect, set-status, set-deps, set-notes, add-comment, remove, import-plan, import-orchplan, claim, heartbeat, set-runtime, set-proof, complete, proof audit, graph apply, compile, aperture select, release, reclaim-stale); do not hand-edit existing JSONL lines.
add --backlog-only or import-plan --backlog-only to update the durable inventory without loading those items into the mirrored plan yet.select to add backlog items into the mirrored plan.deselect to remove items from the mirrored plan without deleting them from disk.plan_sync: {...} payload and mirror it into the native runtime tool in the same turn.
[st-id] step text; preserve that prefix when updating update_plan.st prime --file .step/st-plan.jsonl to regenerate the payload from durable state when needed..step/st-plan.jsonl, let SessionStart hydrate update_plan from the durable ledger only when the mirrored Codex plan is non-empty, and if the repo opts into the Bash PreToolUse guard, require shell work to wait until the transcript semantically matches the SessionStart-emitted update_plan payload.update_plan {"plan":[]} just to satisfy the hook.st assert-projection --file .step/st-plan.jsonl.Run commands from the target repository root. Commands below use st directly; use run_st_tool first when bootstrapping.
st init --file .step/st-plan.jsonl
st add --file .step/st-plan.jsonl --id st-001 --step "Reproduce failing test" --priority high --deps ""
st add --file .step/st-plan.jsonl --id st-002 --step "Investigate optional follow-up" --deps "" --backlog-only
st select --file .step/st-plan.jsonl --ids "st-002"
st add --file .step/st-plan.jsonl --id st-003 --step "Patch core logic" --deps "st-001"
st set-status --file .step/st-plan.jsonl --id st-001 --status in_progress
st set-priority --file .step/st-plan.jsonl --id st-003 --priority medium
st set-deps --file .step/st-plan.jsonl --id st-003 --deps "st-001:blocks"
st set-notes --file .step/st-plan.jsonl --id st-003 --notes "Need benchmark evidence"
st add-comment --file .step/st-plan.jsonl --id st-003 --text "Pausing until CI clears" --author tk
st ready --file .step/st-plan.jsonl --format markdown
st show --file .step/st-plan.jsonl --surface all --format json
st blocked --file .step/st-plan.jsonl --surface backlog --format json
st show --file .step/st-plan.jsonl --format markdown
st doctor --file .step/st-plan.jsonl
st doctor --file .step/st-plan.jsonl --repair-seq
st prime --file .step/st-plan.jsonl
st assert-projection --file .step/st-plan.jsonl
st reconcile-codex --file .step/st-plan.jsonl --input .step/update-plan.json
st reconcile-codex --file .step/st-plan.jsonl --transcript-path /path/to/codex-rollout.jsonl
st import-proposed-plan --file .step/st-plan.jsonl --input .step/proposed-plan.md --select-ready
st guard-session-start --file .step/st-plan.jsonl --session-id thread-123
st guard-pre-tool-use --file .step/st-plan.jsonl --session-id thread-123 --transcript-path /path/to/codex-rollout.jsonl
st export --file .step/st-plan.jsonl --output .step/st-plan.snapshot.json
st import-plan --file .step/st-plan.jsonl --input .step/st-plan.snapshot.json --replace
st import-orchplan --file .step/st-plan.jsonl --input .step/orchplan.yaml --replace
st claim --file .step/st-plan.jsonl --wave w1 --executor codex
st heartbeat --file .step/st-plan.jsonl --id st-001
st set-runtime --file .step/st-plan.jsonl --id st-001 --substrate spawn_agent --thread-id thread-123 --agent-id agent-1
st set-proof --file .step/st-plan.jsonl --id st-001 --proof-state pass --command "zig build test-st" --evidence-ref .step/proof.log
st complete --file .step/st-plan.jsonl --id st-001 --command "zig build test-st" --evidence-ref .step/proof.log
st proof audit --file .step/st-plan.jsonl --id st-001 --format json
st release --file .step/st-plan.jsonl --id st-001 --reason proof_complete
st reclaim-stale --file .step/st-plan.jsonl --now 2026-03-12T00:00:00Z
in_progress item unless $st can prove a safe parallel wave.in_progress is allowed automatically when every active item has claim.state=held, a non-empty claim.wave_id, a non-empty claim.executor, and pairwise non-overlapping claim.lock_roots..step/st-plan.jsonl is not yet tracked and not already ignored, ask whether the repo wants shared tracked state or local-only state via .git/info/exclude before the first mutation.claim.wave_id is authoritative and should be derived from the imported wave, not reconstructed from ad hoc --ids.in_plan=true is the mirrored-plan membership flag. Missing legacy values normalize to true.[st-id] step text prefix; reverse sync must fail closed rather than guessing when an update_plan row cannot be mapped back to a durable item id.completed, deferred, canceled) auto-demote items out of the mirrored plan while keeping them on disk.deps array; dependencies are part of the canonical JSONL schema.$st: allowed values are high, medium, and low; missing legacy values normalize to medium.id or id:type tokens; missing type normalizes to blocks, and type must be kebab-case.select accepts exact IDs (--ids) plus simple field filters (--status, --priority),deselect rejects if it would strand a still-selected dependent on a backlog-only unresolved task.in_progress and completed only when all dependencies are completed.open, queued -> pendingactive, doing -> in_progressdone, closed -> completedadd, select, deselect, set-status, set-priority, set-deps, set-notes, add-comment, remove, import-plan, import-orchplan, claim, heartbeat, set-runtime, set-proof, release, reclaim-stale) automatically print a canonical plan_sync: payload line after durable write.$st is projection-only: it may update mirrored-plan membership, mirrored order, step, and status, but must preserve durable-only metadata such as deps, notes, comments, claim, runtime, and proof.<plan-file>.lock, for example .step/st-plan.jsonl.lock) to be ignored when inside a git repo. In shared mode, add the lock sidecar to .gitignore; in local-only mode, add both the plan file and the lock sidecar to .git/info/exclude.temp + fsync + replace) and compact to a canonical replace event plus checkpoint snapshot at the current seq watermark.doctor is the first-line integrity check for seq/checkpoint contract issues; use doctor --repair-seq only when repair is explicitly needed.import-plan --replace atomically resets the full durable inventory in the same in-place write model.st-001, st-002, ...).show --format markdown for execution: it groups tasks into Ready, Waiting on Dependencies, In Progress, and terminal/manual buckets for the selected surface.$st -> native runtime tools)$st mutation (add, select, deselect, set-status, set-priority, set-deps, set-notes, add-comment, remove, import-plan, import-orchplan, claim, heartbeat, set-runtime, set-proof, release, reclaim-stale), consume the emitted plan_sync: {...} line.init or shell piping), run:
st prime --file .step/st-plan.jsonl$st in plan_sync.items.plan_sync.codex.plan via update_plan.[st-id] prefixes in each step string; they are the stable reverse-sync key back into the durable ledger.plan_sync.opencode.todos via TodoWrite.prime is installed.plan_sync.items is the full durable inventory. plan_sync.codex.plan and plan_sync.opencode.todos emit only the selected mirrored-plan subset.$st (deps); do not encode dependencies in update_plan or TodoWrite.update_plan is invalid while Codex is in Plan Mode.PreToolUse guard, keep the guard state local to $st; do not write transient hook/session guard state into .step/st-plan.jsonl.dep_state=waiting_on_deps, never mirror that item as in_progress.$st, re-check no drift by comparing:
st show --file .step/st-plan.jsonl --format jsonplan_sync payload.run_st_tool --helpst doctor --file .step/st-plan.jsonlst prime --file .step/st-plan.jsonlst assert-projection --file .step/st-plan.jsonlst reconcile-codex --file .step/st-plan.jsonl --input <captured-update-plan.json>st show --file .step/st-plan.jsonl --surface all --format jsonst show --file .step/st-plan.jsonl --format jsonreferences/jsonl-format.md for event schema, status/dependency state vocabulary, and snapshot import/export shapes.tools
Convert markdown plans into beads with dependencies using br CLI. Use when creating task graphs, polishing beads before implementation, or bridging planning to agent swarm execution.
development
Orchestrate Codex skill optimization during active sessions through $cas goal control, $shadow single-session evidence, $tune diagnosis/refinement briefs, and the skill-optimizer custom subagent. Trigger for $opt, skill optimization loops, session-driven skill tuning, meta-skill audits, or explicit validated skill edits. Do not use for general code optimization, product optimization, or performance tuning.
development
Run a targeted fresh-eyes blunder pass over code, specs, plans, adjudications, closure gates, skill edits, or negative-evidence ledgers. Trigger when asked to reread with fresh eyes, find obvious bugs, catch mistakes/oversights/omissions, check for embarrassing misses, or perform a second independent blunder pass before closure. Do not use as a substitute for implementation, adjudication, or verification; use it as the final falsification/check pass for those workflows.
development
Explicitly shadow, tail, watch, follow, monitor, supervise, or companion exactly one Codex session id/path through `$seq`, then apply a named target skill as an interpretation/reporting/proposal/action lens until the watched session stops.