name: self-review description: Use when finishing spec.md before writing test-definitions.md, or when the review gate asks for a spec review — self-reviews the just-authored spec inline and earns its Tier 1 review stamp. Your own inline pass; do not spawn a sub-agent. allowed-tools: '*'
Self-Review
Review the artifact you just authored, then earn its review stamp so the next step is unblocked. This is Tier 1 — a cheap, inline floor. You review your own work; no sub-agent is spawned. The independent check is Tier 2 (the fork review at each phase exit), not this.
Earn the stamp
The line below runs the stamp-earning step at render time. It binds a
review:<scope> stamp to the active ticket's spec.md at its current
content and appends it to skill-invocations.log under the project namespace root, where the
per-asset gate reads it back. Invoking this skill is what writes the stamp —
hand-editing the log is the gameable floor this tier deliberately accepts.
!PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}" && CLAUDE_PROJECT_DIR="$PROJECT_DIR" bun "$PROJECT_DIR/.safeword/hooks/write-review-stamp.ts" spec
If no [skill-invocation-log] ... ✓ line appears above, run this fallback before stopping:
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(git rev-parse --show-toplevel 2> /dev/null || pwd)}"
CLAUDE_PROJECT_DIR="$PROJECT_DIR" bun "$PROJECT_DIR/.safeword/hooks/write-review-stamp.ts" spec
The review stamp is content-bound and uses the normalized runtime identity.
If the automatic line and fallback both print [skill-invocation-log] FAILED, or still do not print ✓: STOP.
The stamp was not written and the gate will keep blocking. Most likely the bash
injection was denied, no in_progress ticket was found, or Bun could not run the
installed helper — report it to the user and resolve before retrying.
Review the spec (do this now, with the stamp written)
The stamp records that a review was invoked; the actual scrutiny is yours. Read
the active ticket's spec.md and check, against personas.md and the ticket's
scope / out_of_scope frontmatter:
- Every JTBD resolves to a real persona and reads as a genuine job (
When I…, I want…, so I can…), not a restated feature. - Each JTBD carries ≥1 Acceptance Criterion stating an observable, product- level guarantee — not an implementation detail.
- The ACs cover the ticket's scope and stop at its
out_of_scopeline — no silent scope creep, no orphan capability. - Nothing leaks implementation (file names, function names, libraries) into spec-level prose.
If the review surfaces a fix, edit spec.md and re-invoke /review — the
content-bound stamp goes stale on any edit, so the gate correctly re-blocks
until the corrected spec is re-reviewed. That is the point: a review that
changes the artifact must be re-earned.
Skip valve
If the artifact is genuinely trivial to review (boilerplate, a docs-only change), log a skip with a reason instead of a review — it clears the same gate and records why:
bun .safeword/hooks/write-review-stamp.ts spec "<why this spec needs no review>"
An empty reason does not clear the gate.