Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ lease: ## pull/lease scheduler demo: workers pull WUs, crash-stop re-lending, or
sphere: ## data-sphere demo: immutable dm-verity sphere, construction-tenancy, intent x link x durability
cd tools && python3 data_sphere.py

inference: ## sovereign inference demo: models as data spheres, fail-closed sovereign routing
cd tools && python3 inference.py

availability: ## report the estate's availability-maturity grades (the Zero-Downtime legend)
cd tools && python3 availability.py

Expand Down
30 changes: 30 additions & 0 deletions capd/sovereign-inference.mesh.capd.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"capability_id": "caps.inference.sovereign@0.1.0",
"kind": "inference.sovereign",
"status": "experimental",
"name": "Sovereign inference — run LLMs on our own mesh, not a cloud provider",
"description": "The whole point of a sovereign PaaS: a sensitive prompt must never leave for a vendor LLM (OpenAI/Anthropic/Gemini). The mesh serves its own models — weights are immutable data spheres (provenance-tracked, residency ring-fenced, read-Grant-gated), served on a TRUSTED GPU backend the Needs firewall keeps sensitive work off untrusted/volunteer/vendor nodes. Inference routing is fail-closed: sensitive inference goes to a sovereign endpoint or it BLOCKS; it never silently falls back to a cloud connector. Where it runs — the always-on cloud twin or the box (direct/LAN) — is a placement decision; both are sovereign, twin by default.",
"links": {
"engine": "tools/inference.py",
"models": "tools/data_sphere.py",
"placement": "tools/compute_plane.py",
"grant_authority": "tools/mcp_a2a_grant.py",
"portal": "tools/portal_server.py",
"reference_pattern": "self-hosted vLLM/llama.cpp/Ollama/TGI on our mesh vs cloud LLM APIs — sovereign, governed, sensitive-data-safe; models as immutable data spheres"
},
"composes_with": {
"data_spheres": "caps.data.spheres@0.1.0",
"compute_plane": "caps.compute.mesh-plane@0.1.0",
"control_plane": "caps.infra.paas.continuum-local@0.1.0",
"scales_up_to": "caps.infra.cluster-scaleup.hyperswarm@0.1.0"
},
"policy": {
"availability": "needs-work",
"sovereign_first": true,
"sensitive_never_vendor": true,
"models_as_data_spheres": true,
"fail_closed": true,
"gpu_trusted_only": true,
"evidence_emitting": true
}
}
77 changes: 77 additions & 0 deletions tools/inference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
"""Sovereign inference — run LLMs on OUR mesh, not a cloud provider.

The whole point of a sovereign PaaS: a sensitive prompt must NEVER leave for a vendor LLM
(OpenAI/Anthropic/Gemini/…). The mesh serves its own models — weights are immutable DATA SPHERES
(provenance-tracked, residency ring-fenced), served on a TRUSTED GPU backend behind a Grant — and
inference routing is fail-closed: sensitive inference goes to a sovereign endpoint or it BLOCKS; it
never silently falls back to a cloud connector. That is the difference between "our infrastructure"
and "a cloud provider like Claude."

Where inference runs — the durable **twin** (always-on cloud K3s) or the **box** (direct/LAN when it
is up) — is a placement decision the compute plane already makes; both are sovereign, and the twin
is the default rendezvous because the box sleeps and the twin does not.
"""
from __future__ import annotations

import data_sphere as ds

ENGINES = ("vllm", "llama.cpp", "ollama", "tgi")


def model_sphere(*, name: str, version: str, weights_digest: str, params_b: float,
engine: str = "vllm", residency: str = "cluster") -> dict:
"""A model is a data sphere: immutable weights, pinned integrity, provenance, residency-fenced.
Loading the weights therefore needs a read Grant, and a mutated model is un-citable."""
s = ds.mint_sphere(name=f"model/{name}", version=version,
content={"weights": weights_digest, "params_b": params_b, "engine": engine},
residency=residency, direction="ingress",
provenance={"kind": "model-weights", "params_b": params_b, "engine": engine})
s["model_name"] = name
s["params_b"] = params_b
s["engine"] = engine
return s


