#6626 wired the limit modals for direct browser→API calls, but a policy's tool
calls run server-side, so their 402 entitlement block never reaches the apiClient
interceptor — the run just showed up "failed" with no modal. Bridge it:
BE (proprietary, billing-layer-agnostic):
- PolicyEngine.runToCompletion catches a downstream RestClientResponseException;
on a 401/402 it regex-extracts the body's `error` sentinel + `subscribed` flag
and surfaces them on the run (PolicyRun.errorCode/errorSubscribed →
PolicyRunView), instead of only a generic failure string. The code is passed
through, not interpreted, so proprietary stays free of saas coupling.
FE:
- usePolicyAutoRun: when a polled run finishes with an entitlement errorCode,
broadcast POLICY_LIMIT_REACHED_EVENT (with `subscribed`), deduped per run so a
folder-watch burst opens the modal once. The proprietary hook can't import the
saas modal API, so it bridges via a window event.
- UsageLimitModalHost (saas): listens for that event and opens the spend-cap
(subscribed) or free-limit (free) modal — the same modals direct calls use.
Tests: PolicyEngineTest asserts a downstream 402 surfaces errorCode +
errorSubscribed on the run. proprietary compileJava, PolicyEngineTest, eslint,
tsc (proprietary + saas), and policies/interceptor vitest all green.