mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-03 15:27:56 +01:00
test: repin the two ship section briefs under no-loss replay GST-464
GST-464 brief-identity check: every reviewer brief lib/review-brief.ts cuts from ship/sections/review-army.md and adversarial.md stays byte-identical to the bodies the L and GST-257 replays admitted; only lead instructions outside the cut spans changed. The check is a test CI runs. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
fe0f86fa98
commit
ebabb59346
2 files changed
+39
-2
No files matched your search
@@ -11,3 +11,4 @@
|
||||
- `test/review-targeted.test.ts`: the generated sections' own commands carry the record from Step 11's verify to `gstack-ship-receipt write`, and ready's line reads `verdict=ok`. A run without the reader passes no flag, and Step 9 clears the file, even when `.git/info` is missing or the exclude file has no final newline.
|
||||
- `test/ship-preflight.test.ts`: a single-branch clone's preflight refreshes `origin/main`, and a 60-file diff against a 3-file or a 61-file PR stops at the pushed head. The stop quotes an unsafe base name and names the fork case. Negative controls: another head, a matching size, or a zero count goes on.
|
||||
- `test/review-plan-cli.test.ts`, `test/gate-diff-cli.test.ts`, `test/diff-scope.test.ts`: a local `main` behind, ahead of or diverged from `origin/main` yields to it, so an unpushed `test.skip` on local `main` is scanned. One next to an unrelated `origin/main` stays the base. A tag or fetched branch named `origin/main` never stands in, and a pinned sha and `HEAD` are never redirected. The review plan of a docs-only branch that merged the newer `origin/main` stays docs; before the fix, the gate scan counted origin's skipped test.
|
||||
- `test/review-packets-removed.test.ts`: the two ship section pins move under replay GST-464, a brief-identity check. Every reviewer brief `lib/review-brief.ts` cuts from those sections must stay byte-identical to the no-loss-tested bodies; a changed brief fails it.
|
||||
@@ -8,7 +8,9 @@ import { describe, test, expect } from 'bun:test';
|
||||
import { spawnSync } from 'child_process';
|
||||
import { createHash } from 'crypto';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import { sectionTexts } from '../lib/review-brief';
|
||||
|
||||
const ROOT = path.join(import.meta.dir, '..');
|
||||
const REMOVED = [
|
||||
@@ -56,11 +58,12 @@ const NO_LOSS_REPLAYS = {
|
||||
'G1': "GSTA-167 variant G Arm G1: live no-loss replay of both prose voices with part 1's prompts, 2 passes, normalizer v2, paired rule against pooled C' (parts 1 and 3; specialists at medium as in C and C2)",
|
||||
'L': "GSTA-167 variant G Arm L: live no-loss replay of one batched reader (testing and security plus scoped checklists) and the Red Team on its findings, 2 passes, scored L∘G1 against G1 on the paired rule (part 2)",
|
||||
'GST-257': "GST-257 PR 1 dispatch-superset no-loss check (test/review-targeted.test.ts): on every fixture diff the branch dispatches main's reviewers at 8be7f21 unchanged plus only the targeted reader, and over the last 100 non-release commits on main it lost none; adds the targeted role and brief to the G1 and L bytes, whose existing reviewer text is unchanged",
|
||||
'GST-464': "GST-464 brief-identity no-loss check (the brief-body test below): every reviewer brief lib/review-brief.ts cuts from ship/sections/review-army.md and adversarial.md is byte-identical to the bodies at the L and GST-257 pins; 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: 'b7ca291a1cc63750bfb9710a4c12fd971523b9598da2a32ef80fb258eb0eceab', replay: 'L' },
|
||||
'ship/sections/adversarial.md': { sha: 'd776ee5bc6e0c13930f8f4de05bad2f1ed9e52bc9fc5df80ae3ba7680455b2bb', replay: 'GST-257' },
|
||||
'ship/sections/review-army.md': { sha: 'ebda452b2cf8aeb34020c789d0507893c0f041027890bcbd8342e46d4b29f29a', replay: 'GST-464' },
|
||||
'ship/sections/adversarial.md': { sha: 'b70577b6987869acd76cc3865f16eeeed743558c0ea09e5f9933d0d8aec8b91e', replay: 'GST-464' },
|
||||
'review/sections/review-army.md': { sha: '78329b64640260cd8831ca81a9189f3f8dcade9c406431631d3f2cd798cd3967', replay: '#3638' },
|
||||
'review/sections/adversarial.md': { sha: 'e6962fa25b78f362654f2954f79683e524d2ebd452d1494f8a2b099888e8e255', replay: 'G1' },
|
||||
'review/checklist.md': { sha: '607788afeb2c83f2dff1dccd58d212616ec72393d28cda2fa18690c1a83df699', replay: '#3638' },
|
||||
@@ -80,7 +83,40 @@ const REVIEWER_BRIEFS: Record<string, { sha: string; replay: Replay }> = {
|
||||
'lib/review-depth.ts': { sha: '4542785a1e217d8dd054985978b42c055b9fd79082579cb7664f187f7066e48e', replay: 'GST-257' },
|
||||
};
|
||||
|
||||
/**
|
||||
* The six reviewer brief bodies lib/review-brief.ts cuts out of the two ship sections, pinned at
|
||||
* the bytes replays L and GST-257 admitted. A section repin under GST-464 is valid only while every
|
||||
* body still hashes here: the section may change outside the cut spans, never inside them.
|
||||
*/
|
||||
const BRIEF_BODIES: Record<string, string> = {
|
||||
specialist: '1ebe47ddb3291a9e4fe90b5a260eb57e328144959549bc95c119b68d23652cb5',
|
||||
framing: 'aad667b5ea4c6d23d930dafffa38178c04be388cd4364fb73759fc92af17bb63',
|
||||
fixtures: '9517c86befe773e76acbf30a0642ed828e211b8ecb524325702072b26429ef16',
|
||||
redTeam: '1cca7957d13f9da08434870290b92958f37750207047b92c9aa52a802da789e8',
|
||||
native: 'ddb1041ec1e4dd373c3e4ab9017e49316e78c230055c1ef3db1bbba518b143a2',
|
||||
outside: 'bd96406da28b03742384560425a333b6d6d7ed2be95bd2026c90e0039632cee2',
|
||||
};
|
||||
const bodyHashes = (root: string) => Object.fromEntries(Object.entries(sectionTexts(root)).map(([k, v]) => [k, createHash('sha256').update(v).digest('hex')]));
|
||||
|
||||
describe('reviewer briefs stay at their no-loss-tested bytes (GSTA-167)', () => {
|
||||
// Value: protects=the GST-464 repin of ship/sections/review-army.md and adversarial.md admits only lead-instruction
|
||||
// edits: every brief a reviewer reads renders byte-identical to the no-loss-tested bodies; fails_when=an edit inside a
|
||||
// cut span changes a brief while its section pin is moved; seam=sectionTexts, the function every render uses;
|
||||
// no_claim=the checklists and the targeted brief, pinned by their own file hashes above
|
||||
test('every reviewer brief cut from the ship sections is byte-identical to its pinned body', () => {
|
||||
expect(bodyHashes(ROOT)).toEqual(BRIEF_BODIES);
|
||||
const copy = fs.mkdtempSync(path.join(os.tmpdir(), 'brief-bodies-'));
|
||||
try {
|
||||
fs.mkdirSync(path.join(copy, 'ship', 'sections'), { recursive: true });
|
||||
for (const f of ['review-army.md', 'adversarial.md']) fs.copyFileSync(path.join(ROOT, 'ship', 'sections', f), path.join(copy, 'ship', 'sections', f));
|
||||
const army = path.join(copy, 'ship', 'sections', 'review-army.md');
|
||||
fs.writeFileSync(army, fs.readFileSync(army, 'utf8').replace('You are a specialist code reviewer.', 'You are a specialist code reviewer. Skim.'));
|
||||
expect(bodyHashes(copy).specialist).not.toBe(BRIEF_BODIES.specialist);
|
||||
} finally {
|
||||
fs.rmSync(copy, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('every pinned reviewer brief, checklist and depth rule hashes to its pin', () => {
|
||||
const drift = Object.entries(REVIEWER_BRIEFS).filter(([file, pin]) => {
|
||||
const text = fs.readFileSync(path.join(ROOT, file), 'utf8').replace(/\r\n/g, '\n');
|
||||
|
||||
Reference in new issue
Block a user