Skip to content
Back to skills

Mastermind Issue Detail

BSecurity

Mastermind issue-detail — inspect and manage one org task: thread, run history, comments, sub-issues, attachments, assignment, closing and recovery.

  • 21 stars
  • 0 votes
  • 0 copies
  • 6 views
  • Added September 10, 2026
ai-agentspythongobash

Security analysis

B88/100
  • criticalSends environment variables or credentials to an external URL

Pro shows the line behind each finding and how to fix it

Scanned October 1, 2026

npx -y skills add monoes/monomind --skill mastermind-issue-detail --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Mastermind Issue Detail?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Mastermind Issue Detail
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/monoes-mastermind-issue-detail/badge)](https://www.skillsdirectory.com/skills/monoes-mastermind-issue-detail)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: mastermind-issue-detail
description: "Mastermind issue-detail — inspect and manage one org task: thread, run history, comments, sub-issues, attachments, assignment, closing and recovery."
type: domain-skill
default_mode: auto
pick: low
---

# Mastermind Issue Detail

This skill is invoked directly via `/mastermind-issue-detail`.

---

## Inputs

- `brain_context`: BRAIN CONTEXT block (injected by command, or loaded below if standalone)
- `org_name`: org the issue belongs to (required)
- `issue_id`: issue id/slug (required)
- `action`: show | thread | runs | sub-issues | attachments | comment | assign | close | reopen | recover
- `comment_body`: comment text (required for comment action)
- `assignee_id`: agent id to assign (required for assign action)
- `recovery_action`: accept | reject (for recover action)
- `days`: lookback window for run history (default 14)
- `caller`: command | master

---

## Issue Status Flow

```
todo → in_progress → in_review → done
         ↓
      blocked → in_progress
         ↓
    cancelled
```

Recovery actions apply when an issue enters `needs_recovery` state after a failed run.

---

## 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 Issue Data

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

issuesFile=".monomind/orgs/${org_name}-issues.json"
[ ! -f "$issuesFile" ] && { echo "ERROR: No issues file for org '$org_name'. Create issues via /mastermind-issues --action create."; exit 1; }

issueDef=$(jq -r --arg id "$issue_id" '(.issues // [])[] | select(.id == $id or .slug == $id)' "$issuesFile")
[ -z "$issueDef" ] && { echo "ERROR: Issue '$issue_id' not found in org '$org_name'."; exit 1; }

resolvedId=$(echo "$issueDef" | jq -r '.id')
activityFile=".monomind/orgs/${org_name}-activity.jsonl"
threadFile=".monomind/orgs/${org_name}-threads.jsonl"
days=${days:-14}
cutoff=$(date -u -v-${days}d +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || date -u -d "${days} days ago" +%Y-%m-%dT%H:%M:%SZ 2>/dev/null || echo "")
```

Normalize any legacy records written by a pre-2.10 version of these skills. Idempotent — safe to run on every load.

```bash
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

### show (default)

```bash
echo "ISSUE DETAIL — $issue_id @ $org_name"
echo "────────────────────────────────────────────────────────"

echo "$issueDef" | jq -r '
  "  ID:            \(.id)",
  "  Title:         \(.title // "(no title)")",
  "  Status:        \(.status // "todo")",
  "  Priority:      \(.priority // "medium")",
  "  Assignee:      \(.assigneeId // "(unassigned)")",
  "  Agent:         \(.assigneeAgentId // "(none)")",
  "  Project:       \(.projectId // "(none)")",
  "  Created:       \(.createdAt // "-")",
  "  Updated:       \(.updatedAt // "-")"
'

# Sub-issues
subCount=$(jq --arg pid "$resolvedId" '[(.issues // [])[] | select(.parentId == $pid)] | length' "$issuesFile" 2>/dev/null || echo 0)
echo "  Sub-issues:    $subCount"

# Attachments
attCount=$(echo "$issueDef" | jq -r '(.attachments // []) | length')
echo "  Attachments:   $attCount"

# Recovery
recoveryStatus=$(echo "$issueDef" | jq -r '.recoveryStatus // "none"')
[ "$recoveryStatus" != "none" ] && echo "" && echo "  RECOVERY STATUS: $recoveryStatus"

# Description
desc=$(echo "$issueDef" | jq -r '.description // ""')
if [ -n "$desc" ]; then
  echo ""
  echo "DESCRIPTION"
  echo "────────────────────────────────────────────────────────"
  echo "$desc" | head -10
fi
```

### thread

```bash
echo "THREAD — $issue_id"
echo "────────────────────────────────────────────────────────"

found=0
if [ -f "$threadFile" ]; then
  while IFS= read -r line; do
    iid=$(echo "$line" | jq -r '.issue_id // ""')
    [ "$iid" != "$resolvedId" ] && continue
    ts=$(echo "$line" | jq -r '.ts // ""')
    role=$(echo "$line" | jq -r '.role // "agent"')
    body=$(echo "$line" | jq -r '.body // ""' | head -3)
    msgType=$(echo "$line" | jq -r '.type // "message"')
    printf "\n  [%s] %-10s (%s)\n" "$ts" "$role" "$msgType"
    echo "$body" | while IFS= read -r l; do echo "    $l"; done
    found=$((found + 1))
  done < "$threadFile"
fi

[ "$found" -eq 0 ] && echo "  No thread messages for this issue."
echo ""
echo "  $found message(s). To add a comment: --action comment --comment-body '...'"
```

### runs

```bash
echo "RUN HISTORY — $issue_id (last ${days} days)"
echo "────────────────────────────────────────────────────────"
printf "%-26s %-12s %-8s %-14s %s\n" "TIMESTAMP" "STATUS" "TOKENS" "AGENT" "SUMMARY"
echo "────────────────────────────────────────────────────────"

found=0
if [ -f "$activityFile" ]; then
  while IFS= read -r line; do
    iid=$(echo "$line" | jq -r '.issue_id // ""')
    [ "$iid" != "$resolvedId" ] && continue
    ts=$(echo "$line" | jq -r '.ts // ""')
    [ -n "$cutoff" ] && [ "$ts" \< "$cutoff" ] && continue
    st=$(echo "$line" | jq -r '.status // "-"')
    tok=$(echo "$line" | jq -r '.tokens // "-"')
    ag=$(echo "$line" | jq -r '.agent // "-"')
    summary=$(echo "$line" | jq -r '.summary // .type // "-"' | cut -c1-30)
    printf "%-26s %-12s %-8s %-14s %s\n" "$ts" "$st" "$tok" "$ag" "$summary"
    found=$((found + 1))
  done < "$activityFile"
fi

[ "$found" -eq 0 ] && echo "  No runs found in the last $days days."
```

### sub-issues

```bash
echo "SUB-ISSUES — $issue_id"
echo "────────────────────────────────────────────────────────"
printf "%-24s %-12s %-10s %s\n" "ID" "STATUS" "PRIORITY" "TITLE"
echo "────────────────────────────────────────────────────────"

count=0
jq -r --arg pid "$resolvedId" '(.issues // [])[] | select(.parentId == $pid) |
  [.id, (.status // "todo"), (.priority // "medium"), (.title // "(no title)")] | @tsv' \
  "$issuesFile" 2>/dev/null | while IFS=$'\t' read -r id st pri title; do
  printf "%-24s %-12s %-10s %s\n" "$id" "$st" "$pri" "$title"
  count=$((count + 1))
done

echo ""
echo "To create a sub-issue: /mastermind-issues --org $org_name --action create --title '<title>' --parent-id $issue_id"
```

### attachments

```bash
echo "ATTACHMENTS — $issue_id"
echo "────────────────────────────────────────────────────────"
atts=$(echo "$issueDef" | jq -r '(.attachments // [])[]' 2>/dev/null)
if [ -z "$atts" ]; then
  echo "  No attachments."
else
  echo "$issueDef" | jq -r '(.attachments // [])[] |
    "  [\(.type // "file")] \(.name // .path // "unnamed") — \(.size_bytes // "?") bytes — added \(.added_at // "?")"'
fi
```

### comment

```bash
[ -z "$comment_body" ] && { echo "ERROR: --comment-body required."; exit 1; }
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)

entry=$(jq -cn --arg iid "$resolvedId" --arg body "$comment_body" --arg ts "$ts" \
  '{"issue_id":$iid,"role":"user","type":"comment","body":$body,"ts":$ts}')
echo "$entry" >> "$threadFile"

echo "Comment added to issue '$issue_id'."
echo "  Body: $comment_body"
echo "  Time: $ts"
```

### assign

```bash
[ -z "$assignee_id" ] && { echo "ERROR: --assignee-id required."; exit 1; }

# Validate agent exists in org
exists=$(jq --arg id "$assignee_id" '[(.roles // [])[] | select(.id == $id)] | length' "$orgFile")
[ "$exists" -eq 0 ] && echo "WARNING: Agent '$assignee_id' not found in org '$org_name'. Assigning anyway."

ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
tmp="${issuesFile}.tmp"
jq --arg id "$resolvedId" --arg ag "$assignee_id" --arg ts "$ts" \
  '.issues = [(.issues // [])[] | if .id == $id then .assigneeId = $ag | .assigneeAgentId = $ag | .assigneeUserId = null | .updatedAt = $ts else . end]' \
  "$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"

echo "Issue '$issue_id' assigned to '$assignee_id'."

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

### close

```bash
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
tmp="${issuesFile}.tmp"
jq --arg id "$resolvedId" --arg ts "$ts" \
  '.issues = [(.issues // [])[] | if .id == $id then .status = "done" | .updatedAt = $ts | .closedAt = $ts else . end]' \
  "$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
echo "Issue '$issue_id' → done (closed at $ts)."

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

### reopen

```bash
ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
tmp="${issuesFile}.tmp"
jq --arg id "$resolvedId" --arg ts "$ts" \
  '.issues = [(.issues // [])[] | if .id == $id then .status = "todo" | .updatedAt = $ts | .closedAt = null else . end]' \
  "$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"
echo "Issue '$issue_id' → reopened."

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

### recover

```bash
[ -z "$recovery_action" ] && { echo "ERROR: --recovery-action required (accept|reject)."; exit 1; }
case "$recovery_action" in accept|reject) : ;; *)
  echo "ERROR: --recovery-action must be 'accept' or 'reject'."; exit 1 ;;
esac

ts=$(date -u +%Y-%m-%dT%H:%M:%SZ)
newStatus=$([ "$recovery_action" = "accept" ] && echo "in_progress" || echo "cancelled")

tmp="${issuesFile}.tmp"
jq --arg id "$resolvedId" --arg st "$newStatus" --arg ts "$ts" --arg ra "$recovery_action" \
  '.issues = [(.issues // [])[] | if .id == $id then
     .status = $st | .recoveryStatus = $ra | .updatedAt = $ts
   else . end]' \
  "$issuesFile" > "$tmp" && mv "$tmp" "$issuesFile"

echo "Recovery action '$recovery_action' applied to '$issue_id'."
echo "  New status: $newStatus"

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

---

## Step 3 — Return Output

```yaml
domain: ops
status: complete
action: <action>
org: <org_name>
issue_id: <issue_id>
issue_status: <status>
```

---

## Step 4 — Brain Write (standalone only)

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

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.