AGENT SKILL

mastermind-liveness

Mastermind liveness — check that every in-progress, blocked or in-review org issue has a way forward (run, queued wake, blocker or recovery action); fix stalled ones.

License 许可
Apache-2.0
所属仓库
monoes/monomind
最近更新
2026-11-10
Stars
★ 23
Forks
2

01 前言 Front Matter

name
mastermind-liveness
pick
low
type
domain-skill
description
Mastermind liveness — check that every in-progress, blocked or in-review org issue has a way forward (run, queued wake, blocker or recovery action); fix stalled ones.
default_mode
auto

03 SKILL.md 正文

Mastermind Liveness

This skill is invoked directly via /mastermind-liveness.


Inputs

  • brain_context: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
  • org_name: org to check (required)
  • action: check | checkout | release | wakeup | recover
  • issue_id: specific issue to operate on (required for checkout/release/wakeup/recover)
  • agent_id: agent claiming checkout (required for checkout)
  • run_id: execution run ID (required for checkout)
  • reason: recovery reason (required for recover)
  • caller: command | master

Liveness Contract

An issue is healthy when the product can answer "what moves this forward next?" without requiring a human to reconstruct intent.

An issue is stalled when it is non-terminal but has no:

  • active run linked to the issue
  • queued wake or continuation deliverable to the responsible agent
  • explicit execution-policy participant
  • pending interaction waiting on a specific responder
  • one-shot monitor (nextCheckAt) that will wake the assignee
  • human owner (assigneeUserId)
  • first-class blocker chain whose leaf issues are themselves healthy
  • open explicit recovery action naming owner + next action

Valid non-terminal statuses for agent-owned work: todo, in_progress, blocked, in_review

Status → execution expectation:

  • todo: actionable but not yet claimed — may still need wake path to assignee
  • in_progress: must have agent assignee + active execution backing (strict)
  • blocked: must have named external dependency (blockedByIssueIds) or explicit human decision needed
  • in_review: review participant must be named; next move belongs to reviewer

Step 0 — Brain Load (standalone only)

If caller is not "command", load brain context following mastermind-protocol/SKILL.md Brain Load Procedure with namespace: ops.


Step 1 — Load Org and Issues

orgFile=".monomind/orgs/${org_name}.json"
[ ! -f "$orgFile" ] && { echo "ERROR: Org '${org_name}' not found."; exit 1; }

issuesFile=".monomind/orgs/${org_name}-issues.json"
stateFile=".monomind/orgs/${org_name}-state.json"

Normalize any legacy records written by a pre-2.10 version of these skills. Idempotent — safe to run on every load. Guarded because this skill tolerates a missing issues file.

[ -f "$issuesFile" ] && python3 - "$issuesFile" <<'PYEOF'
import json, sys
path = sys.argv[1]
data = json.load(open(path))
RENAME = {
    "assignee_id": "assigneeId", "assigned_to": "assigneeId",
    "created_at": "createdAt", "updated_at": "updatedAt",
    "closed_at": "closedAt", "project_id": "projectId",
    "parent_id": "parentId", "recovery_status": "recoveryStatus",
    "lastActivityAt": "updatedAt",
}
changed = False
for iss in data.get("issues", []):
    for old, new in RENAME.items():
        if old in iss:
            iss.setdefault(new, iss.pop(old))
            iss.pop(old, None)
            changed = True
    if iss.get("status") == "open":
        iss["status"] = "todo"
        changed = True
if changed:
    tmp = path + ".tmp"
    with open(tmp, "w") as f:
        json.dump(data, f, indent=2)
    import os; os.replace(tmp, path)
PYEOF

Step 2 — Execute Action

check (default)

Audit every non-terminal agent-owned issue for liveness. Flag stalled issues.

echo "LIVENESS CHECK — ${org_name}"
echo "════════════════════════════════════════════════════════"

python3 - "$issuesFile" "$stateFile" <<'PYEOF'
import json, sys, os
from datetime import datetime, timedelta

issues_path = sys.argv[1]
state_path  = sys.argv[2]

# Load issues
if not os.path.exists(issues_path):
    print("  No issues file found. Org has no tracked issues.")
    sys.exit(0)

data   = json.load(open(issues_path))
issues = data.get("issues", [])

# Load active agent run IDs from state
active_runs = set()
if os.path.exists(state_path):
    try:
        state = json.load(open(state_path))
        for role in state.get("roles", []):
            if role.get("currentRunId"): active_runs.add(role["currentRunId"])
    except: pass

non_terminal_statuses = {"todo","in_progress","blocked","in_review"}
terminal_statuses     = {"done","cancelled"}

healthy, stalled, warnings = [], [], []
now = datetime.utcnow()

for iss in issues:
    status = iss.get("status","")
    iid    = iss.get("id","?")
    title  = (iss.get("title") or "?")[:50]

    if status in terminal_statuses:
        continue
    if status not in non_terminal_statuses:
        # Silently skipping an unknown status is how issues become invisible.
        warnings.append((iid, title, status, f"unknown status '{status}' — outside the canonical vocabulary"))
        continue

    aId = iss.get("assigneeAgentId")
    uId = iss.get("assigneeUserId")

    # Human-owned: the next move belongs to a person, not an execution path.
    if uId and not aId:
        healthy.append((iid, title, status, "user-owned"))
        continue

    paths = []

    run_id = iss.get("executionRunId") or iss.get("checkoutRunId")
    if run_id and run_id in active_runs:
        paths.append("active-run")

    resolved_ids = {i.get("id") for i in issues if i.get("status") in terminal_statuses}
    blockers = iss.get("blockedByIssueIds") or []
    if status == "blocked":
        if blockers:
            unresolved = [b for b in blockers if b not in resolved_ids]
            if unresolved:
                paths.append(f"blocked-by:{','.join(unresolved[:2])}")
            else:
                warnings.append((iid, title, status, "all blockers resolved but issue still blocked"))
        elif not iss.get("recoveryActions"):
            # Liveness Contract: blocked requires a named dependency or an
            # explicit human decision. This issue records neither.
            stalled.append((iid, title, status, "blocked with no blockedByIssueIds and no recovery action"))
            continue

    if iss.get("executionPolicy", {}).get("monitor", {}).get("nextCheckAt"):
        paths.append("monitor")

    if iss.get("recoveryActions") and any(
        r.get("status") not in ("resolved","cancelled")
        for r in iss.get("recoveryActions",[])
    ):
        paths.append("recovery-action")

    if iss.get("currentParticipant"):
        paths.append("participant")

    if status == "in_review" and not (iss.get("reviewerId") or iss.get("currentParticipant")):
        stalled.append((iid, title, status, "in_review with no named reviewer"))
        continue

    if status == "in_progress" and aId and not paths:
        updated = iss.get("updatedAt","")
        if updated:
            try:
                age = now - datetime.fromisoformat(updated[:19])
                if age > timedelta(hours=2):
                    stalled.append((iid, title, status, f"in_progress {int(age.total_seconds()//3600)}h with no active path"))
                    continue
            except Exception:
                pass
        stalled.append((iid, title, status, "in_progress with no active execution path"))
        continue

    if paths:
        healthy.append((iid, title, status, " + ".join(paths)))
    elif not aId:
        warnings.append((iid, title, status, "no assignee — nothing will pick this up"))
    elif status == "todo":
        warnings.append((iid, title, status, "todo assigned to agent — may need wakeup"))
    else:
        stalled.append((iid, title, status, f"{status} with an agent assignee but no execution path"))

print(f"  ✓ Healthy: {len(healthy)}")
if healthy:
    for iid, t, s, p in healthy[:5]:
        print(f"    {iid}: [{s}] {t} — {p}")
    if len(healthy) > 5: print(f"    … {len(healthy)-5} more")

print()
if stalled:
    print(f"  ✗ STALLED: {len(stalled)}")
    for iid, t, s, p in stalled:
        print(f"    {iid}: [{s}] {t}")
        print(f"      → {p}")
    print()
    print("  Fix: /mastermind-liveness --org <org> --action recover --issue-id <id> --reason 'execution path lost'")
else:
    print("  ✓ No stalled issues.")

if warnings:
    print()
    print(f"  ⚠ Warnings: {len(warnings)}")
    for iid, t, s, p in warnings:
        print(f"    {iid}: [{s}] {t} — {p}")
PYEOF

checkout

Claim an issue for execution by an agent run. Sets checkoutRunId and executionRunId.

[ -z "$issue_id" ] && { echo "ERROR: --issue-id required."; exit 1; }
[ -z "$agent_id" ] && { echo "ERROR: --agent-id required."; exit 1; }
[ -z "$run_id"   ] && { echo "ERROR: --run-id required."; exit 1; }
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)

python3 - "$issuesFile" "$issue_id" "$agent_id" "$run_id" "$ts" <<'PYEOF'
import json, os, sys

path, iid, agentId, runId, ts = sys.argv[1:]
data = json.load(open(path))
issues = data.get("issues", [])

