v1.87.3.0 fix: bind review evidence to the reviewed tree (#2875)

* fix(review): bind evidence to completed unchanged review passes

* fix(review): keep unresolved Codex findings unverified

* docs: update review evidence documentation for v1.87.3.0

* test(cso): let Windows integration finish within subprocess budgets

* docs: update project documentation for v1.87.3.0

---------

Co-authored-by: garrytan <19957+garrytan@users.noreply.github.com>
This commit is contained in:
Garry Tan
2026-09-15 20:53:58 +00:00
committed by GitHub
co-authored by garrytan
parent 43c9e45ea7
commit 85b8c038fc
37 changed files with 640 additions and 166 deletions
+11 -6
View File
@@ -1,5 +1,5 @@
import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import { execSync, ExecSyncOptionsWithStringEncoding } from 'child_process';
import { execFileSync, execSync, ExecSyncOptionsWithStringEncoding } from 'child_process';
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
@@ -11,7 +11,7 @@ const BIN = path.join(ROOT, 'bin');
let tmpDir: string;
let slugDir: string;
function run(input: string, opts: { expectFail?: boolean } = {}): { stdout: string; exitCode: number } {
function run(input: string, opts: { expectFail?: boolean; captured?: boolean } = {}): { stdout: string; exitCode: number } {
const execOpts: ExecSyncOptionsWithStringEncoding = {
cwd: ROOT,
env: { ...process.env, GSTACK_HOME: tmpDir },
@@ -19,7 +19,12 @@ function run(input: string, opts: { expectFail?: boolean } = {}): { stdout: stri
timeout: 10000,
};
try {
const stdout = execSync(`${BIN}/gstack-review-log '${input.replace(/'/g, "'\\''")}'`, execOpts).trim(); // timeout via execOpts
const args = [input];
if (opts.captured) {
const token = execFileSync(`${BIN}/gstack-review-log`, ['--start', 'review'], execOpts).trim(); // timeout via execOpts
args.push('--finish', token);
}
const stdout = execFileSync(`${BIN}/gstack-review-log`, args, execOpts).trim(); // timeout via execOpts
return { stdout, exitCode: 0 };
} catch (e: any) {
if (opts.expectFail) {
@@ -86,7 +91,7 @@ describe('gstack-review-log', () => {
}
test('stamps authoritative binding fields (commit_full, tree, wtree, dirty) in a git repo', () => {
const result = run('{"skill":"review","status":"clean"}');
const result = run('{"skill":"review","status":"clean","completed":true,"converged":true}', { captured: true });
expect(result.exitCode).toBe(0);
const rec = readNewestRecord();
expect(rec.commit_full).toMatch(/^[0-9a-f]{40}$/);
@@ -99,8 +104,8 @@ describe('gstack-review-log', () => {
});
test('caller-supplied binding fields are IGNORED, never trusted', () => {
const forged = '{"skill":"review","status":"clean","wtree":"forged","tree":"forged","commit_full":"forged","dirty":"forged"}';
const result = run(forged);
const forged = '{"skill":"review","status":"clean","completed":true,"converged":true,"wtree":"forged","tree":"forged","commit_full":"forged","dirty":"forged"}';
const result = run(forged, { captured: true });
expect(result.exitCode).toBe(0);
const rec = readNewestRecord();
expect(rec.wtree).not.toBe('forged');