Implement attended root custody admission and crash-safe publisher
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a1029d-2c93-7500-a0e0-e3e089668b29
This commit is contained in:
codex 2026-10-03 19:44:22 +02:00
parent 3ee800a0fe
commit fa958cc051
5 changed files with 490 additions and 38 deletions

View file

@ -6,7 +6,7 @@ Scoped made decision receipt: `c2cff929-91b9-4018-bfd6-fa04f7da8280`.
This selects railiance-platform and the exact source below. Identity admission,
attended live provisioning, custody provenance and live readiness remain pending.
NetKingdom canon remains authoritative; reviewed baseline is net-kingdom commit
`de4c4f84f5043b97a205f1a72a26e77f8750d628`. Deployments must pin the validator
`db319335b27b61b855382ee5af5d690f06eeb010`. Deployments must pin the validator
and its schema together, and reconcile amendments before publication.
## Approved source and transport
@ -16,10 +16,12 @@ and its schema together, and reconcile amendments before publication.
- `record_id`: `nk-custody:platform-root`; `owner_system`: `net-kingdom-custody`.
- API response unwrap: `data.data.document` is the complete canon document.
`data.metadata.version` is KV concurrency state, distinct from canon revision.
- Reader: user-engine only. Its repository currently has no deployed workload
namespace/ServiceAccount, so no Kubernetes identity binding is claimed.
User-engine must name its real runtime identity and an existing supported auth
route. Platform admits it only after review. Reader policy is exact-path read;
- Reader: owner manifests identify namespace `user-engine`, ServiceAccount
`user-engine`. Role `user-engine-root-custody-reader` on `auth/kubernetes`
binds exactly those values and audience `openbao`. Tokens last at most 60s,
with no default policy. Dedicated projected JWT is owned by rapp-user-engine;
the existing flex-auth JWT and ESO AppRole are not reused. Live admission
remains unexecuted. Reader policy is exact-path read;
no list, sibling read or write. Never distribute an attended writer token.
- Writer: separate human custody lane, bounded attended MFA operator login,
reviewed exact-path policy. This packet does not grant a credential or role.
@ -37,26 +39,64 @@ refuses missing existing baselines, same-revision changes and rollback. CAS=0
is bootstrap-only, CAS=current-version updates; a CAS conflict requires a fresh
owner read and revalidation, never blind retry. It never prints documents.
The attended executor still needs implementation after actual reader/writer
identity confirmation: suppress output, read document and KV version together,
verify retained high-water mark, call preparation helper, write one complete payload, read back
and compare, and emit non-secret revision/digest receipts. An unvalidated direct
writer bypass is not an accepted delivery path. Policies alone cannot enforce
the human ceremony, validator or global revision monotonicity.
The attended executor is implemented in `scripts/root_grant_attended.py`:
## Exact later live approval packet
- `provision` checks existing Kubernetes auth and active audit, admits only the
exact reviewed reader policy/role, enables CAS on this key and verifies all
readbacks. Differing existing policies/roles are refused without overwrite.
- `publish` reads current document and KV version together, validates pinned
canon and the persisted high-water baseline, fsyncs a pending journal before
CAS write, verifies exact readback, retains immutable local history and
atomically advances state. Exact replay creates no new version. Ambiguous
writes recover only after exact matching owner readback and durable history.
- `restore-check` requires the independently retained publisher baseline to
match the restored source exactly. Missing/different baseline never resets
authority or permits rollback. Off-host history backup is still an execution
dependency; local files alone cannot prove safe disaster restoration.
- The silent child requires the existing warden attended-login envelope and
exact loopback OpenBao tunnel. No raw process response/error is emitted.
Every invocation requires a new receipt path: old success receipts are refused.
After real consumer identity confirmation and final source preparation, request
one explicit attended approval naming the reviewed platform and NetKingdom
commits, exact mount/path/record ID, real reader auth binding, separate writer
binding, audit owner, abort operator, window and provenance reference. Its
bounded actions are: inspect existing mount and identity without values;
configure exact-path admission and KV per-key CAS requirement; publish a
human-reviewed initial document only from real ceremony evidence (or an
explicitly approved empty baseline); verify authenticated reader success,
anonymous/wrong-identity/parent-list/sibling/write denial and failed-read behavior;
return only source ID, revision, content digest, actor/time/provenance references
and pass/fail checks. No synthetic fixture can seed the authoritative record.
## Authorized attended execution packet
Founder approval to "go forward" authorizes continued implementation and bounded
provisioning of the approved design. No additional generic design approval is
requested. Attended OIDC/MFA must still run in the founder's own terminal:
```bash
BAO_ADDR=http://127.0.0.1:18200 VAULT_ADDR=http://127.0.0.1:18200 \
warden access openbao-platform-admin-login --exec -- \
/home/worsch/railiance-platform/scripts/root-grant-attended.sh provision \
--receipt /tmp/platform-root-admission-UNIQUE-RUN.json
```
Replace UNIQUE-RUN with a fresh run identifier. The child is silent. Inspect the
new JSON receipt and warden's printed result; a shell exit code or previous
receipt cannot establish success. Provisioning does not create a custody grant.
Existing operator platform-admin identity provides the human writer lane;
this packet does not create another privileged identity or reuse its token in
user-engine. Deployment/network policy/consumer activation belongs to
rapp-user-engine and follows source image publication and admission receipts.
Publication requires an owner state directory outside the checkout, off-host
history backup, a bounded non-secret initial document and ceremony reference.
Do not infer a custodian from the legacy planned roster or LLDAP account. Real
bootstrap requires the human's exact issuer/subject and signed ceremony; an
empty initial record can be used only if chosen by the founder. Example child
arguments after those inputs exist:
```text
publish --candidate /owner/candidate.json --state /owner/history/baseline.json
--provenance-ref <human-ceremony-or-approved-empty-baseline-reference>
--net-kingdom /home/worsch/net-kingdom
--validator-digest 9156e399c8d92a45b817bfc3738c89843487ce57e1718ed747f804f95cc719bb
--schema-digest bb6cd6da5dc48eddcf118ae78c2cacfafd5f860098fd8a8368fe6bc845776d07
--receipt /tmp/platform-root-publish-UNIQUE-RUN.json
```
Run via the same attended wrapper. `restore-check` takes the same source pins
and state but no candidate or provenance argument. Source digests enforce the
reviewed NetKingdom validator and schema without importing an unreviewed path.
Acceptance also needs revocation/supersession exercise and rollback/restore
receipts. Exercise real grant changes only under their own custody ceremony

