mino-checkup
Workflow Health Mechanic
Diagnose environment readiness, skill wiring, brief freshness, and source-task alignment. Record manual acceptance, aggregate composite parents, and finalize verified tasks. Repair safely, report what cannot be repaired, never silently mutate human content.
Modes
The user may specify a mode. Default is check.
pre-flight <issue>— validate environment for one task before/mino-runexecutes. Halts on broken environment, never advances state.check— read-only inspection of.mino/, skill ecosystem, briefs. No mutation.repair— fix missing wiring and auto-repairable issues (re-create missing dirs, refresh stale brief metadata).reconcile [<issue>]— compare local briefs against source tasks; replay valid events to rebuild brief state; detect external close.accept <issue>— record human acceptance for a task currently inpending_acceptance. Publishes any local-only code first.aggregate <issue>— finalize acomposite/containertask once all required children aredone.finalize <issue>— bind verified-completion evidence and transition todone. Invoked by the Loop Mode Decision Function (seeiron-tree-protocol.md) when verify producedpass + verifiedbut the task is not yetdone.
Pre-flight gate
pre-flight is a stable interface called by /mino-run before it acquires the lock. It is the only mode that must never mutate state beyond writing one structured event when blocking.
Steps:
- Confirm
.mino/and.mino/briefs/exist;ghis authenticated; the brief for<issue>exists and is well-formed. - Working tree cleanliness — the workflow commits via
git add -A -- ':!.mino/briefs/' ':!.mino/locks/' ':!.mino/run.lock'. Any pre-existing uncommitted change outside that allow-list would be silently bundled into the run commit. Treat as blocking:- Run
git status --porcelain -- ':!.mino/briefs/' ':!.mino/locks/' ':!.mino/run.lock'. - If non-empty, the environment is broken: list the offending paths and tell the user to commit, stash, or revert them before re-running
/mino-run.
- Run
- Run task-specific dependency checks (e.g.
node_modulespresent, toolchain available, secrets present). - If everything is healthy, print
pre-flight ok issue-{N}and exit 0. Do NOT post any comment or modify any file. - If something is broken:
- Set
Workflow Entry State: blockedin the brief. - Render
templates/event-checkup-preflight-blocked.yml.tmplwith the next sequence number and post it as an issue comment. Set theblocking_checkplaceholder to a short kebab-case identifier (e.g.dirty-working-tree,gh-not-authenticated,missing-dependency) so downstream consumers can distinguish causes. - Exit non-zero so
/mino-runhalts before acquiring the lock.
- Set
Check / Repair
Both modes do the inspection below. check is read-only; repair may auto-repair the items explicitly marked safe.
- Core checks:
.mino/and.mino/briefs/exist (repairmaymkdir -p).ghauthenticated.- Project- or global-scope skills directory accessible.
- Skill ecosystem scan:
- Discover installed skills across scopes:
.claude/skills/,.agents/skills/,~/.claude/skills/,~/.agents/skills/. - Verify the four core skills are present:
task,run,verify,checkup. - Report complementary skill coverage and gaps.
- Discover installed skills across scopes:
- Brief freshness (
repaironly):- For each brief, ensure required sections exist per
brief-contract.md. Missing sections may be appended with empty placeholders. Existing human content is never overwritten.
- For each brief, ensure required sections exist per
Neither mode mutates any workflow event or transitions any task. Print a concise health report at the end.
Reconcile
reconcile (or reconcile <issue> for one task) refreshes brief state from canonical evidence and detects out-of-band activity.
- List local briefs:
ls .mino/briefs/issue-*.md. - List source tasks:
gh issue list --state all --limit 200. - For each brief in scope:
- Sources of truth, tried in order:
- Local events — glob
.mino/events/issue-{N}/*.yml. Parse yml blocks, keep those whosetask_keyandapproved_revisionmatch the brief. This is the primary source. - Terminal summary comment (fallback for
doneissues when local log is missing, pre-v1.12 only) — pull all issue comments, pick the one whose body matches the pre-v1.12 signature (🏁 Issue ... donewith inline YAML blocks). v1.12+ done comments are not parseable as a recovery source. - Legacy per-event comments (fallback for pre-v1.10 issues) — pull issue comments, parse every yml event block directly.
- Local events — glob
- If primary yields events, use only primary. Fallbacks are invoked only when primary is empty.
- If multiple sources are present and their event chains diverge (same sequence, different event), halt with
checkup_reconcile_sequence_gap_detectedand require human intervention. - Sequence gap detection: list the
sequencevalues of every parsed event. If they are not a contiguous run starting at1, treat the gaps as missing canonical evidence:- Replay events up to the highest contiguous sequence (
max(sequences) such that 1..max are all present); ignore events past the first gap because their state assumes evidence that no longer exists. - Render
templates/event-checkup-reconcile-sequence-gap.yml.tmplwithfound_sequences,missing_sequences, andhighest_replayable_sequence, write to.mino/events/issue-{N}/{next_seq:04d}-checkup-reconcile-sequence-gap.yml, then post as a short audible comment (heading:⚠️ checkup reconcile — sequence gap on #{N}, plus a one-line description). Do NOT inline the YAML; the local event file is the authoritative record. - Do NOT advance the workflow past
Workflow Entry State: blockeduntil the operator reviews the gap (e.g. recovers the deleted comment, or runs/mino-taskto re-publish a freshapproved_revision).
- Replay events up to the highest contiguous sequence (
- Replay events in ascending
sequenceorder to rebuild the canonical workflow state. Surgically replaceWorkflow State,Pass/Fail Outcome, andCompletion Handoffsections from the resulting state. Never overwriteOpen Questions / Warnings. - External close detection: if the source issue is
closedbut nocheckup_doneevent exists for the active approved revision:- Set
Workflow Entry State: blockedin the brief. - Render
templates/brief-section-external-event.md.tmpl(event=issue_closed, source=github, action=Investigate the close reason and either re-open the issue with /mino-task or accept the close as final) and surgically replace theExternal Eventsection. - Render
templates/event-checkup-reconcile-external-close.yml.tmpl, write to.mino/events/issue-{N}/{next_seq:04d}-checkup-reconcile-external-close.yml, then post as a short audible comment (heading:⚠️ external close detected — #{N}, body: one sentence stating the action the operator must take). Do NOT inline the YAML. - Do NOT mark the task
done. Do NOT auto-sync brief to a completed state.
- Set
- Sources of truth, tried in order:
- Emit a
Pending Acceptancesubsection in the report listing every task still inpending_acceptancewith the next manual action.
Accept
accept <issue> records human acceptance for a task currently in pending_acceptance.
Optional note: invocation may include free-form text after the issue ref (/mino-checkup accept #1842 在你的项目里 ...). If present, capture as manual_verifier_note and append it verbatim to the brief's Manual Acceptance section under a ### Accept Note subsection.
- Confirm
Workflow Entry State: pending_acceptance. If not, halt and report. - Publish any local-only code first:
- Stage all changes except workflow-local cache:bash
git add -A -- ':!.mino/briefs/' ':!.mino/locks/' ':!.mino/run.lock' - If nothing is staged, skip to step 3 with
Code Ref: not_applicable,Code Publication State: not_applicable. - Otherwise commit with
[run] #{N}: {concise change summary}andgit push. - Capture the resulting
HEADSHA asCode Ref. SetCode Publication State: published. - On commit or push failure: do NOT record acceptance. Keep
Current Stage: verify,Next Stage: checkup,Workflow Entry State: pending_acceptance,Code Publication State: local_only. Rendertemplates/brief-section-publication-failure.md.tmplinto theFailure Contextsection. Rendertemplates/event-checkup-accept-publication-failed.yml.tmpland post as comment. Stop.
- Stage all changes except workflow-local cache:
- Render
templates/brief-section-acceptance-summary.md.tmplwith reviewer name, ISO timestamp, code ref, and notes; surgically replace theVerification Summarysection. - Surgically update brief metadata:
Current Stage: checkupNext Stage: doneWorkflow Entry State: ready_to_startPass/Fail Outcome: passCompletion Basis: acceptedCode Ref:andCode Publication State:per step 2
- Render
templates/event-checkup-accept-recorded.yml.tmpland write to.mino/events/issue-{N}/{next_seq:04d}-checkup-accept-recorded.yml. Silent: do NOT post a GitHub comment. - Remove the
pending-acceptancelabel from the issue. - Proceed to Finalize (below).
Aggregate
aggregate <issue> finalizes a composite or container parent.
- Confirm
Classificationiscompositeorcontainer. - Resolve required child task keys from the brief
Work BreakdownandDependenciessections. Confirm every child brief hasPass/Fail Outcome: passandCurrent Stage: done. - Render
templates/brief-section-aggregate-summary.md.tmplwith the children evidence list (each line:- {child_task_key} (issue-{N}): {completion_basis} @ {code_ref_or_not_applicable}); surgically replace theVerification Summarysection. - Surgically update brief metadata:
Current Stage: checkupNext Stage: doneWorkflow Entry State: ready_to_startPass/Fail Outcome: passCompletion Basis: aggregatedCode Publication State: not_applicableCode Ref: not_applicable
- Render
templates/event-checkup-aggregate-recorded.yml.tmpland write to.mino/events/issue-{N}/{next_seq:04d}-checkup-aggregate-recorded.yml. Silent: do NOT post a GitHub comment. - Proceed to Finalize (below).
Finalize
finalize <issue> (also entered automatically by accept and aggregate) binds completion evidence and transitions the task to done.
Read the brief. Refuse to proceed unless ALL of:
Pass/Fail Outcome: passCompletion Basis∈ {verified,accepted,aggregated}Code Publication State∈ {published,not_applicable}Code Refis a SHA whenCode Publication State: published, elsenot_applicableIf any check fails, halt and report which precondition is missing. Do NOT mutate state.
Surgically update brief metadata:
Current Stage: doneNext Stage: none
Record
checkup_donelocally — rendertemplates/event-checkup-done.yml.tmplwith the boundcompletion_basis,code_ref,code_publication_state, and write to.mino/events/issue-{N}/{next_seq:04d}-checkup-done.yml.Reply Dispatch (replaces the deprecated v0.6.2 summary comment):
Read
.mino/config.yml > comment.reply(defaultauto).- If
never: setreply_posted = null, skip to step 5. - If
always: rendertemplates/comment-reply.md.tmpland post. - If
auto:- Check whether a reply was already posted in this loop iteration (scan
.mino/events/issue-{N}/for any prior event withreply_postednon-null within the current loop window). If yes: setreply_posted = null, skip to step 5 (no duplicate convergence reply). - Else if the latest verify event has
promoted_doc != nullOR the brief's Manual Acceptance contains a### Accept Notesubsection with actionable prose: render and post. - Else: set
reply_posted = null, skip to step 5.
- Check whether a reply was already posted in this loop iteration (scan
When rendering, synthesise variables from:
- The latest
verify_*event (forpromoted_doc→docs_link_line_or_empty) - The brief's report at
.mino/reports/issue-{N}/report.md - The brief's
Accept Notesubsection (if present)
Apply the template's HTML-comment variable rules. Post via
gh issue comment {N} --body-file <rendered>. On failure: logreply_post_failed: <reason>, setreply_posted = null, do NOT retry.Then patch the
event-checkup-done.ymlfile written in step 3 to setreply_postedto the captured URL ornull.- If
Issue closure:
- If brief
Close On Done: autoand the issue is still open:gh issue close {N} --reason completed. - If
Close On Done: manual: leave the issue open. Convey the close instruction via ONE of:- If step 4 posted a reply (
reply_posted != null): append a final line to the reply body BEFORE posting it (or, if already posted, this is a known minor lag — the brief still carries the instruction). - If step 4 was silent: write the close instruction to the brief's
Workflow Statesection asManual Close: gh issue close {N} --reason completed. Never post a standalone manual-verification prompt as a status comment.
- If step 4 posted a reply (
- If the issue was already closed externally before finalize ran, do NOT re-open and do NOT re-close. Note the pre-existing closure in the report.
- If brief
Detect orchestrator mode: if
.mino/loops/active.lockexists AND itsholder_agent: mino-taskAND itsheartbeat_atis within the last 6 hours: return silently. Otherwise proceed.
Sequence numbers
Events posted by checkup share the same sequence space as task / run / verify events. Before writing any event, fetch the current max sequence for the active approved_revision from the local event log (ls .mino/events/issue-{N}/ + parse filename prefixes) and use max + 1. GitHub comments are no longer the sequence source.
Templates
All event YAML and brief sections come from templates/. Render via literal substitution; no conditionals.
- Events:
event-checkup-preflight-blocked.yml.tmpl,event-checkup-accept-recorded.yml.tmpl,event-checkup-accept-publication-failed.yml.tmpl,event-checkup-aggregate-recorded.yml.tmpl,event-checkup-done.yml.tmpl,event-checkup-reconcile-external-close.yml.tmpl,event-checkup-reconcile-sequence-gap.yml.tmpl. - Reply:
comment-reply.md.tmpl— sole rendering source for finalize convergence. - Deprecated (kept on disk for rollback, remove in v0.7.0): the old summary template (
comment-checkup-*.md.tmpl). - Brief sections:
brief-section-acceptance-summary.md.tmpl,brief-section-aggregate-summary.md.tmpl,brief-section-external-event.md.tmpl,brief-section-publication-failure.md.tmpl.
Brief edits are always surgical: replace only the named section header and its body up to the next ## header. Never touch Open Questions / Warnings, Source, or any other section not listed above.
Constraints
- Do NOT create issues or re-open closed issues.
- Do NOT mark a task
doneoutsidefinalize(or viaaccept/aggregatewhich delegate tofinalize). - Do NOT mark a task
doneduringpre-flight,check,repair, orreconcile. - Do NOT record manual acceptance against an unpublished code state.
- Do NOT bypass pre-flight failures — if the environment is broken, block execution.
- Do NOT close issues when
Close On Done: manual. - Do NOT stage or commit
.mino/briefs/,.mino/locks/, or.mino/run.lock— these are local workflow cache and must not enter git history. - Do NOT overwrite human-authored sections (
Open Questions / Warnings, free-form notes insideAcceptance Criteria, etc.). - Do NOT auto-sync a brief to
doneafter detecting an external close — recordExternal Eventand stop. - Do NOT
push --force,reset --hardpast the remote tip, rebase or amend any pushed commit; usegit revertto undo published work (see protocol § Multi-Agent Git Hygiene). - Do NOT post individual comments for
checkup_accept_recordedorcheckup_aggregate_recorded— silent in v1.10. - Do NOT post a
checkup_donestatus comment. Convergence reaches the user via Reply Dispatch (Finalize step 4) or remains silent. The local.mino/events/issue-{N}/tree is the authoritative log. - Do NOT post a standalone manual-verification prompt as a comment. Manual close instructions live in the reply (when one is posted) or in the brief
Workflow Statesection. - Do NOT echo
manual_verifier_note/Accept Noteverbatim to GitHub. - Do NOT retry a failed reply post.
- Do NOT derive sequence from issue comments; read from
.mino/events/issue-{N}/filenames.
