-
Validate N. Parse the positional argument. Reject if missing, non-integer, <= 0, or > 8 — ask the user rather than silently capping. Never default to a value the user did not provide.
-
Resolve the current GitHub user: USER=$(gh api user -q .login). Use that login as the assignee filter and never hardcode a username.
-
Fetch open curation issues assigned to the user.
gh issue list \
--assignee @me \
--state open \
--label curation \
--json number,title,assignees,body,createdAt \
--limit 100
The --label curation filter is what restricts to "new disease curation requests" — issues filed by /claim-disease carry the curation,enhancement labels and the title pattern Curate <label> (<MONDO_ID>). If a contributor opens curation issues with a different label, document it in this skill rather than relaxing the filter.
-
Filter to sole-assignee issues. Drop any issue whose assignees array has more than one entry. The user explicitly wants solo work — an issue assigned to both alice and bob is a team task, even if the current user is alice. Do this filter in jq, not by hand:
jq '[.[] | select((.assignees | length) == 1)]'
-
Filter out issues with an existing PR. For each remaining issue number ISSUE_NUM, check the authoritative GitHub linkage on the issue itself:
gh issue view "${ISSUE_NUM}" --json closedByPullRequestsReferences \
-q '.closedByPullRequestsReferences | length'
Skip the issue if the count is non-zero. A merged PR usually means the issue should already be closed, but stale links happen — be conservative.
Do NOT use gh pr list --search "closes #${ISSUE_NUM}" as a forward check. GitHub's free-text search matches the literal string #${ISSUE_NUM} anywhere in PR body or commits, including unrelated occurrences like ORPHA:${ISSUE_NUM}. This produced a false positive in production on issue #2704 (Orphanet ID ORPHA:2704 in PR #1992's body matched #2704). closedByPullRequestsReferences is structured GitHub linkage and avoids the trap.
If closedByPullRequestsReferences is rejected as an unknown field by the local gh version, upgrade gh rather than falling back to the lossy text search.
-
Sort and pick. Sort the survivors by number ascending (oldest issue first — that's the conventional FIFO for a curation queue) and take the first N. If fewer than N survive, do not pad — report the shortfall in the final report.
-
Extract the disease label and MONDO ID from each title. Issue titles follow Curate <label> (<MONDO_ID>). Parse with a regex; if a title does not match (e.g. an old hand-filed issue), skip it and note it in the final report rather than passing a garbled label to /curate.
-
Run duplicate preflight for each picked issue. Before dispatch, verify the
disease is still absent from the latest upstream KB and is not already
covered by another PR or issue:
git fetch origin main
git grep -n -i -e "<MONDO_ID>" -e "<label>" origin/main -- kb/disorders || true
gh pr list --repo monarch-initiative/dismech --state all \
--search "\"<MONDO_ID>\" OR \"<label>\"" \
--json number,title,state,url,headRefName --limit 100
gh issue list --repo monarch-initiative/dismech --state all \
--search "\"<MONDO_ID>\" OR \"<label>\"" \
--json number,title,state,url,labels --limit 100
The current issue itself is expected in the issue search results. Skip the
candidate if the KB, another PR, or another issue already covers the same
disorder, and report the skip.
-
Dispatch /curate in parallel. In a single message, launch N Agent tool calls — one per disease — using subagent_type: general-purpose so each agent has full tool access (Tools: *). claude works too on harnesses that register it as a catch-all type, but general-purpose is the canonical name across harnesses; prefer it for portability. Each agent's prompt MUST:
-
State the disease label and MONDO ID verbatim.
-
State that the duplicate preflight against latest KB, all PRs, and all
issues has already been performed, and tell the agent to repeat it before
writing files if its worktree is created later from stale refs.
-
Quote any deep-research provider hints from the issue body (e.g. "using falcon", "using deep-research"). Default to falcon when none are mentioned.
-
Reference the GitHub issue number so the agent links the resulting PR back to it.
-
Instruct the agent to consult the initiate-new-disorder-creation skill for the full curation workflow (this is what /curate does — sub-agents cannot invoke slash commands directly, so this skill must be named in the prompt).
-
For CURATE_ROOT_WITH_SUBTYPES issues, note that subtypes should be modelled with has_subtypes.
-
MUST tell the agent to create a git worktree of its own and cd into it, then root every Read/Edit/Write/Bash file operation in the worktree's path — never in the parent checkout's path. Never give the agent the parent checkout's absolute path as its working directory. In a real production incident, two of three agents took an absolute parent path from the prompt (/Users/.../dismech-1) and wrote kb/disorders/<disease>.yaml plus dozens of references_cache/*.md files into the parent checkout instead of their own worktree — branches were left empty and recovery required surgery. The agent prompt should include something like:
Create your own git worktree (use the `superpowers:using-git-worktrees` skill) on a fresh branch off `origin/main`, then `cd` into that worktree. After `cd`, run `pwd` and confirm the printed path is the worktree's path and is NOT the parent checkout's path BEFORE any file write. For Read/Edit/Write tool calls (which require absolute paths), use absolute paths rooted in the worktree — never an absolute path that contains the parent checkout's location. For Bash calls, prefer relative paths after `cd`-ing into the worktree. Commit and push from inside the worktree.
Dispatching all N in one message is the whole point — sequential dispatch defeats the skill. See superpowers:dispatching-parallel-agents if you need a refresher on parallel sub-agent semantics. Run the agents in the background (run_in_background: true) so the orchestrator regains control immediately and can report; you will be notified as each finishes.
After every agent finishes (or stalls), verify each branch has at least one commit: git log origin/main..<branch> --oneline. If empty, the agent's work is likely uncommitted in its worktree's working tree — or worse, leaked into the parent checkout. Check git status in the parent before dispatching another batch.
-
Report. After all agents finish, list: