docs: prepare safe public registry resume and access handoff
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Reject generated-only commits / generated-commit-guard (push) Successful in 8s

This commit is contained in:
codex 2026-10-14 12:32:20 +02:00
parent 02ec62ca61
commit 0e7bcd128b
5 changed files with 586 additions and 5 deletions

View file

@ -0,0 +1,37 @@
{
"id": "CUST81-REUSE-PUBLIC-REGISTRATION-R1",
"supersedes": "CUST81-REUSE-REGISTRATION-001 for the public-only batch",
"revision": 1,
"status": "prepared; not executed",
"authority": "User requested establishment of the reviewed capabilities with reuse-surface. This revision is limited to the 31 anonymously readable public repositories. It does not authorize or include private-source registration.",
"target": "https://reuse.coulomb.social/v1/repos",
"repositories": 31,
"excluded_private_repositories": [
"rapp-openbao",
"rapp-policy-nexus",
"rapp-postgres",
"rapp-sbom-nexus",
"rapp-telemetry",
"rapp-tenant-engine",
"rapp-user-engine"
],
"plan_file": "hub-public-resume-plan.json",
"plan_sha256": "768449eaec05f38c6820f2747a2ef388b10b57a341dc01768218646499aaf39b",
"helper_file": "register_public_hub.py",
"helper_sha256": "c6a5f08e01af3a5c4b1d6557859f4400eaba0d7eb0bb1976f45bba6bc5a05fda",
"verification_file": "test_register_public_hub.py",
"verification_sha256": "519cd624eef4ad3c0ed97ab686368b4ffb26985066c8baa2d804e1c6c1af8e02",
"credential_lane": "Existing reuse-surface-hub-write-token route via warden access --exec, only if owner admission has been provisioned and verified. No credential export or persistence.",
"preconditions": [
"The helper confirms its 31 actions exactly match hub-public-registration-plan.json and rejects all seven private repositories.",
"Before any registration write, the helper anonymously re-fetches the immutable index and capability entries and the stable main index for each planned repository; all bytes must match local published artifacts.",
"The helper reads GET /v1/repos and compares every submitted registration body field. A conflicting existing row or any POST 409 halts the batch.",
"The write token is available only in the execution child after scoped owner access is confirmed."
],
"expected": "Every planned public registration exists with the exact submitted fields, and the 31 public-source capabilities are discoverable from a fresh hosted federation response.",
"receipt": "Append-only sanitized JSONL at hub-public-resume-receipts.jsonl; includes attempt ID, timestamp, plan hash, repo, outcome and HTTP status only. Each POST has a durable post_intent event before transmission; a timeout records transport_unknown and stops. It never stores tokens, response bodies or headers.",
"verification": "The helper performs a fresh GET /v1/repos after writes and appends readback_verified only if all 31 submitted fields match. Then fetch a fresh hosted federation response. Confirm all reviewed public capability IDs appear exactly once, no unexpected duplicates appear, and source bytes match preflight. Retain status and hashes, not credential material.",
"rollback": "For a uniquely attributable row with outcome=applied in this proposal attempt, issue PATCH /v1/repos/{repo} with {\"enabled\":false}; do not delete registrations. Then GET each affected row and confirm enabled=false, and fetch a fresh federation response to confirm its capabilities are absent. Never change already_matches rows. If a POST has post_intent without a confirmed result, first read back that repo and resolve its state; do not roll it back based only on an ambiguous transport outcome.",
"cost": "31 bounded metadata registrations, anonymous reads limited to these 31 repositories, and public readback on existing services; no deployment or recurring resource commitment.",
"risk": "A stale readback can race with another registrar, or a write may partially succeed before transport failure. Each attempt appends evidence; 409/conflict halts. Resume by reading current state again, never by blindly replaying POSTs."
}

View file

@ -0,0 +1,33 @@
[
{"method":"POST","path":"/v1/repos","body":{"repo":"approval-engine","url":"https://forgejo.coulomb.social/coulomb/approval-engine/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"emergent-security","url":"https://forgejo.coulomb.social/coulomb/emergent-security/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"fin-hub","url":"https://forgejo.coulomb.social/coulomb/fin-hub/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"gate-house","url":"https://forgejo.coulomb.social/coulomb/gate-house/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"glas-harness","url":"https://forgejo.coulomb.social/coulomb/glas-harness/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"informed-decision","url":"https://forgejo.coulomb.social/coulomb/informed-decision/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"kings-guard","url":"https://forgejo.coulomb.social/coulomb/kings-guard/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"maturity-engine","url":"https://forgejo.coulomb.social/coulomb/maturity-engine/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"ops-mason","url":"https://forgejo.coulomb.social/coulomb/ops-mason/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"policy-nexus","url":"https://forgejo.coulomb.social/coulomb/policy-nexus/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"rail-kubernetes","url":"https://forgejo.coulomb.social/coulomb/rail-kubernetes/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"railiance-bootstrap","url":"https://forgejo.coulomb.social/coulomb/railiance-bootstrap/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"railiance-master","url":"https://forgejo.coulomb.social/coulomb/railiance-master/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"railiance-telemetry","url":"https://forgejo.coulomb.social/coulomb/railiance-telemetry/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"rapp-playwright","url":"https://forgejo.coulomb.social/coulomb/rapp-playwright/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"reef-railiance","url":"https://forgejo.coulomb.social/coulomb/reef-railiance/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"rein-aharness","url":"https://forgejo.coulomb.social/coulomb/rein-aharness/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"rein-openweights","url":"https://forgejo.coulomb.social/coulomb/rein-openweights/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"repo-manager","url":"https://forgejo.coulomb.social/coulomb/repo-manager/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"resource-control","url":"https://forgejo.coulomb.social/coulomb/resource-control/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"risk-nexus","url":"https://forgejo.coulomb.social/coulomb/risk-nexus/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"role-engine","url":"https://forgejo.coulomb.social/coulomb/role-engine/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"runbook-tutorials","url":"https://forgejo.coulomb.social/coulomb/runbook-tutorials/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"sand-boxer","url":"https://forgejo.coulomb.social/coulomb/sand-boxer/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"sbom-nexus","url":"https://forgejo.coulomb.social/coulomb/sbom-nexus/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"secrets-engine","url":"https://forgejo.coulomb.social/coulomb/secrets-engine/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"security-canon","url":"https://forgejo.coulomb.social/coulomb/security-canon/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"tenant-engine","url":"https://forgejo.coulomb.social/coulomb/tenant-engine/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"whitehat-security","url":"https://forgejo.coulomb.social/coulomb/whitehat-security/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"zone-engine","url":"https://forgejo.coulomb.social/coulomb/zone-engine/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}},
{"method":"POST","path":"/v1/repos","body":{"repo":"rail-knative","url":"https://forgejo.coulomb.social/coulomb/rail-knative/raw/branch/main/registry/indexes/capabilities.yaml","domain":"infotech","enabled":true,"required":false,"registered_by":"codex-CUST-WP-0081"}}
]

View file

@ -0,0 +1,304 @@
"""Bounded resume helper for the 31 public-only NetKingdom registrations.
Nothing runs at import time. Applying requires the explicit --apply flag and
REUSE_SURFACE_TOKEN. Private repositories are rejected from this plan.
"""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import sys
import urllib.error
import urllib.request
import uuid
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Callable
OUT = Path(__file__).resolve().parent
BASE = "https://reuse.coulomb.social"
PLAN_NAME = "hub-public-resume-plan.json"
SOURCE_PLAN_NAME = "hub-public-registration-plan.json"
PRIVATE_REPOS = {
"rapp-openbao", "rapp-policy-nexus", "rapp-postgres", "rapp-sbom-nexus",
"rapp-telemetry", "rapp-tenant-engine", "rapp-user-engine",
}
MAX_SOURCE_BYTES = 2 * 1024 * 1024
class NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, *args: Any, **kwargs: Any) -> None:
return None
def read_json(path: Path) -> Any:
return json.loads(path.read_text(encoding="utf-8"))
def validate_plan(plan: list[dict[str, Any]], original_public: list[dict[str, Any]]) -> set[str]:
"""Require an exact copy of the 31-item public-only source plan."""
if plan != original_public or len(plan) != 31:
raise ValueError("public resume plan differs from the approved 31-item public plan")
repos: list[str] = []
for action in plan:
if action.get("method") != "POST" or action.get("path") != "/v1/repos":
raise ValueError("only POST /v1/repos actions are allowed")
body = action.get("body")
if not isinstance(body, dict) or not isinstance(body.get("repo"), str):
raise ValueError("registration body has no repo slug")
repo = body["repo"]
if repo in PRIVATE_REPOS:
raise ValueError("private repository is forbidden in public resume plan")
expected_url = f"https://forgejo.coulomb.social/coulomb/{repo}/raw/branch/main/registry/indexes/capabilities.yaml"
if body.get("url") != expected_url:
raise ValueError(f"unexpected source URL for {repo}")
if body.get("domain") != "infotech" or body.get("enabled") is not True or body.get("required") is not False:
raise ValueError(f"unexpected registration fields for {repo}")
repos.append(repo)
if len(repos) != len(set(repos)):
raise ValueError("duplicate repository in public resume plan")
return set(repos)
def body_matches(body: dict[str, Any], current: dict[str, Any]) -> bool:
"""Compare every submitted field; extra hub-managed fields are permitted."""
return all(key in current and current[key] == value for key, value in body.items())
def validate_readback(plan: list[dict[str, Any]], rows: list[dict[str, Any]]) -> None:
"""Require a fresh hub readback to contain every planned body exactly."""
by_repo = {row.get("repo"): row for row in rows}
if len(by_repo) != len(rows):
raise ValueError("hub readback contains duplicate repository rows")
for action in plan:
body = action["body"]
current = by_repo.get(body["repo"])
if current is None or not body_matches(body, current):
raise ValueError("hub readback does not match the public registration plan")
def verify_public_sources(
root: Path,
plan: list[dict[str, Any]],
publications: list[dict[str, Any]],
inventory: dict[str, Any],
fetch: Callable[[str], bytes],
) -> None:
"""Freshly verify only the planned public repos before registration writes."""
commits = {
row["repo"]: row["commit"]
for row in publications
if row.get("verified_remote") and row.get("repo") and row.get("commit")
}
capabilities: dict[str, list[str]] = {}
for item in inventory["capabilities"]:
capabilities.setdefault(item["repo"], []).append(item["entry_path"])
repos = [action["body"]["repo"] for action in plan]
for repo in repos:
if repo not in commits:
raise ValueError(f"no verified immutable publication for {repo}")
paths = ["registry/indexes/capabilities.yaml", *capabilities.get(repo, [])]
for path in paths:
local_path = root / repo / path
expected = hashlib.sha256(local_path.read_bytes()).hexdigest()
commit_url = f"https://forgejo.coulomb.social/coulomb/{repo}/raw/commit/{commits[repo]}/{path}"
remote = fetch(commit_url)
if len(remote) > MAX_SOURCE_BYTES:
raise ValueError(f"published source exceeds byte limit for {repo}:{path}")
actual = hashlib.sha256(remote).hexdigest()
if actual != expected:
raise ValueError(f"immutable published bytes differ for {repo}:{path}")
stable_url = f"https://forgejo.coulomb.social/coulomb/{repo}/raw/branch/main/registry/indexes/capabilities.yaml"
stable = fetch(stable_url)
if len(stable) > MAX_SOURCE_BYTES:
raise ValueError(f"stable public index exceeds byte limit for {repo}")
stable_actual = hashlib.sha256(stable).hexdigest()
index_expected = hashlib.sha256((root / repo / paths[0]).read_bytes()).hexdigest()
if stable_actual != index_expected:
raise ValueError(f"stable public index differs for {repo}")
def preflight_public_batch(
root: Path,
plan: list[dict[str, Any]],
original_public: list[dict[str, Any]],
baseline: dict[str, Any],
publications: list[dict[str, Any]],
inventory: dict[str, Any],
fetch: Callable[[str], bytes],
) -> set[str]:
"""Validate the bounded plan and freshly verify its public sources."""
repos = validate_plan(plan, original_public)
verified_public = {
row["repo"] for row in baseline.get("results", [])
if not row.get("errors") and row.get("stable_index_matches")
}
if not repos <= verified_public:
raise ValueError("one or more planned repositories lack anonymous-source verification")
verify_public_sources(root, plan, publications, inventory, fetch)
return repos
def append_receipt(path: Path, event: dict[str, Any]) -> None:
"""Append one sanitized JSON line; never replace earlier attempts."""
path.parent.mkdir(parents=True, exist_ok=True)
line = (json.dumps(event, sort_keys=True, separators=(",", ":")) + "\n").encode()
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o600)
try:
os.write(fd, line)
os.fsync(fd)
finally:
os.close(fd)
def reconcile(
plan: list[dict[str, Any]],
existing: dict[str, dict[str, Any]],
post: Callable[[dict[str, Any]], int],
receipt: Callable[[dict[str, Any]], None],
*,
apply: bool,
plan_sha256: str,
attempt_id: str | None = None,
) -> None:
"""Read-before-write; any mismatch or 409 halts the remaining batch."""
attempt = attempt_id or str(uuid.uuid4())
# Inspect the full readback before the first POST. A conflict late in the
# plan must not leave earlier registrations newly created by this attempt.
for action in plan:
body = action["body"]
repo = body["repo"]
current = existing.get(repo)
if current is not None and not body_matches(body, current):
receipt({
"attempt_id": attempt,
"at": datetime.now(timezone.utc).isoformat(),
"plan_sha256": plan_sha256,
"repo": repo,
"outcome": "conflict_existing",
})
raise RuntimeError(f"existing registration conflicts for {repo}")
for action in plan:
body = action["body"]
repo = body["repo"]
current = existing.get(repo)
base = {
"attempt_id": attempt,
"at": datetime.now(timezone.utc).isoformat(),
"plan_sha256": plan_sha256,
"repo": repo,
}
if current is not None:
receipt({**base, "outcome": "already_matches"})
continue
if not apply:
receipt({**base, "outcome": "would_create"})
continue
receipt({**base, "outcome": "post_intent"})
try:
status = post(body)
except urllib.error.HTTPError as exc:
status = exc.code
except Exception:
receipt({**base, "outcome": "transport_unknown"})
raise RuntimeError(f"registration transport outcome is unknown for {repo}") from None
if status == 409:
receipt({**base, "http_status": 409, "outcome": "conflict_409"})
raise RuntimeError(f"registration conflict returned 409 for {repo}")
if status < 200 or status >= 300:
receipt({**base, "http_status": status, "outcome": "request_failed"})
raise RuntimeError(f"registration request failed for {repo}")
existing[repo] = dict(body)
receipt({**base, "http_status": status, "outcome": "applied"})
def main() -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--apply", action="store_true", help="perform authenticated POST requests")
args = parser.parse_args()
plan = read_json(OUT / PLAN_NAME)
original_public = read_json(OUT / SOURCE_PLAN_NAME)
baseline = read_json(OUT / "published-source-verification.json")
pub = read_json(OUT / "registry-publication.json") + read_json(OUT / "supplement/registry-publication.json")
inventory = read_json(OUT / "full-inventory.json")
opener = urllib.request.build_opener(urllib.request.ProxyHandler({}), NoRedirect())
def fetch(url: str) -> bytes:
with opener.open(url, timeout=30) as response:
if response.status != 200:
raise RuntimeError("public source verification returned non-200")
body = response.read(MAX_SOURCE_BYTES + 1)
if len(body) > MAX_SOURCE_BYTES:
raise ValueError("public source exceeds the 2 MiB verification limit")
return body
preflight_public_batch(OUT.parents[3], plan, original_public, baseline, pub, inventory, fetch)
def request(method: str, path: str, body: dict[str, Any] | None = None, *, auth: bool = False) -> tuple[int, Any]:
headers = {"Accept": "application/json"}
if body is not None:
headers["Content-Type"] = "application/json"; data = json.dumps(body).encode()
else:
data = None
if auth:
token = os.environ.get("REUSE_SURFACE_TOKEN")
if not token:
raise RuntimeError("required owner-routed write credential is unavailable")
headers["Authorization"] = "Bearer " + token
req = urllib.request.Request(BASE + path, data=data, headers=headers, method=method)
with opener.open(req, timeout=55) as response:
raw = response.read()
return response.status, json.loads(raw) if raw else None
status, listing = request("GET", "/v1/repos")
if status != 200 or not isinstance(listing, dict) or not isinstance(listing.get("repos"), list):
raise RuntimeError("hub registration readback is invalid")
existing = {row["repo"]: row for row in listing["repos"]}
if len(existing) != len(listing["repos"]):
raise RuntimeError("hub returned duplicate repository registrations")
def post(body: dict[str, Any]) -> int:
status, _ = request("POST", "/v1/repos", body, auth=True)
return status
receipt_path = OUT / "hub-public-resume-receipts.jsonl"
plan_hash = hashlib.sha256((OUT / PLAN_NAME).read_bytes()).hexdigest()
attempt_id = str(uuid.uuid4())
reconcile(plan, existing, post, lambda event: append_receipt(receipt_path, event),
apply=args.apply, plan_sha256=plan_hash, attempt_id=attempt_id)
if args.apply:
try:
read_status, readback = request("GET", "/v1/repos")
if read_status != 200 or not isinstance(readback, dict) or not isinstance(readback.get("repos"), list):
raise ValueError("invalid hub readback")
validate_readback(plan, readback["repos"])
except Exception as exc:
append_receipt(receipt_path, {
"attempt_id": attempt_id,
"at": datetime.now(timezone.utc).isoformat(),
"plan_sha256": plan_hash,
"outcome": "readback_failed",
"failure_type": type(exc).__name__,
})
raise RuntimeError("fresh hub registration readback failed") from None
append_receipt(receipt_path, {
"attempt_id": attempt_id,
"at": datetime.now(timezone.utc).isoformat(),
"plan_sha256": plan_hash,
"repo_count": len(plan),
"outcome": "readback_verified",
})
return 0
if __name__ == "__main__":
try:
raise SystemExit(main())
except Exception as exc:
# Avoid serializing transport bodies, headers, exception details, or credentials.
print(f"public registration stopped: {type(exc).__name__}", file=sys.stderr)
raise SystemExit(1)

View file

@ -9,15 +9,51 @@
"field": "REUSE_SURFACE_TOKEN",
"existing_read_policy": "workload-kv-read-reuse-surface-runtime",
"request": "Owner to admit the caller through the existing scoped route and verify its metadata lookup and selected-field read. Retain existing denial evidence; do not grant administrative or unrelated workload access.",
"delivery": "warden access --exec, without exporting or recording the value"
"delivery": "warden access --exec, without exporting or recording the value",
"approval_record": "CCR-2026-0005 is active and was previously approved by platform-operator and reuse-surface-owner; it does not name the caller principal.",
"principal_binding": "Identify the caller OpenBao OIDC entity/accessor without recording any token. If a binding change is needed, record approval for that exact principal with both required approvers before applying the existing policy.",
"existing_policy": "workload-kv-read-reuse-surface-runtime",
"exact_allowed_paths": [
"platform/data/workloads/reuse/reuse-surface/runtime-secrets",
"platform/metadata/workloads/reuse/reuse-surface/runtime-secrets"
],
"negative_check": "An unrelated sibling path must remain denied. Do not broaden policy contents or attach administrative/ESO-only permissions."
},
"private_source_access": {
"repositories": ["rapp-openbao", "rapp-policy-nexus", "rapp-postgres", "rapp-sbom-nexus", "rapp-telemetry", "rapp-tenant-engine", "rapp-user-engine"],
"repositories": [
"rapp-openbao",
"rapp-policy-nexus",
"rapp-postgres",
"rapp-sbom-nexus",
"rapp-telemetry",
"rapp-tenant-engine",
"rapp-user-engine"
],
"request": "Owner to provision a repository-read credential at the federation hub, confirm source-owner consent to public capability metadata, and verify hub-side index and entry fetches.",
"return_only": ["configured auth_env name", "auth_header name if nondefault", "scope and verification receipts"],
"visibility_change_authorized": false
"return_only": [
"configured auth_env name",
"auth_header name if nondefault",
"scope and verification receipts"
],
"visibility_change_authorized": false,
"credential_design": "A new dedicated Forgejo identity/PAT restricted to repository-read for exactly these seven sources; verify a denied-write/admin negative. Keep it distinct from the hub writer token and from other workload credentials.",
"delivery": "Owner-reviewed OpenBao custody and ESO delivery to the reuse-surface hub runtime, then configure the registration auth_env with the environment variable name only.",
"approval": "Platform operator and each relevant source owner must approve the limited private capability-metadata disclosure and reader scope before provisioning."
},
"resume": "Update and retain the exact registration proposal revision with admitted auth_env references, verify source parity, execute bounded registrations, then require all 70 reviewed IDs exactly once in a fresh hosted federation.",
"secret_values_requested_in_chat": false,
"owner_message_sent": false
"owner_message_sent": false,
"attended_sequence": [
"Review CCR-2026-0005 and identify the actual intended caller principal. The existing OIDC identity is not named in the CCR.",
"If needed, obtain and record platform-operator plus reuse-surface-owner approval for binding that exact identity to the existing read-only policy. Verify read on the two exact paths and denial on a sibling path.",
"Use warden access reuse-surface-hub-write-token --exec --field REUSE_SURFACE_TOKEN with a silent helper. Do not use --fetch or print/export the field.",
"After the public-only helper receipt confirms 31 registrations, request the distinct seven-repository read-only source credential and owner disclosure consent. Return only the auth_env name, scope and sanitized verification receipts."
],
"public_batch_prepared": {
"proposal": "hub-public-registration-proposal-r1.json",
"plan": "hub-public-resume-plan.json",
"helper": "register_public_hub.py",
"repositories": 31,
"status": "prepared and tested; not executed"
}
}

View file

@ -0,0 +1,171 @@
"""Offline safety tests for the bounded public registration helper."""
import json
import tempfile
import unittest
from pathlib import Path
import register_public_hub as helper
class PublicResumeTests(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.plan = helper.read_json(helper.OUT / helper.PLAN_NAME)
cls.source_plan = helper.read_json(helper.OUT / helper.SOURCE_PLAN_NAME)
def test_plan_is_exactly_public_scope(self):
repos = helper.validate_plan(self.plan, self.source_plan)
baseline = helper.read_json(helper.OUT / "published-source-verification.json")
verified = {r["repo"] for r in baseline["results"] if not r["errors"] and r["stable_index_matches"]}
self.assertEqual(len(repos), 31)
self.assertTrue(repos <= verified)
self.assertTrue(repos.isdisjoint(helper.PRIVATE_REPOS))
def test_scope_rejects_mutation_and_private_repo(self):
altered = json.loads(json.dumps(self.plan))
altered[0]["body"]["domain"] = "other"
with self.assertRaises(ValueError):
helper.validate_plan(altered, self.source_plan)
altered = json.loads(json.dumps(self.plan))
altered[0]["body"]["repo"] = "rapp-postgres"
with self.assertRaises(ValueError):
helper.validate_plan(altered, self.source_plan)
def test_compares_every_submitted_registration_field(self):
body = self.plan[0]["body"]
self.assertTrue(helper.body_matches(body, dict(body, registered_at="hub-field")))
self.assertFalse(helper.body_matches(body, {k: v for k, v in body.items() if k != "registered_by"}))
changed = dict(body, required=True)
self.assertFalse(helper.body_matches(body, changed))
def test_fresh_readback_requires_all_exact_plan_fields(self):
rows = [dict(action["body"], registered_at="server") for action in self.plan]
helper.validate_readback(self.plan, rows)
rows[0]["enabled"] = False
with self.assertRaisesRegex(ValueError, "does not match"):
helper.validate_readback(self.plan, rows)
def test_dry_run_records_all_actions_without_posting(self):
events = []
posts = []
helper.reconcile(
self.plan, {}, lambda body: posts.append(body) or 201,
events.append, apply=False, plan_sha256="a" * 64,
)
self.assertEqual(posts, [])
self.assertEqual([event["outcome"] for event in events], ["would_create"] * 31)
self.assertTrue(all(set(event) <= {"attempt_id", "at", "plan_sha256", "repo", "outcome"} for event in events))
def test_existing_conflict_stops_before_any_post(self):
events = []
posts = []
repo = self.plan[1]["body"]["repo"]
existing = {repo: {"repo": repo, "url": "https://wrong.invalid/index.yaml"}}
with self.assertRaisesRegex(RuntimeError, "conflicts"):
helper.reconcile(self.plan, existing, lambda body: posts.append(body) or 201,
events.append, apply=True, plan_sha256="b" * 64)
self.assertEqual(posts, [])
self.assertEqual(events[-1]["outcome"], "conflict_existing")
def test_409_is_recorded_and_stops_batch(self):
events = []
calls = []
with self.assertRaisesRegex(RuntimeError, "409"):
helper.reconcile(self.plan[:3], {}, lambda body: calls.append(body) or 409,
events.append, apply=True, plan_sha256="c" * 64)
self.assertEqual(len(calls), 1)
self.assertEqual(len(events), 2)
self.assertEqual(events[0]["outcome"], "post_intent")
self.assertEqual(events[1]["outcome"], "conflict_409")
def test_success_has_durable_intent_and_applied_receipts(self):
events = []
helper.reconcile(self.plan[:1], {}, lambda _body: 201, events.append,
apply=True, plan_sha256="e" * 64)
self.assertEqual([event["outcome"] for event in events], ["post_intent", "applied"])
def test_ambiguous_transport_is_recorded_without_retry(self):
events = []
def lost_response(_body):
raise TimeoutError("do not store this message")
with self.assertRaisesRegex(RuntimeError, "unknown"):
helper.reconcile(self.plan[:2], {}, lost_response, events.append,
apply=True, plan_sha256="f" * 64)
self.assertEqual([event["outcome"] for event in events], ["post_intent", "transport_unknown"])
self.assertNotIn("do not store this message", json.dumps(events))
def test_source_verification_fetches_only_the_planned_public_repo(self):
action = self.plan[0]
repo = action["body"]["repo"]
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp) / "workspace"
(root / repo / "registry/indexes").mkdir(parents=True)
(root / repo / "registry/capabilities").mkdir(parents=True)
index = b"index"
entry = b"entry"
(root / repo / "registry/indexes/capabilities.yaml").write_bytes(index)
(root / repo / "registry/capabilities/example.md").write_bytes(entry)
commits = [{"repo": repo, "commit": "abc123", "verified_remote": True}]
inventory = {"capabilities": [{"repo": repo, "entry_path": "registry/capabilities/example.md"}]}
urls = {}
def fake_fetch(url):
urls[url] = True
return entry if url.endswith("example.md") else index
helper.verify_public_sources(root, [action], commits, inventory, fake_fetch)
self.assertEqual(len(urls), 3) # immutable index + entry, then stable index
self.assertTrue(all(f"/{repo}/" in url for url in urls))
def test_source_verification_rejects_mismatch_before_registration(self):
action = self.plan[0]
repo = action["body"]["repo"]
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp) / "workspace"
(root / repo / "registry/indexes").mkdir(parents=True)
(root / repo / "registry/indexes/capabilities.yaml").write_bytes(b"expected")
inventory = {"capabilities": []}
with self.assertRaisesRegex(ValueError, "differ"):
helper.verify_public_sources(root, [action], [{"repo": repo, "commit": "abc", "verified_remote": True}], inventory, lambda _url: b"wrong")
def test_orchestrated_preflight_calls_source_verifier_for_only_the_31(self):
baseline = helper.read_json(helper.OUT / "published-source-verification.json")
publications = (helper.read_json(helper.OUT / "registry-publication.json")
+ helper.read_json(helper.OUT / "supplement/registry-publication.json"))
inventory = helper.read_json(helper.OUT / "full-inventory.json")
root = helper.OUT.parents[3]
fetched_repos = set()
def local_public_fetch(url):
repo = url.split("/coulomb/", 1)[1].split("/", 1)[0]
rest = url.split("/raw/", 1)[1].split("/")
path = "/".join(rest[2:])
fetched_repos.add(repo)
return (root / repo / path).read_bytes()
repos = helper.preflight_public_batch(root, self.plan, self.source_plan, baseline,
publications, inventory, local_public_fetch)
self.assertEqual(len(repos), 31)
self.assertEqual(fetched_repos, repos)
def test_source_verification_rejects_over_limit_response(self):
action = self.plan[0]
repo = action["body"]["repo"]
with tempfile.TemporaryDirectory() as tmp:
root = Path(tmp)
(root / repo / "registry/indexes").mkdir(parents=True)
(root / repo / "registry/indexes/capabilities.yaml").write_bytes(b"small")
with self.assertRaisesRegex(ValueError, "byte limit"):
helper.verify_public_sources(
root, [action], [{"repo": repo, "commit": "abc", "verified_remote": True}],
{"capabilities": []}, lambda _url: b"x" * (helper.MAX_SOURCE_BYTES + 1),
)
def test_receipts_append_without_serializing_unapproved_fields(self):
with tempfile.TemporaryDirectory() as tmp:
path = Path(tmp) / "receipts.jsonl"
event = {"repo": "approval-engine", "outcome": "would_create", "plan_sha256": "d" * 64}
helper.append_receipt(path, event)
helper.append_receipt(path, event)
rows = [json.loads(line) for line in path.read_text().splitlines()]
self.assertEqual(rows, [event, event])
if __name__ == "__main__":
unittest.main()