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

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

onboard: ## bring up a workstation: local sovereign forge + local cluster + sourceosctl
@echo "[continuum] onboard — scaffold: wires Gitea bring-up + kind/k3s + sourceos-devtools/sourceosctl"

Expand Down
1 change: 1 addition & 0 deletions capd/compute-plane.mesh.capd.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"scales_up_to": "caps.infra.cluster-scaleup.hyperswarm@0.1.0"
},
"policy": {
"availability": "needs-work",
"fail_closed": true,
"evidence_emitting": true,
"sensitive_never_untrusted": true,
Expand Down
1 change: 1 addition & 0 deletions capd/data-spheres.mesh.capd.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"scales_up_to": "caps.infra.cluster-scaleup.hyperswarm@0.1.0"
},
"policy": {
"availability": "almost-zd",
"immutable": true,
"integrity_by_construction": true,
"tenancy_by_construction": true,
Expand Down
1 change: 1 addition & 0 deletions capd/knowledge-commons.mesh.capd.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"scales_up_to": "caps.infra.cluster-scaleup.hyperswarm@0.1.0"
},
"policy": {
"availability": "almost-zd",
"content_addressed": true,
"citable": true,
"reproducibility_gate": true,
Expand Down
1 change: 1 addition & 0 deletions capd/volunteer-mesh-verification.mesh.capd.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"scales_up_to": "caps.infra.cluster-scaleup.hyperswarm@0.1.0"
},
"policy": {
"availability": "almost-zd",
"result_verification": true,
"fail_closed": true,
"redundant_quorum": true,
Expand Down
30 changes: 26 additions & 4 deletions tools/admission.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,39 @@

DEFAULT_QUOTA = {"max_concurrent": 4, "gpu_max": 2, "cost_budget": 100.0}

# Account tiers (BlueMix entitlement, done sovereign + light): a tier sets the quota AND which
# backends a subject may reach. `allowed_backends: None` means all.
TIERS = {
"free": {"max_concurrent": 1, "gpu_max": 0, "cost_budget": 5.0,
"allowed_backends": ["local", "wasm-edge"]},
"pro": {"max_concurrent": 4, "gpu_max": 2, "cost_budget": 100.0,
"allowed_backends": ["local", "wasm-edge", "k8s", "hpc-slurm", "p2p-mesh", "volunteer-boinc"]},
"enterprise": {"max_concurrent": 16, "gpu_max": 8, "cost_budget": 5000.0,
"allowed_backends": None},
}


class AdmissionController:
"""Per-subject (or per-project) quotas + a live consumption ledger.
"""Per-subject (or per-project) quotas + account tiers + a live consumption ledger.

With a `ledger_path`, consumption persists across processes (so a CLI enforces a real running
budget, not a fresh one each invocation)."""
budget, not a fresh one each invocation). A `tiers` map (subject -> tier name) applies the tier's
quota + backend entitlement, which explicit `quotas` may still override."""

def __init__(self, quotas: dict[str, dict] | None = None, ledger_path=None):
def __init__(self, quotas: dict[str, dict] | None = None, ledger_path=None,
tiers: dict[str, str] | None = None):
self._quotas = quotas or {}
self._tiers = tiers or {}
self._ledger_path = Path(ledger_path) if ledger_path else None
self._usage: dict[str, dict] = self._load()

def tier(self, key: str) -> str:
return self._tiers.get(key, "pro")

def allowed_backends(self, key: str) -> list | None:
"""The tier's backend entitlement — feed into compute_plane.place() policy. None = all."""
return TIERS.get(self.tier(key), {}).get("allowed_backends")

def _load(self) -> dict:
if self._ledger_path and self._ledger_path.exists():
try:
Expand All @@ -45,7 +66,8 @@ def _save(self) -> None:
self._ledger_path.write_text(json.dumps(self._usage, sort_keys=True))

def quota_for(self, key: str) -> dict:
return {**DEFAULT_QUOTA, **self._quotas.get(key, {})}
tier_q = {k: v for k, v in TIERS.get(self.tier(key), {}).items() if k != "allowed_backends"}
return {**DEFAULT_QUOTA, **tier_q, **self._quotas.get(key, {})} # tier, then explicit override

def usage(self, key: str) -> dict:
return self._usage.setdefault(key, {"concurrent": 0, "gpu": 0, "cost": 0.0})
Expand Down
49 changes: 49 additions & 0 deletions tools/availability.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env python3
"""Availability maturity grade — the BlueMix / DW-DevOps Zero-Downtime legend as a governance artifact.

Every capability carries an honest availability GRADE (like the commons' reproducible/declared grade).
The ladder is the continuous-availability legend from the Gen4 diagram:

non-managed -> needs-work -> almost-zd -> zero-downtime

A CapD declares its grade in `policy.availability` (default: non-managed). This reports the estate's
availability posture at a glance and gives promotion a hook — a capability shouldn't claim a grade it
can't back. Sovereign + light: a legend, not an IBM stack.
"""
from __future__ import annotations

import json
from pathlib import Path

GRADES = ("non-managed", "needs-work", "almost-zd", "zero-downtime")
_ROOT = Path(__file__).resolve().parent.parent


def grade_rank(grade: str) -> int:
return GRADES.index(grade) if grade in GRADES else 0


def estate_availability(root=None) -> dict:
"""Read every CapD's declared availability grade. Returns per-capability grades + a histogram."""
root = Path(root or _ROOT)
caps = []
d = root / "capd"
for f in sorted(d.glob("*.capd.json")) if d.is_dir() else []:
try:
data = json.loads(f.read_text())
except (OSError, json.JSONDecodeError):
continue
grade = data.get("policy", {}).get("availability", "non-managed")
if grade not in GRADES:
grade = "non-managed"
caps.append({"capability_id": data.get("capability_id", f.stem), "availability": grade})
hist = {g: sum(1 for c in caps if c["availability"] == g) for g in GRADES}
return {"capabilities": sorted(caps, key=lambda c: -grade_rank(c["availability"])),
"histogram": hist, "total": len(caps)}


if __name__ == "__main__":
report = estate_availability()
print(json.dumps({"histogram": report["histogram"], "total": report["total"],
"top": [c for c in report["capabilities"] if c["availability"] != "non-managed"]},
indent=2))
27 changes: 26 additions & 1 deletion tools/test_admission.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,35 @@ def test_subjects_have_isolated_budgets():


def test_default_quota_applies_to_unknown_subject():
ac = adm.AdmissionController()
ac = adm.AdmissionController(tiers={"spiffe://who/dis": "__none__"}) # unknown tier -> DEFAULT_QUOTA
assert ac.quota_for("spiffe://who/dis") == adm.DEFAULT_QUOTA


def test_tier_sets_quota_and_backend_entitlement():
ac = adm.AdmissionController(tiers={"free-user": "free", "ent-user": "enterprise"})
assert ac.quota_for("free-user")["gpu_max"] == 0
assert ac.allowed_backends("free-user") == ["local", "wasm-edge"]
assert ac.allowed_backends("ent-user") is None # enterprise = all backends
assert ac.quota_for("ent-user")["max_concurrent"] == 16


def test_default_tier_is_pro():
ac = adm.AdmissionController()
assert ac.tier("anyone") == "pro" and ac.quota_for("anyone")["gpu_max"] == 2


def test_explicit_quota_overrides_tier():
ac = adm.AdmissionController(quotas={"u": {"gpu_max": 5}}, tiers={"u": "free"})
assert ac.quota_for("u")["gpu_max"] == 5 # explicit override wins
assert ac.quota_for("u")["max_concurrent"] == 1 # ...but the rest is the free tier


def test_free_tier_denies_gpu_work():
ac = adm.AdmissionController(tiers={"u": "free"})
r = ac.admit("u", {"needs_gpu": True})
assert not r["admitted"] and "gpu_max" in r["exceeded"]


def test_ledger_persists_consumption_across_controllers():
import pathlib
import tempfile
Expand Down
27 changes: 27 additions & 0 deletions tools/test_availability.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/usr/bin/env python3
"""Tests for the availability maturity grade (the ZD legend over CapDs)."""
import availability as av


def test_grade_ladder_is_ordered():
assert av.GRADES == ("non-managed", "needs-work", "almost-zd", "zero-downtime")
assert av.grade_rank("almost-zd") > av.grade_rank("needs-work") > av.grade_rank("non-managed")
assert av.grade_rank("bogus") == 0 # unknown -> lowest


def test_estate_reports_declared_grades_and_defaults_the_rest():
r = av.estate_availability()
assert r["total"] >= 5
grades = {c["capability_id"]: c["availability"] for c in r["capabilities"]}
assert all(g in av.GRADES for g in grades.values()) # every grade is valid (default applied)
assert r["histogram"]["almost-zd"] >= 3 # commons, verification, data-spheres
assert any(g == "needs-work" for g in grades.values()) # compute-plane


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)} availability tests passed")
sys.exit(0)
1 change: 1 addition & 0 deletions tools/validate.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
"tools/lease_scheduler.py",
"tools/devmode.py",
"tools/data_sphere.py",
"tools/availability.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 Down
Loading