def inference_service_workload(model: dict, *, replicas: int = 1, sensitivity: str = "sensitive") -> dict:
"""Serving a model = a GPU workload the compute plane places on a TRUSTED backend (the Needs
firewall keeps a sensitive model off untrusted/volunteer/vendor backends). Dispatch it with the
executor like any other workload; reading the weights needs a read Grant on the model sphere."""
return {"name": "infer-" + model["model_name"].replace("/", "-"),
"kind": "inference-service", "engine": model.get("engine", "vllm"),
"model_sphere": model["sphere_id"], "needs_gpu": True, "scalable": True,
"replicas": replicas, "effect": "compute", "sensitivity": sensitivity,
"needs": {"residency": model.get("residency", "cluster")}}


def route_inference(*, model: dict, sovereign_endpoints: list, prompt_sensitivity: str = "sensitive",
allow_vendor: bool = False) -> dict:
"""Fail-closed sovereign-first routing. Returns {route, endpoint, reason}. A sensitive prompt (or
a residency-fenced model) is sent to a sovereign endpoint or BLOCKED — never a cloud LLM."""
if sovereign_endpoints:
return {"route": "sovereign", "endpoint": sovereign_endpoints[0],
"reason": "served on our own mesh — the prompt never leaves"}
sovereign_required = (prompt_sensitivity == "sensitive"
or model.get("residency") in ("local", "cluster", "eu"))
if sovereign_required:
return {"route": "blocked", "endpoint": None,
"reason": "no sovereign endpoint up; REFUSING to send sensitive inference to a cloud LLM"}
if allow_vendor:
return {"route": "vendor", "endpoint": "connector",
"reason": "non-sensitive, no sovereign endpoint: policy-allowed vendor fallback"}
return {"route": "blocked", "endpoint": None,
"reason": "no sovereign endpoint and vendor fallback not permitted"}


if __name__ == "__main__":
import json
m = model_sphere(name="llama-3-70b", version="q4", weights_digest="sha256:" + "ab" * 32,
params_b=70, engine="vllm", residency="any")
print(json.dumps({
"model_sphere": m["sphere_id"],
"service": inference_service_workload(m)["name"],
"sensitive_no_endpoint": route_inference(model=m, sovereign_endpoints=[], prompt_sensitivity="sensitive")["route"],
"sensitive_with_endpoint": route_inference(model=m, sovereign_endpoints=["twin:vllm:8000"])["route"],
"normal_vendor_fallback": route_inference(model=m, sovereign_endpoints=[],
prompt_sensitivity="normal", allow_vendor=True)["route"],
}, indent=2))
70 changes: 66 additions & 4 deletions tools/portal_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,55 @@ def _commons() -> dict:
"cite": r["cite"]} for r in recs]}


def _endpoint() -> str:
"""Which surface this portal is — the always-on cloud 'twin' or the 'box' (direct/LAN). Set
SOURCEOS_ENDPOINT=twin on the twin; defaults to box."""
import os
return os.environ.get("SOURCEOS_ENDPOINT", "box")


def _inference() -> dict:
"""Sovereign-inference posture: our own models, and where a sensitive prompt would route (never a
cloud LLM). Sovereign endpoints = live trusted GPU backends."""
inf = _sib("inference")
reg = _registry()
avail = reg.availability()
sovereign_up = [b for b in ("hpc-slurm", "k8s") if avail.get(b, 0) > 0]
models = [inf.model_sphere(name=n, version=v, weights_digest="sha256:" + "ab" * 32,
params_b=p, engine="vllm")
for (n, v, p) in [("llama-3-8b", "q4", 8), ("mixtral-8x7b", "q4", 47), ("nomic-embed", "f16", 0.1)]]
return {"endpoint": _endpoint(),
"posture": "sovereign-first — sensitive inference never leaves for a cloud LLM",
"sovereign_endpoints": sovereign_up,
"models": [{"model": m["model_name"], "params_b": m["params_b"],
"route": inf.route_inference(model=m, sovereign_endpoints=sovereign_up,
prompt_sensitivity="sensitive")["route"]}
for m in models]}


