betterwithage commited on
Commit
be914de
·
verified ·
1 Parent(s): 615f7e5

chore(sync): mirror backend .py + Dockerfile to Space (hf-sync-backend)

Browse files

Automated backend sync from szl-holdings/a11oy main via hf-sync-backend.
Updated (differed from the Space): Dockerfile, serve.py, szl3d_holographic.py, szl_brainlineage.py
Deleted (gone from the repo + Dockerfile COPY set): (none)

Keeps the Space-built backend (serve.py + the Dockerfile-COPY'd .py
modules) identical to GitHub main so the Space never rebuilds from a
stale backend, new endpoints don't 404 there, and orphaned modules
removed from the repo don't linger in the Space tree.

Files changed (4) hide show
  1. Dockerfile +11 -0
  2. serve.py +20 -0
  3. szl3d_holographic.py +1 -0
  4. szl_brainlineage.py +656 -0
Dockerfile CHANGED
@@ -1546,6 +1546,17 @@ COPY szl_brainconsensus.py ./szl_brainconsensus.py
1546
  # brainqueryaudit.js ships via the existing whole-tree `COPY static/3d/ ./static/3d/`
1547
  # above. RECORDS/OBSERVES only — adds NOTHING to the locked-8; Λ = Conjecture 1; trust 0.97.
1548
  COPY szl_brainqueryaudit.py ./szl_brainqueryaudit.py
 
 
 
 
 
 
 
 
 
 
 
1549
 
1550
 
1551
  # WAVE R Dev 1 — boot-resilience env/secret preflight. Per-file COPY (this
 
1546
  # brainqueryaudit.js ships via the existing whole-tree `COPY static/3d/ ./static/3d/`
1547
  # above. RECORDS/OBSERVES only — adds NOTHING to the locked-8; Λ = Conjecture 1; trust 0.97.
1548
  COPY szl_brainqueryaudit.py ./szl_brainqueryaudit.py
1549
+ # BRAIN LINEAGE (feat/frontier-brainlineage) — NODE-ORIGIN lineage over the SAME
1550
+ # honest brain graph: for a node id or a query's top nodes it reports HOW each node
1551
+ # ENTERED the graph, read VERBATIM from the node's OWN real origin fields
1552
+ # (source/url → structural derivation → none) → TRACED/PARTIAL-LINEAGE/UNKNOWN-ORIGIN,
1553
+ # never a fabricated source; POST .../receipt mints an UNSIGNED SHA-256 digest on write.
1554
+ # Its only import (szl_brain_api) is already in the COPY set; its 3D surface
1555
+ # brainlineage.js ships via the whole-tree `COPY static/3d/ ./static/3d/` above.
1556
+ # Node-origin lineage — NOT per-answer provenance, NOT build/model attestation. Adds
1557
+ # NOTHING to the locked-8; Λ = Conjecture 1; trust 0.97.
1558
+ COPY szl_brainlineage.py ./szl_brainlineage.py
1559
+
1560
 
1561
 
1562
  # WAVE R Dev 1 — boot-resilience env/secret preflight. Per-file COPY (this
serve.py CHANGED
@@ -1179,6 +1179,26 @@ except Exception as _brainqueryaudit_e: # pragma: no cover
1179
  print(f"[a11oy] Brain query audit NOT registered: {_brainqueryaudit_e!r}; SPA + API unaffected", file=__import__("sys").stderr)
1180
 
1181
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1182
  # -- BRAIN COMMAND view (Wave O / Dev 5) — the founder's "Brain powering the
1183
  # ecosystem" dashboard. Read-only command rollup over the Brain nervous-system hub:
1184
  # GET /api/a11oy/v1/brain/command → {knowledge harvested, energy harnessed, organs/
 
1179
  print(f"[a11oy] Brain query audit NOT registered: {_brainqueryaudit_e!r}; SPA + API unaffected", file=__import__("sys").stderr)
1180
 
1181
 
1182
+ # -- BRAIN LINEAGE (feat/frontier-brainlineage) — NODE-ORIGIN lineage over the SAME honest
1183
+ # brain graph: GET /api/a11oy/v1/brain/lineage/info (static describe + which real origin fields
1184
+ # it reads), GET /api/a11oy/v1/brain/lineage?id= (origin chain for one node + verdict) or ?q=
1185
+ # (origin chains for a query's top nodes). For each node it reports HOW it ENTERED the graph,
1186
+ # read VERBATIM from the node's OWN real fields (source/url → structural derivation → none) →
1187
+ # TRACED/PARTIAL-LINEAGE/UNKNOWN-ORIGIN. A node with no source field is UNKNOWN-ORIGIN — NEVER a
1188
+ # fabricated source; the aggregate is NEVER TRACED while any origin is UNKNOWN. POST .../lineage/
1189
+ # receipt mints an UNSIGNED SHA-256 content digest on write only (0 sign-on-GET). This is
1190
+ # node-origin lineage (where a fact came from) — NOT per-answer provenance, NOT build/model
1191
+ # attestation, NOT counter-UAS. Reuses szl_brain_api.get_index (invents no node). Adds NOTHING to
1192
+ # the locked-8; Λ stays Conjecture 1. Registered BEFORE the SPA /{full_path:path} catch-all.
1193
+ # Additive, try/except-guarded. szl_brainlineage.py is per-file COPY'd in the Dockerfile.
1194
+ try:
1195
+ import szl_brainlineage as _szl_brainlineage
1196
+ _brainlineage_status = _szl_brainlineage.register(app, ns="a11oy")
1197
+ print(f"[a11oy] Brain lineage registered: {_brainlineage_status}", file=__import__("sys").stderr)
1198
+ except Exception as _brainlineage_e: # pragma: no cover
1199
+ print(f"[a11oy] Brain lineage NOT registered: {_brainlineage_e!r}; SPA + API unaffected", file=__import__("sys").stderr)
1200
+
1201
+
1202
  # -- BRAIN COMMAND view (Wave O / Dev 5) — the founder's "Brain powering the
1203
  # ecosystem" dashboard. Read-only command rollup over the Brain nervous-system hub:
1204
  # GET /api/a11oy/v1/brain/command → {knowledge harvested, energy harnessed, organs/
szl3d_holographic.py CHANGED
@@ -146,6 +146,7 @@ SURFACES: List[Dict[str, str]] = [
146
  {"id": "brainwatch", "cat": "brain", "title": "Brain Watch · knowledge-graph honesty-posture drift monitor · MEASURED label-distribution/orphan/community/salience snapshot vs a caller-supplied PRIOR → STABLE/DRIFTING/DEGRADED/BASELINE-ONLY (no fabricated trend without a real prior), unsigned SHA-256 receipt-on-write", "owner": "WaveT-Dev1"},
147
  {"id": "brainconsensus", "cat": "brain", "title": "Brain Consensus · honest corroboration of a brain grounding · measures how MANY distinct nodes support a query and how many distinct communities they span (cross-community agreement is stronger than one clique) → CORROBORATED/WEAK-CORROBORATION/SINGLE-SOURCE, single-source-risk flag when support collapses to one node/community, never CORROBORATED while that flag is set, MODELED corroboration honesty not a truth guarantee, unsigned SHA-256 receipt-on-write", "owner": "WaveU-Dev1"},
148
  {"id": "brainqueryaudit", "cat": "brain", "title": "Brain Query Audit · append-only hash-linked ledger of brain queries + the honest verdict each returned · POST appends {query, verdict, grounding_label} and mints an UNSIGNED SHA-256 receipt chained to the prior entry (tamper-evident); GET recomputes the whole chain → CHAIN-INTACT/CHAIN-BROKEN (never softened), ephemeral in-memory ledger labelled honestly, MODELED, receipt-on-write-not-on-read", "owner": "WaveT-Dev1"},
 
149
  ]
150
 
151
  # Content-type by extension (the only extensions we serve from the 3d tree).
 
146
  {"id": "brainwatch", "cat": "brain", "title": "Brain Watch · knowledge-graph honesty-posture drift monitor · MEASURED label-distribution/orphan/community/salience snapshot vs a caller-supplied PRIOR → STABLE/DRIFTING/DEGRADED/BASELINE-ONLY (no fabricated trend without a real prior), unsigned SHA-256 receipt-on-write", "owner": "WaveT-Dev1"},
147
  {"id": "brainconsensus", "cat": "brain", "title": "Brain Consensus · honest corroboration of a brain grounding · measures how MANY distinct nodes support a query and how many distinct communities they span (cross-community agreement is stronger than one clique) → CORROBORATED/WEAK-CORROBORATION/SINGLE-SOURCE, single-source-risk flag when support collapses to one node/community, never CORROBORATED while that flag is set, MODELED corroboration honesty not a truth guarantee, unsigned SHA-256 receipt-on-write", "owner": "WaveU-Dev1"},
148
  {"id": "brainqueryaudit", "cat": "brain", "title": "Brain Query Audit · append-only hash-linked ledger of brain queries + the honest verdict each returned · POST appends {query, verdict, grounding_label} and mints an UNSIGNED SHA-256 receipt chained to the prior entry (tamper-evident); GET recomputes the whole chain → CHAIN-INTACT/CHAIN-BROKEN (never softened), ephemeral in-memory ledger labelled honestly, MODELED, receipt-on-write-not-on-read", "owner": "WaveT-Dev1"},
149
+ {"id": "brainlineage", "cat": "brain", "title": "Brain Lineage · node-origin chain · how each knowledge-graph node ENTERED the graph, read VERBATIM from its OWN real origin fields (source/url → structural derivation → none) → TRACED/PARTIAL-LINEAGE/UNKNOWN-ORIGIN, a node with no source is UNKNOWN-ORIGIN never a fabricated source, aggregate never TRACED while any origin UNKNOWN, unsigned SHA-256 receipt-on-write (node-origin lineage, NOT per-answer provenance, NOT build/model attestation)", "owner": "WaveT-Dev1"},
150
  ]
151
 
152
  # Content-type by extension (the only extensions we serve from the 3d tree).
szl_brainlineage.py ADDED
@@ -0,0 +1,656 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # © 2026 Lutar, Stephen P. — SZL Holdings · ORCID 0009-0001-0110-4173 · Doctrine v11 LOCKED
3
+ # Signed-off-by: Stephen Lutar <stephenlutar2@gmail.com>
4
+ """szl_brainlineage.py — NODE-ORIGIN LINEAGE over the honest brain graph.
5
+
6
+ This surface answers ONE honest question about a knowledge-graph node: HOW did
7
+ this node ENTER the graph — what is its harvest/origin metadata chain? It reads
8
+ ONLY the real fields the brain builder (a11oy_brain_graph) actually attached to
9
+ each node and reconstructs an ordered ORIGIN CHAIN from them. When a node carries
10
+ NO origin/source field, it reports origin = UNKNOWN — it NEVER fabricates a source.
11
+
12
+ This is KNOWLEDGE-GRAPH PROVENANCE-OF-NODE-ORIGIN (where did this fact come from),
13
+ and is DISTINCT from szl_brainprovenance (which nodes supported an ANSWER). It is
14
+ STRICTLY knowledge-graph honesty. It is explicitly NOT:
15
+ * cryptographic attestation of a model, weapon, or artifact,
16
+ * SLSA / in-toto / Rekor BUILD provenance of an image or binary,
17
+ * any counter-UAS / targeting / fusion / effector capability.
18
+
19
+ WHAT IT READS (the REAL origin fields, per node, VERBATIM — never invented):
20
+ STRONG (explicit cited source) : source, url
21
+ STRUCTURAL (derivation/harvest) : derived_from, axis, src_layer, ring, org,
22
+ domain, path, organ, formula_id, asset
23
+ WEAK (classification only) : node_label / label, community, kind, layer
24
+ A node's origin is TRACED only from a STRONG field; a STRUCTURAL field yields a
25
+ partial, structural-only chain; WEAK signals alone are not an origin.
26
+
27
+ VERDICT (per node, and aggregated over a query's top nodes):
28
+ TRACED — an explicit cited source (source and/or url) is present;
29
+ the origin chain traces to a real, named source.
30
+ PARTIAL-LINEAGE — no explicit source, but a structural/derivation origin is
31
+ inferable (derived_from / harvest axis / organ / org / …).
32
+ UNKNOWN-ORIGIN — no origin/source field at all; origin = UNKNOWN. NEVER a
33
+ fabricated source.
34
+
35
+ LABEL (this surface's honest read of the origin, per node):
36
+ MODELED — an explicit source exists; the chain is modeled from real
37
+ source/url fields.
38
+ STRUCTURAL-ONLY — only a structural (no explicit source) origin is inferable,
39
+ or the origin is UNKNOWN.
40
+
41
+ RECEIPTS — RECEIPT-ON-WRITE, NOT ON-READ. The GET info/lineage reads mint NOTHING.
42
+ Only POST .../receipt emits an UNSIGNED SHA-256 content digest over the origin
43
+ chain(s) (mirrors the brainprovenance content-digest pattern) — a plain content
44
+ hash, never a fabricated signature, never a receipt on a GET.
45
+
46
+ DOCTRINE v11:
47
+ * Adds NOTHING to the locked-8 {F1,F4,F7,F11,F12,F18,F19,F22}; it only re-reads
48
+ the brain's OWN node fields. Touches no locked formula and no kernel.
49
+ * Λ stays Conjecture 1 (never a theorem); Khipu BFT stays Conjecture 2. Trust
50
+ ceiling 0.97, never 100%. No label is ever upgraded; UNKNOWN is never hidden.
51
+ * Pure stdlib + numpy (numpy import is guarded; a pure-python path is used when
52
+ it is absent). Additive routes, registered before the SPA catch-all. 0 runtime
53
+ CDN.
54
+ """
55
+
56
+ import datetime
57
+ import hashlib
58
+ import json
59
+
60
+ try: # numpy is allowed; keep it optional so a missing wheel degrades honestly.
61
+ import numpy as _np
62
+ _HAVE_NUMPY = True
63
+ except Exception: # pragma: no cover - numpy is a core dep, but stay honest
64
+ _np = None
65
+ _HAVE_NUMPY = False
66
+
67
+ # Honest Doctrine v11 labels (verbatim — never upgraded).
68
+ MODELED = "MODELED" # explicit source => origin chain modeled from real fields
69
+ STRUCTURAL_ONLY = "STRUCTURAL-ONLY" # only structural/no-explicit-source origin inferable
70
+ LBL_UNAVAILABLE = "UNAVAILABLE"
71
+
72
+ # Verdicts.
73
+ TRACED = "TRACED"
74
+ PARTIAL = "PARTIAL-LINEAGE"
75
+ UNKNOWN = "UNKNOWN-ORIGIN"
76
+
77
+ # Origin-field taxonomy — the REAL fields a11oy_brain_graph attaches to nodes.
78
+ # Read VERBATIM; membership here classifies a field, it never fabricates one.
79
+ STRONG_FIELDS = ("source", "url") # explicit cited origin
80
+ STRUCTURAL_FIELDS = ("derived_from", "axis", "src_layer", "ring",
81
+ "org", "domain", "path", "organ", "formula_id", "asset")
82
+ WEAK_FIELDS = ("node_label", "label", "community", "kind", "layer")
83
+
84
+ TRUST_CEILING = 0.97
85
+ LOCKED_SET = ["F1", "F4", "F7", "F11", "F12", "F18", "F19", "F22"]
86
+ LOCKED_COUNT = 8
87
+
88
+ # This surface's own id (must match szl3d_holographic.SURFACES + holographic.html).
89
+ SURFACE_ID = "brainlineage"
90
+
91
+
92
+ def _now_iso() -> str:
93
+ return datetime.datetime.now(datetime.timezone.utc).isoformat()
94
+
95
+
96
+ def _verbatim_label(node: dict) -> str | None:
97
+ """The node's OWN origin-class label VERBATIM (never upgraded). None if absent."""
98
+ v = node.get("node_label")
99
+ if v is None:
100
+ v = node.get("label")
101
+ if isinstance(v, str) and v.strip():
102
+ return v.strip()
103
+ return None
104
+
105
+
106
+ def _clean(value) -> str | None:
107
+ """A present, non-empty scalar rendered as a string; else None (never faked)."""
108
+ if value is None:
109
+ return None
110
+ if isinstance(value, bool):
111
+ return str(value)
112
+ if isinstance(value, (int, float)):
113
+ return str(value)
114
+ if isinstance(value, str):
115
+ s = value.strip()
116
+ return s or None
117
+ # non-scalar (list/dict) — stringify deterministically, never drop silently
118
+ try:
119
+ return json.dumps(value, sort_keys=True, separators=(",", ":"), default=str)
120
+ except Exception: # pragma: no cover
121
+ return str(value)
122
+
123
+
124
+ # --------------------------------------------------------------------------- #
125
+ # Origin chain — ordered steps read from the node's REAL fields (verbatim).
126
+ # --------------------------------------------------------------------------- #
127
+ def build_origin_chain(node: dict) -> list[dict]:
128
+ """Ordered origin steps for a node, each read VERBATIM from a real field.
129
+
130
+ Order: strong (cited source) first, then structural/derivation, then the
131
+ weak classification signals. A field absent from the node produces NO step —
132
+ a missing origin is never back-filled with a fabricated one."""
133
+ chain: list[dict] = []
134
+
135
+ def _step(field: str, tier: str) -> None:
136
+ val = _clean(node.get(field))
137
+ if val is not None:
138
+ chain.append({"field": field, "value": val, "tier": tier})
139
+
140
+ for f in STRONG_FIELDS:
141
+ _step(f, "STRONG")
142
+ for f in STRUCTURAL_FIELDS:
143
+ _step(f, "STRUCTURAL")
144
+ # weak signals: label first (it is the origin CLASS), then community/kind/layer.
145
+ lab = _verbatim_label(node)
146
+ if lab is not None:
147
+ chain.append({"field": "node_label", "value": lab, "tier": "WEAK"})
148
+ for f in ("community", "kind", "layer"):
149
+ val = _clean(node.get(f))
150
+ if val is not None:
151
+ chain.append({"field": f, "value": val, "tier": "WEAK"})
152
+ return chain
153
+
154
+
155
+ def _tier_present(chain: list[dict], tier: str) -> bool:
156
+ return any(s.get("tier") == tier for s in chain)
157
+
158
+
159
+ def classify(chain: list[dict]) -> tuple[str, str, str]:
160
+ """Honest (verdict, label, origin) for ONE node's origin chain.
161
+
162
+ NEVER TRACED without a STRONG (explicit source/url) step; a node with only
163
+ WEAK signals is UNKNOWN-ORIGIN with origin=UNKNOWN — never a fabricated source."""
164
+ has_strong = _tier_present(chain, "STRONG")
165
+ has_structural = _tier_present(chain, "STRUCTURAL")
166
+ if has_strong:
167
+ # the origin is the first STRONG value read verbatim (source, then url).
168
+ origin = next(s["value"] for s in chain if s["tier"] == "STRONG")
169
+ return TRACED, MODELED, origin
170
+ if has_structural:
171
+ origin = next(s["value"] for s in chain if s["tier"] == "STRUCTURAL")
172
+ return PARTIAL, STRUCTURAL_ONLY, origin
173
+ # only weak signals (or nothing): the origin is genuinely untracked.
174
+ return UNKNOWN, STRUCTURAL_ONLY, "UNKNOWN"
175
+
176
+
177
+ def lineage_for_node(node: dict) -> dict:
178
+ """The full origin-lineage record for ONE real node. Pure; fabricates nothing."""
179
+ chain = build_origin_chain(node)
180
+ verdict, label, origin = classify(chain)
181
+ strong = [s for s in chain if s["tier"] == "STRONG"]
182
+ structural = [s for s in chain if s["tier"] == "STRUCTURAL"]
183
+ return {
184
+ "id": node.get("id"),
185
+ "title": node.get("title", node.get("id")),
186
+ "kind": node.get("kind"),
187
+ "layer": node.get("layer"),
188
+ "node_label": _verbatim_label(node), # VERBATIM origin class, may be None
189
+ "community": node.get("community"),
190
+ "origin": origin, # UNKNOWN when untracked, never faked
191
+ "verdict": verdict,
192
+ "label": label,
193
+ "origin_chain": chain,
194
+ "origin_field_count": len(chain),
195
+ "explicit_source_fields": [s["field"] for s in strong],
196
+ "structural_fields": [s["field"] for s in structural],
197
+ "has_explicit_source": bool(strong),
198
+ }
199
+
200
+
201
+ # --------------------------------------------------------------------------- #
202
+ # Aggregate verdict over a query's top nodes (never TRACED while any UNKNOWN).
203
+ # --------------------------------------------------------------------------- #
204
+ def _fraction(part: int, total: int) -> float:
205
+ if not total:
206
+ return 0.0
207
+ if _HAVE_NUMPY:
208
+ return round(float(_np.divide(part, total)), 8)
209
+ return round(part / total, 8)
210
+
211
+
212
+ def aggregate(records: list[dict]) -> dict:
213
+ """Honest roll-up over per-node lineage records.
214
+
215
+ TRACED only if every node is TRACED; UNKNOWN-ORIGIN only if every node is
216
+ UNKNOWN-ORIGIN (or there are no nodes); PARTIAL-LINEAGE otherwise. The verdict
217
+ is NEVER TRACED while any node's origin is UNKNOWN."""
218
+ total = len(records)
219
+ traced = sum(1 for r in records if r["verdict"] == TRACED)
220
+ partial = sum(1 for r in records if r["verdict"] == PARTIAL)
221
+ unknown = sum(1 for r in records if r["verdict"] == UNKNOWN)
222
+ if total == 0:
223
+ verdict, reason = UNKNOWN, "no nodes matched; nothing to trace, no origin fabricated."
224
+ elif traced == total:
225
+ verdict = TRACED
226
+ reason = f"all {total} node(s) carry an explicit cited source; origin fully traced."
227
+ elif unknown == total:
228
+ verdict = UNKNOWN
229
+ reason = f"all {total} node(s) have no origin/source field; origin UNKNOWN (never fabricated)."
230
+ else:
231
+ verdict = PARTIAL
232
+ reason = (f"{traced}/{total} traced to an explicit source, {partial} structural-only, "
233
+ f"{unknown} UNKNOWN-ORIGIN; never TRACED while any origin is UNKNOWN.")
234
+ return {
235
+ "total_nodes": total,
236
+ "traced": traced,
237
+ "partial_lineage": partial,
238
+ "unknown_origin": unknown,
239
+ "fraction_traced": _fraction(traced, total),
240
+ "fraction_unknown_origin": _fraction(unknown, total),
241
+ "verdict": verdict,
242
+ "verdict_reason": reason,
243
+ }
244
+
245
+
246
+ # --------------------------------------------------------------------------- #
247
+ # Brain access — reuse the SAME honest index; invent no node, harvest nothing.
248
+ # --------------------------------------------------------------------------- #
249
+ def _index(ns: str):
250
+ import szl_brain_api as _brain_api
251
+ return _brain_api.get_index(ns)
252
+
253
+
254
+ def _doctrine_block() -> dict:
255
+ return {
256
+ "label_top": MODELED,
257
+ "locked_proven": LOCKED_COUNT,
258
+ "locked_set": LOCKED_SET,
259
+ "adds_to_locked_8": 0,
260
+ "lambda": "Conjecture 1",
261
+ "khipu_bft": "Conjecture 2",
262
+ "trust_ceiling": TRUST_CEILING,
263
+ "trust_100_percent": False,
264
+ "runtime_cdn": 0,
265
+ "note": ("additive NODE-ORIGIN lineage over the brain's own node fields; touches no "
266
+ "locked formula and no kernel; GET reads sign/mint nothing; POST /receipt "
267
+ "emits an UNSIGNED SHA-256 content digest only; introduces no theorem; a node "
268
+ "with no source field reports origin UNKNOWN, never a fabricated source."),
269
+ }
270
+
271
+
272
+ def _lineage_kind() -> str:
273
+ return "NODE-ORIGIN-LINEAGE (knowledge-graph provenance of where a node came from)"
274
+
275
+
276
+ def _not_lineage() -> list:
277
+ return ["per-answer node provenance (that is szl_brainprovenance)",
278
+ "build/SLSA/in-toto/Rekor artifact attestation",
279
+ "cryptographic model/weapon attestation",
280
+ "counter-UAS/targeting/fusion/effector"]
281
+
282
+
283
+ # --------------------------------------------------------------------------- #
284
+ # Lineage assembly (pure computation — mints nothing).
285
+ # --------------------------------------------------------------------------- #
286
+ def build_lineage_by_id(ns: str, node_id: str) -> dict:
287
+ """Origin chain + verdict for ONE node id. Pure read; mints nothing."""
288
+ node_id = (node_id or "").strip()
289
+ base = {
290
+ "label": MODELED,
291
+ "surface_id": SURFACE_ID,
292
+ "endpoint": "brain/lineage",
293
+ "service": "a11oy.brain.lineage",
294
+ "mode": "id",
295
+ "lineage_kind": _lineage_kind(),
296
+ "not_lineage_of": _not_lineage(),
297
+ "doctrine": _doctrine_block(),
298
+ "receipt_policy": "RECEIPT-ON-WRITE-NOT-ON-READ — GET mints nothing; POST /receipt digests.",
299
+ "timestamp_utc": _now_iso(),
300
+ }
301
+ if not node_id:
302
+ return dict(base, ok=False, found=False, id=node_id, verdict=UNKNOWN,
303
+ verdict_reason="empty id; no lookup performed, no origin fabricated.",
304
+ lineage=None)
305
+ try:
306
+ idx = _index(ns)
307
+ except Exception as exc: # never 500 — honest degraded response
308
+ return dict(base, ok=False, found=False, id=node_id, label=LBL_UNAVAILABLE,
309
+ verdict=UNKNOWN,
310
+ verdict_reason=f"brain index unavailable; no origin fabricated: {str(exc)[:160]}",
311
+ lineage=None)
312
+ node = idx.by_id.get(node_id)
313
+ if node is None:
314
+ return dict(base, ok=False, found=False, id=node_id, verdict=UNKNOWN,
315
+ verdict_reason=f"unknown node id {node_id!r}; origin UNKNOWN, never fabricated.",
316
+ lineage=None)
317
+ rec = lineage_for_node(dict(node, community=idx.community_of.get(node_id)))
318
+ return dict(base, ok=True, found=True, id=node_id,
319
+ verdict=rec["verdict"], verdict_reason=(
320
+ f"origin {rec['verdict']}: "
321
+ + ("explicit cited source present"
322
+ if rec["has_explicit_source"]
323
+ else ("structural origin only"
324
+ if rec["verdict"] == PARTIAL
325
+ else "no origin/source field — origin UNKNOWN, never fabricated"))),
326
+ lineage=rec, verdict_legend=_legend())
327
+
328
+
329
+ def build_lineage_by_query(ns: str, q: str, k: int = 10) -> dict:
330
+ """Origin chains + aggregate verdict for a query's top nodes. Pure read."""
331
+ q = (q or "").strip()
332
+ k = max(1, min(int(k) if isinstance(k, (int, float)) else 10, 50))
333
+ base = {
334
+ "label": MODELED,
335
+ "surface_id": SURFACE_ID,
336
+ "endpoint": "brain/lineage",
337
+ "service": "a11oy.brain.lineage",
338
+ "mode": "query",
339
+ "query": q,
340
+ "k": k,
341
+ "lineage_kind": _lineage_kind(),
342
+ "not_lineage_of": _not_lineage(),
343
+ "doctrine": _doctrine_block(),
344
+ "receipt_policy": "RECEIPT-ON-WRITE-NOT-ON-READ — GET mints nothing; POST /receipt digests.",
345
+ "verdict_legend": _legend(),
346
+ "timestamp_utc": _now_iso(),
347
+ }
348
+ if not q:
349
+ agg = aggregate([])
350
+ return dict(base, ok=False, lineages=[], aggregate=agg,
351
+ verdict=agg["verdict"],
352
+ verdict_reason="empty query; no retrieval performed, no origin fabricated.")
353
+ try:
354
+ idx = _index(ns)
355
+ seeds = idx.search(q, k=k)
356
+ except Exception as exc: # never 500 — honest degraded response
357
+ agg = aggregate([])
358
+ return dict(base, ok=False, label=LBL_UNAVAILABLE, lineages=[], aggregate=agg,
359
+ verdict=agg["verdict"],
360
+ verdict_reason=f"brain retrieval unavailable; no origin fabricated: {str(exc)[:160]}")
361
+ records = []
362
+ for s in seeds:
363
+ node = idx.by_id.get(s["id"])
364
+ if node is None:
365
+ continue
366
+ rec = lineage_for_node(dict(node, community=idx.community_of.get(s["id"])))
367
+ rec["retrieval_score"] = s.get("score")
368
+ records.append(rec)
369
+ agg = aggregate(records)
370
+ return dict(base, ok=True, matched_nodes=len(records), lineages=records,
371
+ aggregate=agg, verdict=agg["verdict"], verdict_reason=agg["verdict_reason"])
372
+
373
+
374
+ def _legend() -> dict:
375
+ return {
376
+ TRACED: "explicit cited source (source/url) present; origin traced to a real source",
377
+ PARTIAL: "no explicit source, but a structural/derivation origin is inferable",
378
+ UNKNOWN: "no origin/source field; origin UNKNOWN — never a fabricated source",
379
+ }
380
+
381
+
382
+ # --------------------------------------------------------------------------- #
383
+ # Receipt — UNSIGNED SHA-256 content digest. RECEIPT-ON-WRITE (POST), never a GET.
384
+ # --------------------------------------------------------------------------- #
385
+ def _canonical_core(payload: dict) -> str:
386
+ """Deterministic canonical serialization of the origin content (excludes the
387
+ volatile timestamp), so the digest attests the ORIGIN CHAIN(S) + verdict."""
388
+ def _rec_core(rec: dict) -> dict:
389
+ return {
390
+ "id": rec.get("id"),
391
+ "verdict": rec.get("verdict"),
392
+ "label": rec.get("label"),
393
+ "origin": rec.get("origin"),
394
+ "origin_chain": [{"field": s.get("field"), "value": s.get("value"),
395
+ "tier": s.get("tier")}
396
+ for s in (rec.get("origin_chain") or [])],
397
+ }
398
+ if payload.get("mode") == "id":
399
+ lin = payload.get("lineage")
400
+ core = {"mode": "id", "id": payload.get("id"),
401
+ "verdict": payload.get("verdict"),
402
+ "lineage": _rec_core(lin) if lin else None}
403
+ else:
404
+ core = {"mode": "query", "query": payload.get("query"),
405
+ "verdict": payload.get("verdict"),
406
+ "aggregate": payload.get("aggregate"),
407
+ "lineages": [_rec_core(r) for r in (payload.get("lineages") or [])]}
408
+ return json.dumps(core, sort_keys=True, separators=(",", ":"), default=str)
409
+
410
+
411
+ def content_receipt(payload: dict) -> dict:
412
+ """An UNSIGNED SHA-256 content-digest receipt over the origin lineage."""
413
+ canonical = _canonical_core(payload)
414
+ digest = hashlib.sha256(canonical.encode("utf-8")).hexdigest()
415
+ return {
416
+ "kind": "szl.brainlineage.origin",
417
+ "algorithm": "sha256",
418
+ "content_sha256": digest,
419
+ "signed": False,
420
+ "mode": "UNSIGNED-CONTENT-DIGEST",
421
+ "receipt_on": "write (POST /receipt)",
422
+ "note": ("unsigned SHA-256 content digest of the node-origin lineage; "
423
+ "RECEIPT-ON-WRITE, never on a GET read. No signature fabricated."),
424
+ "computed_at": _now_iso(),
425
+ }
426
+
427
+
428
+ # --------------------------------------------------------------------------- #
429
+ # Handlers.
430
+ # --------------------------------------------------------------------------- #
431
+ def handle_info(ns: str = "a11oy") -> dict:
432
+ """GET .../lineage/info — static self-describing manifest (no compute). PURE READ."""
433
+ base = f"/api/{ns}/v1/brain/lineage"
434
+ return {
435
+ "ok": True,
436
+ "label": MODELED,
437
+ "surface_id": SURFACE_ID,
438
+ "service": "a11oy.brain.lineage",
439
+ "endpoint": "brain/lineage/info",
440
+ "title": "Brain Lineage — how a node entered the knowledge graph",
441
+ "what": ("for a knowledge-graph node (by id, or a query's top nodes) reconstructs the "
442
+ "ORIGIN CHAIN of how it entered the graph — read ONLY from the REAL fields the "
443
+ "brain builder attached — and honestly reports origin UNKNOWN when no source "
444
+ "field exists (never fabricated)."),
445
+ "lineage_kind": _lineage_kind(),
446
+ "distinct_from": ("szl_brainprovenance answers WHICH nodes supported an ANSWER; this "
447
+ "answers WHERE a node itself came from (its harvest/origin metadata)."),
448
+ "explicitly_not": ("This is NODE-ORIGIN lineage of a knowledge-graph node only. It is NOT "
449
+ "per-answer provenance, NOT cryptographic model/weapon attestation, NOT "
450
+ "SLSA/in-toto/Rekor build attestation, and NOT any counter-UAS / "
451
+ "targeting / fusion / effector capability."),
452
+ "origin_fields_read": {
453
+ "strong_explicit_source": list(STRONG_FIELDS),
454
+ "structural_derivation": list(STRUCTURAL_FIELDS),
455
+ "weak_classification": list(WEAK_FIELDS),
456
+ "note": ("read VERBATIM from each node; TRACED requires a STRONG field; a STRUCTURAL "
457
+ "field yields PARTIAL-LINEAGE; WEAK signals alone are UNKNOWN-ORIGIN."),
458
+ },
459
+ "endpoints": {
460
+ "info": f"GET {base}/info",
461
+ "by_id": f"GET {base}?id=",
462
+ "by_query": f"GET {base}?q=&k=",
463
+ "receipt": f"POST {base}/receipt (body: {{\"id\":..}} or {{\"q\":..,\"k\":..}})",
464
+ },
465
+ "verdicts": [TRACED, PARTIAL, UNKNOWN],
466
+ "verdict_legend": _legend(),
467
+ "honest_labels": {
468
+ "labels": [MODELED, STRUCTURAL_ONLY],
469
+ "note": ("MODELED when an explicit source exists; STRUCTURAL-ONLY when only a "
470
+ "structural (no explicit source) origin is inferable or origin is UNKNOWN. "
471
+ "Labels are never upgraded; UNKNOWN is never hidden."),
472
+ },
473
+ "receipt_policy": "RECEIPT-ON-WRITE-NOT-ON-READ — only POST /receipt emits an unsigned SHA-256 digest.",
474
+ "doctrine": _doctrine_block(),
475
+ "numpy_available": _HAVE_NUMPY,
476
+ "timestamp_utc": _now_iso(),
477
+ }
478
+
479
+
480
+ def handle_lineage(ns: str, id: str = "", q: str = "", k: int = 10) -> dict: # noqa: A002
481
+ """GET .../lineage?id= | ?q= — origin chain(s) + verdict. PURE READ (mints nothing).
482
+
483
+ id takes precedence when both are supplied; an empty request is honestly UNKNOWN."""
484
+ if (id or "").strip():
485
+ return build_lineage_by_id(ns, id)
486
+ return build_lineage_by_query(ns, q, k)
487
+
488
+
489
+ def handle_receipt(ns: str, id: str = "", q: str = "", k: int = 10) -> dict: # noqa: A002
490
+ """POST .../lineage/receipt — lineage + an UNSIGNED SHA-256 content digest
491
+ (RECEIPT-ON-WRITE). Never 500s: honest degraded response on error."""
492
+ payload = handle_lineage(ns, id=id, q=q, k=k)
493
+ out = dict(payload)
494
+ out["receipt"] = content_receipt(payload)
495
+ return out
496
+
497
+
498
+ # --------------------------------------------------------------------------- #
499
+ # FastAPI registration.
500
+ # GET info/lineage — normal FastAPI GET handlers (pure reads; mint nothing).
501
+ # POST receipt — raw-Request handler via app.router.add_route (Starlette
502
+ # passes the Request positionally, version-proof under
503
+ # fastapi==0.137.x), with app.add_api_route as the fallback.
504
+ # Registered BEFORE the SPA catch-all by serve.py.
505
+ # --------------------------------------------------------------------------- #
506
+ def register(app, ns: str = "a11oy") -> str:
507
+ from fastapi.responses import JSONResponse
508
+
509
+ base = f"/api/{ns}/v1/brain/lineage"
510
+
511
+ @app.get(f"{base}/info")
512
+ def _brainlineage_info():
513
+ """Static self-describing manifest (pure read; mints nothing)."""
514
+ return JSONResponse(handle_info(ns))
515
+
516
+ @app.get(base)
517
+ def _brainlineage_get(id: str = "", q: str = "", k: int = 10): # noqa: ANN202,A002
518
+ """Origin chain(s) + verdict for a node id or a query (pure read; mints nothing)."""
519
+ payload = handle_lineage(ns, id=id, q=q, k=k)
520
+ if payload.get("mode") == "id" and payload.get("found") is False and (id or "").strip():
521
+ return JSONResponse(payload, status_code=404)
522
+ return JSONResponse(payload)
523
+
524
+ async def _brainlineage_receipt(request):
525
+ """POST: origin lineage + UNSIGNED SHA-256 content digest (RECEIPT-ON-WRITE)."""
526
+ node_id, q, k = "", "", 10
527
+ try:
528
+ body = await request.json()
529
+ if isinstance(body, dict):
530
+ node_id = str(body.get("id", "") or "")
531
+ q = str(body.get("q", body.get("query", "")) or "")
532
+ kv = body.get("k", 10)
533
+ k = int(kv) if isinstance(kv, (int, float, str)) and str(kv).strip() else 10
534
+ except Exception: # noqa: BLE001 — a bodyless/garbled POST still gets an honest answer
535
+ node_id, q, k = "", "", 10
536
+ # Query params override / supplement a missing body.
537
+ try:
538
+ qp = request.query_params
539
+ if not node_id and qp.get("id"):
540
+ node_id = str(qp.get("id"))
541
+ if not q and qp.get("q"):
542
+ q = str(qp.get("q"))
543
+ if qp.get("k"):
544
+ k = int(qp.get("k"))
545
+ except Exception: # noqa: BLE001
546
+ pass
547
+ return JSONResponse(handle_receipt(ns, id=node_id, q=q, k=k))
548
+
549
+ # Annotate the raw-Request handler as fastapi.Request so the add_api_route fallback
550
+ # path treats the param as the request object (0.137.x signature-analysis gotcha).
551
+ try:
552
+ import fastapi as _fastapi
553
+ _brainlineage_receipt.__annotations__["request"] = _fastapi.Request
554
+ except Exception: # noqa: BLE001 — annotation is best-effort only
555
+ pass
556
+
557
+ rcpt_path = f"{base}/receipt"
558
+ add_route = getattr(getattr(app, "router", None), "add_route", None)
559
+ add_api_route = getattr(app, "add_api_route", None)
560
+ try:
561
+ if callable(add_route):
562
+ app.router.add_route(rcpt_path, _brainlineage_receipt, methods=["POST"])
563
+ elif callable(add_api_route):
564
+ app.add_api_route(rcpt_path, _brainlineage_receipt, methods=["POST"])
565
+ else: # pragma: no cover — last-resort Starlette Route append
566
+ from starlette.routing import Route
567
+ app.router.routes.append(Route(rcpt_path, _brainlineage_receipt, methods=["POST"]))
568
+ except Exception as exc: # additive register must never break boot
569
+ print(f"[{ns}] brainlineage receipt POST route NOT wired (guarded): {exc!r}",
570
+ file=__import__("sys").stderr)
571
+ return "brainlineage-wired:2(get-only)"
572
+
573
+ return "brainlineage-wired:3"
574
+
575
+
576
+ # --------------------------------------------------------------------------- #
577
+ # Self-test — origin chain from real fields, UNKNOWN when no source (no
578
+ # fabrication), verdict transitions, deterministic receipt on write, labels
579
+ # never upgraded.
580
+ # --------------------------------------------------------------------------- #
581
+ def _selftest() -> None:
582
+ import sys as _sys
583
+
584
+ print("=" * 72)
585
+ print("szl_brainlineage — self-test (node-origin lineage)")
586
+ print("=" * 72)
587
+
588
+ # 1) A harvested node with an explicit cited source -> TRACED / MODELED.
589
+ # (Λ is Conjecture 1, never a theorem — no proof claim is made here.)
590
+ harvested = {"id": "field:x", "title": "harvested field node", "kind": "field",
591
+ "layer": -1, "label": "HARVESTED", "ring": "field",
592
+ "url": "https://example.org/paper", "source": "brain/harvest/pass2.jsonl",
593
+ "axis": "A"}
594
+ rec = lineage_for_node(harvested)
595
+ assert rec["verdict"] == TRACED, rec["verdict"]
596
+ assert rec["label"] == MODELED, rec["label"]
597
+ assert rec["origin"] == "brain/harvest/pass2.jsonl", rec["origin"]
598
+ assert rec["has_explicit_source"] is True
599
+ assert rec["origin_chain"][0]["tier"] == "STRONG"
600
+ print(f"[1] harvested node TRACED/MODELED, origin={rec['origin']!r} OK")
601
+
602
+ # 2) A structural node (derived_from only, no explicit source) -> PARTIAL / STRUCTURAL-ONLY.
603
+ topic = {"id": "topic:t", "title": "topic", "kind": "topic", "layer": 1,
604
+ "label": "MODELED", "derived_from": "FORMULA_META.organ"}
605
+ tr = lineage_for_node(topic)
606
+ assert tr["verdict"] == PARTIAL, tr["verdict"]
607
+ assert tr["label"] == STRUCTURAL_ONLY, tr["label"]
608
+ assert tr["origin"] == "FORMULA_META.organ"
609
+ assert tr["has_explicit_source"] is False
610
+ print(f"[2] structural node PARTIAL-LINEAGE/STRUCTURAL-ONLY, origin={tr['origin']!r} OK")
611
+
612
+ # 3) A bare node with only weak signals (label + community) -> UNKNOWN-ORIGIN.
613
+ # origin MUST be UNKNOWN — a missing source is NEVER fabricated.
614
+ bare = {"id": "bare:1", "title": "bare", "kind": "misc", "layer": 0,
615
+ "label": "MODELED", "community": "c3"}
616
+ br = lineage_for_node(bare)
617
+ assert br["verdict"] == UNKNOWN, br["verdict"]
618
+ assert br["origin"] == "UNKNOWN", br["origin"]
619
+ assert br["label"] == STRUCTURAL_ONLY
620
+ assert br["has_explicit_source"] is False
621
+ print(f"[3] bare node UNKNOWN-ORIGIN, origin={br['origin']!r} (never fabricated) OK")
622
+
623
+ # 4) Aggregate: never TRACED while any node is UNKNOWN-ORIGIN.
624
+ agg = aggregate([rec, tr, br])
625
+ assert agg["verdict"] == PARTIAL, agg["verdict"]
626
+ assert agg["traced"] == 1 and agg["unknown_origin"] == 1
627
+ all_traced = aggregate([rec, dict(rec, id="field:y")])
628
+ assert all_traced["verdict"] == TRACED
629
+ all_unknown = aggregate([br, dict(br, id="bare:2")])
630
+ assert all_unknown["verdict"] == UNKNOWN
631
+ assert aggregate([])["verdict"] == UNKNOWN
632
+ print(f"[4] aggregate downgrades honestly: mixed=PARTIAL, all-traced=TRACED, "
633
+ f"all-unknown/empty=UNKNOWN-ORIGIN OK")
634
+
635
+ # 5) Receipt: UNSIGNED sha256, deterministic, ignores the volatile timestamp.
636
+ p_id = {"mode": "id", "id": "field:x", "verdict": TRACED, "lineage": rec}
637
+ r1 = content_receipt(p_id)
638
+ r2 = content_receipt(dict(p_id, timestamp_utc="2026-01-01T00:00:00Z"))
639
+ assert r1["signed"] is False and len(r1["content_sha256"]) == 64
640
+ assert r1["content_sha256"] == r2["content_sha256"], "digest ignores timestamp"
641
+ print(f"[5] receipt UNSIGNED sha256={r1['content_sha256'][:16]}… deterministic OK")
642
+
643
+ # 6) doctrine block honest: locked-8 exact, +0, Λ Conjecture 1, trust 0.97 not 100%.
644
+ d = _doctrine_block()
645
+ assert d["locked_proven"] == 8 and d["adds_to_locked_8"] == 0
646
+ assert d["lambda"] == "Conjecture 1" and d["khipu_bft"] == "Conjecture 2"
647
+ assert d["trust_ceiling"] == 0.97 and d["trust_100_percent"] is False
648
+ assert d["runtime_cdn"] == 0
649
+ print("[6] doctrine: locked-8 exact, +0, Λ=Conjecture 1, trust 0.97 (not 100%) OK")
650
+
651
+ print("\nok:true checks:6")
652
+ _sys.exit(0)
653
+
654
+
655
+ if __name__ == "__main__":
656
+ _selftest()