mirror of
https://github.com/garrytan/gstack.git
synced 2026-10-03 01:46:55 +02:00
Census run 36626737820: the native CEO report arrived framed and indented, so its INPUT line never matched, and the model's exact probe plus two variable echoes was not canonical. A column-zero line inside a frame, command substitution, backticks, redirects, assignments, CODEX_MODE echoes and output line-count mismatches stay rejected. The failure now records before asserting.
267 lines
17 KiB
TypeScript
267 lines
17 KiB
TypeScript
/** Bounded CEO dual-dispatch evidence from the SDK parent stream, never source prose. */
|
|
import { createHash } from 'node:crypto';
|
|
import { existsSync, lstatSync, readFileSync, realpathSync } from 'node:fs';
|
|
import { dirname, isAbsolute, join, resolve, sep } from 'node:path';
|
|
import { loadAutoplanMethodologyBinding } from './autoplan-method-read-audit';
|
|
import { claudeOutsideExecutions } from './outside-voice-evidence';
|
|
|
|
const sha = (value: string) => createHash('sha256').update(value).digest('hex');
|
|
const text = (content: unknown): string => typeof content === 'string' ? content : Array.isArray(content)
|
|
? content.flatMap(block => block?.type === 'text' && typeof block.text === 'string' ? [block.text] : []).join('\n') : '';
|
|
// Claude Code 2.1.284 frames a subagent report with one header line and indents
|
|
// every report line by two spaces. Only a fully indented report is unwrapped;
|
|
// a column-zero line inside the frame stays framed and earns no credit.
|
|
const report = (content: string): string => {
|
|
const header = /^\[Subagent hand-back\] [^\n]*The report follows:\n/.exec(content);
|
|
if (!header) return content;
|
|
const lines = content.slice(header[0].length).split('\n');
|
|
return lines.every(line => line === '' || line.startsWith(' ')) ? lines.map(line => line.slice(2)).join('\n') : content;
|
|
};
|
|
const object = (value: unknown): value is Record<string, any> => value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
const parent = (event: any) => event?.parent_tool_use_id == null && event?.agentId == null && (event?.isSidechain == null || event?.isSidechain === false);
|
|
// These are delivered executable blocks, not a shell interpreter. Only blank
|
|
// lines, indentation and full-line comments may differ; branch/order/args stay exact.
|
|
// The outside matcher also recognizes bounded stop-only availability rechecks.
|
|
const code = (value: string) => value.split(/\r?\n/).map(line => line.trim()).filter(line => line && !line.startsWith('#')).join('\n');
|
|
function block(source: string, needle: string): string {
|
|
const blocks = [...source.matchAll(/```bash\r?\n([\s\S]*?)\r?\n```/g)].map(match => match[1]!);
|
|
const found = blocks.filter(value => value.includes(needle));
|
|
if (found.length !== 1) throw Error('Ambiguous or missing actual Autoplan command contract');
|
|
return found[0]!;
|
|
}
|
|
export function loadAutoplanDualCommandContract(root: string) {
|
|
return { probe: block(readFileSync(join(root, 'autoplan/SKILL.md'), 'utf8'), 'echo "CODEX_MODE: $_CODEX_MODE"'),
|
|
outside: block(readFileSync(join(root, 'autoplan/sections/ceo-phase.md'), 'utf8'), '_gstack_codex_timeout_wrapper 600 codex exec') };
|
|
}
|
|
export interface AutoplanDualEvidenceOptions {
|
|
ownedRoots: string[];
|
|
cwd: string;
|
|
activePlan: string;
|
|
methodologySha256: string;
|
|
commands: { probe: string; outside: string };
|
|
}
|
|
interface Call { id: string; name: string; input: Record<string, any>; order: number;
|
|
result?: { order: number; content: string; error: boolean }; }
|
|
export interface AutoplanDualEvidence {
|
|
claudeVoiceFired: boolean;
|
|
codexVoiceFired: boolean;
|
|
codexAttempted: boolean;
|
|
codexUnavailable: boolean;
|
|
reviewDispatched: boolean;
|
|
nativeToolUseId?: string;
|
|
outsideToolUseId?: string;
|
|
failedOutsideToolUseId?: string;
|
|
probeToolUseId?: string;
|
|
probeMode?: string;
|
|
snapshotSha256?: string;
|
|
reasons: string[];
|
|
}
|
|
/** Keep only public parent tool requests/results; private blocks are not copied or serialized. */
|
|
export function autoplanDualVoiceEvidence(transcript: unknown[], options: AutoplanDualEvidenceOptions): AutoplanDualEvidence {
|
|
const result: AutoplanDualEvidence = { claudeVoiceFired: false, codexVoiceFired: false, codexAttempted: false,
|
|
codexUnavailable: false, reviewDispatched: false, reasons: [] };
|
|
const roots = options.ownedRoots.map(root => realpathSync(root));
|
|
const owned = (file: unknown, immutable = false): file is string => {
|
|
if (typeof file !== 'string' || !isAbsolute(file) || resolve(file) !== file || !roots.some(root => file.startsWith(root + sep))) return false;
|
|
try {
|
|
const existing = existsSync(file) ? file : dirname(file);
|
|
if (realpathSync(existing) !== existing) return false;
|
|
if (immutable) {
|
|
const stat = lstatSync(file);
|
|
if (!stat.isFile() || stat.size > 32 * 1024 * 1024 || process.platform !== 'win32' && (stat.mode & 0o777) !== 0o444) return false;
|
|
}
|
|
return true;
|
|
} catch { return false; }
|
|
};
|
|
const calls = new Map<string, Call>();
|
|
const publicStream: any[] = [];
|
|
let session: string | undefined;
|
|
let order = 0;
|
|
for (const item of transcript) {
|
|
if (!object(item) || !parent(item)) continue;
|
|
const id = item.session_id;
|
|
if (typeof id !== 'string' || !id || item.sessionId != null && item.sessionId !== id) continue;
|
|
if (!session && item.type === 'assistant') session = id;
|
|
if (id !== session) continue;
|
|
// Native background status fields are public execution metadata. Preserve
|
|
// only the existing collector's recognized notification shape.
|
|
if (item.type === 'system' && item.subtype === 'task_notification') {
|
|
publicStream.push({ type: item.type, subtype: item.subtype, session_id: id,
|
|
task_id: item.task_id, tool_use_id: item.tool_use_id, output_file: item.output_file,
|
|
status: item.status, summary: item.summary });
|
|
}
|
|
if (item.type === 'attachment' && item.attachment?.type === 'queued_command' &&
|
|
item.attachment.commandMode === 'task-notification' && typeof item.attachment.prompt === 'string') {
|
|
publicStream.push({ type: item.type, session_id: id, attachment: { type: 'queued_command',
|
|
commandMode: 'task-notification', prompt: item.attachment.prompt } });
|
|
}
|
|
if (!['assistant', 'user'].includes(item.type) || !Array.isArray(item.message?.content)) continue;
|
|
for (const part of item.message.content) {
|
|
order++;
|
|
if (item.type === 'assistant' && part?.type === 'tool_use' && typeof part.id === 'string' && part.id &&
|
|
typeof part.name === 'string' && object(part.input)) {
|
|
const call = { id: part.id, name: part.name, input: part.input, order };
|
|
const previous = calls.get(part.id);
|
|
if (previous) {
|
|
if (previous.name !== call.name || JSON.stringify(previous.input) !== JSON.stringify(call.input)) {
|
|
result.reasons.push('Conflicting parent request identity'); return result;
|
|
}
|
|
continue;
|
|
}
|
|
calls.set(call.id, call);
|
|
publicStream.push({ type: 'assistant', session_id: id, message: { content: [{ type: 'tool_use', id: call.id, name: call.name, input: call.input }] } });
|
|
} else if (item.type === 'user' && part?.type === 'tool_result' && typeof part.tool_use_id === 'string') {
|
|
const call = calls.get(part.tool_use_id);
|
|
if (!call) continue;
|
|
const delivered = { order, content: text(part.content), error: part.is_error === true };
|
|
if (call.result && (call.result.content !== delivered.content || call.result.error !== delivered.error)) {
|
|
result.reasons.push('Conflicting parent result identity'); return result;
|
|
}
|
|
call.result ??= delivered;
|
|
publicStream.push({ type: 'user', session_id: id, message: { content: [{ type: 'tool_result', tool_use_id: call.id,
|
|
content: delivered.content, is_error: delivered.error }] } });
|
|
}
|
|
}
|
|
}
|
|
const canonical = (command: string, expected: string, readiness = false) => {
|
|
// A literal fixture cd is shared by the probe and outside command.
|
|
const prefix = new RegExp('^cd (?:' + [options.cwd, '"' + options.cwd + '"', "'" + options.cwd + "'"]
|
|
.map(value => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')).join('|') + ')(?: \&\&|;)?\\n');
|
|
const actual = code(command.replace(prefix, '')), contract = code(expected);
|
|
if (actual === contract) return true;
|
|
if (!readiness) return false;
|
|
// At dispatch, a fresh availability check may precede or follow the exact
|
|
// host guard. The execution body, host guard and their order remain exact.
|
|
// These finite stop-only forms are not a general shell normalizer.
|
|
const boundary = contract.indexOf('\n_REPO_ROOT=');
|
|
if (boundary < 0 || contract.indexOf('\n_REPO_ROOT=', boundary + 1) >= 0) return false;
|
|
const harness = contract.slice(0, boundary), body = contract.slice(boundary);
|
|
if (!actual.endsWith(body)) return false;
|
|
const edges = actual.slice(0, -body.length).split(harness);
|
|
if (edges.length !== 2) return false;
|
|
if (edges[0] && !edges[0].endsWith('\n') || edges[1] && !edges[1].startsWith('\n')) return false;
|
|
const assignments = code(options.commands.probe).split('\n').filter(line => line.startsWith('_CODEX_CFG='));
|
|
if (assignments.length !== 1) return false;
|
|
const escaped = (value: string) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
const separator = '(?:;[ \\t]*|\\n)';
|
|
const stop = (mode: string) => {
|
|
const literal = `(?:'CODEX_MODE: ${mode}[A-Za-z0-9 .,:_()/=-]*'|"CODEX_MODE: ${mode}[A-Za-z0-9 .,:_()/=-]*")`;
|
|
return `(?:echo ${literal}(?: >&2)?${separator}\\s*)?exit (?:0|[1-9][0-9]?|1[0-9]{2}|2[0-4][0-9]|25[0-5])`;
|
|
};
|
|
const condition = '\\[ "\\$_CODEX_CFG" =?= (?:"disabled"|\'disabled\'|disabled) \\]';
|
|
const cli = 'command -v codex >/dev/null 2>&1';
|
|
const guard = (condition: string, operator: string, mode: string, negated = false) => {
|
|
const exit = stop(mode);
|
|
return `(?:${condition} ${operator} \\{\\s*${exit}${separator}\\s*\\}|if ${negated ? '! ' : ''}${condition}; then\\s*${exit}${separator}\\s*fi)`;
|
|
};
|
|
const config = new RegExp('^' + escaped(assignments[0]!) + '\\n' + guard(condition, '&&', 'disabled') + '(?:\\n|$)');
|
|
const available = new RegExp('^' + guard(cli, '\\|\\|', 'not_installed', true) + '(?:\\n|$)');
|
|
const seen = new Set<string>();
|
|
for (const edge of edges) {
|
|
let remaining = edge.trim();
|
|
while (remaining) {
|
|
const match = config.exec(remaining) ?? available.exec(remaining);
|
|
if (!match) return false;
|
|
const kind = match[0].startsWith(assignments[0]!) ? 'config' : 'cli';
|
|
if (seen.has(kind)) return false;
|
|
seen.add(kind); remaining = remaining.slice(match[0].length).trim();
|
|
}
|
|
}
|
|
return seen.size > 0;
|
|
};
|
|
// The exact probe may be followed by read-only diagnostics: double-quoted
|
|
// echoes of literal text and plain variables, one output line each, never
|
|
// naming CODEX_MODE. Their lines are the only output allowed after the mode.
|
|
const diagnosticEchoes = (command: string): number | null => {
|
|
const actual = code(command), contract = code(options.commands.probe);
|
|
if (!actual.startsWith(contract)) return null;
|
|
const suffix = actual.slice(contract.length);
|
|
if (suffix.includes('CODEX_MODE') ||
|
|
!/^(?:(?:;[ \t]*|\n)echo "(?:[^"$`\\\n]|\$[A-Za-z_][A-Za-z0-9_]*|\$\{[A-Za-z_][A-Za-z0-9_]*(?::-[A-Za-z0-9_ .,:=\/-]*)?\})*")+$/.test(suffix)) return null;
|
|
return suffix.match(/(?:;|\n)[ \t]*echo "/g)!.length;
|
|
};
|
|
let probeResult = 'no Bash call matched the canonical probe block';
|
|
let nonCanonicalProbes = 0;
|
|
for (const call of calls.values()) {
|
|
if (call.name !== 'Bash' || typeof call.input.command !== 'string') continue;
|
|
const echoes = canonical(call.input.command, options.commands.probe) ? 0 : diagnosticEchoes(call.input.command);
|
|
if (echoes === null) {
|
|
if (call.input.command.includes('CODEX_MODE')) nonCanonicalProbes++;
|
|
continue;
|
|
}
|
|
result.probeToolUseId = call.id; delete result.probeMode;
|
|
if (!call.result || call.result.error) { probeResult = call.result ? 'probe result is an error' : 'probe has no result'; continue; }
|
|
const modes = [...call.result.content.matchAll(/^CODEX_MODE: ([a-z_]+)\r?$/gm)];
|
|
const trailing = modes.length === 1 ? call.result.content.slice(modes[0]!.index! + modes[0]![0].length).trimEnd() : '';
|
|
if (modes.length !== 1 || (trailing ? trailing.replace(/^\r?\n/, '').split(/\r?\n/).length : 0) !== echoes) {
|
|
probeResult = `probe output has ${modes.length} CODEX_MODE line(s) and ${modes.length === 1 ? 'does not end with it' : 'needs exactly one'}`;
|
|
continue;
|
|
}
|
|
result.probeToolUseId = call.id; result.probeMode = modes[0]![1]; probeResult = 'mode recorded';
|
|
}
|
|
const native: Array<{ call: Call; snapshot: any; content: string }> = [];
|
|
for (const call of calls.values()) {
|
|
if (call.name !== 'Agent' || typeof call.input.prompt !== 'string' || !call.result || call.result.error) continue;
|
|
try {
|
|
const method = loadAutoplanMethodologyBinding(call.input.prompt, roots);
|
|
if (method.phase !== 'ceo' || method.sha256 !== options.methodologySha256) continue;
|
|
const nativePath = JSON.parse(/^Read file: ("[^\n]+")$/m.exec(call.input.prompt)![1]!);
|
|
const snapshot = JSON.parse(readFileSync(join(dirname(nativePath), 'snapshot.json'), 'utf8'));
|
|
if (!owned(options.activePlan) || snapshot.activePlan !== options.activePlan ||
|
|
!owned(snapshot.snapshotPath, true)) continue;
|
|
const content = readFileSync(snapshot.snapshotPath, 'utf8');
|
|
if (sha(content) !== snapshot.sha256 ||
|
|
!readFileSync(nativePath, 'utf8').includes(content)) continue;
|
|
if (!/^Async agent launched successfully\./.test(call.result.content) &&
|
|
!new RegExp('^INPUT: ceo ' + snapshot.sha256 + '(?:\\r?\\n|$)').test(report(call.result.content).trimStart())) continue;
|
|
native.push({ call, snapshot, content });
|
|
} catch { /* Unowned, spec-only, foreign-phase and forged snapshots earn no voice credit. */ }
|
|
}
|
|
for (const entry of native) {
|
|
result.claudeVoiceFired = result.reviewDispatched = true;
|
|
result.nativeToolUseId = entry.call.id; result.snapshotSha256 = entry.snapshot.sha256;
|
|
for (const outside of calls.values()) {
|
|
if (outside.name !== 'Bash' || typeof outside.input.command !== 'string' || !outside.result ||
|
|
outside.order <= entry.call.result!.order) continue;
|
|
const writes = [...calls.values()].filter(call => call.name === 'Write' && call.result && !call.result.error &&
|
|
call.result.order < outside.order && typeof call.input.content === 'string' && owned(call.input.file_path));
|
|
for (const write of writes) {
|
|
const file = write.input.file_path;
|
|
if (!write.input.content.includes(entry.content) ||
|
|
!write.input.content.includes('You are a CEO/founder advisor reviewing a development plan.') ||
|
|
!write.input.content.includes('File: ' + entry.snapshot.snapshotPath)) continue;
|
|
// A later write/edit of this prepared prompt invalidates the old payload.
|
|
if ([...calls.values()].some(call => call.order > write.order && call.order < outside.order &&
|
|
['Write', 'Edit'].includes(call.name) && call.input.file_path === file)) continue;
|
|
const command = options.commands.outside.replace("'<prepared-prompt-file>'", "'" + file + "'");
|
|
if (/[\r\n\0']/.test(file) || !canonical(outside.input.command, command, true)) continue;
|
|
const otherIdenticalCalls = new Set([...calls.values()].filter(call => call.id !== outside.id &&
|
|
call.name === 'Bash' && call.input.command === outside.input.command).map(call => call.id));
|
|
const thisExecution = publicStream.filter(event => !event.message?.content?.some((part: any) =>
|
|
otherIdenticalCalls.has(part.id ?? part.tool_use_id)));
|
|
for (const execution of claudeOutsideExecutions(thisExecution)) {
|
|
if (execution.command !== outside.input.command) continue;
|
|
if (execution.succeeded && /^OUTSIDE_STATUS: completed provider=codex host=claude$/m.test(execution.output)) {
|
|
result.codexAttempted = result.codexVoiceFired = true; result.outsideToolUseId = outside.id;
|
|
} else if (!execution.background && !execution.succeeded && outside.result.error &&
|
|
/^(?:Codex outside review unavailable: execution failed; missing coverage\. Check the provider diagnosis above\.|Outside review unavailable: (?:empty response|review refused|missing review completion recommendation); missing coverage\.)$/m.test(execution.output)) {
|
|
// These finite diagnostics occur only after the exact generated
|
|
// command reaches Codex or its review validator. They prove an
|
|
// attempted voice, never a completed review or comparison.
|
|
result.codexAttempted = result.codexUnavailable = true;
|
|
result.failedOutsideToolUseId = outside.id;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
result.codexUnavailable ||= result.claudeVoiceFired && ['not_installed', 'not_authed', 'broken_install', 'model_unusable'].includes(result.probeMode ?? '');
|
|
if (!result.claudeVoiceFired) result.reasons.push('No acknowledged current CEO phase dispatch');
|
|
if (!result.codexVoiceFired && !result.codexUnavailable) {
|
|
result.reasons.push('No acknowledged outside execution or actual unavailable probe result');
|
|
result.reasons.push(`probeToolUseId=${result.probeToolUseId ?? 'none'} probeMode=${result.probeMode ?? 'none'} ` +
|
|
`canonicalMatch=${result.probeToolUseId ? 'yes' : 'no'} (${probeResult}; ${nonCanonicalProbes} non-canonical Bash call(s) mention CODEX_MODE)`);
|
|
}
|
|
return result;
|
|
}
|