Spaces:
Running
fix(warhacker): make shallow launch endpoint genuinely mode-aware + real per-run receipts
Browse filesRoot cause: the self-contained /warhacker/launch/{problem} handler returned an IDENTICAL receipt for mode=nominal and mode=tamper (constant id, no real tamper test). It now DELEGATES to the REAL, mode-aware exhaustive-demo engine (szl_warhacker_demos): STL robustness rho, PolyCARP-style geofence, conformal interval, SHA-256 Merkle chain + Rekor-style inclusion proof, DSSE-signed breach event with the in-image ECDSA-P256 key. Receipt id is a real SHA-256 over the per-run DSSE PAE + chain hash + mode + decision, so it differs every run. Added chain_self (live-run own chain re-verified intact, NO tamper) to all 5 demos and a 'live chain' panel block + renderChainSelf() in pages/warhacker.html. Honesty labels preserved: cannonico=REAL TODAY; tychee/hangar2apps/cyber_rts/raven=ROADMAP (substrate real / vertical = sample data). Sovereign: zero CDN.
Signed-off-by: Stephen P. Lutar Jr. <stephenlutar2@gmail.com>
Co-Authored-By: Perplexity Computer Agent <agent@perplexity.ai>
- pages/warhacker.html +18 -0
- serve.py +72 -16
- szl_warhacker_demos.py +40 -5
|
@@ -349,6 +349,8 @@
|
|
| 349 |
'<ul class="tl" id="tl-'+p.key+'"><li class="empty">— run a demo to populate the timeline —</li></ul></div>'+
|
| 350 |
'<div class="block" id="ctblock-'+p.key+'"><div class="block-h"><span class="pillc">catch tree</span> first failing condition auto-expanded</div>'+
|
| 351 |
'<ul class="ct" id="ct-'+p.key+'"><li class="empty">— run a demo —</li></ul></div>'+
|
|
|
|
|
|
|
| 352 |
'<div class="block" id="tamperblock-'+p.key+'"><div class="block-h"><span class="pillc">tamper test</span> one byte flipped → chain breaks</div>'+
|
| 353 |
'<div id="tamper-'+p.key+'"><div class="empty">— run the tamper test to flip one byte and watch the signed chain break —</div></div></div>'+
|
| 354 |
'<div class="block"><div class="block-h"><span class="pillc">formula-proof panel</span> exact formulas + honest status</div>'+
|
|
@@ -459,6 +461,20 @@
|
|
| 459 |
return '<span class="b4">before: '+esc(b)+'</span><br><span class="af">after: '+pre+'<span class="hl">'+ch+'</span>'+post+'</span>';
|
| 460 |
}
|
| 461 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 462 |
function renderTamper(key, tt, problem){
|
| 463 |
var box = $("tamper-"+key);
|
| 464 |
if(!tt){ box.innerHTML = '<div class="empty">— no tamper data —</div>'; return false; }
|
|
@@ -538,6 +554,8 @@
|
|
| 538 |
var anim = renderTimeline(key, d.timeline, true);
|
| 539 |
// catch tree
|
| 540 |
renderCatchTree(key, d.catch_tree, d.first_failing_node);
|
|
|
|
|
|
|
| 541 |
// tamper test (always present — the negative test)
|
| 542 |
var caught = renderTamper(key, d.tamper_test, key);
|
| 543 |
// formula panel
|
|
|
|
| 349 |
'<ul class="tl" id="tl-'+p.key+'"><li class="empty">— run a demo to populate the timeline —</li></ul></div>'+
|
| 350 |
'<div class="block" id="ctblock-'+p.key+'"><div class="block-h"><span class="pillc">catch tree</span> first failing condition auto-expanded</div>'+
|
| 351 |
'<ul class="ct" id="ct-'+p.key+'"><li class="empty">— run a demo —</li></ul></div>'+
|
| 352 |
+
'<div class="block" id="chainselfblock-'+p.key+'"><div class="block-h"><span class="pillc">live chain</span> this run\u2019s own signed chain — re-verified intact</div>'+
|
| 353 |
+
'<div id="chainself-'+p.key+'"><div class="empty">— run a demo to verify the live signed chain —</div></div></div>'+
|
| 354 |
'<div class="block" id="tamperblock-'+p.key+'"><div class="block-h"><span class="pillc">tamper test</span> one byte flipped → chain breaks</div>'+
|
| 355 |
'<div id="tamper-'+p.key+'"><div class="empty">— run the tamper test to flip one byte and watch the signed chain break —</div></div></div>'+
|
| 356 |
'<div class="block"><div class="block-h"><span class="pillc">formula-proof panel</span> exact formulas + honest status</div>'+
|
|
|
|
| 461 |
return '<span class="b4">before: '+esc(b)+'</span><br><span class="af">after: '+pre+'<span class="hl">'+ch+'</span>'+post+'</span>';
|
| 462 |
}
|
| 463 |
|
| 464 |
+
function renderChainSelf(key, cs){
|
| 465 |
+
var box = $("chainself-"+key);
|
| 466 |
+
if(!box) return;
|
| 467 |
+
if(!cs){ box.innerHTML = ""; return; }
|
| 468 |
+
var intact = (cs.chain_intact===true) && (cs.merkle_root_matches===true);
|
| 469 |
+
box.innerHTML =
|
| 470 |
+
'<div class="tamper-grid">'+
|
| 471 |
+
'<div class="tamper-cell"><div class="tk">live-run chain intact</div><div class="tv '+(intact?"good":"bad")+'">'+esc(cs.chain_intact)+'</div></div>'+
|
| 472 |
+
'<div class="tamper-cell"><div class="tk">merkle root matches</div><div class="tv '+(cs.merkle_root_matches?"good":"bad")+'">'+esc(cs.merkle_root_matches)+'</div></div>'+
|
| 473 |
+
'<div class="tamper-cell"><div class="tk">committed merkle root</div><div class="tv">'+esc(String(cs.merkle_root_committed||"").slice(0,24))+'…</div></div>'+
|
| 474 |
+
'<div class="tamper-cell"><div class="tk">chain depth</div><div class="tv">'+esc(cs.depth)+'</div></div>'+
|
| 475 |
+
'</div>';
|
| 476 |
+
}
|
| 477 |
+
|
| 478 |
function renderTamper(key, tt, problem){
|
| 479 |
var box = $("tamper-"+key);
|
| 480 |
if(!tt){ box.innerHTML = '<div class="empty">— no tamper data —</div>'; return false; }
|
|
|
|
| 554 |
var anim = renderTimeline(key, d.timeline, true);
|
| 555 |
// catch tree
|
| 556 |
renderCatchTree(key, d.catch_tree, d.first_failing_node);
|
| 557 |
+
// live-run chain self-verification (this run's OWN chain, intact)
|
| 558 |
+
renderChainSelf(key, d.chain_self);
|
| 559 |
// tamper test (always present — the negative test)
|
| 560 |
var caught = renderTamper(key, d.tamper_test, key);
|
| 561 |
// formula panel
|
|
@@ -3086,34 +3086,90 @@ try:
|
|
| 3086 |
"slsa": "SLSA Build Level 2",
|
| 3087 |
})
|
| 3088 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3089 |
@app.post("/api/a11oy/v1/warhacker/launch/{problem}")
|
| 3090 |
@app.post("/v1/warhacker/launch/{problem}")
|
| 3091 |
@app.get("/api/a11oy/v1/warhacker/launch/{problem}")
|
| 3092 |
@app.get("/v1/warhacker/launch/{problem}")
|
| 3093 |
-
async def _wh_launch_sc(problem: str):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3094 |
d = _WH_BY_KEY.get(problem)
|
| 3095 |
-
|
|
|
|
| 3096 |
return _SCJSON({"ok": False, "error": "unknown scenario", "problem": problem}, status_code=404)
|
| 3097 |
-
|
| 3098 |
-
|
| 3099 |
-
|
| 3100 |
-
|
| 3101 |
-
|
| 3102 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3103 |
result = {
|
| 3104 |
"ok": True, "self_contained": True, "capability": d["capability"],
|
| 3105 |
-
"status": "ok", "http_code": 200,
|
| 3106 |
"scenario": {"id": d["id"], "title": d["title"], "proves": d["proves"]},
|
| 3107 |
-
"decision": {"
|
| 3108 |
-
"
|
| 3109 |
-
|
| 3110 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3111 |
"verify_at": "/api/a11oy/v1/receipt/export",
|
| 3112 |
-
"public_key": "/cosign.pub"
|
| 3113 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3114 |
}
|
| 3115 |
# console renders d.organ + d.organ_response; provide neutral, self-contained shapes
|
| 3116 |
-
return _SCJSON({"ok": True, "capability": d["capability"],
|
|
|
|
| 3117 |
"organ": d["capability"], "organ_response": result,
|
| 3118 |
"receipt": result["receipt"]})
|
| 3119 |
|
|
|
|
| 3086 |
"slsa": "SLSA Build Level 2",
|
| 3087 |
})
|
| 3088 |
|
| 3089 |
+
# Map the launch keys to the REAL exhaustive-demo engine keys (the demos
|
| 3090 |
+
# module uses 'cyber_rts' with an underscore).
|
| 3091 |
+
_WH_LAUNCH_TO_DEMO = {"cannonico": "cannonico", "tychee": "tychee",
|
| 3092 |
+
"hangar2apps": "hangar2apps", "cyber-rts": "cyber_rts",
|
| 3093 |
+
"cyber_rts": "cyber_rts", "raven": "raven"}
|
| 3094 |
+
|
| 3095 |
@app.post("/api/a11oy/v1/warhacker/launch/{problem}")
|
| 3096 |
@app.post("/v1/warhacker/launch/{problem}")
|
| 3097 |
@app.get("/api/a11oy/v1/warhacker/launch/{problem}")
|
| 3098 |
@app.get("/v1/warhacker/launch/{problem}")
|
| 3099 |
+
async def _wh_launch_sc(problem: str, request: Request):
|
| 3100 |
+
# ROOT-CAUSE FIX (2026-06-06): the previous self-contained launch handler
|
| 3101 |
+
# returned an IDENTICAL receipt for mode=nominal and mode=tamper (no real
|
| 3102 |
+
# tamper test). It now DELEGATES to the REAL, mode-aware exhaustive-demo
|
| 3103 |
+
# engine (szl_warhacker_demos), which computes STL robustness rho, the
|
| 3104 |
+
# PolyCARP-style geofence, the conformal interval, a SHA-256 Merkle chain
|
| 3105 |
+
# + Rekor-style inclusion proof, and DSSE-signs the breach event with the
|
| 3106 |
+
# in-image ECDSA-P256 key. nominal => AUTHORIZED + rho>=0 + intact chain;
|
| 3107 |
+
# tamper => UNAUTHORIZED + rho<0 + named crossed axis + chain/inclusion
|
| 3108 |
+
# FAIL. Receipt id is a real hash over the real per-run payload, so it
|
| 3109 |
+
# differs every run. Honest by construction.
|
| 3110 |
d = _WH_BY_KEY.get(problem)
|
| 3111 |
+
demo_key = _WH_LAUNCH_TO_DEMO.get(problem)
|
| 3112 |
+
if not d or not demo_key:
|
| 3113 |
return _SCJSON({"ok": False, "error": "unknown scenario", "problem": problem}, status_code=404)
|
| 3114 |
+
# mode from JSON body OR ?mode= query (GET-friendly)
|
| 3115 |
+
mode = None
|
| 3116 |
+
try:
|
| 3117 |
+
_b = await request.json()
|
| 3118 |
+
if isinstance(_b, dict):
|
| 3119 |
+
mode = _b.get("mode")
|
| 3120 |
+
except Exception:
|
| 3121 |
+
mode = None
|
| 3122 |
+
mode = (mode or request.query_params.get("mode") or "nominal").lower()
|
| 3123 |
+
if mode not in ("nominal", "tamper"):
|
| 3124 |
+
mode = "nominal"
|
| 3125 |
+
try:
|
| 3126 |
+
import szl_warhacker_demos as _whd_engine
|
| 3127 |
+
host = {"sign": _a11oy_sign_receipt,
|
| 3128 |
+
"verify": _a11oy_loop_verify if "_a11oy_loop_verify" in dir() else None}
|
| 3129 |
+
run = _whd_engine._DEMOS[demo_key](mode, host)
|
| 3130 |
+
except Exception as _de:
|
| 3131 |
+
return _SCJSON({"ok": False, "error": "engine error: %r" % _de,
|
| 3132 |
+
"problem": problem, "mode": mode}, status_code=500)
|
| 3133 |
+
authorized = bool(run.get("authorized"))
|
| 3134 |
+
ev = run.get("evaluation", {}) or {}
|
| 3135 |
+
sealed = run.get("sealed", {}) or {}
|
| 3136 |
+
# REAL per-run receipt id: hash over the signed envelope PAE + chain hash
|
| 3137 |
+
env = sealed.get("envelope", {}) or {}
|
| 3138 |
+
rid_basis = (str(env.get("_pae_sha256", "")) + "|" + str(sealed.get("chain_hash", ""))
|
| 3139 |
+
+ "|" + str(run.get("mode")) + "|" + str(run.get("decision")))
|
| 3140 |
+
rid = "a11oy-rcpt-" + _wh_hl.sha256(rid_basis.encode()).hexdigest()[:16]
|
| 3141 |
+
gate = "pass" if authorized else "fail"
|
| 3142 |
result = {
|
| 3143 |
"ok": True, "self_contained": True, "capability": d["capability"],
|
| 3144 |
+
"status": "ok", "http_code": 200, "mode": mode,
|
| 3145 |
"scenario": {"id": d["id"], "title": d["title"], "proves": d["proves"]},
|
| 3146 |
+
"decision": {"verdict": run.get("decision"), "authorized": authorized, "gate": gate,
|
| 3147 |
+
"stl_robustness_rho": ev.get("stl_robustness_rho"),
|
| 3148 |
+
"stl_binding_axis": ev.get("stl_binding_axis"),
|
| 3149 |
+
"first_failing_axis": run.get("first_failing_node"),
|
| 3150 |
+
"note": "Lambda is Conjecture 1 \u2014 an advisory score, not a pass/fail oracle. "
|
| 3151 |
+
"The conjunctive GATE is P2 gate-soundness PROVEN."},
|
| 3152 |
+
"real_or_roadmap": run.get("real_or_roadmap"),
|
| 3153 |
+
"headline": run.get("headline"),
|
| 3154 |
+
"chain": {"merkle_root": (run.get("chain", {}) or {}).get("merkle_root")
|
| 3155 |
+
or sealed.get("merkle_root"),
|
| 3156 |
+
"depth": (run.get("chain", {}) or {}).get("depth")},
|
| 3157 |
+
"chain_self_verification": run.get("chain_self"),
|
| 3158 |
+
"tamper_test": run.get("tamper_test"),
|
| 3159 |
+
"receipt": {"receipt_id": rid, "signed": bool(sealed.get("signed")),
|
| 3160 |
"verify_at": "/api/a11oy/v1/receipt/export",
|
| 3161 |
+
"public_key": "/cosign.pub",
|
| 3162 |
+
"dsse": {"payloadType": env.get("payloadType"),
|
| 3163 |
+
"pae_sha256": env.get("_pae_sha256"),
|
| 3164 |
+
"signed": bool(env.get("signed"))}},
|
| 3165 |
+
"timeline": run.get("timeline"),
|
| 3166 |
+
"catch_tree": run.get("catch_tree"),
|
| 3167 |
+
"first_failing_node": run.get("first_failing_node"),
|
| 3168 |
+
"honesty": run.get("honesty"),
|
| 3169 |
}
|
| 3170 |
# console renders d.organ + d.organ_response; provide neutral, self-contained shapes
|
| 3171 |
+
return _SCJSON({"ok": True, "capability": d["capability"], "mode": mode,
|
| 3172 |
+
"authorized": authorized,
|
| 3173 |
"organ": d["capability"], "organ_response": result,
|
| 3174 |
"receipt": result["receipt"]})
|
| 3175 |
|
|
@@ -543,7 +543,8 @@ def _demo_cannonico(mode, host):
|
|
| 543 |
formulas = _cann_formula_panel()
|
| 544 |
|
| 545 |
# TAMPER test: flip one byte in the sealed breach event -> chain + inclusion break
|
| 546 |
-
|
|
|
|
| 547 |
|
| 548 |
return {
|
| 549 |
"ok": True, "problem": "cannonico", "mode": mode,
|
|
@@ -563,6 +564,12 @@ def _demo_cannonico(mode, host):
|
|
| 563 |
"sealed": sealed,
|
| 564 |
"chain": {"depth": len(chain.entries), "merkle_root": chain.root(),
|
| 565 |
"entries": chain.entries},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 566 |
"tamper_test": tamper,
|
| 567 |
"formula_panel": formulas,
|
| 568 |
"honesty": ("Every number is computed in-image at request time: STL robustness rho, the "
|
|
@@ -694,7 +701,8 @@ def _demo_tychee(mode, host):
|
|
| 694 |
for d in digests]
|
| 695 |
first_fail = next((c for c in catch_tree if not c["pass"]), None)
|
| 696 |
|
| 697 |
-
|
|
|
|
| 698 |
return {
|
| 699 |
"ok": True, "problem": "tychee", "mode": mode,
|
| 700 |
"title": "TYCHEE - reusable air-gap satellite GSW deploy stack (UDS bundle + Zarf)",
|
|
@@ -712,6 +720,12 @@ def _demo_tychee(mode, host):
|
|
| 712 |
"catch_tree": catch_tree,
|
| 713 |
"first_failing_node": (first_fail["node"] if first_fail else None),
|
| 714 |
"sealed": signed, "chain": {"depth": len(chain.entries), "entries": chain.entries},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 715 |
"tamper_test": tamper,
|
| 716 |
"formula_panel": [
|
| 717 |
{"formula": "SHA-256 OCI content digest + Merkle bundle root",
|
|
@@ -853,7 +867,8 @@ def _demo_hangar(mode, host):
|
|
| 853 |
|
| 854 |
catch_tree = [{"node": k, "label": name_of[k], "pass": v} for k, v in axis_vals.items()]
|
| 855 |
first_fail = next((c for c in catch_tree if not c["pass"]), None)
|
| 856 |
-
|
|
|
|
| 857 |
return {
|
| 858 |
"ok": True, "problem": "hangar2apps", "mode": mode,
|
| 859 |
"title": "HANGAR2APPS - unified deployment health readiness + auditable workflow",
|
|
@@ -871,6 +886,12 @@ def _demo_hangar(mode, host):
|
|
| 871 |
"timeline": tl.as_list(),
|
| 872 |
"catch_tree": catch_tree, "first_failing_node": (first_fail["node"] if first_fail else None),
|
| 873 |
"sealed": sealed, "chain": {"depth": len(chain.entries), "entries": chain.entries},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 874 |
"tamper_test": tamper,
|
| 875 |
"formula_panel": [
|
| 876 |
{"formula": "Lambda N-axis conjunctive readiness gate", "role": "MR vs NON-DEPLOYABLE",
|
|
@@ -1054,7 +1075,8 @@ def _demo_cyber_rts(mode, host):
|
|
| 1054 |
]
|
| 1055 |
first_fail = next((c for c in catch_tree if not c["pass"]), None)
|
| 1056 |
safe = not collision_risk and not accuracy_warn
|
| 1057 |
-
|
|
|
|
| 1058 |
return {
|
| 1059 |
"ok": True, "problem": "cyber_rts", "mode": mode,
|
| 1060 |
"title": "CYBER RTS - ingest any trajectory/orbit (TLE/OEM) -> operational context",
|
|
@@ -1074,6 +1096,12 @@ def _demo_cyber_rts(mode, host):
|
|
| 1074 |
"timeline": tl.as_list(),
|
| 1075 |
"catch_tree": catch_tree, "first_failing_node": (first_fail["node"] if first_fail else None),
|
| 1076 |
"sealed": sealed, "chain": {"depth": len(chain.entries), "entries": chain.entries},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1077 |
"tamper_test": tamper,
|
| 1078 |
"formula_panel": [
|
| 1079 |
{"formula": "SGP4 mean-element propagation", "role": "TLE -> ECI state vector",
|
|
@@ -1197,7 +1225,8 @@ def _demo_raven(mode, host):
|
|
| 1197 |
{"node": "mission_authorized", "label": "workload authorized for this node's mission", "pass": mission_authorized},
|
| 1198 |
]
|
| 1199 |
first_fail = next((c for c in catch_tree if not c["pass"]), None)
|
| 1200 |
-
|
|
|
|
| 1201 |
return {
|
| 1202 |
"ok": True, "problem": "raven", "mode": mode,
|
| 1203 |
"title": "RAVEN - deploy + cryptographically authorize a workload at a disconnected edge",
|
|
@@ -1215,6 +1244,12 @@ def _demo_raven(mode, host):
|
|
| 1215 |
"timeline": tl.as_list(),
|
| 1216 |
"catch_tree": catch_tree, "first_failing_node": (first_fail["node"] if first_fail else None),
|
| 1217 |
"sealed": sealed, "chain": {"depth": len(chain.entries), "entries": chain.entries},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1218 |
"tamper_test": tamper,
|
| 1219 |
"formula_panel": [
|
| 1220 |
{"formula": "Keylime TPM 2.0 PCR quote", "role": "hardware root of trust at the edge",
|
|
|
|
| 543 |
formulas = _cann_formula_panel()
|
| 544 |
|
| 545 |
# TAMPER test: flip one byte in the sealed breach event -> chain + inclusion break
|
| 546 |
+
chain_self = chain.verify() # NO tamper: the live run's own chain, proven intact
|
| 547 |
+
tamper = chain.verify(tamper_seq=0) # explicit negative test: flip 1 byte -> break
|
| 548 |
|
| 549 |
return {
|
| 550 |
"ok": True, "problem": "cannonico", "mode": mode,
|
|
|
|
| 564 |
"sealed": sealed,
|
| 565 |
"chain": {"depth": len(chain.entries), "merkle_root": chain.root(),
|
| 566 |
"entries": chain.entries},
|
| 567 |
+
"chain_self": {"chain_intact": chain_self["chain_intact"],
|
| 568 |
+
"merkle_root_committed": chain_self["merkle_root_committed"],
|
| 569 |
+
"merkle_root_matches": chain_self["merkle_root_matches"],
|
| 570 |
+
"depth": chain_self["depth"],
|
| 571 |
+
"note": "The live run's own signed chain, re-verified with NO tampering: "
|
| 572 |
+
"intact. The 'tamper_test' below is the always-on negative test."},
|
| 573 |
"tamper_test": tamper,
|
| 574 |
"formula_panel": formulas,
|
| 575 |
"honesty": ("Every number is computed in-image at request time: STL robustness rho, the "
|
|
|
|
| 701 |
for d in digests]
|
| 702 |
first_fail = next((c for c in catch_tree if not c["pass"]), None)
|
| 703 |
|
| 704 |
+
chain_self = chain.verify() # NO tamper: the live run's own chain, proven intact
|
| 705 |
+
tamper = chain.verify(tamper_seq=0) # explicit negative test: flip 1 byte -> break
|
| 706 |
return {
|
| 707 |
"ok": True, "problem": "tychee", "mode": mode,
|
| 708 |
"title": "TYCHEE - reusable air-gap satellite GSW deploy stack (UDS bundle + Zarf)",
|
|
|
|
| 720 |
"catch_tree": catch_tree,
|
| 721 |
"first_failing_node": (first_fail["node"] if first_fail else None),
|
| 722 |
"sealed": signed, "chain": {"depth": len(chain.entries), "entries": chain.entries},
|
| 723 |
+
"chain_self": {"chain_intact": chain_self["chain_intact"],
|
| 724 |
+
"merkle_root_committed": chain_self["merkle_root_committed"],
|
| 725 |
+
"merkle_root_matches": chain_self["merkle_root_matches"],
|
| 726 |
+
"depth": chain_self["depth"],
|
| 727 |
+
"note": "The live run's own signed chain, re-verified with NO tampering: "
|
| 728 |
+
"intact. The 'tamper_test' below is the always-on negative test."},
|
| 729 |
"tamper_test": tamper,
|
| 730 |
"formula_panel": [
|
| 731 |
{"formula": "SHA-256 OCI content digest + Merkle bundle root",
|
|
|
|
| 867 |
|
| 868 |
catch_tree = [{"node": k, "label": name_of[k], "pass": v} for k, v in axis_vals.items()]
|
| 869 |
first_fail = next((c for c in catch_tree if not c["pass"]), None)
|
| 870 |
+
chain_self = chain.verify() # NO tamper: the live run's own chain, proven intact
|
| 871 |
+
tamper = chain.verify(tamper_seq=0) # explicit negative test: flip 1 byte -> break
|
| 872 |
return {
|
| 873 |
"ok": True, "problem": "hangar2apps", "mode": mode,
|
| 874 |
"title": "HANGAR2APPS - unified deployment health readiness + auditable workflow",
|
|
|
|
| 886 |
"timeline": tl.as_list(),
|
| 887 |
"catch_tree": catch_tree, "first_failing_node": (first_fail["node"] if first_fail else None),
|
| 888 |
"sealed": sealed, "chain": {"depth": len(chain.entries), "entries": chain.entries},
|
| 889 |
+
"chain_self": {"chain_intact": chain_self["chain_intact"],
|
| 890 |
+
"merkle_root_committed": chain_self["merkle_root_committed"],
|
| 891 |
+
"merkle_root_matches": chain_self["merkle_root_matches"],
|
| 892 |
+
"depth": chain_self["depth"],
|
| 893 |
+
"note": "The live run's own signed chain, re-verified with NO tampering: "
|
| 894 |
+
"intact. The 'tamper_test' below is the always-on negative test."},
|
| 895 |
"tamper_test": tamper,
|
| 896 |
"formula_panel": [
|
| 897 |
{"formula": "Lambda N-axis conjunctive readiness gate", "role": "MR vs NON-DEPLOYABLE",
|
|
|
|
| 1075 |
]
|
| 1076 |
first_fail = next((c for c in catch_tree if not c["pass"]), None)
|
| 1077 |
safe = not collision_risk and not accuracy_warn
|
| 1078 |
+
chain_self = chain.verify() # NO tamper: the live run's own chain, proven intact
|
| 1079 |
+
tamper = chain.verify(tamper_seq=0) # explicit negative test: flip 1 byte -> break
|
| 1080 |
return {
|
| 1081 |
"ok": True, "problem": "cyber_rts", "mode": mode,
|
| 1082 |
"title": "CYBER RTS - ingest any trajectory/orbit (TLE/OEM) -> operational context",
|
|
|
|
| 1096 |
"timeline": tl.as_list(),
|
| 1097 |
"catch_tree": catch_tree, "first_failing_node": (first_fail["node"] if first_fail else None),
|
| 1098 |
"sealed": sealed, "chain": {"depth": len(chain.entries), "entries": chain.entries},
|
| 1099 |
+
"chain_self": {"chain_intact": chain_self["chain_intact"],
|
| 1100 |
+
"merkle_root_committed": chain_self["merkle_root_committed"],
|
| 1101 |
+
"merkle_root_matches": chain_self["merkle_root_matches"],
|
| 1102 |
+
"depth": chain_self["depth"],
|
| 1103 |
+
"note": "The live run's own signed chain, re-verified with NO tampering: "
|
| 1104 |
+
"intact. The 'tamper_test' below is the always-on negative test."},
|
| 1105 |
"tamper_test": tamper,
|
| 1106 |
"formula_panel": [
|
| 1107 |
{"formula": "SGP4 mean-element propagation", "role": "TLE -> ECI state vector",
|
|
|
|
| 1225 |
{"node": "mission_authorized", "label": "workload authorized for this node's mission", "pass": mission_authorized},
|
| 1226 |
]
|
| 1227 |
first_fail = next((c for c in catch_tree if not c["pass"]), None)
|
| 1228 |
+
chain_self = chain.verify() # NO tamper: the live run's own chain, proven intact
|
| 1229 |
+
tamper = chain.verify(tamper_seq=0) # explicit negative test: flip 1 byte -> break
|
| 1230 |
return {
|
| 1231 |
"ok": True, "problem": "raven", "mode": mode,
|
| 1232 |
"title": "RAVEN - deploy + cryptographically authorize a workload at a disconnected edge",
|
|
|
|
| 1244 |
"timeline": tl.as_list(),
|
| 1245 |
"catch_tree": catch_tree, "first_failing_node": (first_fail["node"] if first_fail else None),
|
| 1246 |
"sealed": sealed, "chain": {"depth": len(chain.entries), "entries": chain.entries},
|
| 1247 |
+
"chain_self": {"chain_intact": chain_self["chain_intact"],
|
| 1248 |
+
"merkle_root_committed": chain_self["merkle_root_committed"],
|
| 1249 |
+
"merkle_root_matches": chain_self["merkle_root_matches"],
|
| 1250 |
+
"depth": chain_self["depth"],
|
| 1251 |
+
"note": "The live run's own signed chain, re-verified with NO tampering: "
|
| 1252 |
+
"intact. The 'tamper_test' below is the always-on negative test."},
|
| 1253 |
"tamper_test": tamper,
|
| 1254 |
"formula_panel": [
|
| 1255 |
{"formula": "Keylime TPM 2.0 PCR quote", "role": "hardware root of trust at the edge",
|