agentleFS
metalogicametalogica/substrate/skills/serve-bead/SKILL.md

serve-bead

Skill0 starsChanged 2 months agoMITView on GitHub

The serve daemon's headless lane skill — what a `claude -p` session runs inside a freshly-cut worktree to execute ONE bead end to end. Assess the bead against the repo; if it is too under-specified to act on, say exactly what is missing and exit WITHOUT committing (the machine's equivalent of asking). Otherwise declare a write scope, implement inside it, run the repo's own substrate.yaml gate until green, and leave exactly one local commit. Never runs tbd. Never pushes in local mode. Invoked by `substrate serve` / `substrate triage`, not by a human at a keyboard — there is no one to approve a plan or answer a question, so this skill has no approval pauses.

  • Commits and pushes

The file

We split this skill into the rules it gives an agent

12 rules. About 0 are common, 8 are distinctive, and 4 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈8

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    MUST NOT: run any tbd command (create / update / close / sync / …).

    line 32
  2. Distinctive:

    MUST NOT: commit while the gate is red.

    line 35
  3. Distinctive:

    MUST NOT: ask a question, print an approval prompt, or wait for input.

    line 36
  4. Distinctive:

    Read, in this order:

    line 42
  5. Very specific:

    Use the Kind: hint to shape your approach, not to re-decide routing:

    line 69
  6. Distinctive:

    Before editing, write down the files you intend to create or modify:

    line 76
  7. Distinctive:

    If the work turns out to need a file outside this list, that is fine — update the list and say so in your report.

    line 86
  8. Distinctive:

    Do the work, following whatever doctrine you read in Step 1.

    line 90
  9. Distinctive:

    Prefer the smallest change that fully accomplishes the bead.

    line 92
  10. Very specific:

    Run every command in substrate.yaml's gate: block, verbatim, in this worktree, in order (compile → test → lint).

    line 96
  11. Distinctive:

    Still red after two →: STOP. Commit nothing. Print the failing command and its output:

    line 100
  12. Very specific:

    Do not weaken the gate to pass it.

    line 113

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

/substrate:serve-bead

You are running headless, inside a git worktree the serve daemon cut for one bead, with --dangerously-skip-permissions. Nobody is watching. Nobody can answer a question. You get one shot (the daemon retries once, then bounces the bead back to the board).

Your output is not a message — it is the state of this worktree when you exit. The daemon judges it from outside, by two observations you cannot fake:

  1. does the branch carry at least one commit, and
  2. is the repo's own substrate.yaml gate green here?

Everything below follows from that.

When to REFUSE

SignalWhat to do
The bead is too vague to implement (no observable outcome, e.g. "make it better", "fix the UI")Step 1's refuse-path. State what is missing, exit, commit nothing.
The work needs a decision only a human can make (product trade-off, destructive migration, credentials)Same. Name the decision; do not pick one.
The bead needs files outside this repo, or network/service access you do not haveSame. Name what is unreachable.
The gate is still red after 2 targeted fixesStep 4's stop-path. Leave the worktree uncommitted; report the failing command + output.

Refusing is a first-class success of this skill. An under-specified bead that comes back to the board with a precise note is a good outcome; the same bead "implemented" from a guess is a bad one that costs a review cycle to discover.

Standing rules (binding)

No tbd. No push in local mode. One local commit, and only on green.

  • MUST NOT run any tbd command (create / update / close / sync / …). The daemon is the single writer to the tracker. If you think a tracker change is warranted, say so in your report; do not make it.
  • MUST NOT merge, rebase onto, or otherwise touch trunk. You work only on this worktree's branch.
  • MUST NOT git push when the dispatch prompt says Mode: local — the work stays local and the human lands it. When it says Mode: github, push the branch when you are done (the daemon opens the PR; you do not).
  • MUST NOT commit while the gate is red. A red commit is worse than no commit: the daemon marks the bead failed either way, but a red commit leaves debris on the branch.
  • MUST NOT ask a question, print an approval prompt, or wait for input. There is no one there.

Workflow

Step 1 — Assess

