fix(execute): the completion gate says which checks are commands and which are executor judgement
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
2fe6feb74d
commit
a9f5f6251a
3 changed files with 60 additions and 8 deletions
2
tests/fixtures/jsonl-schemas.md
vendored
2
tests/fixtures/jsonl-schemas.md
vendored
|
|
@ -22,7 +22,7 @@
|
|||
| trekbrief-stats | ts, task, slug, mode, interview_turns, review_iterations, brief_quality, research_topics, auto_research, auto_result, intent_approved, project_dir, order_id, order_claimed_at, order_reason | commands/trekbrief.md (orchestrator-emit Phase 7; order_* added by lib/stats/stats-append.mjs) | trekbrief.md:1140-1164 | profile, phase_models, profile_source | none |
|
||||
| trekresearch-stats | ts, question, mode, scope, engine, slug, project_dir, brief_path, dimensions, dimensions_baseline, dimensions_baseline_preserved, effort, conv_turns, empty_turns, unique_sources, agents_local, agents_external, gemini_used, confidence, contradictions, open_questions | lib/stats/stats-append.mjs (trekresearch.md Stats tracking) | trekresearch.md:806-839 | profile, phase_models, parallel_agents, external_research_enabled, profile_source | none |
|
||||
| trekplan-stats | ts, task, mode, slug, brief_path, project_dir, codebase_size, codebase_files, agents_deployed, deep_dives, research_briefs_used, research_scout_used, critic_verdict, guardian_verdict, outcome | lib/stats/stats-append.mjs (trekplan.md Phase 12) | trekplan.md:1305-1333 | profile, phase_models, parallel_agents, profile_source | none |
|
||||
| trekexecute-stats (Phase 9 record) | ts, plan, plan_type, mode, result, steps_total, steps_passed, steps_failed, steps_skipped, failed_at_step | lib/stats/stats-append.mjs (trekexecute.md Phase 9) | trekexecute.md:2943-2965 | profile, phase_models, profile_source | none |
|
||||
| trekexecute-stats (Phase 9 record) | ts, plan, plan_type, mode, result, steps_total, steps_passed, steps_failed, steps_skipped, failed_at_step | lib/stats/stats-append.mjs (trekexecute.md Phase 9) | trekexecute.md:2950-2972 | profile, phase_models, profile_source | none |
|
||||
| trekexecute-stats (autonomy events) | ts, event, known_event, payload | lib/stats/event-emit.mjs `emit()` | event-emit.mjs:78-99 | payload.profile, payload.phase_models, payload.profile_source | none |
|
||||
| trekexecute-stats (PostToolUse Bash) | ts, session_id, command_excerpt, duration_ms, success | hooks/scripts/post-bash-stats.mjs (Bash PostToolUse) | post-bash-stats.mjs:42-54 | none (hook is plugin-level, not profile-aware) | command_excerpt (CWE-212) |
|
||||
| trekreview-stats | ts, slug, verdict, counts (BLOCKER/MAJOR/MINOR/SUGGESTION), reviewed_files_count, mode, duration_ms | lib/stats/stats-append.mjs (trekreview.md Phase 8) | trekreview.md:636-686 | profile, phase_models, profile_source | none |
|
||||
|
|
|
|||
|
|
@ -785,3 +785,48 @@ test('[#33] no gates_mode = \'closed\', "strictest" or --event gates_mode_flag_o
|
|||
'### High-effort behavior (v5.1.1) High effort changes nothing in `/trekexecute`: the step helper and the controller '
|
||||
+ 'already run opus, and every gate already runs. No `gates_mode` is set from the effort.');
|
||||
});
|
||||
|
||||
// --- #28 ---------------------------------------------------------------------------
|
||||
|
||||
/** The completion gate's text with its blockquote markers removed, flattened. */
|
||||
function completionGate() {
|
||||
return flat(section(read(EXEC), '### Machine-verifiable completion gate (stop-signal contract)').replace(/^> ?/gm, ''));
|
||||
}
|
||||
|
||||
test('[#28] the completion gate calls nothing deterministic that is executor judgement, and cites no line number', () => {
|
||||
const gate = completionGate();
|
||||
assert.ok(!gate.includes('Counter liveness (deterministic'), 'clause 3 still calls the counter check deterministic');
|
||||
assert.ok(!gate.includes('deterministic audit'), 'the gate still says termination rests on a deterministic audit');
|
||||
assert.ok(!gate.includes('`:1221`'), 'the gate still cites `:1221`');
|
||||
assert.doesNotMatch(gate, /`:\d+`/, 'the gate cites a line number; line numbers rot');
|
||||
assert.ok(gate.includes('Counter liveness (checked by the executor against the audit\'s counts, defeats "never decremented")'),
|
||||
'clause 3 does not say the executor checks the counter against the audit\'s counts');
|
||||
assert.ok(gate.includes('rests on the audit and an objective stop-signal, never on the model\'s narrative'),
|
||||
'the termination sentence does not rest on the audit and an objective stop-signal');
|
||||
});
|
||||
|
||||
test('[#28] the completion gate names its commands and its executor judgement, and each command is in Phase 7.5', () => {
|
||||
const gate = completionGate();
|
||||
const c = gate.indexOf('Commands:');
|
||||
const j = gate.indexOf('Executor judgement:');
|
||||
assert.ok(c !== -1, 'the gate does not say which checks are commands');
|
||||
assert.ok(j > c, 'the gate does not say which checks are executor judgement, after its commands');
|
||||
const commands = gate.slice(c, j);
|
||||
const judgement = gate.slice(j);
|
||||
// Phase 7.5's own steps only: the gate subsection after them holds the Commands part under test.
|
||||
const phase75 = section(read(EXEC), '## Phase 7.5 — Manifest audit (independent)');
|
||||
const gateAt = phase75.indexOf('\n### Machine-verifiable completion gate');
|
||||
assert.ok(gateAt !== -1, 'Phase 7.5 no longer holds the completion gate subsection');
|
||||
const audit = flat(phase75.slice(0, gateAt));
|
||||
assert.ok(!audit.includes('Commands:'), 'the audit slice still holds the gate\'s Commands part');
|
||||
for (const cmd of ['git rev-list --count', 'bash -n', 'git diff --name-only', 'done-line.mjs --check']) {
|
||||
assert.ok(commands.includes(cmd), `the Commands part does not name ${cmd}`);
|
||||
assert.ok(audit.includes(cmd), `Phase 7.5 does not run ${cmd}, so the gate cannot call it a command`);
|
||||
}
|
||||
for (const s of ['criteria runner', 'arch-rules.mjs', 'plan-scope-sweep.mjs']) {
|
||||
assert.ok(commands.includes(s), `the Commands part does not name ${s}`);
|
||||
}
|
||||
for (const s of ['steps 1, 2 and 4', 'the expected count in step 3', 'clause 3\'s formula']) {
|
||||
assert.ok(judgement.includes(s), `the Executor judgement part does not name ${s}`);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue