execute-db7ce2 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited execute-db7ce2 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Drive an approved / user-supplied / review-only plan through the execution loop, quality polish (Step 3.5), docs consistency (3.6), security preflight (3.7), and delivery (Step 4). Supports multi-batch runs via --stop-after <stage> and the unsafe --accept-external-state opt-in.
exec -> polish -> docs -> security -> delivery lifecycle.Consistency (3.6), Security Preflight (3.7), Delivery (Step 4), shared .review-loop/config.md, shared .review-loop/sessions/*.md, Claude CLI default reviewer, optional local Codex reviewer, shared reviewer schema, Stage 1 hallucination guards.
.agents/skills/plan/SKILL.md.
The Orchestrator MUST Read each of these files at start. They are the single source of truth for this skill's execution loop and output schemas.
docs/protocol/session-file.mddocs/protocol/execution.mddocs/protocol/executor-output.mddocs/protocol/reviewer-output.mdDo not re-derive any rule that already lives in a protocol doc. When a step below says "see docs/protocol/<doc>.md §Foo", follow that doc verbatim. The startup read set is complete only after all 4 docs above have been read explicitly; embedded executor/reviewer prompt bodies are not a substitute for reading executor-output.md and reviewer-output.md.
.review-loop/sessions/{uuid}.md.review_loop_executor never writes the session file directly.review_loop_reviewer never writes the session file directly.the required task context directly. Do not rely on inherited or forked parent thread context.
review_loop_executor andreview_loop_reviewer during this execute session.
spawn_agent call, call close_agent on any completed Codex subagent id from earlier execution rounds, polish substeps, or local-reviewer rounds unless the orchestrator explicitly intends to reuse that exact id.rejected, and any information needed for the session-file update, retry decision, or user-facing failure report has been copied into orchestrator-owned state.
retry finishes, close the completed Executor and local Reviewer subagents for that round before spawning the next agent or moving to the next stage.
completed-agent cleanup does not apply to it. Continue deleting its temporary prompt file immediately after the command returns.
Exactly one of the three entry flags must be supplied. Supplying more than one is a parse error; the Orchestrator exits without touching the session file or the lock.
# Entry mode 1 — resume an approved session
review-loop:execute --session <uuid> [--stop-after <stage>] [--handsfree] [--accept-external-state]
# Entry mode 2 — execute a user-supplied plan verbatim
review-loop:execute --plan <text|path> --title <...> [--description <...>] [--stop-after <stage>] [--handsfree] [--accept-external-state]
# Entry mode 3 — pure code-review over the current working tree
review-loop:execute --review-only [--description <what was done>] [--stop-after <stage>] [--handsfree] [--accept-external-state]Before parsing flags or touching session state, Read the 4 Protocol Imports docs listed above.
Execute before any lock or session write.
--session,--plan, --review-only are present. If ≠ 1 → print usage and exit with non-zero.
supported set per docs/protocol/execution.md §Runtime-supported subsets:
exec-roundbefore-polishbefore-docsbefore-securitybefore-deliverydelivery (default when flag is absent)Codex Stage 1 accepts every value listed above for --stop-after; before-polish, before-docs, and before-security are the most common request points and are highlighted here for that reason. exec-round and before-delivery are also accepted. delivery is the default no-early-stop value (run through delivery), not a stop point.
Any other value → reject at parse time. Error message must list the supported subset. Do not create the lock, do not touch the session file.
Handsfree alone does NOT auto-accept drift — see --accept-external-state.
accept" wherever docs/protocol/session-file.md instructs the Orchestrator to pause-and-confirm (drift check step 4; backward-compat missing-baseline fallback). The flag has no effect outside those two prompts — it does not bypass unmerged-conflict errors, unknown git-state errors, or per-stage hard-stops.
.review-loop/config.md if present; otherwiseuse Stage 1 defaults documented in .agents/skills/review-loop/SKILL.md §Config Loading.
outside-sandbox Claude CLI reviewer path. If codex_reviewer_backend: codex is set, use the local Codex reviewer directly. Do not auto-fall back from the Claude path to the local Codex reviewer.
Compute the session UUID so the lock path is known; do not read or write the session file yet — the single-writer lock must come first per docs/protocol/session-file.md §Lock file lifecycle.
--session <uuid>: adopt the UUID the user supplied. Confirm thepath is well-formed (.review-loop/sessions/{uuid}.md). Do not Read the file content yet.
--plan <text|path>: generate a fresh lowercase UUID.--review-only: generate a fresh lowercase UUID.Flag parsing (Step 0) and --stop-after validation have already completed; those steps are intentionally pre-lock.
Per docs/protocol/session-file.md §Lock file lifecycle. Every subsequent read and write of the session file (creation, resume-time re-baselining, round updates) must happen under this lock.
.review-loop/sessions/{uuid}.lock — PID, ISO-8601 started_at,entry_point, stop_after.
PID dead → prompt-to-recover.
--stop-after stop,signal abort trap, unrecoverable error trap).
Per the entry-mode initialization table in docs/protocol/session-file.md §Entry-mode initialization table. All reads and writes below happen after Step 1 acquired the lock.
entry_point is set once on session creation per docs/protocol/session-file.md §Session Metadata schema; --session resumes preserve the original value.
--session <uuid>.review-loop/sessions/{uuid}.md. If the file is missing →release the lock and exit with an error.
missing, pause-and-prompt per docs/protocol/session-file.md §Backward-compat fallback. --accept-external-state auto-picks (A). Handsfree alone blocks. The entry_point backfill rule for legacy sessions also lives in docs/protocol/session-file.md §Session Metadata schema; this skill defers to the protocol doc rather than re-stating it here.
--plan <text|path>.review-loop/sessions/{uuid}.md with the --plan column ofthe init table:
## Approved Plan → - Source: user-supplied followed by theuser's free-form plan text injected verbatim. If --plan was a path, read the file and inject its contents; if it was inline text, inject directly.
## Current Phase: execution.## Context = "User-supplied plan; no planning-phase contextcaptured." plus any --description.
## Acceptance Criteria = "Implementation matches theuser-supplied plan in ## Approved Plan."
## Session Metadata:entry_point: execute-from-planplan_source: user-suppliedbase_head, base_dirty, etc.) fromcurrent repo state.
execution rounds the reviewer's plan-conformance deviations are advisory / MINOR per docs/protocol/execution.md §Provenance-aware reviewer prompts, plan_source: user-supplied block. Correctness + intent-alignment are still enforced strictly.
--review-only.review-loop/sessions/{uuid}.md with the --review-onlycolumn of the init table:
## Approved Plan → - Source: review-only followed by thetwo-line canonical sentinel exactly as documented in docs/protocol/session-file.md §Canonical sentinel for review-only:
(none — review-only mode)
Scope: see `## Review Target` section below.No other text goes into the body.
## Review Target (non-canonical supplemental section) ispopulated from the user's --description / scope arguments.
## Current Phase: execution.## Files Changed — populated from the actual post-open dirty set(read-only snapshot).
## Session Metadata:entry_point: review-onlyplan_source: review-onlydocs/protocol/execution.md §--review-only first-round skip.
Per docs/protocol/session-file.md §Drift-check decision tree (5 steps). For --plan and --review-only fresh sessions, the freshly written baseline equals current state so steps 2-3 pass cleanly. For --session resumes, run the full decision tree.
On detected drift:
(A) Accept drift and reset baseline to current state
(clears completed_stages entirely, including exec)
(B) Abort--accept-external-state auto-picks (A). Unsafe.decision).
base_head ← current_head, `base_dirty ←current_dirty, last_verified_head ← current_head, last_verified_dirty ← current_dirty, clear completed_stages` entirely, continue.
delivery_blocked_byPer docs/protocol/session-file.md §Resume from non-null delivery_blocked_by. When the existing session has a non-null delivery_blocked_by: prompt continue-or-abort with the previous block reason; on continue, clear delivery_blocked_by ← null and then run the standard drift check.
Per docs/protocol/execution.md §Step 3 — Execution round loop. Round sequence: update context → spawn review_loop_executor (skipped on --review-only round 1) → update context → optional context-persist sub-step → reviewer dispatch → parse → Live Report → loop control → close completed Codex subagents per §Completed Agent Cleanup.
The Orchestrator picks the reviewer-prompt block that matches the active ## Session Metadata.plan_source, per docs/protocol/execution.md §Provenance-aware reviewer prompts:
plan_source: reviewer-approved → strict plan-conformance block.plan_source: user-supplied → plan-conformance deviations become[MINOR]/advisory unless they change user-visible behavior or violate acceptance criteria; correctness + intent still enforced. The orchestrator MUST emit the literal sentinel (plan_source: user-supplied — plan conformance is advisory/MINOR) verbatim inside the reviewer prompt so tests and audits can confirm this block was selected.
plan_source: review-only → pure CR mode. No plan-conformancelanguage. Reviewer is explicitly told the Approved Plan body is the canonical sentinel from docs/protocol/session-file.md §Canonical sentinel for review-only and ## Review Target carries the scope.
--review-only first-round skipPer docs/protocol/execution.md §--review-only first-round skip:
review content targets the existing diff + ## Review Target scope. The Orchestrator writes the round-1 Review History entry with the literal marker - Executor backend: skipped (review-only first round) so tests and audits can assert the skip unambiguously.
before Step 3.5, and mint exec only after Step 3.4 APPROVE/controlled SKIP, or after Step 3.4 REQUEST_CHANGES is repaired and a later normal Step 3 Reviewer returns APPROVE. This remains the only path where exec can be added without the Executor running before the first review-only gate.
(Executor runs, then Reviewer, alternating).
Spawn review_loop_executor with a fresh self-contained prompt that includes the approved plan, relevant session content, unresolved review issues, and the required execution schema from docs/protocol/executor-output.md §Execution round schema. Do not rely on inherited or forked parent thread context.
Concrete dispatch anchor: codex_execution_executor_dispatch. The Codex execution-phase Executor remains a judgment-tier local agent.
Validate the Executor output against the shared schema. If invalid, retry once with explicit correction instructions. If still invalid, stop and surface the failure. Then release the single-writer lock per docs/protocol/session-file.md §Lock file lifecycle before exiting.
Default Claude CLI path. Render the full reviewer prompt to .review-loop/tmp/{session_id}-reviewer-prompt.txt, then run:
claude -p --no-session-persistence --output-format stream-json --include-partial-messages --model {reviewer_model if set; else judgment_model if set; else claude-sonnet-4-6} < .review-loop/tmp/{session_id}-reviewer-prompt.txttype == "result" and use itsresult field as the reviewer output. Intermediate events are heartbeat signals; do not treat them as output. If no type == "result" line appears before exit, treat that as a command execution failure.
result field against the shared reviewer schema indocs/protocol/reviewer-output.md.
.review-loop/tmp/{session_id}-reviewer-prompt.txt immediatelyafter the command returns.
retry Claude for that round. Record a short failure reason summary in ## Review History (command execution / JSON parsing / missing result / reviewer schema validation). If codex_reviewer_backend: codex is not set, surface the Claude-path failure to the user instead of auto-falling back. Then release the single-writer lock per docs/protocol/session-file.md §Lock file lifecycle before exiting.
Optional local Codex reviewer path: spawn review_loop_reviewer only if codex_reviewer_backend: codex is set, or if the user has otherwise explicitly opted in. Use a fresh self-contained prompt with the same review content and the same reviewer schema rules. If invalid, retry once with explicit correction instructions. If still invalid, stop and surface the failure. Then release the single-writer lock per docs/protocol/session-file.md §Lock file lifecycle before exiting.
#### Parallel Reviewer Fan-Out (N>1)
When the orchestrator decides to dispatch N>1 independent reviewer rounds in the same wall-clock window (for example a polish-stage parallel sweep), shell out once to the conflict-aware parallel scheduler in scripts/review_verification.py instead of looping the single-shot path serially. N=1 dispatch keeps the single-shot invocation above byte-identical — argv, stdin handoff, model resolution, and temp-file lifecycle are unchanged.
Build <jobs.json> as a JSON list of objects with one entry per reviewer round, matching the schema accepted by _load_jobs in scripts/review_verification.py:
session_id (required) — current session uuidjob_id (required) — orchestrator-stable identifier unique within theround; used as the per-job prompt-file discriminator
runtime (optional, default "codex") — leave at "codex" for theCodex Stage 1 claude -p shell-out path
prompt_text (required for non-empty dispatch) — the full reviewerprompt body, identical to what would be rendered into .review-loop/tmp/{session_id}-reviewer-prompt.txt in the single-shot path
reviewer_model — resolved via the same shared model-tier rule used bythe single-shot path: reviewer_model if set; else judgment_model if set; else claude-sonnet-4-6 (per docs/protocol/planning.md §Shared model-tier contract)
timeout_secs (optional, default 300.0)conflict_keys, capacity_keys, extra_argv, worktree (optional;omit unless overriding scheduler defaults)
Inline prompt_text directly in the JSON object — do not write per-job prompt files yourself; the scheduler renders each job's prompt_text to .review-loop/tmp/{session_id}-reviewer-prompt.{job_id}.txt internally and hands the FD to the spawned claude -p via stdin redirection (per scripts/review_verification.py:457-459 Scheduler docstring and :648-651 _run_one). For runtime: "codex" jobs (the Codex Stage 1 fan-out path documented in this section), per-job stdout is captured by the scheduler via subprocess.PIPE and surfaced through each <results.json> entry's stdout field — there is no per-job output file. For runtime: "claude_code" jobs (the Claude-Code orchestrator's codex exec -o fan-out, not used here), per-job stdout is written to .review-loop/tmp/{session_id}-reviewer-output.{job_id}.txt.
Invoke the scheduler outside the sandbox:
python3 scripts/review_verification.py --jobs .review-loop/tmp/{session_id}-jobs.json --output .review-loop/tmp/{session_id}-results.json
<results.json> is a JSON list of objects, one per job, each carrying job_id, returncode, stdout, stderr, timed_out, parsed_verdict, parsed_issues, and error. For every entry:
error field is non-null, or timed_out is true, orreturncode is non-zero, classify as a command-execution failure for the round's failure-mode taxonomy and record error, the last 4 KB of stderr, timed_out, and returncode in ## Review History. Do not attempt to parse stdout for that entry — the per-entry diagnostic fields take precedence over stream-json parse outcome.
stdout field as the same stream-json byte streamthe single-shot path reads from claude -p. Find the line where type == "result" and use its result field as the reviewer output.
result against the shared reviewer schema indocs/protocol/reviewer-output.md. The orchestrator remains the single authority for verdict extraction and schema validation; the scheduler's own parsed_verdict / parsed_issues are best-effort metadata only per scripts/review_verification.py:12-17 and must not be substituted for orchestrator-side validation.
(command execution / JSON parsing / missing result / reviewer schema validation) when recording ## Review History.
After the round completes (success or failure), delete every per-job prompt file .review-loop/tmp/{session_id}-reviewer-prompt.{job_id}.txt, every runtime: "claude_code" per-job output file .review-loop/tmp/{session_id}-reviewer-output.{job_id}.txt (absent for the runtime: "codex" path used in this section), and the .review-loop/tmp/{session_id}-jobs.json / .review-loop/tmp/{session_id}-results.json artifacts, matching the single-shot prompt-cleanup discipline.
Per-job prompt files are scheduler-owned and may already be unlinked when the orchestrator's cleanup runs (the scheduler unlinks them in its own finally: per scripts/review_verification.py:646); treat ENOENT as success and do not surface it. The <jobs.json> / <results.json> artifacts are orchestrator-owned — a non-ENOENT failure to delete them should be logged as a warning in ## Review History but must not block the round verdict.
Code review content must include:
files
pre-round and post-round state for files touched in that round
scope
Review History context when presentplan_source (strict for reviewer-approved, advisory/MINOR for user-supplied, omitted entirely for review-only)repository path than the current workspace, return REQUEST_CHANGES with a [CRITICAL] workspace divergence issue
injections (for example HANDOFF pickup banners, LEARNINGS sync text, or other user-level additionalContext) that do not pertain to the provided session file and review task
APPROVE → exit the execution loop. If Step 3.4 has not yet run in thisexecution convergence, run Step 3.4 before Step 3.5 and do not mint exec yet. Step 3.4 is single-pass per execution convergence. Step 3.4 APPROVE or controlled SKIP mints exec into completed_stages for the current tree+index state, then proceeds to Step 3.5 unless --stop-after before-polish. Step 3.4 REQUEST_CHANGES withholds exec and feeds the gate findings to ordinary Step 3 Executor/Reviewer repair rounds; do not run Step 3.4 again while repairing those findings. A later normal Step 3 reviewer APPROVE after those repairs mints exec and proceeds to Step 3.5 unless --stop-after before-polish.
REQUEST_CHANGES → feed feedback to the next Executor round.soft_limit_exec is reached and blockingissues remain, surface the situation to the user instead of silently continuing or silently stopping. Respect the configured execution soft limit, but do not bypass review validation.
--stop-after exec-round → clean exit after the current roundfinishes (even on REQUEST_CHANGES). Perform step 5 of the drift tree (update last_verified_*, append to session_commits).
Per docs/protocol/execution.md §No-op execution round validation.
Use it for file-presence validation and to help derive the current-round delta, but unchanged path sets alone do not prove a no-op.
file set.
delta attributable to that round, using pre-round and post-round state. Same path sets alone are not enough.
execution schema: ### Changes Made states that no code changes were required, ### Files Modified / Created / Deleted is None, and ### Notes for Reviewer identifies the round as a no-op.
## Files Changed. Reject the result if the Executor claims changes that cannot be tied to a meaningful current-round delta.
Then release the single-writer lock per docs/protocol/session-file.md §Lock file lifecycle before exiting. Do not proceed with a partial or invented changed-set.
When an execution round reaches reviewer APPROVE, run Step 3.4 before Step 3.5 if the terminal gate has not yet run in this execution convergence. Step 3.4 is single-pass per execution convergence. Withhold exec until the gate returns APPROVE or controlled SKIP, or until gate-requested repairs later receive a normal Step 3 reviewer APPROVE. Then mint exec into completed_stages in ## Session Metadata per the shared session-file lifecycle. This applies to both edit rounds and reviewed no-op rounds. If Step 3.4 returns REQUEST_CHANGES, do not mint exec; feed the gate findings to ordinary Step 3 Executor/Reviewer repair rounds, and do not run Step 3.4 again while repairing those findings. Do not represent execution completion with custom metadata keys such as completed_at; the shared protocol completion state is carried by completed_stages and related baseline metadata.
Per docs/protocol/execution.md §Step 3.4 — Terminal Adversarial Gate. Single-entry-point Python invoker; single-pass per execution convergence between Step 3 APPROVE and Step 3.5 polish entry. Gate APPROVE/SKIP mints exec; gate REQUEST_CHANGES returns to ordinary Step 3 repair rounds without minting exec, and the gate does not run again while repairing those findings.
# Terminal Adversarial Gate — single-entry-point Python invoker.
python3 scripts/adversarial_gate_invoke.py --focus-file "$focus_text_file"
adversarial_exit=$?
# 0 → APPROVE; 1 → REQUEST_CHANGES; SKIP reasons land on stderr.SKIP banner format: adversarial-gate: SKIP reason=<reason>[ detail=<...>]. Verdict table: adapter exit 0 → APPROVE; exit 1 → REQUEST_CHANGES; exit 2 → REQUEST_CHANGES because produced-but-malformed adversarial output is blocking, not SKIP. APPROVE mints exec; REQUEST_CHANGES does not mint exec and feeds findings to ordinary Step 3 repair rounds without another Step 3.4 pass in that repair path.
Fallback cleanup failure is a blocking REQUEST_CHANGES, not SKIP: if .review-loop/config.md cannot be proven restored/deleted after fallback execution, or an unexpected existing or create-from-empty config change must be preserved for inspection, do not mint exec; feed the synthetic [CRITICAL] cleanup issue to ordinary Step 3 repair rounds without another Step 3.4 pass in that repair path.
Run the adversarial gate invocation outside the sandbox. The Python invoker writes tempfiles (tempfile.mkstemp for config snapshot, tempfile.NamedTemporaryFile for the rendered fallback prompt), which the Codex read-only sandbox blocks. Mirrors the existing reviewer-call and scheduler-call sandbox boundary.
The invoker shells out via Bash, not spawn_agent — completed-agent cleanup does not apply.
The adversarial_gate_skip_paths config key (default ["**/SKILL.md", "docs/protocol/**", "tests/skills/contracts/**"]) lets the orchestrator skip the gate entirely when every Step 3 changed file matches one of the patterns.
Per docs/protocol/execution.md §Step 3.5. Runs language-specific static analysis, code-quality review-fix loop, simplify, test consolidation. quality_focus applies only when Step 3.5 Quality Polish actually runs. If skip_quality_polish: true is set in config, the orchestrator skips the Step 3.5 substeps; in that case skip_quality_polish: true mints polish as a no-op completion and still continues through docs and security.
completed_stages and theOrchestrator replays from exec per docs/protocol/session-file.md §completed_stages lifecycle. Each replay iteration that writes files clears the set and restarts from exec. Termination is guaranteed by the per-stage caps.
reviewer-only fast-replay exception: eligible Step 3.5.4prose/comment/metadata-only writes that do not touch lint-pinned needles or change the bash scripts/run-skill-lint baseline may preserve the current completed_stages per docs/protocol/session-file.md §completed_stages lifecycle.
APPROVE does not mint polish.Step 3.5.6 mints polish only after the full Step 3.5 invocation finishes cleanly with either no writes, or only eligible writes already approved by reviewer-only fast-replay.
0`, discard and retry once; if retry is also 0, skip and report.
--stop-after before-polish → exit after Step 3.4 APPROVE/SKIP andbefore Step 3.5 starts. --stop-after before-docs → exit after Step 3.5 and before Step 3.6.
Per docs/protocol/execution.md §Step 3.6. Single pass. Update project docs + fix stale code comments. Writes → clear completed_stages, replay from exec, except for the narrow reviewer-only fast-replay exception above when the write is eligible prose/comment/metadata-only work that does not touch lint-pinned needles or change the bash scripts/run-skill-lint baseline. No-write or approved reviewer-only fast-replay → mint docs. After minting docs, proceed to Step 3.7 — a no-op docs stage is not a terminal state.
tool_uses: 0, discard and retry once; if retry is also 0, skip and report.--stop-after before-security → exit after Step 3.6 and before Step 3.7.
Per docs/protocol/execution.md §Step 3.7. Single scan. Check for tracked/staged sensitive files; audit .gitignore for missing coverage. Writes to .gitignore or git rm --cached → clear completed_stages, replay from exec. No-write → mint security.
Step 3.7 runs unconditionally after Step 3.6, regardless of whether any prior stage wrote files. A no-op session (zero code changes, zero doc updates) still runs this scan — it is a security gate, not a content-dependent step. The only exits before 3.7 are --stop-after before-security / before-docs / before-polish / exec-round.
tool_uses: 0, discard and retry once; if retry is also 0, skip and report.--stop-after before-delivery → exit after Step 3.7 and before Step 4.
Per docs/protocol/execution.md §Step 4 — Delivery, gated by the delivery gate: Codex Stage 1: {exec, polish, docs, security} ⊆ completed_stages.
On gate failure, hard-stop per §Delivery gate: set delivery_blocked_by ← <first missing stage>, release the single-writer lock per docs/protocol/session-file.md §Lock file lifecycle, and exit without delivering. The stuck summary is printed from docs/protocol/execution.md §Per-stage max-round caps.
On gate pass:
auto_commit: true: stage only the files the Executor reported(never git add -A/git add .), commit with {commit_message_prefix}: {title}, append sha to session_commits.
docs/protocol/execution.md §Step 4 — Delivery — this skill reuses the same format). Render the Delivery Summary in 中文 (Simplified Chinese) per docs/protocol/execution.md §Step 4: section headings, prose, and prose-style field values use 中文; ASCII tokens stay in original form.
docs_file if set.delivery_blocked_by ← null. Release the lock.--stop-after replay / invalidation interaction--stop-after exit at any stage clears delivery_blocked_byper docs/protocol/session-file.md §delivery_blocked_by lifecycle, even if the session was previously blocked (the user already acknowledged on resume).
docs/protocol/session-file.md §completed_stages lifecycle) apply during replay. Each writing substep clears the set; replay restarts from exec. Per-stage caps bound iteration.
delivery_blocked_by lifecyclePer docs/protocol/session-file.md §delivery_blocked_by lifecycle.
<stage>) or signal abort("user-abort").
--stop-after exit, user'sresume-continue choice.
last_verified_* anddelivery_blocked_by unchanged so the user can audit.
For full guard rules see .agents/skills/review-loop/SKILL.md §Codex Hallucination Guard. Briefly: reject Executor output that lacks the required schema sections, claims file changes without concrete paths, claims implementation changes not reflected in the current-round delta attributable to that round, or implies work performed in a different git worktree or repository checkout than the orchestrator-owned current workspace. Reject reviewer output missing ### VERDICT / ### Strengths, using any severity outside [CRITICAL] / [MINOR], or contains semantic inconsistencies (APPROVE with [CRITICAL], REQUEST_CHANGES with only [MINOR]). Reject reviewer output that fails to flag workspace divergence when implementation appears to exist only in a different git worktree or repository path than the current workspace.
The post-Executor set is the source of truth. The pre-Executor set is useful for file-presence validation and current-round delta derivation, but unchanged path sets alone do not prove a no-op. Treat a run as no-op only when the Executor explicitly reports it and there is no meaningful delta attributable to the current round.
The Orchestrator keeps minimal state between rounds (session path, latest Reviewer feedback, round number, current stage). All durable state is on disk. See docs/protocol/planning.md §Context management discipline (applies equally to execution).
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.