mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-20 03:42:24 +02:00
fix(pty-runner): positional floor exclusion, flag builder, outcome union, token tracking
Review-army + adversarial findings on the scope-gate observability work, all verified before fixing: - Floor check: acceptance scanned the CUMULATIVE buffer while the scope-gate exclusion scanned only the 1500-byte tail, so an early gate render satisfied the floor vacuously once ~1.5KB of output accumulated (found independently by 4 review passes; predicate reproduced). Acceptance now scans only content APPENDED after the first gate render (positional anchor), and the LLM-judge 'waiting' shortcut no longer fires while the gate menu is the pending render. - High-water flags are built once and spread at every return path — the hand-spread pattern had already drifted (judge-waiting return omitted two flags), which made must-stay-false asserts vacuous on those paths. - isScopeGateAutoSelectVisible: tense-tolerant selected/selecting/selects token (must-be-TRUE asserts shouldn't fail semantically-perfect paraphrases) and quoted-occurrence rejection (a model verbatim-quoting the announcement while declining must not trip must-stay-FALSE asserts). Fixtures added for both directions. - PlanSkillObservation outcome union gains 'wrote_findings_before_asking' (returned at runtime via classifyVisible but missing from the type). - trackTokens/tokensObserved: cumulative-buffer token high-water for consumption asserts (the 2KB evidence tail is lossy and the plan-file fallback is unreachable outside plan mode). - New scope-gate-floor unit pins (from the ship coverage audit): both gate render forms trip acceptance and exclusion; a genuine finding AUQ is not excluded; tail-scoping semantics pinned. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
57c53e7913
commit
4e61233021
@@ -264,6 +264,33 @@ Recommendation: A when a branch diff exists, otherwise B.
|
||||
expect(isScopeGateAutoSelectVisible(sample)).toBe(false);
|
||||
});
|
||||
|
||||
test('stays false on a VERBATIM QUOTE of the announcement (negation narration)', () => {
|
||||
// The exact announcement line sits quoted in the skill context, so a
|
||||
// model explaining why it is NOT firing it can reproduce it byte-exact
|
||||
// inside quotes — that must not trip a must-stay-false assert.
|
||||
const sample =
|
||||
'Not in plan mode, so I won\'t announce "Scope gate: plan mode — auto-selected B (reviewing <target>)." and will ask instead.';
|
||||
expect(isScopeGateAutoSelectVisible(sample)).toBe(false);
|
||||
});
|
||||
|
||||
test('a later real render still matches after an earlier quoted mention', () => {
|
||||
const sample =
|
||||
'Earlier I said I would render "Scope gate: plan mode — auto-selected B (…)" and now:\n' +
|
||||
'Scope gate: plan mode — auto-selected B (reviewing PLAN.md).';
|
||||
expect(isScopeGateAutoSelectVisible(sample)).toBe(true);
|
||||
});
|
||||
|
||||
test('matches tense paraphrases WITH the announcement prefix (auto-selecting / auto-selects)', () => {
|
||||
expect(
|
||||
isScopeGateAutoSelectVisible('Scope gate: plan mode — auto-selecting B (reviewing the drafted plan).'),
|
||||
).toBe(true);
|
||||
expect(isScopeGateAutoSelectVisible('Scope gate: plan mode — auto-selects B.')).toBe(true);
|
||||
});
|
||||
|
||||
test('stays false on tense paraphrases WITHOUT the announcement prefix', () => {
|
||||
expect(isScopeGateAutoSelectVisible('Auto-selecting B since we are in plan mode.')).toBe(false);
|
||||
});
|
||||
|
||||
test('stays false on AUTO_DECIDE preamble output', () => {
|
||||
const sample = 'Auto-decided scope question → B (your preference). Change with /plan-tune.';
|
||||
expect(isScopeGateAutoSelectVisible(sample)).toBe(false);
|
||||
|
||||
Reference in New Issue
Block a user