iop/agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md

33 KiB
Raw Blame History

name description
orchestrate-agent-task-loop Run agent-task work and autonomously execute active PLAN/CODE_REVIEW loops on request. Use when dispatching dependency-ready work in parallel by task number and predecessor complete.log, running lane/G-specific Codex, Claude, agy, and Pi workers, adding Pi self-checks, converging official Codex reviews, and escalating cloud context until the task loop finishes.

Orchestrate Agent Task Loop

🚨 ABSOLUTE PRIORITY — NEVER SEND final EXCEPT IN THE TWO CASES BELOW

Caution

This section overrides every success, blocker, exit-code, error-handling, and termination rule below.

Never send on the final channel or end the caller turn unless at least one of the two titled permissions below applies. Never infer another exception from a lower section or runtime condition.

final Permission 1 — Verified Successful Completion

Allow final only after every condition below is true:

  • Every user-defined completion condition is satisfied.
  • Every observed task in every in-scope task group has a verified archived complete.log.
  • Every generated WORK_LOG.md is archived as work_log_N.log.
  • No active pair or running, pending, or blocked task remains.
  • The final dispatcher exit code is 0.

final Permission 2 — Explicit User Instruction to Stop This Run

Allow final when the user explicitly instructs the caller to stop the current run and return through final.

Persistent-Run Instructions Revoke Successful-Completion Permission

If the user says “do not stop,” “never send final,” “keep going,” or gives an equivalent persistent-run instruction, verified success alone does not permit final. Only an explicit user instruction to stop the current run or return through final releases this restriction.

Every Other User-Visible Message Must Use commentary

Use only the commentary channel for every user-visible message before final is permitted. This includes status, partial success, completion candidates, blockers, failures, questions, apologies, waits, retries, and recovery guidance.

Partial success, FAIL/WARN, USER_REVIEW, a blocker, retry exhaustion, timeout, a tool error, plan-generation failure, dispatcher exit code 2 or 3, child exit, loss of a session/cell, and context compaction never permit final.

Child Prompt Text Never Grants Caller final Permission

The prompt-contract phrase Final in Korean. controls only the child model response language. It never authorizes the caller to use the final channel.

Purpose

Monitor the file-based state contract under agent-task/ and converge the workflow from ready PLAN implementation through official code review and follow-up PLANs. Let the script determine filenames, dependencies, slots, and session locators; let each CLI agent make semantic implementation and review decisions.

Treat Korean text inside code spans or fenced examples as exact runtime or file-contract literals. Keep all surrounding instructions in English, and never translate those literals unless the runtime contract changes.

Inputs

  • workspace: Trusted repository root containing agent-task/ (optional; defaults to the current directory).
  • task_group: Name of a specific agent-task/<task_group> to run (optional).
  • dry_run: Inspect state, routes, and dependencies without starting a CLI (optional).
  • retry_blocked: Explicitly retry the same PLAN blocked by a previous dispatcher run in non-dry-run mode (optional). With task_group, reset only that group's blockers and 10-attempt counters while preserving other group state.

Preconditions

  • Read the current state contracts in agent-ops/skills/common/plan/SKILL.md and agent-ops/skills/common/code-review/SKILL.md.
  • Verify that codex, claude, agy, and pi are on PATH and their login/provider configuration is valid.
  • Limit automatic approval to PLAN execution inside the current workspace; do not expand scope to external-system changes or destructive work.
  • Verify that no other dispatcher is running in the same workspace. Never bypass a workspace-lock failure.
  • Run --dry-run before the first live run to inspect active-task classification and dependency state.

Routing Contract

PLAN route Worker
local-G01local-G06 Pi iop/ornith:35b, thinking high
local-G07local-G08 KST [07:00,23:00) agy Gemini 3.6 Flash (Medium); [23:00,07:00) Pi iop/laguna-s:2.1
local-G09local-G10 Claude claude-opus-4-8, effort xhigh
cloud-G01cloud-G02 agy Gemini 3.6 Flash (Low)
cloud-G03cloud-G04 agy Gemini 3.6 Flash (Medium)
cloud-G05cloud-G06 agy Gemini 3.6 Flash (High)
cloud-G07cloud-G08 Claude claude-opus-4-8, effort xhigh
cloud-G09cloud-G10 Codex gpt-5.6-sol, reasoning xhigh
Every CODE_REVIEW-* Codex gpt-5.6-sol, reasoning xhigh