found = False
for iss in issues:
    if iss.get("id") == iid:
        existing = iss.get("checkoutRunId")
        if existing and existing != runId:
            print(f"  CONFLICT: Issue already checked out by run {existing}")
            print(f"  Release first: /mastermind-liveness --org <org> --action release --issue-id {iid}")
            sys.exit(1)
        iss["checkoutRunId"]  = runId
        iss["executionRunId"] = runId
        iss["assigneeId"]     = agentId
        iss["assigneeAgentId"]= agentId
        iss["assigneeUserId"] = None
        iss["status"]         = "in_progress"
        iss["checkedOutAt"]   = ts
        iss["updatedAt"]      = ts
        found = True
        print(f"  CHECKOUT: Issue {iid} → agent {agentId}, run {runId}")
        print(f"  Status set to: in_progress")
        break

if not found:
    print(f"  ERROR: Issue '{iid}' not found.")
    sys.exit(1)

data["issues"] = issues
tmp = path + ".tmp"
with open(tmp, "w") as f:
    json.dump(data, f, indent=2)
os.replace(tmp, path)
PYEOF

activityFile=".monomind/orgs/${org_name}-activity.jsonl"
jq -cn --arg iid "$issue_id" --arg ts "$ts" --arg st "in_progress" --arg ag "$agent_id" --arg sm "checkout $issue_id" \
  '{issue_id:$iid, ts:$ts, status:$st, tokens:null, agent:$ag, type:"checkout", summary:$sm}' \
  >> "$activityFile"

release

Release the checkout lock on an issue.

[ -z "$issue_id" ] && { echo "ERROR: --issue-id required."; exit 1; }
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)

python3 - "$issuesFile" "$issue_id" "$ts" "${run_id:-}" <<'PYEOF'
import json, sys, os

path, iid, ts, run_id = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]
data = json.load(open(path))
issues = data.get("issues", [])

for iss in issues:
    if iss.get("id") == iid:
        current = iss.get("checkoutRunId","")
        if run_id and current != run_id:
            print(f"  WARNING: Releasing run {run_id} but issue has run {current}. Proceeding.")
        iss.pop("checkoutRunId", None)
        iss.pop("executionRunId", None)
        iss.pop("checkedOutAt", None)
        iss["updatedAt"] = ts
        print(f"  RELEASED: Checkout cleared for issue {iid}")
        print(f"  Status remains: {iss.get('status','?')} — update separately if needed.")
        data["issues"] = issues
        tmp = path + ".tmp"
        with open(tmp, "w") as f:
            json.dump(data, f, indent=2)
        os.replace(tmp, path)
        sys.exit(0)

print(f"  ERROR: Issue '{iid}' not found.")
sys.exit(1)
PYEOF

activityFile=".monomind/orgs/${org_name}-activity.jsonl"
currentStatus=$(jq -r --arg id "$issue_id" '(.issues // [])[] | select(.id == $id) | .status // "todo"' "$issuesFile")
jq -cn --arg iid "$issue_id" --arg ts "$ts" --arg st "$currentStatus" --arg ag "${agent_id:-operator}" --arg sm "release $issue_id" \
  '{issue_id:$iid, ts:$ts, status:$st, tokens:null, agent:$ag, type:"release", summary:$sm}' \
  >> "$activityFile"

wakeup

Decide whether the assignee of a todo or blocked issue should be woken.

[ -z "$issue_id" ] && { echo "ERROR: --issue-id required."; exit 1; }

python3 - "$issuesFile" "$stateFile" "$issue_id" "${agent_id:-}" <<'PYEOF'
import json, sys, os

issues_path, state_path, iid, actor_agent_id = sys.argv[1:]

data = json.load(open(issues_path))
iss = next((i for i in data.get("issues",[]) if i.get("id") == iid), None)
if not iss:
    print(f"  ERROR: Issue '{iid}' not found.")
    sys.exit(1)

checkout_agent = iss.get("assigneeAgentId") or ""
checkout_run   = iss.get("checkoutRunId","")

# Port of Paperclip's shouldWakeAssigneeOnCheckout logic
actor_is_agent     = bool(actor_agent_id)
actor_differs      = actor_agent_id != checkout_agent
checkout_has_no_run= not checkout_run

should_wake = (
    not actor_is_agent          # non-agent actor (board/human) → always wake
    or actor_differs            # different agent claiming → wake original
    or checkout_has_no_run      # no active run → wake to get work started
)

print(f"  Issue:   {iid} — {iss.get('title','?')[:60]}")
print(f"  Status:  {iss.get('status','?')}")
print(f"  Assignee:{checkout_agent or '(none)'}")
print(f"  Run:     {checkout_run or '(none)'}")
print(f"  Actor:   {actor_agent_id or '(board)'}")
print()
if should_wake:
    print("  WAKE: YES — assignee should be notified to pick up this issue.")
    print("  Reasons:")
    if not actor_is_agent:           print("    · Non-agent actor (board/human)")
    if actor_is_agent and actor_differs: print(f"    · Actor ({actor_agent_id}) != assignee ({checkout_agent})")
    if checkout_has_no_run:          print("    · No active execution run")
