Add killinchu_bridge.py (integrity-stream + cyber quarantine) — staged module, ADDITIVE, NOT auto-wired (Yachay)

#1
killinchu_bridge.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ killinchu_bridge.py — Killinchu side of the Sentra <-> Killinchu cyber bridge.
3
+
4
+ *** PENDING PATCH — NOT PUSHED TO THE KILLINCHU SPACE ***
5
+ This file lives in sentra_killinchu_bridge/pending_patches/ ONLY. The Killinchu
6
+ Space serve.py / killinchu_expansion.py are owned by the in-flight build agent
7
+ `opus_killinchu_drone_flagship_build_mpus8anv`. To avoid a collision we do NOT
8
+ edit those files. The build agent (or a later coordinated commit) applies this
9
+ module additively with the ONE-LINE registration documented in §APPLY below.
10
+
11
+ Adds two endpoints (ADDITIVE, mirrors the existing register_expansion pattern):
12
+ * POST /api/killinchu/v1/integrity-stream
13
+ Emits a Sentra-compatible szl.integrity.event/v1 for a drone integrity
14
+ result, writes a Khipu receipt (kind=integrity.event.cross) with
15
+ flagship_origin + cross_link, and forwards it to the Sentra webhook
16
+ (/api/sentra/v1/drone-cyber/events/ingest). Honest degrade if Sentra down.
17
+ * POST /api/killinchu/v1/quarantine
18
+ Cyber isolation (RTL + link isolation under signed Sentra cert), NEVER
19
+ kinetic, OWN-FLEET ONLY. Re-checks the 2-person Yuyay gate + Lambda floor
20
+ (defence in depth behind Sentra's gate). Honors the legal boundary
21
+ "WE SENSE, WE EVIDENCE" (CFAA / ITAR / Wassenaar).
22
+
23
+ HARD DISCIPLINE:
24
+ * ADDITIVE only; reuses the host app's emit_receipt / lambda_aggregate /
25
+ lambda_floor / signature_placeholder injected via register_killinchu_bridge.
26
+ * Doctrine v11 LOCKED numbers preserved (13-axis yuyay_v3, floor 0.90).
27
+ * DSSE signature PLACEHOLDER until Sigstore CI lands. SLSA L1 (honest).
28
+ * RUWAY is the only ledger writer — we call the injected emit_receipt.
29
+
30
+ — Yachay, 2026-06-01.
31
+
32
+ ============================================================================
33
+ APPLY (one line for the build agent, inside the existing try/except in serve.py,
34
+ right after the register_expansion(...) call):
35
+
36
+ import killinchu_bridge
37
+ killinchu_bridge.register_killinchu_bridge(
38
+ app, drones=_DRONES, emit_receipt=_emit_receipt,
39
+ lambda_aggregate=_lambda_aggregate, lambda_floor=_LAMBDA_FLOOR,
40
+ doctrine=DOCTRINE, json_body=_json_body,
41
+ signature_placeholder=SIGNATURE_PLACEHOLDER,
42
+ sentra_base="https://szlholdings-sentra.hf.space",
43
+ )
44
+ ============================================================================
45
+ """
46
+ from __future__ import annotations
47
+
48
+ import hashlib
49
+ import json
50
+ import urllib.request
51
+ from datetime import datetime, timezone
52
+ from typing import Callable
53
+
54
+ from fastapi import Request
55
+ from fastapi.responses import JSONResponse
56
+
57
+ # Tripwire (T11-T20) -> Sentra signature (DSIG-01..10) + class. Mirrors the
58
+ # 16-sig map in SENTRA_DRONE_CYBER_TAB.md / KILLINCHU_INTEGRITY_EVENT_SCHEMA.md.
59
+ TRIPWIRE_TO_SIG = {
60
+ "T11": ("DSIG-01", "secure-boot-attestation-failure", "tamper"),
61
+ "T12": ("DSIG-02", "firmware-merkle-mismatch", "tamper"),
62
+ "T13": ("DSIG-03", "mavlink-anomaly", "intrusion"),
63
+ "T14": ("DSIG-04", "rf-fingerprint-deviation", "intrusion"),
64
+ "T15": ("DSIG-05", "accelerometer-imu-spoof", "tamper"),
65
+ "T16": ("DSIG-06", "gps-spoof", "intrusion"),
66
+ "T17": ("DSIG-07", "unexpected-ota-attempt", "tamper"),
67
+ "T18": ("DSIG-08", "geofence-violation", "anomaly"),
68
+ "T19": ("DSIG-09", "mission-deviation", "anomaly"),
69
+ "T20": ("DSIG-10", "unauthorized-mavlink-command", "intrusion"),
70
+ }
71
+ OWN_FLEET_SIDES = ("allied", "dual-use", "counter-uas")
72
+
73
+
74
+ def _now() -> str:
75
+ return datetime.now(timezone.utc).isoformat()
76
+
77
+
78
+ def _sha(obj) -> str:
79
+ return hashlib.sha256(
80
+ json.dumps(obj, sort_keys=True, separators=(",", ":")).encode()
81
+ ).hexdigest()
82
+
83
+
84
+ def register_killinchu_bridge(app, *, drones: list, emit_receipt: Callable,
85
+ lambda_aggregate: Callable, lambda_floor: float,
86
+ doctrine: str, json_body: Callable,
87
+ signature_placeholder: str,
88
+ sentra_base: str = "https://szlholdings-sentra.hf.space") -> None:
89
+ """Wire the two bridge endpoints onto the existing FastAPI app (ADDITIVE)."""
90
+
91
+ def _drone_by_id(did: str):
92
+ for d in drones:
93
+ if d.get("id") == did:
94
+ return d
95
+ return None
96
+
97
+ def _build_event(drone: dict, tripwire_id: str, verdict: str,
98
+ lam: float, evidence: dict, prev_hash: str) -> dict:
99
+ sig_id, sig_name, klass = TRIPWIRE_TO_SIG.get(
100
+ tripwire_id, ("", "", "anomaly"))
101
+ body = {
102
+ "schema": "szl.integrity.event/v1",
103
+ "event_id": f"evt_{_now()}_{drone.get('id')}_{tripwire_id}",
104
+ "emitted_at": _now(),
105
+ "flagship_origin": "killinchu",
106
+ "drone": {
107
+ "id": drone.get("id"), "model": drone.get("model", ""),
108
+ "fleet_side": drone.get("side", "allied"),
109
+ },
110
+ "tripwire": {"id": tripwire_id, "name": sig_name, "hukkla": tripwire_id},
111
+ "verdict": verdict,
112
+ "severity": "high" if verdict == "TAMPER-SUSPECTED" else "info",
113
+ "sentra_signature": sig_id,
114
+ "evidence": evidence,
115
+ "lambda": {
116
+ "value": round(lam, 6), "floor": lambda_floor,
117
+ "below_floor": lam < lambda_floor,
118
+ },
119
+ "khipu": {"prev_hash": prev_hash},
120
+ "signature": {
121
+ "mode": "dsse", "value": signature_placeholder,
122
+ "slsa_level": "L1 (honest)",
123
+ },
124
+ }
125
+ body["khipu"]["this_hash"] = "sha256:" + _sha(
126
+ {"e": {k: v for k, v in body.items() if k != "signature"}, "p": prev_hash})
127
+ return body
128
+
129
+ def _forward_to_sentra(event: dict) -> dict:
130
+ """Best-effort POST to the Sentra webhook. Honest degrade on failure."""
131
+ url = sentra_base + "/api/sentra/v1/drone-cyber/events/ingest"
132
+ try:
133
+ data = json.dumps(event).encode()
134
+ req = urllib.request.Request(
135
+ url, data=data, headers={"content-type": "application/json"})
136
+ with urllib.request.urlopen(req, timeout=8.0) as r:
137
+ return {"forwarded": True, "sentra": json.loads(r.read().decode())}
138
+ except Exception as e:
139
+ return {"forwarded": False, "error": str(e),
140
+ "note": "Sentra unreachable — event still receipted locally (honest degrade)."}
141
+
142
+ # ---- Integrity stream webhook (binding b) ----
143
+ @app.api_route("/api/killinchu/v1/integrity-stream", methods=["POST"])
144
+ async def integrity_stream(request: Request):
145
+ """Emit Sentra-compatible szl.integrity.event/v1 for a drone integrity
146
+ result; write a cross Khipu receipt; forward to Sentra."""
147
+ body = await json_body(request)
148
+ did = body.get("drone_id", "")
149
+ drone = _drone_by_id(did)
150
+ if drone is None:
151
+ return JSONResponse({"ok": False, "error": "drone not in fleet",
152
+ "drone_id": did, "doctrine": doctrine}, status_code=404)
153
+ fired = body.get("fired") or []
154
+ verdict = "TAMPER-SUSPECTED" if fired else "ATTESTED-CLEAN"
155
+ axis = body.get("axis_scores") or [0.93] * 13
156
+ lam = lambda_aggregate(axis)
157
+ events = []
158
+ for tid in (fired or ["T11"][:0]): # one event per fired tripwire
159
+ evt = _build_event(
160
+ drone, tid, verdict, lam,
161
+ evidence={"detector": f"szl-sentra-detect/{TRIPWIRE_TO_SIG.get(tid,('','',''))[1]}",
162
+ "raw_ref": f"twin://{did}/tamperFlags/{tid}"},
163
+ prev_hash="")
164
+ rcpt = emit_receipt("integrity.event.cross", {
165
+ "flagship_origin": "killinchu",
166
+ "cross_link": {"to_flagship": "sentra", "event_id": evt["event_id"]},
167
+ "event": evt,
168
+ })
169
+ evt["khipu"]["receipt_id"] = rcpt.get("digest") or rcpt.get("index")
170
+ fwd = _forward_to_sentra(evt)
171
+ events.append({"event": evt, "forward": fwd})
172
+ if not fired:
173
+ # clean scan still gets a receipt (honest, no event forwarded)
174
+ emit_receipt("integrity.event.cross", {
175
+ "flagship_origin": "killinchu", "drone_id": did,
176
+ "verdict": verdict, "fired": []})
177
+ return JSONResponse({
178
+ "ok": True, "drone_id": did, "verdict": verdict,
179
+ "emitted": len(events), "events": events,
180
+ "lambda": round(lam, 6), "lambda_floor": lambda_floor,
181
+ "schema": "szl.integrity.event/v1",
182
+ "signature": signature_placeholder, "slsa_level": "L1 (honest)",
183
+ "doctrine": doctrine,
184
+ "honesty": ("Events forwarded best-effort to Sentra; receipted locally regardless. "
185
+ "Cross-Space durable broker NOT wired — correlation by event_id."),
186
+ })
187
+
188
+ # ---- Cyber quarantine (called by Sentra; defence-in-depth re-check) ----
189
+ @app.api_route("/api/killinchu/v1/quarantine", methods=["POST"])
190
+ async def quarantine(request: Request):
191
+ """Cyber isolation (RTL + link isolation), NEVER kinetic, own-fleet only.
192
+ Re-checks 2-person Yuyay + Lambda floor behind Sentra's gate."""
193
+ body = await json_body(request)
194
+ did = body.get("drone_id", "")
195
+ approvers = sorted(set(a for a in (body.get("approvers") or []) if a))
196
+ drone = _drone_by_id(did)
197
+ # Gate: own-fleet only
198
+ if drone is None:
199
+ return JSONResponse({"ok": False, "decision": "REFUSED",
200
+ "reason": "drone not in fleet", "drone_id": did,
201
+ "kinetic": False, "doctrine": doctrine}, status_code=403)
202
+ if drone.get("side") not in OWN_FLEET_SIDES:
203
+ return JSONResponse({"ok": False, "decision": "REFUSED",
204
+ "reason": ("own-fleet only; cyber isolation never applied to third-party "
205
+ "(WE SENSE, WE EVIDENCE — CFAA/ITAR/Wassenaar)"),
206
+ "drone_id": did, "side": drone.get("side"),
207
+ "kinetic": False, "doctrine": doctrine}, status_code=403)
208
+ # Gate: 2-person
209
+ if len(approvers) < 2:
210
+ return JSONResponse({"ok": False, "decision": "BLOCKED",
211
+ "reason": "2-person Yuyay gate requires >=2 distinct approvers",
212
+ "kinetic": False, "doctrine": doctrine}, status_code=412)
213
+ # Gate: Lambda floor
214
+ axis = body.get("axis_scores") or [0.93] * 13
215
+ lam = lambda_aggregate(axis)
216
+ if lam < lambda_floor:
217
+ rcpt = emit_receipt("quarantine.halted", {
218
+ "drone_id": did, "lambda": round(lam, 6), "reason": "below Λ floor"})
219
+ return JSONResponse({"ok": False, "decision": "HALT",
220
+ "reason": f"Λ={lam:.4f} < floor {lambda_floor}", "drone_id": did,
221
+ "kinetic": False, "khipu_digest": rcpt.get("digest"),
222
+ "signature": signature_placeholder, "doctrine": doctrine}, status_code=409)
223
+ # Cleared — cyber isolation
224
+ cert_sha = _sha({"drone": did, "approvers": approvers, "ts": _now(),
225
+ "cert": body.get("sentra_cert_sha256", "")})
226
+ rcpt = emit_receipt("quarantine.executed", {
227
+ "flagship_origin": "killinchu",
228
+ "cross_link": {"to_flagship": "sentra", "drone_id": did},
229
+ "drone_id": did, "approvers": approvers, "drone_state": "RTL",
230
+ "isolation": "command+telemetry links isolated under signed Sentra cert",
231
+ "lambda": round(lam, 6), "kinetic": False})
232
+ return JSONResponse({
233
+ "ok": True, "decision": "QUARANTINED", "drone_id": did,
234
+ "drone_state": "RTL",
235
+ "isolation": "command+telemetry links isolated under signed Sentra cert",
236
+ "kinetic": False, "approvers": approvers,
237
+ "killinchu_cert_sha256": cert_sha,
238
+ "lambda": round(lam, 6), "lambda_floor": lambda_floor,
239
+ "khipu_digest": rcpt.get("digest"),
240
+ "signature": signature_placeholder, "slsa_level": "L1 (honest)",
241
+ "doctrine": doctrine,
242
+ "honesty": ("Cyber isolation only (RTL + link isolation), NOT kinetic, own-fleet only. "
243
+ "Defence-in-depth re-check behind Sentra's 2-person Yuyay gate. DSSE PLACEHOLDER."),
244
+ })
killinchu_bridge_patch_meta/README.md ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # pending_patches/ — collision-safe, NOT pushed to HF
2
+
3
+ **Why this exists:** the Killinchu Space (`SZLHOLDINGS/killinchu`) `serve.py` and
4
+ `killinchu_expansion.py` are owned by the in-flight build agent
5
+ `opus_killinchu_drone_flagship_build_mpus8anv`. To honor the HARD RULE *"collision risk → write
6
+ to pending_patches/, DO NOT push that one"*, the Killinchu-side bridge module is staged here and
7
+ was **NOT** pushed to the Space.
8
+
9
+ ## File
10
+
11
+ - `killinchu_bridge.py` — adds `POST /api/killinchu/v1/integrity-stream` (binding b webhook,
12
+ emits Sentra-compatible `szl.integrity.event/v1` + cross Khipu receipt + forwards to Sentra)
13
+ and `POST /api/killinchu/v1/quarantine` (cyber isolation, NOT kinetic, own-fleet only,
14
+ 2-person Yuyay + Λ floor re-check). Validated: parses + registers both routes against a stub
15
+ app.
16
+
17
+ ## How the build agent applies it (one-line, additive)
18
+
19
+ Add the file to the Killinchu Space repo and, inside the existing `try/except` in `serve.py`
20
+ right after the `killinchu_expansion.register_expansion(...)` call, add:
21
+
22
+ ```python
23
+ import killinchu_bridge
24
+ killinchu_bridge.register_killinchu_bridge(
25
+ app, drones=_DRONES, emit_receipt=_emit_receipt,
26
+ lambda_aggregate=_lambda_aggregate, lambda_floor=_LAMBDA_FLOOR,
27
+ doctrine=DOCTRINE, json_body=_json_body,
28
+ signature_placeholder=SIGNATURE_PLACEHOLDER,
29
+ sentra_base="https://szlholdings-sentra.hf.space",
30
+ )
31
+ ```
32
+
33
+ The injected dependencies (`_DRONES`, `_emit_receipt`, `_lambda_aggregate`, `_LAMBDA_FLOOR`,
34
+ `DOCTRINE`, `_json_body`, `SIGNATURE_PLACEHOLDER`) are the same ones already passed to
35
+ `register_expansion` — verified present in the live `serve.py`. No existing endpoint, receipt
36
+ schema, or Doctrine v11 LOCKED number is changed. ADDITIVE only.
37
+
38
+ ## Bridge status while pending
39
+
40
+ The **Sentra side is LIVE and self-sufficient**: `/drone-cyber` and
41
+ `/api/sentra/v1/drone-cyber/*` pull the Killinchu fleet directly from the existing live Killinchu
42
+ endpoints (`/drones/database`, `/drones/{id}/twin`, `/drones/{id}/integrity`,
43
+ `/receipt/ledger`). The unified SOC pane is demoable **today** without this Killinchu patch.
44
+
45
+ What this patch *adds* once applied: Killinchu **push** of integrity events to Sentra (vs the
46
+ current Sentra **pull**), and a first-class `/v1/quarantine` defence-in-depth re-check endpoint.
47
+ Until then, Sentra's quarantine endpoint runs the full gate itself (own-fleet check via live
48
+ `/drones/database`, 2-person, cross-flagship Λ) and records the cyber-isolation receipt.
49
+
50
+ — Yachay, 2026-06-01. Collision-safe. NOT pushed. ADDITIVE when applied. v11 LOCKED preserved.