3
scripts/root-grant-attended.sh Executable file
View file

@ -0,0 +1,3 @@
#!/usr/bin/env bash
set -euo pipefail
exec python3 "$(dirname "$0")/root_grant_attended.py" "$@" >/dev/null 2>&1

View file

@ -0,0 +1,255 @@
#!/usr/bin/env python3
"""Silent attended OpenBao admission/publisher; never emits server responses."""
import argparse
import datetime as dt
import fcntl
import hashlib
import importlib.util
import json
import os
from pathlib import Path
import subprocess
import sys
import tempfile
from root_grant_publish import MAX_BYTES, RECORD_ID, prepare_payload
from openbao_platform_admin_check import require_attended
ROOT = Path(__file__).resolve().parents[1]
PATH = "platform/data/custody/net-kingdom/platform-root"
META = "platform/metadata/custody/net-kingdom/platform-root"
ROLE_PATH = "auth/kubernetes/role/user-engine-root-custody-reader"
POLICY = "user-engine-root-custody-reader"
ROLE = {"bound_service_account_names": ["user-engine"],
"bound_service_account_namespaces": ["user-engine"], "audience": "openbao",
"token_policies": [POLICY], "token_no_default_policy": True,
"token_ttl": 60, "token_max_ttl": 60, "token_explicit_max_ttl": 60}
class Refused(Exception):
pass
def digest(document):
return hashlib.sha256(json.dumps(document, sort_keys=True, separators=(",", ":"), allow_nan=False).encode()).hexdigest()
def atomic_json(path, document):
path = Path(path)
if path.is_symlink():
raise Refused("unsafe_state_path")
with tempfile.NamedTemporaryFile(dir=path.parent, delete=False) as out:
temporary = Path(out.name)
os.chmod(temporary, 0o600)
out.write(json.dumps(document, sort_keys=True).encode())
out.flush()
os.fsync(out.fileno())
try:
os.replace(temporary, path)
fd = os.open(path.parent, os.O_RDONLY | os.O_DIRECTORY)
try:
os.fsync(fd)
finally:
os.close(fd)
finally:
temporary.unlink(missing_ok=True)
class Bao:
def call(self, command, payload=None, optional=False):
result = subprocess.run(["bao", *command], input=None if payload is None else json.dumps(payload).encode(),
capture_output=True, timeout=15)
if result.returncode:
# Distinguish a documented missing-path message from auth/outage.
if optional and result.returncode == 2 and result.stderr.strip() == ("No value found at " + command[-1]).encode():
return None
raise Refused("openbao_request_failed")
if len(result.stdout) > MAX_BYTES * 2:
raise Refused("oversize_owner_response")
return json.loads(result.stdout) if result.stdout.strip() else {}
def read(self, path, optional=False):
response = self.call(["read", "-format=json", path], optional=optional)
return None if response is None else response["data"]
def write(self, path, payload):
return self.call(["write", "-format=json", path, "-"], payload)
def check_baseline(actual, state, validator):
if state is None:
if actual is not None:
raise Refused("controlled_baseline_import_required")
return
previous = state["document"]
if validator.validate(previous) or previous["record_id"] != RECORD_ID or state["digest"] != digest(previous):
raise Refused("invalid_retained_baseline")
if actual is None or validator.validate(actual["data"]["document"]):
raise Refused("missing_or_invalid_source")
document = actual["data"]["document"]
if digest(document) != state["digest"] or actual["metadata"]["version"] != state["kv_version"]:
raise Refused("source_differs_from_retained_baseline")
def retain_history(state_path, receipt):
history = state_path.parent / "history"
history.mkdir(mode=0o700, exist_ok=True)
target = history / (str(receipt["revision"]) + "-" + receipt["digest"] + ".json")
if target.exists():
if json.loads(target.read_text()) != receipt:
raise Refused("history_receipt_differs")
return
with target.open("x") as out:
os.chmod(target, 0o600)
json.dump(receipt, out, sort_keys=True)
out.flush()
os.fsync(out.fileno())
fd = os.open(history, os.O_RDONLY | os.O_DIRECTORY)
try:
os.fsync(fd)
finally:
os.close(fd)
def publish(bao, candidate, state_path, validator, provenance):
state_path = Path(state_path)
if not isinstance(provenance, str) or not provenance.strip() or len(provenance) > 300 or validator.SECRET_VALUE.search(provenance):
raise Refused("nonsecret_human_provenance_required")
if state_path.is_symlink():
raise Refused("unsafe_state_path")
state = json.loads(state_path.read_text()) if state_path.exists() else None
actual = bao.read(PATH, optional=True)
# Pending state is fsynced before network mutation. Recover only exact readback;
# ambiguous network failures are never retried or cleared automatically.
if state is not None and state.get("pending"):
pending = state["pending"]
if actual is None or digest(actual["data"]["document"]) != pending["digest"] or actual["metadata"]["version"] != pending["expected_kv_version"]:
raise Refused("pending_publication_requires_owner_review")
if validator.validate(pending["document"]) or pending["document"]["record_id"] != RECORD_ID:
raise Refused("invalid_pending_document")
state = {key: value for key, value in pending.items() if key != "expected_kv_version"}
retain_history(state_path, state)
atomic_json(state_path, state)
check_baseline(actual, state, validator)
previous = None if state is None else state["document"]
version = 0 if actual is None else actual["metadata"]["version"]
if previous is not None and digest(candidate) == state["digest"]:
# Exact replay is an idempotent readback, not a new custody/KV revision.
return {**{key: value for key, value in state.items() if key != "document"}, "unchanged": True}
payload = prepare_payload(candidate, previous, version, validator)
now = dt.datetime.now(dt.timezone.utc)
times = [candidate["updated_at"]]
for entry in candidate["entries"]:
times.append(entry["granted"]["at"])
if entry.get("revoked"):
times.append(entry["revoked"]["at"])
if any(validator.parse_time(value) > now for value in times):
raise Refused("future_custody_action")
receipt = {"record_id": RECORD_ID, "revision": candidate["revision"], "digest": digest(candidate),
"kv_version": version + 1, "document": candidate, "provenance_ref": provenance,
"recorded_at": dt.datetime.now(dt.timezone.utc).isoformat()}
pending = dict(receipt, expected_kv_version=version + 1)
atomic_json(state_path, {**(state or {}), "pending": pending})
bao.write(PATH, payload)
returned = bao.read(PATH)
if returned["metadata"]["version"] != version + 1 or digest(returned["data"]["document"]) != receipt["digest"]:
raise Refused("publication_readback_failed")
# Independent immutable receipts precede advancing local state. They must be
# backed up off-host; restoring only this directory is not independent proof.
retain_history(state_path, receipt)
atomic_json(state_path, receipt)
return {key: value for key, value in receipt.items() if key != "document"}
def provision(bao):
# Require existing Kubernetes auth; no auth mount or cluster reviewer mutation.
if bao.read("auth/kubernetes/config") is None:
raise Refused("kubernetes_auth_unavailable")
audit = bao.read("sys/audit")
if not audit:
raise Refused("audit_required")
policy = (ROOT / "openbao/root-grant/reader.hcl").read_text()
existing = bao.read("sys/policies/acl/" + POLICY, optional=True)
if existing is not None and existing.get("policy", existing.get("rules", "")).strip() != policy.strip():
raise Refused("existing_reader_policy_differs")
role = bao.read(ROLE_PATH, optional=True)
if role is not None and any(role.get(key) != value for key, value in ROLE.items()):
raise Refused("existing_reader_role_differs")
if existing is None:
bao.write("sys/policies/acl/" + POLICY, {"policy": policy})
if role is None:
bao.write(ROLE_PATH, ROLE)
fresh = bao.read(ROLE_PATH)
if any(fresh.get(key) != value for key, value in ROLE.items()):
raise Refused("role_readback_failed")
fresh_policy = bao.read("sys/policies/acl/" + POLICY)
if fresh_policy.get("policy", fresh_policy.get("rules", "")).strip() != policy.strip():
raise Refused("policy_readback_failed")
# Require CAS on this key without altering retention or destroying versions.
metadata = bao.read(META, optional=True)
if not metadata or not metadata.get("cas_required"):
bao.write(META, {"cas_required": True})
if bao.read(META).get("cas_required") is not True:
raise Refused("cas_required_readback_failed")
return {"reader_role": ROLE_PATH, "reader_namespace": "user-engine", "reader_service_account": "user-engine",
"audience": "openbao", "record_id": RECORD_ID, "cas_required": True, "audit_enabled": True}
def main():
parser = argparse.ArgumentParser()
parser.add_argument("action", choices=["provision", "publish", "restore-check"])
parser.add_argument("--receipt", type=Path, required=True)
parser.add_argument("--state", type=Path)
parser.add_argument("--candidate", type=Path)
parser.add_argument("--net-kingdom", type=Path)
parser.add_argument("--provenance-ref")
parser.add_argument("--validator-digest")
parser.add_argument("--schema-digest")
args = parser.parse_args()
try:
if args.receipt.exists() or args.receipt.is_symlink():
raise Refused("unique_run_receipt_required")
require_attended()
if os.getenv("BAO_ADDR") != "http://127.0.0.1:18200":
raise Refused("approved_operator_tunnel_required")
bao = Bao()
if args.action == "provision":
receipt = provision(bao)
else:
if not args.state or not args.net_kingdom or not args.validator_digest or not args.schema_digest:
raise Refused("pinned_source_and_state_required")
source = args.net_kingdom / "tools/custody-record/validate.py"
schema = args.net_kingdom / "canon/schemas/custody-record_v0.1.schema.json"
for path, expected in [(source, args.validator_digest), (schema, args.schema_digest)]:
if hashlib.sha256(path.read_bytes()).hexdigest() != expected:
raise Refused("canon_pin_mismatch")
spec = importlib.util.spec_from_file_location("custody_validator", source)
validator = importlib.util.module_from_spec(spec)
spec.loader.exec_module(validator)
if not args.state.parent.is_dir():
raise Refused("owner_state_directory_required")
# Serialize this publisher, including reads and pending-journal recovery.
with (args.state.parent / "publisher.lock").open("a") as lock:
fcntl.flock(lock, fcntl.LOCK_EX)
if args.action == "restore-check":
if not args.state.exists():
raise Refused("retained_baseline_required")
state = json.loads(args.state.read_text())
if state.get("pending"):
raise Refused("pending_publication_requires_owner_review")
check_baseline(bao.read(PATH, optional=True), state, validator)
receipt = {"record_id": RECORD_ID, "baseline_matches": True, "revision": state["document"]["revision"]}
else:
if not args.candidate or not args.provenance_ref:
raise Refused("candidate_and_human_provenance_required")
candidate = json.loads(args.candidate.read_bytes()[:MAX_BYTES + 1])
receipt = publish(bao, candidate, args.state, validator, args.provenance_ref)
atomic_json(args.receipt, {"ok": True, **receipt})
return 0
except Exception:
# CLI/process/validation errors may embed secrets. Never emit them.
return 1
if __name__ == "__main__":
sys.exit(main())

