Land verified work on trunk after tests and required review; preserve release authority.
Resources
2Install
npx skillscat add mistakeknot/clavain/landing-a-change Install via the SkillsCat registry.
Landing a Change
Verify → Review evidence → Document → Commit → Confirm.
Announce: "I'm using the landing-a-change skill to complete this work."
Step 1: Verify Tests
Artifact-cached skip: If inside a sprint (CLAVAIN_BEAD_ID set), check whether tests already passed at current HEAD:
BEAD_ID="${CLAVAIN_BEAD_ID:-}"
if [[ -n "$BEAD_ID" ]]; then
test_sha=$(clavain-cli get-artifact "$BEAD_ID" "test-pass-sha" 2>/dev/null) || test_sha=""
current_sha=$(git rev-parse HEAD)
if [[ "$test_sha" == "$current_sha" ]]; then
echo "Tests verified at $test_sha (current HEAD). Skipping re-run."
# Skip to Step 2
fi
fiIf HEAD moved since the last recorded test pass, or no test-pass-sha artifact exists, or not in a sprint: run the full test suite (go test ./... / npm test / pytest / cargo test). If tests fail, stop and fix. Do not proceed.
Step 2: Verify Plan Compliance
- Were all plan checkboxes checked?
- Any unresolved TODO comments?
- Implementation matches agreed scope?
If a plan existed, invoke verification-before-completion skill. Otherwise proceed.
Step 3: Evidence Checklist
- Tests pass
- Plan checkpoints complete (if plan exists)
- No unresolved TODOs in changed files
- No debug artifacts (
console.log,fmt.Println, etc.) - Changes in logical commits with descriptive messages
- Deploy verification plan exists (if deploy-relevant)
- Shipped-surface sweep (if the change touches anything a reader/user sees —
pages, UI strings, error messages, emails, docs meant for outsiders). Six
parity questions, each answered against the fresh reader, not the builder:- No pipeline vocabulary — lane/wave/slice/version labels, generator
diagnostics, internal status enums visible to readers? - Affordance parity — does every interaction the copy names actually
exist on that surface? - Audience parity — does each viewer mode only show instructions and
widgets that viewer can actually use? - One CTA per action per view — no duplicate entry points?
- Scope-distinct controls — do controls operating on different scopes
look/read differently? - Spatially true status — does status copy match where it renders
("below" means below)?
Origin: Kublai soft launch, 2026-08-19 — thirteen outside-reader reports,
all preventable by this sweep. Mechanical floor (banned-vocab lint) is
per-repo where one exists; these six are the judgment half.
- No pipeline vocabulary — lane/wave/slice/version labels, generator
If deploy-relevant, consider invoking fd-safety.
Step 4: Present Options (AskUserQuestion)
question: "Implementation verified. How would you like to land this?"
options:
- Commit and push
- Commit locally
- Changelog first (runs /clavain:changelog)
- Review first (show git diff, return to this step)Step 5: Execute
Commit and push / Commit locally:
git add <specific files> # NOT git add .
git commit -m "feat(scope): description
Co-Authored-By: Claude <noreply@anthropic.com>"
git push # only for "Commit and push"Commit locally leaves associated beads open. A close is only eligible after
the implementation commit is visible on the remote.
Changelog first: Run /clavain:changelog, then commit.
Review first: Show git diff --stat && git diff, return to Step 4.
Step 5.5: Post-Push Canary (rsj.1.2)
After push succeeds and inside a sprint (CLAVAIN_BEAD_ID set), run a lightweight canary check on the merged state:
if [[ -n "${CLAVAIN_BEAD_ID:-}" ]] && [[ "${CLAVAIN_SKIP_CANARY:-}" != "true" ]]; then
source "${CLAUDE_PLUGIN_ROOT}/hooks/lib-sprint.sh" 2>/dev/null || true
if ! sprint_canary_check "$CLAVAIN_BEAD_ID"; then
echo "⚠ Post-merge canary FAILED. Sprint NOT recorded as successful."
echo " Fix the issue and re-run, or set CLAVAIN_SKIP_CANARY=true to override."
# Do NOT close the bead or record success
fi
fiIf canary fails: warn user, emit quality_failure event to Interspect, do NOT record sprint as successful. If canary passes: normal flow continues.
Step 5.6: Close After Push
Only after the push and post-push canary succeed, close each selected bead
through the canonical gate:
for bead_id in <issue-ids>; do
"${CLAUDE_PLUGIN_ROOT}/scripts/gates/bead-close.sh" "$bead_id" "Landed in pushed commit $(git rev-parse --short HEAD)"
done
bd dolt push
git pushThe wrapper verifies any installed-runtime evidence requirement before changing
tracker state. If it rejects a bead, leave that bead open and report the gate.
Step 6: Capture Learnings (Optional)
Run /clavain:compound or note insights in project memory files.
Red Flags
- Never push without verified tests
- Never close a bead before its implementation commit is pushed
- Never
git add .— stage specific files - Never auto-push without user selecting Option 1
- Never skip the evidence checklist