_MANIFEST = json.dumps({
"name": "SourceOS Continuum", "short_name": "Continuum", "start_url": "/", "scope": "/",
"display": "standalone", "background_color": "#0b0d12", "theme_color": "#0b0d12",
"description": "See and reach your infrastructure — twin or box.",
"icons": [{"src": "data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'>"
"<rect width='100' height='100' rx='20' fill='%230b0d12'/><circle cx='50' cy='50' r='28' fill='%237ee2a8'/>"
"<circle cx='24' cy='30' r='7' fill='%238fb8ff'/><circle cx='76' cy='30' r='7' fill='%238fb8ff'/></svg>",
"sizes": "any", "type": "image/svg+xml", "purpose": "any maskable"}]})

# cache-first service worker so the console still loads on a flaky mobile link (offline-ish shell).
_SW = ("const C='continuum-v1';"
"self.addEventListener('install',e=>{self.skipWaiting();e.waitUntil(caches.open(C).then(c=>c.add('/')))});"
"self.addEventListener('activate',e=>e.waitUntil(self.clients.claim()));"
"self.addEventListener('fetch',e=>{if(e.request.method!=='GET')return;"
"e.respondWith(fetch(e.request).then(r=>{const cp=r.clone();caches.open(C).then(c=>c.put(e.request,cp));return r})"
".catch(()=>caches.match(e.request)))});")


_CONSOLE = """<!doctype html><html lang=en><head><meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1"><title>SourceOS Continuum — Console</title>
<meta name=viewport content="width=device-width,initial-scale=1,viewport-fit=cover"><title>SourceOS Continuum — Console</title>
<meta name=theme-color content=#0b0d12><link rel=manifest href=/manifest.webmanifest>
<meta name=apple-mobile-web-app-capable content=yes><meta name=apple-mobile-web-app-status-bar-style content=black-translucent>
<meta name=apple-mobile-web-app-title content=Continuum>
<style>
:root{color-scheme:light dark}body{font:15px/1.5 system-ui,sans-serif;margin:0;background:#0b0d12;color:#e8ecf4}
header{padding:20px 28px;border-bottom:1px solid #232838;background:#11141d}
Expand All @@ -128,8 +175,8 @@ def _commons() -> dict:
.pill.exp{background:#2f2a1a;color:#e2c77e}code{color:#8fb8ff}.muted{color:#6b7488;font-size:13px}
.gov{color:#7ee2a8;font-size:12px}
</style></head><body>
<header><h1>SourceOS Continuum — Developer Console</h1>
<div class=sub>Read-only view of the governed surface. Actions run through the MCP surface + fail-closed promotion gate.</div></header>
<header><h1>SourceOS Continuum — Developer Console <span id=epbadge class=pill>…</span></h1>
<div class=sub>Read-only view of the governed surface. Actions run through the MCP surface + fail-closed promotion gate. Installable on mobile; reaches the twin (always-on) or the box (direct/LAN).</div></header>
<main>
<section id=caps><h2>Capabilities</h2><div class=muted>loading…</div></section>
<section id=life><h2>Lifecycle</h2><div class=muted>loading…</div></section>
Expand All @@ -144,6 +191,9 @@ def _commons() -> dict:
<div class=muted>Every capability + workload as a citable, content-addressed record (Zenodo-style). <span class=gov>reproducible</span> = provenance carries the digests to reproduce it; <span class=muted>declared</span> = registered but not yet reproducibility-backed.</div>
<div id=commonssum class=muted style=margin-top:8px></div>
<div id=commonsbody class=muted style=margin-top:10px>loading…</div></section>
<section id=infer><h2>Sovereign inference &mdash; our own LLMs</h2>
<div class=muted>Models are immutable data spheres served on trusted GPU nodes. A <b>sensitive</b> prompt routes to a sovereign endpoint or <span class=gov>blocks</span> &mdash; it never leaves for a cloud LLM.</div>
<div id=inferbody class=muted style=margin-top:10px>loading…</div></section>
<section id=evi><h2>Sealed evidence (latest)</h2><div class=muted>loading…</div></section>
</main>
<script>
Expand Down Expand Up @@ -171,6 +221,13 @@ def _commons() -> dict:
document.getElementById('commonsbody').innerHTML=
d.records.map(r=>`<div class=row><span><code>${esc(r.commons_id.split('+')[0])}</code> <span class=muted>${esc(r.asset_type)}</span></span>`+
`<span class="pill ${r.reproducibility==='reproducible'?'':'exp'}">${esc(r.reproducibility)}</span></div>`).join('')})
j('/api/inference').then(d=>{
document.getElementById('epbadge').textContent=(d.endpoint||'box')==='twin'?'twin':'box';
document.getElementById('inferbody').innerHTML=
`<div class=muted style=margin-bottom:6px>${esc(d.posture)} &middot; sovereign endpoints: ${esc((d.sovereign_endpoints||[]).join(', ')||'none up')}</div>`+
d.models.map(m=>`<div class=row><span><code>${esc(m.model)}</code> <span class=muted>${esc(m.params_b)}B</span></span>`+
`<span class="pill ${m.route==='sovereign'?'':'exp'}">${esc(m.route)}</span></div>`).join('')})
if('serviceWorker' in navigator){navigator.serviceWorker.register('/sw.js').catch(()=>{})}
</script></body></html>"""