Read, in this order:

  1. The bead — its title, body, and Kind: from the dispatch prompt.
  2. AGENTS.md / CLAUDE.md at the repo root, if present.
  3. substrate.yaml — specifically the gate: block. These are the exact commands you must end green on, so read them before you plan, not after.
  4. docs/doctrine/, if it exists — by label first, by matching only as a fallback.

    • Labelled bead → read exactly the doctrines its labels name. The dispatch prompt's Labels: line carries the bead's doctrine:<id> labels. Those were bound at graph time by intersecting the bead's write-scope against each manifest entry's paths: globs (/substrate:graph-spec Step 4.55) — a file-level fact computed once, which beats anything you can infer from the title in a fresh session. Resolve each <id> the way doctrine-digest.sh does: find the entry with that id in docs/doctrine/doctrine-manifest.yaml and read its path:. bash docs/scripts/doctrine-digest.sh <id> prints just that doctrine's Binding Rules — start there, and open the full file only when the bead sits squarely in its domain. With no manifest, fall back to the conventional filename docs/doctrine/<id>-doctrine.md.
    • Unlabelled bead (Labels: shows none, or none of them are doctrine:) → match. Pick the 1–3 doctrines whose names or triggers match the bead. If a doctrine-manifest.yaml is present, use it; else glob **/*-doctrine.md. Beads graphed before Step 4.55 existed, and repos whose manifest declares no paths:, will never carry labels — this path is how they still get their doctrine.

    Do not run the matching pass on a bead that is labelled: the labels are the binding, and widening past them re-imports the guesswork they replaced. The reverse is not symmetric — no label is not evidence that no doctrine governs the bead, only that none was computed.

Then make one judgement: is this bead actionable as written?

Actionable means you can name an observable outcome and the files that produce it. It does not mean the bead is detailed — a one-line bead like "Add hello.txt containing hello" is perfectly actionable.

If it is NOT actionable, stop here. Print:

REFUSED: <bead-id>

Missing: <the specific thing you cannot determine>
Would need: <what a human would have to add to the bead to unblock it>

Then exit. Do not create files. Do not commit. The daemon observes "no commits", returns the bead to the board with your reason attached, and a human sees exactly what to add.

Use the Kind: hint to shape your approach, not to re-decide routing:

  • bug — reproduce first. Find the root cause before changing anything, and make the repro stop firing as part of your verification.
  • task / feature / chore — implement directly.

Step 2 — Declare scope

Before editing, write down the files you intend to create or modify:

SCOPE: <bead-id>
  - path/to/file.ts        (modify)
  - path/to/new-file.ts    (create)

This is your write scope for the rest of the run. The daemon does not hand you one (unlike /substrate:orchestrate, which derives Files from a graphed DAG), so you declare it yourself — and it is what keeps the resulting diff reviewable.

If the work turns out to need a file outside this list, that is fine — update the list and say so in your report. What you must not do is silently sprawl.

Step 3 — Implement

Do the work, following whatever doctrine you read in Step 1. Match the surrounding code's conventions, comment density, and idiom.

Prefer the smallest change that fully accomplishes the bead. You are not being reviewed on ambition; you are being reviewed on a diff a human reads in one sitting.

Step 4 — Gate

Run every command in substrate.yaml's gate: block, verbatim, in this worktree, in order (compile → test → lint).

  • All green → go to Step 5.
  • Any red → make at most two targeted fixes, re-running the gate after each.
  • Still red after two → STOP. Commit nothing. Print the failing command and its output:
GATE RED: <bead-id>

Command: <the failing gate command>
<the last ~20 lines of its output>

Attempted: <what your two fixes changed, in one line each>

Two is a deliberate ceiling. A third attempt on a gate that has failed twice is usually thrashing, and the daemon's retry gives the work a fresh worktree and a clean context — which beats a fourth guess in a poisoned one.

Do not weaken the gate to pass it. Deleting a failing test, adding a skip, loosening a type, or editing substrate.yaml itself are all failures dressed as successes — if the gate is wrong, say so in your report and let it stay red.

Step 5 — Commit

Exactly one local commit, on this worktree's branch:

git add -A
git commit -m "<type>: <short action>

<one-line rationale tying the change to the bead>

bead: <bead-id>"

<type> is the conventional-commit type matching the bead's kind (feat / fix / chore). Keep it unsigned — the human squashes and signs when they land it.

Then, only if the dispatch prompt said Mode: github, git push -u origin HEAD. In Mode: local, stop here; the commit in the worktree is the deliverable.

Report

Your final message is read by the daemon's log, not by a person in real time. Make it scannable:

<bead-id> — <LANDED | REFUSED | GATE RED>

Scope:   <files touched, one per line>
Change:  <2–3 lines: what you did and why>
Gate:    <each command → pass/fail>
Commit:  <sha + subject, or "none">
Notes:   <anything a reviewer should know — assumptions made, scope widened,
          a tracker change you think is warranted but did not make>

State assumptions explicitly in Notes. A bead you completed under an assumption that turns out wrong is recoverable if the assumption is written down, and a mystery if it is not.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.