Skip to content

Commit 5487030

Browse files
feat(gate): implement §4 liveness contract — fail-loud on silent degradation (proposer/f_θ/fallback)
Turns the methodology's §4 from doc into an executable defense: - k3_report_gate.assert_liveness(): asserts proposer ran (blocks>0), f_θ ran when intended (f_theta_ran on every turn), and fallbacks_taken==[] — from RUNTIME signals, not from flags. Missing liveness field = violation. New codes: PROPOSER_NEVER_RAN, FTHETA_NOT_RUN, SILENT_FALLBACK, MISSING_LIVENESS. - validate_report() dispatches liveness reports; validate_k3_reports.py (CI + the Mac-bridge on-device gate) now gates kind=mac_gemma4_kakeya_fused_chat. - harness emits f_theta_intended + fallbacks_taken in the chat report. - fused-chat presets set validate_reports=True → the Mac runner FAILS if the engine silently degraded to verifier-only. - 100% coverage on k3_report_gate + manifest; walker verified to FAIL a degraded report (blocks=0 / f_θ bypassed) and pass a live one. Co-authored-by: FluffyAIcode <FluffyAIcode@users.noreply.github.com>
1 parent 83ac391 commit 5487030

6 files changed

Lines changed: 188 additions & 5 deletions

File tree

inference_engine/bench/k3_report_gate.py

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,12 @@
8989

9090
NATIVE_BASELINE_LABEL = "native_ar_baseline"
9191

92+
# §4 liveness contract (docs/kakeya-autonomous-iteration-and-self-correction.md):
93+
# report kinds that carry per-turn component-liveness signals. The gate proves
94+
# the INTENDED components actually ran — the antidote to silent fallback /
95+
# simplification (proposer→AR, f_θ→bypass) that kept the "fused" label.
96+
LIVENESS_REPORT_KINDS = frozenset({"mac_gemma4_kakeya_fused_chat"})
97+
9298

9399
@dataclass(frozen=True)
94100
class GateViolation:
@@ -103,6 +109,82 @@ def is_gated_report(report: Any) -> bool:
103109
return isinstance(report, dict) and report.get("kind") == MAC_REPORT_KIND
104110

105111

