name: roster-ship
description: Ship — conventional commits, rebase-merge, GitHub PR. Gated on review + QA go.
version: 1.3.0
domain: pipeline
phase: ship
preamble: true
friction_log: true
allowed_tools: [Read, Bash, AskUserQuestion]
human_gate: both
tunables:
merge_strategy: rebase-merge
commit_convention: conventional
pre_pr_checks: ""
friction_warn_threshold: 10
artifacts:
reads:
- briefs/
produces: PR opened or BLOCKED status with reason
name: roster-preamble version: 1.5.0 description: Shared preamble injected into every roster skill that declares preamble true. Not a standalone command.
Roster Preamble
This preamble is injected into every roster skill that declares preamble: true.
It encodes the non-negotiable principles that govern all skill runs.
Principles
Completeness
Do not defer tests, documentation, or robustness in the name of speed. A short-term shortcut is rarely faster than a complete solution. "We'll add tests in a follow-up" is not an acceptable decision — it is explicit debt, or it is not a decision at all.
Search Before Build
Before creating anything, verify what already exists:
- Local (current repo, harness, KB)
- Roster (index.json, roster GitHub)
- Web (if webfetch available)
A false positive (checking for something that didn't exist) costs seconds. A false negative (building something that already existed) costs hours and creates debt.
Anti-Sycophancy
Do not validate a direction if you have a grounded objection. Do not say "good idea" before verifying it is a good idea. If you spot a problem, say so — clearly, factually, without softening. State your recommendation, explain why, mention what context you might be missing, and ask.
User Sovereignty
When you and a sub-agent both agree to change the user's direction: → present the recommendation → explain why you both think it is better → state what context you might be missing → ask
Never act unilaterally in this case. The decision belongs to the user.
Escalation
If you are blocked, the situation is ambiguous, or the action exceeds the declared scope: → escalate to the human — do not deviate from scope, do not guess
Asking Questions
When you need to ask the user something, use your runtime's interactive input tool if one is available — do not ask via plain text output.
Known runtime tool names:
| Runtime | Tool name |
|---|---|
| Claude Code | AskUserQuestion |
| Copilot CLI | ask_user |
| Codex | request_user_input |
| OpenCode | question |
Rules:
- One question at a time — never bundle multiple questions into one message
- Prefer multiple-choice options over open-ended when the answer space is predictable
- If no interactive tool is available, output a clearly marked plain-text question and wait for the user's reply before proceeding
Friction Log
At the end of each run, honestly record:
- frictions encountered (workarounds, long searches, ambiguities)
- methods used
- any suggestion for a tool, skill, or adaptation
This is not a performance review. It is cross-run memory.
Format: see skills-meta/friction.jsonl.
Pipeline State
If your skill's phase: frontmatter field is non-null (i.e. you are one of the staged
pipeline phases) and you are operating on a task with a briefs/<task>- context, append one
event to briefs/<task>-state.json when you finish — this is the durable, resumable record
/roster-run reads to resume and /roster-doctor status renders. Skip entirely if your phase:
is null (standalone skills: doctor, audit, investigate, init, skill-health) or there is no task
context. Create the file if absent; preserve every prior events entry:
{
"task": "<slug>",
"mode": "express|fast|full",
"current_phase": "implement",
"events": [
{ "phase": "implement", "outcome": "COMPLETED", "at": "<ISO-8601 or omit>", "by": "roster-implement" }
]
}
Rules for writing your event:
taskis the canonical slug, derived once from the task description and reused identically by every phase: lowercase, kebab-case, the ≤4 most significant words (the same rule/roster-questionand/roster-intakeuse to namebriefs/<task>-*). The first phase to run —roster-implementin Express/Fast,roster-question/roster-intakein Full — fixes the slug; every later phase, and/roster-run's resume check, MUST derive the byte-identical slug or the ledger will not be found. When in doubt, reuse the slug already present on existingbriefs/<task>-*files for this task rather than re-deriving.phaseMUST be your skill's ownphase:frontmatter value, verbatim — one of the legal tokens:question,research,intake,spec,plan,implement,review,qa,ship. Never invent a synonym (implementation,code-review, …); resume matches on these exact tokens.outcomeis per phase, from this fixed vocabulary —intake:VALIDATED;spec:VALIDATED,SKIPPED(non-spec'd task types), orBOUNCED;review/qa:GOorNO-GO;ship:COMPLETED;question/research/plan/implement:COMPLETED. Do not invent other values.- Append-only audit trail. Always push a new event — never rewrite or delete a prior one.
A re-run after a NO-GO bounce legitimately produces a second
implement/reviewpair; that repetition is the history, not a bug. Setcurrent_phaseto your phase (the latest completed). modeis the task's mode (express/fast/full); set it on first write, leave it thereafter.- Use a timestamp in
atif your runtime can produce one; otherwise omit the field.byis your skill name (orhuman-gatefor a gate decision).
Roster Ship
You carry the implementation branch through to merge. Conventional commits, rebase-merge only, PR with closing issue. Never ship without the double review + QA gate.
Token discipline: terse — links not pastes, one-liner commit subjects.
Input Contract
Before any action, read:
briefs/<task>-review.json— BLOCK if status isNO-GO; read itsmodefieldbriefs/<task>-impl.md— for commit messagesbriefs/<task>-qa.md— required forfast/fullmode (BLOCK if NO-GO or absent). Express mode skips QA (its pipeline is implement → review → ship), so a missingqa.mdis expected and not a block whenreview.json.mode == "express".
If review.json.mode is absent and the impl brief has no Mode: line, require human
confirmation before treating a missing qa.md as expected — the mode cannot be safely
inferred without an authoritative source.
Block conditions:
⛔ BLOCKED: review.json is NO-GO or absent → resolve before shipping. ⛔ BLOCKED: qa.md is NO-GO, or absent on a non-express task → run /roster-qa first.
Steps
1. Pre-checks
git status # repo clean?
git log --oneline -5 # branch state
If the repo is dirty on files outside the task scope → report and ask what to do.
If tunables.pre_pr_checks is defined, execute it and block on failure.
2. Conventional commits
From briefs/<task>-impl.md, build the commits:
Format: type(scope): description
Types: feat, fix, refactor, docs, test, chore, perf, ci
Rules:
- Description in lowercase, imperative, no trailing period, max 72 chars
- One commit = one logical change that compiles independently
- Body if necessary (why, not what) — separated by a blank line
- Footer:
Closes #Nif issue referenced
git add <scope files>
git commit -m "type(scope): description"
3. Rebase on main
git fetch origin
git rebase origin/main
If conflicts → resolve within the task scope only. If conflict is out of scope, report to the human.
4. Human gate — before push
Write the ship summary to briefs/<task>-ship-gate.md, then present the quiz per the human-validation.md protocol (at minimum 1 comprehension + 1 clarification + 1 consistency-check question). All questions uniform format — do not label by type.
Present:
Commits prepared:
<short sha> type(scope): description
...
Branch: <name>
Target: main
Push and open PR?
Wait for explicit human confirmation after the quiz passes.
5. Push and PR
git push origin <branch> --force-with-lease
gh pr create \
--title "type(scope): description" \
--body "$(cat briefs/<task>-impl.md | head -20)
Closes #N" \
--base main
6. Human gate — merge
After review and CI green:
gh pr merge <N> --rebase --delete-branch
Rebase merge only. Never a merge commit, never squash.
7. Confirmation
✅ Shipped: PR #N merged to main
Branch deleted: <branch>
Closes: #N
8. KB sync (conditional)
[ -d kb ] && ([ -f kb/spec.md ] || [ -f kb/index.md ]) && echo "KB present" || echo "KB absent"
If KB is present:
→ Invoke skills/kb/kb-update.md skill.
→ If kb-update reports a contradiction (code contradicts KB spec):
- Surface as WARNING in the ship log — do not attempt to revert the merge.
- Open a follow-up task: "KB amendment —
<task-slug>" (describe the contradiction). → If KB updated cleanly: Wait for human confirmation before pushing KB changes to main. Then:
git add kb/
git commit -m "docs(kb): sync KB with <task-slug> changes"
git push
→ If KB is absent: skip silently.
Output Contract
GitHub PR opened (then merged after human approval), or BLOCKED status documented.
Next: tech-lead / human with merge confirmation.
Increment metabolism counter: After a GO ship (PR opened or merged), increment completed_tasks in .harness/harness.json (fall back to .claude/harness.json if absent):
# read → increment → write (jq required; use a project-local temp file, never /tmp)
HARNESS=".harness/harness.json"
[ -f "$HARNESS" ] || HARNESS=".claude/harness.json"
[ -f "$HARNESS" ] && jq '.layers.metabolism.completed_tasks += 1' "$HARNESS" > "${HARNESS}.tmp" && mv "${HARNESS}.tmp" "$HARNESS"
If jq is not available or neither harness file exists, note the missed increment in the friction log without blocking.
Friction reminder: After incrementing, print the current friction log size.
Substitute tunables.friction_warn_threshold for THRESHOLD before running:
# THRESHOLD = tunables.friction_warn_threshold (default 10)
FRICTION_COUNT=$(awk 'END{print NR}' skills-meta/friction.jsonl 2>/dev/null || echo 0)
echo "💡 Friction log: ${FRICTION_COUNT} entries."
[ "$FRICTION_COUNT" -gt "THRESHOLD" ] && echo "⚠️ Consider running /roster-skill-health to surface improvement proposals."
When to Go Back
| Condition | Action |
|---|---|
| QA brief is not GO | Stop — do not ship; return to /roster-qa or /roster-implement |
| Pre-ship gate check reveals a new failure | Stop — re-run /roster-qa before retrying |
kb-update reports code contradicts KB spec |
Log WARNING, do not revert — open a KB amendment follow-up task |
What Next
Primary path: Done — PR opened, awaiting human merge approval Alternatives:
/roster-intake— start the next task/roster-skill-health— good moment to analyze friction after a completed cycle
💡 A completed ship is the best time to run
/roster-skill-healthand capture what the cycle taught you.
Friction Log
{
"task": "<task-slug>",
"frictions": [],
"methods": [],
"suggestion_type": null,
"suggestion": null,
"effort_estimate": null
}
Rules
- Never a merge commit — rebase-merge only
- Never push without an explicit human gate
- Never ship if review.json is NO-GO or absent, or if qa.md is NO-GO; qa.md may be absent only in express mode (which skips QA)
- Never commit files outside the task scope
- If CI fails after push → do not merge, report