betterwithage commited on
Commit
ee5cf0c
·
verified ·
1 Parent(s): 835f3c5

deploy: exact szl-forge source 53e8b0f1a8bb

Browse files

Git-controlled Space subtree publication with post-commit byte and runtime verification.

Signed-off-by: SZL Holdings <noreply@szlholdings.ai>

Files changed (5) hide show
  1. README.md +14 -2
  2. app.py +160 -23
  3. release.json +5 -5
  4. tests/test_app.py +83 -2
  5. verify_execution_record.py +1 -1
README.md CHANGED
@@ -54,6 +54,13 @@ non-secret `SZL_GITHUB_SOURCE_REVISION` Space variable and verifies it at
54
  That endpoint reports `UNKNOWN` rather than inferring a source revision when
55
  the binding is absent or malformed.
56
 
 
 
 
 
 
 
 
57
  An isolated image-build stage fetches only the exact GGUF and three receipt
58
  files from the immutable model revision, without a token, and verifies them
59
  before the image can finish. It copies only verified regular bytes into the
@@ -80,8 +87,13 @@ It requires no provider token or Space secret and is intended for the Hub's free
80
  tokens, and a 45-second best-effort cutoff checked between streamed chunks
81
  (not a hard wall-clock deadline).
82
  - Greedy decoding (`temperature=0`); outputs are model-generated and may be wrong.
83
- - `/live` is liveness (`STARTING`/`READY` = 200; `FAILED` = 503); `/health` is
84
- readiness and returns 503 until `READY`.
 
 
 
 
 
85
  - `/api/v1/identity` exposes the immutable artifact, runtime limits, source release
86
  marker, and receipt boundary. Source checksums establish internal bundle
87
  consistency only; they are not external authorship evidence.
 
54
  That endpoint reports `UNKNOWN` rather than inferring a source revision when
55
  the binding is absent or malformed.
56
 
57
+ The human-facing surface is the **Khipu Loom**: a responsive Formula Genome
58
+ instrument that keeps the source thread, immutable model pin, receipt boundary,
59
+ runtime state, and unsigned-output limitation visible beside the bounded
60
+ inference controls. It uses no external scripts, fonts, trackers, or UI assets,
61
+ and exposes a deterministic `data-screenshot-ready` signal only after the
62
+ runtime reaches `READY`.
63
+
64
  An isolated image-build stage fetches only the exact GGUF and three receipt
65
  files from the immutable model revision, without a token, and verifies them
66
  before the image can finish. It copies only verified regular bytes into the
 
87
  tokens, and a 45-second best-effort cutoff checked between streamed chunks
88
  (not a hard wall-clock deadline).
89
  - Greedy decoding (`temperature=0`); outputs are model-generated and may be wrong.
90
+ - `/live` and `/healthz` are liveness (`STARTING`/`READY` = 200; `FAILED` =
91
+ 503); `/health` and `/readyz` are readiness and return 503 until `READY`.
92
+ - `/version` fails closed unless the governed deployment provides one exact
93
+ 40-character source revision. `/evidence` fails closed unless that exact
94
+ source identity, source-bundle integrity, and both declared-key receipts are
95
+ simultaneously available. Neither endpoint upgrades unsigned runtime output
96
+ into an attestation.
97
  - `/api/v1/identity` exposes the immutable artifact, runtime limits, source release
98
  marker, and receipt boundary. Source checksums establish internal bundle
99
  consistency only; they are not external authorship evidence.