View file

@ -0,0 +1,140 @@
import copy
import importlib.util
import json
from pathlib import Path
import sys
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "scripts"))
import root_grant_attended as attended
spec = importlib.util.spec_from_file_location("custody_validator", ROOT.parent / "net-kingdom/tools/custody-record/validate.py")
validator = importlib.util.module_from_spec(spec)
spec.loader.exec_module(validator)
class FakeBao:
def __init__(self, document=None, version=1):
self.actual = None if document is None else {"data": {"document": copy.deepcopy(document)}, "metadata": {"version": version}}
self.metadata = {"max_versions": 123, "cas_required": False}
self.config = {"auth/kubernetes/config": {}, "sys/audit": {"file/": {"type": "file"}}, attended.META: self.metadata}
self.writes = []
self.fail_after_write = False
def read(self, path, optional=False):
return copy.deepcopy(self.actual if path == attended.PATH else self.config.get(path))
def write(self, path, payload):
self.writes.append((path, copy.deepcopy(payload)))
if path == attended.PATH:
version = 0 if self.actual is None else self.actual["metadata"]["version"]
if payload["options"]["cas"] != version:
raise attended.Refused("cas_conflict")
self.actual = {"data": payload["data"], "metadata": {"version": version + 1}}
if self.fail_after_write:
raise attended.Refused("ambiguous_timeout")
else:
self.config[path] = payload
if path == attended.META:
self.metadata.update(payload)
self.config[path] = self.metadata
class AttendedTests(unittest.TestCase):
def setUp(self):
self.temp = tempfile.TemporaryDirectory()
self.state = Path(self.temp.name) / "baseline.json"
self.first = json.loads((ROOT.parent / "net-kingdom/tools/custody-record/fixtures/valid/grant.json").read_text())
self.first["record_id"] = attended.RECORD_ID
self.next = dict(copy.deepcopy(self.first), revision=self.first["revision"] + 1)
def tearDown(self):
self.temp.cleanup()
def test_first_publication_and_update_keep_history(self):
bao = FakeBao()
receipt = attended.publish(bao, self.first, self.state, validator, "human-receipt")
self.assertNotIn("document", receipt)
attended.publish(bao, self.next, self.state, validator, "human-receipt-2")
self.assertEqual(len(list((self.state.parent / "history").glob("*.json"))), 2)
self.assertEqual(bao.writes[1][1]["options"], {"cas": 1})
def test_exact_replay_creates_no_kv_version_or_history(self):
bao = FakeBao()
attended.publish(bao, self.first, self.state, validator, "human-receipt")
result = attended.publish(bao, self.first, self.state, validator, "human-receipt")
self.assertTrue(result["unchanged"])
self.assertEqual(len(bao.writes), 1)
self.assertEqual(len(list((self.state.parent / "history").glob("*.json"))), 1)
def test_existing_receipt_prevents_any_live_call(self):
from unittest.mock import patch
receipt = Path(self.temp.name) / "receipt.json"
receipt.write_text('{"ok":true}')
with patch.object(sys, "argv", ["executor", "provision", "--receipt", str(receipt)]), patch.object(attended, "require_attended") as check:
self.assertEqual(attended.main(), 1)
check.assert_not_called()
self.assertEqual(receipt.read_text(), '{"ok":true}')
def test_existing_source_without_baseline_is_not_bootstrap(self):
bao = FakeBao(self.first)
with self.assertRaises(attended.Refused):
attended.publish(bao, self.next, self.state, validator, "human-receipt")
self.assertEqual(bao.writes, [])
def test_rollback_restore_denied(self):
bao = FakeBao()
attended.publish(bao, self.first, self.state, validator, "human-receipt")
attended.publish(bao, self.next, self.state, validator, "human-receipt")
state = json.loads(self.state.read_text())
with self.assertRaises(attended.Refused):
attended.check_baseline(FakeBao(self.first).actual, state, validator)
def test_ambiguous_network_failure_leaves_durable_pending(self):
bao = FakeBao()
bao.fail_after_write = True
with self.assertRaises(attended.Refused):
attended.publish(bao, self.first, self.state, validator, "human-receipt")
self.assertIn("pending", json.loads(self.state.read_text()))
bao.fail_after_write = False
attended.publish(bao, self.next, self.state, validator, "human-receipt-2")
self.assertNotIn("pending", json.loads(self.state.read_text()))
self.assertEqual(len(bao.writes), 2)
self.assertEqual(len(list((self.state.parent / "history").glob("*.json"))), 2)
def test_pending_mismatch_requires_review_and_no_retry(self):
bao = FakeBao()
bao.fail_after_write = True
with self.assertRaises(attended.Refused):
attended.publish(bao, self.first, self.state, validator, "human-receipt")
bao.actual = None
with self.assertRaises(attended.Refused):
attended.publish(bao, self.next, self.state, validator, "human-receipt")
self.assertEqual(len(bao.writes), 1)
def test_exact_admission_is_idempotent_and_retention_unchanged(self):
bao = FakeBao()
attended.provision(bao)
self.assertEqual(bao.config[attended.ROLE_PATH], attended.ROLE)
self.assertTrue(bao.metadata["cas_required"])
self.assertEqual(bao.metadata["max_versions"], 123)
writes = len(bao.writes)
attended.provision(bao)
self.assertEqual(writes, len(bao.writes))
def test_different_existing_role_and_missing_audit_are_refused_before_write(self):
for mode in ["role", "audit"]:
bao = FakeBao()
if mode == "role":
bao.config[attended.ROLE_PATH] = dict(attended.ROLE, bound_service_account_names=["other"])
else:
bao.config["sys/audit"] = {}
with self.assertRaises(attended.Refused):
attended.provision(bao)
self.assertEqual(bao.writes, [])
if __name__ == "__main__":
unittest.main()

View file

@ -41,36 +41,39 @@ These are preparation artifacts, not an admitted or operational source.
```task
id: RPF-WP-0049-T02
status: wait
status: done
priority: high
depends_on: [NK-WP-0045-T01, NK-WP-0045-T04]
blocked_on: message-from:user-engine
blocking_reason: "Design selection is approved; user-engine must still supply its actual runtime reader identity and supported authentication route. No deployed ServiceAccount is known."
state_hub_task_id: "16096f84-6232-5d97-8fe3-b4683c79f4fb"
```
Approved source: platform/data/custody/net-kingdom/platform-root, record ID
nk-custody:platform-root and exact-path read using the existing owner-routed
workload admission. user-engine confirmed nested document compatibility;
its adapter is transport-neutral and runtime identity remains unconfirmed.
its adapter is transport-neutral. Owner rapp-user-engine manifests confirm
namespace user-engine / ServiceAccount user-engine. Selected admission role
is user-engine-root-custody-reader, auth/kubernetes, audience openbao, 60s
maximum token TTL and no default policy; dedicated projection is owned by
rapp-user-engine. This resolves source identity, not live admission.
## Implement attended executor, recovery and audit for the approved source
```task
id: RPF-WP-0049-T03
status: wait
status: done
priority: high
depends_on: [RPF-WP-0049-T02]
blocking_reason: "Surface is approved; actual reader identity and separate attended writer custody bindings remain required for final executor/admission/restore configuration."
state_hub_task_id: "0bc4bc1f-e279-5c92-97bb-cf76d2e33749"
```
Implement reviewed value-safe executor with owner-read baseline + CAS, exact
identity admission configuration, per-key required CAS, retention/independent
high-water history, audit and rollback-safe restoration. Pin canon source.
Do not let direct writer capability bypass transition or ceremony requirements.
Implemented silent attended provision/publish/restore-check executor with exact
reader admission, per-key required CAS, active-audit check, pinned canon, retained
high-water baseline, fsynced pending journal and immutable local history.
Readback is mandatory; replay is idempotent; conflicting existing role/policy,
missing state and rollback fail closed. Off-host history placement and actual
recovery evidence remain execution/acceptance dependencies in T04/T05.
## Approve bounded live provisioning and custody bootstrap
## Execute authorized attended provisioning and establish initial baseline
```task
id: RPF-WP-0049-T04
@ -78,13 +81,16 @@ status: wait
priority: high
depends_on: [RPF-WP-0049-T03]
needs_human: true
blocking_reason: "Separate founder go for named commits, exact read/writer bindings, attended window and real custody provenance; decision on design alone is not live approval."
blocking_reason: "Founder go-forward is recorded; execution needs founder terminal OIDC/MFA, owner state/history location and real ceremony inputs or founder choice of an empty baseline. No real custodian can be inferred."
state_hub_task_id: "88b932e8-1010-56c6-be27-ad46f47e1e80"
```
Assemble exact later approval packet from producer README. Source-only draft
policies are not approval to apply or create entries. Bootstrap ceremony facts
are supplied by human custodian, never inferred from IAM or test fixtures.
Founder continued approval: "Good, i approve go forward please." This authorizes
bounded execution of the reviewed design; generic permission is not pending.
The concrete attended provisioning command is in the producer README. The
founder runs existing operator OIDC/MFA in their own terminal. Human supplies
real ceremony issuer/subject/reference or chooses a no-grant empty baseline;
legacy planned roster and bootstrap setup operator are not grant evidence.
## Return producer delivery receipts
@ -116,3 +122,11 @@ bindings/final executor/recovery preparation, T04 on separate attended live
approval and ceremony provenance, and T05 on actual producer delivery receipts.
The workplan remains blocked on those residual dependencies. No live mutation
or real custody entry is authorized by this design acceptance.
## Continued implementation — 2026-10-03
T02/T03 source identity and executor implementation complete. No further
generic approval requested; T04 is attended execution/information dependency.
T05 still requires live producer read/denial/outage/restore/audit receipts.
NetKingdom canon pin db319335b27b61b855382ee5af5d690f06eeb010. No real
root grant, privileged login, production admission or readiness claimed.