fix: review header excludes advisory findings from N; shard settlement treats the force point as a phase boundary, not a failure

This commit is contained in:
garrytan committed 2026-10-03 23:04:14 +00:00
1 parent 28af1364cb
commit 9057bf3266
7 files changed
+21 -10

No files matched your search

+5
View File
@@ -29,6 +29,11 @@ This release closes the follow-ups filed by the v1.91.15.0 prompt cleanup. The c
- Parity caps lowered to measured sizes for land-and-deploy, design-consultation and ship.
- The codex consult section drops issue numbers from its runtime prose.
#### Fixed
- /review's specialist header counted advisory findings in its total; the header's N is now defined as critical plus informational.
- Free-lane shards failed with "browser ownership deadline exceeded" when a browse daemon took more than 5 seconds to exit after SIGINT. Reaching the force-kill point now ends the graceful phase instead of recording a cleanup failure; a probe cut off at that point still fails the shard.
- `bun run audit:manifest` printed backslash paths on Windows.
#### For contributors
- Five safety rules and the qa workflow, review and cookie judges keep their wording; TODOS.md lists what each needs before it can change.
+2 -1
View File
@@ -175,7 +175,8 @@ Core findings keep the core Confidence Calibration gates.
#### 5. Score and present specialists
Only specialist findings enter this header and `quality_score`; core findings do not.
Use the merged NON-advisory specialist findings for both counts and score:
Use the merged NON-advisory specialist findings for both counts and score;
the header's N is X + Y, so advisory findings never add to it:
`quality_score = max(0, 10 - (critical_count * 2 + informational_count * 0.5))`
Cap at 10 and retain for the review-log entry in Step 5.8. These are not final unresolved-defect totals.
Print only this block: the stage 6 activity object and `test_stub` bodies are log and Fix-First data.
+2 -1
View File
@@ -197,7 +197,8 @@ Core findings keep the core Confidence Calibration gates.
#### 5. Score and present specialists
Only specialist findings enter this header and \`quality_score\`; core findings do not.
Use the merged NON-advisory specialist findings for both counts and score:
Use the merged NON-advisory specialist findings for both counts and score;
the header's N is X + Y, so advisory findings never add to it:
\`quality_score = max(0, 10 - (critical_count * 2 + informational_count * 0.5))\`
Cap at 10 and retain for ${persistRef}. These are not final unresolved-defect totals.
Print only this block: the stage 6 activity object and \`test_stub\` bodies are log and Fix-First data.
+3 -3
View File
@@ -1432,7 +1432,7 @@ function trackShardBrowser(stateDir: string, env: NodeJS.ProcessEnv) {
let alive = true;
const check = (capture: Capture) => {
if (closed || capture.abort.signal.aborted || active !== capture) throw new CaptureStopped();
if (closed || capture.abort.signal.aborted || active !== capture || (!forced && performance.now() >= forceAt)) throw new CaptureStopped();
if (performance.now() >= Math.min(capture.deadline, deadline)) throw new BrowserCleanupError('browser ownership deadline exceeded');
};
const probe = async (capture: Capture, command: string, args: string[], timeout: number) => {
@@ -1462,7 +1462,7 @@ function trackShardBrowser(stateDir: string, env: NodeJS.ProcessEnv) {
killProcessGroup(child, 'SIGKILL');
reaper = setTimeout(() => finish(null), 100);
};
const timer = setTimeout(stop, Math.max(1, remaining));
const timer = setTimeout(() => { if (!closed) errors.add('browser identity probe did not complete'); stop(); }, Math.max(1, Math.min(remaining, forced ? Infinity : forceAt - performance.now())));
capture.abort.signal.addEventListener('abort', stop, { once: true });
child.once('error', () => { failed = true; finish(null); });
child.once('close', finish);
@@ -1693,7 +1693,7 @@ function trackShardBrowser(stateDir: string, env: NodeJS.ProcessEnv) {
};
const enqueue = () => {
if (closed || pending || process.platform === 'win32') return;
const operation: Capture = { abort: new AbortController(), deadline: Math.min(performance.now() + 10000, deadline, forced ? Infinity : forceAt), probes: new Set() };
const operation: Capture = { abort: new AbortController(), deadline: Math.min(performance.now() + 10000, deadline), probes: new Set() };
active = operation;
pending = (async () => {
try {
+2 -1
View File
@@ -396,7 +396,8 @@ Core findings keep the core Confidence Calibration gates.
#### 5. Score and present specialists
Only specialist findings enter this header and `quality_score`; core findings do not.
Use the merged NON-advisory specialist findings for both counts and score:
Use the merged NON-advisory specialist findings for both counts and score;
the header's N is X + Y, so advisory findings never add to it:
`quality_score = max(0, 10 - (critical_count * 2 + informational_count * 0.5))`
Cap at 10 and retain for the review-log persist. These are not final unresolved-defect totals.
Print only this block: the stage 6 activity object and `test_stub` bodies are log and Fix-First data.
+2 -1
View File
@@ -2219,7 +2219,8 @@ Core findings keep the core Confidence Calibration gates.
#### 5. Score and present specialists
Only specialist findings enter this header and `quality_score`; core findings do not.
Use the merged NON-advisory specialist findings for both counts and score:
Use the merged NON-advisory specialist findings for both counts and score;
the header's N is X + Y, so advisory findings never add to it:
`quality_score = max(0, 10 - (critical_count * 2 + informational_count * 0.5))`
Cap at 10 and retain for the review-log persist. These are not final unresolved-defect totals.
Print only this block: the stage 6 activity object and `test_stub` bodies are log and Fix-First data.
+5 -3
View File
@@ -87,6 +87,7 @@ if (role === 'leaf') {
const current = JSON.parse(fs.readFileSync(path.join(path.dirname(process.env.BROWSE_STATE_FILE), 'terminal-agent-pid'), 'utf8'));
try { process.kill(current.pid, 'SIGTERM'); } catch {}
for (const child of children) try { child.kill('SIGTERM'); } catch {}
if (mode === 'settle-slow-exit') return;
const finish = () => {
fs.rmSync(process.env.BROWSE_STATE_FILE, {force:true});
fs.rmSync(path.join(path.dirname(process.env.BROWSE_STATE_FILE), 'terminal-agent-pid'), {force:true});
@@ -126,10 +127,11 @@ if (role === 'leaf') {
} else if (role === 'harness') {
if (mode === 'settle-cold-probes') Object.defineProperty(process, 'platform', {value:'darwin'});
let spy;
if (['replaced-start', 'exit-environment-race', 'unavailable-environment'].includes(mode)) {
if (['replaced-start', 'exit-environment-race', 'unavailable-environment', 'settle-slow-exit'].includes(mode)) {
const original = fs.readFileSync;
spy = spyOn(fs, 'readFileSync').mockImplementation((filename, ...args) => {
const value = original(filename, ...args);
if (mode === 'settle-slow-exit' && String(filename).endsWith('/environ') && fs.existsSync(file('.interrupted'))) Bun.sleepSync(300);
if (String(filename).endsWith('/environ') && fs.existsSync(file('.ready'))
&& (mode === 'unavailable-environment' || mode === 'exit-environment-race' && fs.existsSync(file('.interrupted')))) {
const own = JSON.parse(original(file('.ready'), 'utf8'));
@@ -186,8 +188,8 @@ function ownershipProcessAlive(identity: { pid: number; start: string; ticks: st
describe('test-free-shards: owned detached browser settlement', () => {
for (const mode of ['success', 'failure', 'timeout', 'cancel', 'cancel-force', 'endpoint-mix', 'full-state-mix',
'terminal-mix', 'chromium-mix', 'replaced-pid', 'stale-child-start', 'replaced-start', 'exit-environment-race',
'unavailable-environment', 'directory-remove-failure', 'cancel-cold-probes', 'settle-cold-probes']) {
test.skipIf(process.platform === 'win32' || ((['replaced-start', 'exit-environment-race', 'unavailable-environment'].includes(mode) || mode.endsWith('cold-probes')) && process.platform !== 'linux'))(mode, async () => {
'unavailable-environment', 'directory-remove-failure', 'cancel-cold-probes', 'settle-cold-probes', 'settle-slow-exit']) {
test.skipIf(process.platform === 'win32' || ((['replaced-start', 'exit-environment-race', 'unavailable-environment', 'settle-slow-exit'].includes(mode) || mode.endsWith('cold-probes')) && process.platform !== 'linux'))(mode, async () => {
const directory = fs.mkdtempSync(path.join(os.tmpdir(), 'free-owned-browser-'));
const actor = path.join(directory, 'actor.ts');
fs.writeFileSync(actor, OWNERSHIP_ACTOR);