112+
def is_liveness_report(report: Any) -> bool:
113+
"""True when ``report`` carries the §4 component-liveness contract."""
114+
return isinstance(report, dict) and report.get("kind") in LIVENESS_REPORT_KINDS
115+
116+
117+
def assert_liveness(report: Dict[str, Any]) -> List[GateViolation]:
118+
"""§4 liveness contract — prove the intended components actually executed.
119+
120+
Asserts, from RUNTIME signals (never from flags passed in):
121+
* proposer ran — total proposer ``blocks`` across turns > 0,
122+
* f_θ ran — when ``f_theta_intended`` is true, every turn has
123+
``f_theta_ran == true``,
124+
* no silent fallback — ``fallbacks_taken`` (report- and turn-level) empty.
125+
A missing liveness field is itself a violation (absence = "we don't know it
126+
ran" = invalid), not a skip.
127+
"""
128+
violations: List[GateViolation] = []
129+
turns = report.get("turns")
130+
if not isinstance(turns, list) or not turns:
131+
return [GateViolation(
132+
"MISSING_LIVENESS",
133+
"liveness report has no 'turns'; component liveness cannot be "
134+
"asserted (absence of evidence = invalid run)",
135+
)]
136+
137+
# --- proposer liveness: blocks > 0 (else it silently fell back to AR) ---
138+
total_blocks = 0
139+
missing_blocks = False
140+
for t in turns:
141+
b = t.get("blocks") if isinstance(t, dict) else None
142+
if isinstance(b, (int, float)) and not isinstance(b, bool):
143+
total_blocks += int(b)
144+
else:
145+
missing_blocks = True
146+
if missing_blocks:
147+
violations.append(GateViolation(
148+
"MISSING_LIVENESS",
149+
"a turn lacks numeric 'blocks'; proposer liveness unknown",
150+
))
151+
elif total_blocks <= 0:
152+
violations.append(GateViolation(
153+
"PROPOSER_NEVER_RAN",
154+
"fused chat executed 0 proposer blocks across all turns — the "
155+
"proposer silently fell back to native AR (verifier-only)",
156+
))
157+
158+
# --- f_θ liveness: if intended, it must run on every turn ---
159+
if report.get("f_theta_intended") is True:
160+
ran = [t.get("f_theta_ran") if isinstance(t, dict) else None for t in turns]
161+
if any(r is None for r in ran):
162+
violations.append(GateViolation(
163+
"MISSING_LIVENESS",
164+
"f_theta_intended=true but a turn lacks 'f_theta_ran'",
165+
))
166+
elif not all(bool(r) for r in ran):
167+
violations.append(GateViolation(
168+
"FTHETA_NOT_RUN",
169+
"f_theta_intended=true but f_theta_ran is false on >=1 turn — "
170+
"f_θ restoration was silently bypassed",
171+
))
172+
173+
# --- no silent fallback: declared fallbacks (report- + turn-level) empty ---
174+
fallbacks: List[str] = [str(x) for x in (report.get("fallbacks_taken") or [])]
175+
for t in turns:
176+
if isinstance(t, dict):
177+
fallbacks += [str(x) for x in (t.get("fallbacks_taken") or [])]
178+
if fallbacks:
179+
violations.append(GateViolation(
180+
"SILENT_FALLBACK",
181+
f"fallbacks_taken is non-empty: {sorted(set(fallbacks))} — a "
182+
"component degraded to a fallback; the system under test is not "
183+
"the intended one",
184+
))
185+
return violations
186+
187+
106188
def is_legacy_report(report: Dict[str, Any]) -> bool:
107189
"""True when the report predates the evidence gate (schema < 2)."""
108190
try:
@@ -202,6 +284,8 @@ def validate_report(report: Dict[str, Any]) -> List[GateViolation]:
202284
one ``LEGACY_SCHEMA`` violation (the CI walker downgrades that one
203285
code to a warning — everything else fails the build).
204286
"""
287+
if is_liveness_report(report):
288+
return assert_liveness(report)
205289
if not is_gated_report(report):
206290
return []
207291
if is_legacy_report(report):

inference_engine/bridge/manifest.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ def _harness_preset(
711711
"max_new_tokens": ("int:max_new_tokens", "64"),
712712
"block_size": ("int:block_size", "4"),
713713
},
714-
validate_reports=False,
714+
validate_reports=True, # §4 liveness gate on-device (proposer/f_θ/fallback)
715715
),
716716
Preset(
717717
name="mlx-kakeya-fused-chat-ftheta",
@@ -747,7 +747,7 @@ def _harness_preset(
747747
"max_new_tokens": ("int:max_new_tokens", "32"),
748748
"block_size": ("int:block_size", "4"),
749749
},
750-
validate_reports=False,
750+
validate_reports=True, # §4 liveness gate: asserts f_theta_ran on-device
751751
),
752752
Preset(
753753
name="mlx-kakeya-launcher-smoke",
@@ -769,7 +769,7 @@ def _harness_preset(
769769
),
770770
timeout_minutes=45,
771771
params={"max_new_tokens": ("int:max_new_tokens", "64")},
772-
validate_reports=False,
772+
validate_reports=True, # §4 liveness gate on-device
773773
),
774774
)
775775
}

scripts/research/k3_integrated_niah_eval_mac.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,11 @@ def _gen_turn(pid: List[int]) -> Dict[str, Any]:
862862
"f_theta_dir": args.f_theta_dir, "sink": args.sink_size,
863863
"window": args.window_size, "block_size": args.block_size,
864864
"exact_layers": full_attn_idx, "chat_eos": sorted(chat_eos),
865+
# §4 liveness contract: f_θ is INTENDED on the torch path
866+
# (not --all-mlx-drafter); the evidence gate asserts
867+
# f_theta_ran on every turn when this is true.
868+
"f_theta_intended": mlx_drafter is None,
869+
"fallbacks_taken": [],
865870
"turns": transcript}
866871
if args.output:
867872
op = Path(args.output)

scripts/validate_k3_reports.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from inference_engine.bench.k3_report_gate import (
3232
is_gated_report,
3333
is_legacy_report,
34+
is_liveness_report,
3435
summarize_violations,
3536
validate_report,
3637
)
@@ -47,9 +48,13 @@ def main(argv: list) -> int:
4748
report = json.loads(path.read_text())
4849
except (json.JSONDecodeError, UnicodeDecodeError, OSError):
4950
continue
50-
if not is_gated_report(report):
51+
gated = is_gated_report(report)
52+
live = is_liveness_report(report)
53+
if not (gated or live):
5154
continue
52-
if is_legacy_report(report):
55+
# The schema-2 legacy grandfather applies only to the NIAH acceptance
56+
# report; liveness reports (§4 contract) are always asserted.
57+
if gated and is_legacy_report(report):
5358
legacy += 1
5459
print(f"[legacy] {path}: schema<2 — grandfathered, NON-EVIDENCE "
5560
"(rerun with the hardened harness to make claims)")

tests/inference_engine/bench/test_k3_report_gate.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,108 @@
1919
from inference_engine.bench.k3_report_gate import (
2020
CLAIM_ORACLE_DECODE_LOOP,
2121
GATED_SCHEMA_VERSION,
22+
LIVENESS_REPORT_KINDS,
2223
MAC_REPORT_KIND,
2324
MAX_PREFILL_SPREAD,
2425
MIN_MEDIAN_DECODE_TOKENS,
2526
MIN_PERF_SAMPLES,
2627
NATIVE_BASELINE_LABEL,
2728
GateViolation,
29+
assert_liveness,
2830
decode_only_block,
2931
is_gated_report,
3032
is_legacy_report,
33+
is_liveness_report,
3134
prefill_spread,
3235
row_prefill_seconds,
3336
summarize_violations,
3437
validate_report,
3538
)
3639

3740

41+
# ---------------------------------------------------------------------------
42+
# §4 liveness contract (proposer / f_θ / no-fallback)
43+
# ---------------------------------------------------------------------------
44+
45+
46+
def _live_report(**over: Any) -> Dict[str, Any]:
47+
"""A fused-chat liveness report that passes the §4 contract."""
48+
rep = {
49+
"kind": next(iter(LIVENESS_REPORT_KINDS)),
50+
"schema_version": 1,
51+
"f_theta_intended": True,
52+
"fallbacks_taken": [],
53+
"turns": [
54+
{"user": "q1", "blocks": 2, "mean_accept_len": 4.0,
55+
"f_theta_ran": True, "fallbacks_taken": []},
56+
{"user": "q2", "blocks": 4, "mean_accept_len": 3.5,
57+
"f_theta_ran": True, "fallbacks_taken": []},
58+
],
59+
}
60+
rep.update(over)
61+
return rep
62+
63+
64+
def test_liveness_report_detection_and_pass():
65+
rep = _live_report()
66+
assert is_liveness_report(rep) and not is_gated_report(rep)
67+
assert validate_report(rep) == [] # dispatches to assert_liveness
68+
assert assert_liveness(rep) == []
69+
70+
71+
def test_liveness_missing_turns_is_invalid():
72+
codes = {v.code for v in assert_liveness(_live_report(turns=[]))}
73+
assert codes == {"MISSING_LIVENESS"}
74+
75+
76+
def test_liveness_proposer_never_ran():
77+
rep = _live_report(turns=[
78+
{"blocks": 0, "f_theta_ran": True}, {"blocks": 0, "f_theta_ran": True}])
79+
codes = {v.code for v in assert_liveness(rep)}
80+
assert "PROPOSER_NEVER_RAN" in codes
81+
82+
83+
def test_liveness_missing_blocks_field():
84+
rep = _live_report(turns=[{"f_theta_ran": True}]) # no 'blocks'
85+
codes = {v.code for v in assert_liveness(rep)}
86+
assert "MISSING_LIVENESS" in codes
87+
88+
89+
def test_liveness_bool_blocks_not_counted_as_int():
90+
# True is an int subclass — must NOT be accepted as a block count.
91+
rep = _live_report(turns=[{"blocks": True, "f_theta_ran": True}])
92+
codes = {v.code for v in assert_liveness(rep)}
93+
assert "MISSING_LIVENESS" in codes
94+
95+
96+
def test_liveness_ftheta_not_run_when_intended():
97+
rep = _live_report(turns=[
98+
{"blocks": 2, "f_theta_ran": True}, {"blocks": 2, "f_theta_ran": False}])
99+
codes = {v.code for v in assert_liveness(rep)}
100+
assert "FTHETA_NOT_RUN" in codes
101+
102+
103+
def test_liveness_ftheta_missing_flag_when_intended():
104+
rep = _live_report(turns=[{"blocks": 2}]) # f_theta_intended True but no flag
105+
codes = {v.code for v in assert_liveness(rep)}
106+
assert "MISSING_LIVENESS" in codes
107+
108+
109+
def test_liveness_ftheta_not_required_when_not_intended():
110+
# all-MLX fast path: f_θ bypassed by design → no FTHETA_NOT_RUN.
111+
rep = _live_report(f_theta_intended=False, turns=[
112+
{"blocks": 2, "f_theta_ran": False}, {"blocks": 3, "f_theta_ran": False}])
113+
assert assert_liveness(rep) == []
114+
115+
116+
def test_liveness_silent_fallback_report_and_turn_level():
117+
rep = _live_report(fallbacks_taken=["proposer->ar"])
118+
assert any(v.code == "SILENT_FALLBACK" for v in assert_liveness(rep))
119+
rep2 = _live_report(turns=[
120+
{"blocks": 2, "f_theta_ran": True, "fallbacks_taken": ["f_theta->identity"]}])
121+
assert any(v.code == "SILENT_FALLBACK" for v in assert_liveness(rep2))
122+
123+
38124
def _valid_report(n: int = MIN_PERF_SAMPLES) -> Dict[str, Any]:
39125
"""A schema-2 report that passes every rule."""
40126
cross_rows = [

tests/inference_engine/bridge/test_manifest.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ def test_harness_presets_validate_reports_others_do_not():
103103
assert gated == {
104104
"k3-step1-incremental", "k3-step2-fused", "k3-native-baseline",
105105
"k3-step2-fused-allmlx",
106+
# §4 liveness gate runs on-device for the fused-chat presets too:
107+
"mlx-kakeya-fused-chat-smoke", "mlx-kakeya-fused-chat-ftheta",
108+
"mlx-kakeya-launcher-smoke",
106109
}
107110

108111

0 commit comments

Comments
 (0)