| name | mastermind-approvev1 |
| description | LEGACY-ORG-V1 (2026-07): v2 approvals arrive as question events in the dashboard Human Input tab — no skill needed. Mastermind approvev1 — review and action pending approval requests from agents in a running v1 (prompt-orchestrated) org. Agents can request human approval before proceeding with sensitive actions. Reach it only via `/mastermind:approvev1`. |
| type | domain-skill |
| default_mode | confirm |
Mastermind Approve (v1, legacy)
LEGACY-ORG-V1 — file-based approval queue for prompt-orchestrated v1 orgs. Reach it only via /mastermind:approvev1.
v2 approvals arrive as question events in the dashboard Human Input tab — there is no v2 approve skill, the dashboard UI is the approval surface. This skill remains only for orgs not yet migrated off the v1 board_id/topology config shape.
This skill is invoked by mastermind:approvev1 or directly via /mastermind:approvev1.
Inputs
brain_context: BRAIN CONTEXT block
org_name: org to check approvals for
action: list | approve | reject | inspect
approval_id: id of the specific approval request (for approve/reject/inspect)
reason: optional reason for rejection
caller: command | master
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 Approvals
Approvals are stored in .monomind/orgs/<org_name>-approvals.json:
orgFile=".monomind/orgs/${org_name}.json"
approvalsFile=".monomind/orgs/${org_name}-approvals.json"
[ ! -f "$approvalsFile" ] && echo '{"approvals":[]}' > "$approvalsFile"
Step 2 — Execute Action
list (default)
Show pending approval requests from agents:
jq -r '
(.approvals // []) | map(select(.status == "pending")) |
if length == 0 then "No pending approvals." else
.[] | "[\(.id)] \(.agent_id): \(.title)\n Action: \(.action)\n Risk: \(.risk_level // "low")\n Requested: \(.requested_at)"
end
' "$approvalsFile"
Render as:
PENDING APPROVALS — org: <org_name>
──────────────────────────────────────────────────
[req-001] content-writer: Publish to external blog
Action: POST to https://blog.example.com/api/posts
Risk: medium
Requested: 2 min ago
[req-002] marketer: Send email campaign
Action: Send to 1,200 subscribers
Risk: high ← requires explicit approval
Requested: 5 min ago
──────────────────────────────────────────────────
2 pending | Type "approve <id>" or "reject <id> <reason>"
inspect
Show full details of a single approval request:
jq --arg id "$approval_id" '(.approvals // [])[] | select(.id == $id)' "$approvalsFile"
Print the agent's requested action, context, and any supporting evidence they provided.
approve
Update approval status and notify the waiting agent via memory:
tmp="${approvalsFile}.tmp"
jq --arg id "$approval_id" \
'.approvals = [(.approvals // [])[] | if .id == $id then .status = "approved" | .resolved_at = (now|todate) | .resolved_by = "human" else . end]' \
"$approvalsFile" > "$tmp" && mv "$tmp" "$approvalsFile"
approval=$(jq --arg id "$approval_id" '(.approvals // [])[] | select(.id == $id)' "$approvalsFile")
agent_id=$(echo "$approval" | jq -r '.agent_id')
memNs="org:${org_name}"
npx monomind@latest memory store \
--key "approval:${approval_id}" \
--namespace "$memNs" \
--value '{"status":"approved","approval_id":"'"$approval_id"'","ts":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"}'
echo "Approved request $approval_id — agent $agent_id may proceed."
Emit org:approval:approved event to dashboard.
reject
tmp="${approvalsFile}.tmp"
jq --arg id "$approval_id" --arg reason "${reason:-No reason given}" \
'.approvals = [(.approvals // [])[] | if .id == $id then .status = "rejected" | .resolved_at = (now|todate) | .resolved_by = "human" | .rejection_reason = $reason else . end]' \
"$approvalsFile" > "$tmp" && mv "$tmp" "$approvalsFile"
approval=$(jq --arg id "$approval_id" '(.approvals // [])[] | select(.id == $id)' "$approvalsFile")
agent_id=$(echo "$approval" | jq -r '.agent_id')
memNs="org:${org_name}"
npx monomind@latest memory store \
--key "approval:${approval_id}" \
--namespace "$memNs" \
--value '{"status":"rejected","approval_id":"'"$approval_id"'","reason":"'"${reason:-No reason given}"'","ts":"'"$(date -u +%Y-%m-%dT%H:%M:%SZ)"'"}'
echo "Rejected request $approval_id. Agent $agent_id has been notified."
Emit org:approval:rejected event.
How Agents Request Approval
Agents that need human approval before a sensitive action should:
- Write to the approvals file:
approvalsFile=".monomind/orgs/${orgName}-approvals.json"
[ ! -f "$approvalsFile" ] && echo '{"approvals":[]}' > "$approvalsFile"
approval_id="req-$(date +%s)-$$-$RANDOM"
tmp="${approvalsFile}.tmp"
jq --arg id "$approval_id" \
--arg agent "$role_id" \
--arg title "$action_title" \
--arg action "$action_description" \
--arg risk "medium" \
'.approvals += [{"id":$id,"agent_id":$agent,"title":$title,"action":$action,"risk_level":$risk,"status":"pending","requested_at":(now|todate)}]' \
"$approvalsFile" > "$tmp" && mv "$tmp" "$approvalsFile"
-
Emit org:approval:requested event to dashboard (so the human is notified).
-
Poll for the approval decision — check the approvals file first (authoritative, updated by both the dashboard UI and /mastermind:approvev1), then fall back to memory:
approvalsFile=".monomind/orgs/${orgName}-approvals.json"
while true; do
file_status=$(jq --arg id "$approval_id" '(.approvals // [])[] | select(.id == $id) | .status // ""' "$approvalsFile" 2>/dev/null || echo "")
if [ -z "$file_status" ] || [ "$file_status" = '"pending"' ] || [ "$file_status" = "pending" ]; then
mem_status=$(npx monomind@latest memory get --key "approval:${approval_id}" --namespace "${memNs}" 2>/dev/null | jq -r '.status // ""' 2>/dev/null)
[ -n "$mem_status" ] && [ "$mem_status" != "pending" ] && file_status="$mem_status"
fi
file_status=$(echo "$file_status" | tr -d '"')
[ "$file_status" = "approved" ] && break
[ "$file_status" = "rejected" ] && { echo "Action rejected by governance policy — skip this action"; exit 1; }
sleep 30
done
Step 3 — Return Output
domain: ops
status: complete
action: <action>
org: <org_name>
approval_id: <approval_id if applicable>
pending_count: <N>
Step 4 — Brain Write (standalone only)
If caller is not "command", follow mastermind-protocol/SKILL.md Brain Write Procedure for domain ops.