| name | soa |
| description | Son-of-Anton canonical entrypoint. Use for /soa plan, /soa decompose, /soa execute, /soa resume, /soa preflight, /soa triage-ticket, /soa triage-standalone, /soa triage-advisory-observations (/soa tao), /soa quality-control (/soa qc), /soa install, /soa update, /soa closeout, and /soa ideate. Manages installation, updates, quality control, and the full delivery lifecycle. |
Son-of-Anton Skill
Manages son-of-anton installation, updates, and the full delivery lifecycle.
Public slash-command entrypoint: /soa.
Commands
Dispatch on the first word of $ARGUMENTS.
install
Trigger: /soa install
Add son-of-anton to the current repo for the first time:
git subtree add --prefix .son-of-anton https://github.com/cesarnml/son-of-anton.git main --squash
bash .son-of-anton/scripts/soa-sync.sh
If .son-of-anton already exists, tell the user to use update instead.
soa-sync.sh wires the Claude Code adapter as /soa plus soa-* helper
skills. The prefixed helper names are intentional so existing user skills named
grill-me, pr-review, enter-worktree, etc. are not shadowed.
update
Trigger: /soa update
Pull the latest changes from son-of-anton in consumer repos, then re-sync
skill symlinks.
If .son-of-anton/scripts/soa-update.sh exists, run:
bash .son-of-anton/scripts/soa-update.sh
Otherwise run the manual recipe (legacy consumers before this script shipped):
git fetch https://github.com/cesarnml/son-of-anton.git main
UPSTREAM_SHA="$(git rev-parse FETCH_HEAD)"
git subtree merge --prefix .son-of-anton "$UPSTREAM_SHA" --squash
bash .son-of-anton/scripts/soa-sync.sh
UPSTREAM_HASH="$(git show "$UPSTREAM_SHA":docs/template/delivery/adversarial-review-template.md | git hash-object --stdin)"
LOCAL_HASH="$(git hash-object .son-of-anton/docs/template/delivery/adversarial-review-template.md)"
test "$UPSTREAM_HASH" = "$LOCAL_HASH"
Fetch upstream first, capture UPSTREAM_SHA, and merge that commit — not plain
main (which can resolve through the consumer repo's local branch history) and
not bare FETCH_HEAD after later git commands may have moved it.
Path mapping for verification: upstream files live at docs/... in the
Son-of-Anton repo; in consumer repos the same content is at
.son-of-anton/docs/....
Those hashes must match. If they do not, report the update as failed and do not
claim the repo is current.
Report what changed. If already up to date, say so.
The sync step is required after every update. It refreshes /soa and removes
stale soa-* helper symlinks before relinking the current helper set.
ideate
Trigger: /soa ideate [topic]
Optional. Use when developer intention is too half-formed to yield a concrete plan directly. Skip this and go straight to /soa plan when the idea is already clear or comes from a retrospective follow-up.
Turn a developer ideation storm into a draft phase plan that feeds /soa plan.
- Ask the developer open-ended questions to surface goals, constraints, and unknowns. Be relentless — this is the
soa-grill-me stage for ideas, not plans.
- Synthesize the conversation into a concise draft phase summary (title, goal, proposed scope, open questions).
- Stop and seek developer approval of the summary before writing any files.
- Once approved, write the draft to
docs/product/drafts/<slug>.md.
The next step is /soa plan docs/product/drafts/<slug>.md.
plan
Trigger: /soa plan [path-to-plan or inline description], optionally prefixed /soa plan phase-NN: issue #<N> <rest of description> when the phase originates from an open GitHub issue.
Output: docs/product/plans/phase-N.md only — the "what" and "why". No tickets. No implementation details.
Accepts a concrete idea (inline description), a draft from /soa ideate (docs/product/drafts/<slug>.md), or any existing rough plan. Runs an soa-grill-me session scoped to product-level decisions: goals, success criteria, scope, explicit deferrals, and dependencies. The session ends when docs/product/plans/phase-N.md is written and approved.
- Read the plan if a file path is given. Otherwise use the inline description.
- Parse an origin issue only from the explicit
issue #<N> form in the trigger itself. Do not infer one from prose elsewhere in the description or draft — this is an explicit opt-in, not a guess. If present, fetch/confirm the issue is open before proceeding.
- Invoke the
soa-grill-me skill in Mode 1 (product plan) — pass the plan content and instruct it to stay at the product level (scope, goals, success criteria, deferrals, risks). Explicitly tell it: no schema design, no API routes, no ticket breakdown.
- After
soa-grill-me closes, write docs/product/plans/phase-N.md using the product-plan template at .son-of-anton/docs/template/stubs/product-plan.template.md. If an origin issue was parsed in step 2, record it as Origin issue: #<N> in the template's dedicated field — this is the only field /soa decompose will trust for linking later. Do not write this field otherwise.
- Hard stop. Ask the developer to approve the product plan. Do not proceed to tickets.
The next step after approval is /soa decompose docs/product/plans/phase-N.md.
decompose (alias: decomp, tickets)
Trigger: /soa decompose [path] or /soa decomp or /soa tickets
Output: docs/product/delivery/phase-N/implementation-plan.md + ticket files — the "how". Requires an approved product plan as input.
Take the approved docs/product/plans/phase-N.md and produce a detailed delivery plan with exact ticket decomposition.
-
Read the product plan at the given path (or ask for it). Refuse to proceed if no approved product plan exists — send the developer to /soa plan first.
-
Check the product plan's Origin issue: field. This is the only source for an origin issue — do not infer one from ticket content, commit messages, or your own reading of the phase. If the field is absent, this phase has no origin issue and step 5 skips the Origin issue line entirely.
-
Invoke the soa-grill-me skill in Mode 2 (delivery decomposition) — pass the product plan and focus on: schema/migration strategy, API route structure, ticket granularity, PR slice boundaries, dependency order, test strategy, exit conditions per ticket.
-
Stop and seek developer approval of the ticket list before writing files.
-
Before writing any ticket file, read the canonical template at docs/template/stubs/ticket.template.md. Do not use existing ticket files as format references — they may predate the current template and will produce format drift if copied. Then write docs/product/delivery/phase-N/implementation-plan.md and individual ticket-NN-*.md files per that template. Only after the developer approves the ticket list in step 4, if the product plan carried an Origin issue: field, record it in implementation-plan.md's ## Epic section as Origin issue: #<N> exactly — the orchestrator parses that literal format and appends Closes #<N> to the phase's final ticket's PR body only, since the issue isn't resolved until that last stacked PR lands on the closeout branch.
-
After files are written and developer approves, surface this prompt:
Files written. Run /soa preflight phase-N to verify template compliance before starting execution.
preflight
Trigger: /soa preflight <phase-N>
Template-compliance gate between decompose and execute. Reads implementation-plan.md and all ticket files for the named phase and checks them against the canonical stubs in docs/template/stubs/. Reports a structured PASS/FAIL checklist. Must PASS before /soa execute is invoked.
Invoke the soa-preflight skill — pass the phase name and the path to the delivery directory.
Do not proceed to /soa execute if preflight reports any failures. List all issues and ask the developer to fix them first.
execute
Trigger: /soa execute <phase-XX|epic-XX>
Begin orchestrated delivery of the named phase or epic.
Read these files before doing anything else — they are gospel:
.son-of-anton/docs/template/overview/start-here.md
.son-of-anton/docs/template/delivery/delivery-orchestrator.md (read in full)
.son-of-anton/docs/template/delivery/son-of-anton.md
.son-of-anton/orchestrator.config.json
Then:
- Locate the
implementation-plan.md for the named phase/epic.
- Identify the first unstarted ticket.
- Execute via the orchestrator path — do not ad-hoc implement.
- Valid stopping points are defined in
delivery-orchestrator.md and orchestrator.config.json. Respect them.
- At each stopping point, surface the canonical resume prompt so the developer can continue with
/soa resume.
resume
Trigger: /soa resume <phase-XX|epic-XX>
Resume delivery after a stopping point.
- Read
.son-of-anton/docs/template/delivery/delivery-orchestrator.md in full and orchestrator.config.json.
- Check
state.json for the last recorded position, or run git worktree list to identify active worktrees.
- Read the handoff notes from the last stopping point.
- Continue from exactly where delivery left off — do not restart, do not re-plan.
- Stick to the orchestrator path as configured.
triage-ticket
Trigger: /soa triage-ticket PR#<number>
Reconcile late external AI review comments on a done ticket-linked phase PR.
This command is only for PRs that belong to an already-delivered ticket in a
phase/epic stack. For standalone PRs, use /soa triage-standalone PR#<number>.
- Parse the PR number from
PR#<number>, #<number>, or <number>. Ask for a
PR number if it is missing or ambiguous.
- Read
.son-of-anton/docs/template/delivery/delivery-orchestrator.md in full
when running in a consumer repo; in the Son-of-Anton source repo, read
docs/template/delivery/delivery-orchestrator.md.
- Locate delivery state by searching
.agents/delivery/*/state.json in the
current checkout and known git worktree list entries for tickets whose
prNumber matches the PR number.
- Refuse to continue unless the matches resolve to exactly one ticket identity
(
planPath + ticket id) and that ticket's status is done. Ignore duplicate
mirrored state files only when they agree on that identity and status. If the
PR is standalone, unknown to delivery state, matched by conflicting states,
or attached to a non-done ticket, stop and explain the correct command or
missing state.
- Run from the matched ticket's recorded
worktreePath when available; if the
orchestrator emits a worktree-guard recovery command, follow it exactly:
bun run deliver --plan <state.planPath> triage-ticket <ticket-id>
- Apply the
soa-pr-review stance to any findings: patch only prudent
actionable issues, push fixes, resolve native inline threads that are
patched/already-outdated/rejected when resolvable, and let the orchestrator
refresh the PR body best-effort.
triage-standalone
Trigger: /soa triage-standalone PR#<number>
Run the standalone PR external AI review triage path for a non-ticketed PR.
This command is only for standalone PRs. For done ticket-linked phase PRs, use
/soa triage-ticket PR#<number> so delivery state and review artifacts remain
authoritative.
- Parse the PR number from
PR#<number>, #<number>, or <number>. Ask for a
PR number if it is missing or ambiguous.
- Read
.son-of-anton/docs/template/delivery/delivery-orchestrator.md in full
when running in a consumer repo; in the Son-of-Anton source repo, read
docs/template/delivery/delivery-orchestrator.md.
- If
.agents/delivery/*/state.json contains a ticket with this prNumber,
stop and direct the operator to /soa triage-ticket PR#<number> instead.
- Surface that standalone triage uses real wall-clock polling, then run:
bun run deliver triage-standalone --pr <number>
- Apply the
soa-pr-review stance to any findings: patch only prudent
actionable issues, push fixes, resolve native inline threads that are
patched/already-outdated/rejected when resolvable, and let the standalone
review flow refresh the PR body best-effort.
triage-advisory-observations (alias: tao)
Trigger: /soa triage-advisory-observations <phase-XX|epic-XX> or /soa tao <phase-XX|epic-XX>
Run the post-phase advisory-observation triage lane after the stacked phase has
landed on the configured closeoutBranch and before the next phase starts. This
is for non-blocking Advisory Observations from subagent-review reports. It is
not a per-ticket pre-PR gate and it must not apply patches automatically.
- Parse the phase or epic target and locate its
implementation-plan.md.
- Read
docs/template/delivery/delivery-orchestrator.md in the source repo
(or .son-of-anton/docs/template/delivery/delivery-orchestrator.md in a
consumer repo) before running commands.
- Resolve or create an explicit dispositions input file for every parsed
advisory observation. Do not guess dispositions from report prose.
- Run the underlying command from the checkout where the phase delivery state
is authoritative:
bun run deliver --plan <plan-path> triage-advisory-observations --dispositions <path>
- Report the written triage artifact path and any warnings about untriaged
observations or suspicious report evidence. Keep
Actionable findings
separate: they remain the blocking reconciliation lane and are not part of
advisory-observation disposition.
quality-control (alias: qc)
Trigger: /soa quality-control phase-NN: <description> or /soa qc phase-NN: <description>.
phase-unknown is accepted in place of phase-NN when the operator can't name
the originating phase up front — the soa-quality-control skill resolves it
via investigation and operator confirmation before recording.
Run the post-phase quality control lane for a small, verified fix that should
create one review-gap ledger entry.
- Require a phase argument (
phase-NN or the phase-unknown placeholder)
before inspecting or changing files. If neither form is given, ask for one.
- Invoke the
soa-quality-control skill. That skill owns fix verification,
commit provenance, phase attribution (including resolving phase-unknown),
review-gap ledger capture, and promotion-queue guidance.
- Keep this skill-led. Do not add a
bun run deliver quality-control
delivery-orchestrator command for this path.
closeout (alias: closeout-stack)
Trigger: /soa closeout XX
Squash-merge a completed stacked PR set onto the configured closeoutBranch.
Run the closeout script:
bun run .son-of-anton/scripts/closeout-stack.ts
Pass any argument (stack name or number) through to the script. Report the result. If the script is not found, tell the user to complete the setup steps in the README.