review: default review.panel all, one-reader shape opt-in (GSTA-258 build C, option B)

Today's reviewer panel stays the default dispatch. review.panel risk (and off)
opt in to the one-reader shape, whose no-loss replay came back FIX-METHOD
(readers saw only the diff, no repository: 2/68 non-risk blockers).
Raise-only additions stay on by default: HARN-1, eval and policy classes,
GST-1129 spend-binding money and --declare-risk, doc secrets. Platform depth
stays off by default.

Repins ship/sections/review-army.md, ship/sections/adversarial.md,
lib/review-depth.ts and lib/review-risk.ts under no-loss check GSTA-258-C:
the planner over the last 200 first-parent main commits to 6f1dfd5b7c plans
the same depth, classes and dispatches on 196 and only raises on the other 4;
brief bodies still hash to their pins.

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-11-03 03:51:25 +00:00
1 parent aae15e294e
commit 889b99bbda
14 files changed
+38 -37

No files matched your search

+9 -2
View File
@@ -86,7 +86,7 @@ describe('R65 lean dispatch (GSTA-258 build C): one reviewer, once', () => {
expect(roles(p)).toEqual(['adversarial-native:single:full:lane']);
expect(roles(planReview(base({ shape: lean({ readerModel: 'cross-family' }) })))).toEqual(['adversarial-native:single:full:cross-family']);
});
test('default (panel risk, FOUN-64 item 1): a risk-class diff gets the printed full-depth panel; a fixed blocker re-runs the printed plan as round 2 (FOUN-32 §5)', () => {
test('panel risk (opt-in, FOUN-64 item 1): a risk-class diff gets the printed full-depth panel; a fixed blocker re-runs the printed plan as round 2 (FOUN-32 §5)', () => {
const today = roles(planReview(base({ paths: ['lib/billing.ts'], targeted: { classes: ['money'] }, shape: undefined })));
const p = planReview(base({ paths: ['lib/billing.ts'], targeted: { classes: ['money'] } }));
expect([p.depth, p.mode, roles(p)]).toEqual(['full', 'panel', today]);
@@ -140,6 +140,13 @@ describe('C6 platform depth (FOUN-32, founderstar#496): a planned skip needs the
expect(planReview(base({ paths: ['lib/billing.ts'], shape: on(ev) })).mode).toBe('panel');
expect(planReview(base({ paths: ['src/app.ts', 'docs/r.md'], numbers: scanNumbers({ 'docs/r.md': ['p50 4.7 h'] }), shape: on(ev) })).mode).toBe('lean');
});
test('under the default panel all, platform on still takes the platform depth at HEAD; everything else keeps today\'s panel', () => {
const ev = { id: '1', head: HEAD, reviewer: 'capy-ai[bot]' };
const all = (review: ReviewShape['platformReview']) => lean({ panel: 'all', platform: 'on', platformReview: review });
expect(planReview(base({ ...docs, shape: all(ev) })).mode).toBe('platform');
expect(planReview(base({ ...docs, shape: all(null) })).mode).toBe('panel');
expect(planReview(base({ shape: all(ev) })).mode).toBe('panel');
});
test('the platform skip is pass 1 only: a later step plans as lean', () => {
const p = planReview(base({ shape: on({ id: '1', head: HEAD, reviewer: 'capy-ai[bot]' }), history: { fullPasses: 1, last: 'full', fixedBlocking: true } }));
expect(p.next.step).toBe('fix-check');
@@ -193,7 +200,7 @@ describe('C7 merged reader brief and the outside voice reading its diff from dis
describe('ship policy: the base-read review key', () => {
const codes = (raw: object) => validatePolicy(raw).map(e => `${e.code}:${e.path}`);
test('defaults: panel risk, the lane\'s native reader, platform off, no extra risk paths', () => expect(DEFAULT_POLICY.review).toEqual({ panel: 'risk', reader_model: 'lane', platform: 'off', risk_paths: [] }));
test('defaults: panel all (today\'s panel; risk is opt-in until its no-loss replay passes), the lane\'s native reader, platform off, no extra risk paths', () => expect(DEFAULT_POLICY.review).toEqual({ panel: 'all', reader_model: 'lane', platform: 'off', risk_paths: [] }));
test('valid values pass with min_gstack_version; bad ones name the field', () => {
const v = REVIEW_POLICY_KEY_VERSION;
expect(codes({ review: { platform: 'on', reader_model: 'anthropic/claude-opus-5-5', panel: 'risk', risk_paths: ['src/balance/**'] }, min_gstack_version: v })).toEqual([]);
-2
View File
@@ -22,8 +22,6 @@ function fixture() {
fs.writeFileSync(path.join(root, 'gitconfig'), '[commit]\n\tgpgsign = false\n');
const sh = (cwd: string, c: string) => { const r = spawnSync('bash', ['-c', c], { cwd, env, encoding: 'utf8', timeout: 60_000 }); if (r.status !== 0) throw new Error(`${c}: ${r.stderr}`); return r.stdout.trim(); };
sh(root, 'git init -q --bare -b main origin.git && git clone -q origin.git work && git clone -q origin.git other 2>/dev/null || true');
// The briefs this case reads are today's panel (review.panel all); R65's one native reader renders at Step 11.
fs.mkdirSync(path.join(work, '.gstack')); fs.writeFileSync(path.join(work, '.gstack', 'ship-policy.json'), JSON.stringify({ review: { panel: 'all' }, min_gstack_version: '1.94.0.0' }) + '\n');
sh(work, "echo '{}' > package.json && mkdir src && echo 'export const a = 1;' > src/a.ts && git add -A && git commit -qm base && git push -q origin main");
sh(root, 'rm -rf other && git clone -q origin.git other');
sh(path.join(root, 'other'), 'mkdir -p up && for i in $(seq 1 12); do echo "export const u$i = $i;" > up/u$i.ts; done && git add -A && git commit -qm upstream && git push -q origin main');
+2 -3
View File
@@ -12,14 +12,13 @@ import { KEEP_ARG_MAX_BYTES, readSelection, reviewExclude, tooLargeLine, unreada
import { collectCommit, collectLive } from '../lib/review-collect';
import { extractReceipt } from '../lib/ship-receipt';
import { bindShippedReceipt, receiptReviewAtHead } from '../lib/ship-receipt-depth';
import { REVIEW_EXCLUDE_KEY_VERSION, REVIEW_POLICY_KEY_VERSION, isUnavailable } from '../lib/ship-policy';
import { REVIEW_EXCLUDE_KEY_VERSION, isUnavailable } from '../lib/ship-policy';
import { loadPolicyAt } from '../lib/ship-policy-at';
import { cleanup, commit, makeFixtureRepo, runBin, write, type FixtureRepo } from './helpers/pregate-fixture';
const repos: FixtureRepo[] = [];
afterEach(() => { while (repos.length) cleanup(repos.pop()!); });
// review.panel all keeps today's panel, whose every brief these cases read; R65's one-reader default is pinned in review-depth-lean.test.ts.
const policyText = (patterns: string[]) => JSON.stringify({ review_exclude_paths: patterns, review: { panel: 'all' }, min_gstack_version: REVIEW_POLICY_KEY_VERSION }) + '\n';
const policyText = (patterns: string[]) => JSON.stringify({ review_exclude_paths: patterns, min_gstack_version: REVIEW_EXCLUDE_KEY_VERSION }) + '\n';
const GZ = Buffer.from([0x1f, 0x8b, 0, 1, 2, 3, 0, 0]);
const EXCLUDED = ['receipts/a/result.json', 'receipts/a/trial.gz', 'receipts/config/blob.bin', 'receipts/c/result.json', 'receipts/e/result.json', 'receipts/notes.md'];
const KEPT = ['receipts/b/result.json', 'receipts/d/fixture.json', 'receipts/run.sh'];
+5 -4
View File
@@ -73,11 +73,12 @@ const NO_LOSS_REPLAYS = {
'GST-967': "GST-967 dispatch-superset no-loss check (test/review-depth.test.ts, 'GST-967 dispatch-superset no-loss check'): over 1,440 planReview cases the branch plans exactly what main planned at 1022f4f except the 71 gate-class stops before Step 11, which add only Step 11's adversarial, outside and targeted voices, so no reviewer main dispatches is dropped or re-efforted; the brief bodies lib/review-brief.ts cuts from the ship sections hash to main's; only the lead's repeat-decision and Step 11 instructions changed; reviewer text is unchanged",
'GST-508+GST-464+GST-967': "wave review-53cfb5bfe011 merge of main 68410828f into #3852: ship/sections/review-army.md and adversarial.md are main's GST-967 bytes plus exactly the GST-508+GST-464 lines (the merged file minus main equals the wave minus fc292e22f, line for line), so GST-967's dispatch-superset no-loss check and GST-508's no-loss replay both hold; merged-head checks in GStack Minder drive handoffs/GSTA-202/merge-6841-checks.md",
'GST-508+R51+GST-911+GST-967': "wave review-53cfb5bfe011 merge of main 68410828f into #3852: lib/review-depth.ts is main's GST-967 bytes plus exactly the GST-508+R51+GST-911 lines (the merged file minus main equals the wave minus fc292e22f, line for line); GST-967's dispatch-superset no-loss check (test/review-depth.test.ts) passes on the merged file, and the GST-508+R51+GST-911 checks are rerun at the merged head (GStack Minder drive handoffs/GSTA-202/merge-6841-checks.md)",
'GSTA-258-C': "GSTA-258 build C planner no-loss check: review.panel defaults to all, so the default plan is today's panel; over the last 200 first-parent main commits to 6f1dfd5b7c, planReview and collectCommit from origin/main and from this branch give the same depth, class, risk classes, next step and dispatches on 196, and the other 4 only raise: 4eff47c5cf goes light to full (eval class, main's own full panel adds the red team), e25997515c gains money at full gate, and 83ae96e086 and 7f815411f3 lose a money class from JSON lines (HARN-1) but keep full depth and the same reviewers (GStack Minder drive handoffs/GSTA-258/C-planner-noloss/); the one-reader shape ships opt-in (review.panel risk) because its own no-loss replay was FIX-METHOD (handoffs/GSTA-258/C-noloss-results.md); every brief body lib/review-brief.ts cuts from the ship sections still hashes to its pin, so only lead instructions outside the cut spans changed",
} as const;
type Replay = keyof typeof NO_LOSS_REPLAYS;
const REVIEWER_BRIEFS: Record<string, { sha: string; replay: Replay }> = {
'ship/sections/review-army.md': { sha: 'de3e0d35f2af56492c42fd287b6868fbe19bce96b86321e74a4947ba909b74eb', replay: 'GST-508+GST-464+GST-967' },
'ship/sections/adversarial.md': { sha: '0142d6bc3f2a5bceb9f8b2adef1d3a206e5836c99a0667fe995568da2e80a5a6', replay: 'GST-508+GST-464+GST-967' },
'ship/sections/review-army.md': { sha: '25c09be7ea5c0e438ee059af2064f5bf038f6b69e3b5378f6c47be669f7ecd17', replay: 'GSTA-258-C' },
'ship/sections/adversarial.md': { sha: 'c623d65c4c53054108ac0166773c89233d76a25b0d35eb72d1c546f7bec4bdc9', replay: 'GSTA-258-C' },
'review/sections/review-army.md': { sha: '78329b64640260cd8831ca81a9189f3f8dcade9c406431631d3f2cd798cd3967', replay: '#3638' },
'review/sections/adversarial.md': { sha: 'e6962fa25b78f362654f2954f79683e524d2ebd452d1494f8a2b099888e8e255', replay: 'G1' },
'review/checklist.md': { sha: 'a32963ef38d9d3613c58c805e8517cd2e593c63769b30dd7d40e2592fa48fc78', replay: 'GSTA-224 H1' },
@@ -94,8 +95,8 @@ const REVIEWER_BRIEFS: Record<string, { sha: string; replay: Replay }> = {
'review/specialists/testing.md': { sha: 'd6cc2bef7be562387d0c0a22fefe646dff9c295f1d34d8453a6cb496584150e4', replay: '#3638' },
'review/specialists/targeted.md': { sha: '7f92a0d0a8319c3c0e076fb3b1a4689c45120b2be2c14dfc7d4cb03aafa9d6a5', replay: 'GST-257' },
'scripts/resolvers/fix-check.ts': { sha: '712bf5b0c439e96bac32f19cbe25394dabb4c94aa66600100bfde9b100e15a08', replay: '#3638' },
'lib/review-depth.ts': { sha: 'd76a9afcfadfe0a95b15428c04e6f7a88c6b0fa75591201c45f023fec2bb90db', replay: 'GST-508+R51+GST-911+GST-967' },
'lib/review-risk.ts': { sha: '126eff0f1de6982e03dc24d8017c67e6807c91dfa518b18d2db3aa910aac911f', replay: 'GST-508+R51+GST-911' },
'lib/review-depth.ts': { sha: '7d5e18436404ed8d620bfe6a7d042dff9251956a790d978407445ec7444a70ee', replay: 'GSTA-258-C' },
'lib/review-risk.ts': { sha: '2c5b96b921b8be5b977b734b3787361ed80e7d3f779ff6c4a20948f85e4d4474', replay: 'GSTA-258-C' },
};
/**
-4
View File
@@ -10,7 +10,6 @@ import * as path from 'node:path';
import { promptHash, sectionTexts, withWorkspace, workspaceParagraph, workspaceStep } from '../lib/review-brief';
import { CHUNK_CHARS, PARENT_ONLY_QA, buildManifest, chunkCount, chunkOf, markReader, renderStage, specialistFindings, type Manifest } from '../lib/review-pass';
import type { Dispatch } from '../lib/review-depth';
import { REVIEW_POLICY_KEY_VERSION } from '../lib/ship-policy';
const ROOT = path.resolve(import.meta.dir, '..');
const BIN = path.join(ROOT, 'bin');
@@ -132,9 +131,6 @@ function repo(): { dir: string; env: NodeJS.ProcessEnv } {
const dir = tmp('rp-repo-');
const env = { ...process.env, PATH: BIN + path.delimiter + process.env.PATH, GSTACK_STATE_ROOT: path.join(dir, '.state'), GIT_AUTHOR_NAME: 't', GIT_AUTHOR_EMAIL: 't@t', GIT_COMMITTER_NAME: 't', GIT_COMMITTER_EMAIL: 't@t' };
const sh = (c: string) => { const r = spawnSync('bash', ['-c', c], { cwd: dir, env, encoding: 'utf8', timeout: 60_000 }); if (r.status !== 0) throw new Error(r.stderr); };
// The pass program cases pin today's panel (review.panel all keeps it on every class); R65's default one-reader table is
// pinned in test/review-depth-lean.test.ts.
fs.mkdirSync(path.join(dir, '.gstack')); fs.writeFileSync(path.join(dir, '.gstack', 'ship-policy.json'), JSON.stringify({ review: { panel: 'all' }, min_gstack_version: REVIEW_POLICY_KEY_VERSION }) + '\n');
sh("git init -q -b main && echo '{}' > package.json && mkdir src && echo 'export const a = 1;' > src/a.ts && echo .state > .gitignore && git add -A && git commit -qm base && git checkout -qb feat");
sh('for i in $(seq 1 80); do echo "export const v$i = $i;" >> src/a.ts; done && git commit -qam feat');
return { dir, env };
+1 -6
View File
@@ -3,7 +3,6 @@ import { spawnSync } from 'node:child_process';
import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import { REVIEW_POLICY_KEY_VERSION } from '../lib/ship-policy';
const BIN = path.join(import.meta.dir, '..', 'bin', 'gstack-review-plan');
const dirs: string[] = [];
@@ -15,11 +14,7 @@ function repo(files: Record<string, string>): { dir: string; state: string } {
dirs.push(dir, state);
const git = (...a: string[]) => spawnSync('git', a, { cwd: dir, encoding: 'utf8', timeout: 10_000 });
git('init', '-q', '-b', 'main'); git('config', 'user.email', 't@t'); git('config', 'user.name', 't'); git('config', 'commit.gpgsign', 'false');
fs.writeFileSync(path.join(dir, 'README.md'), '# x\n');
// These cases pin today's panel and its scoped second pass, which review.panel all keeps for every class; R65's default
// table (one reader off risk class) is pinned in test/review-depth-lean.test.ts.
fs.mkdirSync(path.join(dir, '.gstack')); fs.writeFileSync(path.join(dir, '.gstack', 'ship-policy.json'), JSON.stringify({ review: { panel: 'all' }, min_gstack_version: REVIEW_POLICY_KEY_VERSION }) + '\n');
git('add', '.'); git('commit', '-qm', 'base');
fs.writeFileSync(path.join(dir, 'README.md'), '# x\n'); git('add', '.'); git('commit', '-qm', 'base');
git('checkout', '-qb', 'feat');
for (const [p, text] of Object.entries(files)) { fs.mkdirSync(path.dirname(path.join(dir, p)), { recursive: true }); fs.writeFileSync(path.join(dir, p), text); }
git('add', '.'); git('commit', '-qm', 'feat');
+3 -4
View File
@@ -189,8 +189,8 @@ function planRepo(f: Fixture) {
*/
const FULL_PANEL = ['specialist', 'red-team', 'adversarial-native', 'outside-voice'];
const R51: Record<string, { depth: string; panel: boolean; dropped?: string[] }> = {
'none-light': { depth: 'light', panel: false, dropped: ['specialist'] }, 'none-standard': { depth: 'light', panel: false, dropped: ['specialist', 'outside-voice'] }, 'none-docs': { depth: 'light', panel: false },
'none-tests': { depth: 'light', panel: false }, 'none-costume': { depth: 'light', panel: false, dropped: ['specialist'] }, 'none-gate-path': { depth: 'full', panel: true },
'none-light': { depth: 'light', panel: false }, 'none-standard': { depth: 'light', panel: false, dropped: ['outside-voice'] }, 'none-docs': { depth: 'light', panel: false },
'none-tests': { depth: 'light', panel: false }, 'none-costume': { depth: 'light', panel: false }, 'none-gate-path': { depth: 'full', panel: true },
'secret-light': { depth: 'full', panel: true }, 'secret-path': { depth: 'full', panel: true }, 'secret-removed': { depth: 'full', panel: true }, 'gate-tagged': { depth: 'full', panel: true },
'money-light': { depth: 'full', panel: true }, 'money-path': { depth: 'full', panel: true }, 'money-removed': { depth: 'full', panel: true }, 'money-standard': { depth: 'full', panel: true },
'auth-path': { depth: 'full', panel: true }, 'money-fix-check': { depth: 'full', panel: false }, 'money-pass2': { depth: 'full', panel: false }, 'gate-repeat': { depth: 'full', panel: false },
@@ -204,8 +204,7 @@ describe('gstack-review-plan prints TARGETED and dispatches the targeted reader'
// with no class; seam=bin/gstack-review-plan end to end; no_claim=that the reader finds the defect (the paid replay's question)
// R51 changes the table: risk and gate fixtures plan full (every role main dispatched, plus the full panel), and the one
// non-risky standard fixture drops only the outside voice; fails_when=a risk fixture loses a role main dispatched or misses
// the full panel, or a non-risky fixture loses a role the R51 table does not list. R65 (GSTA-258 build C): a non-risky code
// fixture runs one native adversarial reader carrying the checklists and the Red Team, so its batched specialist drops too
// the full panel, or a non-risky fixture loses a role the R51 table does not list
test('the dispatch-superset no-loss check: risk and gate fixtures keep every role main dispatched plus the full panel; non-risky ones drop only what R51 lists', () => {
expect(Object.keys(MAIN).sort()).toEqual(Object.keys(FIXTURES).sort());
expect(Object.keys(R51).sort()).toEqual(Object.keys(FIXTURES).sort());
+1 -1
View File
@@ -41,7 +41,7 @@ describe('C6 receipt: review_depth platform, honest and bound to the exact head
test('a docs diff under review.platform on with capy-ai[bot]\'s review at HEAD records platform, and the queue accepts it at that head only', () => {
const { dir, head } = repo({ review: { platform: 'on' } }, { 'docs/howto.md': 'Run the installer.\n' });
const d = receiptReviewAtHead(dir, 'main', BIN, head).depth;
expect([d.depth, d.mode]).toEqual(['light', 'lean']);
expect([d.depth, d.mode]).toEqual(['light', 'panel']);
const p = withGh(head, () => platformReceiptDepth(dir, 'main', d, head, '99'));
expect(p.ok && [p.depth.depth, p.depth.mode, p.depth.platform_review]).toEqual(['platform', 'platform', { id: '99', head, reviewer: 'capy-ai[bot]' }]);
const r = { gstack_version: '1.94.0.0', review_depth: (p as any).depth } as ShipReceipt;