From 68737b5a3b2a01ef5de52dbaead77a1a849dd55a Mon Sep 17 00:00:00 2001 From: garrytan Date: Sat, 31 Oct 2026 16:58:51 +0000 Subject: [PATCH] docs(ship): a closing-summary phantom stays at its label in the judged set (GST-435 Step 11) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- changelog.d/gst-435-collect-labels.md | 6 +++--- docs/review-policy.md | 2 +- test/review-dispatch.test.ts | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/changelog.d/gst-435-collect-labels.md b/changelog.d/gst-435-collect-labels.md index a580c9fc9..f82ed391e 100644 --- a/changelog.d/gst-435-collect-labels.md +++ b/changelog.d/gst-435-collect-labels.md @@ -1,12 +1,12 @@ **/ship's review collection keeps every label a reviewer writes, and new tests lock that in.** GST-435 tried three ways to stop a reader's own closing summary ("I found three INFORMATIONAL issues and no CRITICAL ones", "Neither finding is CRITICAL.") from collecting as a CRITICAL finding. Each version lost a real blocker in review, for example "The token leak in log.ts:3 blocks the merge. Nothing else is CRITICAL." A fix that kept a list item's title when its label first shows up in a later paragraph also put labels on the wrong finding in review. Collection is unchanged from before, and the tests now hold it there. What reviewers see is unchanged too, and every brief renders byte for byte as before. ### Known -- **A reader's own closing summary still collects at its label.** Lines like "I found three INFORMATIONAL issues and no CRITICAL ones", "found nothing CRITICAL" and GEVA-77's "Neither finding is CRITICAL." collect as CRITICAL, and `judge` won't let the lead drop them, so the lead folds each one. A follow-up will tag these lines `summary_candidate` and let `judge` dismiss a tagged line on record. +- **A reader's own closing summary still collects at its label.** Lines like "I found three INFORMATIONAL issues and no CRITICAL ones", "found nothing CRITICAL" and GEVA-77's "Neither finding is CRITICAL." collect as CRITICAL, and `judge` won't let the lead drop or lower them, so each one stays CRITICAL in the judged set. A follow-up will tag these lines `summary_candidate` and let `judge` dismiss a tagged line on record. - **A list item whose label first appears in an indented later paragraph still collects as that paragraph alone.** In HARN-15's ship2 run, native item 4 ("The host lock is not atomic") collected as its "Fix: …" paragraph without its title. The fix is deferred to the same follow-up. - "Severity: Low (not High)" collects as High, as before. ### Tests -- `test/review-dispatch.test.ts`: every line the GST-435 review rounds found losing or lowering a label collects at its label, including exception clauses, negated subjects, "else" and "other", and a blocker named in an earlier sentence. So do fix-check 5's table rows and harness-evals #152's native FIXABLE findings. The HARN-15 and GEVA-77 summaries are listed as known phantoms that keep their label. An indented JSON finding, an indented label heading and a later `Blocks: yes` under a list item keep their label on the right finding. Fixtures under `test/fixtures/review-ledger/` (already registered to that test). +- `test/review-dispatch.test.ts`: every line the GST-435 review rounds found losing or lowering a label collects at its label, including exception clauses, negated subjects, "else" and "other", and a blocker named in an earlier sentence. So do fix-check 5's table rows and harness-evals #152's native FIXABLE findings. The HARN-15 and GEVA-77 summaries are listed as known phantoms that keep their label. An indented JSON finding, an indented label heading and a later `Blocks: yes` under a list item collect as they did before. Fixtures under `test/fixtures/review-ledger/` (already registered to that test). ### Docs -- `docs/review-policy.md` (collect) says a closing summary collects at its label and the lead folds it. +- `docs/review-policy.md` (collect) says a closing summary collects at its label and keeps it in the judged set. diff --git a/docs/review-policy.md b/docs/review-policy.md index c6a19f4af..d526247bf 100644 --- a/docs/review-policy.md +++ b/docs/review-policy.md @@ -470,7 +470,7 @@ ones, and the arm lost blockers. `bin/gstack-review-dispatch` closes both ends: wherever they stand, headings and table rows included; a top-level list item under a label-only heading takes the stronger of the two). Every label word counts, a reader's own closing summary included ("I found nothing CRITICAL", "Neither finding is CRITICAL"): it - collects at its label and the lead folds it (GST-435). A `Severity:` or `Blocks:` line + collects at its label and stays at that label in the judged set (GST-435). A `Severity:` or `Blocks:` line continues the finding above it until a list item, heading, bold paragraph opener or a second line for the same field starts another: `Severity` raises its label, `Blocks: yes` makes it CRITICAL and `Blocks: no` never lowers it; an inline diff --git a/test/review-dispatch.test.ts b/test/review-dispatch.test.ts index c5f8f5c8c..656efc44c 100644 --- a/test/review-dispatch.test.ts +++ b/test/review-dispatch.test.ts @@ -454,10 +454,10 @@ describe('gstack-review-dispatch sent, collect, judge and verify: nothing change }); // Value: protects=a reader's own closing summary is a known phantom that keeps its label (HARN-15's Red Team and fix-check replies, - // GEVA-77's "Neither finding is CRITICAL.", "found nothing CRITICAL"): it collects, judge refuses to drop it and the lead folds it; the + // GEVA-77's "Neither finding is CRITICAL.", "found nothing CRITICAL"): it collects, and judge refuses to drop or lower it; the // follow-up tags such lines summary_candidate so judge may dismiss a tagged one on record; fails_when=a summary line collects nothing // or a weaker label, which would mean a drop path is back; why_new=GST-435 removed the drop after it lost blockers in three review - // rounds; seam=parseFindings, collect and judge; no_claim=that a phantom is free (it costs a fold) + // rounds; seam=parseFindings, collect and judge; no_claim=that a phantom is free (it stays CRITICAL in the judged set) test('known phantoms: closing summaries keep their label until the summary_candidate follow-up', () => { const fixture = (name: string) => fs.readFileSync(path.join(ROOT, 'test/fixtures/review-ledger', name), 'utf8'); const replies: Array<[string, string, number]> = [['red-team', 'harn15-ship2-red-team.txt', 3], ['red-team', 'harn15-ship2-p2-red-team.txt', 3],