From 65152e9e83b33c28783917327a205b041fc3ff11 Mon Sep 17 00:00:00 2001 From: fullstackjam Date: Sat, 16 May 2026 21:59:25 +0800 Subject: [PATCH 1/4] fix(harness): drop --auto from ship-pr; insert review gate between CI and merge MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous ship-pr flow ended with `gh pr merge --auto --squash`, which queues the merge to fire as soon as branch-protection checks pass. That defeats the purpose of having a review step — auto-merge bypasses review entirely. The corrected flow: push → gh pr create → gh pr checks --watch → architecture-review the diff → surface findings → ask user → gh pr merge --squash (no --auto) → local cleanup Branch protection (docs/MERGE_POLICY.md) is the mechanical gate; this skill adds the inferential gate on top of it. Skipping the gate by queueing auto-merge was the wrong default. AGENTS.md and docs/HARNESS.md updated to match the new flow. --- .claude/skills/ship-pr/SKILL.md | 158 +++++++++++++++++--------------- AGENTS.md | 11 ++- docs/HARNESS.md | 2 +- 3 files changed, 94 insertions(+), 77 deletions(-) diff --git a/.claude/skills/ship-pr/SKILL.md b/.claude/skills/ship-pr/SKILL.md index 4d6833f..b4e3002 100644 --- a/.claude/skills/ship-pr/SKILL.md +++ b/.claude/skills/ship-pr/SKILL.md @@ -1,15 +1,19 @@ --- name: ship-pr -description: Use when the user wants to open a pull request for the current branch — phrases like "open a PR", "ship this", "submit PR", "let's send it", "提 PR", "提个 MR". Walks through the canonical post-edit flow: local architecture review → L1 unit tests → push → gh pr create → gh pr merge --auto. Trigger any time the user signals they're done editing and want the change on its way to main; do NOT trigger for `gh pr view` / status checks on existing PRs. +description: Use when the user wants to open a pull request for the current branch — phrases like "open a PR", "ship this", "submit PR", "let's send it", "提 PR", "提个 MR". Walks through the canonical post-edit flow: push → open PR → wait for CI → review the diff → surface findings → user-confirmed manual merge → local cleanup. Trigger any time the user signals they're done editing and want the change on its way to main; do NOT trigger for `gh pr view` / status checks on existing PRs. --- # Ship a PR for openboot This is the canonical way to move a finished change from a feature branch into `main`. The branch protection rules defined in [docs/MERGE_POLICY.md](../../../docs/MERGE_POLICY.md) -do the gating — this skill makes sure the obvious local checks are done -first and that auto-merge is enabled so the change lands without a human -having to babysit CI. +define the **mechanical** gate (6 required checks). This skill adds the +**inferential** gate on top: after CI is green, the diff gets reviewed, +findings are surfaced, and merge only happens after the user confirms. + +**Auto-merge is intentionally not used.** `gh pr merge --auto` skips the +review step entirely — that defeats the purpose of having a review gate. +The merge command is run from this session, after the user OKs it. ## When to use @@ -17,9 +21,9 @@ Trigger when the user says they're done with a change and want a PR. **Do not** use this for: - Draft PRs / WIP work the user wants reviewed but not merged. Use plain - `gh pr create --draft` and skip auto-merge. -- Changes to `.github/workflows/` or branch protection. Those need human - review on `main`'s ruleset interaction. + `gh pr create --draft` and stop. +- Changes to `.github/workflows/` or branch protection rules. Those need + a human to also poke the GitHub UI. - Release tags (`v*.*.*`). Releases follow `make test-vm-release` first. ## The flow @@ -35,31 +39,17 @@ git log --oneline main..HEAD # commits actually exist If the branch is `main`, stop — make a feature branch first. If there are no commits ahead of `main`, stop — nothing to ship. -### Step 2 — Local review (cheap, catches most issues) - -Invoke the [`architecture-review`](../architecture-review/SKILL.md) skill -on the current diff. Fix anything it flags before moving on. The point of -running it locally is to avoid burning a CI cycle on a violation that -`internal/archtest` would catch in ~15 seconds. - -### Step 3 — L1 locally - -```bash -make test-unit -``` - -This is the same suite the `pre-push` hook would run, so think of it as -"don't ship without doing what the hook does". If `make install-hooks` is -already wired, this step is redundant — but running it explicitly costs -~15s and removes any uncertainty. - -### Step 4 — Push +### Step 2 — Push ```bash git push -u origin "$(git rev-parse --abbrev-ref HEAD)" ``` -### Step 5 — Open the PR +The `pre-push` hook (installed via `make install-hooks`) runs L1 here +automatically — no need to run `make test-unit` separately. If the hook +is not installed, that's the user's choice; CI will still gate. + +### Step 3 — Open the PR ```bash gh pr create --title "" --body "$(cat <<'EOF' @@ -80,78 +70,102 @@ Title rules (from CLAUDE.md): `test:` / `chore:` / `ci:` / `perf:`. - Keep under 70 chars. Detail goes in the body. -### Step 6 — Hand the PR to GitHub's auto-merge +### Step 4 — Wait for CI ```bash -gh pr merge --auto --squash --delete-branch +gh pr checks --watch ``` -GitHub will hold the merge until every required check from -[docs/MERGE_POLICY.md](../../../docs/MERGE_POLICY.md) reports success — -currently: +This blocks until every check finishes. Typical wall time is 3–10 min +depending on which jobs run. The required checks per +[docs/MERGE_POLICY.md](../../../docs/MERGE_POLICY.md): + +- `lint`, `unit (L1)`, `integration (L2)`, `contract schema (L3)`, + `curl|bash smoke`, `old-cli compat` -- `lint` -- `unit (L1)` -- `integration (L2)` -- `contract schema (L3)` -- `curl|bash smoke` -- `old-cli compat` +If any required check fails: +- **Stop. Do not proceed to review or merge.** +- Read the failure (`gh run view --log-failed`), explain it to the user, + and ask whether to fix it now. +- Drift sensors (`govulncheck`, `deadcode`, etc.) failing is + informational — flag them but do not block. -There is no need to `gh pr checks --watch` in the session. If any check -fails, GitHub will refuse to merge and the user will see the failure on -the PR — handle it the next time the user mentions the PR. +### Step 5 — Review the diff -### Step 7 — Tell the user +Once CI is green, invoke the +[`architecture-review`](../architecture-review/SKILL.md) skill on the +**full PR diff** (`git diff main...HEAD`). CI catches mechanical +violations; this catches the rest — behaviour, design, test coverage, +risk, rollback. -Return the PR URL and one sentence on what was queued. Example: +Output what the review found in plain language. Distinguish: +- **Blocking** — must be fixed before merge. +- **Nit** — suggest, but user can choose to defer. +- **Follow-up** — out of scope for this PR; open an issue if material. -> PR opened: . Auto-merge enabled — will land once the 6 required -> checks pass. +### Step 6 — Hand the decision to the user -### Step 8 — Post-merge cleanup (if already merged) +Surface: +1. CI status — all required green. +2. Review findings — blocking? nits? clean? +3. The PR URL. -Immediately re-check whether the PR has already landed — for small PRs -that hit `MERGEABLE` and pass CI in seconds, `gh pr merge --auto` can -complete before the user sees the PR URL: +Then **ask** whether to merge. Do not assume "clean review" means +"merge now" — the user may want to sit on it, ask for a second pair of +eyes, or batch with another change. + +### Step 7 — Merge (only after user confirms) ```bash -gh pr view --json state -q .state +gh pr merge --squash --delete-branch ``` -If the output is `MERGED`, the remote branch has been deleted by -`--delete-branch`. Clean up the local side in the same session so the -user doesn't have to: +No `--auto`. No `--admin`. The branch-protection rules still apply — if +something flipped red between Step 4 and now, GitHub will refuse and +we'll loop back to Step 4. + +### Step 8 — Local cleanup + +After merge succeeds, the remote branch was deleted by `--delete-branch`. +Bring local in sync: ```bash git checkout main && git pull --quiet git branch -d "$(git symbolic-ref --quiet --short @{-1} 2>/dev/null)" ``` -If the output is `OPEN`, do nothing here. The +(`@{-1}` refers to the previously checked-out branch — the one we just +merged.) + +If the user closes the session before reaching Step 8, the [`session-start.sh`](../../hooks/session-start.sh) stale-branch sensor -will catch it on the next session and prompt cleanup. +catches it on the next session and prints the same cleanup hint. ## What NOT to do -- **Do not skip step 2.** "It's a small change" is exactly when archtest - violations sneak in. -- **Do not merge without `--auto`** (i.e. plain `gh pr merge`) unless the - user explicitly asks for an immediate merge. Bypassing required checks - is reserved for emergencies and must be documented. -- **Do not use `--admin`.** That bypasses branch protection entirely. +- **Do not use `--auto`.** It skips Step 5 (review) entirely, which is + the whole reason this skill exists. +- **Do not use `--admin`.** That bypasses branch protection. +- **Do not merge before CI completes.** Even if the diff looks trivial, + let `gh pr checks --watch` finish — drift detection sometimes catches + surprising things. - **Do not amend / force-push** after `gh pr create` unless the user asks - — it invalidates in-flight reviews. -- **Do not push directly to `main`.** Branch protection will reject it - anyway, but try anyway and you'll have to clean up the failed push. + — it invalidates in-flight reviews and re-runs CI from scratch. +- **Do not push directly to `main`.** Branch protection will reject it. +- **Do not silently fix issues found in review.** Surface them, let the + user decide scope. ## Why this is encoded as a skill -Per [docs/HARNESS.md](../../../docs/HARNESS.md), repeated guidance -becomes a control. The post-edit flow ("review → test → push → PR → -auto-merge") was previously oral tradition; encoding it here means: +Per [docs/HARNESS.md](../../../docs/HARNESS.md), repeated guidance becomes +a control. The merge gate has two layers: + +- **Mechanical** (branch protection / required checks) — already + enforced by GitHub. Catches what CI knows how to check. +- **Inferential** (review of the diff) — was previously oral tradition. + Encoding the order here ("CI green THEN review THEN ask THEN merge") + is the harness; without it, the easy thing is auto-merge, which is + cheap and wrong. -1. New agents follow the same recipe without being told. -2. If the recipe changes (e.g. a new required check), this is the one - place to edit, and AGENTS.md points here. -3. Skipped steps become a reviewable diff against this file, not a - judgment call buried in a session transcript. +If the recipe changes (new required check, different review tool), this +is the one place to edit; AGENTS.md points here. diff --git a/AGENTS.md b/AGENTS.md index ef657ec..8914781 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -64,10 +64,13 @@ Project-specific Claude skills live under [`.claude/skills/`](.claude/skills/): - `bootstrap-feature` — how to add a CLI command end-to-end. - `architecture-review` — what to check when reviewing a PR against project invariants. -- `ship-pr` — canonical post-edit flow: local review → L1 → push → - `gh pr create` → `gh pr merge --auto`. Use this instead of calling - `gh pr create` directly so auto-merge against - [`docs/MERGE_POLICY.md`](docs/MERGE_POLICY.md) is consistent. +- `ship-pr` — canonical post-edit flow: push → `gh pr create` → wait + for CI → review the diff → surface findings to the user → user-OK'd + manual `gh pr merge --squash` → local cleanup. Use this instead of + calling `gh pr create` / `gh pr merge` directly. **Do not use + `--auto`** — it skips the review gate, which is the point of having + this skill on top of the branch protection rules in + [`docs/MERGE_POLICY.md`](docs/MERGE_POLICY.md). These are loaded automatically when Claude runs in this repo. diff --git a/docs/HARNESS.md b/docs/HARNESS.md index 6a91c91..b678e7f 100644 --- a/docs/HARNESS.md +++ b/docs/HARNESS.md @@ -56,7 +56,7 @@ Three regulation categories: | Feedfwd. | Skills | model-loaded | `.claude/skills/*` | | Feedfwd. | Session-start hook (warm caches, fetch deps) | every Claude session | `.claude/hooks/session-start.sh` | | Feedback (agent) | Stale-branch sensor (suggests cleanup when current branch's upstream is gone) | every Claude session | `.claude/hooks/session-start.sh` | -| Feedfwd. | `ship-pr` skill — canonical PR flow incl. post-merge cleanup | model-loaded | `.claude/skills/ship-pr/SKILL.md` | +| Feedfwd. | `ship-pr` skill — canonical PR flow (push → CI → review → user-OK'd manual merge → cleanup; **no `--auto`**) | model-loaded | `.claude/skills/ship-pr/SKILL.md` | | Feedback (agent) | `go vet` on edited package | after every Edit/Write/MultiEdit | `.claude/hooks/post-tool-use.sh` | | Feedback (agent) | `go vet ./...` + archtest | end of every Claude turn (if .go dirty) | `.claude/hooks/stop.sh` | | Maint. | `golangci-lint` on the staged diff | local git pre-commit | `scripts/hooks/pre-commit` | From 3cbc146f8b824578debb01e4384abcf435986aee Mon Sep 17 00:00:00 2001 From: fullstackjam Date: Sat, 16 May 2026 22:03:49 +0800 Subject: [PATCH 2/4] =?UTF-8?q?fix(harness):=20ship-pr=20=E2=80=94=20triag?= =?UTF-8?q?e=20review=20findings=20(self-fix=20vs=20escalate)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds Step 6 "Triage the findings" between review and asking the user. Findings split into: - Self-fixable (typos, formatting, missing tests for branches this PR adds, bug fixes that don't change behaviour, following through on a rule the user already stated in-session) → fix in-session, loop back to Step 4. Do not burn the user's attention on them. - Needs user judgment (design, scope, anything touching a prior deliberate choice) → surface, stop. Without this layer, the previous skill would either silently fix everything (over-eager) or escalate every typo (over-cautious). The triage rule comes from the user's instruction in-session and is itself the recursive case — fixing the missing triage rule, in the same PR that adds the rule. --- .claude/skills/ship-pr/SKILL.md | 60 +++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 14 deletions(-) diff --git a/.claude/skills/ship-pr/SKILL.md b/.claude/skills/ship-pr/SKILL.md index b4e3002..892c8ab 100644 --- a/.claude/skills/ship-pr/SKILL.md +++ b/.claude/skills/ship-pr/SKILL.md @@ -98,23 +98,52 @@ Once CI is green, invoke the violations; this catches the rest — behaviour, design, test coverage, risk, rollback. -Output what the review found in plain language. Distinguish: -- **Blocking** — must be fixed before merge. -- **Nit** — suggest, but user can choose to defer. -- **Follow-up** — out of scope for this PR; open an issue if material. - -### Step 6 — Hand the decision to the user - -Surface: +### Step 6 — Triage the findings + +Every finding goes into one of two buckets. Get this right or the gate +fails open. + +**Self-fixable — fix in this session, then loop back to Step 4.** +Anything where the correction is mechanical and clearly inside the +PR's stated scope: +- typos, formatting, doc rewording for clarity, +- dead code that this PR introduced, +- missing imports, missing test cases for branches this PR adds, +- bug fixes that don't change observable behaviour, +- following through on a rule the user has already stated in this + session (this is the recursive case). + +Fix it, push to the same branch, return to Step 4 to wait for CI again, +then come back to Step 5. Do **not** prompt the user. The point of this +branch is to keep the human's attention budget for decisions that +actually need it. + +**Needs user judgment — surface and stop.** +Anything with a real choice or scope question: +- design decisions, API shape, behaviour changes, +- anything that touches a deliberate prior decision (e.g. an explicit + user instruction or an existing convention in CLAUDE.md), +- anything that would expand the PR beyond its stated scope, +- anything you'd ask a teammate about before pushing. + +Surface the finding with the question made explicit; stop the flow. + +**Rule of thumb:** would a thoughtful junior engineer file this as a +question, or just push a follow-up commit? If question → escalate. If +follow-up commit → fix yourself. + +### Step 7 — Hand the decision to the user + +Only reached when Step 6 produced no escalation. Surface: 1. CI status — all required green. -2. Review findings — blocking? nits? clean? +2. Review findings — clean (or list of nits the user might still want). 3. The PR URL. Then **ask** whether to merge. Do not assume "clean review" means "merge now" — the user may want to sit on it, ask for a second pair of eyes, or batch with another change. -### Step 7 — Merge (only after user confirms) +### Step 8 — Merge (only after user confirms) ```bash gh pr merge --squash --delete-branch @@ -124,7 +153,7 @@ No `--auto`. No `--admin`. The branch-protection rules still apply — if something flipped red between Step 4 and now, GitHub will refuse and we'll loop back to Step 4. -### Step 8 — Local cleanup +### Step 9 — Local cleanup After merge succeeds, the remote branch was deleted by `--delete-branch`. Bring local in sync: @@ -137,7 +166,7 @@ git branch -d "$(git symbolic-ref --quiet --short @{-1} 2>/dev/null)" (`@{-1}` refers to the previously checked-out branch — the one we just merged.) -If the user closes the session before reaching Step 8, the +If the user closes the session before reaching Step 9, the [`session-start.sh`](../../hooks/session-start.sh) stale-branch sensor catches it on the next session and prints the same cleanup hint. @@ -152,8 +181,11 @@ catches it on the next session and prints the same cleanup hint. - **Do not amend / force-push** after `gh pr create` unless the user asks — it invalidates in-flight reviews and re-runs CI from scratch. - **Do not push directly to `main`.** Branch protection will reject it. -- **Do not silently fix issues found in review.** Surface them, let the - user decide scope. +- **Do not auto-fix findings that need user judgment.** Anything that + could change behaviour, expand scope, or touches a prior deliberate + choice goes through Step 7 — not a silent commit. Self-fixable items + (typos, missing tests, doc tweaks following a stated rule) are the + exception, not the default. ## Why this is encoded as a skill From d9efa2384863a1f5a85341e5b939aff8d1947b8f Mon Sep 17 00:00:00 2001 From: fullstackjam Date: Sat, 16 May 2026 22:09:27 +0800 Subject: [PATCH 3/4] =?UTF-8?q?fix(harness):=20ship-pr=20=E2=80=94=20merge?= =?UTF-8?q?=20directly=20on=20clean=20review,=20don't=20ask?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previous Step 7 always handed the merge decision to the user, even when review was clean. That defeats the harness loop: asking when there is nothing to decide just burns the user's attention. Triage now has three branches, not two: - Needs user judgment → escalate, stop. - Self-fixable → fix in-session, loop back to Step 4. - Clean → merge directly. No confirmation prompt. User explicitly stated this in-session ("没啥问题,也没啥需要我知道的, 你自己就合并了") — codifying it so the next agent doesn't repeat the over-cautious default. AGENTS.md and docs/HARNESS.md pointer text updated to match. --- .claude/skills/ship-pr/SKILL.md | 35 ++++++++++++++++++--------------- AGENTS.md | 14 +++++++------ docs/HARNESS.md | 2 +- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/.claude/skills/ship-pr/SKILL.md b/.claude/skills/ship-pr/SKILL.md index 892c8ab..3e6ade7 100644 --- a/.claude/skills/ship-pr/SKILL.md +++ b/.claude/skills/ship-pr/SKILL.md @@ -1,6 +1,6 @@ --- name: ship-pr -description: Use when the user wants to open a pull request for the current branch — phrases like "open a PR", "ship this", "submit PR", "let's send it", "提 PR", "提个 MR". Walks through the canonical post-edit flow: push → open PR → wait for CI → review the diff → surface findings → user-confirmed manual merge → local cleanup. Trigger any time the user signals they're done editing and want the change on its way to main; do NOT trigger for `gh pr view` / status checks on existing PRs. +description: Use when the user wants to open a pull request for the current branch — phrases like "open a PR", "ship this", "submit PR", "let's send it", "提 PR", "提个 MR". Walks through the canonical post-edit flow: push → open PR → wait for CI → review the diff → triage findings (self-fix small issues, escalate decisions to the user, merge directly when clean) → local cleanup. Trigger any time the user signals they're done editing and want the change on its way to main; do NOT trigger for `gh pr view` / status checks on existing PRs. --- # Ship a PR for openboot @@ -128,22 +128,20 @@ Anything with a real choice or scope question: Surface the finding with the question made explicit; stop the flow. -**Rule of thumb:** would a thoughtful junior engineer file this as a -question, or just push a follow-up commit? If question → escalate. If -follow-up commit → fix yourself. - -### Step 7 — Hand the decision to the user +**Clean — proceed straight to merge.** +If CI is green AND the diff review found nothing self-fixable AND +nothing that needs user judgment, skip the "ask the user" step and +merge directly. Asking when there is nothing to decide just burns the +user's attention. -Only reached when Step 6 produced no escalation. Surface: -1. CI status — all required green. -2. Review findings — clean (or list of nits the user might still want). -3. The PR URL. +**Rule of thumb:** would a thoughtful junior engineer file this as a +question, push a follow-up commit, or just merge it? Escalate / fix / +merge accordingly. -Then **ask** whether to merge. Do not assume "clean review" means -"merge now" — the user may want to sit on it, ask for a second pair of -eyes, or batch with another change. +### Step 7 — Merge -### Step 8 — Merge (only after user confirms) +Reached when Step 6 ended in "clean", OR when the user has explicitly +approved a merge after an escalation. ```bash gh pr merge --squash --delete-branch @@ -153,7 +151,12 @@ No `--auto`. No `--admin`. The branch-protection rules still apply — if something flipped red between Step 4 and now, GitHub will refuse and we'll loop back to Step 4. -### Step 9 — Local cleanup +Report the merge to the user as a one-liner ("PR #N merged, branch +deleted, local cleaned up"). Do not ask for confirmation **before** +merging on a clean review — the harness loop is supposed to close +itself when there is nothing to decide. + +### Step 8 — Local cleanup After merge succeeds, the remote branch was deleted by `--delete-branch`. Bring local in sync: @@ -166,7 +169,7 @@ git branch -d "$(git symbolic-ref --quiet --short @{-1} 2>/dev/null)" (`@{-1}` refers to the previously checked-out branch — the one we just merged.) -If the user closes the session before reaching Step 9, the +If the user closes the session before reaching Step 8, the [`session-start.sh`](../../hooks/session-start.sh) stale-branch sensor catches it on the next session and prints the same cleanup hint. diff --git a/AGENTS.md b/AGENTS.md index 8914781..c4ff07c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -65,12 +65,14 @@ Project-specific Claude skills live under [`.claude/skills/`](.claude/skills/): - `architecture-review` — what to check when reviewing a PR against project invariants. - `ship-pr` — canonical post-edit flow: push → `gh pr create` → wait - for CI → review the diff → surface findings to the user → user-OK'd - manual `gh pr merge --squash` → local cleanup. Use this instead of - calling `gh pr create` / `gh pr merge` directly. **Do not use - `--auto`** — it skips the review gate, which is the point of having - this skill on top of the branch protection rules in - [`docs/MERGE_POLICY.md`](docs/MERGE_POLICY.md). + for CI → review the diff → triage (self-fix small stuff, escalate + decisions, merge directly when clean) → `gh pr merge --squash` → + local cleanup. Use this instead of calling `gh pr create` / + `gh pr merge` directly. **Do not use `--auto`** — it skips the + review gate, which is the point of having this skill on top of the + branch-protection rules in [`docs/MERGE_POLICY.md`](docs/MERGE_POLICY.md). + **Do not ask the user to confirm a clean merge** — the loop closes + itself when there is nothing to decide. These are loaded automatically when Claude runs in this repo. diff --git a/docs/HARNESS.md b/docs/HARNESS.md index b678e7f..5448e75 100644 --- a/docs/HARNESS.md +++ b/docs/HARNESS.md @@ -56,7 +56,7 @@ Three regulation categories: | Feedfwd. | Skills | model-loaded | `.claude/skills/*` | | Feedfwd. | Session-start hook (warm caches, fetch deps) | every Claude session | `.claude/hooks/session-start.sh` | | Feedback (agent) | Stale-branch sensor (suggests cleanup when current branch's upstream is gone) | every Claude session | `.claude/hooks/session-start.sh` | -| Feedfwd. | `ship-pr` skill — canonical PR flow (push → CI → review → user-OK'd manual merge → cleanup; **no `--auto`**) | model-loaded | `.claude/skills/ship-pr/SKILL.md` | +| Feedfwd. | `ship-pr` skill — canonical PR flow (push → CI → review → triage: self-fix / escalate / merge directly when clean → cleanup; **no `--auto`**, **no "do you want me to merge?" when clean**) | model-loaded | `.claude/skills/ship-pr/SKILL.md` | | Feedback (agent) | `go vet` on edited package | after every Edit/Write/MultiEdit | `.claude/hooks/post-tool-use.sh` | | Feedback (agent) | `go vet ./...` + archtest | end of every Claude turn (if .go dirty) | `.claude/hooks/stop.sh` | | Maint. | `golangci-lint` on the staged diff | local git pre-commit | `scripts/hooks/pre-commit` | From dbff532b8e1ac50fb42751fe1387df6f103cdf83 Mon Sep 17 00:00:00 2001 From: fullstackjam Date: Sat, 16 May 2026 22:12:12 +0800 Subject: [PATCH 4/4] =?UTF-8?q?fix(harness):=20ship-pr=20=E2=80=94=20corre?= =?UTF-8?q?ct=20stale=20step=20reference=20(7=20=E2=86=92=206)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Renumbering left a 'Step 7' reference in the 'What NOT to do' entry pointing at Merge instead of Triage. Escalation happens inside Step 6. --- .claude/skills/ship-pr/SKILL.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.claude/skills/ship-pr/SKILL.md b/.claude/skills/ship-pr/SKILL.md index 3e6ade7..4eb8e69 100644 --- a/.claude/skills/ship-pr/SKILL.md +++ b/.claude/skills/ship-pr/SKILL.md @@ -186,9 +186,9 @@ catches it on the next session and prints the same cleanup hint. - **Do not push directly to `main`.** Branch protection will reject it. - **Do not auto-fix findings that need user judgment.** Anything that could change behaviour, expand scope, or touches a prior deliberate - choice goes through Step 7 — not a silent commit. Self-fixable items - (typos, missing tests, doc tweaks following a stated rule) are the - exception, not the default. + choice gets surfaced in Step 6 — not silently committed. Self-fixable + items (typos, missing tests, doc tweaks following a stated rule) are + the exception, not the default. ## Why this is encoded as a skill