betterwithage Claude Opus 4.7 commited on
Commit
c18b71e
·
verified ·
1 Parent(s): 2617224

deploy(hf): sync szl-holdings/a11oy@3eea2d39482790e50919b1c168bb4c5fa1334592 derived COPY set

Browse files

Reusable Dockerfile-COPY-derived deploy from szl-holdings/a11oy 3eea2d39482790e50919b1c168bb4c5fa1334592.
Files: 1297 Pruned: 0
Derived from Dockerfile COPY sources (NO hand-maintained allowlist).

Signed-off-by: SZL Holdings <noreply@szlholdings.ai>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

Dockerfile CHANGED
@@ -674,6 +674,8 @@ COPY a11oy_ayllu_wall.py ./a11oy_ayllu_wall.py
674
  # Packet 8 Decision Integrity desk on a-11-oy.com (GET /decision).
675
  # Frozen evals. Formula authority NONE. Status ROADMAP. Does not stamp LIVE.
676
  COPY a11oy_decision_integrity.py ./
 
 
677
  COPY verticals/_kernel/a11oy_kernel.py ./verticals/_kernel/a11oy_kernel.py
678
  COPY verticals/PACKET8.json ./verticals/PACKET8.json
679
  COPY verticals/terra ./verticals/terra
 
674
  # Packet 8 Decision Integrity desk on a-11-oy.com (GET /decision).
675
  # Frozen evals. Formula authority NONE. Status ROADMAP. Does not stamp LIVE.
676
  COPY a11oy_decision_integrity.py ./
677
+ # Bound-path Command Center SPA on a-11-oy.com/command. Does not steal /console.
678
+ COPY a11oy_command_center.py ./a11oy_command_center.py
679
  COPY verticals/_kernel/a11oy_kernel.py ./verticals/_kernel/a11oy_kernel.py
680
  COPY verticals/PACKET8.json ./verticals/PACKET8.json
681
  COPY verticals/terra ./verticals/terra
a11oy_canonical_domain.py CHANGED
@@ -64,7 +64,7 @@ FORBIDDEN_PUBLIC_HOST = "a11oy.com"
64
 
65
  # HTML document paths crawlers and monitors probe with HEAD. GET-only FastAPI
66
  # routes 405 on HEAD; /verify and /ecosystem already declare GET+HEAD and 200.
67
- HTML_DOCUMENT_HEAD_PATHS = ("/", "/console", "/trust", "/assurance", "/robots.txt")
68
  # QHAPAQ S1–S12 MEASURED 2026-08-28 13:05–13:12 ET: GET 200 / HEAD 405 on
69
  # /healthz /readyz /api/health; GET 200 / HEAD 404 on /api/a11oy/healthz and
70
  # /api/a11oy/v1/health (HEAD fell through to the /api/a11oy/{path} proxy).
 
64
 
65
  # HTML document paths crawlers and monitors probe with HEAD. GET-only FastAPI
66
  # routes 405 on HEAD; /verify and /ecosystem already declare GET+HEAD and 200.
67
+ HTML_DOCUMENT_HEAD_PATHS = ("/", "/console", "/command", "/trust", "/assurance", "/robots.txt")
68
  # QHAPAQ S1–S12 MEASURED 2026-08-28 13:05–13:12 ET: GET 200 / HEAD 405 on
69
  # /healthz /readyz /api/health; GET 200 / HEAD 404 on /api/a11oy/healthz and
70
  # /api/a11oy/v1/health (HEAD fell through to the /api/a11oy/{path} proxy).