Expand All @@ -181,9 +238,14 @@ def route(path: str) -> tuple[int, str, str]:
return 200, "text/html; charset=utf-8", _CONSOLE
if path == "/healthz":
return 200, "text/plain", "ok"
if path == "/manifest.webmanifest":
return 200, "application/manifest+json", _MANIFEST
if path == "/sw.js":
return 200, "application/javascript", _SW
api = {"/api/capabilities": _capabilities, "/api/lifecycle": _lifecycle,
"/api/evidence": _evidence, "/api/compute": _compute,
"/api/mesh": _mesh, "/api/placements": _placements, "/api/commons": _commons}
"/api/mesh": _mesh, "/api/placements": _placements, "/api/commons": _commons,
"/api/inference": _inference}
if path in api:
return 200, "application/json", json.dumps(api[path](), indent=2, sort_keys=True)
return 404, "text/plain", "not found"
Expand Down
67 changes: 67 additions & 0 deletions tools/test_inference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/usr/bin/env python3
"""Tests for sovereign inference. Load-bearing: a model is an immutable data sphere, serving it is a
trusted-GPU workload, and routing NEVER sends sensitive inference to a cloud LLM (fail-closed)."""
import inference as inf


def test_model_is_an_immutable_integrity_pinned_data_sphere():
m = inf.model_sphere(name="llama", version="q4", weights_digest="sha256:" + "ab" * 32,
params_b=8, engine="vllm")
assert m["sphere_id"].startswith("sphere:model/llama@q4+")
assert m["immutable"] is True and m["root_hash"].startswith("sha256:")
assert m["engine"] == "vllm" and m["params_b"] == 8


def test_serving_a_model_is_a_trusted_gpu_workload_referencing_the_sphere():
m = inf.model_sphere(name="llama", version="q4", weights_digest="sha256:" + "ab" * 32, params_b=8)
wl = inf.inference_service_workload(m, sensitivity="sensitive")
assert wl["needs_gpu"] is True and wl["sensitivity"] == "sensitive"
assert wl["model_sphere"] == m["sphere_id"]
assert wl["needs"]["residency"] == "cluster"


def test_routing_prefers_a_sovereign_endpoint():
m = inf.model_sphere(name="x", version="1", weights_digest="sha256:" + "cd" * 32, params_b=1)
r = inf.route_inference(model=m, sovereign_endpoints=["twin:vllm:8000"])
assert r["route"] == "sovereign" and r["endpoint"] == "twin:vllm:8000"


def test_sensitive_inference_blocks_rather_than_leaking_to_a_cloud_llm():
m = inf.model_sphere(name="x", version="1", weights_digest="sha256:" + "cd" * 32, params_b=1)
r = inf.route_inference(model=m, sovereign_endpoints=[], prompt_sensitivity="sensitive")
assert r["route"] == "blocked" and r["endpoint"] is None
assert "REFUSING" in r["reason"]


