Skip to content

/goal-chain

Run a linear sequence of goalkeeper goals where the judge gates progression between them. Use when the user invokes /goal-chain "<file>" to start a chain. Also auto-invoked by the judge skill on approval to advance the chain cursor.

shell
$ npx -y skills add bonfire-systems/goalkeeper --skill goal-chain --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
  • You can call itInvoke it directly when you want it.
  • Slash command/goal-chain
How auto-invocation works

Context preview

The summary Claude sees to decide when to auto-load this skill.

Run a linear sequence of goalkeeper goals where the judge gates progression between them. Use when the user invokes /goal-chain "<file>" to start a chain. Also auto-invoked by the judge skill on approval to advance the chain cursor.

SKILL.md

goal-chain.SKILL.md
name: goal-chain
description: Run a linear sequence of goalkeeper goals where the judge gates progression between them. Use when the user invokes /goal-chain "<file>" to start a chain. Also auto-invoked by the judge skill on approval to advance the chain cursor.

You are operating the **goal-chain** skill. A chain is a linear ordered list of goal slugs that execute one after another, gated by judge approval at each step.

Modes

The skill operates in one of three modes determined by args and state:

1. **Start mode** — `args` is a non-empty path to a chain file. Begin a new chain. 2. **Advance mode** — invoked by the judge skill after approve. No args. Move cursor forward. 3. **Status mode** — `args == "status"` or chain exists and user asks plainly. Show progress.

Start mode

Triggered by `/goal-chain "<path/to/chain.md>"`.

1. Parse chain file

The chain file is a markdown document with optional frontmatter and an ordered list of slugs. Accepted formats:

---
name: my-chain-name
---

1. first-goal-slug
2. second-goal-slug
3. third-goal-slug

Or with bullets:

- first-goal-slug
- second-goal-slug

Extract slugs from numbered list items or bullets. Trim whitespace. Strip any trailing comments after `#`.

2. Validate every slug has a contract

For each slug, verify `.claude/goals/<slug>/contract.md` exists. If any are missing, list them and stop. Tell the user to run `/goal-prep` for each missing slug, or remove them from the chain file.

3. Refuse to overlap

If `.claude/goals/active.json` shows an active goal, or `.claude/goals/chain.json` exists with status `active`, refuse and tell the user to `/goal-clear` first.

4. Write chain.json

Per the canonical chain.json shape (see goal.md "Canonical state shapes"):

{
  "name": "<from frontmatter or filename>",
  "slugs": ["...", "..."],
  "cursor": 0,
  "status": "active",
  "started_at": "<ISO8601>",
  "completed_at": null,
  "source_file": "<absolute path to chain file>",
  "link_approvals": []
}

`link_approvals` starts empty and accumulates one entry per judge-approved link as the chain advances.

5. Activate the first slug

Write `.claude/goals/active.json` per the canonical active shape with `chain` populated:

{
  "slug": "<slugs[0]>",
  "activated_at": "<ISO8601>",
  "chain": "<chain name>"
}

Initialize that goal's `state.json` per the canonical state.json shape (status=active, rejection_count=0, started_at=now, started_at_commit=`git rev-parse HEAD`, started_at_dirty_paths=`git status --porcelain`, chain_step=1). Append to its `log.md`:

## <ISO8601> — activated (chain step 1/<N>)
Chain: <name>. Starting first goal: <slug>.

6. Spawn the executor subagent

**v0.3+:** chains run their per-goal execution in a **fresh-context subagent** instead of the main conversation. Main context only orchestrates — spawning executor, spawning judge, applying verdict, advancing cursor. This is the load-bearing change that lets a chain run autonomously across many goals without main-context aging out.

Use the Agent tool with `subagent_type: general-purpose`. Pass a self-contained prompt:

1. **The full `contract.md`** — verbatim. 2. **The full `log.md`** — verbatim (so the executor sees the activation entry + any prior checkpoints if this is a re-spawn after judge rejection). 3. **Chain context** — chain name, current cursor position, total slugs, the prior link's approval timestamp. 4. **Repo state** — `git rev-parse HEAD`, `git status --porcelain` (first 20 lines). 5. **The directive** — verbatim, in this exact format:

You are the goalkeeper EXECUTOR SUBAGENT for goal `<slug>` (chain step <N>/<total>).

Your job: read the contract above, execute every Definition-of-Done item, run
the validator at the end, and return a structured summary. You operate in a
fresh context — you have no conversation history beyond this prompt. The
contract is your spec; do not improvise outside it.

Execution loop:
  1. Read the contract carefully. Identify the implementation work required.
  2. Do the work. Edit/write files as needed. Follow the contract's non-goals
     and anti-placeholder rule strictly.
  3. Append checkpoint entries to `.claude/goals/<slug>/log.md` as you go
     (one per logical sub-task or every ~5 file edits — whichever is more
     natural for the work).
  4. Run the validator: `<validator.command>`. Capture stdout+stderr.
  5. If validator FAILS: diagnose, fix, re-run. Repeat up to a reasonable
     attempt budget (~3-5 inner attempts). If still failing, document why
     in the log and return with status=blocked.
  6. If validator PASSES: append a "validator passed" entry to the log,
     update `.claude/goals/<slug>/state.json` with last_validator_result=pass
     and last_checkpoint_at, then return.

DO NOT spawn the judge yourself. The chain orchestrator handles that step.
DO NOT advance the chain cursor. DO NOT modify chain.json, active.json, or
the goals_completed list. DO NOT activate the next goal. Just do the work
for THIS goal and return.

Return ONCE with this structured output:

STATUS: validator_pass | validator_fail | blocked | needs_clarification

SUMMARY:
<3-8 sentences describing what you did: files touched, decisions made, any
non-obvious tradeoffs, anything the judge should pay particular attention to>

VALIDATOR_OUTPUT_TAIL:
<last ~40 lines of the validator's stdout+stderr — let the judge see the
actual pass/fail signal directly>

FILES_CHANGED:
<bulleted list of paths modified relative to repo root, plus brief one-line
note per file about what changed>

BLOCKERS: (only if status != validator_pass)
<specific reason: which DoD item, which file, what's missing or wrong>

7. Receive executor return, spawn judge

When the executor subagent returns its structured summary:

  • **STATUS = blocked or needs_clarification** — append a `## <ISO8601> — executor blocked` entry to the goal's log with the BLOCKERS verbati
Read more
Read it on GitHub ↗

Showing the first part of this file.

Ships withgoalkeeper

Durable contract-driven goal execution for Claude Code. A subagent judge gates completion against an explicit Definition of Done.

Get the whole plugin, auto-invoked
Stats
12
Stars
0
Views
2
Forks
Maintained
Maintenance
Python
Language
MIT
License
1mo ago
Last commit
2mo ago
Created

Repo: bonfire-systems/goalkeeper

Other skills on goalkeeper.