betterwithage commited on
Commit
7ba37da
·
verified ·
1 Parent(s): 32e4f58

feat: chain Council proposals into Khipu

Browse files

Adds a best-effort in-process Khipu receipt so freshly issued Council evidence can pass signature, payload-digest, and hash-chain verification. Persistence remains explicitly in-memory and resets on restart.

Files changed (2) hide show
  1. a11oy_ayllu.py +37 -0
  2. test/test_council_contract.py +2 -0
a11oy_ayllu.py CHANGED
@@ -174,6 +174,7 @@ def council_manifest(ns: str = "a11oy") -> Dict[str, Any]:
174
  "persona/model/round/output digest per turn",
175
  "Nemo governed-route decision and DSSE receipt",
176
  "deterministic replay key over participants, mode, and output digests",
 
177
  "outer Council DSSE receipt",
178
  ],
179
  "limits": {
@@ -184,6 +185,7 @@ def council_manifest(ns: str = "a11oy") -> Dict[str, Any]:
184
  "effectors": "none",
185
  "decision_state": "PROPOSAL_ONLY",
186
  "semantic_consensus": "NOT_MEASURED",
 
187
  },
188
  "reproduce": {
189
  "manifest": base + "/council/manifest",
@@ -318,6 +320,38 @@ def _build_council_contract(prompt: str, result: Dict[str, Any],
318
  }
319
 
320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  # --- The /ayllu page: a working chat + council UI. 0-CDN (pure inline markup, no
322
  # external assets). `__NS__`/`__VERSION__` are substituted at render time so the
323
  # JS+CSS braces stay literal (no f-string brace-doubling). --------------------
@@ -800,6 +834,7 @@ def register(app, ns: str = "a11oy") -> str:
800
  signer = _runtime_signer(request)
801
  nemo_route = _nemo_council_route(prompt, sign_fn=signer)
802
  contract = _build_council_contract(prompt, result, nemo_route)
 
803
  receipt_body = {
804
  "council_id": council_id,
805
  "prompt_sha256": hashlib.sha256(prompt.encode()).hexdigest(),
@@ -813,11 +848,13 @@ def register(app, ns: str = "a11oy") -> str:
813
  "nemo_route_receipt_sha256": _receipt_sha(
814
  (contract.get("routing") or {}).get("receipt")),
815
  "human_checkpoint": contract["human_checkpoint"],
 
816
  }
817
  receipt = _make_receipt({
818
  "schema": "szl.ayllu.council-receipt/v2",
819
  "body": receipt_body,
820
  "payload_digest": _sha256_json(receipt_body),
 
821
  }, sign_fn=signer)
822
  return JSONResponse({"council_id": council_id, "result": result,
823
  "contract": contract, "receipt": receipt})
 
174
  "persona/model/round/output digest per turn",
175
  "Nemo governed-route decision and DSSE receipt",
176
  "deterministic replay key over participants, mode, and output digests",
177
+ "in-process Khipu chain receipt (resets on process restart)",
178
  "outer Council DSSE receipt",
179
  ],
180
  "limits": {
 
185
  "effectors": "none",
186
  "decision_state": "PROPOSAL_ONLY",
187
  "semantic_consensus": "NOT_MEASURED",
188
+ "chain_persistence": "IN_MEMORY_RESETS_ON_RESTART",
189
  },
190
  "reproduce": {
191
  "manifest": base + "/council/manifest",
 
320
  }
321
 
322
 
323
+ def _mint_council_chain(contract: Dict[str, Any], ns: str = "a11oy") -> Dict[str, Any]:
324
+ """Append the proposal receipt to the shared in-process Khipu chain."""
325
+ try:
326
+ import szl_khipu
327
+ dag = szl_khipu.get_dag("ayllu_council", ns=ns)
328
+ receipt = dag.emit("ayllu.council.proposal", {
329
+ "contract_version": contract.get("contract_version"),
330
+ "decision_state": contract.get("decision_state"),
331
+ "evidence_state": contract.get("evidence_state"),
332
+ "prompt_sha256": contract.get("prompt_sha256"),
333
+ "replay_key": (contract.get("replay") or {}).get("key"),
334
+ })
335
+ chain = dag.verify_chain()
336
+ return {
337
+ "state": "LIVE",
338
+ "organ": "ayllu_council",
339
+ "receipt_id": receipt.get("digest"),
340
+ "seq": receipt.get("seq"),
341
+ "chain_verified": bool(chain.get("ok")),
342
+ "depth": dag.depth(),
343
+ "persistence": "IN_MEMORY_RESETS_ON_RESTART",
344
+ }
345
+ except Exception as exc:
346
+ return {
347
+ "state": "UNAVAILABLE",
348
+ "organ": "ayllu_council",
349
+ "receipt_id": None,
350
+ "error": type(exc).__name__,
351
+ "honesty": "Khipu append unavailable; no chain receipt fabricated.",
352
+ }
353
+
354
+
355
  # --- The /ayllu page: a working chat + council UI. 0-CDN (pure inline markup, no
356
  # external assets). `__NS__`/`__VERSION__` are substituted at render time so the
357
  # JS+CSS braces stay literal (no f-string brace-doubling). --------------------
 
834
  signer = _runtime_signer(request)
835
  nemo_route = _nemo_council_route(prompt, sign_fn=signer)
836
  contract = _build_council_contract(prompt, result, nemo_route)
837
+ contract["chain"] = _mint_council_chain(contract, ns=ns)
838
  receipt_body = {
839
  "council_id": council_id,
840
  "prompt_sha256": hashlib.sha256(prompt.encode()).hexdigest(),
 
848
  "nemo_route_receipt_sha256": _receipt_sha(
849
  (contract.get("routing") or {}).get("receipt")),
850
  "human_checkpoint": contract["human_checkpoint"],
851
+ "chain": contract["chain"],
852
  }
853
  receipt = _make_receipt({
854
  "schema": "szl.ayllu.council-receipt/v2",
855
  "body": receipt_body,
856
  "payload_digest": _sha256_json(receipt_body),
857
+ "receipt_id": contract["chain"].get("receipt_id"),
858
  }, sign_fn=signer)
859
  return JSONResponse({"council_id": council_id, "result": result,
860
  "contract": contract, "receipt": receipt})
test/test_council_contract.py CHANGED
@@ -74,6 +74,8 @@ class CouncilContractTests(unittest.TestCase):
74
  self.assertEqual(body["contract"]["decision_state"], "PROPOSAL_ONLY")
75
  self.assertTrue(body["receipt"]["signed"])
76
  self.assertEqual(body["contract"]["routing"]["state"], "HEURISTIC")
 
 
77
 
78
 
79
  if __name__ == "__main__":
 
74
  self.assertEqual(body["contract"]["decision_state"], "PROPOSAL_ONLY")
75
  self.assertTrue(body["receipt"]["signed"])
76
  self.assertEqual(body["contract"]["routing"]["state"], "HEURISTIC")
77
+ self.assertEqual(body["contract"]["chain"]["state"], "LIVE")
78
+ self.assertTrue(body["contract"]["chain"]["chain_verified"])
79
 
80
 
81
  if __name__ == "__main__":