app.py CHANGED
@@ -64,6 +64,8 @@ SYSTEM_PROMPT = (
64
  SOURCE_ROOT = Path(__file__).resolve().parent
65
  SOURCE_REVISION_ENV = "SZL_GITHUB_SOURCE_REVISION"
66
  ARTIFACT_ROOT = Path("/opt/szl/model-artifacts")
 
 
67
 
68
 
69
  state: dict[str, Any] = {
@@ -622,6 +624,22 @@ def identity_payload() -> dict[str, Any]:
622
  }
623
 
624
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
625
  def build_info_payload() -> dict[str, Any]:
626
  """Expose the exact Git source bound by the governed deploy workflow.
627
 
@@ -630,17 +648,14 @@ def build_info_payload() -> dict[str, Any]:
630
  the internal release manifest.
631
  """
632
 
633
- raw_revision = os.getenv(SOURCE_REVISION_ENV, "").strip().lower()
634
- revision_observed = (
635
- len(raw_revision) == 40
636
- and all(character in "0123456789abcdef" for character in raw_revision)
637
- )
638
  return {
639
  "schema": "szl.build-info/v1",
640
- "service": "szl-model-inference-lab",
641
  "build": {
642
  "state": "OBSERVED" if revision_observed else "UNKNOWN",
643
- "revision": raw_revision if revision_observed else None,
644
  "revision_source": (
645
  f"Hugging Face Space variable {SOURCE_REVISION_ENV}"
646
  if revision_observed
@@ -659,6 +674,77 @@ def build_info_payload() -> dict[str, Any]:
659
  }
660
 
661
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
662
  def canonical_json_bytes(payload: dict[str, Any]) -> bytes:
663
  return json.dumps(
664
  payload, ensure_ascii=False, separators=(",", ":"), sort_keys=True
@@ -802,12 +888,37 @@ def health() -> JSONResponse:
802
  )
803
 
804
 
 
 
 
 
 
805
  @app.get("/live")
806
  def live() -> JSONResponse:
807
  code = 503 if state["status"] == "FAILED" else 200
808
  return JSONResponse({"status": state["status"]}, status_code=code)
809
 
810
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
811
  @app.get("/api/v1/identity")
812
  def identity() -> dict[str, Any]:
813
  return identity_payload()
@@ -1040,22 +1151,48 @@ def openai_chat_completions(request: ChatCompletionRequest) -> JSONResponse:
1040
  @app.get("/", response_class=HTMLResponse)
1041
  def index() -> str:
1042
  return """<!doctype html>
1043
- <html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
1044
- <title>SZL Model Inference Lab</title><style>
1045
- body{margin:0;background:#080b13;color:#e9efff;font:16px/1.5 system-ui,sans-serif}main{max-width:820px;margin:auto;padding:40px 22px}
1046
- .card{background:#101728;border:1px solid #2a385b;border-radius:18px;padding:24px;box-shadow:0 18px 60px #0007}h1{margin:.1em 0;color:#8ce8ff}
1047
- textarea{box-sizing:border-box;width:100%;min-height:130px;background:#080d19;color:#fff;border:1px solid #40537f;border-radius:10px;padding:12px}
1048
- button{margin-top:12px;background:#7ce6ff;color:#06101a;border:0;border-radius:999px;padding:10px 18px;font-weight:700;cursor:pointer}pre{white-space:pre-wrap;background:#080d19;padding:14px;border-radius:10px;min-height:52px}code{color:#a7f3d0}.fine{color:#aebbd4;font-size:.9rem}a{color:#8ce8ff}</style></head>
1049
- <body><main><div class="card"><p class="fine">FREE CPU BASIC · ONE REQUEST AT A TIME · IMMUTABLE Q4_K_M</p><h1>SZL Model Inference Lab</h1>
1050
- <p>Real, bounded CPU inference for <code>SZL-Khipu-1.5B-GGUF</code>. Max 1,200 input characters and 32 generated tokens.</p>
1051
- <textarea id="prompt" maxlength="1200">Reply with one short sentence describing what a cryptographic receipt can prove.</textarea><br>
1052
- <button id="run" disabled aria-disabled="true">Run bounded inference</button><pre id="out" role="status" aria-live="polite">Checking runtime…</pre>
1053
- <p class="fine">Upstream receipt signatures verify against the repository-declared key only; no independent identity or key-ownership binding is claimed. No independent benchmark, post-quantization quality claim, or safety certification. Prompts are not intentionally stored. <a href="/api/v1/identity">Machine identity</a> · <a href="/health">Health</a></p></div></main>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1054
  <script>
1055
- const b=document.querySelector('#run'),o=document.querySelector('#out'),p=document.querySelector('#prompt');
 
1056
  let running=false,hasResult=false;
1057
- function renderStatus(status,failure){const ready=status==='READY';b.disabled=!ready||running;b.setAttribute('aria-disabled',String(b.disabled));if(running)return;if(ready){if(!hasResult)o.textContent='Runtime READY. You can run bounded inference.';return}hasResult=false;o.textContent=status==='FAILED'?'Runtime FAILED'+(failure?': '+failure:'')+'.':status==='STARTING'?'Runtime STARTING…':'Runtime status unavailable; retrying…'}
1058
- async function checkHealth(){try{const r=await fetch('/health',{cache:'no-store'}),j=await r.json();renderStatus(j.status,j.failure_code)}catch(_){renderStatus('UNAVAILABLE')}}
1059
- b.onclick=async()=>{if(b.disabled)return;running=true;hasResult=false;b.disabled=true;b.setAttribute('aria-disabled','true');o.textContent='Running on free CPU…';try{const r=await fetch('/api/v1/infer',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({prompt:p.value,max_new_tokens:24})}),j=await r.json();hasResult=true;o.textContent=r.ok?j.output:JSON.stringify(j)}catch(e){hasResult=true;o.textContent='Request failed: '+e}finally{running=false;await checkHealth()}};
1060
- checkHealth();setInterval(checkHealth,5000);
 
 
 
1061
  </script></body></html>"""
 
64
  SOURCE_ROOT = Path(__file__).resolve().parent
65
  SOURCE_REVISION_ENV = "SZL_GITHUB_SOURCE_REVISION"
66
  ARTIFACT_ROOT = Path("/opt/szl/model-artifacts")
67
+ SERVICE_NAME = "szl-model-inference-lab"
68
+ SURFACE_NAME = "model-inference"
69
 
70
 
71
  state: dict[str, Any] = {
 
624
  }
625
 
626
 
627
+ def observed_source_revision() -> str | None:
628
+ """Return only an exact deploy-bound Git revision.
629
+
630
+ The Space repository SHA, release identifier, and model revision are all
631
+ different identities. None is allowed to stand in for the governed
632
+ GitHub source revision.
633
+ """
634
+
635
+ raw_revision = os.getenv(SOURCE_REVISION_ENV, "").strip().lower()
636
+ if len(raw_revision) != 40:
637
+ return None
638
+ if any(character not in "0123456789abcdef" for character in raw_revision):
639
+ return None
640
+ return raw_revision
641
+
642
+
643
  def build_info_payload() -> dict[str, Any]:
644
  """Expose the exact Git source bound by the governed deploy workflow.
645
 
 
648
  the internal release manifest.
649
  """
650
 
651
+ revision = observed_source_revision()
652
+ revision_observed = revision is not None
 
 
 
653
  return {
654
  "schema": "szl.build-info/v1",
655
+ "service": SERVICE_NAME,
656
  "build": {
657
  "state": "OBSERVED" if revision_observed else "UNKNOWN",
658
+ "revision": revision,
659
  "revision_source": (
660
  f"Hugging Face Space variable {SOURCE_REVISION_ENV}"
661
  if revision_observed
 
674
  }
675
 
676
 
677
+ def version_payload() -> dict[str, Any]:
678
+ revision = observed_source_revision()
679
+ return {
680
+ "schemaVersion": "szl.vertical-conformance.version.v1",
681
+ "service": SERVICE_NAME,
682
+ "surface": SURFACE_NAME,
683
+ "gitSha": revision,
684
+ "evidenceState": "MEASURED" if revision is not None else "UNAVAILABLE",
685
+ }
686
+
687
+
688
+ def evidence_payload() -> dict[str, Any]:
689
+ revision = observed_source_revision()
690
+ receipts_verified = (
691
+ state["receipt_status"] == "DECLARED_KEY_SIGNATURES_VALID"
692
+ )
693
+ return {
694
+ "schemaVersion": "szl.vertical-conformance.evidence.v1",
695
+ "service": SERVICE_NAME,
696
+ "surface": SURFACE_NAME,
697
+ "gitSha": revision,
698
+ "evidenceState": (
699
+ "MEASURED"
700
+ if revision is not None and state["source_integrity"] and receipts_verified
701
+ else "UNAVAILABLE"
702
+ ),
703
+ "runtime": {
704
+ "status": state["status"],
705
+ "ready": state["status"] == "READY",
706
+ "sourceIntegrity": state["source_integrity"],
707
+ "modelSha256Verified": state["model_sha256"] == MODEL_SHA256,
708
+ },
709
+ "model": {
710
+ "repo": MODEL_REPO,
711
+ "revision": MODEL_REVISION,
712
+ "file": MODEL_FILE,
713
+ "sha256": MODEL_SHA256,
714
+ },
715
+ "receipts": [
716
+ {
717
+ "kind": "training",
718
+ "status": state["receipt_status"],
719
+ "canonicalSha256": (
720
+ state.get("receipt_evidence", {}).get(
721
+ "training_canonical_sha256"
722
+ )
723
+ ),
724
+ "scope": "repository-declared key continuity only",
725
+ },
726
+ {
727
+ "kind": "evaluation",
728
+ "status": state["receipt_status"],
729
+ "canonicalSha256": (
730
+ state.get("receipt_evidence", {}).get("eval_canonical_sha256")
731
+ ),
732
+ "scope": "repository-declared key continuity only",
733
+ },
734
+ ],
735
+ "outputProvenance": {
736
+ "signatureStatus": "UNSIGNED",
737
+ "authenticityEstablished": False,
738
+ "record": "content-addressed and returned to the caller; not persisted",
739
+ },
740
+ "limitations": [
741
+ "No independent benchmark or safety certification is claimed.",
742
+ "Training and evaluation receipts do not cover this runtime output.",
743
+ "The public Space is best-effort and has no service-level agreement.",
744
+ ],
745
+ }
746
+
747
+
748
  def canonical_json_bytes(payload: dict[str, Any]) -> bytes:
749
  return json.dumps(
750
  payload, ensure_ascii=False, separators=(",", ":"), sort_keys=True
 
888
  )
889
 
890
 
891
+ @app.get("/readyz")
892
+ def readyz() -> JSONResponse:
893
+ return health()
894
+
895
+
896
  @app.get("/live")
897
  def live() -> JSONResponse:
898
  code = 503 if state["status"] == "FAILED" else 200
899
  return JSONResponse({"status": state["status"]}, status_code=code)
900
 
901
 
902
+ @app.get("/healthz")
903
+ def healthz() -> JSONResponse:
904
+ return live()
905
+
906
+
907
+ @app.get("/version")
908
+ def version() -> JSONResponse:
909
+ payload = version_payload()
910
+ return JSONResponse(payload, status_code=200 if payload["gitSha"] else 503)
911
+
912
+
913
+ @app.get("/evidence")
914
+ def evidence() -> JSONResponse:
915
+ payload = evidence_payload()
916
+ return JSONResponse(
917
+ payload,
918
+ status_code=200 if payload["evidenceState"] == "MEASURED" else 503,
919
+ )
920
+
921
+
922
  @app.get("/api/v1/identity")
923
  def identity() -> dict[str, Any]:
924
  return identity_payload()
 
1151
  @app.get("/", response_class=HTMLResponse)
1152
  def index() -> str:
1153
  return """<!doctype html>
1154
+ <html lang="en" data-screenshot-ready="false"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
1155
+ <meta name="theme-color" content="#0c0811"><meta name="color-scheme" content="dark">
1156
+ <meta name="description" content="A bounded, source-bound GGUF inference instrument with visible model, receipt, and unsigned-output boundaries.">
1157
+ <meta property="og:type" content="website"><meta property="og:title" content="SZL Model Inference Lab - Khipu Loom">
1158
+ <meta property="og:description" content="Every token leaves a thread: inspect exact model bytes, deploy identity, receipt evidence, and bounded execution together.">
1159
+ <meta property="og:url" content="https://szlholdings-szl-model-inference-lab.hf.space/">
1160
+ <link rel="canonical" href="https://szlholdings-szl-model-inference-lab.hf.space/">
1161
+ <title>SZL Model Inference Lab - Khipu Loom</title>
1162
+ <style>
1163
+ :root{--ink:#0c0811;--ink-2:#120d19;--panel:#171020;--line:#3b2a45;--text:#f7f0f4;--muted:#bcaebc;--fiber:#ef86d7;--ember:#ffbd69;--mint:#63e6d4;--danger:#ff6f82;--radius:22px;--shadow:0 30px 90px #0009}
1164
+ *{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;background:radial-gradient(circle at 78% 12%,#301733 0,transparent 34%),radial-gradient(circle at 7% 78%,#172b30 0,transparent 30%),var(--ink);color:var(--text);font:16px/1.55 Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;min-height:100vh}
1165
+ body:before{content:"";position:fixed;inset:0;pointer-events:none;opacity:.2;background-image:linear-gradient(#fff1 1px,transparent 1px),linear-gradient(90deg,#fff1 1px,transparent 1px);background-size:48px 48px;mask-image:linear-gradient(to bottom,#000,transparent 82%)}
1166
+ a{color:inherit}.skip{position:fixed;left:16px;top:-60px;background:var(--text);color:var(--ink);padding:10px 14px;z-index:20}.skip:focus{top:16px}
1167
+ .shell{width:min(1180px,calc(100% - 40px));margin:auto;position:relative}.nav{display:flex;align-items:center;justify-content:space-between;gap:24px;padding:22px 0;border-bottom:1px solid #ffffff14}.brand{display:flex;align-items:center;gap:12px;text-decoration:none}.mark{width:34px;height:34px;border:1px solid var(--fiber);border-radius:50%;position:relative;box-shadow:inset 0 0 18px #ef86d744}.mark:before,.mark:after{content:"";position:absolute;background:var(--mint)}.mark:before{width:1px;height:46px;left:16px;top:-7px}.mark:after{width:46px;height:1px;left:-7px;top:16px}.brand strong{letter-spacing:.08em}.brand small{display:block;color:var(--muted);font:700 10px/1.2 ui-monospace,monospace;letter-spacing:.18em;text-transform:uppercase}.links{display:flex;gap:22px;align-items:center}.links a{color:var(--muted);font-size:13px;text-decoration:none}.links a:hover{color:var(--text)}
1168
+ .hero{display:grid;grid-template-columns:minmax(0,1.02fr) minmax(360px,.98fr);gap:58px;align-items:center;padding:82px 0 50px}.eyebrow,.mono{font-family:ui-monospace,SFMono-Regular,Consolas,monospace}.eyebrow{color:var(--mint);font-size:12px;font-weight:700;letter-spacing:.18em;text-transform:uppercase}.hero h1{font-size:clamp(52px,7vw,92px);line-height:.94;letter-spacing:-.06em;margin:20px 0 26px;max-width:760px}.hero h1 span{color:var(--ember);font-family:Georgia,serif;font-style:italic;font-weight:500}.lede{font-size:clamp(18px,2vw,22px);color:var(--muted);max-width:660px}.hero-actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:30px}.button,.ghost{display:inline-flex;align-items:center;justify-content:center;min-height:48px;padding:0 20px;border-radius:999px;font-weight:800;text-decoration:none}.button{border:0;background:var(--text);color:var(--ink);cursor:pointer}.button:hover{background:var(--ember)}.button:disabled{cursor:not-allowed;opacity:.48}.ghost{border:1px solid var(--line);color:var(--text);background:#ffffff08}.ghost:hover{border-color:var(--fiber)}
1169
+ .loom{min-height:470px;border:1px solid #ffffff1b;border-radius:32px;background:linear-gradient(145deg,#ffffff0d,#ffffff03);box-shadow:var(--shadow);position:relative;overflow:hidden}.loom:before{content:"";position:absolute;inset:28px;border:1px solid #ffffff12;border-radius:24px}.cord{position:absolute;left:13%;right:13%;height:1px;transform-origin:center;background:linear-gradient(90deg,transparent,var(--fiber),var(--ember),var(--mint),transparent);box-shadow:0 0 14px #ef86d766}.cord.c1{top:23%;transform:rotate(14deg)}.cord.c2{top:43%;transform:rotate(-9deg)}.cord.c3{top:65%;transform:rotate(5deg)}.cord.c4{top:78%;transform:rotate(-15deg)}.knot{position:absolute;width:18px;height:18px;border-radius:50%;background:var(--panel);border:3px solid var(--ember);box-shadow:0 0 0 7px #ffbd6917,0 0 28px #ffbd6955}.k1{left:24%;top:29%}.k2{left:52%;top:39%;border-color:var(--fiber)}.k3{left:72%;top:58%;border-color:var(--mint)}.k4{left:34%;top:70%}.loom-label{position:absolute;padding:9px 12px;border:1px solid var(--line);border-radius:12px;background:#0c0811db;font:700 10px/1.2 ui-monospace,monospace;letter-spacing:.12em;text-transform:uppercase}.l1{left:9%;top:12%;color:var(--fiber)}.l2{right:8%;top:33%;color:var(--ember)}.l3{left:12%;bottom:13%;color:var(--mint)}.loom-core{position:absolute;left:50%;top:50%;width:130px;height:130px;transform:translate(-50%,-50%);border:1px solid #ffffff20;border-radius:50%;display:grid;place-items:center;background:#100b17cc;box-shadow:0 0 0 22px #ffffff05,0 0 80px #ef86d72b;text-align:center}.loom-core b{font:700 12px/1.2 ui-monospace,monospace;letter-spacing:.13em}.loom-core small{display:block;color:var(--muted);margin-top:5px}
1170
+ .status-strip{display:grid;grid-template-columns:repeat(4,1fr);border:1px solid var(--line);border-radius:20px;background:#0c0811b8;overflow:hidden;margin:4px 0 72px}.metric{padding:20px 22px;border-right:1px solid var(--line)}.metric:last-child{border:0}.metric b{display:block;font:800 14px/1.25 ui-monospace,monospace;word-break:break-word}.metric small{color:var(--muted);font-size:11px;letter-spacing:.1em;text-transform:uppercase}.state{display:inline-flex;align-items:center;gap:8px}.state:before{content:"";width:8px;height:8px;border-radius:50%;background:var(--ember);box-shadow:0 0 14px currentColor}.state.ready{color:var(--mint)}.state.ready:before{background:var(--mint)}.state.failed{color:var(--danger)}.state.failed:before{background:var(--danger)}
1171
+ .section{padding:72px 0;border-top:1px solid #ffffff12}.section-head{display:flex;align-items:end;justify-content:space-between;gap:30px;margin-bottom:30px}.section h2{font-size:clamp(34px,5vw,58px);line-height:1;margin:10px 0;letter-spacing:-.04em}.section-copy{color:var(--muted);max-width:600px}.composer{display:grid;grid-template-columns:1.08fr .92fr;border:1px solid var(--line);border-radius:28px;overflow:hidden;background:var(--panel);box-shadow:var(--shadow)}.input-pane,.output-pane{padding:28px}.output-pane{background:#0a0710;border-left:1px solid var(--line)}label{display:block;font-weight:800;margin-bottom:10px}textarea{box-sizing:border-box;width:100%;min-height:180px;resize:vertical;background:#0b0710;color:var(--text);border:1px solid #4a3554;border-radius:16px;padding:16px;font:15px/1.55 ui-monospace,monospace}textarea:focus{outline:2px solid var(--fiber);outline-offset:2px}.composer-meta{display:flex;justify-content:space-between;gap:14px;color:var(--muted);font-size:12px;margin:10px 2px}.run-row{display:flex;align-items:center;justify-content:space-between;gap:18px;margin-top:18px}.output-label{color:var(--mint);font:700 11px ui-monospace,monospace;letter-spacing:.14em;text-transform:uppercase}.output-pane pre{white-space:pre-wrap;margin:18px 0 0;min-height:220px;color:#e8dfe8;font:15px/1.7 ui-monospace,monospace}.thread-id{color:var(--muted);font-size:11px;word-break:break-all}
1172
+ .evidence-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}.evidence-card{min-height:220px;border:1px solid var(--line);border-radius:20px;background:#ffffff08;padding:22px}.evidence-card .number{color:var(--ember);font:700 12px ui-monospace,monospace}.evidence-card h3{font-size:20px;margin:40px 0 10px}.evidence-card p{color:var(--muted);font-size:14px}.evidence-card a{color:var(--mint)}
1173
+ .boundary{display:grid;grid-template-columns:1fr 1fr;gap:16px}.boundary article{padding:26px;border-radius:22px;border:1px solid var(--line)}.boundary article:first-child{background:#17302e55}.boundary article:last-child{background:#34182255}.boundary h3{margin-top:0}.boundary ul{padding-left:20px;color:var(--muted)}footer{display:flex;justify-content:space-between;gap:24px;padding:38px 0 56px;color:var(--muted);font-size:12px;border-top:1px solid #ffffff12}
1174
+ :focus-visible{outline:2px solid var(--mint);outline-offset:3px}@media(max-width:850px){.links{display:none}.hero{grid-template-columns:1fr;padding-top:56px}.loom{min-height:390px}.status-strip{grid-template-columns:1fr 1fr}.metric:nth-child(2){border-right:0}.metric:nth-child(-n+2){border-bottom:1px solid var(--line)}.composer{grid-template-columns:1fr}.output-pane{border-left:0;border-top:1px solid var(--line)}.evidence-grid{grid-template-columns:1fr}.boundary{grid-template-columns:1fr}.section-head{display:block}}@media(max-width:520px){.shell{width:min(100% - 24px,1180px)}.hero{gap:34px}.hero h1{font-size:52px}.loom{min-height:330px}.status-strip{grid-template-columns:1fr}.metric{border-right:0;border-bottom:1px solid var(--line)!important}.metric:last-child{border-bottom:0!important}.input-pane,.output-pane{padding:20px}.run-row{align-items:stretch;flex-direction:column}.button{width:100%}footer{display:block}}
1175
+ @media(prefers-reduced-motion:reduce){html{scroll-behavior:auto}*,*:before,*:after{animation:none!important;transition:none!important}}
1176
+ </style></head>
1177
+ <body><a class="skip" href="#main">Skip to inference lab</a><div class="shell">
1178
+ <nav class="nav" aria-label="Primary"><a class="brand" href="/"><span class="mark" aria-hidden="true"></span><span><strong>SZL / KHIPU LOOM</strong><small>Bounded inference instrument</small></span></a><div class="links"><a href="#run-lab">Run</a><a href="#evidence">Evidence</a><a href="/api/v1/identity">Identity</a><a href="/.well-known/szl-inference-contract.json">API contract</a></div></nav>
1179
+ <main id="main"><section class="hero"><div><p class="eyebrow">Formula genome 01 / public cpu instrument</p><h1>Every token leaves a <span>thread.</span></h1><p class="lede">A bounded inference surface where the exact model bytes, source revision, receipt chain, limits, and missing guarantees remain visible together.</p><div class="hero-actions"><a class="button" href="#run-lab">Enter the loom</a><a class="ghost" href="/evidence">Inspect machine evidence</a></div></div>
1180
+ <div class="loom" aria-label="Abstract Khipu provenance loom showing source, model, and receipt threads"><i class="cord c1"></i><i class="cord c2"></i><i class="cord c3"></i><i class="cord c4"></i><i class="knot k1"></i><i class="knot k2"></i><i class="knot k3"></i><i class="knot k4"></i><span class="loom-label l1">source / exact sha</span><span class="loom-label l2">model / q4_k_m</span><span class="loom-label l3">output / unsigned</span><div class="loom-core"><div><b>KHIPU<br>1.5B</b><small>CPU bound</small></div></div></div></section>
1181
+ <section class="status-strip" aria-label="Live runtime summary"><div class="metric"><small>Runtime</small><b id="runtime-state" class="state">CHECKING</b></div><div class="metric"><small>Git source</small><b id="source-sha">UNAVAILABLE</b></div><div class="metric"><small>Model pin</small><b>67d60ec...f4a4b5d25</b></div><div class="metric"><small>Output proof</small><b>UNSIGNED / HASHED</b></div></section>
1182
+ <section class="section" id="run-lab"><div class="section-head"><div><p class="eyebrow">Bounded generation</p><h2>Pull one thread.</h2></div><p class="section-copy">One request at a time. At most 1,200 characters, 800 formatted prompt tokens, and 32 generated tokens. Greedy decoding. No tools, streaming, or hidden fallback.</p></div>
1183
+ <div class="composer"><div class="input-pane"><label for="prompt">Prompt</label><textarea id="prompt" maxlength="1200">Reply with one short sentence describing what a cryptographic receipt can prove.</textarea><div class="composer-meta"><span id="char-count">0 / 1,200 characters</span><span>24 output tokens</span></div><div class="run-row"><button class="button" id="run" disabled aria-disabled="true">Run bounded inference</button><span class="mono thread-id" id="request-state">Waiting for readiness</span></div></div><div class="output-pane"><span class="output-label">Model output</span><pre id="out" role="status" aria-live="polite">Checking the runtime and evidence threads...</pre></div></div></section>
1184
+ <section class="section" id="evidence"><div class="section-head"><div><p class="eyebrow">Inspectable by default</p><h2>The evidence bay.</h2></div><p class="section-copy">The interface does not turn provenance into decoration. Every status below resolves to a machine-readable surface.</p></div><div class="evidence-grid"><article class="evidence-card"><span class="number">01 / SOURCE</span><h3>Exact deploy identity</h3><p id="source-detail">The Git revision must come from the governed Space variable. Missing or malformed identity fails closed.</p><a href="/version">Open /version</a></article><article class="evidence-card"><span class="number">02 / RECEIPTS</span><h3>Declared-key chain</h3><p id="receipt-detail">Training and evaluation receipts are verified against the repository-declared key and canonical hash chain.</p><a href="/evidence">Open /evidence</a></article><article class="evidence-card"><span class="number">03 / RUNTIME</span><h3>Exact model bytes</h3><p>Q4_K_M GGUF bytes are fetched at image build from an immutable revision, size-checked, hash-checked, and loaded offline.</p><a href="/api/v1/identity">Open identity</a></article></div></section>
1185
+ <section class="section"><div class="boundary"><article><p class="eyebrow">What is measured</p><h3>Internal integrity and bounded execution</h3><ul><li>Exact GGUF revision, size, and SHA-256</li><li>Exact deploy-bound Git revision when configured</li><li>Declared-key training/evaluation receipt chain</li><li>Runtime readiness and deterministic request limits</li></ul></article><article><p class="eyebrow">What is not claimed</p><h3>Authenticity and quality remain bounded</h3><ul><li>No independent identity or key-ownership binding</li><li>No post-quantization quality or safety certification</li><li>No signed output or reproducible execution claim</li><li>No provider SLA, sensitive-data handling guarantee, or autonomy</li></ul></article></div></section></main>
1186
+ <footer><span>SZL Holdings / Khipu Loom / Apache-2.0</span><span class="mono">MEASURED, REPORTED, UNKNOWN, or UNAVAILABLE - never implied</span></footer></div>
1187
  <script>
1188
+ const b=document.querySelector('#run'),o=document.querySelector('#out'),p=document.querySelector('#prompt'),root=document.documentElement;
1189
+ const runtimeState=document.querySelector('#runtime-state'),sourceSha=document.querySelector('#source-sha'),requestState=document.querySelector('#request-state'),charCount=document.querySelector('#char-count'),sourceDetail=document.querySelector('#source-detail'),receiptDetail=document.querySelector('#receipt-detail');
1190
  let running=false,hasResult=false;
1191
+ function short(value){return typeof value==='string'&&value.length>12?value.slice(0,7)+'...'+value.slice(-7):value||'UNAVAILABLE'}
1192
+ function countChars(){charCount.textContent=p.value.length.toLocaleString()+' / 1,200 characters'}
1193
+ function renderStatus(status,failure){const ready=status==='READY';runtimeState.textContent=status||'UNAVAILABLE';runtimeState.className='state '+(ready?'ready':status==='FAILED'?'failed':'');b.disabled=!ready||running;b.setAttribute('aria-disabled',String(b.disabled));root.dataset.screenshotReady=String(ready);if(running)return;if(!hasResult)requestState.textContent=ready?'Runtime ready':status==='FAILED'?'Runtime failed':'Warming exact model bytes';if(ready){if(!hasResult)o.textContent='Runtime READY. Pull a thread when you are ready.';return}if(!hasResult)o.textContent=status==='FAILED'?'Runtime FAILED'+(failure?': '+failure:'')+'.':status==='STARTING'?'Runtime STARTING. Verifying exact model bytes and receipts...':'Runtime status unavailable; retrying...'}
1194
+ async function getJson(path){const r=await fetch(path,{cache:'no-store'});let j={};try{j=await r.json()}catch(_){j={}}return{ok:r.ok,status:r.status,json:j}}
1195
+ async function refresh(){const [health,version,evidence]=await Promise.allSettled([getJson('/health'),getJson('/version'),getJson('/evidence')]);if(health.status==='fulfilled')renderStatus(health.value.json.status,health.value.json.failure_code);else renderStatus('UNAVAILABLE');if(version.status==='fulfilled'){const sha=version.value.json.gitSha;sourceSha.textContent=short(sha);sourceDetail.textContent=sha?'Governed Git source '+sha+' is bound to this deployment.':'Exact governed Git source is unavailable; /version fails closed.'}if(evidence.status==='fulfilled'){const receipts=evidence.value.json.receipts||[];const verified=receipts.filter(x=>x.status==='DECLARED_KEY_SIGNATURES_VALID').length;receiptDetail.textContent=verified===2?'Two declared-key receipts are visible and chain-verified. Runtime outputs remain unsigned.':'Receipt evidence is not yet available; no green state is inferred.'}}
1196
+ p.addEventListener('input',countChars);b.addEventListener('click',async()=>{if(b.disabled)return;running=true;hasResult=false;b.disabled=true;b.setAttribute('aria-disabled','true');requestState.textContent='Inference in progress';o.textContent='Pulling the bounded model thread on free CPU...';try{const r=await fetch('/api/v1/infer',{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify({prompt:p.value,max_new_tokens:24})});const j=await r.json();hasResult=true;o.textContent=r.ok?j.output:JSON.stringify(j);requestState.textContent=r.ok?'Completed / output unsigned':'Request refused / '+r.status}catch(_){hasResult=true;o.textContent='Request unavailable. No result was fabricated.';requestState.textContent='Network unavailable'}finally{running=false;await refresh()}});
1197
+ countChars();refresh();setInterval(refresh,5000);
1198
  </script></body></html>"""
release.json CHANGED
@@ -1,15 +1,15 @@
1
  {
2
  "schema": "szl.space-source-release/v1",
3
- "release_id": "145e9425-ff95-444d-825e-b644530bf520",
4
  "source_files": {
5
  ".dockerignore": "dba1fb4c6538a44cd8d7e77f133af90a8e7927d3dee23f8694fe6d867238333c",
6
  "Dockerfile": "6d982909b8678c6ab3bfc21766f3356c1dedfff1c2efea5ba0fbc64ed7cff4b8",
7
  "LICENSE": "0a41cda63c0751e5cdb240864525fc8bf29b2d3f2cb5c6406b9bae97f1e1407b",
8
- "README.md": "7f3b1bac2c3b2648b6b5f3320f5ac7855e7bb4954ca323447eabcc3d521ac666",
9
- "app.py": "5f382fe7a6303a8e8cb5e0a44b60f13f8edc46d0e3a8f30dd94e8f759aff390b",
10
  "download_artifacts.py": "aa9f98b3d19753953864beae167b5e74872270c880e78430bb345a5f06b4ef36",
11
  "requirements.txt": "9f690793b7b9c6e1adce88244de01d77898d117779c3428b80190eabaf4658f9",
12
- "tests/test_app.py": "736b419a6f4b213661a9da33e6b68ae202cb636939cab63309fe415131f7af11",
13
- "verify_execution_record.py": "7ff66006fa6f405c8d31c1f2b9f6aca7c288e9eb3aef23e38122b1565d3cd6db"
14
  }
15
  }
 
1
  {
2
  "schema": "szl.space-source-release/v1",
3
+ "release_id": "c893e93c-9bd8-47e9-941e-f8613a608992",
4
  "source_files": {
5
  ".dockerignore": "dba1fb4c6538a44cd8d7e77f133af90a8e7927d3dee23f8694fe6d867238333c",
6
  "Dockerfile": "6d982909b8678c6ab3bfc21766f3356c1dedfff1c2efea5ba0fbc64ed7cff4b8",
7
  "LICENSE": "0a41cda63c0751e5cdb240864525fc8bf29b2d3f2cb5c6406b9bae97f1e1407b",
8
+ "README.md": "c2edfc0957ccd9f2719ca3c8e71baefd23a9e88d61cfc5d3445009ae470618cb",
9
+ "app.py": "992badf3f02189d7f44bb4cbb5881dce837ecc72f183a7dd40952cf0106a8e37",
10
  "download_artifacts.py": "aa9f98b3d19753953864beae167b5e74872270c880e78430bb345a5f06b4ef36",
11
  "requirements.txt": "9f690793b7b9c6e1adce88244de01d77898d117779c3428b80190eabaf4658f9",
12
+ "tests/test_app.py": "6538ee45b40e5d0dc12b1849b29c4dcb6b3184542199b0e6669c6239a73888e0",
13
+ "verify_execution_record.py": "1a64e3c8097409c19d971f711d63fbeb2066e3bfe804da31f684d0b795a529a6"
14
  }
15
  }
tests/test_app.py CHANGED
@@ -285,6 +285,77 @@ class AppContractTests(unittest.TestCase):
285
  else:
286
  os.environ[app.SOURCE_REVISION_ENV] = original
287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  def test_openai_model_catalog_is_immutable_and_unsigned(self):
289
  response = app.openai_models()
290
  payload = json.loads(response.body)
@@ -736,11 +807,21 @@ class AppContractTests(unittest.TestCase):
736
  def test_root_waits_for_readiness_before_enabling_inference(self):
737
  html = app.index()
738
  self.assertIn('id="run" disabled aria-disabled="true"', html)
739
- self.assertIn("Checking runtime", html)
740
- self.assertIn("fetch('/health'", html)
 
 
741
  self.assertIn("status==='READY'", html)
742
  self.assertIn("status==='STARTING'", html)
743
  self.assertIn("status==='FAILED'", html)
 
 
 
 
 
 
 
 
744
 
745
  def test_body_limiter_rejects_chunked_overflow(self):
746
  downstream_called = False
 
285
  else:
286
  os.environ[app.SOURCE_REVISION_ENV] = original
287
 
288
+ def test_operational_aliases_preserve_liveness_and_readiness(self):
289
+ original = app.state["status"]
290
+ try:
291
+ app.state["status"] = "STARTING"
292
+ self.assertEqual(200, app.healthz().status_code)
293
+ self.assertEqual(503, app.readyz().status_code)
294
+ app.state["status"] = "READY"
295
+ self.assertEqual(200, app.healthz().status_code)
296
+ self.assertEqual(200, app.readyz().status_code)
297
+ app.state["status"] = "FAILED"
298
+ self.assertEqual(503, app.healthz().status_code)
299
+ self.assertEqual(503, app.readyz().status_code)
300
+ finally:
301
+ app.state["status"] = original
302
+
303
+ def test_version_fails_closed_without_exact_deploy_revision(self):
304
+ original = os.environ.pop(app.SOURCE_REVISION_ENV, None)
305
+ try:
306
+ response = app.version()
307
+ payload = json.loads(response.body)
308
+ self.assertEqual(503, response.status_code)
309
+ self.assertIsNone(payload["gitSha"])
310
+ self.assertEqual("UNAVAILABLE", payload["evidenceState"])
311
+
312
+ os.environ[app.SOURCE_REVISION_ENV] = "b" * 40
313
+ response = app.version()
314
+ payload = json.loads(response.body)
315
+ self.assertEqual(200, response.status_code)
316
+ self.assertEqual("b" * 40, payload["gitSha"])
317
+ self.assertEqual("model-inference", payload["surface"])
318
+ finally:
319
+ if original is None:
320
+ os.environ.pop(app.SOURCE_REVISION_ENV, None)
321
+ else:
322
+ os.environ[app.SOURCE_REVISION_ENV] = original
323
+
324
+ def test_evidence_requires_source_and_verified_receipts(self):
325
+ original_revision = os.environ.get(app.SOURCE_REVISION_ENV)
326
+ original_state = dict(app.state)
327
+ try:
328
+ os.environ[app.SOURCE_REVISION_ENV] = "c" * 40
329
+ app.state.update(
330
+ {
331
+ "status": "READY",
332
+ "source_integrity": True,
333
+ "model_sha256": app.MODEL_SHA256,
334
+ "receipt_status": "DECLARED_KEY_SIGNATURES_VALID",
335
+ "receipt_evidence": {
336
+ "training_canonical_sha256": "d" * 64,
337
+ "eval_canonical_sha256": "e" * 64,
338
+ },
339
+ }
340
+ )
341
+ response = app.evidence()
342
+ payload = json.loads(response.body)
343
+ self.assertEqual(200, response.status_code)
344
+ self.assertEqual("MEASURED", payload["evidenceState"])
345
+ self.assertEqual(2, len(payload["receipts"]))
346
+ self.assertEqual("UNSIGNED", payload["outputProvenance"]["signatureStatus"])
347
+
348
+ app.state["receipt_status"] = "NOT_CHECKED"
349
+ response = app.evidence()
350
+ self.assertEqual(503, response.status_code)
351
+ finally:
352
+ app.state.clear()
353
+ app.state.update(original_state)
354
+ if original_revision is None:
355
+ os.environ.pop(app.SOURCE_REVISION_ENV, None)
356
+ else:
357
+ os.environ[app.SOURCE_REVISION_ENV] = original_revision
358
+
359
  def test_openai_model_catalog_is_immutable_and_unsigned(self):
360
  response = app.openai_models()
361
  payload = json.loads(response.body)
 
807
  def test_root_waits_for_readiness_before_enabling_inference(self):
808
  html = app.index()
809
  self.assertIn('id="run" disabled aria-disabled="true"', html)
810
+ self.assertIn("Checking the runtime and evidence threads", html)
811
+ self.assertIn("getJson('/health')", html)
812
+ self.assertIn("getJson('/version')", html)
813
+ self.assertIn("getJson('/evidence')", html)
814
  self.assertIn("status==='READY'", html)
815
  self.assertIn("status==='STARTING'", html)
816
  self.assertIn("status==='FAILED'", html)
817
+ self.assertIn("if(running)return;if(!hasResult)requestState", html)
818
+ self.assertIn("if(!hasResult)o.textContent", html)
819
+ self.assertIn('data-screenshot-ready="false"', html)
820
+ self.assertIn("prefers-reduced-motion:reduce", html)
821
+ self.assertIn("Every token leaves a", html)
822
+ self.assertIn('name="description"', html)
823
+ self.assertIn('property="og:title"', html)
824
+ self.assertIn('rel="canonical"', html)
825
 
826
  def test_body_limiter_rejects_chunked_overflow(self):
827
  downstream_called = False
verify_execution_record.py CHANGED
@@ -34,7 +34,7 @@ EXPECTED_MODEL = {
34
  "sha256": "13c1a1993063e1dff92f7413ccf48eaca6d48efc8801ae9af35961ae3396623a",
35
  }
36
  EXPECTED_SPACE_ID = "SZLHOLDINGS/szl-model-inference-lab"
37
- EXPECTED_RELEASE_ID = "145e9425-ff95-444d-825e-b644530bf520"
38
  EXPECTED_RECORD_HASH_SCOPE = (
39
  "canonical UTF-8 JSON with sorted keys and compact separators, "
40
  "excluding record_sha256"
 
34
  "sha256": "13c1a1993063e1dff92f7413ccf48eaca6d48efc8801ae9af35961ae3396623a",
35
  }
36
  EXPECTED_SPACE_ID = "SZLHOLDINGS/szl-model-inference-lab"
37
+ EXPECTED_RELEASE_ID = "c893e93c-9bd8-47e9-941e-f8613a608992"
38
  EXPECTED_RECORD_HASH_SCOPE = (
39
  "canonical UTF-8 JSON with sorted keys and compact separators, "
40
  "excluding record_sha256"