def test_residency_fenced_model_forces_sovereign_even_for_normal_prompts():
m = inf.model_sphere(name="x", version="1", weights_digest="sha256:" + "cd" * 32, params_b=1,
residency="eu")
r = inf.route_inference(model=m, sovereign_endpoints=[], prompt_sensitivity="normal")
assert r["route"] == "blocked" # residency ring-fence overrides "normal"


def test_non_sensitive_may_fall_back_to_a_vendor_only_when_allowed():
m = inf.model_sphere(name="x", version="1", weights_digest="sha256:" + "cd" * 32, params_b=1,
residency="any")
assert inf.route_inference(model=m, sovereign_endpoints=[], prompt_sensitivity="normal",
allow_vendor=True)["route"] == "vendor"
assert inf.route_inference(model=m, sovereign_endpoints=[], prompt_sensitivity="normal",
allow_vendor=False)["route"] == "blocked"


def test_inference_service_places_on_a_trusted_gpu_backend():
import compute_plane as cp
m = inf.model_sphere(name="x", version="1", weights_digest="sha256:" + "cd" * 32, params_b=70,
residency="cluster")
wl = inf.inference_service_workload(m)
d = cp.place(wl, {}, {b: 100 for b in cp.BACKENDS})
assert d["backend"] in ("hpc-slurm", "k8s") and d["backend_trust"] == "trusted" # never volunteer/vendor


if __name__ == "__main__":
import sys
fns = [v for k, v in sorted(globals().items()) if k.startswith("test_")]
for fn in fns:
fn()
print(f"ok: {len(fns)} inference tests passed")
sys.exit(0)
23 changes: 23 additions & 0 deletions tools/test_portal_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,29 @@ def test_unknown_path_is_404():
assert status == 404


def test_pwa_manifest_and_service_worker_are_served():
st, ct, body = ps.route("/manifest.webmanifest")
assert st == 200 and "manifest" in ct and "Continuum" in body and "standalone" in body
st2, ct2, _ = ps.route("/sw.js")
assert st2 == 200 and "javascript" in ct2


def test_console_is_installable_and_shows_sovereign_inference():
html = ps.route("/")[2]
assert "rel=manifest" in html and "Sovereign inference" in html and "epbadge" in html


def test_inference_api_is_sovereign_first_and_fail_closed_without_endpoints():
with tempfile.TemporaryDirectory() as td:
old, ps._HEARTBEATS = ps._HEARTBEATS, pathlib.Path(td) # no live GPU backend -> no sovereign endpoint
try:
d = json.loads(ps.route("/api/inference")[2])
assert "endpoint" in d and d["sovereign_endpoints"] == []
assert all(m["route"] == "blocked" for m in d["models"]) # never a cloud LLM
finally:
ps._HEARTBEATS = old


def test_devspace_capability_is_surfaced():
caps = json.loads(ps.route("/api/capabilities")[2])["capabilities"]
ids = {c.get("capability_id") for c in caps}
Expand Down
3 changes: 3 additions & 0 deletions tools/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"capd/self-healing-loop.mesh.capd.json",
"capd/volunteer-mesh-verification.mesh.capd.json",
"capd/data-spheres.mesh.capd.json",
"capd/sovereign-inference.mesh.capd.json",
"tools/promotion_gate.py",
"tools/portal_server.py",
"tools/compute_plane.py",
Expand All @@ -42,6 +43,7 @@
"tools/devmode.py",
"tools/data_sphere.py",
"tools/availability.py",
"tools/inference.py",
]
CAPD_KEYS = ("capability_id", "kind", "status", "links", "composes_with", "policy")
# Every CapD in capd/ must carry the core keys and parse — not just the flagship control-plane one.
Expand All @@ -53,6 +55,7 @@
"capd/self-healing-loop.mesh.capd.json": "caps.compute.self-healing-loop",
"capd/volunteer-mesh-verification.mesh.capd.json": "caps.compute.volunteer-mesh-verification",
"capd/data-spheres.mesh.capd.json": "caps.data.spheres",
"capd/sovereign-inference.mesh.capd.json": "caps.inference.sovereign",
}

errors: list[str] = []
Expand Down
Loading