From a2d7a6f0fe75c4d55ae35869bc00cdfa8c3a4553 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Mon, 2 Nov 2026 08:01:05 -0800 Subject: [PATCH] v1.93.4.0 fix(review-ledger): a finding's own Severity field sets its label, not severity words in its text (GST-976) (#3867) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(review-ledger): a finding's Severity field sets its label, body severity words never raise it (GST-976) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(review-ledger): Severity counts only in field position, locus-first and emoji-led labels lead, an inline field floors the next (GST-976 review) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(review-ledger): linear lead-label prefix, all-caps leads before a space, fields after a parenthesis or without a colon at the line start (GST-976 review) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(review-ledger): a lead's file:line has no runaway backtracking and may be a range; a mid-line Severity field must close its clause (GST-976 review) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(review-ledger): a field at the line's start needs no closing clause; mid-line fields accept : / and → after the label (GST-976 fix-check) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: changelog fragment and review-policy collect step for GST-976 Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * fix(review-ledger): a Severity field's label chain (High/Critical) takes its strongest label; mid-line fields keep the clause-closing set (GST-976 scoped check) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * test(review-ledger): never weaker than main invariant over pinned inputs, fixtures and generated field shapes; a multi-label Severity field counts as none, lowercase fields keep their label (GST-976) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> * docs: GST-976 re-audit, multi-label and lowercase Severity fields Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --------- Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- CHANGELOG.md | 8 ++ VERSION | 2 +- agents-digest/gstack-AGENTS.md | 2 +- docs/review-policy.md | 5 +- lib/review-ledger.ts | 50 ++++++++--- package.json | 2 +- test/fixtures/review-ledger/main-labels.json | 1 + test/review-dispatch.test.ts | 91 ++++++++++++++++++-- test/review-ledger-invariant.test.ts | 46 ++++++++++ 9 files changed, 185 insertions(+), 22 deletions(-) create mode 100644 test/fixtures/review-ledger/main-labels.json create mode 100644 test/review-ledger-invariant.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index f79cbdd8f..9e8ede21c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## [1.93.4.0] - 2026-11-02 + +**/ship's finding collector reads severity from a finding's own Severity field, so a severity word in the finding's text no longer raises it.** + +### Fixed + +- When a reader's finding carries its own `Severity:` field, the collector uses that field. A word like "P0" in the finding's text (a plan phase name, for example) no longer makes it a blocker the reader marked `Blocks: no`. A label leading the line (`CRITICAL:`, `[P0]`, `- High:`, a label heading) still sets the floor, `Blocks: yes` still makes a finding CRITICAL, and the native voice's FIXABLE still collects as CRITICAL. A field that names more than one label ("High/Critical") counts as no field, and a lowercase `severity:` keeps its label. Lines with no Severity field collect as before. (GST-976) + ## [1.93.3.0] - 2026-11-02 **The queue now refuses a head whose required targeted review is missing or failed (GST-966).** On gstack-evals#140, the receipt showed `REVIEW_TARGETED: required=auth receipt=legacy verdict=missing` and `gstack-ship-queue ready` still exited 0, so a skipped required reader looked the same as a clean one. diff --git a/VERSION b/VERSION index 60f5b647e..a52c976ef 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.93.3.0 +1.93.4.0 diff --git a/agents-digest/gstack-AGENTS.md b/agents-digest/gstack-AGENTS.md index cf103d7a3..ad9ada396 100644 --- a/agents-digest/gstack-AGENTS.md +++ b/agents-digest/gstack-AGENTS.md @@ -1,4 +1,4 @@ -# gstack digest v1.93.3.0 — regenerate/re-copy after upgrading gstack +# gstack digest v1.93.4.0 — regenerate/re-copy after upgrading gstack Behavioral rules from gstack (https://github.com/garrytan/gstack), compressed for agent hosts without a full skill install. The full skills add workflows, diff --git a/docs/review-policy.md b/docs/review-policy.md index 0ed8e3e9b..328d8b944 100644 --- a/docs/review-policy.md +++ b/docs/review-policy.md @@ -540,10 +540,11 @@ ones, and the arm lost blockers. `bin/gstack-review-dispatch` closes both ends: 3. `collect` hashes each reader's raw output and appends its findings to `merged.jsonl` with the label as written (a JSON line's `severity`, or the most severe of a prose line's Critical, High, Medium, Low, P0-P3, FIXABLE or INVESTIGATE - wherever they stand, headings and table rows included; a top-level list item under a + wherever they stand, headings and table rows included, except that a line with its own `Severity` field takes that + field's label (any letter case; a field stating more than one label, "High/Critical", counts as none), so a severity word in the finding's text does not raise it, and a label leading the line stays its floor (GST-976); a top-level list item under a label-only heading takes the stronger of the two). 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, + second line for the same field starts another: `Severity` sets its label (a label leading the finding stays its floor), `Blocks: yes` makes it CRITICAL and `Blocks: no` never lowers it; an inline `Blocks: yes` is CRITICAL too, and with no finding above it is one. The native adversarial voice's FIXABLE collects as CRITICAL (normalizer v2, GSTA-167). An unnumbered, unlabeled bullet with no file:line diff --git a/lib/review-ledger.ts b/lib/review-ledger.ts index dd3266dee..4406d59c5 100644 --- a/lib/review-ledger.ts +++ b/lib/review-ledger.ts @@ -8,8 +8,8 @@ * judgment each lead-judgment change: an added or promoted finding, with its reason * judge the verdict on the parent's judged set (ok, or the dropped and downgraded ids) * - * Findings reach merged.jsonl only through collect, with each voice's label as written (a prose line's most severe one, - * raised by the Severity line below it), except that a prose voice's `Blocks: yes` and the native voice's FIXABLE collect + * Findings reach merged.jsonl only through collect, with each voice's label as written (a prose finding's own Severity field when + * it has one, else its line's most severe label), except that a prose voice's `Blocks: yes` and the native voice's FIXABLE collect * as CRITICAL (GSTA-167 normalizer v2). * The parent's judged set may add or promote a finding and may fold a duplicate into one at least * as severe; it never drops or downgrades one. verify replays every check from the ledger alone. @@ -67,6 +67,20 @@ const META = new RegExp(`^(?:[-*+]\\s+)?\\**\\s*(Severity|Blocks)\\**\\s*(?::|\\ /** The severity and Blocks a prose finding's own fields state (GST-766): recorded beside the collected label, never in its place. */ export interface Stated { severity?: string; blocks?: string } const STATED_SEVERITY = new RegExp(`(?]\\s+|\\d+[.)]\\s+)?\\**\\s*Severity\\**\\s*:?\\s*\\**\\s*((?:${LABELS})(?:\\s*[/→]\\s*\\**\\s*(?:${LABELS}))*)(?![A-Za-z0-9])|(?:[.;,|()]\\s*|\\s[—–-]\\s*)\\**\\s*Severity\\**\\s*:\\s*\\**\\s*((?:${LABELS})(?:\\s*[/→]\\s*\\**\\s*(?:${LABELS}))*)(?![A-Za-z0-9])(?=\\**\\s*(?:$|[.;,|()*—–]|-\\s|Blocks)))`, 'gi'); +/** + * A label leading its line past list, quote, heading, emphasis and emoji marks (one mark per step, so a long divider stays linear) + * and an optional file:line, closed by a mark or a separator, or by a space, comma or parenthesis after an all-caps word ("[P0] …", + * "1. **High**: …", "### CRITICAL: …", "1. api.ts:10 CRITICAL: …", "1. CRITICAL missing auth"): the reader's own label, which a + * Severity field never lowers. "P0 pilot …" is not one. + */ +const FIELD_LABELS = new RegExp(ANY_LABEL.source, 'gi'); +const LEAD_LABEL = new RegExp(`^(?:[^\\p{L}\\p{N}\\s]\\s*|\\d+[.)]\\s*)*(?:\\w[\\w./-]*:\\d+(?:[-–:,]\\s*\\d+)*[^\\p{L}\\p{N}\\s]*\\s+(?:[^\\p{L}\\p{N}\\s]\\s*)*)?(${LABELS})(?=[*_\`\\])]|\\s*[:|—–]|\\s+-\\s|\\s*$|(?<=[A-Z]{3})[\\s,(.])`, 'u'); const STATED_BLOCKS = /(? { - type Finding = { label: string; raw: string; fields: Set; list: boolean }; + type Finding = { label: string; raw: string; fields: Set; list: boolean; lead?: string }; const out: Finding[] = []; let section: string | null = null; let current: Finding | null = null; @@ -97,8 +113,17 @@ export function parseFindings(reader: string, output: string): Array<{ label: st let treeSeen = false; const role = reader.split('/')[0]; const named = (l: string) => (role === 'adversarial-native' && l.toUpperCase() === 'FIXABLE' ? 'CRITICAL' : l); - const strongest = (t: string) => [...t.matchAll(ALL_LABELS)].map(m => named(m[1]!)).reduce((a, b) => (a === undefined ? b : stronger(a, b)), undefined); - const push = (label: string, raw: string, fields: string[] = []): Finding => { const f = { label, raw, fields: new Set(fields), list: LIST_ITEM.test(raw) }; out.push(f); return f; }; + const strongestOf = (labels: Array) => labels.reduce((a, b) => (a === undefined ? b : b === undefined ? a : stronger(a, b)), undefined); + const strongest = (t: string) => strongestOf([...t.matchAll(ALL_LABELS)].map(m => named(m[1]!))); + const fieldOf = (t: string) => { const ls = [...t.matchAll(SEVERITY_FIELD)].flatMap(m => (m[1] ?? m[2]!).match(FIELD_LABELS)!); return ls.length === 1 ? ls[0] : undefined; }; + const critical = (t: string) => BLOCKS_YES.test(t) || (role === 'adversarial-native' && /(? { const l = LEAD_LABEL.exec(t)?.[1]; return l === undefined ? undefined : named(l); }; + const labelOf = (t: string) => { + const field = fieldOf(t); + if (field === undefined) return strongest(t); + return critical(t) ? 'CRITICAL' : strongestOf([leadOf(t), field])!; + }; + const push = (label: string, raw: string, fields: string[] = [], lead?: string): Finding => { const f = { label, raw, fields: new Set(fields), list: LIST_ITEM.test(raw), lead }; out.push(f); return f; }; for (const line of output.replace(/\r\n/g, '\n').split('\n')) { const t = line.trim(); if (!t) { gap = true; continue; } @@ -107,7 +132,7 @@ export function parseFindings(reader: string, output: string): Array<{ label: st gap = false; if (/^NO FINDINGS\.?$/.test(t) || /^Recommendation:/i.test(t)) { current = null; continue; } const indented = line !== line.trimStart(); - const label = strongest(t); + const label = labelOf(t); const blocks = BLOCKS_YES.test(t); const listItem = !indented && LIST_ITEM.test(t); const locus = LOCUS.test(t); @@ -117,6 +142,7 @@ export function parseFindings(reader: string, output: string): Array<{ label: st if (current && !current.fields.has(field)) { current.fields.add(field); if (blocks) current.label = 'CRITICAL'; + else if (field === 'severity' && fieldOf(t) !== undefined && !critical(current.raw)) current.label = strongestOf([current.lead, label])!; else if (label) current.label = stronger(current.label, label); current.raw += ` | ${t}`; } else if (blocks || label) current = push(blocks ? 'CRITICAL' : label!, head ? `${head} | ${t}` : t, [field]); @@ -129,7 +155,7 @@ export function parseFindings(reader: string, output: string): Array<{ label: st if (t.startsWith('{')) { try { const o = JSON.parse(t) as Record; - if (typeof o.severity === 'string') { current = push(o.severity, t); continue; } + if (typeof o.severity === 'string') { current = push(o.severity, t, [], o.severity); continue; } } catch { /* prose that starts with a brace */ } } const detail = listItem && /^[-*+]\s/.test(t) && !locus && !label && !section && !!current && !current.list && !current.fields.size; @@ -138,7 +164,11 @@ export function parseFindings(reader: string, output: string): Array<{ label: st if (fresh) { current = null; head = t; } const inherited = section && listItem ? section : undefined; const found = label && inherited ? stronger(inherited, label) : label ?? inherited; - if (found) { current = push(blocks ? 'CRITICAL' : found, t); if (!indented) head = t; continue; } + if (found) { + current = push(blocks ? 'CRITICAL' : found, t, [], strongestOf([leadOf(t), inherited, fieldOf(t)])); + if (!indented) head = t; + continue; + } if (blocks && !t.startsWith('{')) { if (current) { current.label = 'CRITICAL'; current.raw += ` | ${t}`; continue; } current = push('CRITICAL', head && head !== t ? `${head} | ${t}` : t); diff --git a/package.json b/package.json index dd09256e6..84b50853b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gstack", - "version": "1.93.3", + "version": "1.93.4", "description": "Garry's Stack — Claude Code skills + fast headless browser. One repo, one install, entire AI engineering workflow.", "license": "MIT", "type": "module", diff --git a/test/fixtures/review-ledger/main-labels.json b/test/fixtures/review-ledger/main-labels.json new file mode 100644 index 000000000..c923a6ceb --- /dev/null +++ b/test/fixtures/review-ledger/main-labels.json @@ -0,0 +1 @@ +{"note":"parseFindings labels at main 82e9d7ec (GST-976): every input the review-dispatch and prose-voice-floor tests pass it, every reader fixture here, and generated Severity field shapes. Regenerate only from a frozen main.","main":"82e9d7ec7a2c222f20b04aaf5b965fa50d7b6bdb","entries":[{"source":"pinned","reader":"adversarial-native","output":"FIXABLE: race in a.ts:3\nSeverity: Medium\nBlocks: no","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"INVESTIGATE: odd lock in b.ts:9\nSeverity: Low\nBlocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"INVESTIGATE: odd lock in b.ts:9\nBlocks: no","main":["INVESTIGATE"]},{"source":"pinned","reader":"adversarial-native","output":"FIXABLE: race in a.ts:3. Severity: Medium. Blocks: no","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"1. FIXABLE: race in a.ts:3 — Severity: Low, Blocks: no","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"- FIXABLE: race in a.ts:3\n- Severity: Medium\n- Blocks: no","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Drops the last row (q.ts:7). Severity: Critical. Blocks: no","main":["Critical"]},{"source":"pinned","reader":"outside-voice","output":"1. Cache evicts sessions (c.ts:4)\n Severity: High","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"1. Retry storm (r.ts:2)\n Severity: Medium\n Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Index drift (i.ts:5). Severity: Low. Blocks: Yes, it loses the row","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Naming (n.ts:1)\n Severity: Low\n Blocks: no","main":["Low"]},{"source":"pinned","reader":"specialist/testing","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\nNO FINDINGS\n","main":[]},{"source":"pinned","reader":"specialist/testing","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\n{\"severity\":\"CRITICAL\",\"path\":\"a.ts\",\"line\":3,\"category\":\"logic\",\"summary\":\"off by one\",\"specialist\":\"testing\"}\n{\"severity\":\"INFORMATIONAL\",\"path\":\"a.ts\",\"line\":9,\"category\":\"style\",\"summary\":\"name\",\"specialist\":\"testing\"}\n","main":["CRITICAL","INFORMATIONAL"]},{"source":"pinned","reader":"outside-voice","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\nFindings:\n1. **High**: retry loop never backs off (q.ts:78)\n2. Low - log line is noisy\nRecommendation: Fix the retry because it DoSes the pool\n","main":["High","Low"]},{"source":"pinned","reader":"specialist/testing","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\n{\"severity\":\"CRITICAL\",\"path\":\"a.ts\",\"line\":3,\"category\":\"logic\",\"summary\":\"x\",\"specialist\":\"testing\"}\n","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\n{\"severity\":\"CRITICAL\",\"path\":\"b.ts\",\"line\":1,\"category\":\"x\",\"summary\":\"y\",\"specialist\":\"red-team\"}\n","main":["CRITICAL"]},{"source":"pinned","reader":"specialist/testing","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\n{\"severity\":\"CRITICAL\",\"path\":\"a.ts\",\"line\":3,\"category\":\"logic\",\"summary\":\"x\",\"specialist\":\"testing\"}\n{\"severity\":\"INFORMATIONAL\",\"path\":\"b.ts\",\"line\":1,\"category\":\"n\",\"summary\":\"y\",\"specialist\":\"testing\"}\n","main":["CRITICAL","INFORMATIONAL"]},{"source":"pinned","reader":"r","output":"NO FINDINGS\n","main":[]},{"source":"pinned","reader":"r","output":"## High\n1. The auth check skips webhooks (a.ts:4)\n - Impact: nested evidence\n **Fix:**\n- second one\n## Notes\n- not a finding\n**Critical findings**\n- real one\n**Recommendations**\n- consider renaming foo\n","main":["High","High","Critical"]},{"source":"pinned","reader":"r","output":"1. **Unbounded retry in queue.ts:78** (FIXABLE): loops on 429\n2. `auth.ts:42` skips token expiry check — INVESTIGATE\n### CRITICAL: missing auth check in api.ts:10\n#### [P1] token not expired\n### High: authorization bypass (auth.ts:14)\n- **HIGH**: leak\n| High | race in queue.ts:4 |\nClassification: INVESTIGATE\n7. **Informational: reads every file**","main":["FIXABLE","INVESTIGATE","CRITICAL","P1","High","HIGH","High","INVESTIGATE","Informational"]},{"source":"pinned","reader":"r","output":"FIXABLE: race in a.ts:3\nINVESTIGATE: odd lock\nRecommendation: Fix the race because x\n","main":["FIXABLE","INVESTIGATE"]},{"source":"pinned","reader":"outside-voice","output":"No CRITICAL issues except the token leak in log.ts:3","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No CRITICAL issues except the token leak in log.ts:3","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"No CRITICAL issues except the token leak in log.ts:3","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"No CRITICAL issues except the token leak in log.ts:3","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"There is no CRITICAL issue other than the SQL injection at db.ts:12","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"There is no CRITICAL issue other than the SQL injection at db.ts:12","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"There is no CRITICAL issue other than the SQL injection at db.ts:12","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"There is no CRITICAL issue other than the SQL injection at db.ts:12","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing CRITICAL apart from the auth bypass (auth.ts:9).","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"Nothing CRITICAL apart from the auth bypass (auth.ts:9).","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"Nothing CRITICAL apart from the auth bypass (auth.ts:9).","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"Nothing CRITICAL apart from the auth bypass (auth.ts:9).","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No new CRITICAL findings, but the token leak in log.ts:3 still blocks.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No new CRITICAL findings, but the token leak in log.ts:3 still blocks.","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"No new CRITICAL findings, but the token leak in log.ts:3 still blocks.","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"No new CRITICAL findings, but the token leak in log.ts:3 still blocks.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"None CRITICAL besides the race in queue.ts:40, which loses writes.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"None CRITICAL besides the race in queue.ts:40, which loses writes.","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"None CRITICAL besides the race in queue.ts:40, which loses writes.","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"None CRITICAL besides the race in queue.ts:40, which loses writes.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"- **No CRITICAL** issues remain except F2 (store.ts:22 corrupts data).","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"- **No CRITICAL** issues remain except F2 (store.ts:22 corrupts data).","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"- **No CRITICAL** issues remain except F2 (store.ts:22 corrupts data).","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"- **No CRITICAL** issues remain except F2 (store.ts:22 corrupts data).","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"REVIEWED_TREE: bedd511efa0fa16c9277821073c68e438dc760d2 /workspace/gstack-evals\n{\"severity\":\"INFORMATIONAL\",\"path\":\"wiki/board/README.md\",\"line\":229,\"summary\":\"Section 9's opening still says every ruling is recorded in the approvals file.\"}\n{\"severity\":\"INFORMATIONAL\",\"path\":\"wiki/board/README.md\",\"line\":113,\"summary\":\"The tstack row still runs on full stacks-r1 and is not labelled raw.\"}\n\nI checked these against the post, the frozen texts and the pinned code, and found nothing CRITICAL. The arithmetic is consistent throughout:\n- The new secondary: 47/60, 15/60, 5/40, 7/40, 4/40 and 11.5/40.\n- The minimum p of 2^-15.","main":["INFORMATIONAL","INFORMATIONAL","CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"Found no CRITICAL issues in the fix range.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"Nothing CRITICAL or HIGH remains.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"This is not CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"I found zero Critical findings, and none High.","main":["Critical"]},{"source":"pinned","reader":"fix-check","output":"The retry path is safe; without CRITICAL impact.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No new CRITICAL issues introduced by the fix.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No remaining CRITICAL or HIGH findings.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"**No** CRITICAL issues found.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No **CRITICAL** issues found.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No `CRITICAL` issue.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No [P1] issues remain.","main":["P1"]},{"source":"pinned","reader":"fix-check","output":"Nothing at CRITICAL severity remains.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No CRITICAL regressions introduced by the fix.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"Nothing CRITICAL to report.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"There is nothing CRITICAL in the fix range.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No CRITICAL — the fix is sound.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"Found no CRITICAL or HIGH regressions.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No HIGH-risk changes.","main":["HIGH"]},{"source":"pinned","reader":"fix-check","output":"No CRITICAL/HIGH findings.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No P0/P1 issues.","main":["P0"]},{"source":"pinned","reader":"fix-check","output":"No CRITICAL, HIGH or MEDIUM issues.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"Checked collect() at lib/review-ledger.ts:189; no CRITICAL issues remain.","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"No CRITICAL issues; served on localhost:3000.","main":["CRITICAL"]},{"source":"pinned","reader":"r","output":"Not CRITICAL, but High: the cache drops a row (c.ts:4)","main":["CRITICAL"]},{"source":"pinned","reader":"r","output":"No CRITICAL, High: the cache drops a row (c.ts:4)","main":["CRITICAL"]},{"source":"pinned","reader":"r","output":"Nothing CRITICAL / HIGH: race in q.ts:7","main":["CRITICAL"]},{"source":"pinned","reader":"r","output":"No CRITICAL lock guards the write in Makefile:7\nSeverity: CRITICAL","main":["CRITICAL"]},{"source":"pinned","reader":"r","output":"1. auth.ts:3 LOW: log line too verbose\nNo CRITICAL lock guards the write in Makefile:7\nSeverity: CRITICAL","main":["LOW","CRITICAL"]},{"source":"pinned","reader":"r","output":"1. auth.ts:3 LOW: log line too verbose\nNo CRITICAL issues remain.","main":["LOW","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"- a.ts:3 race. Severity: Low. Blocks: no\n Separately, nothing CRITICAL about b.ts:9, but it leaks fds.\n Severity: High","main":["Low","CRITICAL"]},{"source":"pinned","reader":"r","output":"1. A CRITICAL race in queue.ts:78 that no lock covers","main":["CRITICAL"]},{"source":"pinned","reader":"r","output":"- A divide by zero CRITICAL bug in parse()","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"FIXABLE: no timeout on the fetch in a.ts:3","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Retry loop drops the last row (queue.ts:78). Severity: Medium · Blocks: yes\n2. INVESTIGATE: lock order in pool.ts:12\n Blocks: yes\n3. FIXABLE: stale cache key (cache.ts:4)\n Severity: High\n Blocks: no\n4. Token never expires (auth.ts:9)\n Fix: check exp\n **Blocks:** yes\nRecommendation: Fix the retry loop because it loses rows","main":["CRITICAL","CRITICAL","High","CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"1. INVESTIGATE: lock order in pool.ts:12\n Severity: Medium\n Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Low-level retry loop in queue.ts:78 drops writes on 429. Severity: Critical. Blocks: no\n- [P2] cache.ts:40 evicts live sessions. Severity: High. Blocks: no","main":["Critical","High"]},{"source":"pinned","reader":"outside-voice","output":"1. FIXABLE: race in a.ts:3\nWhy it matters: two writers\nSeverity: Low\nBlocks: yes\n2. Unlabeled item about b.ts:9\nSeverity: Medium","main":["CRITICAL","Medium"]},{"source":"pinned","reader":"outside-voice","output":"1. Token never expires (auth.ts:9). Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Token never expires in auth.ts:9 — Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Token never expires (auth.ts:9)\nFix: check exp **Blocks:** yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"## Critical findings\n- Severity: Medium — missing owner check at auth.ts:14\n- Severity: Low — token logged at log.ts:3","main":["Critical","Critical"]},{"source":"pinned","reader":"outside-voice","output":"**Finding 1.** a.ts:3 drops rows\nSeverity: Low\nBlocks: no\n**Finding 2.** b.ts:4 leaks\nSeverity: High\nBlocks: yes","main":["Low","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"a.ts:3 drops rows\nSeverity: High\nBlocks: yes\nb.ts:4 leaks\nSeverity: High\nBlocks: yes","main":["CRITICAL","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Medium: cache key drift (c.ts:4)\n Blocks the event loop on every miss - High","main":["Medium","High"]},{"source":"pinned","reader":"outside-voice","output":"2. Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"> Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"A in a.ts:1.\nSeverity: Low\n\nB in b.ts:2.\nBlocks: yes","main":["Low","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"A in a.ts:1.\nSeverity: Low\nB in b.ts:2.\nBlocks: yes","main":["Low","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Findings:\n A in a.ts:1.\n Severity: Low\n B in b.ts:2.\n Blocks: yes","main":["Low","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"A in a.ts:1.\nSeverity: Low\nB in b.ts:2 drops rows. Blocks: yes","main":["Low","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"**Finding 1.** a.ts:3 races. Severity: Low\n**Finding 2.** b.ts:4 leaks. Blocks: yes","main":["Low","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"FIXABLE: race in a.ts:3\nSeverity: Medium\nWhy: the writer races\nBlocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"- Unlabeled thing in a.ts:3\n- Severity: Medium\n- Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Token never expires (auth.ts:9)\nFix: check exp\nBlocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Retry storm (r.ts:2)\nSeverity High","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"CRITICAL: x.ts:4 drops rows (pass 1 had Severity: Low)","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native/adversarial","output":"FIXABLE: race in a.ts:3\nSeverity: Medium\nBlocks: no","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"FIXABLE: race in a.ts:3\nSeverity: Medium","main":["Medium"]},{"source":"pinned","reader":"outside-voice","output":"1. Retry loses writes (queue.ts:78). Severity: Medium\n Fix: reject the batch. Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"specialist-batched","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\nI couldn't run the review because the diff base doesn't exist. `git diff 1b68e637c07cea38f01c01120e02d184575da82c` fails with \"bad object\", and fetching that sha from origin is refused with \"not our ref\", so the commit is neither in this checkout nor on the remote.\n\nThis checkout is on `main` at 047dad7 (v1.91.357.0), tracking origin/main with no uncommitted changes, so there's nothing local to review against either. I'm not returning NO FINDINGS, because that would claim a clean diff I never saw.\n\nTo continue I need one of these: a diff base that exists, or the branch or sha holding the c3-36-p1 change. It may only exist on another machine and was never pushed. I've read all three checklists (testing, security, state-machines) and will apply them as soon as I have a diff.","main":[]},{"source":"pinned","reader":"specialist/testing","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\n","main":[]},{"source":"pinned","reader":"specialist/testing","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\nI could not access the diff: git diff failed with \"bad object\", so there is nothing here to review.\n","main":[]},{"source":"pinned","reader":"specialist/testing","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\n{\"severity\":\"CRITICAL\",\"path\":\"a.ts\",\"line\":3,\"category\":\"logic\",\"summary\":\"off by one\",\"specialist\":\"testing\"}\n","main":["CRITICAL"]},{"source":"pinned","reader":"specialist/testing","output":"NO FINDINGS\n","main":[]},{"source":"pinned","reader":"specialist-batched","output":"`NO FINDINGS`\n","main":[]},{"source":"pinned","reader":"targeted","output":"NO FINDINGS\n","main":[]},{"source":"pinned","reader":"fix-check","output":"NO FINDINGS\n","main":[]},{"source":"pinned","reader":"red-team","output":"Fixtures were reviewed in summary mode only.\n\nNO FINDINGS\n","main":[]},{"source":"pinned","reader":"adversarial-native","output":"Fixtures were reviewed in summary mode.\n\nRecommendation: Ship as-is because no finding survived tracing\n","main":[]},{"source":"pinned","reader":"adversarial-native","output":"NO FINDINGS\n","main":[]},{"source":"pinned","reader":"outside-voice","output":"No actionable findings in the supplied diff. Static review only.\n\nRecommendation: approve because the diff introduces no demonstrated bypass.\n","main":[]},{"source":"pinned","reader":"outside-voice","output":"NO FINDINGS\n","main":[]},{"source":"pinned","reader":"specialist/testing","output":"Recommendation: ship because it is clean\n","main":[]},{"source":"pinned","reader":"specialist/testing","output":"I'm not returning NO FINDINGS, because I never saw the diff.\n","main":[]},{"source":"pinned","reader":"red-team","output":"","main":[]},{"source":"pinned","reader":"fix-check","output":"The fixes look fine to me.\n","main":[]},{"source":"pinned","reader":"adversarial-native","output":"I could not read the diff.\n","main":[]},{"source":"pinned","reader":"adversarial-native","fixture":"review-ledger/gsta-196-native.txt","main":["High","CRITICAL","CRITICAL","Low"]},{"source":"pinned","reader":"outside-voice","output":"1. FIXABLE: race in a.ts:3\n- Unlabeled sibling at b.ts:9\nSeverity: Medium","main":["FIXABLE","Medium"]},{"source":"pinned","reader":"outside-voice","output":"**Retry storm in r.ts:2 (INVESTIGATE).**\n- detail\n- High: a second defect in s.ts:4\nSeverity: Medium","main":["INVESTIGATE","High"]},{"source":"pinned","reader":"outside-voice","output":"Low: cache TTL mismatch (cache.ts:4)\n\n2. Token never expires (auth.ts:9)\nSeverity: High\nBlocks: yes","main":["Low","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"**Race in a.ts:3 (High).**\n- the writer holds no lock\nSeverity: Medium","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"**Race in a.ts:3 (Medium).**\n\n- the writer holds no lock\n\nSeverity: Medium. Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"fix-check","output":"{\"severity\":\"INFORMATIONAL\",\"path\":\"a.ts\",\"line\":3,\"summary\":\"Severity: High is the wrong word here\"}\n","main":["INFORMATIONAL"]},{"source":"pinned","reader":"outside-voice","output":"| 1 | `CRITICAL` | High | token leak in log.ts:3 |","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"| log.ts:3 | `CRITICAL` | High | token leak |","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"None of the writes are atomic and are CRITICAL (queue.ts:78); High confidence","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing guards the write path the failure of which is CRITICAL","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"| a.ts:3 | race | not CRITICAL, Low |","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"| a.ts:3 | maps `FIXABLE` to `CRITICAL` in a comment | Low |","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Neither path checks auth so this is CRITICAL (a.ts:3)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"None of the inputs are sanitized so this is CRITICAL (a.ts:3)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing checks the token which is CRITICAL (a.ts:3)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No bounds check lets CRITICAL data leak (a.ts:3)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No defects in parsing but the upload handler is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Without auth this is CRITICAL (a.ts:3)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Not checking expiry at auth.ts:9 lets stale tokens through. Severity: High","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"The lock isn't released on error (pool.ts:12): High","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"A retry storm could escalate up to CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Low: the parser now maps `FIXABLE` to `CRITICAL` in a comment (a.ts:3)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No input validation is CRITICAL (upload.ts:4)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No CSRF token is a CRITICAL gap at form.ts:12","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing escaped here is CRITICAL: stored XSS at view.ts:8","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No timeout here is High (fetch.ts:3)","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"Upgraded: not High, CRITICAL (a.ts:3)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Severity: not Medium, CRITICAL","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing else is CRITICAL except the token leak in log.ts:3.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No other issue is CRITICAL besides the auth bypass in auth.ts:9.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"None of the other findings are CRITICAL, but the SQL injection in db.ts:12 is.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing here is CRITICAL apart from the unescaped query (db.ts:12).","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing else is CRITICAL except the token leak.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Fix the token leak in log.ts:3 first; nothing else is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"The token leak in log.ts:3 blocks the merge. Nothing else is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Token leak in log.ts:3 must be fixed before landing.\n\nNothing else is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"The token leak blocks the merge.\nNo other issue is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"The token leak in log.ts:3 blocks the merge. None of the other findings are CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"The token leak in log.ts:3 must block the merge. The other two are nits. Neither finding is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Apart from the token leak in log.ts:3, I found two nits. Neither finding is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Besides the auth bypass at auth.ts:9 there are three nits. None of the three findings are CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"The token leak in log.ts:3 must block the merge. Nothing here is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No auth check guards the admin route, so nothing CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"adversarial-native","fixture":"review-ledger/harn15-152-p1-adversarial-native.txt","main":["CRITICAL","INVESTIGATE","INVESTIGATE","CRITICAL","INVESTIGATE","INVESTIGATE","CRITICAL"]},{"source":"pinned","reader":"adversarial-native","output":"**1. Race in a.ts:3 (`FIXABLE`).**\nSeverity: Low. Blocks: no","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"1. Race in a.ts:3 (FIXABLE).","main":["FIXABLE"]},{"source":"pinned","reader":"adversarial-native","output":"No rate limit is FIXABLE (login.ts:9)","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","fixture":"review-ledger/harn15-ship2-red-team.txt","main":["CRITICAL","INFORMATIONAL","INFORMATIONAL","INFORMATIONAL"]},{"source":"pinned","reader":"red-team","fixture":"review-ledger/harn15-ship2-p2-red-team.txt","main":["CRITICAL","INFORMATIONAL","INFORMATIONAL","INFORMATIONAL"]},{"source":"pinned","reader":"fix-check","fixture":"review-ledger/harn15-ship2-p2-fix-check.txt","main":["CRITICAL","INFORMATIONAL","INFORMATIONAL","INFORMATIONAL","INFORMATIONAL"]},{"source":"pinned","reader":"fix-check","fixture":"review-ledger/harn15-152-p2-fix-check.txt","main":["CRITICAL","INFORMATIONAL","INFORMATIONAL"]},{"source":"pinned","reader":"fix-check","fixture":"review-ledger/geva-77-fix-check.txt","main":["INFORMATIONAL","INFORMATIONAL","CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"There are no CRITICAL findings.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"No CRITICAL or High findings to report.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"I found nothing CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"So there's nothing at CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Neither finding is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing here is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Neither fix is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Nothing in this diff is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"This is not CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Severity: Low (not High)","main":["High"]},{"source":"pinned","reader":"adversarial-native","fixture":"review-ledger/harn15-ship2-p2-adversarial-native.txt","main":["CRITICAL","CRITICAL","CRITICAL","CRITICAL","CRITICAL","Low"]},{"source":"pinned","reader":"outside-voice","output":"1. **Race on the lock** (a.ts:3)\n - the writer holds no lock\n\n Fix: take it first. Severity: High. Blocks: no.","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"1. Lock race (a.ts:3)\n\n Fix: take it first. Blocks: yes\n2. Cache drift (c.ts:4)","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"1. Unescaped query\n {\"severity\":\"critical\",\"summary\":\"Low-level race in q.ts\"}","main":["critical"]},{"source":"pinned","reader":"red-team","output":"1. Unescaped query\n **Critical**\n2. Token leak in the logger","main":["Critical"]},{"source":"pinned","reader":"red-team","output":"1. Unescaped query\n ## High\n2. Token leak in the logger","main":["High"]},{"source":"pinned","reader":"red-team","output":"1. Race in queue\n- Severity: Low\n this one blocks. Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"red-team","output":"1. Unescaped query\n {\"severity\":\"low\",\"summary\":\"race\"}\n this blocks the merge. Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"The problems below are about accounting and what the post leaves out. None of them breaks a test, production or custody.\n\n1. **The per-task cost leaves out model spend.** The P0 and bulk go or no-go will re-project cost from these figures, so they will come out too low. Severity: Medium. Blocks: no.\n\n2. **One round-2 K1 pair is not accounted for.** The post sets a precedent for P0 yield math, so that drop should be named. Severity: Low. Blocks: no.\n\n3. **The two probe populations are not reconciled.** The stage table probes 189 candidates. Severity: Low. Blocks: no.\n\n4. **The P0 impact of the shortfall is missing.** The plan's P0 (line 323) needs 6 K4 replays and 2 decoys. The post says the shortfall but not that it blocks P0. Severity: Low. Blocks: no.\n\n6. **Some wording is ambiguous.** Two examples:\n - \"Repositories 4 (3 for build tasks)\" is set against a target of \"at least 5 repositories\".\n\n Severity: Low. Blocks: no.\n\nRecommendation: ship after a one-line fix because finding 1's per-task cost leaves out measured model spend.","main":["P0","P0","Low","P0","Low"]},{"source":"pinned","reader":"outside-voice","output":"[P0] Token leak in log.ts:3","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"P0: token leak in log.ts:3","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. Token leak in log.ts:3\n Severity: P0","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot drops the last row (q.ts:7). Severity: P0. Blocks: no","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"**Critical**\n- Token leak in log.ts:3","main":["Critical"]},{"source":"pinned","reader":"outside-voice","output":"## P0\n- Token leak in log.ts:3","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"### CRITICAL: missing auth check in api.ts:10","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot loses rows on retry (r.ts:2). Severity: Low. Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot loses rows on retry (r.ts:2)\n Severity: Medium\n Blocks: yes","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot table drops a row (t.md:3)","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. api.ts:10 CRITICAL: missing auth. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. api.ts:10 CRITICAL: missing auth\n Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. 🔴 CRITICAL: missing auth. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. Token leak in auth.ts:3 lets anyone read sessions. Severity: Critical\n\nSeverity: Low","main":["Critical"]},{"source":"pinned","reader":"outside-voice","output":"- auth.ts:3 token leak. Severity: Low (pre-exploit), Severity: Critical (once exposed)","main":["Critical"]},{"source":"pinned","reader":"outside-voice","output":"- Missing auth on DELETE /users lets any user wipe accounts (CRITICAL); the old ticket filed it at severity low.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"- api.ts:10 lets any user wipe accounts. Earlier triage said Severity: Low; it is CRITICAL.","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. CRITICAL missing auth. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. CRITICAL, missing auth on DELETE. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. CRITICAL (api.ts:10) missing auth. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot table drops a row (t.md:3) Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot table drops a row\nSeverity Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot table drops a row\n**Severity** Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. Bypass x.ts:3 is CRITICAL (Severity: Low in pass 1)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Still open: x.ts:3 is CRITICAL, Severity: Low in pass 1 understated it","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. lib/x.ts:42-58 CRITICAL: drops rows. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. lib/x.ts:42:7 CRITICAL: drops rows. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. (lib/x.ts:42, 50) CRITICAL: drops rows. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot table drops a row\nSeverity: Low: only the pilot","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot table drops a row\nSeverity: Low because it is internal","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot table drops a row\nSeverity: Low/Medium","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"Severity: Low: only the P0 pilot table","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. The P0 pilot drops a row. Severity: Low/P3","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"1. drops rows\nSeverity: High/Critical","main":["Critical"]},{"source":"pinned","reader":"outside-voice","output":"Severity: Medium/CRITICAL","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. x.ts:3 drops prod rows. Severity: Low/CRITICAL","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. x.ts:3 is CRITICAL (Severity: Low/Medium in pass 1)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"1. x.ts:3 is CRITICAL (Severity: Low: pass 1)","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Still open: x.ts:3 is P0, Severity: Low: pass 1 understated it","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"============================================================ P0 pilot table. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"============================================================ High-risk. Severity: Low","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"============================================================ CRITICAL findings follow. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"============================================================ a.ts:3 P0 pilot. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"------------------------------------------------------------ P0 pilot table. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"------------------------------------------------------------ High-risk. Severity: Low","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"------------------------------------------------------------ CRITICAL findings follow. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"------------------------------------------------------------ a.ts:3 P0 pilot. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"|------------------------------------------------------------| P0 pilot table. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"|------------------------------------------------------------| High-risk. Severity: Low","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"|------------------------------------------------------------| CRITICAL findings follow. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"|------------------------------------------------------------| a.ts:3 P0 pilot. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴 P0 pilot table. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴 High-risk. Severity: Low","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴 CRITICAL findings follow. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴🔴 a.ts:3 P0 pilot. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . P0 pilot table. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . High-risk. Severity: Low","main":["High"]},{"source":"pinned","reader":"outside-voice","output":". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . CRITICAL findings follow. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":". . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . a.ts:3 P0 pilot. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. P0 pilot table. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. High-risk. Severity: Low","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. CRITICAL findings follow. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. a.ts:3 P0 pilot. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"```````````````````````````````````````````````````````````` P0 pilot table. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"```````````````````````````````````````````````````````````` High-risk. Severity: Low","main":["High"]},{"source":"pinned","reader":"outside-voice","output":"```````````````````````````````````````````````````````````` CRITICAL findings follow. Severity: Low","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"```````````````````````````````````````````````````````````` a.ts:3 P0 pilot. Severity: Low","main":["P0"]},{"source":"pinned","reader":"outside-voice","output":"---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- P0 pilot table. Severity: Low","main":["P0"]},{"source":"pinned","reader":"specialist/testing","output":"REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\nI could not access the diff.\n","main":[]},{"source":"pinned","reader":"outside-voice","output":"Codex timed out after 9 minutes and was terminated; this pass produced NO findings.\n","main":[]},{"source":"pinned","reader":"outside-voice","output":"1. **CRITICAL**: token leak in a.ts:3\nCodex then timed out.\n","main":["CRITICAL"]},{"source":"pinned","reader":"specialist/testing","output":"- **REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt**\nNO FINDINGS\n","main":[]},{"source":"pinned","reader":"outside-voice","output":"1. **CRITICAL**: auth bypass in a.ts:3\nBlocks: yes\n\nRecommendation: request changes\n","main":["CRITICAL"]},{"source":"pinned","reader":"outside-voice","output":"Codex timed out before it reviewed anything.\n","main":[]},{"source":"pinned","reader":"outside-voice","fixture":"review-wrong-tree/gpt-6.1-sol-gst850-p1.out","main":["CRITICAL","CRITICAL","CRITICAL","CRITICAL","CRITICAL"]},{"source":"pinned","reader":"outside-voice","fixture":"review-wrong-tree/gpt-6.1-sol-gst850-p2.out","main":["CRITICAL","CRITICAL","CRITICAL"]},{"source":"pinned","reader":"specialist/testing","output":"cd '/home/user/.capy/work/gst976/wt' && echo \"REVIEWED_TREE: $(git rev-parse 'HEAD^{tree}') $(git rev-parse --show-toplevel)\"\nprinted: REVIEWED_TREE: d0dd42d6a88fbc2a6abca4f6b2dfde7e35520c5a /home/user/.capy/work/gst976/wt\nNO FINDINGS\n","main":[]},{"source":"fixture","reader":"outside-voice","fixture":"review-ledger/main-labels.json","main":["CRITICAL"]},{"source":"fixture","reader":"outside-voice","fixture":"review-ledger/gsta-196-native.txt","main":["High","Low","Low","Low"]},{"source":"fixture","reader":"outside-voice","fixture":"review-ledger/gsta-196-refusal.txt","main":[]}],"shapes":{"bodies":["1. The P0 pilot drops rows (a.ts:3)","1. CRITICAL: drops rows in a.ts:3","- High: the cache leaks (c.ts:4)","**Race in q.ts:7** nothing CRITICAL here","FIXABLE: race in r.ts:2","Note on b.ts:4 for the p1 pilot"],"fields":["Severity: Low","Severity: low","Severity: High/Critical","Severity: Medium/CRITICAL","Severity: Low/Medium","Severity: Low → Medium","Severity: Low: only the pilot","Severity: Low because it is internal","Severity: Low in pass 1, P0 now","(Severity: Low in pass 1)","(Severity: Low/Medium in pass 1)","(Severity: Low: pass 1)","**Severity:** Medium","**Severity** Low","Severity Low","SEVERITY: LOW","Severity: P3","Severity: Low (not High)","Severity: Low. Blocks: no","Severity: Low. Blocks: yes"],"joins":[". ","\n","\n "," — ",", "," "],"readers":["outside-voice","adversarial-native"],"generated":[[0,0,0,0,["P0"]],[0,0,0,1,["P0"]],[0,0,1,0,["P0"]],[0,0,1,1,["P0"]],[0,0,2,0,["P0"]],[0,0,2,1,["P0"]],[0,0,3,0,["P0"]],[0,0,3,1,["P0"]],[0,0,4,0,["P0"]],[0,0,4,1,["P0"]],[0,0,5,0,["P0"]],[0,0,5,1,["P0"]],[0,1,0,0,["P0"]],[0,1,0,1,["P0"]],[0,1,1,0,["P0"]],[0,1,1,1,["P0"]],[0,1,2,0,["P0"]],[0,1,2,1,["P0"]],[0,1,3,0,["P0"]],[0,1,3,1,["P0"]],[0,1,4,0,["P0"]],[0,1,4,1,["P0"]],[0,1,5,0,["P0"]],[0,1,5,1,["P0"]],[0,2,0,0,["P0"]],[0,2,0,1,["P0"]],[0,2,1,0,["P0"]],[0,2,1,1,["P0"]],[0,2,2,0,["P0"]],[0,2,2,1,["P0"]],[0,2,3,0,["P0"]],[0,2,3,1,["P0"]],[0,2,4,0,["P0"]],[0,2,4,1,["P0"]],[0,2,5,0,["P0"]],[0,2,5,1,["P0"]],[0,3,0,0,["P0"]],[0,3,0,1,["P0"]],[0,3,1,0,["P0"]],[0,3,1,1,["P0"]],[0,3,2,0,["P0"]],[0,3,2,1,["P0"]],[0,3,3,0,["P0"]],[0,3,3,1,["P0"]],[0,3,4,0,["P0"]],[0,3,4,1,["P0"]],[0,3,5,0,["P0"]],[0,3,5,1,["P0"]],[0,4,0,0,["P0"]],[0,4,0,1,["P0"]],[0,4,1,0,["P0"]],[0,4,1,1,["P0"]],[0,4,2,0,["P0"]],[0,4,2,1,["P0"]],[0,4,3,0,["P0"]],[0,4,3,1,["P0"]],[0,4,4,0,["P0"]],[0,4,4,1,["P0"]],[0,4,5,0,["P0"]],[0,4,5,1,["P0"]],[0,5,0,0,["P0"]],[0,5,0,1,["P0"]],[0,5,1,0,["P0"]],[0,5,1,1,["P0"]],[0,5,2,0,["P0"]],[0,5,2,1,["P0"]],[0,5,3,0,["P0"]],[0,5,3,1,["P0"]],[0,5,4,0,["P0"]],[0,5,4,1,["P0"]],[0,5,5,0,["P0"]],[0,5,5,1,["P0"]],[0,6,0,0,["P0"]],[0,6,0,1,["P0"]],[0,6,1,0,["P0"]],[0,6,1,1,["P0"]],[0,6,2,0,["P0"]],[0,6,2,1,["P0"]],[0,6,3,0,["P0"]],[0,6,3,1,["P0"]],[0,6,4,0,["P0"]],[0,6,4,1,["P0"]],[0,6,5,0,["P0"]],[0,6,5,1,["P0"]],[0,7,0,0,["P0"]],[0,7,0,1,["P0"]],[0,7,1,0,["P0"]],[0,7,1,1,["P0"]],[0,7,2,0,["P0"]],[0,7,2,1,["P0"]],[0,7,3,0,["P0"]],[0,7,3,1,["P0"]],[0,7,4,0,["P0"]],[0,7,4,1,["P0"]],[0,7,5,0,["P0"]],[0,7,5,1,["P0"]],[0,8,0,0,["P0"]],[0,8,0,1,["P0"]],[0,8,1,0,["P0"]],[0,8,1,1,["P0"]],[0,8,2,0,["P0"]],[0,8,2,1,["P0"]],[0,8,3,0,["P0"]],[0,8,3,1,["P0"]],[0,8,4,0,["P0"]],[0,8,4,1,["P0"]],[0,8,5,0,["P0"]],[0,8,5,1,["P0"]],[0,9,0,0,["P0"]],[0,9,0,1,["P0"]],[0,9,1,0,["P0","Low"]],[0,9,1,1,["P0","Low"]],[0,9,2,0,["P0","Low"]],[0,9,2,1,["P0","Low"]],[0,9,3,0,["P0"]],[0,9,3,1,["P0"]],[0,9,4,0,["P0"]],[0,9,4,1,["P0"]],[0,9,5,0,["P0"]],[0,9,5,1,["P0"]],[0,10,0,0,["P0"]],[0,10,0,1,["P0"]],[0,10,1,0,["P0","Medium"]],[0,10,1,1,["P0","Medium"]],[0,10,2,0,["P0","Medium"]],[0,10,2,1,["P0","Medium"]],[0,10,3,0,["P0"]],[0,10,3,1,["P0"]],[0,10,4,0,["P0"]],[0,10,4,1,["P0"]],[0,10,5,0,["P0"]],[0,10,5,1,["P0"]],[0,11,0,0,["P0"]],[0,11,0,1,["P0"]],[0,11,1,0,["P0","Low"]],[0,11,1,1,["P0","Low"]],[0,11,2,0,["P0","Low"]],[0,11,2,1,["P0","Low"]],[0,11,3,0,["P0"]],[0,11,3,1,["P0"]],[0,11,4,0,["P0"]],[0,11,4,1,["P0"]],[0,11,5,0,["P0"]],[0,11,5,1,["P0"]],[0,12,0,0,["P0"]],[0,12,0,1,["P0"]],[0,12,1,0,["P0"]],[0,12,1,1,["P0"]],[0,12,2,0,["P0"]],[0,12,2,1,["P0"]],[0,12,3,0,["P0"]],[0,12,3,1,["P0"]],[0,12,4,0,["P0"]],[0,12,4,1,["P0"]],[0,12,5,0,["P0"]],[0,12,5,1,["P0"]],[0,13,0,0,["P0"]],[0,13,0,1,["P0"]],[0,13,1,0,["P0"]],[0,13,1,1,["P0"]],[0,13,2,0,["P0"]],[0,13,2,1,["P0"]],[0,13,3,0,["P0"]],[0,13,3,1,["P0"]],[0,13,4,0,["P0"]],[0,13,4,1,["P0"]],[0,13,5,0,["P0"]],[0,13,5,1,["P0"]],[0,14,0,0,["P0"]],[0,14,0,1,["P0"]],[0,14,1,0,["P0"]],[0,14,1,1,["P0"]],[0,14,2,0,["P0"]],[0,14,2,1,["P0"]],[0,14,3,0,["P0"]],[0,14,3,1,["P0"]],[0,14,4,0,["P0"]],[0,14,4,1,["P0"]],[0,14,5,0,["P0"]],[0,14,5,1,["P0"]],[0,15,0,0,["P0"]],[0,15,0,1,["P0"]],[0,15,1,0,["P0"]],[0,15,1,1,["P0"]],[0,15,2,0,["P0"]],[0,15,2,1,["P0"]],[0,15,3,0,["P0"]],[0,15,3,1,["P0"]],[0,15,4,0,["P0"]],[0,15,4,1,["P0"]],[0,15,5,0,["P0"]],[0,15,5,1,["P0"]],[0,16,0,0,["P0"]],[0,16,0,1,["P0"]],[0,16,1,0,["P0"]],[0,16,1,1,["P0"]],[0,16,2,0,["P0"]],[0,16,2,1,["P0"]],[0,16,3,0,["P0"]],[0,16,3,1,["P0"]],[0,16,4,0,["P0"]],[0,16,4,1,["P0"]],[0,16,5,0,["P0"]],[0,16,5,1,["P0"]],[0,17,0,0,["P0"]],[0,17,0,1,["P0"]],[0,17,1,0,["P0"]],[0,17,1,1,["P0"]],[0,17,2,0,["P0"]],[0,17,2,1,["P0"]],[0,17,3,0,["P0"]],[0,17,3,1,["P0"]],[0,17,4,0,["P0"]],[0,17,4,1,["P0"]],[0,17,5,0,["P0"]],[0,17,5,1,["P0"]],[0,18,0,0,["P0"]],[0,18,0,1,["P0"]],[0,18,1,0,["P0"]],[0,18,1,1,["P0"]],[0,18,2,0,["P0"]],[0,18,2,1,["P0"]],[0,18,3,0,["P0"]],[0,18,3,1,["P0"]],[0,18,4,0,["P0"]],[0,18,4,1,["P0"]],[0,18,5,0,["P0"]],[0,18,5,1,["P0"]],[0,19,0,0,["CRITICAL"]],[0,19,0,1,["CRITICAL"]],[0,19,1,0,["CRITICAL"]],[0,19,1,1,["CRITICAL"]],[0,19,2,0,["CRITICAL"]],[0,19,2,1,["CRITICAL"]],[0,19,3,0,["CRITICAL"]],[0,19,3,1,["CRITICAL"]],[0,19,4,0,["CRITICAL"]],[0,19,4,1,["CRITICAL"]],[0,19,5,0,["CRITICAL"]],[0,19,5,1,["CRITICAL"]],[1,0,0,0,["CRITICAL"]],[1,0,0,1,["CRITICAL"]],[1,0,1,0,["CRITICAL"]],[1,0,1,1,["CRITICAL"]],[1,0,2,0,["CRITICAL"]],[1,0,2,1,["CRITICAL"]],[1,0,3,0,["CRITICAL"]],[1,0,3,1,["CRITICAL"]],[1,0,4,0,["CRITICAL"]],[1,0,4,1,["CRITICAL"]],[1,0,5,0,["CRITICAL"]],[1,0,5,1,["CRITICAL"]],[1,1,0,0,["CRITICAL"]],[1,1,0,1,["CRITICAL"]],[1,1,1,0,["CRITICAL"]],[1,1,1,1,["CRITICAL"]],[1,1,2,0,["CRITICAL"]],[1,1,2,1,["CRITICAL"]],[1,1,3,0,["CRITICAL"]],[1,1,3,1,["CRITICAL"]],[1,1,4,0,["CRITICAL"]],[1,1,4,1,["CRITICAL"]],[1,1,5,0,["CRITICAL"]],[1,1,5,1,["CRITICAL"]],[1,2,0,0,["CRITICAL"]],[1,2,0,1,["CRITICAL"]],[1,2,1,0,["CRITICAL"]],[1,2,1,1,["CRITICAL"]],[1,2,2,0,["CRITICAL"]],[1,2,2,1,["CRITICAL"]],[1,2,3,0,["CRITICAL"]],[1,2,3,1,["CRITICAL"]],[1,2,4,0,["CRITICAL"]],[1,2,4,1,["CRITICAL"]],[1,2,5,0,["CRITICAL"]],[1,2,5,1,["CRITICAL"]],[1,3,0,0,["CRITICAL"]],[1,3,0,1,["CRITICAL"]],[1,3,1,0,["CRITICAL"]],[1,3,1,1,["CRITICAL"]],[1,3,2,0,["CRITICAL"]],[1,3,2,1,["CRITICAL"]],[1,3,3,0,["CRITICAL"]],[1,3,3,1,["CRITICAL"]],[1,3,4,0,["CRITICAL"]],[1,3,4,1,["CRITICAL"]],[1,3,5,0,["CRITICAL"]],[1,3,5,1,["CRITICAL"]],[1,4,0,0,["CRITICAL"]],[1,4,0,1,["CRITICAL"]],[1,4,1,0,["CRITICAL"]],[1,4,1,1,["CRITICAL"]],[1,4,2,0,["CRITICAL"]],[1,4,2,1,["CRITICAL"]],[1,4,3,0,["CRITICAL"]],[1,4,3,1,["CRITICAL"]],[1,4,4,0,["CRITICAL"]],[1,4,4,1,["CRITICAL"]],[1,4,5,0,["CRITICAL"]],[1,4,5,1,["CRITICAL"]],[1,5,0,0,["CRITICAL"]],[1,5,0,1,["CRITICAL"]],[1,5,1,0,["CRITICAL"]],[1,5,1,1,["CRITICAL"]],[1,5,2,0,["CRITICAL"]],[1,5,2,1,["CRITICAL"]],[1,5,3,0,["CRITICAL"]],[1,5,3,1,["CRITICAL"]],[1,5,4,0,["CRITICAL"]],[1,5,4,1,["CRITICAL"]],[1,5,5,0,["CRITICAL"]],[1,5,5,1,["CRITICAL"]],[1,6,0,0,["CRITICAL"]],[1,6,0,1,["CRITICAL"]],[1,6,1,0,["CRITICAL"]],[1,6,1,1,["CRITICAL"]],[1,6,2,0,["CRITICAL"]],[1,6,2,1,["CRITICAL"]],[1,6,3,0,["CRITICAL"]],[1,6,3,1,["CRITICAL"]],[1,6,4,0,["CRITICAL"]],[1,6,4,1,["CRITICAL"]],[1,6,5,0,["CRITICAL"]],[1,6,5,1,["CRITICAL"]],[1,7,0,0,["CRITICAL"]],[1,7,0,1,["CRITICAL"]],[1,7,1,0,["CRITICAL"]],[1,7,1,1,["CRITICAL"]],[1,7,2,0,["CRITICAL"]],[1,7,2,1,["CRITICAL"]],[1,7,3,0,["CRITICAL"]],[1,7,3,1,["CRITICAL"]],[1,7,4,0,["CRITICAL"]],[1,7,4,1,["CRITICAL"]],[1,7,5,0,["CRITICAL"]],[1,7,5,1,["CRITICAL"]],[1,8,0,0,["CRITICAL"]],[1,8,0,1,["CRITICAL"]],[1,8,1,0,["CRITICAL"]],[1,8,1,1,["CRITICAL"]],[1,8,2,0,["CRITICAL"]],[1,8,2,1,["CRITICAL"]],[1,8,3,0,["CRITICAL"]],[1,8,3,1,["CRITICAL"]],[1,8,4,0,["CRITICAL"]],[1,8,4,1,["CRITICAL"]],[1,8,5,0,["CRITICAL"]],[1,8,5,1,["CRITICAL"]],[1,9,0,0,["CRITICAL"]],[1,9,0,1,["CRITICAL"]],[1,9,1,0,["CRITICAL","Low"]],[1,9,1,1,["CRITICAL","Low"]],[1,9,2,0,["CRITICAL","Low"]],[1,9,2,1,["CRITICAL","Low"]],[1,9,3,0,["CRITICAL"]],[1,9,3,1,["CRITICAL"]],[1,9,4,0,["CRITICAL"]],[1,9,4,1,["CRITICAL"]],[1,9,5,0,["CRITICAL"]],[1,9,5,1,["CRITICAL"]],[1,10,0,0,["CRITICAL"]],[1,10,0,1,["CRITICAL"]],[1,10,1,0,["CRITICAL","Medium"]],[1,10,1,1,["CRITICAL","Medium"]],[1,10,2,0,["CRITICAL","Medium"]],[1,10,2,1,["CRITICAL","Medium"]],[1,10,3,0,["CRITICAL"]],[1,10,3,1,["CRITICAL"]],[1,10,4,0,["CRITICAL"]],[1,10,4,1,["CRITICAL"]],[1,10,5,0,["CRITICAL"]],[1,10,5,1,["CRITICAL"]],[1,11,0,0,["CRITICAL"]],[1,11,0,1,["CRITICAL"]],[1,11,1,0,["CRITICAL","Low"]],[1,11,1,1,["CRITICAL","Low"]],[1,11,2,0,["CRITICAL","Low"]],[1,11,2,1,["CRITICAL","Low"]],[1,11,3,0,["CRITICAL"]],[1,11,3,1,["CRITICAL"]],[1,11,4,0,["CRITICAL"]],[1,11,4,1,["CRITICAL"]],[1,11,5,0,["CRITICAL"]],[1,11,5,1,["CRITICAL"]],[1,12,0,0,["CRITICAL"]],[1,12,0,1,["CRITICAL"]],[1,12,1,0,["CRITICAL"]],[1,12,1,1,["CRITICAL"]],[1,12,2,0,["CRITICAL"]],[1,12,2,1,["CRITICAL"]],[1,12,3,0,["CRITICAL"]],[1,12,3,1,["CRITICAL"]],[1,12,4,0,["CRITICAL"]],[1,12,4,1,["CRITICAL"]],[1,12,5,0,["CRITICAL"]],[1,12,5,1,["CRITICAL"]],[1,13,0,0,["CRITICAL"]],[1,13,0,1,["CRITICAL"]],[1,13,1,0,["CRITICAL"]],[1,13,1,1,["CRITICAL"]],[1,13,2,0,["CRITICAL"]],[1,13,2,1,["CRITICAL"]],[1,13,3,0,["CRITICAL"]],[1,13,3,1,["CRITICAL"]],[1,13,4,0,["CRITICAL"]],[1,13,4,1,["CRITICAL"]],[1,13,5,0,["CRITICAL"]],[1,13,5,1,["CRITICAL"]],[1,14,0,0,["CRITICAL"]],[1,14,0,1,["CRITICAL"]],[1,14,1,0,["CRITICAL"]],[1,14,1,1,["CRITICAL"]],[1,14,2,0,["CRITICAL"]],[1,14,2,1,["CRITICAL"]],[1,14,3,0,["CRITICAL"]],[1,14,3,1,["CRITICAL"]],[1,14,4,0,["CRITICAL"]],[1,14,4,1,["CRITICAL"]],[1,14,5,0,["CRITICAL"]],[1,14,5,1,["CRITICAL"]],[1,15,0,0,["CRITICAL"]],[1,15,0,1,["CRITICAL"]],[1,15,1,0,["CRITICAL"]],[1,15,1,1,["CRITICAL"]],[1,15,2,0,["CRITICAL"]],[1,15,2,1,["CRITICAL"]],[1,15,3,0,["CRITICAL"]],[1,15,3,1,["CRITICAL"]],[1,15,4,0,["CRITICAL"]],[1,15,4,1,["CRITICAL"]],[1,15,5,0,["CRITICAL"]],[1,15,5,1,["CRITICAL"]],[1,16,0,0,["CRITICAL"]],[1,16,0,1,["CRITICAL"]],[1,16,1,0,["CRITICAL"]],[1,16,1,1,["CRITICAL"]],[1,16,2,0,["CRITICAL"]],[1,16,2,1,["CRITICAL"]],[1,16,3,0,["CRITICAL"]],[1,16,3,1,["CRITICAL"]],[1,16,4,0,["CRITICAL"]],[1,16,4,1,["CRITICAL"]],[1,16,5,0,["CRITICAL"]],[1,16,5,1,["CRITICAL"]],[1,17,0,0,["CRITICAL"]],[1,17,0,1,["CRITICAL"]],[1,17,1,0,["CRITICAL"]],[1,17,1,1,["CRITICAL"]],[1,17,2,0,["CRITICAL"]],[1,17,2,1,["CRITICAL"]],[1,17,3,0,["CRITICAL"]],[1,17,3,1,["CRITICAL"]],[1,17,4,0,["CRITICAL"]],[1,17,4,1,["CRITICAL"]],[1,17,5,0,["CRITICAL"]],[1,17,5,1,["CRITICAL"]],[1,18,0,0,["CRITICAL"]],[1,18,0,1,["CRITICAL"]],[1,18,1,0,["CRITICAL"]],[1,18,1,1,["CRITICAL"]],[1,18,2,0,["CRITICAL"]],[1,18,2,1,["CRITICAL"]],[1,18,3,0,["CRITICAL"]],[1,18,3,1,["CRITICAL"]],[1,18,4,0,["CRITICAL"]],[1,18,4,1,["CRITICAL"]],[1,18,5,0,["CRITICAL"]],[1,18,5,1,["CRITICAL"]],[1,19,0,0,["CRITICAL"]],[1,19,0,1,["CRITICAL"]],[1,19,1,0,["CRITICAL"]],[1,19,1,1,["CRITICAL"]],[1,19,2,0,["CRITICAL"]],[1,19,2,1,["CRITICAL"]],[1,19,3,0,["CRITICAL"]],[1,19,3,1,["CRITICAL"]],[1,19,4,0,["CRITICAL"]],[1,19,4,1,["CRITICAL"]],[1,19,5,0,["CRITICAL"]],[1,19,5,1,["CRITICAL"]],[2,0,0,0,["High"]],[2,0,0,1,["High"]],[2,0,1,0,["High"]],[2,0,1,1,["High"]],[2,0,2,0,["High"]],[2,0,2,1,["High"]],[2,0,3,0,["High"]],[2,0,3,1,["High"]],[2,0,4,0,["High"]],[2,0,4,1,["High"]],[2,0,5,0,["High"]],[2,0,5,1,["High"]],[2,1,0,0,["High"]],[2,1,0,1,["High"]],[2,1,1,0,["High"]],[2,1,1,1,["High"]],[2,1,2,0,["High"]],[2,1,2,1,["High"]],[2,1,3,0,["High"]],[2,1,3,1,["High"]],[2,1,4,0,["High"]],[2,1,4,1,["High"]],[2,1,5,0,["High"]],[2,1,5,1,["High"]],[2,2,0,0,["Critical"]],[2,2,0,1,["Critical"]],[2,2,1,0,["Critical"]],[2,2,1,1,["Critical"]],[2,2,2,0,["Critical"]],[2,2,2,1,["Critical"]],[2,2,3,0,["Critical"]],[2,2,3,1,["Critical"]],[2,2,4,0,["Critical"]],[2,2,4,1,["Critical"]],[2,2,5,0,["Critical"]],[2,2,5,1,["Critical"]],[2,3,0,0,["CRITICAL"]],[2,3,0,1,["CRITICAL"]],[2,3,1,0,["CRITICAL"]],[2,3,1,1,["CRITICAL"]],[2,3,2,0,["CRITICAL"]],[2,3,2,1,["CRITICAL"]],[2,3,3,0,["CRITICAL"]],[2,3,3,1,["CRITICAL"]],[2,3,4,0,["CRITICAL"]],[2,3,4,1,["CRITICAL"]],[2,3,5,0,["CRITICAL"]],[2,3,5,1,["CRITICAL"]],[2,4,0,0,["High"]],[2,4,0,1,["High"]],[2,4,1,0,["High"]],[2,4,1,1,["High"]],[2,4,2,0,["High"]],[2,4,2,1,["High"]],[2,4,3,0,["High"]],[2,4,3,1,["High"]],[2,4,4,0,["High"]],[2,4,4,1,["High"]],[2,4,5,0,["High"]],[2,4,5,1,["High"]],[2,5,0,0,["High"]],[2,5,0,1,["High"]],[2,5,1,0,["High"]],[2,5,1,1,["High"]],[2,5,2,0,["High"]],[2,5,2,1,["High"]],[2,5,3,0,["High"]],[2,5,3,1,["High"]],[2,5,4,0,["High"]],[2,5,4,1,["High"]],[2,5,5,0,["High"]],[2,5,5,1,["High"]],[2,6,0,0,["High"]],[2,6,0,1,["High"]],[2,6,1,0,["High"]],[2,6,1,1,["High"]],[2,6,2,0,["High"]],[2,6,2,1,["High"]],[2,6,3,0,["High"]],[2,6,3,1,["High"]],[2,6,4,0,["High"]],[2,6,4,1,["High"]],[2,6,5,0,["High"]],[2,6,5,1,["High"]],[2,7,0,0,["High"]],[2,7,0,1,["High"]],[2,7,1,0,["High"]],[2,7,1,1,["High"]],[2,7,2,0,["High"]],[2,7,2,1,["High"]],[2,7,3,0,["High"]],[2,7,3,1,["High"]],[2,7,4,0,["High"]],[2,7,4,1,["High"]],[2,7,5,0,["High"]],[2,7,5,1,["High"]],[2,8,0,0,["P0"]],[2,8,0,1,["P0"]],[2,8,1,0,["P0"]],[2,8,1,1,["P0"]],[2,8,2,0,["P0"]],[2,8,2,1,["P0"]],[2,8,3,0,["P0"]],[2,8,3,1,["P0"]],[2,8,4,0,["P0"]],[2,8,4,1,["P0"]],[2,8,5,0,["P0"]],[2,8,5,1,["P0"]],[2,9,0,0,["High"]],[2,9,0,1,["High"]],[2,9,1,0,["High","Low"]],[2,9,1,1,["High","Low"]],[2,9,2,0,["High","Low"]],[2,9,2,1,["High","Low"]],[2,9,3,0,["High"]],[2,9,3,1,["High"]],[2,9,4,0,["High"]],[2,9,4,1,["High"]],[2,9,5,0,["High"]],[2,9,5,1,["High"]],[2,10,0,0,["High"]],[2,10,0,1,["High"]],[2,10,1,0,["High","Medium"]],[2,10,1,1,["High","Medium"]],[2,10,2,0,["High","Medium"]],[2,10,2,1,["High","Medium"]],[2,10,3,0,["High"]],[2,10,3,1,["High"]],[2,10,4,0,["High"]],[2,10,4,1,["High"]],[2,10,5,0,["High"]],[2,10,5,1,["High"]],[2,11,0,0,["High"]],[2,11,0,1,["High"]],[2,11,1,0,["High","Low"]],[2,11,1,1,["High","Low"]],[2,11,2,0,["High","Low"]],[2,11,2,1,["High","Low"]],[2,11,3,0,["High"]],[2,11,3,1,["High"]],[2,11,4,0,["High"]],[2,11,4,1,["High"]],[2,11,5,0,["High"]],[2,11,5,1,["High"]],[2,12,0,0,["High"]],[2,12,0,1,["High"]],[2,12,1,0,["High"]],[2,12,1,1,["High"]],[2,12,2,0,["High"]],[2,12,2,1,["High"]],[2,12,3,0,["High"]],[2,12,3,1,["High"]],[2,12,4,0,["High"]],[2,12,4,1,["High"]],[2,12,5,0,["High"]],[2,12,5,1,["High"]],[2,13,0,0,["High"]],[2,13,0,1,["High"]],[2,13,1,0,["High"]],[2,13,1,1,["High"]],[2,13,2,0,["High"]],[2,13,2,1,["High"]],[2,13,3,0,["High"]],[2,13,3,1,["High"]],[2,13,4,0,["High"]],[2,13,4,1,["High"]],[2,13,5,0,["High"]],[2,13,5,1,["High"]],[2,14,0,0,["High"]],[2,14,0,1,["High"]],[2,14,1,0,["High"]],[2,14,1,1,["High"]],[2,14,2,0,["High"]],[2,14,2,1,["High"]],[2,14,3,0,["High"]],[2,14,3,1,["High"]],[2,14,4,0,["High"]],[2,14,4,1,["High"]],[2,14,5,0,["High"]],[2,14,5,1,["High"]],[2,15,0,0,["High"]],[2,15,0,1,["High"]],[2,15,1,0,["High"]],[2,15,1,1,["High"]],[2,15,2,0,["High"]],[2,15,2,1,["High"]],[2,15,3,0,["High"]],[2,15,3,1,["High"]],[2,15,4,0,["High"]],[2,15,4,1,["High"]],[2,15,5,0,["High"]],[2,15,5,1,["High"]],[2,16,0,0,["High"]],[2,16,0,1,["High"]],[2,16,1,0,["High"]],[2,16,1,1,["High"]],[2,16,2,0,["High"]],[2,16,2,1,["High"]],[2,16,3,0,["High"]],[2,16,3,1,["High"]],[2,16,4,0,["High"]],[2,16,4,1,["High"]],[2,16,5,0,["High"]],[2,16,5,1,["High"]],[2,17,0,0,["High"]],[2,17,0,1,["High"]],[2,17,1,0,["High"]],[2,17,1,1,["High"]],[2,17,2,0,["High"]],[2,17,2,1,["High"]],[2,17,3,0,["High"]],[2,17,3,1,["High"]],[2,17,4,0,["High"]],[2,17,4,1,["High"]],[2,17,5,0,["High"]],[2,17,5,1,["High"]],[2,18,0,0,["High"]],[2,18,0,1,["High"]],[2,18,1,0,["High"]],[2,18,1,1,["High"]],[2,18,2,0,["High"]],[2,18,2,1,["High"]],[2,18,3,0,["High"]],[2,18,3,1,["High"]],[2,18,4,0,["High"]],[2,18,4,1,["High"]],[2,18,5,0,["High"]],[2,18,5,1,["High"]],[2,19,0,0,["CRITICAL"]],[2,19,0,1,["CRITICAL"]],[2,19,1,0,["CRITICAL"]],[2,19,1,1,["CRITICAL"]],[2,19,2,0,["CRITICAL"]],[2,19,2,1,["CRITICAL"]],[2,19,3,0,["CRITICAL"]],[2,19,3,1,["CRITICAL"]],[2,19,4,0,["CRITICAL"]],[2,19,4,1,["CRITICAL"]],[2,19,5,0,["CRITICAL"]],[2,19,5,1,["CRITICAL"]],[3,0,0,0,["CRITICAL"]],[3,0,0,1,["CRITICAL"]],[3,0,1,0,["CRITICAL"]],[3,0,1,1,["CRITICAL"]],[3,0,2,0,["CRITICAL"]],[3,0,2,1,["CRITICAL"]],[3,0,3,0,["CRITICAL"]],[3,0,3,1,["CRITICAL"]],[3,0,4,0,["CRITICAL"]],[3,0,4,1,["CRITICAL"]],[3,0,5,0,["CRITICAL"]],[3,0,5,1,["CRITICAL"]],[3,1,0,0,["CRITICAL"]],[3,1,0,1,["CRITICAL"]],[3,1,1,0,["CRITICAL"]],[3,1,1,1,["CRITICAL"]],[3,1,2,0,["CRITICAL"]],[3,1,2,1,["CRITICAL"]],[3,1,3,0,["CRITICAL"]],[3,1,3,1,["CRITICAL"]],[3,1,4,0,["CRITICAL"]],[3,1,4,1,["CRITICAL"]],[3,1,5,0,["CRITICAL"]],[3,1,5,1,["CRITICAL"]],[3,2,0,0,["CRITICAL"]],[3,2,0,1,["CRITICAL"]],[3,2,1,0,["CRITICAL"]],[3,2,1,1,["CRITICAL"]],[3,2,2,0,["CRITICAL"]],[3,2,2,1,["CRITICAL"]],[3,2,3,0,["CRITICAL"]],[3,2,3,1,["CRITICAL"]],[3,2,4,0,["CRITICAL"]],[3,2,4,1,["CRITICAL"]],[3,2,5,0,["CRITICAL"]],[3,2,5,1,["CRITICAL"]],[3,3,0,0,["CRITICAL"]],[3,3,0,1,["CRITICAL"]],[3,3,1,0,["CRITICAL"]],[3,3,1,1,["CRITICAL"]],[3,3,2,0,["CRITICAL"]],[3,3,2,1,["CRITICAL"]],[3,3,3,0,["CRITICAL"]],[3,3,3,1,["CRITICAL"]],[3,3,4,0,["CRITICAL"]],[3,3,4,1,["CRITICAL"]],[3,3,5,0,["CRITICAL"]],[3,3,5,1,["CRITICAL"]],[3,4,0,0,["CRITICAL"]],[3,4,0,1,["CRITICAL"]],[3,4,1,0,["CRITICAL"]],[3,4,1,1,["CRITICAL"]],[3,4,2,0,["CRITICAL"]],[3,4,2,1,["CRITICAL"]],[3,4,3,0,["CRITICAL"]],[3,4,3,1,["CRITICAL"]],[3,4,4,0,["CRITICAL"]],[3,4,4,1,["CRITICAL"]],[3,4,5,0,["CRITICAL"]],[3,4,5,1,["CRITICAL"]],[3,5,0,0,["CRITICAL"]],[3,5,0,1,["CRITICAL"]],[3,5,1,0,["CRITICAL"]],[3,5,1,1,["CRITICAL"]],[3,5,2,0,["CRITICAL"]],[3,5,2,1,["CRITICAL"]],[3,5,3,0,["CRITICAL"]],[3,5,3,1,["CRITICAL"]],[3,5,4,0,["CRITICAL"]],[3,5,4,1,["CRITICAL"]],[3,5,5,0,["CRITICAL"]],[3,5,5,1,["CRITICAL"]],[3,6,0,0,["CRITICAL"]],[3,6,0,1,["CRITICAL"]],[3,6,1,0,["CRITICAL"]],[3,6,1,1,["CRITICAL"]],[3,6,2,0,["CRITICAL"]],[3,6,2,1,["CRITICAL"]],[3,6,3,0,["CRITICAL"]],[3,6,3,1,["CRITICAL"]],[3,6,4,0,["CRITICAL"]],[3,6,4,1,["CRITICAL"]],[3,6,5,0,["CRITICAL"]],[3,6,5,1,["CRITICAL"]],[3,7,0,0,["CRITICAL"]],[3,7,0,1,["CRITICAL"]],[3,7,1,0,["CRITICAL"]],[3,7,1,1,["CRITICAL"]],[3,7,2,0,["CRITICAL"]],[3,7,2,1,["CRITICAL"]],[3,7,3,0,["CRITICAL"]],[3,7,3,1,["CRITICAL"]],[3,7,4,0,["CRITICAL"]],[3,7,4,1,["CRITICAL"]],[3,7,5,0,["CRITICAL"]],[3,7,5,1,["CRITICAL"]],[3,8,0,0,["CRITICAL"]],[3,8,0,1,["CRITICAL"]],[3,8,1,0,["CRITICAL"]],[3,8,1,1,["CRITICAL"]],[3,8,2,0,["CRITICAL"]],[3,8,2,1,["CRITICAL"]],[3,8,3,0,["CRITICAL"]],[3,8,3,1,["CRITICAL"]],[3,8,4,0,["CRITICAL"]],[3,8,4,1,["CRITICAL"]],[3,8,5,0,["CRITICAL"]],[3,8,5,1,["CRITICAL"]],[3,9,0,0,["CRITICAL"]],[3,9,0,1,["CRITICAL"]],[3,9,1,0,["CRITICAL","Low"]],[3,9,1,1,["CRITICAL","Low"]],[3,9,2,0,["CRITICAL","Low"]],[3,9,2,1,["CRITICAL","Low"]],[3,9,3,0,["CRITICAL"]],[3,9,3,1,["CRITICAL"]],[3,9,4,0,["CRITICAL"]],[3,9,4,1,["CRITICAL"]],[3,9,5,0,["CRITICAL"]],[3,9,5,1,["CRITICAL"]],[3,10,0,0,["CRITICAL"]],[3,10,0,1,["CRITICAL"]],[3,10,1,0,["CRITICAL","Medium"]],[3,10,1,1,["CRITICAL","Medium"]],[3,10,2,0,["CRITICAL","Medium"]],[3,10,2,1,["CRITICAL","Medium"]],[3,10,3,0,["CRITICAL"]],[3,10,3,1,["CRITICAL"]],[3,10,4,0,["CRITICAL"]],[3,10,4,1,["CRITICAL"]],[3,10,5,0,["CRITICAL"]],[3,10,5,1,["CRITICAL"]],[3,11,0,0,["CRITICAL"]],[3,11,0,1,["CRITICAL"]],[3,11,1,0,["CRITICAL","Low"]],[3,11,1,1,["CRITICAL","Low"]],[3,11,2,0,["CRITICAL","Low"]],[3,11,2,1,["CRITICAL","Low"]],[3,11,3,0,["CRITICAL"]],[3,11,3,1,["CRITICAL"]],[3,11,4,0,["CRITICAL"]],[3,11,4,1,["CRITICAL"]],[3,11,5,0,["CRITICAL"]],[3,11,5,1,["CRITICAL"]],[3,12,0,0,["CRITICAL"]],[3,12,0,1,["CRITICAL"]],[3,12,1,0,["CRITICAL"]],[3,12,1,1,["CRITICAL"]],[3,12,2,0,["CRITICAL"]],[3,12,2,1,["CRITICAL"]],[3,12,3,0,["CRITICAL"]],[3,12,3,1,["CRITICAL"]],[3,12,4,0,["CRITICAL"]],[3,12,4,1,["CRITICAL"]],[3,12,5,0,["CRITICAL"]],[3,12,5,1,["CRITICAL"]],[3,13,0,0,["CRITICAL"]],[3,13,0,1,["CRITICAL"]],[3,13,1,0,["CRITICAL"]],[3,13,1,1,["CRITICAL"]],[3,13,2,0,["CRITICAL"]],[3,13,2,1,["CRITICAL"]],[3,13,3,0,["CRITICAL"]],[3,13,3,1,["CRITICAL"]],[3,13,4,0,["CRITICAL"]],[3,13,4,1,["CRITICAL"]],[3,13,5,0,["CRITICAL"]],[3,13,5,1,["CRITICAL"]],[3,14,0,0,["CRITICAL"]],[3,14,0,1,["CRITICAL"]],[3,14,1,0,["CRITICAL"]],[3,14,1,1,["CRITICAL"]],[3,14,2,0,["CRITICAL"]],[3,14,2,1,["CRITICAL"]],[3,14,3,0,["CRITICAL"]],[3,14,3,1,["CRITICAL"]],[3,14,4,0,["CRITICAL"]],[3,14,4,1,["CRITICAL"]],[3,14,5,0,["CRITICAL"]],[3,14,5,1,["CRITICAL"]],[3,15,0,0,["CRITICAL"]],[3,15,0,1,["CRITICAL"]],[3,15,1,0,["CRITICAL"]],[3,15,1,1,["CRITICAL"]],[3,15,2,0,["CRITICAL"]],[3,15,2,1,["CRITICAL"]],[3,15,3,0,["CRITICAL"]],[3,15,3,1,["CRITICAL"]],[3,15,4,0,["CRITICAL"]],[3,15,4,1,["CRITICAL"]],[3,15,5,0,["CRITICAL"]],[3,15,5,1,["CRITICAL"]],[3,16,0,0,["CRITICAL"]],[3,16,0,1,["CRITICAL"]],[3,16,1,0,["CRITICAL"]],[3,16,1,1,["CRITICAL"]],[3,16,2,0,["CRITICAL"]],[3,16,2,1,["CRITICAL"]],[3,16,3,0,["CRITICAL"]],[3,16,3,1,["CRITICAL"]],[3,16,4,0,["CRITICAL"]],[3,16,4,1,["CRITICAL"]],[3,16,5,0,["CRITICAL"]],[3,16,5,1,["CRITICAL"]],[3,17,0,0,["CRITICAL"]],[3,17,0,1,["CRITICAL"]],[3,17,1,0,["CRITICAL"]],[3,17,1,1,["CRITICAL"]],[3,17,2,0,["CRITICAL"]],[3,17,2,1,["CRITICAL"]],[3,17,3,0,["CRITICAL"]],[3,17,3,1,["CRITICAL"]],[3,17,4,0,["CRITICAL"]],[3,17,4,1,["CRITICAL"]],[3,17,5,0,["CRITICAL"]],[3,17,5,1,["CRITICAL"]],[3,18,0,0,["CRITICAL"]],[3,18,0,1,["CRITICAL"]],[3,18,1,0,["CRITICAL"]],[3,18,1,1,["CRITICAL"]],[3,18,2,0,["CRITICAL"]],[3,18,2,1,["CRITICAL"]],[3,18,3,0,["CRITICAL"]],[3,18,3,1,["CRITICAL"]],[3,18,4,0,["CRITICAL"]],[3,18,4,1,["CRITICAL"]],[3,18,5,0,["CRITICAL"]],[3,18,5,1,["CRITICAL"]],[3,19,0,0,["CRITICAL"]],[3,19,0,1,["CRITICAL"]],[3,19,1,0,["CRITICAL"]],[3,19,1,1,["CRITICAL"]],[3,19,2,0,["CRITICAL"]],[3,19,2,1,["CRITICAL"]],[3,19,3,0,["CRITICAL"]],[3,19,3,1,["CRITICAL"]],[3,19,4,0,["CRITICAL"]],[3,19,4,1,["CRITICAL"]],[3,19,5,0,["CRITICAL"]],[3,19,5,1,["CRITICAL"]],[4,0,0,0,["Low"]],[4,0,0,1,["CRITICAL"]],[4,0,1,0,["Low"]],[4,0,1,1,["CRITICAL"]],[4,0,2,0,["Low"]],[4,0,2,1,["CRITICAL"]],[4,0,3,0,["Low"]],[4,0,3,1,["CRITICAL"]],[4,0,4,0,["Low"]],[4,0,4,1,["CRITICAL"]],[4,0,5,0,["Low"]],[4,0,5,1,["CRITICAL"]],[4,1,0,0,["FIXABLE"]],[4,1,0,1,["CRITICAL"]],[4,1,1,0,["FIXABLE"]],[4,1,1,1,["CRITICAL"]],[4,1,2,0,["FIXABLE"]],[4,1,2,1,["CRITICAL"]],[4,1,3,0,["FIXABLE"]],[4,1,3,1,["CRITICAL"]],[4,1,4,0,["FIXABLE"]],[4,1,4,1,["CRITICAL"]],[4,1,5,0,["FIXABLE"]],[4,1,5,1,["CRITICAL"]],[4,2,0,0,["Critical"]],[4,2,0,1,["CRITICAL"]],[4,2,1,0,["Critical"]],[4,2,1,1,["CRITICAL"]],[4,2,2,0,["Critical"]],[4,2,2,1,["CRITICAL"]],[4,2,3,0,["Critical"]],[4,2,3,1,["CRITICAL"]],[4,2,4,0,["Critical"]],[4,2,4,1,["CRITICAL"]],[4,2,5,0,["Critical"]],[4,2,5,1,["CRITICAL"]],[4,3,0,0,["CRITICAL"]],[4,3,0,1,["CRITICAL"]],[4,3,1,0,["CRITICAL"]],[4,3,1,1,["CRITICAL"]],[4,3,2,0,["CRITICAL"]],[4,3,2,1,["CRITICAL"]],[4,3,3,0,["CRITICAL"]],[4,3,3,1,["CRITICAL"]],[4,3,4,0,["CRITICAL"]],[4,3,4,1,["CRITICAL"]],[4,3,5,0,["CRITICAL"]],[4,3,5,1,["CRITICAL"]],[4,4,0,0,["Medium"]],[4,4,0,1,["CRITICAL"]],[4,4,1,0,["Medium"]],[4,4,1,1,["CRITICAL"]],[4,4,2,0,["Medium"]],[4,4,2,1,["CRITICAL"]],[4,4,3,0,["Medium"]],[4,4,3,1,["CRITICAL"]],[4,4,4,0,["Medium"]],[4,4,4,1,["CRITICAL"]],[4,4,5,0,["Medium"]],[4,4,5,1,["CRITICAL"]],[4,5,0,0,["Medium"]],[4,5,0,1,["CRITICAL"]],[4,5,1,0,["Medium"]],[4,5,1,1,["CRITICAL"]],[4,5,2,0,["Medium"]],[4,5,2,1,["CRITICAL"]],[4,5,3,0,["Medium"]],[4,5,3,1,["CRITICAL"]],[4,5,4,0,["Medium"]],[4,5,4,1,["CRITICAL"]],[4,5,5,0,["Medium"]],[4,5,5,1,["CRITICAL"]],[4,6,0,0,["Low"]],[4,6,0,1,["CRITICAL"]],[4,6,1,0,["Low"]],[4,6,1,1,["CRITICAL"]],[4,6,2,0,["Low"]],[4,6,2,1,["CRITICAL"]],[4,6,3,0,["Low"]],[4,6,3,1,["CRITICAL"]],[4,6,4,0,["Low"]],[4,6,4,1,["CRITICAL"]],[4,6,5,0,["Low"]],[4,6,5,1,["CRITICAL"]],[4,7,0,0,["Low"]],[4,7,0,1,["CRITICAL"]],[4,7,1,0,["Low"]],[4,7,1,1,["CRITICAL"]],[4,7,2,0,["Low"]],[4,7,2,1,["CRITICAL"]],[4,7,3,0,["Low"]],[4,7,3,1,["CRITICAL"]],[4,7,4,0,["Low"]],[4,7,4,1,["CRITICAL"]],[4,7,5,0,["Low"]],[4,7,5,1,["CRITICAL"]],[4,8,0,0,["P0"]],[4,8,0,1,["CRITICAL"]],[4,8,1,0,["P0"]],[4,8,1,1,["CRITICAL"]],[4,8,2,0,["P0"]],[4,8,2,1,["CRITICAL"]],[4,8,3,0,["P0"]],[4,8,3,1,["CRITICAL"]],[4,8,4,0,["P0"]],[4,8,4,1,["CRITICAL"]],[4,8,5,0,["P0"]],[4,8,5,1,["CRITICAL"]],[4,9,0,0,["Low"]],[4,9,0,1,["CRITICAL"]],[4,9,1,0,["FIXABLE","Low"]],[4,9,1,1,["CRITICAL","Low"]],[4,9,2,0,["FIXABLE","Low"]],[4,9,2,1,["CRITICAL","Low"]],[4,9,3,0,["Low"]],[4,9,3,1,["CRITICAL"]],[4,9,4,0,["Low"]],[4,9,4,1,["CRITICAL"]],[4,9,5,0,["Low"]],[4,9,5,1,["CRITICAL"]],[4,10,0,0,["Medium"]],[4,10,0,1,["CRITICAL"]],[4,10,1,0,["FIXABLE","Medium"]],[4,10,1,1,["CRITICAL","Medium"]],[4,10,2,0,["FIXABLE","Medium"]],[4,10,2,1,["CRITICAL","Medium"]],[4,10,3,0,["Medium"]],[4,10,3,1,["CRITICAL"]],[4,10,4,0,["Medium"]],[4,10,4,1,["CRITICAL"]],[4,10,5,0,["Medium"]],[4,10,5,1,["CRITICAL"]],[4,11,0,0,["Low"]],[4,11,0,1,["CRITICAL"]],[4,11,1,0,["FIXABLE","Low"]],[4,11,1,1,["CRITICAL","Low"]],[4,11,2,0,["FIXABLE","Low"]],[4,11,2,1,["CRITICAL","Low"]],[4,11,3,0,["Low"]],[4,11,3,1,["CRITICAL"]],[4,11,4,0,["Low"]],[4,11,4,1,["CRITICAL"]],[4,11,5,0,["Low"]],[4,11,5,1,["CRITICAL"]],[4,12,0,0,["Medium"]],[4,12,0,1,["CRITICAL"]],[4,12,1,0,["Medium"]],[4,12,1,1,["CRITICAL"]],[4,12,2,0,["Medium"]],[4,12,2,1,["CRITICAL"]],[4,12,3,0,["Medium"]],[4,12,3,1,["CRITICAL"]],[4,12,4,0,["Medium"]],[4,12,4,1,["CRITICAL"]],[4,12,5,0,["Medium"]],[4,12,5,1,["CRITICAL"]],[4,13,0,0,["Low"]],[4,13,0,1,["CRITICAL"]],[4,13,1,0,["Low"]],[4,13,1,1,["CRITICAL"]],[4,13,2,0,["Low"]],[4,13,2,1,["CRITICAL"]],[4,13,3,0,["Low"]],[4,13,3,1,["CRITICAL"]],[4,13,4,0,["Low"]],[4,13,4,1,["CRITICAL"]],[4,13,5,0,["Low"]],[4,13,5,1,["CRITICAL"]],[4,14,0,0,["Low"]],[4,14,0,1,["CRITICAL"]],[4,14,1,0,["Low"]],[4,14,1,1,["CRITICAL"]],[4,14,2,0,["Low"]],[4,14,2,1,["CRITICAL"]],[4,14,3,0,["Low"]],[4,14,3,1,["CRITICAL"]],[4,14,4,0,["Low"]],[4,14,4,1,["CRITICAL"]],[4,14,5,0,["Low"]],[4,14,5,1,["CRITICAL"]],[4,15,0,0,["LOW"]],[4,15,0,1,["CRITICAL"]],[4,15,1,0,["LOW"]],[4,15,1,1,["CRITICAL"]],[4,15,2,0,["LOW"]],[4,15,2,1,["CRITICAL"]],[4,15,3,0,["LOW"]],[4,15,3,1,["CRITICAL"]],[4,15,4,0,["LOW"]],[4,15,4,1,["CRITICAL"]],[4,15,5,0,["LOW"]],[4,15,5,1,["CRITICAL"]],[4,16,0,0,["P3"]],[4,16,0,1,["CRITICAL"]],[4,16,1,0,["P3"]],[4,16,1,1,["CRITICAL"]],[4,16,2,0,["P3"]],[4,16,2,1,["CRITICAL"]],[4,16,3,0,["P3"]],[4,16,3,1,["CRITICAL"]],[4,16,4,0,["P3"]],[4,16,4,1,["CRITICAL"]],[4,16,5,0,["P3"]],[4,16,5,1,["CRITICAL"]],[4,17,0,0,["High"]],[4,17,0,1,["CRITICAL"]],[4,17,1,0,["High"]],[4,17,1,1,["CRITICAL"]],[4,17,2,0,["High"]],[4,17,2,1,["CRITICAL"]],[4,17,3,0,["High"]],[4,17,3,1,["CRITICAL"]],[4,17,4,0,["High"]],[4,17,4,1,["CRITICAL"]],[4,17,5,0,["High"]],[4,17,5,1,["CRITICAL"]],[4,18,0,0,["Low"]],[4,18,0,1,["CRITICAL"]],[4,18,1,0,["Low"]],[4,18,1,1,["CRITICAL"]],[4,18,2,0,["Low"]],[4,18,2,1,["CRITICAL"]],[4,18,3,0,["Low"]],[4,18,3,1,["CRITICAL"]],[4,18,4,0,["Low"]],[4,18,4,1,["CRITICAL"]],[4,18,5,0,["Low"]],[4,18,5,1,["CRITICAL"]],[4,19,0,0,["CRITICAL"]],[4,19,0,1,["CRITICAL"]],[4,19,1,0,["CRITICAL"]],[4,19,1,1,["CRITICAL"]],[4,19,2,0,["CRITICAL"]],[4,19,2,1,["CRITICAL"]],[4,19,3,0,["CRITICAL"]],[4,19,3,1,["CRITICAL"]],[4,19,4,0,["CRITICAL"]],[4,19,4,1,["CRITICAL"]],[4,19,5,0,["CRITICAL"]],[4,19,5,1,["CRITICAL"]],[5,0,0,0,["Low"]],[5,0,0,1,["Low"]],[5,0,1,0,["Low"]],[5,0,1,1,["Low"]],[5,0,2,0,["Low"]],[5,0,2,1,["Low"]],[5,0,3,0,["Low"]],[5,0,3,1,["Low"]],[5,0,4,0,["Low"]],[5,0,4,1,["Low"]],[5,0,5,0,["Low"]],[5,0,5,1,["Low"]],[5,1,0,0,[]],[5,1,0,1,[]],[5,1,1,0,[]],[5,1,1,1,[]],[5,1,2,0,[]],[5,1,2,1,[]],[5,1,3,0,[]],[5,1,3,1,[]],[5,1,4,0,[]],[5,1,4,1,[]],[5,1,5,0,[]],[5,1,5,1,[]],[5,2,0,0,["Critical"]],[5,2,0,1,["Critical"]],[5,2,1,0,["Critical"]],[5,2,1,1,["Critical"]],[5,2,2,0,["Critical"]],[5,2,2,1,["Critical"]],[5,2,3,0,["Critical"]],[5,2,3,1,["Critical"]],[5,2,4,0,["Critical"]],[5,2,4,1,["Critical"]],[5,2,5,0,["Critical"]],[5,2,5,1,["Critical"]],[5,3,0,0,["CRITICAL"]],[5,3,0,1,["CRITICAL"]],[5,3,1,0,["CRITICAL"]],[5,3,1,1,["CRITICAL"]],[5,3,2,0,["CRITICAL"]],[5,3,2,1,["CRITICAL"]],[5,3,3,0,["CRITICAL"]],[5,3,3,1,["CRITICAL"]],[5,3,4,0,["CRITICAL"]],[5,3,4,1,["CRITICAL"]],[5,3,5,0,["CRITICAL"]],[5,3,5,1,["CRITICAL"]],[5,4,0,0,["Medium"]],[5,4,0,1,["Medium"]],[5,4,1,0,["Medium"]],[5,4,1,1,["Medium"]],[5,4,2,0,["Medium"]],[5,4,2,1,["Medium"]],[5,4,3,0,["Medium"]],[5,4,3,1,["Medium"]],[5,4,4,0,["Medium"]],[5,4,4,1,["Medium"]],[5,4,5,0,["Medium"]],[5,4,5,1,["Medium"]],[5,5,0,0,["Medium"]],[5,5,0,1,["Medium"]],[5,5,1,0,["Medium"]],[5,5,1,1,["Medium"]],[5,5,2,0,["Medium"]],[5,5,2,1,["Medium"]],[5,5,3,0,["Medium"]],[5,5,3,1,["Medium"]],[5,5,4,0,["Medium"]],[5,5,4,1,["Medium"]],[5,5,5,0,["Medium"]],[5,5,5,1,["Medium"]],[5,6,0,0,["Low"]],[5,6,0,1,["Low"]],[5,6,1,0,["Low"]],[5,6,1,1,["Low"]],[5,6,2,0,["Low"]],[5,6,2,1,["Low"]],[5,6,3,0,["Low"]],[5,6,3,1,["Low"]],[5,6,4,0,["Low"]],[5,6,4,1,["Low"]],[5,6,5,0,["Low"]],[5,6,5,1,["Low"]],[5,7,0,0,["Low"]],[5,7,0,1,["Low"]],[5,7,1,0,["Low"]],[5,7,1,1,["Low"]],[5,7,2,0,["Low"]],[5,7,2,1,["Low"]],[5,7,3,0,["Low"]],[5,7,3,1,["Low"]],[5,7,4,0,["Low"]],[5,7,4,1,["Low"]],[5,7,5,0,["Low"]],[5,7,5,1,["Low"]],[5,8,0,0,["P0"]],[5,8,0,1,["P0"]],[5,8,1,0,["P0"]],[5,8,1,1,["P0"]],[5,8,2,0,["P0"]],[5,8,2,1,["P0"]],[5,8,3,0,["P0"]],[5,8,3,1,["P0"]],[5,8,4,0,["P0"]],[5,8,4,1,["P0"]],[5,8,5,0,["P0"]],[5,8,5,1,["P0"]],[5,9,0,0,["Low"]],[5,9,0,1,["Low"]],[5,9,1,0,["Low"]],[5,9,1,1,["Low"]],[5,9,2,0,["Low"]],[5,9,2,1,["Low"]],[5,9,3,0,["Low"]],[5,9,3,1,["Low"]],[5,9,4,0,["Low"]],[5,9,4,1,["Low"]],[5,9,5,0,["Low"]],[5,9,5,1,["Low"]],[5,10,0,0,["Medium"]],[5,10,0,1,["Medium"]],[5,10,1,0,["Medium"]],[5,10,1,1,["Medium"]],[5,10,2,0,["Medium"]],[5,10,2,1,["Medium"]],[5,10,3,0,["Medium"]],[5,10,3,1,["Medium"]],[5,10,4,0,["Medium"]],[5,10,4,1,["Medium"]],[5,10,5,0,["Medium"]],[5,10,5,1,["Medium"]],[5,11,0,0,["Low"]],[5,11,0,1,["Low"]],[5,11,1,0,["Low"]],[5,11,1,1,["Low"]],[5,11,2,0,["Low"]],[5,11,2,1,["Low"]],[5,11,3,0,["Low"]],[5,11,3,1,["Low"]],[5,11,4,0,["Low"]],[5,11,4,1,["Low"]],[5,11,5,0,["Low"]],[5,11,5,1,["Low"]],[5,12,0,0,["Medium"]],[5,12,0,1,["Medium"]],[5,12,1,0,["Medium"]],[5,12,1,1,["Medium"]],[5,12,2,0,["Medium"]],[5,12,2,1,["Medium"]],[5,12,3,0,["Medium"]],[5,12,3,1,["Medium"]],[5,12,4,0,["Medium"]],[5,12,4,1,["Medium"]],[5,12,5,0,["Medium"]],[5,12,5,1,["Medium"]],[5,13,0,0,["Low"]],[5,13,0,1,["Low"]],[5,13,1,0,["Low"]],[5,13,1,1,["Low"]],[5,13,2,0,["Low"]],[5,13,2,1,["Low"]],[5,13,3,0,["Low"]],[5,13,3,1,["Low"]],[5,13,4,0,["Low"]],[5,13,4,1,["Low"]],[5,13,5,0,["Low"]],[5,13,5,1,["Low"]],[5,14,0,0,["Low"]],[5,14,0,1,["Low"]],[5,14,1,0,["Low"]],[5,14,1,1,["Low"]],[5,14,2,0,["Low"]],[5,14,2,1,["Low"]],[5,14,3,0,["Low"]],[5,14,3,1,["Low"]],[5,14,4,0,["Low"]],[5,14,4,1,["Low"]],[5,14,5,0,["Low"]],[5,14,5,1,["Low"]],[5,15,0,0,["LOW"]],[5,15,0,1,["LOW"]],[5,15,1,0,["LOW"]],[5,15,1,1,["LOW"]],[5,15,2,0,["LOW"]],[5,15,2,1,["LOW"]],[5,15,3,0,["LOW"]],[5,15,3,1,["LOW"]],[5,15,4,0,["LOW"]],[5,15,4,1,["LOW"]],[5,15,5,0,["LOW"]],[5,15,5,1,["LOW"]],[5,16,0,0,["P3"]],[5,16,0,1,["P3"]],[5,16,1,0,["P3"]],[5,16,1,1,["P3"]],[5,16,2,0,["P3"]],[5,16,2,1,["P3"]],[5,16,3,0,["P3"]],[5,16,3,1,["P3"]],[5,16,4,0,["P3"]],[5,16,4,1,["P3"]],[5,16,5,0,["P3"]],[5,16,5,1,["P3"]],[5,17,0,0,["High"]],[5,17,0,1,["High"]],[5,17,1,0,["High"]],[5,17,1,1,["High"]],[5,17,2,0,["High"]],[5,17,2,1,["High"]],[5,17,3,0,["High"]],[5,17,3,1,["High"]],[5,17,4,0,["High"]],[5,17,4,1,["High"]],[5,17,5,0,["High"]],[5,17,5,1,["High"]],[5,18,0,0,["Low"]],[5,18,0,1,["Low"]],[5,18,1,0,["Low"]],[5,18,1,1,["Low"]],[5,18,2,0,["Low"]],[5,18,2,1,["Low"]],[5,18,3,0,["Low"]],[5,18,3,1,["Low"]],[5,18,4,0,["Low"]],[5,18,4,1,["Low"]],[5,18,5,0,["Low"]],[5,18,5,1,["Low"]],[5,19,0,0,["CRITICAL"]],[5,19,0,1,["CRITICAL"]],[5,19,1,0,["CRITICAL"]],[5,19,1,1,["CRITICAL"]],[5,19,2,0,["CRITICAL"]],[5,19,2,1,["CRITICAL"]],[5,19,3,0,["CRITICAL"]],[5,19,3,1,["CRITICAL"]],[5,19,4,0,["CRITICAL"]],[5,19,4,1,["CRITICAL"]],[5,19,5,0,["CRITICAL"]],[5,19,5,1,["CRITICAL"]]]}} diff --git a/test/review-dispatch.test.ts b/test/review-dispatch.test.ts index 56e140c84..c58e92af0 100644 --- a/test/review-dispatch.test.ts +++ b/test/review-dispatch.test.ts @@ -4,7 +4,7 @@ import * as fs from 'node:fs'; import * as os from 'node:os'; import * as path from 'node:path'; import { BriefError, checkReviewedTree, promptHash, renderBrief, sectionTexts, workspaceParagraph, workspaceStep } from '../lib/review-brief'; -import { collect, judge, parseFindings, readJsonl, type MergedLine } from '../lib/review-ledger'; +import { collect, judge, parseFindings, rank, readJsonl, type MergedLine } from '../lib/review-ledger'; const ROOT = path.resolve(import.meta.dir, '..'); const BIN = path.join(ROOT, 'bin', 'gstack-review-dispatch'); @@ -305,8 +305,9 @@ describe('gstack-review-dispatch sent, collect, judge and verify: nothing change // Value: protects=a negated severity word still collects at its label, so a reader's closing prose ("found nothing CRITICAL") is a // known phantom lead judgment folds and never a dropped line (GSTA-167 S1 reverts GST-766's negation drop); fails_when=any negated - // form collects nothing or a weaker label; why_new=GST-766's drop lost blockers named in exception clauses; seam=parseFindings; - // no_claim=that a negated line is a real finding (judge folds phantoms) + // form collects nothing or a weaker label, except under the finding's own Severity field, which decides it (GST-976); + // why_new=GST-766's drop lost blockers named in exception clauses; seam=parseFindings; no_claim=that a negated line is a real + // finding (judge folds phantoms) test('a negated severity word still collects at its label: GEVA-92 fix-check#5 and its negated forms are known phantoms', () => { const fixCheck = [ 'REVIEWED_TREE: bedd511efa0fa16c9277821073c68e438dc760d2 /workspace/gstack-evals', @@ -332,7 +333,7 @@ describe('gstack-review-dispatch sent, collect, judge and verify: nothing change expect(parseFindings('r', 'No CRITICAL lock guards the write in Makefile:7\nSeverity: CRITICAL').map(f => f.label)).toEqual(['CRITICAL']); expect(parseFindings('r', '1. auth.ts:3 LOW: log line too verbose\nNo CRITICAL lock guards the write in Makefile:7\nSeverity: CRITICAL').map(f => [f.label, f.raw])).toEqual([['LOW', '1. auth.ts:3 LOW: log line too verbose'], ['CRITICAL', 'No CRITICAL lock guards the write in Makefile:7 | Severity: CRITICAL']]); expect(parseFindings('r', '1. auth.ts:3 LOW: log line too verbose\nNo CRITICAL issues remain.').map(f => f.label)).toEqual(['LOW', 'CRITICAL']); - expect(parseFindings('outside-voice', '- a.ts:3 race. Severity: Low. Blocks: no\n Separately, nothing CRITICAL about b.ts:9, but it leaks fds.\n Severity: High').map(f => [f.label, f.raw])).toEqual([['Low', '- a.ts:3 race. Severity: Low. Blocks: no'], ['CRITICAL', 'Separately, nothing CRITICAL about b.ts:9, but it leaks fds. | Severity: High']]); + expect(parseFindings('outside-voice', '- a.ts:3 race. Severity: Low. Blocks: no\n Separately, nothing CRITICAL about b.ts:9, but it leaks fds.\n Severity: High').map(f => [f.label, f.raw])).toEqual([['Low', '- a.ts:3 race. Severity: Low. Blocks: no'], ['High', 'Separately, nothing CRITICAL about b.ts:9, but it leaks fds. | Severity: High']]); expect(parseFindings('r', '1. A CRITICAL race in queue.ts:78 that no lock covers').map(f => f.label)).toEqual(['CRITICAL']); expect(parseFindings('r', '- A divide by zero CRITICAL bug in parse()').map(f => f.label)).toEqual(['CRITICAL']); expect(parseFindings('adversarial-native', 'FIXABLE: no timeout on the fetch in a.ts:3').map(f => f.label)).toEqual(['CRITICAL']); @@ -406,8 +407,8 @@ describe('gstack-review-dispatch sent, collect, judge and verify: nothing change expect(parseFindings('outside-voice', '> Blocks: yes').map(f => f.label)).toEqual(['CRITICAL']); }); // Value: protects=a later finding's Severity/Blocks line never lands on the finding before it, and an explicit Severity label - // decides its line (#3660 pass 2 Red Team); fails_when=the later blocker's text is lost and the earlier finding takes its - // CRITICAL, or 'Severity: Low (not High)' collects as High; seam=parseFindings + // decides its line unless a stronger label leads that line (#3660 pass 2 Red Team, GST-976); fails_when=the later blocker's text + // is lost and the earlier finding takes its CRITICAL, or 'Severity: Low (not High)' collects as High; seam=parseFindings test('prose after a finding\'s field, a blank-line paragraph or an indented block starts the next finding; an explicit Severity label wins', () => { const raws = (o: string) => parseFindings('outside-voice', o).map(f => [f.label, f.raw]); const two = [['Low', 'A in a.ts:1. | Severity: Low'], ['CRITICAL', 'B in b.ts:2. | Blocks: yes']]; @@ -603,7 +604,7 @@ describe('gstack-review-dispatch sent, collect, judge and verify: nothing change for (const line of ['There are no CRITICAL findings.', 'No CRITICAL or High findings to report.', 'I found nothing CRITICAL.', "So there's nothing at CRITICAL.", 'Neither finding is CRITICAL.', 'Nothing here is CRITICAL.', 'Neither fix is CRITICAL.', 'Nothing in this diff is CRITICAL.', 'This is not CRITICAL.']) expect([line, parseFindings('outside-voice', line).map(f => f.label)]).toEqual([line, ['CRITICAL']]); - expect(parseFindings('outside-voice', 'Severity: Low (not High)').map(f => f.label)).toEqual(['High']); + expect(parseFindings('outside-voice', 'Severity: Low (not High)').map(f => f.label)).toEqual(['Low']); }); // Value: protects=item layouts collect as on main: an indented JSON finding keeps its JSON severity, an indented label heading sets @@ -626,6 +627,82 @@ describe('gstack-review-dispatch sent, collect, judge and verify: nothing change .toEqual([['CRITICAL', '{"severity":"low","summary":"race"} | this blocks the merge. Blocks: yes']]); }); + // Value: protects=a finding's own Severity and Blocks fields set its collected label, so a severity word in its body never raises it + // (gstack-evals #143: the outside voice marked six findings Blocks: no, and the "P0" in #1, #2 and #4 was the plan's phase name), + // while a real P0 or CRITICAL in label position, a Severity: P0 field and Blocks: yes still collect as blocking; fails_when=a body + // token outranks the finding's fields, or a label-position P0/CRITICAL or Blocks: yes collects below CRITICAL rank; + // why_new=GST-976: #1, #2 and #4 collected as P0, judge refused the downgrade (JUDGMENT_REJECTED), verify stayed dirty and the + // receipt needed accepted_by; seam=parseFindings, collect and judge; no_claim=that a body-only label on a line with no Severity field + // is a real finding (it still collects at that label, a known phantom judge may fold; GSTA-167 S1 keeps body labels with no fields + // because dropping them lost blockers) + test('GST-976: a severity word in a finding body never outranks its Severity and Blocks fields; real P0 and CRITICAL still block', () => { + const blocking = (label: string) => rank(label) === 4; + // The #143 outside-voice reply, cut to each finding's title, its P0 sentence and its fields (gstack-evals is private). + const reply = [ + 'The problems below are about accounting and what the post leaves out. None of them breaks a test, production or custody.', + '', + '1. **The per-task cost leaves out model spend.** The P0 and bulk go or no-go will re-project cost from these figures, so they will come out too low. Severity: Medium. Blocks: no.', + '', + '2. **One round-2 K1 pair is not accounted for.** The post sets a precedent for P0 yield math, so that drop should be named. Severity: Low. Blocks: no.', + '', + '3. **The two probe populations are not reconciled.** The stage table probes 189 candidates. Severity: Low. Blocks: no.', + '', + "4. **The P0 impact of the shortfall is missing.** The plan's P0 (line 323) needs 6 K4 replays and 2 decoys. The post says the shortfall but not that it blocks P0. Severity: Low. Blocks: no.", + '', + '6. **Some wording is ambiguous.** Two examples:', + ' - "Repositories 4 (3 for build tasks)" is set against a target of "at least 5 repositories".', + '', + ' Severity: Low. Blocks: no.', + '', + "Recommendation: ship after a one-line fix because finding 1's per-task cost leaves out measured model spend.", + ].join('\n'); + const d = tmp(); + const merged = path.join(d, 'merged.jsonl'); + const r = collect(path.join(d, 'l.jsonl'), 'outside-voice', reply, merged); + expect(r.lines.map(l => [l.label, l.stated])).toEqual([['Medium', { severity: 'Medium', blocks: 'no' }], ...Array(4).fill(['Low', { severity: 'Low', blocks: 'no' }])]); + expect(r.lines.filter(l => blocking(l.label)).map(l => l.id)).toEqual([]); + const judged = path.join(d, 'judged.jsonl'); + fs.writeFileSync(judged, r.lines.map(l => JSON.stringify({ id: l.id, severity: l.stated!.severity })).join('\n') + '\n'); + expect(judge(readJsonl(merged), readJsonl(judged))).toMatchObject({ ok: true, downgraded: [] }); + const real: Array<[string, string]> = [['[P0] Token leak in log.ts:3', 'P0'], ['P0: token leak in log.ts:3', 'P0'], ['1. Token leak in log.ts:3\n Severity: P0', 'P0'], + ['1. The P0 pilot drops the last row (q.ts:7). Severity: P0. Blocks: no', 'P0'], ['**Critical**\n- Token leak in log.ts:3', 'Critical'], ['## P0\n- Token leak in log.ts:3', 'P0'], + ['### CRITICAL: missing auth check in api.ts:10', 'CRITICAL'], ['1. The P0 pilot loses rows on retry (r.ts:2). Severity: Low. Blocks: yes', 'CRITICAL'], + ['1. The P0 pilot loses rows on retry (r.ts:2)\n Severity: Medium\n Blocks: yes', 'CRITICAL']]; + for (const [output, label] of real) { + const got = parseFindings('outside-voice', output).map(f => f.label); + expect([output, got, got.map(blocking)]).toEqual([output, [label], [true]]); + } + expect(parseFindings('outside-voice', '1. The P0 pilot table drops a row (t.md:3)').map(f => f.label)).toEqual(['P0']); + // Review of this fix (gst976-p1): a locus-first or emoji-led label, an inline field the next field line follows, a second field on + // the line, and prose that only mentions a severity never lower a blocker the reader labeled. + const kept: Array<[string, string]> = [['1. api.ts:10 CRITICAL: missing auth. Severity: Low', 'CRITICAL'], ['1. api.ts:10 CRITICAL: missing auth\n Severity: Low', 'CRITICAL'], + ['1. 🔴 CRITICAL: missing auth. Severity: Low', 'CRITICAL'], ['1. Token leak in auth.ts:3 lets anyone read sessions. Severity: Critical\n\nSeverity: Low', 'Critical'], + ['- auth.ts:3 token leak. Severity: Low (pre-exploit), Severity: Critical (once exposed)', 'Critical'], + ['- Missing auth on DELETE /users lets any user wipe accounts (CRITICAL); the old ticket filed it at severity low.', 'CRITICAL'], + ['- api.ts:10 lets any user wipe accounts. Earlier triage said Severity: Low; it is CRITICAL.', 'CRITICAL']]; + for (const [output, label] of kept) expect([output, parseFindings('outside-voice', output).map(f => f.label)]).toEqual([output, [label]]); + // gst976-p2: an all-caps lead before a space, comma or parenthesis; a field after a locus's parenthesis or with no colon at the + // line's start; and a long run of marks before a label stays linear. + const p2: Array<[string, string]> = [['1. CRITICAL missing auth. Severity: Low', 'CRITICAL'], ['1. CRITICAL, missing auth on DELETE. Severity: Low', 'CRITICAL'], + ['1. CRITICAL (api.ts:10) missing auth. Severity: Low', 'CRITICAL'], ['1. The P0 pilot table drops a row (t.md:3) Severity: Low', 'Low'], + ['1. The P0 pilot table drops a row\nSeverity Low', 'Low'], ['1. The P0 pilot table drops a row\n**Severity** Low', 'Low'], + ['1. Bypass x.ts:3 is CRITICAL (Severity: Low in pass 1)', 'CRITICAL'], ['Still open: x.ts:3 is CRITICAL, Severity: Low in pass 1 understated it', 'CRITICAL'], + ['1. lib/x.ts:42-58 CRITICAL: drops rows. Severity: Low', 'CRITICAL'], ['1. lib/x.ts:42:7 CRITICAL: drops rows. Severity: Low', 'CRITICAL'], + ['1. (lib/x.ts:42, 50) CRITICAL: drops rows. Severity: Low', 'CRITICAL'], + ['1. The P0 pilot table drops a row\nSeverity: Low: only the pilot', 'Low'], ['1. The P0 pilot table drops a row\nSeverity: Low because it is internal', 'Low'], + ['1. The P0 pilot table drops a row\nSeverity: Low/Medium', 'P0'], ['Severity: Low: only the P0 pilot table', 'Low'], + ['1. The P0 pilot drops a row. Severity: Low/P3', 'P0'], ['1. drops rows\nSeverity: High/Critical', 'Critical'], + ['Severity: Medium/CRITICAL', 'CRITICAL'], ['1. x.ts:3 drops prod rows. Severity: Low/CRITICAL', 'CRITICAL'], + ['1. x.ts:3 is CRITICAL (Severity: Low/Medium in pass 1)', 'CRITICAL'], ['1. x.ts:3 is CRITICAL (Severity: Low: pass 1)', 'CRITICAL'], + ['Still open: x.ts:3 is P0, Severity: Low: pass 1 understated it', 'P0']]; + for (const [output, label] of p2) expect([output, parseFindings('outside-voice', output).map(f => f.label)]).toEqual([output, [label]]); + const t0 = performance.now(); + for (const run of ['='.repeat(60), '-'.repeat(60), '|' + '-'.repeat(60) + '|', '🔴'.repeat(60), '. '.repeat(60), '-.'.repeat(60), '`'.repeat(60)]) + for (const tail of [' P0 pilot table', ' High-risk', ' CRITICAL findings follow', ' a.ts:3 P0 pilot']) parseFindings('outside-voice', run + tail + '. Severity: Low'); + parseFindings('outside-voice', '-'.repeat(16000) + ' P0 pilot table. Severity: Low'); + expect(performance.now() - t0).toBeLessThan(1000); + }); + // Value: protects=a non-review the same dispatch later answers with a review is voided (counted, VERIFY clean), and a failed outside // voice recorded with --unavailable reads UNAVAILABLE (missing coverage, never a review) without blocking, while --unavailable is // refused for any other reader; fails_when=one outside-voice timeout or one refusal makes VERIFY dirty for good, or --unavailable diff --git a/test/review-ledger-invariant.test.ts b/test/review-ledger-invariant.test.ts new file mode 100644 index 000000000..f2edd39d3 --- /dev/null +++ b/test/review-ledger-invariant.test.ts @@ -0,0 +1,46 @@ +import { describe, expect, test } from 'bun:test'; +import * as fs from 'node:fs'; +import * as path from 'node:path'; +import { parseFindings, rank } from '../lib/review-ledger'; + +const ROOT = path.resolve(import.meta.dir, '..'); +const LABELS = 'CRITICAL|INFORMATIONAL|Critical|Informational|High|HIGH|Medium|MEDIUM|Low|LOW|P[0-3]|FIXABLE|INVESTIGATE'; +const CHAIN = `(?:${LABELS})(?:\\s*[/→]\\s*\\**\\s*(?:${LABELS}))*`; +/** A finding's own Severity field as GST-976 defines it: at a line's start (colon optional), or after a separator with its colon and a closed clause. */ +const FIELD = new RegExp(`(?:(?:^|\\| )(?:[-*+>]\\s+|\\d+[.)]\\s+)?\\**\\s*Severity\\**\\s*:?\\s*\\**\\s*(${CHAIN})(?![A-Za-z0-9])|(?:[.;,|()]\\s*|\\s[—–-]\\s*)\\**\\s*Severity\\**\\s*:\\s*\\**\\s*(${CHAIN})(?![A-Za-z0-9])(?=\\**\\s*(?:$|[.;,|()*—–]|-\\s|Blocks)))`, 'gi'); +const LEAD = new RegExp(`(?:^|\\| )[^\\p{L}\\p{N}]*(?:\\d+[.)]\\s*[^\\p{L}\\p{N}]*)?(?:\\w[\\w./-]*:\\d+(?:[-–:,]\\s*\\d+)*\\S*\\s+[^\\p{L}\\p{N}]*)?(?:${LABELS})(?![a-z])`, 'u'); +const HEADING = new RegExp(`^(?:#{1,6}\\s*|\\*\\*)(?:${LABELS})\\b`, 'm'); +const LABEL = new RegExp(`${LABELS}`, 'gi'); + +describe('parseFindings is never weaker than main (GST-976 invariant)', () => { + // Value: protects=no input the suite pins, no reader fixture and no Severity field shape collects below the label main (82e9d7ec) + // collected, unless the finding's own Severity field states exactly one label, and such a finding collects at that label unless a + // leading label, a label heading, Blocks: yes or the native voice's FIXABLE raises it; fails_when=a field chain (High/Critical) keeps + // its weaker label (b3ddd6c) or a field whose clause runs on stops counting and a body P0 raises the finding (f3810d4); + // why_new=three GST-976 review rounds each found a shape the row tables missed; seam=parseFindings; no_claim=that main's label was + // right (it is the floor), or coverage of stored private reader outputs (checked outside the repo) + test('every pinned input, reader fixture and generated field shape', () => { + const { entries, shapes } = JSON.parse(fs.readFileSync(path.join(ROOT, 'test/fixtures/review-ledger/main-labels.json'), 'utf8')); + const { bodies, fields: tails, joins, readers, generated } = shapes; + for (const [b, f, j, r, main] of generated) entries.push({ reader: readers[r], output: bodies[b] + joins[j] + tails[f], main }); + const bad: string[] = []; + let findings = 0; + for (const e of entries as Array<{ reader: string; output?: string; fixture?: string; main: string[] }>) { + const output = e.output ?? fs.readFileSync(path.join(ROOT, 'test/fixtures', e.fixture!), 'utf8'); + const got = parseFindings(e.reader, output); + if (!e.main.length) continue; + if (got.length !== e.main.length) { bad.push(`count ${got.length}/${e.main.length} ${JSON.stringify(output.slice(0, 80))}`); continue; } + got.forEach((f, i) => { + findings++; + const fields = [...f.raw.matchAll(FIELD)].map(m => (m[1] ?? m[2])!); + const single = fields.length === 1 && fields[0]!.match(LABEL)!.length === 1 ? fields[0]!.match(LABEL)![0] : undefined; + const raised = /Blocks:?\**:?\s*\**\s*yes/i.test(f.raw) || (e.reader.startsWith('adversarial-native') && /FIXABLE/.test(f.raw)) || LEAD.test(f.raw) || HEADING.test(output); + const ok = single === undefined ? (rank(f.label) ?? 0) >= (rank(e.main[i]) ?? 0) + : (rank(f.label) ?? 0) >= (rank(single) ?? 0) && (raised || (rank(f.label) ?? 0) === (rank(single) ?? 0)); + if (!ok) bad.push(`${e.reader} main=${e.main[i]} got=${f.label} field=${single ?? '-'} ${JSON.stringify(f.raw.slice(0, 100))}`); + }); + } + expect(bad).toEqual([]); + expect(findings).toBeGreaterThan(1000); + }); +});