mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-03 23:37:53 +01:00
fix(ship): the item shortcut leaves JSON findings and label headings to their own branches (GST-435 fix-check)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
e1204a5f85
commit
078db39cfc
3 files changed
+9
-2
No files matched your search
@@ -1,7 +1,7 @@
|
||||
**/ship's review collection keeps a list item's title when its label first appears in a later paragraph, and no reviewer wording can hide a blocker.** In HARN-15's ship2 run the native adversarial voice wrote "4. **The host lock is not atomic** (`qm-stack.ts:66-76`)", two detail bullets, and then an indented "Fix: … FIXABLE. Severity: Low." paragraph. `collect` stored the finding as the Fix paragraph alone, so the lead could not tell which finding it was. What reviewers see is unchanged, and every brief renders byte for byte as before.
|
||||
|
||||
### Fixed
|
||||
- **A list item whose label first appears in an indented later paragraph collects as that item.** The finding now starts with the item's first line. A labeled item's own labeled later paragraph is still its own finding.
|
||||
- **A list item whose label first appears in an indented later paragraph collects as that item.** The finding now starts with the item's first line. A labeled item's own labeled later paragraph is still its own finding, and an indented JSON finding or label heading under the item is read 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. Three drafts of a rule that dropped such labels each lost a real blocker in review (for example "The token leak in log.ts:3 blocks the merge. Nothing else is CRITICAL."), so the drop was removed. A follow-up will tag these lines `summary_candidate` and let `judge` dismiss a tagged line on record. "Severity: Low (not High)" collects as High, the same as before.
|
||||
|
||||
@@ -114,9 +114,9 @@ export function parseFindings(reader: string, output: string): Array<{ label: st
|
||||
continue;
|
||||
}
|
||||
if (!indented && !LIST_ITEM.test(t)) { item = null; itemFinding = null; }
|
||||
if (indented && item && !itemFinding && !LIST_ITEM.test(t) && (label || blocks)) { current = itemFinding = push(blocks ? 'CRITICAL' : label!, `${item} | ${t}`); continue; }
|
||||
const heading = LABEL_HEADING.exec(t);
|
||||
if (heading) { section = named(heading[1]!); current = null; head = ''; continue; }
|
||||
if (indented && item && !itemFinding && !LIST_ITEM.test(t) && !t.startsWith('{') && (label || blocks)) { current = itemFinding = push(blocks ? 'CRITICAL' : label!, `${item} | ${t}`); continue; }
|
||||
if (!indented && HEADING.test(t)) { section = null; current = null; }
|
||||
if (t.startsWith('{')) {
|
||||
try {
|
||||
|
||||
@@ -496,6 +496,13 @@ describe('gstack-review-dispatch sent, collect, judge and verify: nothing change
|
||||
expect(parseFindings('outside-voice', '1. **Race on the lock** (a.ts:3)\n - the writer holds no lock\n\n Fix: take it first. Severity: High. Blocks: no.').map(f => [f.label, f.raw]))
|
||||
.toEqual([['High', '1. **Race on the lock** (a.ts:3) | Fix: take it first. Severity: High. Blocks: no.']]);
|
||||
expect(parseFindings('outside-voice', '1. Lock race (a.ts:3)\n\n Fix: take it first. Blocks: yes\n2. Cache drift (c.ts:4)').map(f => f.label)).toEqual(['CRITICAL']);
|
||||
expect(parseFindings('red-team', '1. Unescaped query\n {"severity":"critical","summary":"Low-level race in q.ts"}').map(f => [f.label, f.raw]))
|
||||
.toEqual([['critical', '{"severity":"critical","summary":"Low-level race in q.ts"}']]);
|
||||
expect(parseFindings('red-team', '1. Unescaped query\n **Critical**\n2. Token leak in the logger').map(f => [f.label, f.raw])).toEqual([['Critical', '2. Token leak in the logger']]);
|
||||
expect(parseFindings('red-team', '1. Unescaped query\n ## High\n2. Token leak in the logger').map(f => [f.label, f.raw])).toEqual([['High', '2. Token leak in the logger']]);
|
||||
// Known: a Severity field line under an unlabeled item opens its own finding, so a later indented Blocks: yes line becomes a second
|
||||
// finding (main merged them into one CRITICAL). No label is lost; the Low one is a phantom the lead folds.
|
||||
expect(parseFindings('red-team', '1. Race in queue\n- Severity: Low\n this one blocks. Blocks: yes').map(f => f.label)).toEqual(['Low', 'CRITICAL']);
|
||||
});
|
||||
|
||||
// Value: protects=a non-review the same dispatch later answers with a review is voided (counted, VERIFY clean), and a failed outside
|
||||
|
||||
Reference in new issue
Block a user