From spade
Onboard a project into the SPADE framework. Creates AGENTS.md, CLAUDE.md, architecture templates, and example files if they don't exist, then analyses the codebase to fill in architecture docs. Use when someone says "onboard this project", "set up SPADE", "spade init", or when starting SPADE in a new repo. Also use when architecture docs are still templates with placeholder comments.
How this skill is triggered — by the user, by Claude, or both
Slash command
/spade:spade-onboardThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Before doing anything else, run `~/.spade/bin/spade-update-check` using the
Before doing anything else, run ~/.spade/bin/spade-update-check using the
Bash tool and show the output to the user if it is non-empty. If the script
does not exist or fails, skip silently and continue with the skill.
You are onboarding a project into the SPADE framework. Your job is twofold:
Before anything else, check whether the current working directory is the SPADE framework repository itself:
if { [ -f ".claude/skills/spade-onboard/SKILL.md" ] || [ -f "skills/spade-onboard/SKILL.md" ]; } && [ -f "fragments/AGENTS-section.md" ]; then
echo "This looks like the SPADE framework repository."
echo "Refusing to self-onboard — the framework's own AGENTS.md / CLAUDE.md"
echo "are the canonical source, not fragment-wrapped copies."
exit 0
fi
If the guard triggers, stop and tell the human:
This is the SPADE framework repo itself — no onboarding needed. Its
AGENTS.md,CLAUDE.md, and architecture docs are already the source of truth. If you wanted to onboard a different project,cdinto it and run/spade-onboardthere.
Do not proceed to the steps below when in the framework repo.
Once the self-onboard guard has passed, initialise or update framework files
using the marker-replace contract implemented by
~/.spade/bin/spade-marker-replace:
spade-marker-replace TARGET_FILE FRAGMENT_FILE VERSION
The contract is deterministic and idempotent:
| Target state | Outcome |
|---|---|
| Target file absent | Create with START (vVERSION) + fragment + END |
| Target exists, no markers | Append blank line, then START + fragment + END; preserve existing text |
Target has one matching vX.Y.Z marker pair | Replace block in place, re-stamping START to vVERSION |
| Target has mismatched markers (START != END) | Exit 2, no modification |
| Target has multiple START/END pairs | Exit 3, no modification (human must resolve) |
Running twice with the same inputs produces an unchanged file on the
second run. This is the property onboarding relies on — re-running
/spade-onboard must not drift the consumer repo.
Call the helper to insert or refresh the SPADE section:
~/.spade/bin/spade-marker-replace \
"$PWD/AGENTS.md" \
~/.spade/fragments/AGENTS-section.md \
1.7.0
If the helper exits with code 2 (mismatched markers), stop and show the human the error message. Do NOT try to "fix" the target file automatically — malformed markers usually signal hand-editing the human should review.
If it exits with code 3 (duplicate markers), same behaviour — refuse, report, ask the human to collapse the blocks by hand before re-running.
Same pattern, using the CLAUDE fragment:
~/.spade/bin/spade-marker-replace \
"$PWD/CLAUDE.md" \
~/.spade/fragments/CLAUDE-section.md \
1.7.0
For each of these files, create them only if they don't exist. Read the
template from ~/.spade/ and copy it:
ARCHITECTURE.md (from ~/.spade/ARCHITECTURE.md)PATTERNS.md (from ~/.spade/PATTERNS.md)ANTI-PATTERNS.md (from ~/.spade/ANTI-PATTERNS.md)If any of these already exist, decide whether to prompt the human
deterministically by detecting unfilled template markers. The
framework templates use HTML comments of the shape
<!-- Describe ... -->, <!-- List ... -->, <!-- Example: ... -->,
or <!-- Add ... --> to mark sections the consumer is meant to
fill in. A real filled-in document has zero such markers (the comment
prompt has been replaced with project-specific prose).
Detection mechanism:
# Case-insensitive match for the four canonical template marker
# openings. Two or more matches in a single file = still a template.
grep -ciE '<!--[[:space:]]*(Describe|List|Example:|Add)[[:space:]]' "$f"
If the count is ≥ 2, treat the file as still a template and
prompt the human via AskUserQuestion (per docs/FRAMEWORK.md
§ "Asking the Human") with options:
If the count is 0 or 1, leave the file untouched — the consumer already has real project-specific content and the prompt would be noise. (The "1 match" tolerance covers a stray HTML comment in otherwise-filled-in prose.)
Open-ended steps later in this skill (architecture-conflict resolution, free-form pattern descriptions) stay free-form per the convention's exception clause — only the overwrite/merge/skip decision is structured.
Create INTENT.md at the repository root only if it does not already
exist, by copying the distributable template:
[ -f "$PWD/INTENT.md" ] || cp ~/.spade/templates/INTENT.md "$PWD/INTENT.md"
INTENT.md is the project's durable statement of intent — the problem it
solves, who it serves, what it does, what success looks like, and its
non-goals. It is a root reference document, peer to ARCHITECTURE.md.
Do not AI-fill INTENT.md. This is a deliberate exception to the
fill-in pattern used for the architecture docs in Steps 3–5. Project intent
is the most human-owned artefact in SPADE — only a human can author it.
Onboarding's job is to scaffold the template and hand off; the human fills
it in with the /spade-intent skill.
After scaffolding — or if INTENT.md already exists but is still an
unfilled template — tell the human:
INTENT.mdhas been scaffolded. Run/spade-intentto fill it in — it walks you through the project's problem, users, what it does, success, non-goals, and maturity. The SPADE loop readsINTENT.mdto keep Scopes aligned with the project's purpose.
If INTENT.md already exists and is filled in, leave it untouched — the
same create-if-absent rule as the architecture templates.
Create .spade/config if it doesn't exist. This file tells all SPADE skills
which Linear team and project to target. If Linear MCP is available, help
the human fill it in interactively:
list_teams to show available teams. Ask which one.list_projects to show projects for that team. Ask which one.Write the config file as YAML, using the same nested shape this repo's
own .spade/config uses:
# SPADE per-repo configuration.
# Read by SPADE skills to avoid prompting for team/project on every invocation.
linear:
team: M-KOPA
team_id: 55069140-fef8-4f1a-8d04-726227e0292b
project: Argus
project_id: <uuid from list_projects>
default_assignee: me
team_id and project_id are optional but recommended — capturing them
during onboarding saves a list_* round-trip on every future skill
invocation.
If Linear MCP is not available, create the file with placeholder values
(omit the *_id fields) and tell the human to fill it in manually.
All SPADE skills that interact with Linear MUST read .spade/config first
to determine the team, project, and assignee. Do not prompt for these values
if the config file exists and is populated.
/spade-handoff spawns a fresh CLI agent in a new terminal window to
deliver an approved Plan. It is opt-in — dormant until a handoff:
block exists in .spade/config. Offer it; do not assume it.
Ask the human via AskUserQuestion whether to set up handoff now:
/spade-handoffIf they skip, do nothing: /spade-handoff stays dormant and a consumer
who never opts in is unaffected.
If they opt in, ask two structured questions (AskUserQuestion):
Then add the handoff: block to .spade/config only if no handoff:
key is already present — re-running /spade-onboard must not duplicate
or overwrite an existing block (the same idempotency rule the
marker-replace contract enforces for AGENTS.md / CLAUDE.md). Use this
shape, setting agent and autonomous from the answers above:
handoff:
agent: claude # which agent to spawn: claude | amp
autonomous: false # false = spawned agent runs interactively;
# true = add the agent's skip-permission flag
# and confirm on every run
agents:
claude:
command: ["claude", "--permission-mode", "acceptEdits"]
prompt_via: arg
autonomous_flag: "--dangerously-skip-permissions"
amp:
command: ["amp"]
prompt_via: stdin
autonomous_flag: "--dangerously-allow-all"
The agents: map is the per-agent command contract: command is the
argv the launcher runs, prompt_via is how the handoff prompt reaches
the agent (arg = a single trailing argv element; stdin = piped), and
autonomous_flag is appended only when an autonomous handoff is
confirmed. If a CLI flag changes, edit it here — no skill or script
change is needed.
Terminal choice is machine-specific and must never be committed. Ask
the human (AskUserQuestion: iTerm2 / Terminal.app) and write it to
.spade/handoff.local:
terminal: iterm # iterm | terminal
Ensure .spade/handoff.local appears in .gitignore — add the line if
absent (idempotent; do not duplicate it).
/spade-handoff itself is documented in docs/FRAMEWORK.md § Handoff.
Before any tracker call or local-file access, resolve the operating mode
once per docs/FRAMEWORK.md § Mode Resolver:
mode: from .spade/config. An explicit value (linear,
local, or hybrid) wins immediately.mode: is absent, auto-detect: probe with a list_teams MCP call
(try/skip, 5-second timeout). Resolve linear if it returns a team
set containing linear.team_id; otherwise resolve local.mode with a configured team_id and a
failing probe is a fail-loud abort; an absent mode with a
failing probe degrades quietly to local.Do not embed the resolver algorithm — it is single-sourced in FRAMEWORK.md.
Onboarding MUST scaffold the local artefact layout so that local and
hybrid modes have somewhere to write. Create these directories if they
do not already exist — this is idempotent, never error when a
directory is already present:
.spade/scopes/.spade/plans/.spade/learnings/Then write a starter .spade/config that includes an explicit mode:
line. The mode value is chosen once, at onboard time — it is not
re-derived on every skill run:
list_teams
try/skip with a 5-second timeout).AskUserQuestion (per
docs/FRAMEWORK.md § "Asking the Human") with options linear,
local, and hybrid. Use the probe result as the recommended
default — linear when the probe succeeds, local when it does
not..spade/config as the mode: line. In
linear or hybrid mode, also write the linear: block (§ Project
Config above); capturing team_id/project_id via list_teams /
list_projects is the only tracker call onboarding makes, and it
runs after the mode is known. In local mode, write only
mode: local and make no tracker calls.Because the choice is persisted, later skill runs read mode: directly
and never re-probe. The onboard summary output (see § Report What Was
Done) MUST state the chosen mode.
.spade/examples/ if it doesn't exist and copy example files from
~/.spade/examples/.spade/docs/ and copy docs from ~/.spade/docs/.spade/version with install metadataAfter initialisation, tell the human what was created and what was skipped. The summary MUST state the operating mode chosen during local-layout provisioning:
SPADE project files:
✓ AGENTS.md created
✓ CLAUDE.md created
✓ ARCHITECTURE.md created (template)
✓ INTENT.md created (template — fill with /spade-intent)
! PATTERNS.md already exists, skipped
✓ .spade/scopes/ .spade/plans/ .spade/learnings/ created
✓ .spade/examples/ created
✓ .spade/config written — mode: linear
If all files already existed, say so and move straight to the analysis step.
Before asking the human anything, explore the project:
Summarise what you have found and present it to the human for validation:
Cover:
Based on the validated understanding, generate the content for ARCHITECTURE.md. Follow the template structure already in the file, but replace all placeholder comments with real content.
Present each section to the human for approval before moving to the next. They know things about the system that code analysis cannot reveal (planned migrations, deprecated components, infrastructure not visible in the repo).
Document the coding patterns, conventions, and approved libraries visible in the codebase. Focus on:
Ask the human: "Are there patterns you want to enforce that are not yet consistently applied? These are also worth documenting."
This requires the most human input because anti-patterns often come from painful experience rather than code analysis. Ask the human directly:
Document each anti-pattern with a clear rationale. The rationale matters because it helps AI agents understand why the constraint exists, not just that it exists.
After all three documents are filled in:
git add AGENTS.md CLAUDE.md ARCHITECTURE.md PATTERNS.md ANTI-PATTERNS.md .claude/ .spade/
git commit -m "Onboard project with SPADE framework"
Remind them: "These documents are living. Update them as your architecture evolves. The better the context, the better the AI-generated Plans."
Also remind them: "Once these files are committed, teammates who clone
this repo will have SPADE working automatically — they just need the
global skills install (~/.spade/setup)."
The quality of AI-generated Plans is directly proportional to the quality of the architecture context. A blank ARCHITECTURE.md means the AI will guess. A detailed one means the AI will propose solutions that fit your world. This onboarding step is the single highest-leverage thing you can do to make SPADE work well.
Before finishing, verify:
/spade-intent's job; the human composes project intent)Also help the human set up the Linear integration:
.spade/config are correctThe onboarding is complete when:
npx claudepluginhub chrisfmlyc/spades --plugin spades-anywhereGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.