Concurrency limits:

  • Pi ornith:35b: 3.
  • agy: 1.
  • Official Codex review: no separate numeric limit.
  • Run worker/self-check and official review in parallel when they belong to different dependency-ready tasks, regardless of write-set. Prevent only duplicate execution of the same task.
  • Even with complete.log, treat an explicit predecessor as unfinished while live model/review execution evidence for that task remains. Delay only its consumers; do not propagate the delay to dependency-free siblings or other task groups.
  • Run official reviews for different dependency-ready tasks in parallel.
  • Before the first review batch, normalize the Agent-Ops-managed .gitignore block once so reviews do not concurrently modify the same shared control file.
  • Treat 수정 파일 요약 as review-scope and stagnation evidence, not as a dispatch-order constraint.

Prompt Contract

Keep control prompts in English, insert absolute paths only, and do not expand these sentences unnecessarily.

  • Cloud worker: Read {PLAN_PATH} and complete the task. Final in Korean.
  • Pi worker: Think in English. Final in Korean. Read {PLAN_PATH} and complete the task.
  • Pi self-check: Think in English. Final in Korean. Read {CODE_REVIEW_PATH} and fill every missing implementation field. Do not finish until all implementation fields are complete. This is a self-check of completed work, not a review. Read {PLAN_PATH} and finish any missing work. Recheck and fix your work.
  • Official review: Read {CODE_REVIEW_PATH} and start the review. Final in Korean.
  • Review-exit recovery: Continue the review for {TASK_PATH}. Final in Korean.
  • Context escalation: Continue from {LOCATOR_PATH}. Check the saved context and current workspace. Final in Korean.

Never ask a worker, self-check, or review model to create, edit, or summarize WORK_LOG.md.

Do not treat Pi self-check exit code 0 as success by itself. Set selfcheck_done=true only when the implementation-completion table, 구현 체크리스트, 계획 대비 변경 사항, 주요 설계 결정, 검증 결과, and final CODE_REVIEW synchronization item in CODE_REVIEW_PATH all contain real content. If any field is empty, retry with the same prompt. After 10 consecutive incomplete results, block that task and continue draining independent work.

For Pi recovery attempts, pass only Read {PLAN_PATH}. Continue. without a locator explanation. For other CLI escalation attempts, pass Continue from {LOCATOR_PATH}. Check the saved context and current workspace. Final in Korean. Preserve the collaboration prohibition and next-state-materialization sentence in official-review escalation and recovery prompts. Do not ask the model to write a separate handoff summary.

When recovering a KST-night local-G07local-G08 Laguna locator or a terminal session-stall locator left by an earlier dispatcher, do not create a fresh session ID. Resume the prior locator's native session file with pi --session and the existing --session-dir, and pass Think in English. Final in Korean. Continue this session and complete the current task. After a dispatcher restart, find the failed locator and resume the same session. Count this same-session restart toward the same stage's 10-consecutive-failure limit.

Work-Log Contract

  • Keep exactly one agent-task/{task_group}/WORK_LOG.md per task group. Do not create one in a split-subtask directory.
  • Allow only the dispatcher to modify this file. Worker/self-check/review models need not read or update it, and success must not depend on its prose.
  • Append chronological START/FINISH rows with time, task, role, attempt, model, result, and locator. Record time in KST (UTC+09:00) as YY-MM-DD HH:MM:SS, for example 26-07-26 07:40:15. Use this single timeline to inspect parallel execution order.
  • When code-review moves a PASS task, do not move, copy, or delete the task-group WORK_LOG.md. For a single task, create the archive destination and move every artifact except WORK_LOG.md, preserving the path where the dispatcher writes the final FINISH.
  • After every observed task in a task group has a verified complete archive and no active/running task remains, append the final FINISH and move the generated WORK_LOG.md under the final completed archive's group root as work_log_N.log. If an archive exists after restart but the last START lacks FINISH, do not terminate or archive while any PID/start token, per-attempt process marker, or pidless stream/native evidence remains live. Track it until execution evidence has ended and the complete archive is verified, then append FINISH with reconciled:verified-complete-archive and move the log. Use agent-task/archive/YYYY/MM/{task_group}/ for split tasks and the actual suffix-bearing archive destination for a single task. Set N to one more than the maximum suffix for the same task group across all months, starting at 0.
  • If WORK_LOG.md archiving fails or multiple active/archive sources exist, drain other independent work and return non-terminal exit 3 for retry. Return successful exit 0 only after a completed group that generated a log has no active WORK_LOG.md and its work_log_N.log is verified. Keep an incomplete group's WORK_LOG.md active for blocker or exit 3 recovery.
  • Split each attempt locator into stream.log for model stdout/stderr and heartbeat.log for dispatcher state. Determine health only from the newest progress in stream.log and native session events; never use heartbeat mtime as progress evidence. Do not copy either log into WORK_LOG.md.
  • If locator refresh temporarily fails after an attempt starts, do not terminate a live model process or start a duplicate task. Record a warning, keep monitoring, and preserve error evidence at the next successful refresh.
  • After verifying a PASS archive's complete.log and confirming no live execution evidence for that task, delete all of its attempt directories, including locators, native sessions, stream.log, heartbeat.log, and CLI auxiliary logs. Do not delete them while a model process or conservatively active pidless stream/native evidence remains. Treat transient deletion failure as non-terminal exit 3 for the next reconciliation without blocking the completed task or other tasks; do not return successful exit 0 while any attempt directory remains. Preserve failed or blocked attempt logs as recovery evidence.
  • Record log-creation or append failure in the locator as work-log-setup or work-log-runtime-write and block the task.
  • Exclude dispatcher-authored WORK_LOG.md changes from official-review progress/stagnation signatures. Count only real changes in PLAN/CODE_REVIEW, review logs, and the write-set.

