Skip to main content

skill-orchestrate

Autonomous state machine that drives a task through its full lifecycle (research -> plan -> implement -> complete) without user confirmation between phases. Invoke for /orchestrate command.

설치로 이동

소스 정보

저장소
benbrastmckie/nvim
최근 소스 활동
2026년 8월 18일 00:48
감지된 SKILL.md 언어
영어
스타
444
포크
459

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
skill-orchestrate
description
Autonomous state machine that drives a task through its full lifecycle (research -> plan -> implement -> complete) without user confirmation between phases. Invoke for /orchestrate command.
allowed-tools
Agent, Bash, Read, Edit
# Orchestrate Skill Fire-and-forget autonomous loop implementing the 10-state task lifecycle state machine. Drives research, planning, implementation, and blocker escalation without user interaction. ## Context References Architecture documentation (load as needed): - `.claude/docs/architecture/orchestrate-state-machine.md` - Complete state table and transition diagram - `.claude/docs/architecture/handoff-schema.md` - Orchestrator handoff JSON schema Infrastructure (source as needed): - `.claude/scripts/skill-base.sh` - Shared skill lifecycle functions --- ## Execution Flow ### Stage 0: Multi-Task Mode Detection Parse `multi_task_mode` from the delegation context. If true, branch to multi-task stages (MT-1 through MT-5) in the **Multi-Task Mode** section below. If false or absent, fall through to Stage 1 (single-task mode). Read from delegation context: - `multi_task_mode` (default: false) - `session_id` - `focus_prompt` (default: "") - `lit_flag` (default: "false") If `multi_task_mode` is true: skip Stages 1-8 entirely and proceed to Stage MT-1. --- ### Stage 1: Input Validation Read from delegation context: - `task_number` (from `task_context.task_number`) - `session_id`, `focus_prompt`, `lit_flag` - `continue_budget` (default: `false`) → `continue_budget_flag`. Defect B: explicit, operator-typed budget-continuation override for an exhausted work-cycle budget, threaded from the command's `--continue-budget` flag. Never inferred from `session_id`, mtime, or any automatic signal. See Stage 2 below for the override mechanism. Resolve from `specs/state.json`: ```bash PADDED_NUM=$(printf "%03d" "$task_number") TASK_DATA=$(jq -r --argjson num "$task_number" \ '.active_projects[] | select(.project_number == $num)' \ specs/state.json) ``` If `TASK_DATA` is empty: exit with error "Task $task_number not found in state.json". Extract: `PROJECT_NAME`, `TASK_TYPE` (default: "general"), `DESCRIPTION`, `TASK_DIR="specs/${PADDED_NUM}_${PROJECT_NAME}"`. Then resolve the absolute anchor that every dispatched agent will be handed. `TASK_DIR` stays relative (many consumers below depend on that); `TASK_DIR_ABS` is the anchor that goes into delegation contexts, because a dispatched agent has no reliable way to know what the ambient working directory will be when its Write tool runs. ```bash # SKILL_REPO_ROOT is exported by skill-base.sh, which resolves it from BASH_SOURCE rather than # from the ambient cwd. $(pwd) is a last-resort fallback for direct invocation. TASK_DIR_ABS="${TASK_DIR_ABS:-${SKILL_REPO_ROOT:-$(pwd)}/${TASK_DIR}}" HANDOFF_PATH_ABS="${TASK_DIR_ABS}/.orchestrator-handoff.json" ``` ### Stage 1b: Resolve Task-Type Routing Map task_type to the correct research, plan, and implementation agents via the single canonical agent resolver, `command-route-agent.sh` — sourced from the shared manifest-routing-lib.sh ladder (the same one `command-route-skill.sh` uses), against each manifest's `routing_agents` declarations. No case table, no directory probe, no sed derivation: agent names are declared data, not derived strings (see `context/guides/manifest-routing-schema.md`). ```bash source .claude/scripts/command-route-agent.sh "research" "$TASK_TYPE" "general-research-agent" "" RESEARCH_AGENT="$AGENT_NAME" source .claude/scripts/command-route-agent.sh "plan" "$TASK_TYPE" "planner-agent" "" PLANNER_AGENT="$AGENT_NAME" source .claude/scripts/command-route-agent.sh "implement" "$TASK_TYPE" "general-implementation-agent" "" IMPLEMENT_AGENT="$AGENT_NAME" echo "[orchestrate] Task type: $TASK_TYPE → research=$RESEARCH_AGENT, plan=$PLANNER_AGENT, implement=$IMPLEMENT_AGENT" ``` ### Stage 2: Loop Guard Initialization Create or read the loop guard file. This tracks cycle count across conversational turns. **Ephemeral, never committed.** `.orchestrator-loop-guard` is per-cycle runtime state with no freshness check on read (see the resume branch below: any syntactically valid guard file at this path is trusted, with no `session_id` or mtime comparison against the current dispatch). A git-restored copy of a stale guard would silently resume a wrong `cycle_count`/`infra_failures` pair — exactly the hazard this file's gitignore coverage exists to prevent. See `context/standards/orchestrator-runtime-files.md` for the full two-class policy and rationale. ```bash MAX_CYCLES=5 # Single shared implementation, orchestrate-loop-guard-init.sh — see that script's header for # the full contract (MAX_INFRA_FAILURES constant, loop_guard_file/handoff_file assignment, # mkdir -p "$TASK_DIR", and the blocker-escalation counter pair applied further below in this # same fence). This is the same call skill-orchestrate-hard/SKILL.md's Stage 2 makes for its own # genuinely-common portion — everything else in this stage (MAX_CYCLES's own value, the # hard-only loop-guard-staleness detector, churn-state init) stays per-engine, either because it # differs or because it sits inside the locked budget-continuation-override region below, which # this script and its call site never touch. loop_guard_init_json=$(bash .claude/scripts/orchestrate-loop-guard-init.sh "$TASK_DIR" "${HANDOFF_PATH_ABS}") loop_guard_file=$(echo "$loop_guard_init_json" | jq -r '.loop_guard_file') handoff_file=$(echo "$loop_guard_init_json" | jq -r '.handoff_file') MAX_INFRA_FAILURES=$(echo "$loop_guard_init_json" | jq -r '.max_infra_failures') # --- budget-continuation-override:begin --- # Defect B: cycle_count is a per-task, CUMULATIVE budget that survives re-invocation BY DESIGN -- # it is deliberately NOT reset on a new session_id, because that would let an operator silently # bypass MAX_CYCLES by simply re-invoking /orchestrate. test-session-runtime-files.sh Case 3 is # the regression protecting this decision; this override must never disturb it. The override # below is the sanctioned, explicit, loudly-logged escape hatch for a genuinely exhausted budget # -- never automatic, never session_id-gated, never inferred from mtime. Verbatim-twin mechanism # to skill-orchestrate-hard/SKILL.md's Stage 2 (base mode has no loop-guard-staleness detector to # sit after, so this runs immediately before the pre-existing resume-read block below). if [ -f "$loop_guard_file" ] && jq empty "$loop_guard_file" 2>/dev/null; then peek_cycle_count=$(jq -r '.cycle_count // 0' "$loop_guard_file") if [ "$peek_cycle_count" -ge "$MAX_CYCLES" ]; then if [ "$continue_budget_flag" = "true" ]; then exhaust_ts=$(date -u +%s) exhausted_guard_dest="${TASK_DIR}/.exhausted-loop-guard-${exhaust_ts}.json" echo "[orchestrate] BUDGET EXHAUSTED (cycle_count=${peek_cycle_count}/${MAX_CYCLES}) — --continue-budget authorized a fresh budget. Archiving exhausted guard to ${exhausted_guard_dest} for auditability, reinitializing at cycle_count=0 with cross-invocation history fields (dispatch_seq_counter, detected_defects) preserved." >&2 if cp "$loop_guard_file" "$exhausted_guard_dest" 2>/dev/null; then # Reinit IN PLACE from the just-archived copy: reset only cycle_count, never wipe # dispatch_seq_counter (must never repeat a value within this task) or detected_defects. jq --arg updated "$(date -u +%Y-%m-%dT%H:%M:%SZ)" '.cycle_count = 0 | .last_updated = $updated' \ "$exhausted_guard_dest" > "${loop_guard_file}.tmp" && mv "${loop_guard_file}.tmp" "$loop_guard_file" else echo "[orchestrate] WARNING: could not archive exhausted guard to ${exhausted_guard_dest}; proceeding without archiving (cycle_count reset in place)." >&2 jq --arg updated "$(date -u +%Y-%m-%dT%H:%M:%SZ)" '.cycle_count = 0 | .last_updated = $updated' \ "$loop_guard_file" > "${loop_guard_file}.tmp" && mv "${loop_guard_file}.tmp" "$loop_guard_file" fi else echo "[orchestrate] ERROR: work-cycle budget exhausted (cycle_count=${peek_cycle_count}/${MAX_CYCLES}). This is a budget limit, not an error condition -- the task's plan may still have incomplete phases." >&2 echo "[orchestrate] To continue this task's work, explicitly authorize a fresh budget: /orchestrate ${task_number} --continue-budget" >&2 exit 1 fi fi fi # --- budget-continuation-override:end --- if [ -f "$loop_guard_file" ] && jq empty "$loop_guard_file" 2>/dev/null; then # Resume: read existing guard. No session_id or mtime check — see the ephemerality note above; # this is precisely why a git-restorable guard would corrupt the cycle budget. cycle_count=$(jq -r '.cycle_count // 0' "$loop_guard_file") infra_failures=$(jq -r '.infra_failures // 0' "$loop_guard_file") # System-defect observation log for this run (contract: Stage MT-1's `detected_defects` # declaration). `// []` is the forward-compatible read for a guard file written before this # field existed, matching the `// 0` idiom above. detected_defects=$(jq -c '.detected_defects // []' "$loop_guard_file") # dispatch_seq_counter: orchestrator-minted per-dispatch identity (Defect A), verbatim-twin # field to skill-orchestrate-hard/SKILL.md's Stage 2. `// 0` forward-compatible read, matching # cycle_count's own idiom — a guard written before this field existed resumes at 0, never # repeating a value already minted this task since the counter only ever increments (see # mint_dispatch_seq() below). dispatch_seq_counter=$(jq -r '.dispatch_seq_counter // 0' "$loop_guard_file") # Observational-only session_id tracking (NEVER a gate — see Ephemeral note above and # context/standards/status-markers.md's rationale: SESSION_ID is regenerated per /orchestrate # invocation, while this guard is explicitly designed to survive across conversational turns. # The real same-task concurrency guard is task-lock.sh's acquire/heartbeat/release mutex, not # session_id equality). A mismatch is logged, never branched on. guard_session_id=$(jq -r '.session_id // ""' "$loop_guard_file") if [ -n "$guard_session_id" ] && [ "$guard_session_id" != "$session_id" ]; then echo "[orchestrate] INFO: loop guard was last written by a different session_id ('${guard_session_id}' vs current '${session_id}') — expected on conversational resume, not gated." fi echo "[orchestrate] Resuming — cycle $cycle_count of $MAX_CYCLES (infra failures: $infra_failures of $MAX_INFRA_FAILURES)" else # Fresh start: create guard atomically via init-marker. A plain # `>` redirect has no O_EXCL semantics, so two racing writers could both take # this branch and stomp each other's counters; init-marker's mkdir-gate + # tmp-mv payload guarantees exactly one winner. On a lost race (exit 1), # degrade to the same resume-read the `if`-branch above performs. if jq -n \ --arg session_id "$session_id" \ --argjson max_cycles "$MAX_CYCLES" \ --argjson max_infra_failures "$MAX_INFRA_FAILURES" \ --arg started "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \ '{ "session_id": $session_id, "cycle_count": 0, "max_cycles": $max_cycles, "infra_failures": 0, "max_infra_failures": $max_infra_failures, "current_state": "reading", "detected_defects": [], "started": $started, "last_updated": $started, "dispatch_seq_counter": 0 }' | bash .claude/scripts/task-lock.sh init-marker "$loop_guard_file"; then cycle_count=0 infra_failures=0 detected_defects='[]' dispatch_seq_counter=0 echo "[orchestrate] Starting fresh — MAX_CYCLES=$MAX_CYCLES, MAX_INFRA_FAILURES=$MAX_INFRA_FAILURES" else # Lost the creation race: another writer won. Resume from their guard, reading BOTH # counters — not just cycle_count — and the system-defect observation log alongside them. cycle_count=$(jq -r '.cycle_count // 0' "$loop_guard_file") infra_failures=$(jq -r '.infra_failures // 0' "$loop_guard_file") detected_defects=$(jq -c '.detected_defects // []' "$loop_guard_file") dispatch_seq_counter=$(jq -r '.dispatch_seq_counter // 0' "$loop_guard_file") echo "[orchestrate] Resuming (lost init race) — cycle $cycle_count of $MAX_CYCLES (infra failures: $infra_failures of $MAX_INFRA_FAILURES)" fi fi # mint_dispatch_seq(): named-shim to the single shared implementation, # skill_orchestrate_mint_dispatch_seq (scripts/skill-base.sh) — see that function's header for the # full contract. Kept as a locally-named function (not called directly by name) because Stage 4/5 # call sites below still say `mint_dispatch_seq`, and this file pair is where a one-sided rename # is a known recurring defect class. Source is defensive/idempotent: this Stage 2 fence has no # earlier explicit source line of its own to depend on. source .claude/scripts/skill-base.sh mint_dispatch_seq() { skill_orchestrate_mint_dispatch_seq "$loop_guard_file" } # Blocker escalation counter (reset each /orchestrate invocation) — from the same shared # orchestrate-loop-guard-init.sh call above. blocker_escalation_count=$(echo "$loop_guard_init_json" | jq -r '.blocker_escalation_count') MAX_BLOCKER_ESCALATIONS=$(echo "$loop_guard_init_json" | jq -r '.max_blocker_escalations') # Drift detection constants (reset each /orchestrate invocation) — base-mode-only; hard mode has # no Stage 5a Drift Inspection equivalent (its own H5 divergence-audit mechanism plays that role # instead), so these stay out of the shared script. drift_inspection_count=0 MAX_DRIFT_INSPECTIONS=1 DRIFT_COMPLETION_THRESHOLD=0.70
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기