Without a gate, integration owns every block the day it arrives, including the ones whose collateral contradicts itself. With a gate, ownership transfers on evidence: the checks pass, the waivers are few and owned, and the version is recorded. The gate has three parts: how a delivery is scored, what refusal looks like, and how waivers age so that a temporary excuse cannot become permanent silence.
The gate scores four areas with fixed weights that the project agrees once: completeness of the delivery from the first lesson, consistency between the collateral items, verification evidence for the exact configuration shipped, and documentation quality for the integrator and the driver author. The worked scorer below uses illustrative weights of 30, 30, 25 and 15 out of 100, with acceptance at 80 and no single area below half of its weight (the floor): a perfect file list cannot compensate for missing verification evidence. Area scores are computed from the number of checks passed in each area, not typed in. Each waived item records its owner and its expiry in days; the gate fails any delivery with an expired waiver, and the expiry is what forces redelivery instead of forgiveness.
WEIGHTS = {"completeness": 30, "consistency": 30, # illustrative weights
"evidence": 25, "documentation": 15}
THRESHOLD = 80 # illustrative acceptance bar
FLOOR = 0.5 # no area below half of its weight
def verdict(checks, waivers):
"""checks: area -> (passed, total). Returns the list of refusal reasons."""
pts = {a: WEIGHTS[a] * p / t for a, (p, t) in checks.items()}
reasons = []
if sum(pts.values()) < THRESHOLD:
reasons.append("total")
reasons += ["floor: " + a for a in WEIGHTS if pts[a] < FLOOR * WEIGHTS[a]]
reasons += ["expired: " + w["item"] for w in waivers if w["days_left"] <= 0]
return reasons
checks = {"completeness": (9, 10), "consistency": (8, 10),
"evidence": (12, 25), "documentation": (13, 15)} # wrong-configuration evidence
live = [{"item": "cdc_reset stamp", "owner": "dma-team", "days_left": 14}]
dead = live + [{"item": "power intent", "owner": "dma-team", "days_left": 0}]
# 27 + 24 + 12 + 13 = 76: below 80, and evidence 12 is below its floor 12.5
assert verdict(checks, live) == ["total", "floor: evidence"]
assert verdict(checks, dead) == ["total", "floor: evidence", "expired: power intent"]
# rerun evidence arrives (22 of 25): 27 + 24 + 22 + 13 = 86, floor met
better = dict(checks, evidence=(22, 25))
assert verdict(better, live) == []
assert verdict(better, dead) == ["expired: power intent"]
# paperwork cannot buy back missing evidence: total 85 but floor still refuses
paper = dict(checks, completeness=(10, 10), consistency=(10, 10), evidence=(10, 25))
assert verdict(paper, live) == ["floor: evidence"]
print("PASS: 76 refused on total and floor; 86 accepts; 85 with weak evidence still refused")The score sheet with the four areas, the threshold and the per-area floor, attached to the integration record.
Every waiver names an owner and an expiry; expired waivers fail the gate automatically, no discussion.
Refusals state the missing evidence precisely enough that the redelivery can be checked mechanically on return.
Age the waivers weekly: the report lists days remaining per item and escalates anything under seven days to the block owner. When a redelivery arrives, rerun the completeness checker from the first lesson before rescoring; most second refusals are new files with old stamps. Record the accepted version in the integration manifest so the constraint-merge and verification topics build on the same identity. For the physical-macro side of the same gate see Acceptance Gate and Redelivery and Hard-Macro Handoff Failures.
Refuse. The expiry is the mechanism that keeps waivers honest; accepting an expired waiver teaches every team that expiry is advisory. The redelivery is cheap: renew the waiver with an owner and a date, or deliver the evidence.