Caller Lifecycle and Status Display

  • ABSOLUTE RULE — Do not stop the whole task group when a task-local blocker appears. Delay only the blocked task and consumers that require its incomplete result as a predecessor. Keep the caller turn active until every independent ready/running task finishes.
  • ABSOLUTE RULE — Scan the complete new-task candidate set only on initial dispatcher entry and immediately after creating a verified complete.log. After a worker/self-check/review attempt ends or a task changes stage, reclassify only that task. After complete.log is created, immediately start every runnable task except currently running tasks in the same pass. Another task's execution, wait, dependency, review, or recovery state must not block a candidate. If no candidate or running task remains and only blockers and their dependent waits remain, exit with code 2.
  • Treat the caller agent running this skill—not the child dispatcher process—as the lifecycle owner. The dispatcher is only an execution mechanism. Child exit, tool yield, or loss of a session/cell never ends the caller lifecycle by itself.
  • Keep the caller turn active and launch the dispatcher as one persistent foreground execution. If the execution tool returns a live session/cell ID, poll the same ID. Never start a duplicate dispatcher while the child is live.
  • Never wrap the dispatcher in timeout, a short wait_for, or an arbitrary cancel/terminate wrapper. Tool yield or expiration of a response window is not process termination; poll the same session/cell again.
  • If the child exits unexpectedly or its session/cell is lost, re-inspect active tasks, locators, PIDs, and state, then continue every available reconnect, recovery, or rerun path. Exit code 0 is successful terminal state. Exit code 2 is a drained blocker or explicit persistent-state-error terminal state. Exit code 3 is a non-terminal tracking state, including another dispatcher's workspace lock, a live external agent, or an unexpected dispatcher interruption; inspect PID, locator, and state and continue tracking or recovery.
  • On a scheduler/control-plane exception or unexpected exception in an individual agent coroutine, do not immediately freeze it as a task blocker or let the dispatcher event loop cancel other running agents and child processes. Monitor every independent running agent until natural completion, return non-terminal exit 3, and let the next dispatcher reconcile file and state results. Even when the original exception is a persistent-state error, do not convert it to exit 2 if any agent was running.
  • In drained-blocker terminal state, persist the orchestration group as blocked, directly blocked tasks as blocked, consumers waiting on their predecessors as waiting, and verified independent completed tasks as complete in .git/agent-task-dispatcher/state.json. On re-entry, set incomplete observed tasks back to orchestration state active, then reevaluate actual task-local blockers and dependencies.
  • Persist observed tasks and the complete same-name archive baseline present at startup, regardless of complete.log, in .git/agent-task-dispatcher/state.json. If an active task disappears after child restart, recover completion only when exactly one new complete.log archive absent from the baseline exists; block when none or multiple exist. Do not count a late complete.log added to an incomplete archive that existed before execution as current-run completion.
  • If existing state.json cannot be read or validated as a JSON object, block the dispatcher. Never replace it with empty state or reset the 10-attempt budget. Repair or explicitly handle it before rerunning.
  • When a new user turn arrives, continue tracking the same overall request unless it explicitly cancels the previous request.
  • Send each 작업시작, 자가검증시작, 리뷰시작, 리뷰재시도, Pi복구재시도, 세션응답복구재시도, 세션연결재시도, 리뷰결과, 작업대기, 작업차단, 디스패치추적대기, and 작업완료 banner to the user through commentary. Even without a new banner, while work is active report the current stage, latest locator, and task-group WORK_LOG.md path within 60 seconds.
  • Determine every CLI's health/progress primarily from actual stdout/stderr in stream.log, plus native session events when available. Never use heartbeat mtime as progress evidence. Record dispatcher PID, agent PID, each process start token, and the per-attempt process environment marker in the locator. Another dispatcher must not start a duplicate attempt merely because the stream is quiet when the PID/start token or marker shows the same process is alive. For a locator without an agent PID, never infer stale state or duplicate recovery from elapsed time while any stream/native progress evidence exists; use only an actual terminal error or confirmed process exit as recovery evidence for every model. Run Pi with --mode json so thinking_delta, text_delta, and tool streams reach stdout. End an exact Pi toolCall-to-all-toolResult interval only when every toolCall.id in the preceding assistant event matches a later toolResult.toolCallId; never terminate the process on a time limit. If the locator lacks an agent PID during this interval, never classify it as stale or duplicate recovery based on log age; require recorded process evidence to show termination. Do not infer tool execution from starting, unknown, model reasoning, or post-toolResult state. Outside this interval, use only stream.log updates for Pi liveness; toolResult alone does not reset the model-response silence clock. If the stream stops for three minutes outside tool execution, store the final stream excerpt as pi_silence_inspection for Pi or stream_silence_inspection for another CLI, emit 모델응답점검, and do not terminate the model process. Recover only from an actual terminal error or process exit.
  • Detect a local-model repetition-loop only when the same normalized chunk repeats three consecutive times with no new tool event or file/state change. Do not infer it from similarity or semantic duplication in thinking_delta/text_delta. This signal alone must not terminate the process, block the task, trigger recovery/retry, or escalate the model; keep observing for substantive progress or an actual terminal error.
  • Keep provider-connection, provider-stream-disconnect, session-stall, generic-error, process-terminated, context/quota/model errors, and review-control violations distinct, but make them share a budget of 10 consecutive automatic recovery failures for the same task stage. On the 10th failure, block that task and do not auto-resume after cooldown. Reset the stage counter after success.
  • Record an explicit terminal blocker when Pi self-check leaves implementation fields incomplete 10 consecutive times or official review makes no change 10 consecutive times.
  • While one task recovers or becomes blocked, continue every ready/running task that does not require it as a predecessor. Internal recovery or blocking must not trigger an arbitrary complete-candidate rescan.
  • If review shared-state preflight fails, block only ready review tasks and still start every worker/self-check in the same pass. The complete scan after complete.log must preserve the existing snapshot rather than reread already running task directories, avoiding races with parallel archive moves that could stop another process.
  • For KST-night local-G07local-G08 Laguna locator context-limit/session-stall, prefer the Prompt Contract's same-session resume and display Pi세션연속재시작. Use a fresh session and 세션응답복구재시도 only for other legacy Pi session-stall recovery.
  • Do not stop for user review based on filename alone. Recognize a user-review terminal blocker only when the active task's USER_REVIEW.md contains 상태: USER_REVIEW, 유형: milestone-lock, a real agent-roadmap/**/milestones/*.md target, non-없음/미정 blocker rationale, unresolved decisions, and resume conditions that prevent the next safe implementation step. If the form is incomplete or conflicts with active PLAN/CODE_REVIEW, block it as a task-state contract error instead.
  • Recognize only the single 종합 판정: PASS|WARN|FAIL field inside ## 코드리뷰 결과 as the review verdict. Never parse the same string in implementation evidence, command output, or example text as the runtime verdict.
  • Locator/raw logs under .git/agent-task-dispatcher/runs/ are internal recovery state and may not appear in the normal project tree. Include the locator= path emitted when the dispatcher starts an attempt and the task-group WORK_LOG.md path in status updates.
  • If a specified task_group has neither an observed active task nor a persisted completed task, return state error unobserved-task-group with exit code 2; never treat it as empty completion.
  • If child failure is recoverable inside the repository, continue within the 10-attempt budget. After draining independent work, report a blocker that the caller cannot clear in the current turn—such as exhausted budget, required user decision, or external permission—with its path, evidence, and resume condition.

