Conversation
Signed-off-by: Jake Gaylor <jhgaylor@gmail.com>
BinaryBourbon
left a comment
There was a problem hiding this comment.
Approving.
Promoting the helper to _unsafe_check_saved_execution_allowance/1 with a docstring is the correct move under the naming rule — it is now called from ConversationServer and the rehydrator, and the prefix is what tells a reader at those call sites that ownership had to be established upstream.
The substantive change is moving close_autonomous_turn(state, "superseded_by_prompt") from before the gates to inside the success branch. That is broader than execution limits — a prompt refused by TurnMachine.gate/2 (billing) or capacity_gate/2 no longer kills the background narration either — and I think it is right: refusing a prompt should not have the side effect of ending work the user did not ask to end. #817's semantics for the accepted case are unchanged, which is what that issue was actually about. The description calls this out, so it is a deliberate widening rather than an accident.
Checked the else branch returns the pre-close state, so the refusal path really is inert.
The active × malformed matrix asserting :sys.get_state(pid) == before alongside unchanged turns, unchanged conversation row and unchanged usage count is a strong shape for this — it catches a partial mutation that a return-value assertion would miss.
When a prompt reaches an existing server, an unsupported saved allowance previously returned HTTP 200
queuedafter turn admission refused it. It could also complete autonomous work and close the connection. Check saved policy before superseding that work, returning HTTP 422 with the current state intact. Billing and capacity preflights also precede supersession; user-busy precedence and cancellation remain unchanged.Stacked on #1777 (
fix/saved-allowance-wake-guard). Reuses its saved-policy check and HTTP mapping. Focused replacement for #1745/#1754; tracked in #1732.Validation: six new real-server regressions, including idle/autonomous HTTP refusals for unsupported/malformed policy, unchanged turns/usage/connection, cancellation, empty-policy handoff and busy-user behavior. Four reproduce
200 queuedon the parent. All 159 related tests pass. Full precommit passes 4,748 tests plus six doctests, zero failures; diff secret scan passes.This is preflight: #1776 still rechecks inside turn admission if policy changes concurrently. It does not add an atomic prompt receipt, enforce running-turn limits or enable saved-policy writes. Initial prompt casts, channel reuse, direct boot recovery, ceilings and runtime enforcement remain separate; live enforcement acceptance is still required.