Your agent writes the code. A different model tries to break it.
Only what survives ships, and only when you say go. πΎ
secondmate is a Claude Code plugin that makes your AI coding agent check its own work with a second opinion.
When an agent writes code, the same agent usually reviews it, so it misses its own mistakes. secondmate splits the job in two: one agent writes the change (the maker), a different AI model reviews it (the checker), and nothing gets merged until the checker passes it, the change clears an automated safety gate, and you give the final OK.
Because the checker is a different model than the maker, it catches bugs the maker is blind to. secondmate also keeps long runs from going off the rails, remembers your decisions across restarts, and can hand hard analysis to a reasoning model on the side. Works with any coding-agent CLI.
claude plugin marketplace add eshwarvijay/secondmate
claude plugin install secondmate@secondmate
# restart Claude Code, then let it set itself up β you just approve each step:
/secondmate-doctorThen run any change through the loop:
/loop-task add a rate limiter to the API and prove it workssecondmate spawns the maker in an isolated worktree, runs a different model as an edit-locked checker,
gates on its {verdict} plus a clean verify-gate, and asks you before anything merges. Need a quick
read-only analysis? /secondmate-reason why does this test flake only in CI?
flowchart LR
A[loop-task: goal] --> P[plan-committee<br/>6 models in parallel]
P --> S[supervisor: Sonnet<br/>synthesizes plan]
S --> M[maker<br/>Claude or pi+Qwen --thinking medium]
M --> C[checker<br/>gpt-terra, read-only]
C --> V{verdict}
V -- fail --> S2[supervisor<br/>synthesizes fix plan]
S2 --> M
V -- pass --> G{verify-gate}
G -- refuse --> M
G -- pass --> H{{your approval}}
H -- merge --> D[ship]
The planning committee runs unconditionally for every task. For complex tasks it runs 6 open-weight models (DeepSeek-R1, Qwen3-Next-80B, Qwen3-Coder-Next, Kimi K3 (bedrock cross-region inference profile: global.moonshotai.kimi-k3), Mistral-Large-3, GLM-5) in parallel, each covering a different dimension. Sonnet synthesizes all outputs into one consolidated plan, then routes to the right maker: Claude for tasks needing judgment or MCP tools, pi + Qwen3-Coder (
--thinking medium) for well-specified pure-code tasks.On a checker
fail, the supervisor synthesizes a fix plan and hands it back to the same maker (task-scoped agent name, same worktree) β never fixes inline. The supervisor never writes project code.
Deeper dive: docs/ARCHITECTURE.md β roles, the guarantee behind every stage, and the full component map.
π‘ Best with herdr. Inside herdr the full loop runs natively:
herdr worktree createspawns the maker worktree + workspace in one call; the pi maker runs as a lifecycle-trackedherdr agent(blocked recovery, stall detection); the checker runs viaherdr pane run+pane wait-outputβ no timeout caps, no silent failures. Anywhere else secondmate falls back to headless sub-agents with the same guards.
| Component | What it does |
|---|---|
secondmate skill |
The full SOP: plan-committee β triage β spawn β check β gate β hold β integrate |
bin/plan-committee.sh |
6 open-weight pi planners in parallel, one dimension each β outputs for Sonnet to synthesize; JSON-aware output validation rejects tool-call-shaped garbage, retries once with a changed prompt, marks self-healed planners, preserves failed raw output, and refuses to overwrite a different task's planning directory |
bin/committee-output.py |
Extracts final planner prose from pi's JSON event stream and classifies empty, tool-call-shaped, or structurally invalid responses |
| SessionStart hook | Surfaces durable open decisions each session so a restart never drops a pending gate |
bin/scope-guard.py (PreToolUse hook) |
Confines a marked maker session to its own worktree β denies Bash/Read/Edit/Write/NotebookEdit outside it, credential-store commands (Keychain, gh auth, incl. wrapped in sh -c/eval), and common Bash evasions (shell-var indirection, inline python3 -c/node -e, any pipeline ending in a shell interpreter); recognizes literal patterns only β see the limitation callout below for what it permanently does not catch; no-op for the supervisor's primary checkout |
bin/scope-guard-extension.ts |
pi extension equivalent of scope-guard.py β denies the same tool calls and patterns for pi maker sessions; uses pi's tool_call event instead of Claude's PreToolUse hook; activated by same mark-maker.sh convention; same heuristic limitations Apply |
bin/mark-maker.sh |
The one shared call every maker-launch site uses to drop the scope-guard marker outside the worktree, keyed by the worktree's realpath; refuses to mark anything but an isolated linked worktree (never the primary checkout) |
bin/hold.py |
Durable human-gate decisions (hold / answer / open / next); hold/answer support an optional --sha that binds a decision to the exact commit it applies to, and next hands back exactly one oldest-open decision at a time; a successful answer prints an advisory reminder that the decision should represent a genuine human call, not a self-answered hold |
bin/claim-ledger.py |
Atomic task-id claims for concurrently-running sub-agent-supervisors, each in its own worktree β claim/release --token/steal --reason/status, append-only JSONL guarded by the same fcntl-based ledger lock as hold.py; defaults to the shared git rev-parse --git-common-dir location so every worktree of a repo agrees on one ledger (not a CWD-relative path); release requires a real secrets.token_hex proof minted by claim/steal, not just a repeatable --owner label; steal is a mandatory-reason human override that re-folds the ledger fresh inside the lock (no TOCTOU) |
bin/verify-gate.sh |
Pre-integration gate: clean tree, non-empty diff, exact-SHA match, tests |
bin/merge-sequencer.sh |
Serializes concurrent merges to main from multiple independent sub-agent-supervisors finishing around the same time: validates --worktree is an ACTUAL linked worktree of --repo (matching git-common-dir, resolved via pwd -P) before doing anything else, refusing an independent/stale clone that could otherwise pass verify-gate.sh's freshness check against its own stale local refs while the real merge lands somewhere else entirely β mkdir-based singleton lock anchored to --repo by default (<repo>/.secondmate/merge-sequencer.lock, bounded wait, no auto-steal) β not to the calling process's own ambient CWD, since a sub-agent-supervisor's natural CWD is its own worktree, not --repo β β re-invokes bin/verify-gate.sh fresh, inside the lock immediately before merging (the actual freshness guarantee β the lock is ordering/UX, not correctness) β checks --branch itself resolves to exactly --checked-sha (verify-gate.sh only vouches for --worktree's HEAD, not for whatever string --branch happens to be β refuses BRANCH_MISMATCH otherwise) β checks $repo isn't already mid an unrelated in-progress merge or dirty for a reason this invocation didn't cause (refuses before ever touching it, never calls merge --abort on a conflict it didn't start; the dirty-check excludes the EXACT paths of both self-created artifacts (its own lock directory AND ledger file), never a basename match, so neither self-created artifact ever trips its own guard, and a genuinely unrelated same-named path elsewhere in the repo still correctly refuses) β git merge --no-ff in the primary checkout β git push origin <base> still inside the same lock. On a genuine push race (origin advanced between merge and push β requiring BOTH a race-shaped keyword AND git's own bare [rejected] structural summary line, never a keyword alone, since arbitrary local text β a hook, a transport helper, a proxy β has no reason to replicate that exact git-generated line; and never a hook/protected-branch rejection even if its own message happens to contain a race-shaped word): the singleton lock stays held through the ENTIRE recovery sequence (never released mid-recovery β an earlier revision released it per-attempt, letting a second concurrent invocation mutate the same primary checkout while the first was still recovering), fetches, git merge --no-ff origin/<base> (a distinctive merge-sequencer: race recovery (attempt N/3) commit so recovery is auditable via git log alone), retries the push β bounded at 3 total attempts (the initial push + 2 retries, never a 4th) before giving up (PUSH_RACE_RECOVERED on success, PUSH_RACE_EXHAUSTED on exhaustion/recovery-merge-conflict/an unrelated failure such as a hook rejection or auth/network error hit mid-recovery β the retry loop only continues when a failure is still affirmatively race-shaped, never by default). A concurrent server-side ref-transaction race ("cannot lock ref ... incorrect old value provided") is recovered the same way β distinguished from a real hook/policy rejection by matching git's own client-generated (incorrect old value provided) summary reason on a line that isn't itself a relayed remote: line, since a hook's own message (however it's worded, even an attempt to literally spoof that exact text) can never appear anywhere except on a remote: -prefixed line. Accepted limitation: a LOCAL pre-push hook (client-side, no remote: framing at all) can defeat this text-based classification entirely β if $repo has (or at any point during the invocation acquires) one, race auto-recovery is disabled for that repo and every push failure is reported PUSH_FAILED instead; checked before the first push AND monotonically re-checked (never reset once true) before every retry, so a hook can't evade detection either by deleting itself afterward or by only appearing mid-recovery. The one thing that stays un-closed: the exact instant between any single sample and the push it's immediately followed by. A separate, broader accepted limitation: every classifier here trusts that git in PATH is the genuine, unmodified system binary β a PATH/transport-helper substitute could fabricate any of these structural markers, the same class of threat bin/caffeinate-guard.sh already declines to defend against. --preflight-only runs git merge-tree --write-tree against a freshly-fetched origin/<base> to detect a conflict before ever acquiring the lock or touching $repo's working tree/index/branch-refs/ledger (--branch must still resolve to exactly --checked-sha, same as the real merge path) β exit 6 conflict / 7 unsupported-or-precondition-failed / 8 clean; fetch's and merge-tree --write-tree's own ordinary git-internal footprint (.git/FETCH_HEAD, downloaded objects, an unreachable dangling merge-result tree) is outside that guarantee, not a bug. Every outcome is appended to <repo>/audit/merge-ledger.jsonl (GATE_REFUSE/BRANCH_MISMATCH/MERGE_CONFLICT/MERGE_REJECTED/PUSH_FAILED/PUSH_RACE_RECOVERED/PUSH_RACE_EXHAUSTED/LOCK_TIMEOUT/SUCCESS β a ledger-write failure never fails an otherwise-successful merge, it prints a loud stderr WARNING naming the ledger path instead of silently vanishing). Right before a real merge (never on --preflight-only), prints an advisory reminder to confirm .claude-plugin/plugin.json's version and README/ARCHITECTURE docs are synced |
bin/launch-checker.sh |
Edit-locked (--exclude-tools edit,write) cross-model checker + verdict-envelope contract; streams pi's --mode json output through checker-progress.py for live progress visibility |
bin/verdict.py |
Parse the checker's {verdict} β exit 0 pass / 1 fail / 2 errorΒ·refusedΒ·ambiguous; with --lenses <list> cross-checks lens coverage; enforces findings validation for fail verdicts (must have file:line or [NOLOC]) |
bin/dispatch-report.py |
Parses a sub-supervisor's final output for the fan-out pattern below β exactly one of SM_DONE_MERGED:<sha> / SM_STUCK_NEED_HUMAN:<reason> / SM_REFUSED:<reason>, anchored at start-of-line so a tag echoed mid-prose (e.g. from the sub-supervisor's own instructions) can't be mistaken for the real signal; last matching line wins β exit 0 done / 1 refused / 2 stuck / 3 no tag found (its own, more-cautious-than-stuck code) |
bin/checker-progress.py |
Filter pi's --mode json output: prints one progress line per tool execution to stderr (live activity), extracts final assistant message text from agent_end and writes to stdout (exactly as --mode text would); handles malformed JSON lines gracefully; preserves exit code propagation via pipefail |
bin/loop-guard.sh |
Stuck-loop abort (exit 3) + per-run round/spawn caps + machine-parseable restart signal (exit 5) via action --key; round-state.md handoff file; reset clears only loop state (action.key, action.count, rounds, spawns), not task state |
bin/run-round.sh |
Wall-clock timeout + idle watchdog + paired audit record (even on kill) |
bin/prune-output.sh |
Model-free head/tail truncation of bulky logs |
bin/new-worktree.sh |
Isolated git worktree per maker (never the primary checkout) |
bin/sync-worktree-skills.sh |
Backfills gitignored project-local skill directories into a freshly created worktree, for every convention a maker harness actually reads: .claude/skills/ (Claude Code), .pi/skills/ (pi, project-local), and .agents/skills/ (the neutral "Agent Skills" standard both harnesses read directly β the fix for a real gap where pi's own skill loader never reads .claude/skills/ at all) β git worktree add only ever populates tracked content, so a gitignored skill is otherwise genuinely absent, causing "Unknown skill" errors (Claude Code) or silent non-discovery (pi) for any maker/supervisor operating there; resolves a skill that's itself a symlink to its real target anywhere in the checkout and materializes real content (never a symlink) in the worktree, refuses anything resolving outside the primary checkout, and never touches an already-present target (even a dangling symlink) β one-time copy at worktree-creation time, wired into both bin/new-worktree.sh and the herdr-based Spawn step. Does not and cannot bypass pi's own trust-gating for newly-synced .agents/skills//.pi/skills/ content β see bin/doctor.sh's skill discovery check for the companion diagnostic |
bin/reason.sh |
Read-only, tool-free reasoning one-shot on a reasoning model |
bin/lesson-lookup.py |
Retrieves known failure patterns from the lesson store as a retrievable checklist β reads bin/lessons/**/*.md with YAML-shaped frontmatter, scores non-E4 lessons by term overlap, buckets a never-yet-helpful lesson below ones with recorded helpful_count > 0 (deprioritized, never excluded), always includes E4 (proven-core) lessons, outputs the exact header ## Known failure patterns β DO NOT SKIP with selected lessons as bullets (each with a (helpful X/Y) success-rate suffix once it has any recorded feedback); falls back to original 4 seed lessons if the store is unavailable. Optional --task-id <id> (fail-open, never blocks injection) logs the selected lesson ids to a git rev-parse --git-common-dir-anchored injection ledger. tag --lesson-id <id> --outcome helpful|harmful records supervisor-observed feedback, atomically incrementing that lesson file's own helpful_count/harmful_count frontmatter via a surgical text edit that preserves every other line byte-for-byte |
bin/teardown-check.sh |
Advisory scan for per-task state a supervisor believes is already torn down β reports whether a git worktree, the sm/<id> branch, a herdr pane/agent, or a claim-ledger.py entry for a task-id is still present (exit 0 clean, nonzero if anything's still around); degrades a headless run's unreachable herdr check to its own "unknown" condition rather than a false "clean", without blocking a genuinely clean headless teardown. Accepted limitation: the herdr check covers maker agents only (sm-<task-id>/sm-pi-<task-id>) β a leaked visible checker pane has no task-id-derived identity anywhere in this repo's current herdr integration, so it's invisible to this check |
bin/lessons/ |
Directory of failure pattern lessons in Markdown with frontmatter (tags, evidence: E4, earned-in: seed); seeds include commit-before-done, mutation-test-your-tests, stay-in-literal-scope, avoid-ad-hoc-debug-loops |
bin/lessons/debugging/ |
Subdirectory for debugging-related lessons |
bin/lessons/testing/ |
Subdirectory for testing-related lessons |
bin/lessons/workflow/ |
Subdirectory for workflow-related lessons |
bin/log-round.sh |
Appends one structured JSONL record per checker round to audit/metrics.jsonl (task, round, maker, verdict, finding-category tags, repeatable --lesson-id for lessons injected that round, optional cost/duration) β queryable alongside the per-task audit entries below |
bin/audit-log.py |
Lookup-only audit trail so the flow/decision history never auto-loads unboundedly: add writes one task's entry verbatim to its own file under audit/flow//audit/decision/, then regenerates a size-capped audit/INDEX.md (last N entries per type β the only thing @-imported into CLAUDE.md); list/search/show retrieve full history on demand, never in bulk; migrate one-time-splits an existing monolithic file into per-task files, verbatim and idempotently; sanitizes task-id-derived filenames against path traversal (same precedent as bin/claim-ledger.py) |
bin/caffeinate-guard.sh |
Prevents macOS sleep during session execution via start/stop commands; session-scoped single guard process with PID verification and bounded -t TTL ceiling; idempotent (safe to call multiple times); accepted limitation: host-wide singleton = multiple concurrent sessions on same machine not supported |
bin/herdr-pane.sh |
When in herdr: spawn starts any maker (Claude or pi) as a lifecycle-tracked agent and returns <name> <pane_id> for cleanup, marking its worktree for scope-guard.py; checker runs via herdr pane run + pane wait-output with a per-round unique marker |
bin/doctor.sh |
Pre-flight + self-heal: detects missing requirements (herdr, ponytail, adhd) and installs them on demand; detects AWS Bedrock model-metadata overrides (kimi-k3, deepseek-r1 maxTokens values) for pi's local models.json and fixes them; detects skill discovery asymmetry between pi and Claude Code, scanned at ANY depth (monorepo-safe, matching bin/sync-worktree-skills.sh's own scan of the identical three conventions) β a project skill present only under .claude/skills/ is invisible to pi, and vice versa for .pi/skills/; .agents/skills/ is the portable intersection both read; two subprojects with the same skill name get distinct, unambiguous rows qualified by their relative path β and, for the pi-invisible case, offers a safe one-directory copy into .agents/skills/<name> at that same subproject location (never overwrites, never follows a symlink resolving outside the repo); detects secondmate plugin staleness (SHA behind marketplace checkout), heals with git pull --ff-only + claude plugin update, and warns about the /reload-plugins requirement. Safe aborts on dirty tree, detached HEAD, or non-fast-forward; uses mkdir-based lock to prevent concurrent heals. |
Commands: /secondmate-doctor Β· /secondmate-reason Β· /secondmate-verify Β· /loop-task
β οΈ Scope guard for pi makers requires an explicit --extension flag at launch time β there is no auto-discovery.Both implementations share the same permanent limitations: they recognize literal patterns only, not a shell parser, not data-flow analysis, not an OS sandbox. They will not be extended further to chase new bypasses β every round of "found one, patched it" converges on the same wall. They do not reliably catch: (a) alternate redirection syntax with no space before the operator (e.g.
cat</etc/passwd,>/etc/foo); (b) indirect/deferred execution where the program invoked arrives as data at runtime rather than a literal token (e.g.find . -exec cat /etc/passwd \;,... | xargs -0 sh -c 'cat "$0"'); (c) interpreter code that shells out via a library call instead of visible path text (e.g.python3 -c "import os; os.system('cat /etc/passwd')", Node'schild_process, Ruby/Perl backticks). These are representative examples of permanent gaps, not a todo list β closing them for real needs OS-level sandboxing (chroot/seccomp/containers), which is explicitly out of scope here.
The checker isn't one generic reviewer. Per task, secondmate loads only the specialized disciplines the
diff actually needs β a router β sub-skill design (progressive disclosure), so the checker gets focused
context instead of a generic dump. Lenses live in bin/lenses/<role>/; the supervisor reads each role's
ROUTER.md, matches the diff, and injects just the matching sub-lenses
(--lens redteam/injection --lens qa/coverage).
| Role | Sub-lenses |
|---|---|
| redteam (security) | injection Β· access-control Β· server-side-requests Β· deserialization Β· secrets-supply-chain Β· llm |
| qa (tests / behavior) | test-reality Β· coverage Β· risk-flagging Β· behavioral-contracts |
| reverse-engineer (unfamiliar / third-party code) | dataflow Β· hidden-behavior Β· intent-vs-impl Β· unknown-code |
| research (groundedness) | groundedness Β· prior-art Β· assumption-audit |
Add your own: drop bin/lenses/<role>/<name>.md (a lean, specialized discipline) and list it in that role's ROUTER.md.
git, gh, python3, and (recommended) a checker harness CLI (defaults to pi).
Just run /secondmate-doctor: it detects and installs everything, asking only for your approval, and never
hands you a manual checklist.
No harness? You still get a cross-model check. secondmate falls back to a second Claude model as the checker, in-session, so the maker is still not the checker. An external harness like pi gives a stronger cross-vendor check (a different vendor, not just a different Claude model). Either way, the models need credentials only you can supply.
Companions β installed by /secondmate-doctor
| Companion | What it adds | Install |
|---|---|---|
| pi | default checker + reasoning harness (multi-model) | npm install -g @earendil-works/pi-coding-agent |
| herdr | visible multi-pane maker/checker orchestration | brew install herdr |
| ponytail | complexity / over-engineering lens | claude plugin install ponytail@ponytail |
| loop-task | maker/checker loop driver command | bundled β ships with secondmate |
| adhd | divergent ideation for open-ended triage | claude plugin marketplace add UditAkhourii/adhd && claude plugin install adhd@adhd |
Configuration β env vars, all optional (sane defaults)
| Var | Default | Purpose |
|---|---|---|
SM_CHECKER_HARNESS |
pi |
checker CLI |
SM_CHECKER_PROVIDER |
amazon-bedrock |
checker provider |
SM_CHECKER_MODEL |
global.openai.gpt-5.6-terra |
checker model (a different family than the maker) |
SM_CHECKER_THINKING |
high |
checker reasoning effort |
SM_CHECKER_PROMPT |
bin/checker-prompt.md |
base checker discipline (point at your own to override) |
SM_REASON_HARNESS |
pi |
reasoning CLI |
SM_REASON_PROVIDER |
amazon-bedrock |
reasoning provider |
SM_REASON_MODEL |
r1 |
default reasoning model alias (r1 / gpt / sonnet / full id) |
SM_COMMITTEE_PROVIDER |
amazon-bedrock |
planner provider for plan-committee.sh |
SM_COMMITTEE_TIMEOUT |
300 |
per-planner wall-clock timeout in seconds |
SM_HOLD_LEDGER |
./decisions.jsonl |
per-repo decision ledger |
SM_CLAIM_LEDGER |
shared git rev-parse --git-common-dir-anchored .secondmate/claims.jsonl -- the common-dir's parent when its own basename is .git (a normal repo/worktree), else the common-dir itself (a bare repo or a submodule) (or $SM_LOOP_STATE/claims.jsonl if set, else a CWD-relative fallback with a loud warning outside any git repo) |
task-id claim ledger for bin/claim-ledger.py, shared across every worktree of the same repo |
SM_LOOP_STATE |
./.secondmate |
loop-guard state dir. bin/merge-sequencer.sh uses this same var as an override, but its own default lock lives at <repo>/.secondmate/merge-sequencer.lock (anchored to --repo, not to ./) so every caller targeting the same --repo shares the same lock regardless of its own ambient CWD β distinct from bin/caffeinate-guard.sh's own lock under SM_CAFFEINATE_ROOT |
SM_WT_ROOT |
~/.secondmate-worktrees |
where maker worktrees are created |
SM_MARKER_ROOT |
~/.secondmate-markers |
where mark-maker.sh drops the scope-guard activation marker (must stay outside every worktree) |
SM_CAFFEINATE_ROOT |
~/.secondmate-caffeinate |
where caffeinate-guard.sh stores the session-scoped guard PID file (PID + fingerprint) |
SM_MAKER_ALLOW_CREDS |
unset | set to 1 inside a maker session to opt in to credential-store commands (Keychain security, gh auth) that scope-guard.py otherwise denies |
SM_METRICS_LEDGER |
./audit/metrics.jsonl |
append-only per-round metrics ledger written by bin/log-round.sh |
SM_AUDIT_DIR |
./audit |
root directory for bin/audit-log.py's per-task entries (audit/flow/, audit/decision/) and the generated audit/INDEX.md β always run from the primary checkout per the skill's own instruction, so a CWD-relative default is correct |
SM_MERGE_LEDGER |
<repo>/audit/merge-ledger.jsonl |
append-only per-attempt merge ledger written by bin/merge-sequencer.sh (SUCCESS/GATE_REFUSE/BRANCH_MISMATCH/MERGE_CONFLICT/MERGE_REJECTED/PUSH_FAILED/PUSH_RACE_RECOVERED/PUSH_RACE_EXHAUSTED/LOCK_TIMEOUT); like the lock, anchored to --repo by default so every caller targeting the same --repo writes to the same ledger |
SM_LENS_COVERAGE_LEDGER |
shared git rev-parse --git-common-dir-anchored audit/lens-coverage.jsonl -- the common-dir's parent when its own basename is .git (a normal repo/worktree), else the common-dir itself (a bare repo or a submodule) |
lens-coverage ledger written by bin/verdict.py when --lenses is used, shared across every worktree of the same repo |
SM_LESSON_LEDGER |
shared git rev-parse --git-common-dir-anchored .secondmate/lesson-injections.jsonl (same anchoring rule as SM_CLAIM_LEDGER; falls back to $SM_LOOP_STATE/lesson-injections.jsonl if that's set, else a CWD-relative fallback with a loud warning outside any git repo) |
injection ledger written by bin/lesson-lookup.py when --task-id is given, shared across every worktree of the same repo |
The default model IDs are Amazon Bedrock inference-profile IDs β override them for your provider.
Manual install & verify
# install from a local clone instead of GitHub
claude plugin marketplace add /path/to/secondmate
claude plugin install secondmate@secondmate
# verify everything
bin/verdict.py selfcheck && bin/loop-guard.sh selfcheck && bin/verify-gate.sh --selfcheck \
&& bin/prune-output.sh --selfcheck && bin/run-round.sh selfcheck && bin/reason.sh --selfcheck \
&& bin/plan-committee.sh --selfcheck && bin/doctor.sh --selfcheck && bin/scope-guard.py selfcheck \
&& bin/mark-maker.sh --selfcheck && bin/new-worktree.sh --selfcheck && bin/sync-worktree-skills.sh --selfcheck \
&& bin/herdr-pane.sh --selfcheck \
&& bin/log-round.sh --selfcheck && bin/caffeinate-guard.sh --selfcheck && bin/checker-progress.py selfcheck \
&& bin/hold.py selfcheck && bin/committee-output.py --selfcheck \
&& bin/claim-ledger.py selfcheck && bin/merge-sequencer.sh --selfcheck \
&& bin/dispatch-report.py selfcheck && bin/launch-checker.sh --selfcheck \
&& bin/lesson-lookup.py selfcheck && bin/teardown-check.sh --selfcheck \
&& bin/audit-log.py selfcheck \
&& echo ALL_OK
claude plugin validate .MIT Β© Eshwar Vijay