a11oy_command_center.py ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ # SPDX-License-Identifier: Apache-2.0
3
+ # (c) 2026 Lutar, Stephen P. - SZL Holdings - ORCID 0009-0001-0110-4173
4
+ """Serve the public Command Center SPA as a bound path on the product origin.
5
+
6
+ Product host: a-11-oy.com (this surface)
7
+ Proof host: a11oy.net (do not serve this surface there)
8
+
9
+ Bound path only. Does not edit the landing door (Products / Catalog / Proof).
10
+ Does not steal existing /console (Python operator runtime). Mounts:
11
+
12
+ GET+HEAD /command
13
+ GET+HEAD /command/{rest}
14
+
15
+ /command-center is 307'd onto /command by serve.py. Read-path only.
16
+ """
17
+ from pathlib import Path
18
+ from typing import List
19
+
20
+ SPA_NAME = "command-center.html"
21
+ MOUNTS = ("/command",)
22
+
23
+
24
+ def _spa_path() -> Path:
25
+ here = Path(__file__).resolve().parent
26
+ for cand in (
27
+ here / "pages" / SPA_NAME,
28
+ Path("/app/pages") / SPA_NAME,
29
+ here / SPA_NAME,
30
+ ):
31
+ if cand.is_file():
32
+ return cand
33
+ return here / "pages" / SPA_NAME
34
+
35
+
36
+ def _existing_paths(app) -> set:
37
+ try:
38
+ router = getattr(app, "router", app)
39
+ return {getattr(r, "path", None) for r in getattr(router, "routes", [])}
40
+ except Exception:
41
+ return set()
42
+
43
+
44
+ def _front_move(app, paths: set) -> None:
45
+ router = getattr(app, "router", app)
46
+ routes = getattr(router, "routes", None)
47
+ if not routes:
48
+ return
49
+ chosen = [r for r in routes if getattr(r, "path", None) in paths]
50
+ if not chosen:
51
+ return
52
+ for r in chosen:
53
+ try:
54
+ routes.remove(r)
55
+ except ValueError:
56
+ pass
57
+ for r in reversed(chosen):
58
+ routes.insert(0, r)
59
+
60
+
61
+ def register(app, ns: str = "a11oy") -> List[str]:
62
+ """Mount the Command Center SPA. Additive; skips paths already registered."""
63
+ del ns # surface is host-level, not namespaced
64
+ spa = _spa_path()
65
+ registered: List[str] = []
66
+ if not spa.is_file():
67
+ return [f"command-center SPA missing at {spa}"]
68
+
69
+ from starlette.responses import FileResponse
70
+ from starlette.routing import Route
71
+
72
+ async def _spa(_request=None, rest: str = ""):
73
+ return FileResponse(spa, media_type="text/html; charset=utf-8")
74
+
75
+ existing = _existing_paths(app)
76
+ mounted: set = set()
77
+ router = getattr(app, "router", app)
78
+
79
+ def _add(path: str, handler, methods: List[str]) -> None:
80
+ if path in existing and path != "/command/{rest:path}":
81
+ registered.append("%s already registered (skipped)" % path)
82
+ return
83
+ try:
84
+ router.routes.insert(0, Route(path, handler, methods=methods))
85
+ except Exception:
86
+ app.add_api_route(path, handler, methods=methods, include_in_schema=False)
87
+ existing.add(path)
88
+ mounted.add(path)
89
+ registered.append("GET+HEAD %s" % path)
90
+
91
+ for path in MOUNTS:
92
+ _add(path, _spa, ["GET", "HEAD"])
93
+ _add("/command/{rest:path}", _spa, ["GET", "HEAD"])
94
+ _front_move(app, mounted | set(MOUNTS) | {"/command/{rest:path}"})
95
+ registered.append(
96
+ "command-center SPA on /command (does not steal /console; not a landing door)"
97
+ )
98
+ return registered
99
+
100
+
101
+ def _selftest() -> None:
102
+ from starlette.applications import Starlette
103
+ from starlette.responses import HTMLResponse
104
+ from starlette.routing import Route
105
+ from starlette.testclient import TestClient
106
+
107
+ spa = _spa_path()
108
+ assert spa.is_file(), spa
109
+ html = spa.read_text(encoding="utf-8")
110
+ assert "a11oy Command Center" in html
111
+ assert "https://a-11-oy.com/command" in html
112
+ assert "/console" in html, "must keep a link to the operator console"
113
+ assert "cdnjs" not in html and "googleapis" not in html and "jsdelivr" not in html
114
+ assert "fonts.gstatic" not in html
115
+ assert "Conjecture 1" in html
116
+ assert "a11oy.net" in html
117
+
118
+ async def _console(_req):
119
+ return HTMLResponse("<html><body>operator console</body></html>")
120
+
121
+ app = Starlette(routes=[Route("/console", _console)])
122
+ out = register(app, ns="a11oy")
123
+ assert any("/command" in row for row in out), out
124
+ c = TestClient(app)
125
+ for path in ("/command", "/command/zk", "/command/invest", "/command/build", "/command/census", "/command/console"):
126
+ r = c.get(path)
127
+ assert r.status_code == 200, (path, r.status_code)
128
+ assert "a11oy Command Center" in r.text
129
+ h = c.head(path)
130
+ assert h.status_code == 200, (path, h.status_code)
131
+ op = c.get("/console")
132
+ assert op.status_code == 200 and "operator console" in op.text
133
+ print("a11oy_command_center: ALL OK (SPA on /command; /console untouched; 0 CDN)")
134
+
135
+
136
+ if __name__ == "__main__":
137
+ _selftest()
pages/command-center.html ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8"/>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
6
+ <title>a11oy Command Center</title>
7
+ <meta name="description" content="Governed command on a-11-oy.com. Deny by default. Receipts. Proof lab. Lambda = Conjecture 1. Proof stays on a11oy.net."/>
8
+ <link rel="canonical" href="https://a-11-oy.com/command"/>
9
+ <meta property="og:title" content="a11oy Command Center"/>
10
+ <meta property="og:url" content="https://a-11-oy.com/command"/>
11
+ <style>
12
+ :root {
13
+ --void:#080c14; --panel:#0a1019; --panel-2:#12161d;
14
+ --teal:#3af4c8; --fg:#e8eef6; --muted:#aebccf; --border:#1c2942;
15
+ --deny:#e25c5c; --signal:#e4d3a5; --conjecture:#7b8898;
16
+ --sans: ui-sans-serif, system-ui, sans-serif;
17
+ --display: ui-sans-serif, system-ui, sans-serif;
18
+ --mono: ui-monospace, Menlo, monospace;
19
+ }
20
+ * { box-sizing: border-box; }
21
+ html, body { margin:0; background:var(--void); color:var(--fg); font-family:var(--sans); line-height:1.55; }
22
+ a { color:var(--teal); text-decoration:none; }
23
+ button, [role=button] { cursor:pointer; }
24
+ button:disabled { cursor:not-allowed; opacity:.5; }
25
+ h1,h2,h3 { font-family:var(--display); letter-spacing:-.03em; line-height:1.1; text-wrap:balance; }
26
+ .wrap { max-width:72rem; margin:0 auto; padding:0 1.5rem; }
27
+ header { position:sticky; top:0; z-index:40; border-bottom:1px solid var(--border); background:rgba(8,12,20,.8); backdrop-filter:blur(12px); }
28
+ .bar { display:flex; align-items:center; justify-content:space-between; gap:1rem; min-height:3.5rem; }
29
+ .brand { display:flex; align-items:center; gap:.6rem; color:var(--fg); font-family:var(--display); font-weight:600; letter-spacing:.16em; text-transform:uppercase; font-size:.85rem; }
30
+ .mark { width:.9rem; height:.9rem; background:var(--teal); border-radius:2px; position:relative; }
31
+ .mark::after { content:""; position:absolute; inset:3px; background:var(--void); border-radius:1px; }
32
+ nav a { display:inline-flex; min-height:2.75rem; align-items:center; padding:0 .75rem; color:var(--muted); font-size:.875rem; }
33
+ nav a.active { color:var(--teal); }
34
+ .menu { display:none; min-width:2.75rem; min-height:2.75rem; border:1px solid var(--border); background:transparent; color:var(--fg); border-radius:6px; }
35
+ main { min-height:70dvh; padding:2.5rem 0 4rem; }
36
+ .kicker { font-family:var(--mono); font-size:.7rem; letter-spacing:.18em; text-transform:uppercase; color:var(--teal); }
37
+ .muted { color:var(--muted); }
38
+ .grid { display:grid; gap:.75rem; }
39
+ .g3 { grid-template-columns:repeat(auto-fit,minmax(14rem,1fr)); }
40
+ .g2 { grid-template-columns:repeat(auto-fit,minmax(16rem,1fr)); }
41
+ .card { border:1px solid var(--border); background:var(--panel); border-radius:14px; padding:1.25rem; }
42
+ .badge { display:inline-block; font-family:var(--mono); font-size:.65rem; letter-spacing:.08em; text-transform:uppercase; border:1px solid var(--border); padding:.2rem .45rem; border-radius:4px; color:var(--muted); }
43
+ .badge.MEASURED { color:var(--teal); border-color:rgba(58,244,200,.3); background:rgba(58,244,200,.1); }
44
+ .badge.BLOCKED, .badge.DENY { color:var(--deny); border-color:rgba(226,92,92,.3); background:rgba(226,92,92,.1); }
45
+ .badge.CONJECTURE { color:var(--conjecture); }
46
+ .badge.MODELED, .badge.REPORTED, .badge.SOFTWARE { background:var(--panel-2); }
47
+ .badge.UNAVAILABLE { color:var(--signal); }
48
+ .btn { display:inline-flex; min-height:2.75rem; align-items:center; justify-content:center; gap:.5rem; padding:0 1rem; border-radius:6px; border:1px solid transparent; font-size:.875rem; font-weight:500; }
49
+ .btn-p { background:var(--teal); color:var(--void); }
50
+ .btn-g { background:transparent; color:var(--fg); border-color:var(--border); }
51
+ .btn-q { background:var(--panel-2); color:var(--muted); border-color:var(--border); }
52
+ .skip { position:absolute; left:-999px; }
53
+ .skip:focus { left:1rem; top:1rem; z-index:80; }
54
+ input, select, textarea { width:100%; min-height:2.75rem; background:var(--void); color:var(--fg); border:1px solid var(--border); border-radius:6px; padding:.5rem .75rem; font:inherit; }
55
+ textarea { min-height:6rem; }
56
+ table { width:100%; border-collapse:collapse; font-size:.875rem; }
57
+ th { text-align:left; font-family:var(--mono); font-size:.7rem; color:var(--muted); text-transform:uppercase; padding:.75rem 1rem; }
58
+ td { border-top:1px solid var(--border); padding:.75rem 1rem; }
59
+ footer { border-top:1px solid var(--border); padding:2rem 0; font-size:.75rem; color:var(--muted); }
60
+ .mono { font-family:var(--mono); }
61
+ .ok { color:var(--teal); } .no { color:var(--deny); }
62
+ @media (max-width: 800px) {
63
+ .desk { display:none; }
64
+ .menu { display:inline-flex; }
65
+ .mob { display:none; border-top:1px solid var(--border); padding:.5rem 1rem 1rem; }
66
+ .mob.open { display:block; }
67
+ .mob a { display:flex; min-height:2.75rem; color:var(--muted); }
68
+ }
69
+ @media (prefers-reduced-motion: reduce) { * { animation:none !important; transition:none !important; } }
70
+ </style>
71
+ </head>
72
+ <body>
73
+ <a href="#main" class="skip btn btn-p">Skip to main</a>
74
+ <header>
75
+ <div class="wrap bar">
76
+ <a class="brand" href="/command">
77
+ <span class="mark" aria-hidden="true"></span> a11oy <span class="muted" style="letter-spacing:0;font-weight:400">command</span>
78
+ </a>
79
+ <nav class="desk" aria-label="Primary">
80
+ <a href="/command" data-nav="home">Origin</a>
81
+ <a href="/command/console" data-nav="console">Receipts</a>
82
+ <a href="/command/zk" data-nav="zk">Proof</a>
83
+ <a href="/command/census" data-nav="census">Estate</a>
84
+ <a href="/command/invest" data-nav="invest">Investor</a>
85
+ <a href="/command/build" data-nav="build">Developer</a>
86
+ <a href="/console">Operator</a>
87
+ </nav>
88
+ <button class="menu" type="button" aria-label="Menu">☰</button>
89
+ </div>
90
+ <nav class="mob" aria-label="Mobile"></nav>
91
+ </header>
92
+ <main id="main" class="wrap"></main>
93
+ <footer>
94
+ <div class="wrap">
95
+ <p>Product origin <a href="https://a-11-oy.com">a-11-oy.com</a> · Proof <a href="https://a11oy.net">a11oy.net</a> · Λ = Conjecture 1 · Energy UNAVAILABLE in this browser.</p>
96
+ <p class="mono">Signer UNSIGNED-honest · No secret values · This surface is MODELED on static origin until the Space runtime signs a write. Operator console stays at /console.</p>
97
+ </div>
98
+ </footer>
99
+ <script>
100
+ const P = (1n<<255n)-19n, N = P-1n, G = 2n;
101
+ const GENESIS = "0".repeat(64);
102
+ const CATALOG = [
103
+ {id:"inspect", title:"Inspect receipt chain", needs:false, d:"ALLOW", reason:"Read-only local verification."},
104
+ {id:"estate", title:"List public estate", needs:false, d:"ALLOW", reason:"Public inventory. Location only."},
105
+ {id:"score", title:"Score Lambda advisory", needs:false, d:"ALLOW", reason:"Advisory organ. Output labeled CONJECTURE."},
106
+ {id:"infer", title:"Governed inference", needs:true, d:"ALLOW", reason:"User-initiated. Static origin cannot spend a key — BLOCKED here."},
107
+ {id:"zk_prove", title:"Seal modeled ZK transcript", needs:true, d:"ALLOW", reason:"Public transcript only."},
108
+ {id:"claim_proven", title:"Declare Lambda proven", needs:false, d:"DENY", reason:"Lambda uniqueness is Conjecture 1."},
109
+ {id:"exfiltrate", title:"Export signer material", needs:false, d:"DENY", reason:"No secret-value disclosure."},
110
+ {id:"unsigned_deploy", title:"Unsigned production push", needs:false, d:"DENY", reason:"Unsigned deploy is outside authority."},
111
+ ];
112
+ const ESTATE = [
113
+ ["a11oy","CORE","Product origin","VERIFIED_CURRENT","SOFTWARE","Python"],
114
+ ["a11oy-net","CORE","Proof registry","VERIFIED_CURRENT","SOFTWARE","HTML"],
115
+ ["lutar-lean","CORE","Lean 4 kernel","VERIFIED_CURRENT","REPORTED","Lean"],
116
+ ["szl-router","CORE","Governed router","VERIFIED_CURRENT","SOFTWARE","Python"],
117
+ ["ouroboros","CORE","Self-host loop","LISTED","REPORTED","Python"],
118
+ ];
119
+ function badge(h){ return `<span class="badge ${h}">${h}</span>`; }
120
+ function mod(a,m=P){ const r=a%m; return r<0n?r+m:r; }
121
+ function modPow(b,e,m=P){ let x=mod(b,m), k=e<0n?0n:e, o=1n; while(k>0n){ if(k&1n) o=(o*x)%m; x=(x*x)%m; k>>=1n;} return o; }
122
+ function randBelow(max){ const buf=new Uint8Array(40); crypto.getRandomValues(buf); let x=0n; for(const n of buf) x=(x<<8n)|BigInt(n); return (x%(max-1n))+1n; }
123
+ function hex(n){ return n.toString(16); }
124
+ function shortHex(n){ const h=hex(n); return h.length<=16?h:h.slice(0,8)+"…"+h.slice(-4); }
125
+ function shortHash(h){ return h.slice(0,8)+"…"+h.slice(-4); }
126
+ async function sha256Hex(s){ const b=await crypto.subtle.digest("SHA-256", new TextEncoder().encode(s)); return [...new Uint8Array(b)].map(x=>x.toString(16).padStart(2,"0")).join(""); }
127
+ function verifySchnorr(Y,t,c,s){ return modPow(G,s)===mod(t*modPow(Y,c)); }
128
+ function simulate(Y){ const c=randBelow(N), s=randBelow(N); const inv=modPow(modPow(Y,c), P-2n); return {t:mod(modPow(G,s)*inv), c, s}; }
129
+ function rangeCircuit(x,T,n=8){
130
+ const v=Math.trunc(x); const bits=[]; for(let i=0;i<n;i++) bits.push((v>>i)&1);
131
+ const recon=bits.reduce((a,b,i)=>a+b*2**i,0);
132
+ const cs=[...bits.map((b,i)=>({ok:b===0||b===1,label:`b${i}·(b${i}−1)=0`})),
133
+ {ok:recon===v,label:"x = Σ bᵢ·2ⁱ"}, {ok:v>=0&&v<2**n,label:`0 ≤ x < 2^${n}`}, {ok:v>=T,label:"x ≥ T"}];
134
+ return {cs, sat:cs.every(c=>c.ok)};
135
+ }
136
+ const LAKE_KEY="a11oy-origin-lake";
137
+ function loadLake(){ try { return JSON.parse(localStorage.getItem(LAKE_KEY)||"[]"); } catch { return []; } }
138
+ function saveLake(r){ localStorage.setItem(LAKE_KEY, JSON.stringify(r)); }
139
+ async function sealReceipt(action, decision, reason, payload=""){
140
+ const receipts=loadLake();
141
+ const prev=receipts.at(-1)?.hash || GENESIS;
142
+ const body={id:crypto.randomUUID(), ts:new Date().toISOString(), action, decision, reason, payload, prev};
143
+ body.hash=await sha256Hex(JSON.stringify(body));
144
+ receipts.push(body); saveLake(receipts); return body;
145
+ }
146
+ function evaluate(kind, prompt){
147
+ const item=CATALOG.find(c=>c.id===kind); if(!item) return {decision:"DENY", reason:"Unknown. Deny by default."};
148
+ if(item.d==="DENY") return {decision:"DENY", reason:item.reason};
149
+ if(kind==="infer") return {decision:"BLOCKED", reason:"Static origin has no server key. Refused rather than guessed."};
150
+ if(kind==="zk_prove"){
151
+ const t=(prompt||"").trim();
152
+ if(!t) return {decision:"BLOCKED", reason:"Empty transcript."};
153
+ if(/("x"|"secret"|"witness"|"nonce")\s*:/i.test(t)) return {decision:"DENY", reason:"Witness material cannot enter the lake."};
154
+ }
155
+ return {decision:item.d, reason:item.reason};
156
+ }
157
+
158
+ const $ = (sel, el=document) => el.querySelector(sel);
159
+ function page(){
160
+ const h = (location.hash || "").replace(/^#\/?/, "");
161
+ if (h) return h.split("/")[0] || "home";
162
+ const p = (location.pathname || "/").replace(/\/+$/, "") || "/";
163
+ if (p === "/command" || p === "/origin" || p === "/") return "home";
164
+ if (p.startsWith("/command/")) return p.slice("/command/".length).split("/")[0] || "home";
165
+ return p.replace(/^\//, "").split("/")[0] || "home";
166
+ }
167
+ function nav(){
168
+ document.querySelectorAll("[data-nav]").forEach(a => a.classList.toggle("active", a.dataset.nav===page() || (page()==="home"&&a.dataset.nav==="home")));
169
+ }
170
+ $(".menu").onclick = () => {
171
+ const m=$(".mob"); m.classList.toggle("open");
172
+ if(!m.dataset.ready){ m.innerHTML=[...document.querySelectorAll("nav.desk a")].map(a=>a.outerHTML).join(""); m.dataset.ready="1"; }
173
+ };
174
+
175
+ function home(){
176
+ return `
177
+ <p class="kicker">Product origin · a-11-oy.com</p>
178
+ <h1>Control before capability.</h1>
179
+ <p class="muted" style="max-width:40rem">a11oy Command lives on this host. Deny by default. Hash-chained receipts. Λ is Conjecture 1 — never green. The operator runtime stays at /console. Proof stays on a11oy.net.</p>
180
+ <p style="margin-top:1.5rem;display:flex;gap:.75rem;flex-wrap:wrap">
181
+ <a class="btn btn-p" href="/command/console">Open receipt lake</a>
182
+ <a class="btn btn-g" href="/console">Operator console</a>
183
+ <a class="btn btn-g" href="/command/zk">Proof lab</a>
184
+ <a class="btn btn-g" href="https://a11oy.net">Proof registry</a>
185
+ </p>
186
+ <ul class="grid g3" style="margin-top:2.5rem;list-style:none;padding:0">
187
+ <li class="card"><p class="kicker">Fail closed</p><h3>Deny by default</h3><p class="muted">Unknown acts, unsigned deploys, and proof-closure return DENY with a receipt.</p></li>
188
+ <li class="card"><p class="kicker">Receipts</p><h3>Every change hashed</h3><p class="muted">SHA-256 chain in this browser. Re-verify offline. No secrets in the lake.</p></li>
189
+ <li class="card"><p class="kicker">Honesty</p><h3>Gray over fake live</h3><p class="muted">Energy UNAVAILABLE. Signer UNSIGNED-honest. SNARK proving ROADMAP.</p></li>
190
+ </ul>`;
191
+ }
192
+ function consolePage(){
193
+ const radios = CATALOG.map((c,i)=>`<label style="display:flex;gap:.6rem;min-height:2.75rem;align-items:center"><input type="radio" name="act" value="${c.id}" ${i===0?"checked":""}/> ${c.title} ${badge(c.d)}</label>`).join("");
194
+ return `<p class="kicker">Receipt lake · local to this browser</p><h1>Act. Get a receipt. Or a denial.</h1>
195
+ <p class="muted">This lake is MODELED in-browser. The operator runtime is <a href="/console">/console</a>.</p>
196
+ <div class="grid g2" style="margin-top:1.5rem">
197
+ <div class="card">
198
+ ${radios}
199
+ <textarea id="prompt" placeholder="Prompt only for inference / ZK seal"></textarea>
200
+ <div style="display:flex;gap:.5rem;margin-top:1rem;flex-wrap:wrap">
201
+ <button class="btn btn-p" id="submit">Submit</button>
202
+ <button class="btn btn-g" id="verify">Verify chain</button>
203
+ </div>
204
+ <p class="muted mono" id="status" style="margin-top:.75rem"></p>
205
+ </div>
206
+ <div class="card" id="lake"></div>
207
+ </div>`;
208
+ }
209
+ function renderLake(){
210
+ const r=loadLake();
211
+ $("#lake").innerHTML = r.length? `<p class="kicker">${r.length} receipts</p>`+r.slice().reverse().map(x=>`<div style="border-top:1px solid var(--border);padding:.75rem 0"><div>${x.action} ${badge(x.decision)}</div><div class="mono muted">${shortHash(x.hash)}</div></div>`).join("") : `<p class="muted">Empty lake. Submit an allowed act.</p>`;
212
+ }
213
+ function censusPage(){
214
+ return `<p class="kicker">Estate</p><h1>Location is not quality.</h1>
215
+ <p class="muted">GitHub org szl-holdings · Hub SZLHOLDINGS. Hub RUNNING is not production ready. Labels below are SOFTWARE or REPORTED — not live meters.</p>
216
+ <div class="card" style="margin-top:1.5rem;overflow:auto">
217
+ <table><thead><tr><th>Repo</th><th>Group</th><th>Role</th><th>Disposition</th><th>Honesty</th></tr></thead>
218
+ <tbody>${ESTATE.map(r=>`<tr><td class="mono">${r[0]}</td><td>${r[1]}</td><td>${r[2]}</td><td>${r[3]}</td><td>${badge(r[4])}</td></tr>`).join("")}</tbody></table></div>
219
+ <p class="muted" style="margin-top:1rem">Full census lives on <a href="https://a11oy.net/estate/">a11oy.net/estate</a>.</p>`;
220
+ }
221
+ function investPage(){
222
+ return `<p class="kicker">Investor map</p><h1>What is sold. What is not.</h1>
223
+ <div class="grid g2" style="margin-top:1.5rem">
224
+ <article class="card"><h3>Sold</h3><p class="muted">Governed command. Receipts. Deny-by-default policy. Honesty classes. A public origin on a-11-oy.com.</p></article>
225
+ <article class="card"><h3>Not sold</h3><p class="muted">Λ proven. Energy meters. Production SNARKs. “Hub RUNNING means ready.” Signer keys.</p></article>
226
+ </div>`;
227
+ }
228
+ function buildPage(){
229
+ return `<p class="kicker">Developer map</p><h1>Public origin. GitHub is the source of truth.</h1>
230
+ <ol class="muted" style="margin-top:1rem">
231
+ <li>Product origin a-11-oy.com (this host).</li>
232
+ <li>Proof a11oy.net (separate failure domain).</li>
233
+ <li>Source GitHub szl-holdings/a11oy. Promote via Space sync. Not Replit.</li>
234
+ <li>Unsigned deploy DENY. Witness material DENY.</li>
235
+ </ol>`;
236
+ }
237
+ function zkPage(){
238
+ return `<p class="kicker">Proof lab ${badge("MODELED")}</p>
239
+ <h1>Prove knowledge. Reveal nothing.</h1>
240
+ <p class="muted">Sigma is runnable here. Range circuits satisfy locally. Succinct proving is ROADMAP. Λ stays conjecture. Lasting public RECORD stays on a11oy.net.</p>
241
+ <div style="display:flex;gap:.5rem;margin:1.25rem 0;flex-wrap:wrap">
242
+ <button class="btn btn-g zk-tab active" data-z="sigma">Sigma</button>
243
+ <button class="btn btn-g zk-tab" data-z="snark">SNARKs</button>
244
+ </div>
245
+ <div id="zkroot"></div>`;
246
+ }
247
+ function sigmaUI(){
248
+ return `<div class="grid g2">
249
+ <div class="card">
250
+ <p class="kicker">Prover</p>
251
+ <div style="display:flex;gap:.5rem;flex-wrap:wrap;margin:.75rem 0">
252
+ <button class="btn btn-g mode" data-m="honest">Honest</button>
253
+ <button class="btn btn-g mode" data-m="cheat">Cheater</button>
254
+ <button class="btn btn-g mode" data-m="simulate">Simulator</button>
255
+ </div>
256
+ <p class="mono muted" id="pstate">Witness: —</p>
257
+ <button class="btn btn-p" id="znext">Mint keypair</button>
258
+ <button class="btn btn-q" id="zreset">Reset</button>
259
+ </div>
260
+ <div class="card">
261
+ <p class="kicker">Verifier · wire</p>
262
+ <p class="mono">g^s ≟ t · Y^c (mod p)</p>
263
+ <p class="mono" id="vstate">No check yet.</p>
264
+ </div>
265
+ </div>`;
266
+ }
267
+ function snarkUI(){
268
+ return `<div class="card">
269
+ <p class="kicker">Range credential ${badge("MEASURED")}</p>
270
+ <p class="muted">Prove age ≥ T. The value stays off the verifier. MEASURED here means the circuit ran in this browser — not a production SNARK.</p>
271
+ <label class="muted">Age x <input type="number" id="age" value="21" min="0" max="255"/></label>
272
+ <label class="muted">Threshold T <input type="number" id="th" value="18" min="0" max="255"/></label>
273
+ <button class="btn btn-p" id="rsat" style="margin-top:1rem">Satisfy circuit</button>
274
+ <p class="mono" id="rstate" style="margin-top:.75rem">Verifier sees T only. x = hidden.</p>
275
+ </div>
276
+ <p class="muted" style="margin-top:1rem">Groth16 proving ${badge("ROADMAP")}.</p>`;
277
+ }
278
+
279
+ const Z = { mode:"honest", phase:"idle", x:null, Y:null, r:null, t:null, c:null, s:null };
280
+ function zLabel(){
281
+ if(Z.phase==="idle") return Z.mode==="simulate"?"Publish Y":Z.mode==="cheat"?"Publish a statement you cannot prove":"Mint keypair";
282
+ if(Z.mode==="simulate"&&Z.phase==="keyed") return "Forge transcript (no witness)";
283
+ if(Z.phase==="keyed") return "Commit t = g^r";
284
+ if(Z.phase==="committed") return "Random challenge";
285
+ if(Z.phase==="challenged") return Z.mode==="cheat"?"Guess a response":"Respond s = r + c·x";
286
+ if(Z.phase==="responded") return "Verify g^s ≟ t·Y^c";
287
+ return null;
288
+ }
289
+ function bindZk(){
290
+ const root=$("#zkroot"); root.innerHTML=sigmaUI();
291
+ document.querySelectorAll(".zk-tab").forEach(b=>b.onclick=()=>{
292
+ document.querySelectorAll(".zk-tab").forEach(x=>x.classList.remove("active"));
293
+ b.classList.add("active");
294
+ if(b.dataset.z==="snark"){ root.innerHTML=snarkUI(); $("#rsat").onclick=()=>{ const o=rangeCircuit(Number($("#age").value), Number($("#th").value)); $("#rstate").innerHTML = (o.sat?'<span class="ok">CIRCUIT SAT</span>':'<span class="no">CIRCUIT UNSAT</span>')+" · verifier sees T="+$("#th").value+", x=hidden"; }; }
295
+ else bindZk();
296
+ });
297
+ const next=$("#znext"), st=$("#pstate"), vs=$("#vstate");
298
+ document.querySelectorAll(".mode").forEach(b=>b.onclick=()=>{ Z.mode=b.dataset.m; Z.phase="idle"; Z.x=Z.Y=Z.r=Z.t=Z.c=Z.s=null; next.textContent=zLabel(); st.textContent="Witness: —"; vs.textContent="No check yet."; });
299
+ $("#zreset").onclick=()=>{ Z.phase="idle"; Z.x=Z.Y=Z.r=Z.t=Z.c=Z.s=null; next.textContent=zLabel(); };
300
+ next.onclick=()=>{
301
+ if(Z.phase==="idle"){ const x=randBelow(N); Z.Y=modPow(G,x); Z.x=Z.mode==="honest"?x:null; Z.phase="keyed"; st.textContent="Witness: "+(Z.x?"held locally":"absent")+" · Y "+shortHex(Z.Y); }
302
+ else if(Z.mode==="simulate"&&Z.phase==="keyed"){ const f=simulate(Z.Y); Z.t=f.t; Z.c=f.c; Z.s=f.s; const ok=verifySchnorr(Z.Y,Z.t,Z.c,Z.s); vs.innerHTML=ok?'<span class="ok">ACCEPT · unused witness. MODELED zero-knowledge.</span>':'<span class="no">REJECT</span>'; Z.phase="done"; }
303
+ else if(Z.phase==="keyed"){ Z.r=randBelow(N); Z.t=modPow(G,Z.r); Z.phase="committed"; }
304
+ else if(Z.phase==="committed"){ Z.c=randBelow(N); Z.phase="challenged"; }
305
+ else if(Z.phase==="challenged"){ Z.s=Z.mode==="honest"&&Z.x!=null? mod(Z.r+Z.c*Z.x,N): randBelow(N); Z.phase="responded"; }
306
+ else if(Z.phase==="responded"){ const ok=verifySchnorr(Z.Y,Z.t,Z.c,Z.s); vs.innerHTML=ok?'<span class="ok">ACCEPT · equation holds</span>':'<span class="no">REJECT · equation fails</span>'; Z.phase="done"; }
307
+ next.textContent=zLabel()||"Done";
308
+ if(!zLabel()) next.disabled=true; else next.disabled=false;
309
+ };
310
+ }
311
+
312
+ const PAGES = { home, console:consolePage, census:censusPage, invest:investPage, build:buildPage, zk:zkPage };
313
+ function render(){
314
+ nav();
315
+ const id = page();
316
+ $("#main").innerHTML = (PAGES[id]||home)();
317
+ if(id==="console"){
318
+ renderLake();
319
+ $("#submit").onclick=async()=>{
320
+ const kind=document.querySelector("[name=act]:checked").value;
321
+ const ev=evaluate(kind, $("#prompt").value);
322
+ await sealReceipt(kind, ev.decision, ev.reason, kind==="zk_prove"?$("#prompt").value.slice(0,4000):"");
323
+ $("#status").textContent=ev.decision+" · "+ev.reason;
324
+ renderLake();
325
+ };
326
+ $("#verify").onclick=async()=>{
327
+ const r=loadLake(); let prev=GENESIS, ok=true;
328
+ for(const x of r){ const {hash, ...rest}=x; const h=await sha256Hex(JSON.stringify(rest)); if(h!==x.hash||x.prev!==prev) ok=false; prev=x.hash; }
329
+ $("#status").textContent=ok?`MEASURED ${r.length} receipts. Chain intact.`:"Chain broken.";
330
+ };
331
+ }
332
+ if(id==="zk") bindZk();
333
+ }
334
+ window.addEventListener("hashchange", render);
335
+ window.addEventListener("popstate", render);
336
+ render();
337
+ </script>
338
+ </body>
339
+ </html>
serve.py CHANGED
@@ -1738,6 +1738,16 @@ try:
1738
  except Exception as _n25_organs_e: # pragma: no cover
1739
  print(f"[a11oy] N1–N25 organs NOT registered: {_n25_organs_e!r}; SPA + API unaffected", file=__import__("sys").stderr)
1740
 
 
 
 
 
 
 
 
 
 
 
1741
 
1742
  # -- BRAIN GRAPH (self-writing brain substrate) -- GET /api/a11oy/v1/brain/graph is the
1743
  # MODELED derived view that HARVESTS the real estate (64 frontier surfaces + 23 PURIQ
@@ -12138,14 +12148,24 @@ async def command_console_page() -> Response:
12138
  # Each now maps to its REAL destination. Registered BEFORE the SPA catch-all so
12139
  # they win the ordered match. ADDITIVE — no existing route touched.
12140
 
12141
- # /command + /command-center: the "command centre" IS the console. Old links /
12142
- # bookmarks landed on the dead SPA shell; 307 to the real, working /console.
12143
- async def _command_center_redirect() -> Response:
 
 
 
 
12144
  return _PTG_Redirect(url="/console", status_code=307)
12145
 
12146
 
12147
- for _cc_path in ("/command", "/command-center"):
12148
- app.add_api_route(_cc_path, _command_center_redirect, methods=["GET"], include_in_schema=False)
 
 
 
 
 
 
12149
 
12150
 
12151
  # /pinn — Physical-Bounds Certifier surface (distinct from /pinn-console).
 
1738
  except Exception as _n25_organs_e: # pragma: no cover
1739
  print(f"[a11oy] N1–N25 organs NOT registered: {_n25_organs_e!r}; SPA + API unaffected", file=__import__("sys").stderr)
1740
 
1741
+ # Command Center SPA — bound path on a-11-oy.com/command.
1742
+ # Does not steal /console. Does not rewrite the landing door.
1743
+ # Proof stays on a11oy.net.
1744
+ try:
1745
+ import a11oy_command_center as _a11oy_command_center
1746
+ _command_center_status = _a11oy_command_center.register(app, ns="a11oy")
1747
+ print(f"[a11oy] Command Center SPA registered: {_command_center_status}", file=__import__("sys").stderr)
1748
+ except Exception as _command_center_e: # pragma: no cover
1749
+ print(f"[a11oy] Command Center SPA NOT registered: {_command_center_e!r}; /console unaffected", file=__import__("sys").stderr)
1750
+
1751
 
1752
  # -- BRAIN GRAPH (self-writing brain substrate) -- GET /api/a11oy/v1/brain/graph is the
1753
  # MODELED derived view that HARVESTS the real estate (64 frontier surfaces + 23 PURIQ
 
12148
  # Each now maps to its REAL destination. Registered BEFORE the SPA catch-all so
12149
  # they win the ordered match. ADDITIVE — no existing route touched.
12150
 
12151
+ # /command is a bound-path public Command Center SPA (pages/command-center.html).
12152
+ # Does not steal /console. Does not rewrite the landing door. If the SPA file
12153
+ # is missing, fall back to /console. /command-center 307s to /command.
12154
+ async def _command_center_page() -> Response:
12155
+ f = PAGES_DIR / "command-center.html"
12156
+ if f.is_file():
12157
+ return FileResponse(f, media_type="text/html")
12158
  return _PTG_Redirect(url="/console", status_code=307)
12159
 
12160
 
12161
+ app.add_api_route("/command", _command_center_page, methods=["GET", "HEAD"], include_in_schema=False)
12162
+
12163
+
12164
+ async def _command_center_alias() -> Response:
12165
+ return _PTG_Redirect(url="/command", status_code=307)
12166
+
12167
+
12168
+ app.add_api_route("/command-center", _command_center_alias, methods=["GET", "HEAD"], include_in_schema=False)
12169
 
12170
 
12171
  # /pinn — Physical-Bounds Certifier surface (distinct from /pinn-console).