docs(receipt): a fenced copy of the exception line is skipped too (GST-977 review)

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-11-02 11:29:33 +00:00
1 parent 8a7d853dfd
commit db666b117f
3 files changed
+6 -4

No files matched your search

@@ -1,7 +1,7 @@
**`gstack-ship-receipt read --check-prose` no longer reads the required Review-loop exception line as counter claims (GST-977).** `write --review-loop-exception` requires the PR body to carry the whole `Review-loop exception: …` line word for word, but the prose check read that line as prose. On gstack-evals #139 the owner's reason "outside 1 and 2 skip detector" was read as a `2 skip` claim against the receipt's 70 skips, so no body could pass both checks.
### Fixed
- **`lib/ship-receipt-prose.ts`:** the line that matches the receipt's own exception exactly (the same test `write` applies) is skipped, like the rendered `## Approvals` block. The same words anywhere else, or a line for a different exception, are still checked.
- **`lib/ship-receipt-prose.ts`:** the line that matches the receipt's own exception exactly (the same test `write` applies) is skipped, like the rendered `## Approvals` block. A copy of that exact line inside a code fence is skipped too, as `write` accepts one. The same words inside a longer line, or a line for a different exception, are still checked.
### Tests
- `test/ship-receipt-prose.test.ts`: the #139 exception text passes `--check-prose` beside a matching `70 skip` claim, and a wrong number elsewhere still fails. On main the same body failed with `gate.unit.skip body=2 receipt=70`.
+2 -1
View File
@@ -1226,7 +1226,8 @@ a `## Approvals` example inside a code fence, are still checked. The
`Review-loop exception: …` line the receipt's own exception requires is
skipped the same way (GST-977): it quotes the owner's reason, so "outside 1 and
2 skip detector" is not a `2 skip` claim. Only a line that matches the rendered
line exactly is skipped; the same words anywhere else are still checked. Data PRs (evals,
line exactly is skipped, inside a code fence too, as the receipt check accepts
a fenced copy; the same words inside a longer line are still checked. Data PRs (evals,
measurements, sweeps) run it before READY so the body's numbers are the run's.
<a id="review-scope"></a>
+3 -2
View File
@@ -69,8 +69,9 @@ function withoutApprovalsBlocks(body: string): string {
/**
* The body without the `Review-loop exception: …` line the receipt's own exception requires (GST-977): write and the
* receipt check want it word for word, and it quotes the owner's reason (`outside 1 and 2 skip detector`), not this
* PR's counters. Only a line whose trimmed text is that rendered line, the test write applies, is left out; the same
* words anywhere else stay prose. A marker line takes its place so the text on either side never joins into a claim.
* PR's counters. Only a line whose trimmed text is that rendered line, the test write applies, is left out (a fenced
* copy too, as write accepts one); the same words inside a longer line stay prose. A marker line takes its place so
* the text on either side never joins into a claim.
*/
function withoutExceptionLine(body: string, exception: unknown): string {
if (exception === undefined) return body;