Failure Classification and Reporting Contract

  • Record dispatcher PID, actual agent PID, import time, source path, import-time SHA-256, attempt-start current SHA-256, and dispatcher_source_matches_loaded in every attempt locator. Every failure banner and subsequent status must present the locator's exact failure_class, failure_source, provider_transport_failure_confirmed, dispatcher_pid, agent_pid, dispatcher_source_sha256, source-match state, and locator; never summarize them into a broader cause.
  • A running Python dispatcher does not hot-reload source edits. If dispatcher_source_matches_loaded=false, do not claim that new rules are active. Report the loaded/current hashes and execution-version difference until the process-owning session can safely exit and restart.
  • Use provider-connection or provider-stream-disconnect only when original CLI terminal diagnostics contain a strong provider pattern in provider/backend/SSE context. Do not infer provider failure from connection refused, dial tcp, or curl peer failure in ordinary tool/test stderr. For a confirmed attempt, preserve failure_source=provider-terminal-diagnostic, provider_transport_failure_confirmed=true, failure_evidence_source, and failure_evidence_excerpt in the locator.
  • Treat legacy locator session-stall as a record of an earlier dispatcher timeout policy, not as provider failure. During recovery, report failure_source=dispatcher-timeout, provider_transport_failure_confirmed=false, termination_initiator=dispatcher, and the original timeout phase/seconds. Never let the current dispatcher create a new silence timeout.
  • Record a SIGTERM-family termination not initiated by the dispatcher as process-terminated, with failure_source=process-termination and termination_initiator=unknown. Never classify exit code 143 as provider failure without actual provider terminal evidence.
  • Do not generalize one pi -p fresh/isolated session attempt to a Pi TUI or system-wide provider outage. Describe a system-level provider outage only with additional controlled reproduction using the same command, model, and prompt, or backend-health evidence.
  • Count process-terminated in the same per-stage consecutive-failure budget as other automatic-recovery classes. On the 10th consecutive failure, block that task; never reset the budget after cooldown or auto-resume. A shared budget does not imply common causation or establish provider-failure evidence.

