review-depth: key the first-pass Red Team cut to the branch review log (GSTA-167 option a)

A restarted /ship reset fullPasses and last, so it dropped the Red Team on
a branch an earlier run had already reviewed. gstack-review-plan now reads
the branch review log (lib/ship-budget reviewPaths, DIFF_REVIEWS rows) and
keeps the Red Team when a row exists or the log is unreadable.

Repins lib/review-depth.ts under replay V7 (the cut only narrows).
DEPTH_RULES unchanged (e9281c6c3758ea0f).

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-31 17:23:58 +00:00
1 parent db1405e8bb
commit 072ef1d5dc
8 files changed
+82 -18

No files matched your search

+3 -1
View File
@@ -299,6 +299,8 @@ export interface PlanInput extends ClassInput {
tiers?: boolean;
/** The targeted classes (lib/review-targeted.ts) and whether the targeted reader already read this product patch. */
targeted?: { classes: readonly string[]; ran?: boolean };
/** This branch's review log holds a diff-review row from an earlier run, or could not be read: the first full pass keeps the Red Team. */
reviewedBefore?: boolean;
}
/** One reviewer. `exclude` holds git pathspec argv items the reviewer's diff leaves out; `checklists` names what the batched specialist reads. */
export interface Dispatch { role: Role; name: string; effort: Effort; exclude: string[]; checklists?: string[]; reason?: string }
@@ -413,7 +415,7 @@ export function planReview(i: PlanInput): ReviewPlan {
if (checklists.length) add('specialist', 'batched', specialist, full ? [] : docsAndOutputs, { checklists });
const codeLike = dcls === 'code' || dcls === 'gate';
const sized = dcls === 'gate' || (dcls === 'code' && lines > RED_TEAM_LINES);
const firstPassCut = sized && h.fullPasses === 0 && h.last === 'none' && !RED_TEAM_FIRST_PASS;
const firstPassCut = sized && h.fullPasses === 0 && h.last === 'none' && !i.reviewedBefore && !RED_TEAM_FIRST_PASS;
if (codeLike && (!!i.criticalFound || raised || (sized && !firstPassCut))) add('red-team', 'red-team', 'full');
else if (firstPassCut) skipped.push('red-team (first full pass; Round 7 no-loss)');
else skipped.push(`red-team (${dcls} class${dcls === 'code' ? `, ${lines} runtime lines, no critical` : ''})`);
+1 -1
View File
@@ -5,7 +5,7 @@ import { join } from 'node:path';
import { deriveReviewStatus, readJsonl } from './headless-artifacts';
import { resultLine, type ResultCodeName } from './result-codes';
const DIFF_REVIEWS = new Set(['review', 'review-fix-check', 'adversarial-review', 'codex-review', 'design-review-lite', 'ship']);
export const DIFF_REVIEWS: ReadonlySet<string> = new Set(['review', 'review-fix-check', 'adversarial-review', 'codex-review', 'design-review-lite', 'ship']);
const SHARED_LIBS_COVERAGE_VERSION = 1;
const HASH = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;