fix(enforce): hole 4 — triggers_matched fallback when classifier silent
Brain-retro #5 candidate C, hole 4: enforce-classifier-match.mjs main() read only state.classification.recommended_node, which is null for prefilter/regex classifier sources. When triggers_matched[0] contained a recommendation, the rule was bypassed. Added fallback: if recommended_node is null, use triggers_matched[0]. decide() already accepts null confidence on this path (only numeric < 0.7 blocks).
This commit is contained in:
@@ -98,8 +98,17 @@ async function main() {
|
||||
|
||||
const state = readRouterState(event.session_id);
|
||||
const cls = state && state.classification;
|
||||
const recommendation = cls && (cls.recommended_node || cls.recommendedNode);
|
||||
let recommendation = cls && (cls.recommended_node || cls.recommendedNode);
|
||||
const confidence = cls && typeof cls.confidence === 'number' ? cls.confidence : null;
|
||||
// Hole 4 fix: fall back to triggers_matched[0] when classifier silent.
|
||||
// Confidence stays null in fallback path — decide() accepts null (only
|
||||
// numeric confidence < 0.7 blocks the rule).
|
||||
if (!recommendation) {
|
||||
const triggers = (cls && cls.triggers_matched) || [];
|
||||
if (Array.isArray(triggers) && triggers.length > 0 && typeof triggers[0] === 'string' && triggers[0].length > 0) {
|
||||
recommendation = triggers[0];
|
||||
}
|
||||
}
|
||||
const toolUses = turnToolUses(transcript);
|
||||
const assistantText = lastAssistantText(transcript);
|
||||
|
||||
|
||||
@@ -156,4 +156,16 @@ describe('enforce-classifier-match / decide', () => {
|
||||
override: null,
|
||||
}).block).toBe(false);
|
||||
});
|
||||
|
||||
// hole 4: triggers_matched fallback — decide() contract test
|
||||
it('blocks when recommendation comes from triggers_matched fallback (hole 4, null confidence)', () => {
|
||||
const r = decide({
|
||||
toolUses: [{ name: 'Edit', input: {} }],
|
||||
recommendation: 'superpowers:writing-plans', // would-be from triggers_matched[0]
|
||||
confidence: null, // no LLM, but triggers present
|
||||
assistantText: '',
|
||||
override: null,
|
||||
});
|
||||
expect(r.block).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user