Procedure

  1. Inspect state.

    • Print active tasks, routes, stages, and dependencies:

      python3 agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py --dry-run
      
    • Treat NN_... as immediately eligible. Treat NN+PP[,QQ...]_... as eligible only after each predecessor's complete.log is found once in the active or narrow archive lookup for the same task group and predecessor execution evidence has ended.

    • Never infer an implicit dependency from numeric order alone.

  2. Run the dispatcher.

    • Run all active tasks:

      python3 agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py
      
    • Run one task group:

      python3 agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py --task-group <task_group>
      
    • If a worker/self-check/review future ends without complete.log, reread only that task and run its next stage. Do not rescan the complete candidate set.

    • Persist active_stage for a running task. After dispatcher restart, exclude only that task from candidates and immediately dispatch every other dependency-ready task in parallel. A running task must not delay candidate discovery or another task's execution.

    • ABSOLUTE RULE: Scan the complete candidate set only at initial entry and immediately after creating a verified complete.log. In that scan, exclude only tasks shown as running by persistent state and native session/locator evidence; immediately run all dependency-ready tasks in parallel. An unmet dependency excludes only that task. Exit instead of polling when no candidate remains.

    • Persist Pi worker success, Pi self-check success, and official review as separate stages. If restart state is worker_done=true and selfcheck_done=false, resume with a fresh self-check session on the same Pi model, not with worker or review.

    • Key persistent state to the task/plan/tag generation at the start of PLAN. Checklist/body edits to the same PLAN do not reset the stage; a new plan number in a follow-up PLAN does.

    • Send an already completed review stub with no dispatcher execution record to review. Never send dispatcher-recorded Pi worker success to review before self-check completes.

    • Start official review and worker/self-check together when they belong to different dependency-ready tasks. Do not wait for another task's checkout or write-set.

    • Let the dispatcher record every worker/self-check/review attempt start and finish in the task-group WORK_LOG.md.

    • Archive WORK_LOG.md as work_log_N.log only after the final task review process exits, the dispatcher appends FINISH, and a complete scan finds no active/running task in that group. The code-review process must not move it first.

  3. Escalate and recover context.

    • Escalate agy -> Claude -> Codex or Claude -> Codex only on terminal provider error events or stderr evidence of context/output limits, provider quota/rate limits, unavailable models, or confirmed provider transport errors. For AGY, accept top-level error, fatal, request.failed, or turn.failed events; failed/rejected status with a top-level error/code; stderr; or strong RESOURCE_EXHAUSTED, HTTP 429, quota, or rate-limit evidence in agy-cli.log. For Claude, classify a rate_limit_event with rate_limit_info.status=rejected, an error result with api_error_status=429 or error=rate_limit, or a You've hit your session limit · resets ... terminal diagnostic as provider-quota. Never escalate from an assistant message, source text, tool/test output, or a plain quota-configuration string in an AGY log.
    • Target Codex gpt-5.6-terra with reasoning high when escalating from Claude to Codex.
    • If Codex returns the same error, retry in a fresh Codex session using the locator while preserving the previous Codex model/reasoning and sharing the same stage's 10-consecutive-failure limit. Continue dispatching other tasks during recovery.
    • When current source reads a locator blocked 10 times as generic-error by older dispatcher source, collapse those 10 failures into one terminal error and clear only that task's blocker only if all 10 terminal-evidence records for the same task/plan/role/source/execution target reclassify to the same escalatable error. Include stream.log and the attempt's agy-cli.log for AGY. Do not adjust automatically when any history is missing or mixed, or when the locator dispatcher source hash equals the current source hash. Dry-run must display this escalation recovery and next model without writing state. Live execution must choose the higher target from the locator's actual failed target, not the initial PLAN route, inherit locator context, and restore the same escalation target and locator from persisted reclassification metadata after immediate restart.
    • Recover timeout, crash, process termination, permission, and ordinary implementation errors on the same target within the same stage's 10-consecutive-failure limit, preserving the actual failure class and locator. At exhaustion, block only that task and keep dispatching independent work.
    • On success after escalation, record worker_cli and worker_model from the successful locator's actual target, not the initial PLAN route.
    • Never escalate Pi to a cloud model.
    • Use attempt identity <task-name>__p<plan>__<role>__aNN. Record workspace, CLI/model/reasoning effort, PLAN/review, WORK_LOG.md, session ID, native session path, and raw output log in the locator.
    • Store locators under repository .git/agent-task-dispatcher/runs/. Fall back to ${XDG_STATE_HOME}/agent-task-dispatcher/<workspace-id>/runs/ only when .git state is unwritable.
  4. Converge review.

    • Run every official review in an independent Codex one-shot session with no separate numeric limit. Dispatch all ready reviews in parallel.
    • For finalization recovery without an active PLAN, recover the review target from the archived plan log for the same task/plan/tag. Never treat the write-set as a dispatch blocker.
    • Forbid collaboration/sub-agent tools in official review and finish inside the current one-shot session. If such a tool call appears, clean up that attempt's independent subprocess group and retry in a fresh review session. Count the failure toward the same stage's 10-consecutive-failure limit.
    • Delegate PASS archive, WARN/FAIL follow-up pairs, and review-finalization recovery to the code-review file contract.
    • Reclassify any remaining active pair and send it to worker or review.
    • Declare stagnation only when the plan write-set source snapshot and review/finding artifacts are all unchanged. Display 루프정체경고 and retry with backoff; on the 10th unchanged attempt, block that task as review-no-progress-limit.
    • Record a verified USER_REVIEW.md, dependency ambiguity, 10 repeated failures, or work-log setup/runtime-write failure only as that task's blocker. Delay only the blocker and consumers that depend on it; continue every independent ready/running task. Return drained terminal blocker exit code 2 only when no independent work remains.

