plan-6c4c34 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited plan-6c4c34 (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
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 a work item through the Plan loop (Executor drafts → Reviewer critiques → iterate) until the Reviewer returns APPROVE, then stop. This skill does not enter the execution phase; it hands off to review-loop:execute --session <uuid> (or to a different runtime's execute skill) via the shared session file.
exec -> polish -> docs -> security -> delivery lifecycle..review-loop/config.md,shared .review-loop/sessions/*.md, Claude CLI default reviewer, optional local Codex reviewer, shared reviewer schema, Stage 1 hallucination guards.
Preflight, Delivery — those live in .agents/skills/execute/SKILL.md.
The Orchestrator MUST Read each of these files at start. They are the single source of truth for this skill's planning loop and output schemas.
docs/protocol/session-file.mddocs/protocol/planning.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 planning session.
spawn_agent call, call close_agent on any completed Codex subagent id from earlier planning 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.
completed Executor and local Reviewer subagents for that round before spawning the next agent.
completed-agent cleanup does not apply to it. Continue deleting its temporary prompt file immediately after the command returns.
update naming the cleanup count.
run plan on: <work item description> [--handsfree]--handsfree forwards decision-type Executor questions to the Reviewer instead of pausing for the user. External-info questions still pause regardless of mode. See docs/protocol/planning.md §Question classification.
Before loading config or checking backend availability, Read the 4 Protocol Imports docs listed above.
.review-loop/config.md if present; otherwise fall back toStage 1 defaults documented in .agents/skills/review-loop/SKILL.md §Config Loading.
--handsfree in the invocation message. If present (orhandsfree: true in config), enable handsfree for this session.
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.
docs/protocol/session-file.md §Lock file lifecycle. The lock must exist before the session file is created; all subsequent reads and writes of the session file (creation, metadata write, planning round updates, and Step 1.5 suggest-and-exit cleanup) happen under this lock.
.review-loop/sessions/{uuid}.md with thecanonical section list per docs/protocol/session-file.md §Canonical sections, using the plan entry-mode column of §Entry-mode initialization table.
## Approved Plan body is empty; no Source sub-field is writtenduring planning draft rounds.
## Draft Plan is present; it will be overwritten by each planninground's Executor output.
## Current Phase: planning.## Session Metadata block.entry_point: plan. plan_source is omitted during planning draft rounds — it is written on APPROVE only.
Extract from the user's message: title, problem description, context, acceptance criteria. If critical information is missing, ask ONE clarifying question before proceeding.
plan does not auto-route into execution. If the work item looks like it should skip the planning loop, print a suggestion and exit instead of dispatching — the user is the one who chose the plan entry point, and the hand-off is their call.
Check:
at an already-written plan doc, or the conversation shows an approved plan): suggest
Detected: existing plan in the conversation/context.
Next: review-loop:execute --plan "<text|path>" --title "<title>"
(or review-loop:execute --session <uuid> if you already have a session)git status shows substantial,task-relevant changes): suggest
Detected: implementation appears to already be in the working tree.
Next: review-loop:execute --review-only --description "<what was done>"Print the suggestion and exit. Do not dispatch Executor / Reviewer. Before exiting on either suggest-and-exit branch, release the single-writer lock acquired in Step 0.5 per docs/protocol/session-file.md §Lock file lifecycle.
This step is strictly optional. Skip it entirely and silently if no external memory tool is available. Never ask the user to install anything. Never mention the tool name to users who don't have it. The fail-silently contract applies to the entire lifecycle — probe failure, runtime failure, malformed output — per CLAUDE.md §"Optional integrations must fail silently".
mempalace_search MCP tool is listed,OR run which mempalace. If neither, skip.
## Historical Context section, skip.
deadline rather than awaiting it. Any error / hang / timeout / non-zero exit / stderr / malformed output → silently skip.
## Historical Context section. Otherwise skip — no empty section.
Run the planning loop per docs/protocol/planning.md §Round loop. For this skill specifically:
review_loop_executor with afresh self-contained prompt → write the round's draft into ## Draft Plan → optional context-persist sub-step → reviewer dispatch → parse → Live Report → close completed agents per §Completed Agent Cleanup above.
APPROVE → promote ## Draft Plan into## Approved Plan with - Source: reviewer-approved, write plan_source: reviewer-approved to ## Session Metadata, remove ## Draft Plan entirely from the session file, and exit the planning loop. Do NOT continue into execution — that is the execute skill's job.
REQUEST_CHANGES → feed feedback into the next Executor round.soft_limit_plan is reached and blocking issues remain, surfacethe situation to the user instead of silently continuing or silently stopping. Respect the configured plan soft limit, but do not bypass review validation.
Spawn review_loop_executor with a fresh self-contained prompt that includes the work item, the relevant session content, the planning schema from docs/protocol/executor-output.md §Planning round schema, and any prior reviewer feedback. Do not rely on inherited or forked parent thread context.
Dispatch anchor: plan_executor_dispatch_skill. The planning-phase Executor remains a judgment-tier dispatch; missing tier defaults to judgment.
Validate the Executor output against the shared schema before persisting to ## Draft Plan. If invalid, retry once with explicit correction instructions. If still invalid, stop and surface the failure to the user. 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.txtline where type == "result" and use its result field as the reviewer output. Intermediate events (thinking deltas, assistant blocks, rate limit 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.
Plan review content must include:
Review History context when presentassumptions
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
After the Reviewer returns APPROVE:
## Approved Plan populated with- Source: reviewer-approved and ## Session Metadata.plan_source: reviewer-approved. ## Draft Plan has been removed.
docs/protocol/session-file.md §Lock filelifecycle.
── review-loop:plan — approved ──────────────────
Session: {uuid}
Session file: .review-loop/sessions/{uuid}.md
Plan rounds: {N}
Status: Approved (plan_source: reviewer-approved)
Next: review-loop:execute --session {uuid}
────────────────────────────────────────────────The plan skill does not deliver code and does not enter any execution stage. completed_stages is not minted here — that is strictly the execute skill's responsibility. No auto-dispatch.
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, or implies work performed in a different git worktree or repository checkout than the orchestrator-owned current workspace. Reject reviewer output that is missing ### VERDICT / ### Strengths, uses any severity outside [CRITICAL] / [MINOR], or contains semantic inconsistencies (APPROVE with [CRITICAL], REQUEST_CHANGES with only [MINOR]).
The Orchestrator keeps minimal state between rounds (session path, latest Reviewer feedback, round number). All durable state lives on disk in the session file. See docs/protocol/planning.md §Context management discipline.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.