← Journal §12 · §13 · 3D flow · Transmission cells · Multi-agent typing · Figures home

Where halt is adjudicated (MA4b)

When a question cannot be answered from licensed sources, the pipeline should refuse. MA4b asks where that decision belongs: inside the generator's prompt, or in a deterministic rule upstream of the generator that reads retrieved metadata and never asks the model to decide. Four arms, 18 frozen items, retrieval held flat at top-5 in every arm, hand-off envelope identical in every arm. Only the halt mechanism varies. Model llama3.2:3b at temperature 0.0, seed 19870317. Scoring is deterministic regex and set arithmetic; no model scored any output.

Figure H1 · Where the refusal decision is made

Four arms as four paths through the same pipeline

In the two prompt-clause arms the generator is called on every item and asked to decide. In the two gate arms the rule reads the retrieved-hit metadata and, when it closes, the pipeline writes the canonical halt string and makes no model call at all - neither hop. That bypass is the whole mechanism, and it is why the call count falls from 36 to 14.

Figure H2 · The trade-off, and where the errors come from

Three proportions by arm, then the error decomposition for the best arm

All three measures are proportions on a shared 0 to 1 axis. D2_rule_gate is the best arm on every measure that trades off: recall equal to the prompt-clause arm, higher precision, higher F1, and 22 fewer generator calls. It is still not a precise instrument. The decomposition is the part that matters: six of its eight false refusals were produced by the gate before any model call, and only two by the generator on items the gate had cleared. Fixing the generator cannot recover those six. The gate is where the remaining error lives.

Figure H3 · The clause was never evaluated

The same predicate as a rule and as a sentence in a prompt

The halt clause licenses refusal only when the received message carries no SHELL=soviet_outward and no SHELL=rival. Every dot is a hop-1 message that visibly carried one of those tags, so the clause's own stated precondition was false. Both arms containing the clause refused all of them. The same two arms' counterparts, running the same model on the same substrate with no halt language in the prompt, refused 4 of 11 and 1 of 6. And the clause written as a rule, R3, whose wording the prereg records as mirroring the generator clause, closed 1 item in 18. The instruction was never wrong about which items to refuse. At this model scale it was never evaluated as a condition: mentioning refusal was sufficient to produce refusal.

What this does not establish

One model, one seed, eighteen items. This is llama3.2:3b at temperature 0.0 and seed 19870317 on the 18 frozen items of one plate, of which 5 are should-refuse and 13 should-answer. One item moves refusal recall by 0.20. There is no null model, no effect size, and no second model. The refusal label is a lexical detector throughout, and on gate-closed items in the two gate arms it is scoring the canonical halt string rather than any model output.

The gate is not solved, and flat retrieval is the binding constraint. The figures above are MA4b on flat top-5 retrieval (ma4b_rule_layer_halt_report.json, llama3.2:3b). The gate is topic-blind: it closes when an unpaired outward claim or a documented miss appears anywhere in the top five. That is why gate-level false closure on answerable items is 0.4615 and D2 false refusal is 0.6154.

Follow-up MA4c (scoped retriever, qwen2.5:3b, 2026-10-02). Same arms on E4-style outward-only top-5 (ma4c_scoped_rule_gate_report.json in the thesis lab). Baseline false refusal fell to 0.23 (scoped context, no internal units in the hit list). The rule gate closed 0 of 18 items (R1/R2 never fire on outward-only hits), so D2 recall fell to 0.40 while false refusal stayed 0.23. Tradeoff: scoped retrieval fixes tier noise; the flat gate predicate does not transfer without reading the flat touch set or using E4's retrieval-layer halt. See journal §13 and transmission T3.

Every number in this figure, with its source key

