fix: pre-landing review fixes (pass 1)

Twelve informational findings from the /ship pass-1 review, all below the
blocking floor, fixed in place:

- docs-caps reads docs.caps from origin/<base>'s policy (--base <ref>), never
  the branch's copy; an unavailable base policy refuses with
  POLICY_SOURCE_UNAVAILABLE instead of substituting DEFAULT_POLICY
- receiptVersion returns "none" only when the stamp file is absent; other
  errors surface as undefined
- checkReceiptProse groups counters by leaf key and uses word boundaries that
  cover hyphenated names, so shared leaf keys and hyphenated words no longer
  report RECEIPT_PROSE_MISMATCH
- gstack-coauthor-trailers refuses a --range/--base starting with "-",
  prefixes origin/ when origin/<ref> resolves (slash-named branches), and
  passes --end-of-options to git log
- REVIEW_SCOPE_KEY_VERSION and DOCS_CAPS_KEY_VERSION name the releases that
  first read their keys
- the Step 11 late-defer row logs under skill review-late-defer so a tokenless
  review row never reads UNVERIFIED; summarizeReviewLoop counts both
- the "already filed" literal is one constant shared by bin and renderer
- receiptDocs (dead) removed
- Step 14.5 clears .gstack/tmp/docs-audit.json on first entry
- dispatched review prompts carry a literal diff-base sha (<diff-base>) instead
  of a shell variable the reviewer process never sees
- the coauthor-trailers tests launch the bin through runScriptSync so the
  Windows lane can run them

Tests extended for each change; SKILL.md, sections and goldens regenerated.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-26 21:46:04 +00:00
1 parent f9e8f7b1e2
commit d39ea5d631
22 files changed
+241 -91

No files matched your search

+8 -3
View File
@@ -88,9 +88,14 @@ Print the selection:
"Dispatching N specialists: [names]. Skipped: [names] (scope not detected). Gated: [names] (0 findings in N+ reviews)."`;
}
/** The diff command every dispatched reviewer runs: in /ship, pass 2+ reads the range since the previous pass (RANGE_BASE), never the whole branch again. */
/**
* The diff command every dispatched reviewer runs. In /ship the parent writes the
* base sha into the prompt (the merge base on pass 1, RANGE_BASE from pass 2 on):
* a reviewer is its own process and never sees the parent's shell variables, so a
* `$RANGE_BASE` reference there would silently fall back to the whole branch.
*/
function diffBase(ctx: TemplateContext): string {
return ctx.skillName === 'ship' ? 'DIFF_BASE=${RANGE_BASE:-$(git merge-base origin/<base> HEAD)}' : 'DIFF_BASE=$(git merge-base origin/<base> HEAD)';
return ctx.skillName === 'ship' ? 'DIFF_BASE=<diff-base>' : 'DIFF_BASE=$(git merge-base origin/<base> HEAD)';
}
function generateSpecialistDispatch(ctx: TemplateContext): string {
@@ -134,7 +139,7 @@ Every other specialist, including Testing, reads the full diff with fixtures.
5. Instructions:
"You are a specialist code reviewer. Read the checklist at {checklist path}, then run
\`${diffBase(ctx)} && git diff "$DIFF_BASE"\` to get the ${ctx.skillName === 'ship' ? 'diff (the whole branch on pass 1; from pass 2 on, RANGE_BASE is set and the diff is the range since the previous pass)' : 'full diff'}. Apply the checklist against the diff.
\`${diffBase(ctx)} && git diff "$DIFF_BASE"\` to get the ${ctx.skillName === 'ship' ? 'diff (`<diff-base>`: write the sha in before dispatch, the merge base on pass 1 and `RANGE_BASE` from pass 2 on; never a shell variable)' : 'full diff'}. Apply the checklist against the diff.
\`NO FINDINGS\` alone is the expected, complete result for a clean diff; never invent an item to show work. Otherwise output one JSON object per finding, on its own line:
{\\"severity\\":\\"CRITICAL|INFORMATIONAL\\",\\"confidence\\":N,\\"path\\":\\"file\\",\\"line\\":N,\\"category\\":\\"category\\",\\"summary\\":\\"description\\",\\"fix\\":\\"recommended fix\\",\\"fingerprint\\":\\"path:line:category\\",\\"specialist\\":\\"name\\"}