else:
    print("  WAKE: NO — assignee already has an active run for this issue.")
PYEOF

recover

File an explicit recovery action on a stalled issue with a named owner and next step.

[ -z "$issue_id" ] && { echo "ERROR: --issue-id required."; exit 1; }
[ -z "$reason"   ] && { echo "ERROR: --reason required."; exit 1; }
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
recoveryId="recovery-$(python3 -c 'import time; print(int(time.time()*1000))')"

python3 - "$issuesFile" "$issue_id" "$recoveryId" "${agent_id:-operator}" "$reason" "$ts" <<'PYEOF'
import json, os, sys

path, iid, rid, owner, cause, ts = sys.argv[1:]
data = json.load(open(path))
issues = data.get("issues", [])

for iss in issues:
    if iss.get("id") == iid:
        recovery = {
            "id": rid,
            "kind": "restore-liveness",
            "owner": owner,
            "cause": cause,
            "createdAt": ts,
            "status": "open",
            "nextAction": f"Investigate why issue '{iid}' has no active execution path and restore it.",
        }
        iss.setdefault("recoveryActions", []).append(recovery)
        iss["status"] = "blocked"
        iss["updatedAt"] = ts
        data["issues"] = issues
        tmp = path + ".tmp"
        with open(tmp, "w") as f:
            json.dump(data, f, indent=2)
        os.replace(tmp, path)
        print(f"  RECOVERY ACTION FILED: {rid}")
        print(f"  Issue {iid} → status: blocked (pending recovery)")
        print(f"  Owner: {owner}")
        print(f"  Cause: {cause}")
        print(f"  Resolve with: /mastermind-liveness --org <org> --action checkout --issue-id {iid} --agent-id <id> --run-id <id>")
        sys.exit(0)

print(f"  ERROR: Issue '{iid}' not found.")
sys.exit(1)
PYEOF

activityFile=".monomind/orgs/${org_name}-activity.jsonl"
jq -cn --arg iid "$issue_id" --arg ts "$ts" --arg st "blocked" --arg ag "${agent_id:-operator}" --arg sm "recover $issue_id" \
  '{issue_id:$iid, ts:$ts, status:$st, tokens:null, agent:$ag, type:"recover", summary:$sm}' \
  >> "$activityFile"

Step 3 — Return Output

domain: ops
status: complete
action: <action>
org_name: <org_name>
issue_id: <issue_id or all>

Step 4 — Brain Write (standalone only)

If caller is not "command", follow mastermind-protocol/SKILL.md Brain Write Procedure for domain ops.

04 同仓库更多 Skills

monoes
monoes/monomind

zk-steward

Org role guidance for a ZK steward: engineer zero-knowledge proof systems with circuit design, SNARK vs STARK choice and security review. This is zero-knowledge cryptography, not Zettelkasten note-taking.

★ 23
monoes
monoes/monomind

writing-plans

Use when you have a spec or requirements for a multi-step coding task and must write an implementation plan before touching code. Produces bite-sized TDD tasks with exact file paths, code and commands for an engineer with zero context.

内容创作者写作与文案
★ 23
monoes
monoes/monomind

write-spec

Write a feature spec or PRD from a problem statement or feature idea. Use when turning a vague idea or user request into a structured document, scoping a feature with goals and non-goals, defining success metrics and acceptance criteria, or breaking a big ask into a phased spec.

产品经理
★ 23
monoes
monoes/monomind

write-query

Write optimized SQL for your dialect with best practices. Use when translating a natural-language data need into SQL, building a multi-CTE query with joins and aggregations, optimizing a query against a large partitioned table, or getting dialect-specific syntax for Snowflake, BigQuery, Postgres, etc.

数据分析师
★ 23
monoes
monoes/monomind

workflow-automation

Org role guidance for workflow automation: build and maintain CI/CD definitions in GitHub Actions or equivalent: triggers, jobs, matrices, caching. Covers path filters, dependency caching, parallel jobs, timeouts and fail-fast ordering.

运维与部署Skill与智能体开发
★ 23
monoes
monoes/monomind

workflow-architect

Org role guidance for a workflow architect: map full workflow trees for systems, user journeys and agents, covering every branch and failure. Covers discovering workflows from code, handoff contracts, timeouts, recovery paths and observable state.

Skill与智能体开发
★ 23