ValueWhere it appearsKey in ma4b_rule_layer_halt_report.json
18 items, 5 should-refuse, 13 should-answerH1, H2, prosen_items, n_should_refuse, n_should_answer
llama3.2:3b, seed 19870317, temperature 0.0lede, prosemodel, seed, temperature
flat top-5, held constant across armslede, H1, proseretrieval
Generator calls: 36, 36, 14, 14H1summary[arm].generator_calls
22 calls saved in both gate armsH1summary.D2_rule_gate.generator_calls_saved_vs_baseline, same for E2
100 generator calls in the runH1total_generator_calls
Generator ran on 18, 18, 7, 7 itemsH1summary[arm].post_hoc.halt_clause_audit.n_generator_ran
Gate: 11 closed, 7 open (identical in both gate arms)H1, H3summary.D2_rule_gate.gate.n_closed, .n_open
Closure reasons: R1 on 7, R2 on 3, R3 on 1H1, H3counted from summary.D2_rule_gate.gate.closed_reasons
B2 caught 1 of 5 should-refuse itemsH1summary.B2_no_halt.true_positives, n_should_refuse
C2 refused all 18; no usable answerH1summary.C2_generator_halt.post_hoc.n_nonrefusal = 0; true_positives 5 + false_positives 13
D2 on the cleared slice: 5 answered, 2 refused of 7H1, H2summary.D2_rule_gate.gate_cleared_slice.refusal_rate_on_cleared 0.2857, n_cleared 7
E2 on the cleared slice: refused 7 of 7H1, H3summary.E2_rule_gate_plus_typed_halt.gate_cleared_slice.refusal_rate_on_cleared 1.0, n_cleared 7
Refusal recall 0.2000, 1.0000, 1.0000, 1.0000H2summary[arm].refusal_recall
False refusal 0.3846, 1.0000, 0.6154, 1.0000H2, prosesummary[arm].false_refusal
Refusal F1 0.1818, 0.4348, 0.5556, 0.4348H2summary[arm].refusal_f1
Refusal precision 0.1667, 0.2778, 0.3846, 0.2778this tablesummary[arm].refusal_precision
D2 false refusals: 8 totalH2summary.D2_rule_gate.false_positives
6 of those 8 came from the gateH2gate.n_closed 11 less the 5 should-refuse it caught (gate_recall_on_should_refuse 1.0); equals gate_false_closure_on_should_answer 0.4615 × 13
2 of those 8 came from the generatorH2gate_cleared_slice.refusal_rate_on_cleared_should_answer 0.2857 × n_cleared_should_answer 7
The 6 gate false closures: e2_i06, e2_i07, e2_i10, e2_i11, e2_i12, e2_i15H2records[] where arm is D2_rule_gate, refusal true, refusal_correct_item false, gate_open false
The 2 generator false refusals: e2_i04, e2_i08; B2 refused both tooH2same filter with gate_open true; cross-checked against records[] for B2_no_halt
C2 and E2 false refusal 1.0000 on all 13H2summary[arm].false_refusal, summary[arm].false_positives 13
Hop-1 carried an outward shell tag: 11, 11, 6, 6H3summary[arm].post_hoc.halt_clause_audit.n_hop1_carries_outward_shell_tag
Refused anyway: 4, 11, 1, 6H3summary[arm].post_hoc.halt_clause_audit.n_refused_despite_outward_shell_tag
Rate refused anyway: 0.3636, 1.0000, 0.1667, 1.0000H3summary[arm].post_hoc.halt_clause_audit.rate_refused_despite_outward_shell_tag
R3 as a rule closed 1 item of 18H3one R3 entry in summary.D2_rule_gate.gate.closed_reasons (e2_i06), against n_items 18
Gate false closure on answerable items 0.4615H2, prosesummary.D2_rule_gate.gate.gate_false_closure_on_should_answer
Gate recall on should-refuse 1.0000H1, prosesummary.D2_rule_gate.gate.gate_recall_on_should_refuse
Gate predicate R1 / R2 / R3, no model callH1, H3, prosegate_predicate
32-unit corpus; one unit triggers R1, one triggers R2; gate is topic-blindproseknown_limitations[1]
One item moves refusal recall by 0.20proseknown_limitations[4]
Halt string, not the model, is scored on gate-closed itemsproseknown_limitations[0]
Gate evaluated on flat top-5, not the scoped retrieverprosescope_limit

Chart bar labels are shown at two decimal places; this table carries the report's full precision. The preregistered false-refusal ceiling of 0.25 comes from the run's prereg document, not from the JSON report, and is the only figure on this page drawn from the prose rather than the report.