| name | swain-doctor |
| description | Auto-invoked at session start when swain-preflight detects issues. Also user-invocable for on-demand health checks. Validates project health: governance rules, tool availability, memory directory, settings files, script permissions, .agents directory, and .tickets/ validation. Auto-migrates stale .beads/ directories to .tickets/ and removes them. Remediates issues across all swain skills. Idempotent — safe to run any time. |
| user-invocable | true |
| license | MIT |
| allowed-tools | Bash, Read, Write, Edit, Grep, Glob |
| metadata | {"short-description":"Session-start health checks and repair","version":"2.5.0","author":"cristos","source":"swain"} |
Doctor
Session-start health checks for swain projects. Validates and repairs health across all swain skills — governance, tools, directories, settings, scripts, caches, and runtime state. Auto-migrates stale .beads/ directories to .tickets/ and removes them. Idempotent — run it every session; it only writes when repairs are needed.
Run checks in the order listed below. Collect all findings into a summary table at the end.
Preflight integration
A lightweight shell script (swain-preflight.sh, located via find "$REPO_ROOT" -path '*/swain-doctor/scripts/swain-preflight.sh') performs quick checks before invoking the full doctor. If preflight exits 0, swain-doctor is skipped for the session. If it exits 1, swain-doctor runs normally.
The preflight checks are a subset of this skill's checks — governance files, .agents directory, .tickets health, script permissions. It runs as pure bash with zero agent tokens. See AGENTS.md § Session startup for the invocation flow.
When invoked directly by the user (not via the auto-invoke flow), swain-doctor always runs regardless of preflight status.
Session-start governance check
-
Detect the agent platform and locate the context file:
| Platform | Context file | Detection |
|---|
| Claude Code | CLAUDE.md (project root) | Default — use if no other platform detected |
| Cursor | .cursor/rules/swain-governance.mdc | .cursor/ directory exists |
-
Check whether governance rules are already present:
grep -l "swain governance" CLAUDE.md AGENTS.md .cursor/rules/swain-governance.mdc 2>/dev/null
If any file matches, governance is installed. Check freshness (step 3), then proceed to Legacy skill cleanup.
-
If governance markers found, check freshness:
Extract the block between <!-- swain governance and <!-- end swain governance --> from the installed context file. Compare against the canonical source at skills/swain-doctor/references/AGENTS.content.md (same extraction, excluding marker lines).
extract_gov() { awk '/<!-- swain governance/{f=1;next}/<!-- end swain governance/{f=0}f' "$1"; }
INSTALLED_HASH=$(extract_gov "$GOV_FILE" | shasum -a 256 | cut -d' ' -f1)
CANONICAL_HASH=$(extract_gov "skills/swain-doctor/references/AGENTS.content.md" | shasum -a 256 | cut -d' ' -f1)
-
If no marker match in step 2 (governance missing), run Legacy skill cleanup, then proceed to Governance injection.
Legacy skill cleanup
Clean up renamed and retired skill directories using fingerprint checks. Read references/legacy-cleanup.md for the full procedure. Data source: skills/swain-doctor/references/legacy-skills.json.
Platform dotfolder cleanup
Remove dotfolder stubs (.windsurf/, .cursor/, etc.) for agent platforms that are not installed. Read references/platform-cleanup.md for the detection and cleanup procedure. Requires jq.
Governance injection
Inject governance rules into the platform context file when missing. Read references/governance-injection.md for Claude Code and Cursor injection procedures. Source: skills/swain-doctor/references/AGENTS.content.md.
Governance replacement
Replace a stale governance block with the current canonical version. Read references/governance-injection.md § Stale governance replacement for the replacement procedure. This runs when freshness check (step 3) detects a hash mismatch.
Tickets directory validation
Validates .tickets/ health — YAML frontmatter, stale locks. Skip if .tickets/ does not exist. Read references/tickets-validation.md for the full procedure.
Stale .beads/ migration and cleanup
Auto-migrates .beads/ → .tickets/ if present. Skip if .beads/ does not exist. Read references/beads-migration.md for the migration procedure.
Governance content reference
The canonical governance rules live in skills/swain-doctor/references/AGENTS.content.md. Both swain-doctor and swain-init read from this single source of truth. If the upstream rules change in a future swain release, update that file and bump the skill version. The freshness check (step 3 of the governance check) will automatically detect the mismatch and offer replacement on the next session.
Tool availability
Check required (git, jq) and optional (tk, uv, gh, tmux, fswatch) tools. Never install automatically. Read references/tool-availability.md for the check commands, degradation notes, and reporting format.
Runtime checks
Memory directory, settings validation, script permissions, .agents directory, status cache bootstrap, and SSH alias readiness. Read references/runtime-checks.md for the full procedures and bash commands.
tk health (extended .tickets checks)
Verify vendored tk is executable at skills/swain-do/bin/tk and check for stale lock files. Skip if .tickets/ does not exist. See references/tickets-validation.md for details.
swain-box symlink
Ensure ./swain-box exists as a symlink to the installed swain-box script so operators can launch Docker Sandboxes from the project root. The script is distributed inside the swain skill tree at */swain/scripts/swain-box. Skip if the script cannot be found.
Detection
SWAIN_BOX_SCRIPT=$(find . .claude .agents -path '*/swain/scripts/swain-box' -print -quit 2>/dev/null)
if [ -n "$SWAIN_BOX_SCRIPT" ]; then
SWAIN_BOX_REL=$(python3 -c "import os,sys; print(os.path.relpath(sys.argv[1]))" "$SWAIN_BOX_SCRIPT" 2>/dev/null || echo "$SWAIN_BOX_SCRIPT")
if [ -L swain-box ] && [ "$(readlink swain-box)" = "$SWAIN_BOX_REL" ]; then
echo "ok"
elif [ -e swain-box ] && [ ! -L swain-box ]; then
echo "conflict"
else
echo "missing"
fi
fi
Remediation
Status values
- ok — symlink present and correct
- repaired — symlink created
- warning — conflict (real file); manual action needed
Lifecycle directory migration
Detect old phase directories from before ADR-003's three-track normalization. Read references/lifecycle-migration.md for detection commands, remediation steps, and status values.
Superpowers detection
Check whether superpowers skills are installed:
SUPERPOWERS_SKILLS="brainstorming writing-plans test-driven-development verification-before-completion subagent-driven-development executing-plans"
found=0
missing=0
missing_names=""
for skill in $SUPERPOWERS_SKILLS; do
if ls .agents/skills/$skill/SKILL.md .claude/skills/$skill/SKILL.md 2>/dev/null | head -1 | grep -q .; then
found=$((found + 1))
else
missing=$((missing + 1))
missing_names="$missing_names $skill"
fi
done
Status values and response
- ok — all superpowers skills detected. No output.
- partial — some skills present, some missing. List the missing ones, then prompt (see below). A partial install may indicate a failed update — note this in the prompt.
- missing — no superpowers skills found. Prompt the user.
When status is missing or partial, ask:
Superpowers (obra/superpowers) is not installed [or: partially installed — N of 6 skills missing]. It provides TDD, brainstorming, plan writing, and verification skills that swain chains into during implementation and design work.
Install superpowers now? (yes/no)
If the user says yes:
npx skills add obra/superpowers
Report success or failure. On success, update status to ok.
If the user says no, note "Superpowers: skipped" and continue. They can install later: npx skills add obra/superpowers.
Superpowers is strongly recommended but not required. Declining is always allowed.
Stale worktree detection
Enumerate all linked worktrees and classify their health. Skip if the repo has no linked worktrees. Read references/worktree-detection.md for the detection commands, classification rules, and status values.
Epics without parent-initiative (migration advisory)
This is a non-blocking advisory check. It does not gate any other checks.
Detection
grep -rl "parent-vision:" docs/epic/ 2>/dev/null | while read f; do
if ! grep -q "parent-initiative:" "$f"; then
echo "$f"
fi
done
Response
If any EPICs are found without parent-initiative:
Advisory: N Epic(s) have a parent-vision but no parent-initiative. The INITIATIVE artifact type is now available as a mid-level container between Vision and Epic. Adding parent-initiative links is optional but recommended for projects using prioritization features (specgraph recommend, specgraph decision-debt).
To add the link, edit each Epic's frontmatter and add:
parent-initiative: INITIATIVE-NNN
This check is informational — no action required. To run the guided migration, ask: "how do I fix the initiative migration?" or "run the initiative migration".
Guided migration workflow
Read references/initiative-migration.md for the full 6-step guided migration workflow (scan, cluster, create initiatives, re-parent, set weights, verify).
Status values
- ok — all Active EPICs already have
parent-initiative, or no EPICs exist
- advisory — one or more Active EPICs lack
parent-initiative (non-blocking)
Evidence Pool → Trove Migration
Detect unmigrated evidence pools:
- If
docs/evidence-pools/ exists: warn and offer to run migration
- If any artifact frontmatter contains
evidence-pool:: warn and offer migration
- If both
docs/troves/ and docs/evidence-pools/ exist: warn about incomplete migration
Migration script: bash "$(find "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" -path '*/swain-search/scripts/migrate-to-troves.sh' -print -quit 2>/dev/null)"
Dry run first: bash "$(find "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" -path '*/swain-search/scripts/migrate-to-troves.sh' -print -quit 2>/dev/null)" --dry-run
Summary report
After all checks complete, output a concise summary table:
swain-doctor summary:
Governance ......... ok
Legacy cleanup ..... ok (nothing to clean)
Platform dotfolders ok (nothing to clean)
.tickets/ .......... ok
Stale .beads/ ...... ok (not present)
Tools .............. ok (1 optional missing: fswatch)
Memory directory ... ok
Settings ........... ok
Script permissions . ok
.agents directory .. ok
Status cache ....... seeded
tk health .......... ok
Lifecycle dirs ..... ok
Epics w/o initiative advisory (3 epics — see note below)
Worktrees .......... ok
Superpowers ........ ok (6/6 skills detected)
3 checks performed repairs. 0 issues remain.
Use these status values:
- ok — nothing to do
- repaired — issue found and fixed automatically
- warning — issue found, user action recommended (give specifics)
- skipped — check could not run (e.g., jq missing for JSON validation)
If any checks have warnings, list them below the table with remediation steps.