Verification Checklist

  • Scan the complete candidate set only on initial entry and immediately after verified complete.log; start every ready candidate except running tasks in parallel in the same pass.
  • Confirm the actual CLI/model for each route matches the routing table.
  • Run exactly one fresh-session self-check only for Pi work.
  • Run every official review with Codex gpt-5.6-sol xhigh and dispatch dependency-ready reviews in parallel without a numeric limit.
  • Locate the native session and output log for every attempt locator.
  • Record every worker/self-check/review attempt START/FINISH in one task-group WORK_LOG.md.
  • For every completed task group that generated WORK_LOG.md, archive a work_log_N.log containing the final review FINISH and leave no active WORK_LOG.md.
  • Verify that a PASS task is archived and each newly released dependent task starts.
  • For success, verify every task's complete.log. For blocker exit, verify that no ready/running task remains and only task-local blockers and their dependent waits remain.
  • On blocking, output the task, reason, and locator.
  • If verification fails, stop the dispatcher and report only the cause without manually moving or overwriting active PLAN/CODE_REVIEW files.

Output Format

------------------------------------------
작업시작: 03+01_event_contract_unit_tests
------------------------------------------
model=pi/iop/ornith:35b
plan=/absolute/path/PLAN-local-G05.md
work_log=/absolute/path/WORK_LOG.md
[03+01_event_contract_unit_tests][worker][a00] ...

------------------------------------------
리뷰시작: 03+01_event_contract_unit_tests
------------------------------------------
model=codex/gpt-5.6-sol xhigh
review=/absolute/path/CODE_REVIEW-local-G05.md

Use the same separator format for 작업대기, 작업수행중, 자가검증시작, 로그보완재시도, 모델승격, 리뷰결과, 루프정체경고, 작업차단, 작업로그아카이브, and 작업완료.

Prohibitions

  • Never reevaluate PLAN/CODE_REVIEW lane or G in the dispatcher or rename those files.
  • Never infer dependency from numeric order when no predecessor index is present.
  • Never scan the complete archive or read archive files outside dependency candidates.
  • Never ask a worker to perform official review, archive work, or create complete.log.
  • Never treat Pi self-check as official review.
  • Never depend on a model-authored handoff summary for context recovery.
  • Never treat a generic failure as token/quota failure and escalate it to a higher model.
  • Never resolve USER_REVIEW.md automatically or guess a user decision.