OPT-GOV Phase 3 — LTV bid-weighting (shadow, flag-dark) + stockout DEL veto
Branch: claude/opt-gov-phase3-ltv-supply · Session: 7pjhmg · Date: 2026-08-22
Authority: OPT-GOV_PRE_APPROVAL_2026-08-21 (standing GATE-1, conditions verified below) + owner in-session triple release 2026-08-22 (approved:merge/commit/deploy). This phase adds one pre-approved flag — LTV_BID_WEIGHTING, default-false by source-pinned test. GATE-2 flips remain owner-only.
BUILD 1 — LTV governor extension (extend f2_ltv in place)
- Governed config, no literals:
ltv_blend_weightjoins the per-tenantconfig/f2_ltv.yamlschema ([0, 1] or null; null = not provided ⇒ bid_weighting claims nothing). A blend weight is a business value the config declares — the module carries no numeric default. The r3.5.2 one-way floor (min_observed_quarters≥ 2, raise-only) is untouched. bid_weighting.py(new):blended = (1−w)·immediate + w·discounted_multi_quarter_value, computed only from afindingevaluation —data_insufficientis refused as evidence here exactly as at the PLAN bridge (the F2 code guard reaches this surface). Units inherit dtr.py's per-acquired-customer basis; the blend inherits the never-project-beyond-observed-quarters cap through the evaluation it cites.- Flag-dark, shadow-first:
LTV_BID_WEIGHTINGdefaultFalse(source literal, fail-if-flipped test; measurement-rails flag convention). Flag OFF: every emission is a shadow comparison record (applied: false) ANDblended_bid_valueis offered asNone— a caller cannot act on a dark flag even by ignoringapplied. Flag ON (owner GATE-2): the value rides in-band; acting stays the operator-owned caller's move. Anything but"true"in the env is OFF — a typo'd enable stays dark. - Seam discipline: records emit only through the caller-injected
recordcallable; the package tripwire (no HTTP client / cloud SDK / numeric heavies) covers the new module automatically.
BUILD 2 — stockout SUPPLY_CHAIN_VETO (DEL-side hard constraint, F5-mirrored)
contracts/mizoki_contracts/supply_veto.py(new), v1 declared: per-tenant config (config/supply_veto.yamltemplate shipped with zero tenants) — threshold in (0,1] (0 refused: it would veto everything), declared stockout share [0,1] whose stated provenance is the F3 lane's measured output (unified.f3_recommendations, cell37) copied through config review,declared_as_ofREQUIRED with a share (undated declarations would enforce forever), explicitapplies_to_domains(never defaulted). Arming is env-var-only (SUPPLY_VETO_CONFIG_PATH, F5-identical — a cwd-relative auto-discovery could arm the gate by accident; refused by test). The live F3 feed read is the stated v2; the evaluation is source-agnostic.- Fail-closed BOTH ways: absent/invalid config claims nothing (policy engine byte-identical to the pre-veto engine — full eligibility matrix pinned); a stale declaration cannot prove a stockout and vetoes NOTHING even at share 1.0 (probed explicitly), stated in detail rather than silently passing. A veto fires only when everything is proven: enforceable tenant + fresh declaration + domain in scope + spend-carrying + share ≥ threshold.
- Policy-engine wiring: second hard-constraint class, evaluated after treasury (nothing outranks the cash position — pinned: when both fire, the treasury constraint is named) and before every other gate. Strictness-only by construction: the veto only converts would-pass evaluations to BLOCKED; no code path raises an eligibility, lowers a DEL threshold, or softens a gate (satisfies the pre-approval "DEL floors raise-only" condition — this build adds a block and moves no floor). Health reports
supply_vetohonestly (configured + usable-tenant count / not_configured);/reloadcovers it. - Breach action = veto + human routing, never approvable: DCP routes by constraint class —
supply_*vetoes land asSBR-*records insupply_breach_reviews(posture-registered), surfaced by audit-replay's newGET /api/v1/supply/breaches; the treasury queue stays byte-identical, and the cross-queue negative (a supply veto appears in NEITHER the treasury queue NOR approvals) is probed explicitly. - F3 invariants untouched: a veto is a reduction, never a dispatch —
f3-recommendation-onlystays registered in no adapter registry; this lane reads declared state and names a block, emitting no action of any kind. (Prompt-0's compatibility caveat stands recorded; the owner's phase release covered this build.)
Gate results (pre-push, fresh venv)
governance suite 462 passed (434 baseline + 28 new: supply-veto parse/evaluate/service/routing + bid-weighting flag/blend/refusals/config) · remediation suite 294 passed · skill_sync --audit, both parity checkers, canon-status check, V1–V3 greps, memory strict: see commit gate line · one new flag (LTV_BID_WEIGHTING), default-false source-pinned; the other three pre-approved flags remain for their phases · no protected or site-visible paths · new store supply_breach_reviews posture-registered; no new service or ingress surface (the breaches route rides audit-replay behind verify_caller).