diff --git a/docs/changes/netkingdom-target-2026-10-17/key39-infra-finalization-r1/finalization-recheck-progress.json b/docs/changes/netkingdom-target-2026-10-17/key39-infra-finalization-r1/finalization-recheck-progress.json new file mode 100644 index 00000000..9da18a06 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/key39-infra-finalization-r1/finalization-recheck-progress.json @@ -0,0 +1,14 @@ +{ + "workplan_id": "09c3bddf-6058-5603-8488-cccdb7be4f86", + "id": "ebeaa526-9ece-45ca-a4cb-c8afd4c863c4", + "topic_id": null, + "task_id": "03da4c38-1dac-53b1-8b0b-e697df48e9d3", + "decision_id": null, + "event_type": "note", + "summary": "Rechecked KEY-WP-0039 against current infrastructure source review and primary State Hub: all 14 executable/test/producer-decision pins and 3 Platform pins match; T01/T03 done, T02 wait, parent active; KEY38 T02/T03 remain wait. Existing finalization assessment remains valid. Source-only approval is not live readiness/custody or a negative/expiry/cleanup receipt. No workplan/status edits, credentials, live changes or renewed approval request. Recheck evidence: docs/changes/netkingdom-target-2026-10-17/key39-infra-finalization-r1/finalization-recheck.json.", + "detail": null, + "author": "codex", + "session_id": null, + "created_at": "2026-10-17T17:27:33.253863Z", + "workstream_id": "09c3bddf-6058-5603-8488-cccdb7be4f86" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/key39-infra-finalization-r1/finalization-recheck.json b/docs/changes/netkingdom-target-2026-10-17/key39-infra-finalization-r1/finalization-recheck.json new file mode 100644 index 00000000..cb13f4f2 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/key39-infra-finalization-r1/finalization-recheck.json @@ -0,0 +1,148 @@ +{ + "checked_at": "2026-10-17T17:27:31.694709+00:00", + "owner_head": "d803e9282a47b49daf930fb905312fa5104c0ace", + "source_pin_checks": [ + { + "path": "net-kingdom/sso-mfa/k8s/keycape/openbao-negative-node-route.md", + "expected_sha256": "cad3e3dc481d45295cc014e48285e81614911dfb4a10523883f3044f6085f363", + "actual_sha256": "cad3e3dc481d45295cc014e48285e81614911dfb4a10523883f3044f6085f363", + "match": true + }, + { + "path": "net-kingdom/sso-mfa/k8s/keycape/openbao-negative-node-wrapper.py", + "expected_sha256": "76ac013d1a676a0dfa58aea1ce87b0c3e72483ccd21f586a22c5475e9132f6c1", + "actual_sha256": "76ac013d1a676a0dfa58aea1ce87b0c3e72483ccd21f586a22c5475e9132f6c1", + "match": true + }, + { + "path": "net-kingdom/sso-mfa/k8s/keycape/openbao-negative-session.py", + "expected_sha256": "24b7b803e4eb7e6e7c0700a069dad0ec315ee7eb5538a88b9e56147f8fab5cdd", + "actual_sha256": "24b7b803e4eb7e6e7c0700a069dad0ec315ee7eb5538a88b9e56147f8fab5cdd", + "match": true + }, + { + "path": "net-kingdom/sso-mfa/k8s/keycape/test_openbao_negative_session.py", + "expected_sha256": "01e23f2b4fc77824a161a57acb3a52d19aad846b3b6c0fd3abd81afa1dc2985c", + "actual_sha256": "01e23f2b4fc77824a161a57acb3a52d19aad846b3b6c0fd3abd81afa1dc2985c", + "match": true + }, + { + "path": "net-kingdom/sso-mfa/k8s/keycape/test_openbao_node_route.py", + "expected_sha256": "1c57053be6e8472174e4034fdfbf34b3e1729f5e239b3a9af89d9e59a08d6cb6", + "actual_sha256": "1c57053be6e8472174e4034fdfbf34b3e1729f5e239b3a9af89d9e59a08d6cb6", + "match": true + }, + { + "path": "net-kingdom/sso-mfa/k8s/keycape/test_openbao_private_input.py", + "expected_sha256": "84277edb5bd7858885173dea802b6bdc4f0f0c7785d6e200ee9a98d8553891a1", + "actual_sha256": "84277edb5bd7858885173dea802b6bdc4f0f0c7785d6e200ee9a98d8553891a1", + "match": true + }, + { + "path": "net-kingdom/sso-mfa/k8s/keycape/test_openbao_private_ready.py", + "expected_sha256": "8a7a033b1c509ba21397d1d74580c44f24592045b2b9de50fe87638607224277", + "actual_sha256": "8a7a033b1c509ba21397d1d74580c44f24592045b2b9de50fe87638607224277", + "match": true + }, + { + "path": "key-cape/docs/openbao-negative-token-producer-decision.json", + "expected_sha256": "7b3e4a53ac4af33c780f16c3f1aa9cde0154040ad2747a8d361dd79bbb7f435c", + "actual_sha256": "7b3e4a53ac4af33c780f16c3f1aa9cde0154040ad2747a8d361dd79bbb7f435c", + "match": true + }, + { + "path": "key-cape/docs/openbao-negative-token-producer-decision.md", + "expected_sha256": "38e4c9660ca57a1fb6e5ff04f214af61dd1a58abf564a5ed22216d909e27fc73", + "actual_sha256": "38e4c9660ca57a1fb6e5ff04f214af61dd1a58abf564a5ed22216d909e27fc73", + "match": true + }, + { + "path": "key-cape/scripts/openbao_negative_private_handoff.py", + "expected_sha256": "faf63a3e9504dcbb46847a114275f83d508521e095410a47f92f02b86ba82b1b", + "actual_sha256": "faf63a3e9504dcbb46847a114275f83d508521e095410a47f92f02b86ba82b1b", + "match": true + }, + { + "path": "key-cape/scripts/openbao_negative_private_launcher.py", + "expected_sha256": "46e57504b3185cc13f1656901a0ca02cc3887527cb09566e270f57b76099ab9c", + "actual_sha256": "46e57504b3185cc13f1656901a0ca02cc3887527cb09566e270f57b76099ab9c", + "match": true + }, + { + "path": "key-cape/scripts/test_openbao_negative_private_handoff.py", + "expected_sha256": "e4eb600718e7d93b0e801ac3ab1427af9895a6e5d877c1134369e049e0849797", + "actual_sha256": "e4eb600718e7d93b0e801ac3ab1427af9895a6e5d877c1134369e049e0849797", + "match": true + }, + { + "path": "key-cape/scripts/test_openbao_negative_private_launcher.py", + "expected_sha256": "243426a85075b3447adeb2ca320a13711409744f71837a06699de6ad5b04ee9d", + "actual_sha256": "243426a85075b3447adeb2ca320a13711409744f71837a06699de6ad5b04ee9d", + "match": true + }, + { + "path": "key-cape/scripts/test_openbao_negative_private_preparation.py", + "expected_sha256": "8e4dd327c4a339a0151ecba57db5987965b5d536ca18123fb7c74a047a241548", + "actual_sha256": "8e4dd327c4a339a0151ecba57db5987965b5d536ca18123fb7c74a047a241548", + "match": true + }, + { + "path": "railiance-platform/helm/openbao-ui-overlay-k8s.yaml", + "expected_sha256": "7b345359906bf1ecc4cb8e61de7a9f1a121068a66bd919e606190a9217a82daf", + "actual_sha256": "7b345359906bf1ecc4cb8e61de7a9f1a121068a66bd919e606190a9217a82daf", + "match": true + }, + { + "path": "railiance-platform/helm/openbao-ui-overlay/nginx.conf", + "expected_sha256": "464f7f5cecc69ea343c1e2acc5932e832b2a9c0e6a5099113634a12abc80ccb3", + "actual_sha256": "464f7f5cecc69ea343c1e2acc5932e832b2a9c0e6a5099113634a12abc80ccb3", + "match": true + }, + { + "path": "railiance-platform/helm/openbao-values.yaml", + "expected_sha256": "a10239851277889dd69dacb8636109dddd095551d85b46ca4ed2c141944e8d1e", + "actual_sha256": "a10239851277889dd69dacb8636109dddd095551d85b46ca4ed2c141944e8d1e", + "match": true + } + ], + "primary_task_readback": [ + { + "id": "4d06b059-3768-53bb-83a4-a9a71c0850b8", + "record_id": "KEY-WP-0039-T01", + "status": "done", + "blocking_reason": null, + "needs_human": false + }, + { + "id": "03da4c38-1dac-53b1-8b0b-e697df48e9d3", + "record_id": "KEY-WP-0039-T02", + "status": "wait", + "blocking_reason": "Ordered identity gate: Forgejo first SecurityCase registration/claims proof, then NetKingdom registry session and attended human/coding-agent custody; original secrets-engine-openbao registration go remains resolved; probe/coding-client custody and attended readiness are not established.", + "needs_human": false + }, + { + "id": "54d37ad8-2352-51c2-bb2e-af6070dbbd73", + "record_id": "KEY-WP-0039-T03", + "status": "done", + "blocking_reason": null, + "needs_human": false + }, + { + "id": "ddcfb482-8f33-5c81-9ce8-84be8fa5dc30", + "record_id": "KEY-WP-0038-T02", + "status": "wait", + "blocking_reason": "Registration runs as the first KnownSecurityCase of type oidc-browser-relying-party (NK-WP-0048-T06), not as a hand-built rollout.", + "needs_human": false + }, + { + "id": "40ddaa29-7245-508c-ad48-ddc063e25115", + "record_id": "KEY-WP-0038-T03", + "status": "wait", + "blocking_reason": "Claims are verified against the registered client.", + "needs_human": false + } + ], + "parent_status": "active", + "disposition": "Source review finalized; native acceptance outstanding. Preserve active parent and T02 wait. No new approval request, credential access or native action.", + "assessment": "ASSESSMENT.md" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/apply_prepare.py b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/apply_prepare.py new file mode 100644 index 00000000..771fde3a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/apply_prepare.py @@ -0,0 +1,92 @@ +"""Prepared source integration only. Root runs --execute; no commit/projection here.""" +from pathlib import Path +import argparse +import hashlib +import json +import re +import subprocess +import sys + +PACKET = Path(__file__).resolve().parent +ROOT = Path('/home/worsch/net-kingdom') +WARDEN = Path('/home/worsch/ops-warden') + +def sha(data): + return 'sha256:' + hashlib.sha256(data).hexdigest() + +def git(root, *args): + return subprocess.check_output(['git', '-C', str(root), *args], text=True).strip() + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--execute', action='store_true') + args = parser.parse_args() + manifest = json.loads((PACKET / 'publication-inputs.json').read_text()) + assert git(ROOT, 'rev-parse', '--abbrev-ref', 'HEAD') == 'main' + assert git(ROOT, 'rev-parse', 'HEAD') == manifest['base_revision'] + assert git(WARDEN, 'rev-parse', 'HEAD') == manifest['warden_revision'] + workplan = ROOT / manifest['workplan'] + original = workplan.read_bytes() + candidate = (PACKET / 'workplan.candidate.md').read_bytes() + assert sha(original) == manifest['workplan_preimage_sha256'] + assert sha(candidate) == manifest['workplan_candidate_sha256'] + assert sha((PACKET / 'task-T35.md').read_bytes()) == manifest['task_addition_sha256'] + assert candidate == original + (PACKET / 'task-T35.md').read_bytes() + assert len(re.findall(rb'^```task$', original, re.M)) == 34 + assert len(re.findall(rb'^```task$', candidate, re.M)) == 35 + assert b'id: NK-WP-0048-T35' not in original + assert sha((PACKET / 'candidate.patch').read_bytes()) == manifest['patch_sha256'] + for row in manifest['files']: + path = ROOT / row['path'] + if row['preimage_sha256'] is None: + assert not path.exists() and not path.is_symlink(), str(path) + else: + assert sha(path.read_bytes()) == row['preimage_sha256'], str(path) + protected_before = {name: sha((ROOT / name).read_bytes()) for name in manifest['protected_files']} + assert protected_before == manifest['protected_files'], 'Operator brief/index changed: refresh the prepared inputs first.' + # Preserve the original index exactly; this script never stages anything. + index = git(ROOT, 'ls-files', '--stage', '-z') + assert sha(Path('/home/worsch/repo-manager/src/repo_manager/identifiers.py').read_bytes()) == manifest['repo_manager_identifiers_sha256'] + sys.path.insert(0, '/home/worsch/repo-manager/src') + from repo_manager.identifiers import ensure_missing_work_record_identifiers + before = ensure_missing_work_record_identifiers(ROOT, execute=False) + assert before['ok'] and before['assignments'] == [] and before['files_changed'] == [] + subprocess.run(['git', 'apply', '--check', str(PACKET / 'candidate.patch')], cwd=ROOT, check=True) + if not args.execute: + print(json.dumps({'prepared_only': True, 'preimages_verified': True, 'files': 4, + 'next': 'Run this script with --execute, then run_validation.py --execute.'})) + return + subprocess.run(['git', 'apply', str(PACKET / 'candidate.patch')], cwd=ROOT, check=True) + for row in manifest['files']: + assert sha((ROOT / row['path']).read_bytes()) == row['sha256'], row['path'] + workplan.write_bytes(candidate) + preview = ensure_missing_work_record_identifiers(ROOT, execute=False) + (PACKET / 'identifier-preview.json').write_text(json.dumps(preview, indent=2) + '\n') + assert preview['ok'] and preview['files_changed'] == [manifest['workplan']] + assert len(preview['assignments']) == 1 + assignment = preview['assignments'][0] + assert (assignment['kind'], assignment['record_id'], assignment['path']) == ( + 'task', 'NK-WP-0048-T35', manifest['workplan']) + # UUID comes only from the ordinary allocator, never from this packet. + actual = ensure_missing_work_record_identifiers(ROOT, execute=True) + assert actual['assignments'] == preview['assignments'] + assert actual['files_changed'] == [manifest['workplan']] + (PACKET / 'identifier-assignment.json').write_text(json.dumps(actual, indent=2) + '\n') + allocated = workplan.read_bytes() + assert allocated.startswith(original), 'Existing workplan bytes must be preserved.' + assert len(re.findall(rb'^```task$', allocated, re.M)) == 35 + assert allocated.count(b'id: NK-WP-0048-T35\n') == 1 + assert not ensure_missing_work_record_identifiers(ROOT, execute=False)['assignments'] + assert git(ROOT, 'ls-files', '--stage', '-z') == index, 'Index must remain unchanged.' + assert {name: sha((ROOT / name).read_bytes()) for name in manifest['protected_files']} == protected_before + (PACKET / 'workplan.allocated.md').write_bytes(allocated) + publication = {'owner': 'net-kingdom', 'base_revision': manifest['base_revision'], + 'message': manifest['message'], 'files': [ + {'path': row['path'], 'sha256': sha((ROOT / row['path']).read_bytes()).removeprefix('sha256:')} + for row in manifest['files'] + [{'path': manifest['workplan']}]]} + (PACKET / 'publication-inputs.allocated.json').write_text(json.dumps(publication, indent=2) + '\n') + print(json.dumps({'source_applied': True, 'task_count': 35, 'allocated_only': assignment['record_id'], + 'files': len(publication['files']), 'commit_and_projection': 'Root handles separately.'})) + +if __name__ == '__main__': + main() diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/candidate.patch b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/candidate.patch new file mode 100644 index 00000000..671f3e21 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/candidate.patch @@ -0,0 +1,243 @@ +diff --git a/sso-mfa/k8s/keycape/test_admit_1_3_type.py b/sso-mfa/k8s/keycape/test_admit_1_3_type.py +--- a/sso-mfa/k8s/keycape/test_admit_1_3_type.py ++++ b/sso-mfa/k8s/keycape/test_admit_1_3_type.py +@@ -8,7 +8,9 @@ + acknowledged 1.3 is still refused until ops-warden adds a 1.3 pin. That is an + ops-warden owner change, and it is not made here. The tests show that 1.3's + parameters carry 1.2's pinned fingerprint, and that with only that one pin added in +-memory the committed map admits exactly the composed descriptors and nothing else. ++memory the five resolvable steps admit. The two Apps attended steps remain refused ++because their establishing login is unresolved in the synthetic catalog. Four real ++draft lane shapes are hypothetically active in that fixture; no catalog is promoted. + Trust is fixture-only, nothing is dispatched, and none of this is owner admission + or an acknowledgment. + """ +@@ -37,6 +39,8 @@ + TYPE_DIR = REPO / 'security-case-type-revisions/1.3/oidc-browser-relying-party' + TYPE_BYTES = (TYPE_DIR / 'type.yaml').read_bytes() + ARTIFACT = json.loads((ROOT / 'descriptor-composition-1.3.candidate.json').read_text()) ++CATALOG = (ROOT / 'kernel-catalog.fixture.yaml').read_bytes() ++UNRESOLVED_APPS = {'deliver-consumer-secret', 'hand-over'} + EVIDENCE = {'fixture-acceptance', 'fixture-materialization', 'fixture-descriptor', 'fixture-session'} + + +@@ -74,12 +78,13 @@ + ARTIFACT['params']['consumer_owner_repo'], + version='1.3')) + +- def admit(self, desc, type_source, *, actor=None, lane=None, agent_id=None): ++ def admit(self, desc, type_source, *, actor=None, lane=None, agent_id=None, catalog=CATALOG): + desc_bytes = c.encode(desc) + adapter = Adapter(desc.adapter, desc.adapter_source, unused, unused) + executor = Executor(Journal(Path(self.temp.name) / desc.step), + {adapter.reference: adapter}, +- lambda purpose, source, evidence: evidence in EVIDENCE, ++ lambda purpose, source, evidence: (evidence in EVIDENCE and ++ (purpose != 'catalog-routing-acceptance' or source == digest(CATALOG))), + browser_inputs=inputs.BrowserInputs(REPO)) + with mock.patch.dict(os.environ): + if agent_id is None: +@@ -87,7 +92,7 @@ + else: + os.environ['WARDEN_AGENT_ID'] = agent_id + return executor.admit(self.case_source, type_source, desc_bytes, +- b'fixture-only-catalog', principal='founder', actor=actor or desc.actor, ++ catalog, principal='founder', actor=actor or desc.actor, + lane=lane or desc.lane, + acceptance_evidence='fixture-acceptance', + materialization_evidence='fixture-materialization', +@@ -112,18 +117,33 @@ + self.assertEqual(parameter_fingerprint(TYPE_BYTES), inputs.PARAMETER_PINS['1.2']) + acknowledged = with_status('acknowledged') + for step, desc in self.descriptors.items(): ++ if step in UNRESOLVED_APPS: ++ continue # The attended session gate correctly precedes parameter validation. + with self.subTest(step=step), self.assertRaisesRegex( + Refused, 'failed exact-version validation'): + self.admit(desc, acknowledged) + +- def test_committed_map_admits_every_descriptor_once_acknowledged_and_pinned(self): ++ def test_committed_map_conditionally_admits_five_resolvable_steps(self): + acknowledged = with_status('acknowledged') + for step, desc in self.descriptors.items(): ++ if step in UNRESOLVED_APPS: ++ continue + with self.subTest(step=step), pinned_13(): + admitted, invocation, _ = self.admit(desc, acknowledged) + self.assertEqual(admitted, desc) + self.assertEqual((invocation.step, invocation.actor, invocation.target), + (desc.step, desc.actor, 'forgejo')) ++ ++ def test_unresolved_apps_sessions_refused_even_once_acknowledged_and_pinned(self): ++ for step in sorted(UNRESOLVED_APPS): ++ with self.subTest(step=step), pinned_13(), self.assertRaisesRegex( ++ Refused, 'does not resolve to an active, reviewed login lane'): ++ self.admit(self.descriptors[step], with_status('acknowledged')) ++ ++ def test_catalog_evidence_is_bound_to_exact_fixture_bytes(self): ++ mint = self.descriptors['mint-secret'] ++ with pinned_13(), self.assertRaisesRegex(Refused, 'independent owner evidence not verified'): ++ self.admit(mint, with_status('acknowledged'), catalog=CATALOG + b'\n# changed source\n') + + def test_descriptor_outside_the_map_is_refused(self): + acknowledged = with_status('acknowledged') +diff --git a/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py b/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py +--- a/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py ++++ b/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py +@@ -259,8 +259,13 @@ + case_source = yaml.safe_dump(case).encode() + typ = yaml.safe_load((root / 'security-case-types/oidc-browser-relying-party/type.yaml').read_bytes()) + typ['spec']['execution_descriptors'] = {'register-client': digest(self.desc_bytes)} ++ # Fixture-only successor lane for the adapter's current descriptor. ++ # Canonical 1.1 still names the earlier login lane and is not edited. ++ typ['spec']['follow_through'] = [ ++ dict(step, lane=self.admitted.lane) if step['id'] == 'register-client' else step ++ for step in typ['spec']['follow_through']] + type_source = yaml.safe_dump(typ).encode() +- catalog = b'fixture-only-catalog' ++ catalog = (ROOT / 'kernel-catalog.fixture.yaml').read_bytes() + sheet = json.dumps(['register-client', 'net-kingdom', 'forgejo', 'human', + 'founder', 'keycape-attended-case-change', 'fixture-acceptance', 'fixture-materialization', + 'fixture-descriptor', 'fixture-session'], separators=(',', ':')).encode() +@@ -270,6 +275,8 @@ + adapter = a.build(**dict(self.kw, admitted=invocation, case_source=case_source, + case_acceptance='fixture-acceptance')) + def fixture_verifier(purpose, source, evidence): ++ if purpose == 'catalog-routing-acceptance': ++ return source == digest(catalog) and evidence == 'fixture-descriptor' + if purpose.startswith('session-revocation:'): + _, lane, operation, attempt = purpose.split(':') + return source == digest(case_source) and lane == invocation.lane and evidence == ( +diff --git a/sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml b/sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml +new file mode 100644 +--- /dev/null ++++ b/sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml +@@ -0,0 +1,128 @@ ++# TEST ONLY: synthetic subset shaped after ops-warden 5abde817 catalog. ++# Four draft entries are hypothetically active; Apps session_lane remains unresolved. ++# Not an authenticated owner catalog, promotion, login choice or native authority. ++entries: ++- id: key-cape-oidc-login ++ risk: standard ++ owner_repo: key-cape ++ warden_executes: false ++ reviewed: '2026-06-27' ++ status: active ++ delegation: ++ mode: interim ++ intended_owner: key-cape ++ reviewed: '2026-09-08' ++ blocked_on: fixture-only; no native authority ++ lane: login ++ title: Synthetic key-cape-oidc-login ++ need_keywords: ++ - key-cape-oidc-login ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: keycape-client-secret-generate ++ risk: high ++ owner_repo: railiance-platform ++ warden_executes: false ++ reviewed: '2026-10-10' ++ status: active ++ delegation: ++ mode: native ++ intended_owner: railiance-platform ++ reviewed: '2026-10-10' ++ lane: secret ++ title: Synthetic keycape-client-secret-generate ++ need_keywords: ++ - keycape-client-secret-generate ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: keycape-attended-case-change ++ lane: attended-change ++ session_lane: key-cape-oidc-login ++ risk: high ++ owner_repo: key-cape/net-kingdom ++ warden_executes: false ++ reviewed: '2026-10-17' ++ status: active ++ delegation: ++ mode: interim ++ intended_owner: key-cape ++ reviewed: '2026-10-17' ++ blocked_on: fixture-only; no native authority ++ title: Synthetic keycape-attended-case-change ++ need_keywords: ++ - keycape-attended-case-change ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: platform-secret-delivery ++ risk: high ++ owner_repo: railiance-platform ++ warden_executes: false ++ reviewed: '2026-10-17' ++ status: active ++ delegation: ++ mode: native ++ intended_owner: railiance-platform ++ reviewed: '2026-10-17' ++ title: Synthetic platform-secret-delivery ++ need_keywords: ++ - platform-secret-delivery ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: consumer-owner-deployment ++ lane: attended-change ++ session_lane: pending-owner-confirmation ++ risk: high ++ owner_repo: railiance-apps ++ warden_executes: false ++ reviewed: '2026-10-17' ++ status: active ++ delegation: ++ mode: native ++ intended_owner: railiance-apps ++ reviewed: '2026-10-17' ++ title: Synthetic consumer-owner-deployment ++ need_keywords: ++ - consumer-owner-deployment ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: apps-consumer-handover ++ lane: attended-change ++ session_lane: pending-owner-confirmation ++ risk: high ++ owner_repo: railiance-apps ++ warden_executes: false ++ reviewed: '2026-10-17' ++ status: active ++ delegation: ++ mode: native ++ intended_owner: railiance-apps ++ reviewed: '2026-10-17' ++ title: Synthetic apps-consumer-handover ++ need_keywords: ++ - apps-consumer-handover ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/preparation.json b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/preparation.json new file mode 100644 index 00000000..20770873 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/preparation.json @@ -0,0 +1,36 @@ +{ + "schema": "custodian.nk48-catalog-fixture-publication-preparation.v1", + "status": "prepared only; canonical apply and validation runners not executed, including dry-run", + "owner_base": "342a6f25af5cdc602841948f42759ea52ef1c8f5", + "warden_base": "ae7bc73b4f4bac22454144959b870d161498e0af", + "root_source_review": "Root explicitly accepted fixture patch SHA256 df69fb2ec9f1e1cf0dd94194e3c046c995ed8a7deabf65a8e9bec34662adb501 for source integration; no owner/native assent inferred.", + "task_refinement": "Append completed T35 for distinct current authenticated-catalog/mode-aware fixture compatibility; preserve exact original workplan bytes, all34 existing task blocks/frontmatter/status/UUID. Normal allocator preview must yield exactlyT35 before execution; no manual UUID.", + "root_commands": [ + "python3 /home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/apply_prepare.py --execute", + "python3 /home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/run_validation.py --execute", + "Root normal scoped commit using publication-inputs.allocated.json; normal owner projection afterwards." + ], + "mutation_scope": [ + "Exactly the three reviewed fixture files plus the appended T35 workplan task.", + "No git stage,commit,push,projection,brief refresh or index generation in prepared scripts.", + "Preexisting operator .custodian-brief.md/WORK-RECORDS.md remain byte-identical; unrelated dirty/untracked paths are never read or written by the apply script." + ], + "validation_scope": "Canonical NK test and source files against Warden mainae7bc73;105 explicit public source hashes checked before and after. Two scoped test modules only; expected31 tests/53 subtests; no skip/deselection accepted. EmptyHOME and allowlisted environment; fresh redirected Python caches; pytest cache/conftest discovery disabled. Network denied. Native processes denied except exact pinned offline metadata validator with guarded empty-environment child. Reads from /home or /root denied except exact prehashed public source files; canonical writes denied.", + "unverified_limits": [ + "Prepared runner has only been AST-parsed; root must execute and inspect logs.", + "Python audit controls are bounded to reviewed test execution and do not claim operating-system credential isolation or an autopilot grant.", + "Warden code is source-only; 1.3 parameter pin, draft promotion, pending Apps login, nativeT03 and downstream acceptance remain gated.", + "Existing adverse review history remains unchanged." + ], + "files": { + "apply_prepare.py": "sha256:b294e6339e8c9af9ba911667646dd0ab52e75cf798de93238d84d1057c8a9e70", + "run_validation.py": "sha256:16236aa55a774f8ea6d66da4ee17f7737c6d1b013d844ca9b9759e02b615af51", + "validation-guard.py": "sha256:13611f4de25dc7d01348905c4b365a0ffbb95fd93a61c75c8faf38d705c54f50", + "workplan.preimage.md": "sha256:f92962c5aa21aade0fc2f6b4f8d9a95932fe85b107413cdd2824b6ebe72c36d9", + "publication-inputs.json": "sha256:d9bf5555013aa9e399037672c80a72af23c6815db03088bee3db4c8583197146", + "candidate.patch": "sha256:df69fb2ec9f1e1cf0dd94194e3c046c995ed8a7deabf65a8e9bec34662adb501", + "task-T35.md": "sha256:7d14d261ffbab2a930c4a3ff962cec786060cad6177280773cf1c0b0f006127f", + "validation-child.py": "sha256:6bd4e3cda22e65f90bbb4006b403270405947293be2ae8bf8fdade0abed61f45", + "workplan.candidate.md": "sha256:3bce122c5b83d9044b142fc2cabc48de5558ab0d65dc0223a8ed0325f219e981" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/publication-inputs.json b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/publication-inputs.json new file mode 100644 index 00000000..6e6f5307 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/publication-inputs.json @@ -0,0 +1,176 @@ +{ + "schema": "custodian.nk48-catalog-fixture-publication-inputs.v1", + "prepared_only": true, + "owner": "net-kingdom", + "base_revision": "342a6f25af5cdc602841948f42759ea52ef1c8f5", + "warden_revision": "ae7bc73b4f4bac22454144959b870d161498e0af", + "message": "test: align security case fixtures with authenticated catalog admission", + "workplan": "workplans/NK-WP-0048-security-case-types.md", + "workplan_preimage_sha256": "sha256:f92962c5aa21aade0fc2f6b4f8d9a95932fe85b107413cdd2824b6ebe72c36d9", + "workplan_candidate_sha256": "sha256:3bce122c5b83d9044b142fc2cabc48de5558ab0d65dc0223a8ed0325f219e981", + "task_addition_sha256": "sha256:7d14d261ffbab2a930c4a3ff962cec786060cad6177280773cf1c0b0f006127f", + "patch_sha256": "sha256:df69fb2ec9f1e1cf0dd94194e3c046c995ed8a7deabf65a8e9bec34662adb501", + "files": [ + { + "path": "sso-mfa/k8s/keycape/test_admit_1_3_type.py", + "preimage_sha256": "sha256:c512ba00513d066fd1ca8af08fd6bf106fbd7a132981b1dcc5af80a745ab03f0", + "sha256": "sha256:2186eab00b000a534ab1452f14fa7b1a7ed352d5b27c400687c1c8ec7c4c3019" + }, + { + "path": "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py", + "preimage_sha256": "sha256:4d0126416522e54eec1ae4c83b5488e09ff11ffb97ec1ee6d234548780c60f63", + "sha256": "sha256:86268e082763c388528e5175184fd32362167c3441716436e4b1cab150c3e79a" + }, + { + "path": "sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml", + "preimage_sha256": null, + "sha256": "sha256:7885b8c380c03ccb0198e540532ce80c791c8e86698521d7173642e0c7a56e53" + } + ], + "allocation": { + "method": "repo_manager.identifiers.ensure_missing_work_record_identifiers", + "manual_uuid": false, + "preexisting_assignments": [], + "expected_new_record_ids": [ + "NK-WP-0048-T35" + ], + "expected_files_changed": [ + "workplans/NK-WP-0048-security-case-types.md" + ], + "expected_task_count": 35, + "concrete_postallocation_manifest": "publication-inputs.allocated.json" + }, + "protected_files": { + ".custodian-brief.md": "sha256:3eb7f91f2443090c9b859a716d83711310364897b6144dcf10d3254342fec3d1", + "WORK-RECORDS.md": "sha256:a1fec217a6e380f528778d781dbea1fc5a836fdefa1dd4dd0308100fbe08112a" + }, + "validation": { + "tests": [ + "sso-mfa/k8s/keycape/test_admit_1_3_type.py", + "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py" + ], + "expected_result": "31 passed,53 subtests passed; no skipped or deselected tests", + "python": "/tmp/warden-kernel-review-r1/final/.venv/bin/python", + "source_hashes": { + "net-kingdom": { + "sso-mfa/k8s/keycape/test_vergabe_client_rollout.py": "sha256:f9b7defc312b0fea24ded92ef479dcc8aef063f7a66a8245760918bcf44c4af1", + "sso-mfa/k8s/keycape/test_compose_1_2_descriptors.py": "sha256:9a4b9fb0141221d6e5bcb72b3656613afda54d16ede300bffa8f71956ae6fd2c", + "sso-mfa/k8s/keycape/test_keycape_client.py": "sha256:9572044679feaedfe732e15a2b6f8ef6b41a8fe2e4430257f309a3e83e97736c", + "sso-mfa/k8s/keycape/openbao-negative-node-wrapper.py": "sha256:76ac013d1a676a0dfa58aea1ce87b0c3e72483ccd21f586a22c5475e9132f6c1", + "sso-mfa/k8s/keycape/portal-client-rollout.py": "sha256:158e1d36eb881cdd0a2eda91b472adea5e8fde5061e00d26dda368580aeb871f", + "sso-mfa/k8s/keycape/test_playwright_activation.py": "sha256:6fc22d091f27a76c32d2fb0a7fc3c6e18e54ff98d242699c518b2f9dc9fd4cbd", + "sso-mfa/k8s/keycape/exercise-approval-clients.py": "sha256:e2d3dd741ac52af28dce752344227a4443b78fedd4cfcc06ba902e679dfc9351", + "sso-mfa/k8s/keycape/keycape-client.py": "sha256:4b63161cf3365d34dd684a3116e2c935baaf7f6aa4b30983f6883546db3d6591", + "sso-mfa/k8s/keycape/test_openbao_negative_session.py": "sha256:01e23f2b4fc77824a161a57acb3a52d19aad846b3b6c0fd3abd81afa1dc2985c", + "sso-mfa/k8s/keycape/authentication-policy-rollout.py": "sha256:2c1bd23fded4855bae1eb3a08dbc4510d7f60f2bc4d625d60e471ab78f6f0251", + "sso-mfa/k8s/keycape/handover-adapter.py": "sha256:bad7c1132258f2140b0d83548031ac86eecea4f4019f34adedc1e9e3774a3832", + "sso-mfa/k8s/keycape/openbao-signin-diagnosis-rollout.py": "sha256:a57b957d6eed9e8fb09d2a7aa7405a39deeafd9aaf57a9e6dc907afabd380371", + "sso-mfa/k8s/keycape/test_handover_adapter.py": "sha256:cd1fb0eb64a777699221ebdfcd6fea96bafb9b27ec388e95dcfe66189eac8ca2", + "sso-mfa/k8s/keycape/test_authentication_policy_rollout.py": "sha256:11c10039d99a34d2819b09146a966c8b7cba6095e7a8b51c055a01e7167e3ed5", + "sso-mfa/k8s/keycape/test_deliver_consumer_secret_adapter.py": "sha256:f4e6c6acd75a36f675007d2f62a7c7c4f7bfe2951cbb5e3e4cdde8b53f17f473", + "sso-mfa/k8s/keycape/bind-env-adapter.py": "sha256:fa17fae21776b5c620ee9782adf050649c3a28719a6687d2524ff67ca7ad1925", + "sso-mfa/k8s/keycape/test_keycape_checker_snapshot.py": "sha256:9271f25c760ad732c257d59d259b5c767436a2dc2d5ba24fca259bc57761d6d1", + "sso-mfa/k8s/keycape/test_openbao_signin_diagnosis_rollout.py": "sha256:25d46fe7caca2ad4c262bd2a25188c91847304b6b051c4f3b3705c69f2803f01", + "sso-mfa/k8s/keycape/test_openbao_private_ready.py": "sha256:8a7a033b1c509ba21397d1d74580c44f24592045b2b9de50fe87638607224277", + "sso-mfa/k8s/keycape/test_mint_secret_adapter.py": "sha256:8110b6a8abd8e9a1f5e1feae11ec09c4e28cb7486c759b0e8459da1fb1b7144d", + "sso-mfa/k8s/keycape/playwright-activation.py": "sha256:5ac683b3324b00e6253f6040f4c73057027b1f98f7071160a6153794ba522757", + "sso-mfa/k8s/keycape/test_admit_1_3_type.py": "sha256:2186eab00b000a534ab1452f14fa7b1a7ed352d5b27c400687c1c8ec7c4c3019", + "sso-mfa/k8s/keycape/test_openbao_node_route.py": "sha256:1c57053be6e8472174e4034fdfbf34b3e1729f5e239b3a9af89d9e59a08d6cb6", + "sso-mfa/k8s/keycape/test_secrets_engine_openbao_client_rollout.py": "sha256:e6f86fb7712c1b9c01d9b684f26d5cc949649b823d2732eced132d59acd3fe01", + "sso-mfa/k8s/keycape/openbao-client-config.py": "sha256:1b908b4c36134212d78f9fbe7a2a201eb3ced06d31bb1dcea4a59d80689d84b1", + "sso-mfa/k8s/keycape/test_registration_original_intent_reconcile.py": "sha256:e2897b8200ec97445fc4a26c55ad82651fcb1a4d22efe7fe59d0fcfc5cd8ec71", + "sso-mfa/k8s/keycape/test_ensure_groups_adapter.py": "sha256:c8754a2ba735116edc6fe257aa993d0530cea9ca9f954ea5a621e38694906be2", + "sso-mfa/k8s/keycape/test_keycape_checker_environment.py": "sha256:35f316eed168d3df588498faf24ab9377733a7d857ddfa5e0e4322a6287c93ff", + "sso-mfa/k8s/keycape/test_bind_env_adapter.py": "sha256:a1e5e7a631a4843f9a0d2310a3942b26936103d786aeae47a142ff7c7b2fdbdb", + "sso-mfa/k8s/keycape/create-secrets.py": "sha256:5da672fff36eb94101741ad99e2a1a96ae81fea15ed1871304c40e63ce27c787", + "sso-mfa/k8s/keycape/approval-clients-rollout.py": "sha256:488d5cc59e081993dd2b5fc6d9e46bbddcaec4f5170b8f7a5ad0aae3a211a790", + "sso-mfa/k8s/keycape/vergabe-client-rollout.py": "sha256:8cee6cc5ff3e3e8617304055263d04b393d0e005c34d9af12cb7e8bc685bac1a", + "sso-mfa/k8s/keycape/keycape-registration-adapter.py": "sha256:a53beea4dbbe373ce7a5b84d55e79be8407ab9688037c7ee057afcc7be576047", + "sso-mfa/k8s/keycape/compose-1.2-descriptors.py": "sha256:39021cac900b11a59d00c5a1d5491b1ee4c639955cde07d07854c3db8bc04958", + "sso-mfa/k8s/keycape/test_approval_clients_rollout.py": "sha256:745316d42c3aba6b59b562d3bbcd4b2cb92871fb5e51a954e2254e2e550bb408", + "sso-mfa/k8s/keycape/register-user-engine-portal.py": "sha256:67173edc44f5457e7b6a3e0fb2321b398159cfce5dea8ead01eabf835fb38d76", + "sso-mfa/k8s/keycape/test_issuer_pin.py": "sha256:e471ed815af246633c0b21ac2cf5cae94d0dbdeff9e6ce801b4ddd033097dc20", + "sso-mfa/k8s/keycape/openbao-negative-session.py": "sha256:24b7b803e4eb7e6e7c0700a069dad0ec315ee7eb5538a88b9e56147f8fab5cdd", + "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py": "sha256:86268e082763c388528e5175184fd32362167c3441716436e4b1cab150c3e79a", + "sso-mfa/k8s/keycape/deliver-consumer-secret-adapter.py": "sha256:65db5386cdf08a1aa932886c046abed20330a36c96e63d4267adb8341b23da42", + "sso-mfa/k8s/keycape/test_portal_client_rollout.py": "sha256:a16cd4bf278970c10de2e1b1025597b3872c9515713dd947ac6b50cb78feea1f", + "sso-mfa/k8s/keycape/test_deliver_secret_adapter.py": "sha256:24cedec29071b62fc2c2458950ed244feeff542bc20a7d480667dd99cda16b03", + "sso-mfa/k8s/keycape/deliver-secret-adapter.py": "sha256:cd1a515a1ae2def2093660ed2a810a9c66d1d4cf7126f573ee7e9c4c42afb98d", + "sso-mfa/k8s/keycape/test_openbao_private_input.py": "sha256:84277edb5bd7858885173dea802b6bdc4f0f0c7785d6e200ee9a98d8553891a1", + "sso-mfa/k8s/keycape/register-coulomb-social.py": "sha256:b40ff4bdba71b797f8f393e79cb3c9d73b790045a0f7df6ecea35803369793c7", + "sso-mfa/k8s/keycape/mint-secret-adapter.py": "sha256:246323c7243ded18229ab063956577e151d56d9be485d3bd44fc38e5af0edf3c", + "sso-mfa/k8s/keycape/test_adapter_source_closure.py": "sha256:63cb442636d996fcf1c36b7b746ed860106a7da35dbaeb1c5129a41420ca4155", + "sso-mfa/k8s/keycape/secrets-engine-openbao-client-rollout.py": "sha256:8b834e5f0353a5e11797637420609e06e7bf7de47777c7e78b774f74d4a6afbd", + "sso-mfa/k8s/keycape/test_openbao_client_config.py": "sha256:7104a73fb936aca4829ef8046e39497d0b7347d3e74810f672e4d4ddc3346457", + "sso-mfa/k8s/keycape/ensure-groups-adapter.py": "sha256:6cba5b07a9262a8e0bf445dc4095ba03b31ddc15e2efbfe374e93f4f78b6aed4", + "sso-mfa/k8s/keycape/verify-user-engine-portal.py": "sha256:ccd5106395bd5d7b4f3dbbcbad449e3793aff217d4429b5d5af9e52ab9a58103", + "sso-mfa/k8s/keycape/test_playwright_registration.py": "sha256:b97ea8619ac768f520e4058aeb50b0b1e8ef6d2e9a1a0fff932a151a3d4b61ae", + "sso-mfa/k8s/keycape/playwright-registration.py": "sha256:bf2d6b83d93629df8ddaf6c31d6c7408ae3866969d63895714df0e08a570da99", + "identity-provisioner/group_provenance_postgres.py": "sha256:2a0111e83ad7b611076a1b45634e7f698b3d2e9acc473320b4a8ba009ebd0932", + "identity-provisioner/password_setup.py": "sha256:53012fc708384fc9cd0fff4f3fa5f204ab85866db91d726457dd130799e88ca0", + "identity-provisioner/provisioner.py": "sha256:19d1b837cbafeeacb1aa815856cd68091e6702281d72b1d860230fa320e1725b", + "identity-provisioner/copy-client-secret.py": "sha256:0f1907a9f16688148aede9fceb53a55cfd0504bcb8552f158d0fa77e9ad960c8", + "identity-provisioner/group_provenance.py": "sha256:405e08eaaab7c21d618dff4db5970607806f32ab6c461effb81c737e32182b10", + "identity-provisioner/server.py": "sha256:b61c83da6c7ce20fa2790d5bb00aeca6a91dccd133526bc559ed26562f90eb29", + "security-case-types/oidc-browser-relying-party/type.yaml": "sha256:f705c64e4875e9b8e18a912fb51c135e77898926d6a451f5cb74ab3c0cbe4d1c", + "security-case-type-revisions/1.2/oidc-browser-relying-party/type.yaml": "sha256:9e60ff569fb0d860a2bbde7bbb0991a54d4b0688f62b56df0fa5d161fd624578", + "security-case-type-revisions/1.3/oidc-browser-relying-party/type.yaml": "sha256:e75fe94110ef9fb7fb18072fe2856941b33507c99cb406d36576046481485d0a", + "security-case-type-revisions/1.3/oidc-browser-relying-party/examples/forgejo.yaml": "sha256:546aad5cf26842c484fc6ba99940d56697b85531afea11872556761008923c94", + "security-cases/forgejo-netkingdom-oidc.yaml": "sha256:bcc2c6d5bae0d28242b3cdb71e74d8ca297c2afe04766b55d53597f86893351d", + "sso-mfa/k8s/keycape/descriptor-composition-1.3.candidate.json": "sha256:773daa1df72cc7cf6a6d8aa082208181ca2438cdecc9179b1bc5b1c3a09099c2", + "sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml": "sha256:7885b8c380c03ccb0198e540532ce80c791c8e86698521d7173642e0c7a56e53", + "tools/security-case-types/security_case_evidence.py": "sha256:da8efa59c52ad73283397ebe639ae259d0cb9c6348b5cb829135c24230dcdc75", + "tools/security-case-types/security_case_validator.py": "sha256:1bcc62e9bc374c711363295549f3cd5bb0b32952671ed4b08fddc7f74742959b", + "tools/security-scenario-composer/security_scenario_composer.py": "sha256:9f0cc69930aa8ee2cc3fb92236e6a99728df17b8c0fe36e1250241c38fc01c4f", + "tools/playbook-capability-contract/playbook_contract_validator.py": "sha256:2e1e0c809d4bc9d64c2d974cc23fecd1c5636785154c2554edd9191852fd926d" + }, + "ops-warden": { + "src/warden/ca.py": "sha256:d5282819c5d29386fd59a7dc46d1abdc01e99fc6838a1a6637f90868389fe557", + "src/warden/inventory.py": "sha256:9401db92d7cbf3bea962b97e83ef2c252a19c69ab94ce4836ba58f68638cb311", + "src/warden/memory.py": "sha256:ecf5f7ccabb669b56bfca3a109b10bbe8437bdd2ea30a47a4c08570f97d7be2a", + "src/warden/case_inputs.py": "sha256:1334b0cd9897e763cfea2d306e997c659f3f284ecc3f9612140c2104835da7c7", + "src/warden/audit.py": "sha256:6b5b8fe053064d3905294bfde1b691fcca8a0806c889e52a49494470d29c24a0", + "src/warden/case_type.py": "sha256:7b659b8d682863cd28df24025be4b10dd7ca3df724350a22d360c6af9615bca7", + "src/warden/vault.py": "sha256:860b8c9f498b3955b363a74dd74087b6d0c399599ef22b951a076ee33c95929f", + "src/warden/taint.py": "sha256:8c3d161d18d429d026aad715ac01e2d33e0f4e84ac03fbaea3cea15017ad39a1", + "src/warden/case_run.py": "sha256:1bc73e30ac718fd75bbaff2a739495fc051aeaec73802ac71f0583cb2d53ab0a", + "src/warden/vault_hints.py": "sha256:0d158ffcc3a93d5442df5fbe13d4c1e3b3159dd60301530bbdae6db9bc9c709e", + "src/warden/access.py": "sha256:258d45d2f84b54b2464373ad4d7d6df6ff95b8e8d60f5e85ceb2d962fcfa8a61", + "src/warden/clock_attribution.py": "sha256:5fcf07a2525a6a250442e14b6f6229f7db2a6ca02fc6aac23cdaa4c1a78c63eb", + "src/warden/case_plan.py": "sha256:9352ae8683d1181980c4ff38524582e4be448d33c85b558f60582c1e5bb5bbaa", + "src/warden/caller_identity.py": "sha256:747edfaceecd470981949253bda0c3bd2f487d40a9a2f77c2cc1eff3f34f04f7", + "src/warden/policy.py": "sha256:aac46f538e986731cd841581c91efe004b8c1940966b954ef635780a719dada4", + "src/warden/case_receipt_state.py": "sha256:a2cda7f187e77bd76d4d209505638de44a587fae0bc033ec75c23ee9ea9f73bc", + "src/warden/config.py": "sha256:8a857faa3811b00303d4d5c904d69255ebdaff3239e8516f97e6606e53b46924", + "src/warden/openbao_caller.py": "sha256:7e6d07827d00eae7de3b2367c97bdcda1a13d6559627201a4ba09a0e42d46a17", + "src/warden/doubles.py": "sha256:5460e07f5bd0f51a81d3f3c0ac84efde65ca9130b1039f94ee22ca484976a9de", + "src/warden/posture.py": "sha256:1bb60c4dd4634ea42cb130ae1325d7415adf43096906bde2515396c368256e33", + "src/warden/cli.py": "sha256:196cd829d3dbfbd2333598a983687bde1f9bcdfadef95b2fd1d237c4a5f060a9", + "src/warden/proxy.py": "sha256:69649bcf8979e4ed7f9104e927b458827a355c4846143367f4cd49c8b89b96da", + "src/warden/plan.py": "sha256:001b3197e644221344d52e6b1594eb8eae78d10e73d18ed31273505909f3916b", + "src/warden/worker.py": "sha256:d7c2b391b36033d44d8c6841b9bce18a05c74b41ef2910b91689820b6a1cb44e", + "src/warden/mask.py": "sha256:0876412d453fa84109dc8ee0468449f40cf4d3421b056f30fc205f0f59ec494b", + "src/warden/models.py": "sha256:f4100b02c5d96d537980e00d4b874159cd5822ba8219f1f533a2516912b7bd85", + "src/warden/__init__.py": "sha256:047e0feba479474235f0707a207655ecfddfb33cd4f54069134419b8ca4ea24a", + "src/warden/scorecard.py": "sha256:0fa5aef34aeb004fa7fcfabc287759cc47421ca5244c1f31fc467b22a653353c", + "src/warden/desk.py": "sha256:2499120392a5a1c0fd8f423d5b5c787c75a4efb9a986a1b7bcb85eae13423e85", + "src/warden/routing/scaffold.py": "sha256:5079c8e51f8d487eae3f322a66324bd70cefb637bb28f46c861032de8ec54aa2", + "src/warden/routing/models.py": "sha256:b85372b2572a49af62e9534f26a33963b894633c7cd43dd2a28416b8959cba3e", + "src/warden/routing/__init__.py": "sha256:e9124811ebe11ad32c98ab462b2eed634d4ddca08792981d0f353b223a239902", + "src/warden/routing/catalog.py": "sha256:5b95810df9e6102a33d3a116a096cd75292c8572bad721fe6baa772caacc9bc3", + "src/warden/scripts/ops_ssh_wrapper.py": "sha256:e8c289882f2ad439d2eb32f9a871967420fefaffe745c9271c1a2e948fbdfe50", + "src/warden/scripts/__init__.py": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + } + }, + "repo_manager_identifiers_sha256": "sha256:4e35fcd009c20822574fd33171176bd14a1ff2dd5af8b0bb2820954974593a2a", + "authorization": "Root accepted the exact source fixture patch for source integration. This packet adds no owner/native authority or catalog/pin promotion. No prepared script has been executed.", + "publishable": false, + "requires_allocated_manifest": true, + "publication_file_paths": [ + "sso-mfa/k8s/keycape/test_admit_1_3_type.py", + "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py", + "sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml", + "workplans/NK-WP-0048-security-case-types.md" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/run_validation.py b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/run_validation.py new file mode 100644 index 00000000..12f783d6 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/run_validation.py @@ -0,0 +1,73 @@ +"""Prepared canonical source validation; --execute launches only the two scoped tests.""" +from pathlib import Path +import argparse +import hashlib +import json +import re +import shutil +import subprocess +import tempfile + +PACKET = Path(__file__).resolve().parent +ROOTS = {'net-kingdom': Path('/home/worsch/net-kingdom'), 'ops-warden': Path('/home/worsch/ops-warden')} + +def sha(data): + return 'sha256:' + hashlib.sha256(data).hexdigest() + +def sources(manifest): + allowed = [] + for owner, rows in manifest['validation']['source_hashes'].items(): + for relative, expected in rows.items(): + path = ROOTS[owner] / relative + assert not path.is_symlink(), str(path) + assert sha(path.read_bytes()) == expected, str(path) + allowed.append(str(path.resolve())) + return allowed + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--execute', action='store_true') + args = parser.parse_args() + manifest = json.loads((PACKET / 'publication-inputs.json').read_text()) + allowed = sources(manifest) + revision = subprocess.check_output(['git', '-C', str(ROOTS['ops-warden']), 'rev-parse', 'HEAD'], text=True).strip() + assert revision == manifest['warden_revision'] + if not args.execute: + print(json.dumps({'prepared_only': True, 'public_source_files_verified': len(allowed), + 'tests': manifest['validation']['tests']})) + return + protected = {name: sha((ROOTS['net-kingdom'] / name).read_bytes()) for name in manifest['protected_files']} + scratch = Path(tempfile.mkdtemp(prefix='nk48-catalog-canonical-validation-')) + for name in ['home', 'tmp', 'guard', 'pycache']: + (scratch / name).mkdir() + shutil.copyfile(PACKET / 'validation-guard.py', scratch / 'guard/sitecustomize.py') + shutil.copyfile(PACKET / 'validation-child.py', scratch / 'child.py') + (scratch / 'allowed.json').write_text(json.dumps(allowed)) + (scratch / 'pytest.ini').write_text('[pytest]\n') + environment = { + 'HOME': str(scratch / 'home'), 'TMPDIR': str(scratch / 'tmp'), 'PATH': '/usr/bin:/bin', + 'PYTHONPATH': str(scratch / 'guard') + ':' + str(ROOTS['ops-warden'] / 'src'), + 'PYTHONDONTWRITEBYTECODE': '1', 'PYTHONPYCACHEPREFIX': str(scratch / 'pycache'), + 'LANG': 'C.UTF-8', 'WARDEN_REVIEW_ALLOWED_SOURCE_LIST': str(scratch / 'allowed.json'), + 'WARDEN_REVIEW_VALIDATOR_PREFIX': str(scratch / 'tmp/warden-case-validator-'), + } + with (PACKET / 'canonical-validation.log').open('w') as log: + result = subprocess.run([manifest['validation']['python'], str(scratch / 'child.py')], + cwd=ROOTS['net-kingdom'], env=environment, + stdout=log, stderr=subprocess.STDOUT) + sources(manifest) + assert protected == {name: sha((ROOTS['net-kingdom'] / name).read_bytes()) for name in manifest['protected_files']} + log_text = (PACKET / 'canonical-validation.log').read_text() + counts_verified = bool(re.search(r'\b31 passed, 53 subtests passed\b', log_text)) + counts_verified = counts_verified and not re.search(r'\b[1-9][0-9]* (?:skipped|deselected)\b', log_text) + receipt = {'executed': True, 'counts_verified': counts_verified, 'returncode': result.returncode, 'warden_revision': revision, + 'net_kingdom_head': subprocess.check_output(['git', '-C', str(ROOTS['net-kingdom']), 'rev-parse', 'HEAD'], text=True).strip(), + 'verified_public_source_files': len(allowed), 'tests': manifest['validation']['tests'], + 'log_sha256': sha((PACKET / 'canonical-validation.log').read_bytes()), 'scratch': str(scratch), + 'limitations': 'Source fixture tests only; no native owner execution, acceptance, catalog promotion or pin.'} + (PACKET / 'canonical-validation.json').write_text(json.dumps(receipt, indent=2) + '\n') + print(json.dumps(receipt, indent=2)) + raise SystemExit(result.returncode or (0 if counts_verified else 1)) + +if __name__ == '__main__': + main() diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/task-T35.md b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/task-T35.md new file mode 100644 index 00000000..78735f2d --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/task-T35.md @@ -0,0 +1,38 @@ + +## T35 — Align source admission fixtures with the authenticated catalog and attended-session API + +```task +id: NK-WP-0048-T35 +status: done +priority: high +``` + +Completed 2026-10-17, source fixture compatibility only. Distinct from T32's +independent agent-mint regression repair: both remaining opaque catalog byte +placeholders now use one well-formed synthetic catalog whose exact bytes are +bound by the fixture evidence verifier. The fixture mirrors the six relevant +Warden lane shapes; four draft statuses are hypothetically active, while both +Apps establishing login references remain unresolved. No real catalog entry, +owner login choice or production parameter pin changes. + +Against the reviewed mode-aware Warden source now integrated at +`ae7bc73b4f4bac22454144959b870d161498e0af`, scratch validation passes 31 tests +and 53 subtests. Five resolvable 1.3 descriptors conditionally admit under +fixture-only acknowledgment and pinning; both Apps attended steps refuse before +execution. Changed catalog bytes refuse, all independent mint-guard tests still +reach their intended guard, and the registration fixture's actual kernel +run/rollback and uncertain-result paths pass with synthetic owner callbacks. +The registration fixture explicitly aligns its in-memory proposed type lane +with its current descriptor; canonical 1.1 is unchanged. + +The same tests against predecessor `117fec9241e7b985dfb187b992e173d0a5dc3700` +pass 31 tests and 51 subtests, with only the two new Apps refusal assertions +failing because that predecessor lacks the attended-session catalog check. +Tests target the reviewed current API; the parser or Apps gate is not weakened +for predecessor compatibility. Evidence and root source review: +`the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-update-r1/` +and `nk48-catalog-fixture-publication-r1/`. Canonical validation/publication +receipts belong in the latter packet when performed. This records source +fixture work, not native T03, owner assent, exact-type acknowledgment, PIN-1, +composition/admission completion under T16 or the native first case under T06. +T33 and T34 retain their existing issuer-store and consumer-inverse work. diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/validation-child.py b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/validation-child.py new file mode 100644 index 00000000..7e659ae1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/validation-child.py @@ -0,0 +1,43 @@ +"""Focused canonical-source test process. Network/native/estate-read guard required.""" +from pathlib import Path +import os +import socket +import subprocess +import sys +import sitecustomize + +assert sitecustomize.ACTIVE is True +assert not {'BAO_TOKEN', 'VAULT_TOKEN', 'WARDEN_AGENT_ID'} & os.environ.keys() +assert list(Path.home().iterdir()) == [] +try: + socket.socket() +except RuntimeError as error: + assert str(error) == 'fixture validation: network disabled' +else: + raise AssertionError('network guard inactive') + +import warden.case_inputs as inputs +import pytest + +assert Path(inputs.__file__).resolve() == Path('/home/worsch/ops-warden/src/warden/case_inputs.py') +PREAMBLE = '''import sys as _review_sys\ndef _review_guard(event,args):\n if event.startswith('socket.') or event in {'subprocess.Popen','os.system','os.exec','os.posix_spawn'}:\n raise RuntimeError('review validator: network/native disabled')\n if event=='open' and isinstance(args[0],str) and (args[0].startswith('/home/') or args[0].startswith('/root/')):\n raise RuntimeError('review validator: ambient home denied')\n_review_sys.addaudithook(_review_guard)\n''' +old_run = subprocess.run + +def run_pinned(arguments, *positional, **keywords): + if (type(arguments) is not list or len(arguments) != 5 + or arguments[:3] != [sys.executable, '-I', '-c'] + or arguments[3] != inputs._VALIDATE + or not str(arguments[4]).startswith(sitecustomize.VALIDATOR_PREFIX) + or keywords.get('env') != {}): + raise RuntimeError('fixture validation: unexpected process refused') + return old_run([*arguments[:3], PREAMBLE + arguments[3], arguments[4]], + *positional, **keywords) + +inputs.subprocess.run = run_pinned +raise SystemExit(pytest.main([ + '-q', '-p', 'no:cacheprovider', '--noconftest', + '-c', str(Path(os.environ['TMPDIR']).parent / 'pytest.ini'), + '--rootdir=/home/worsch/net-kingdom', + '/home/worsch/net-kingdom/sso-mfa/k8s/keycape/test_admit_1_3_type.py', + '/home/worsch/net-kingdom/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py', +])) diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/validation-guard.py b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/validation-guard.py new file mode 100644 index 00000000..05f72946 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/validation-guard.py @@ -0,0 +1,35 @@ +"""Copied as sitecustomize.py into a fresh scratch directory by run_validation.""" +import json +import os +from pathlib import Path +import sys + +ALLOWED = frozenset(json.loads(Path(os.environ['WARDEN_REVIEW_ALLOWED_SOURCE_LIST']).read_text())) +VALIDATOR_PREFIX = os.environ['WARDEN_REVIEW_VALIDATOR_PREFIX'] + +def guard(event, args): + if event.startswith('socket.'): + raise RuntimeError('fixture validation: network disabled') + if event == 'subprocess.Popen': + command = args[1] + if (type(command) is list and len(command) == 5 + and command[:3] == [sys.executable, '-I', '-c'] + and command[3].startswith('import sys as _review_sys\ndef _review_guard(') + and str(command[4]).startswith(VALIDATOR_PREFIX) and args[3] == {}): + return + raise RuntimeError('fixture validation: native process disabled') + if event in {'os.system', 'os.exec', 'os.posix_spawn'}: + raise RuntimeError('fixture validation: native process disabled') + if event == 'open' and isinstance(args[0], str): + path = str(Path(args[0]).absolute()) + if path.startswith(('/home/', '/root/')): + # Only exact prehashed public source may be read from the estate. + if str(Path(path).resolve()) not in ALLOWED: + raise PermissionError('fixture validation: unlisted estate file disabled') + mode, flags = args[1:3] + if ((isinstance(mode, str) and any(c in mode for c in 'wax+')) + or (flags & (os.O_WRONLY | os.O_RDWR | os.O_CREAT | os.O_TRUNC | os.O_APPEND))): + raise PermissionError('fixture validation: canonical source writes disabled') + +sys.addaudithook(guard) +ACTIVE = True diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/workplan.candidate.md b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/workplan.candidate.md new file mode 100644 index 00000000..82f67d2c --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/workplan.candidate.md @@ -0,0 +1,1647 @@ +--- +id: NK-WP-0048 +type: workplan +title: "Establish SecurityCaseTypes so that known security cases are light" +domain: infotech +repo: net-kingdom +status: active +flavor: implementation +owner: claude-code +topic_slug: netkingdom +created: "2026-10-08" +updated: "2026-10-17" +depends_on: [] +related_repos: + - ops-mason + - ops-warden + - key-cape + - railiance-platform + - informed-decision +state_hub_workstream_id: "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb" +--- + +# NK-WP-0048 - Establish SecurityCaseTypes so that known security cases are light + +## Why + +The founder's direction (2026-10-08): setting up a security integration of a +kind that has been done before should be easy, meaning accept the case, then +ops-mason arranges it and ops-warden follows through. Setting up a new kind +needs ample documentation and tests and an informed-decision, because its shape +is part of the security architecture. + +Today every integration is hand-built: per-client helper scripts, per-lane +custody, founder checklists. The trigger was KEY-WP-0038 (Forgejo as an OIDC +client), whose next step was going to be yet another hand-written rollout +script. + +This plan continues the pattern work of NK-WP-0008 (pattern infospace), +NK-WP-0009 (tutorials) and NK-WP-0030 (scenario composition). It turns patterns +into **SecurityCaseTypes** that ops-mason and ops-warden can execute. Canon: +`canon/standards/security-case-types_v0.1.md` (proposed). + +Companion plans: ops-mason `MASON-WP-0010` (materialization) and ops-warden +`WARDEN-WP-0044` (follow-through). + +## Tasks + +```task +id: NK-WP-0048-T01 +status: done +priority: high +state_hub_task_id: "930ac3e9-20ec-5473-98cd-3fe8fddb730f" +``` + +### T01 — Accept the terminology and the canon + +Founder review of `canon/standards/security-case-types_v0.1.md`, including its +section 10 open questions. On acceptance the canon status goes from `proposed` +to `accepted`. + +2026-10-08: accepted by the founder (in session). Canon status `accepted`; +section 10's open questions are carried forward to the first type (T04, T05). + +```task +id: NK-WP-0048-T02 +status: done +priority: high +state_hub_task_id: "19c25d96-a55c-58f0-9168-3fdbc4955fc2" +``` + +### T02 — Inventory the de-facto types already built by hand + +Read-only. List every security integration built so far and group them by shape. +Known starting points: + +- browser OIDC relying parties on key-cape: informed-decision-approver, + coulomb-social, user-engine portal, openbao-admin, and Forgejo (pending) +- confidential service clients with `client_credentials`: secrets-engine + approval, requester and openbao clients, approval-engine operator +- workload KV read lanes on OpenBao: the railiance-platform credential lane + designs and CCRs, for example `railiance-backup-offsite-lane` +- short-lived SSH certificates through ops-warden (`warden sign`) +- tunnelled operator access (ops-bridge) + +For each: the repositories involved, the hand-built steps, attended human steps, +custody paths, verification evidence, and rollback (if any). Output +`docs/security-case-type-inventory.md`, ranking candidate types by how often the +shape recurs and how much manual work each instance costs today. + +2026-10-08: done, `docs/security-case-type-inventory.md`. 36 of 37 CCRs are +already `request_type: workload-kv-read`, a de-facto type reviewed each time as +if it were new. Browser clients: 5 hand-built plus Forgejo, each with its own +rollout script. Confidential service clients need a registration plus two or +three KV-read CCRs each. A forge read identity is needed in bulk by +ORGREF-WP-0002-T06. Recommendation: oidc-browser-relying-party first (unblocks +the forge), workload-kv-read second (largest payoff), then forge-read-identity. + +```task +id: NK-WP-0048-T03 +status: done +depends_on: [NK-WP-0048-T01] +priority: high +state_hub_task_id: "e487975b-73b1-516c-971d-da4cbbb93063" +``` + +### T03 — Schema, template and validator + +- `canon/schemas/security-case-type_v0.1.schema.json` and + `security-case_v0.1.schema.json` +- `security-case-types/_template/` with `type.yaml`, `README.md` and tests to copy +- a validator, extending `tools/security-scenario-composer/`, that checks a type, + checks a case against its type, and renders the case into the composer's + deterministic plan (still `execution.permitted: false`) + +Acceptance: the validator rejects missing sections, secret-shaped parameter +values, unpinned providers and cases against non-`implemented` types, with tests +for each. + +2026-10-08: done. `canon/schemas/security-case-type_v0.1.schema.json` and +`security-case_v0.1.schema.json`; `tools/security-case-types/security_case_validator.py` +(`validate-type`, `validate-case`, `render`, reusing the scenario composer); +`security-case-types/_template/` (a valid, runnable example type over +`net-kingdom.local-identity`, with README sections, an example case and tests that +travel with every copy). 31 tests pass, including the composer's existing suite. + +```task +id: NK-WP-0048-T04 +status: done +depends_on: [NK-WP-0048-T02, NK-WP-0048-T03] +priority: high +state_hub_task_id: "2fffe112-7d55-5680-9952-78d74f44f87f" +``` + +### T04 — Define the first type: browser OIDC relying party + +`security-case-types/oidc-browser-relying-party/`, version 1.0: + +- parameters: client id, display name, exact redirect URIs, scopes, client type + (confidential or public), MFA pin, the groups the consuming service maps, + custody path for the secret (confidential only), consuming service and its + owner +- composition: key-cape client registration (key-cape declares it as a playbook + capability), secret minting into custody (railiance-platform), LLDAP group + existence and membership (net-kingdom identity-provisioner), handover to the + consuming service +- materialization (ops-mason) and follow-through (ops-warden) sections +- verification: discovery lists the redirect URI; a test sign-in returns the + expected claims for one human; anonymous access to the custody path is denied +- rollback: remove exactly this client and its custody path +- README: threat model, MFA rationale, why redirect URIs are exact, which steps + still need an attended login and how that is minimised +- reference instances: informed-decision-approver, coulomb-social, user-engine + portal, openbao-admin + +Acceptance: complete per canon section 3, tests green, status `proposed`. + +2026-10-08: done. `security-case-types/oidc-browser-relying-party/` 1.0 (proposed): +`type.yaml` with 12 parameters (the custody reference is required only for +confidential clients), composition over key-cape's new +`key-cape.oidc-client-registration` declaration (contract PASS, `maturity: +planned`), materialization and follow-through, verification and rollback, all +conditional on client type where it matters. One attended step, +`register-client`, justified by the live registry being a Kubernetes Secret. +README with threat model, alternatives, an honest fit table (portal and vergabe +fit; Forgejo is the first confidential case; openbao-admin, coulomb.social and +informed-decision-approver do not fit 1.0), and known limits. Examples: Forgejo +(checked against the accepted request) and a public portal. The validator gained +`when` / `required_when` conditions and provider discovery. 43 tests pass. +ops-mason's and ops-warden's sections are drafted in the type. Their owners +review them in MASON-WP-0010-T01 and WARDEN-WP-0044-T01 before acknowledgment +(T05). + +```task +id: NK-WP-0048-T05 +status: done +depends_on: [NK-WP-0048-T04, MASON-WP-0010-T01, WARDEN-WP-0044-T01] +priority: high +state_hub_task_id: "3d987d3d-0797-538b-86e4-51185a327ae2" +``` + +### T05 — Acknowledge the type through informed-decision + +Prepare the Decision Memo from the type's README and `type.yaml` and submit it +through informed-decision's production intake. On acknowledgment the type +moves to `acknowledged`. + +2026-10-08: Decision Memo prepared. Hub decision `e418263e-a71f-4f01-a970-c87c9e187c09`. +`security-case-types/oidc-browser-relying-party/decision/`: `packet.md` (question, +one act, what acknowledging does not do, the shape, alternatives, attended +steps, limits, evidence), `build_intake.py` and the built `intake.json` (memo +class `decision-record`, review group `net-kingdom-admins`, resolves the hub +decision on answer). The envelope passes informed-decision's own +`validate_submission`. Queuing it is an attended operator step, a write inside +the production dispatcher pod: + + kubectl -n state-hub exec -i deploy/state-hub-memo-dispatch -- \ + python -m api.services.memo_dispatch --queue /data/private enqueue --envelope /dev/stdin \ + < security-case-types/oidc-browser-relying-party/decision/intake.json + +The answer then appears for review in informed-decision. + +2026-10-08: queued by the founder (`pending`, `queued`) after one refusal: the +first envelope's idempotency key was not State Hub's stable +`state-hub..` form, and the builder now validates against both +sides. The dispatcher delivered it to informed-decision (ledger 7 → 8 +delivered). T05 waits for the founder's answer in informed-decision, which +resolves hub decision `e418263e`. + +2026-10-08: ops-mason's review (MASON-WP-0010-T01) folded into the type, still +1.0 `proposed`: `secret_ref` is no longer a parameter, the type derives +`platform/workloads/keycape/{client_id}`; policies are +`workload-kv-read-keycape-{client_id}-eso` and +`workload-kv-read-keycape-{client_id}-{consuming_service}`, each with a templated +body (`read` on that one data path); new `openbao_role` +`external-secrets-keycape-{client_id}` (Kubernetes auth, ESO service account, +15m, no default policy); catalog entry `{consuming_service}-keycape-client`; +the two rollback steps on the KV path collapse into one metadata delete. The +schema and validator now require a `body` on policy and role items. 105 tests +pass. Two consequences: the delivered memo describes the type before these +changes (a case-set custody reference, two differently named policies, no ESO +role), so the founder answers on a superseded shape unless the memo is +re-sent; and Forgejo's custody path moves from the accepted request's proposed +`platform/workloads/forgejo/netkingdom-oidc-client` to +`platform/workloads/keycape/forgejo`, which key-cape (KEY-WP-0038) and +railiance-apps (RAPPS-WP-0016-T02) need to adopt in T06. ops-warden's review +(WARDEN-WP-0044-T01) is still in progress. + +2026-10-08: revised memo `nk-wp-0048-t05-oidc-browser-relying-party-r2` built +(`packet.md`, `intake.json`, packet `sha256:af6435e2…`); it states that it +supersedes the first memo and passes informed-decision's and the dispatcher's +validation. It needs a new memo id because the dispatcher refuses new content +under a delivered idempotency key (`idempotency_conflict`). Queuing it is the +same attended step as above. Both memos serve hub decision `e418263e`; the +first answer resolves it, so the first memo must not stay open: an accept on it +would acknowledge the superseded shape, and a decline would resolve the +decision against r2. Close it with `return` (a reviewer verb that requests a +new revision and does not resolve the hub decision; only accept and decline +do), commenting that r2 supersedes it, then answer r2. `withdraw` exists in +the vocabulary but is not offered to reviewers, and lifecycle `revise` only +applies to lifecycle-registered memos, not intake-delivered ones. + +2026-10-09: the founder reports r2 enqueued and the first memo returned. At +close, hub decision `e418263e` still showed `open` (not verified whether r2 +was answered or the answer is still in transit; the dispatcher ledger was not +read). ops-warden's review (WARDEN-WP-0044-T01, ops-warden +`history/2026-10-08-oidc-rp-follow-through-review.md`, d470f2e) arrived at +21:25, before r2 was built, and is not in r2. Required before WARDEN-WP-0044-T02: +R1 a per-step `lane` (missing: identity-provisioner caller credential, +railiance-platform broker grant), R2 canon meaning of `warden_executes: true` +(caller proxy, caller identity, no standing ops-warden token; ADR-0002), R3 a +per-step `value_handling`. Refinements R4 (one type-level catalog lane instead +of a per-case entry, which conflicts with ops-mason's item 5), R5 (ESO Ready gate +before bind-env), R6 (exact accepted memberships), R7 (mfa-pinned and +secret-delivered checks). Next: if r2 was accepted, fold R1-R3 and R5-R7 in as +a follow-up and settle R4 between ops-warden and ops-mason before T06; if not, +hold r2, fold them in and build r3. + key-cape and railiance-apps were told about Forgejo's new custody +path. + +2026-10-09: r2 was not answered (hub decision `e418263e` open; dispatcher 9 +delivered), so r2 is held and r3 replaces it. ops-warden withdrew R4 for R4′ +(message a66a9204): one catalog entry per case with its body templated in the +type. Folded in: + +- Canon section 3: a narrow meaning of `warden_executes: true` (caller proxy, + caller identity, no standing credential; ops-warden ADR-0002), plus per-step + `lane`, `value_handling` and an optional `ready_check`. A catalog entry body is + now required, like policy and role bodies. +- Schema and validator enforce all of these. +- The type: lanes `identity-provisioner-groups` and + `keycape-client-secret-generate` (both new) and `key-cape-oidc-login`; + `mint-secret` is `generated_in_custody`; a Ready gate on `deliver-secret`; + `ensure-groups` adds exactly the accepted case's memberships; new checks + `secret-delivered` and `mfa-pinned`; the catalog-entry body follows R4′. +- 110 tests pass. + +Memo r3 (`nk-wp-0048-t05-oidc-browser-relying-party-r3`, packet +`sha256:726dfc01…`) passes informed-decision's and the dispatcher's validation. +The founder queues it with the same command, returns r2 with a comment that r3 +supersedes it, then answers r3. + +Prerequisites for T06, not for T05: +- the two new lanes, each through its owner; +- a founder-approved rollout of an identity-provisioner image containing + 630ebfd (the deployed one is main-6c4fcaf from 2026-09-24, without + `/v1/groups/ensure`). + +ops-mason's request to create LLDAP group `fluid-telegram-operators` (message +259ec26d) was answered: not possible from here by that path; the founder creates +it in the LLDAP admin UI. + +2026-10-09: ops-warden finished its side of WARDEN-WP-0044-T01 (message +`58d33f40`, commit 0e7ceb8): the revised type conforms to `warden case +check-type`, with no further changes asked of the type. This acknowledges that +review. Its later addendum R8 (message `af274783`, ops-warden +`history/2026-10-08-oidc-rp-follow-through-review.md`) showed that lane +`identity-provisioner-groups` cannot exist as declared: the provisioner's only +HTTP credential is user-engine's runtime token, and its NetworkPolicy admits +only user-engine pods, so a caller-proxy lane would act as user-engine. Taken +option 1 (ops-warden's recommendation): `ensure-groups` and its rollback are +attended, in the `register-client` session on `key-cape-oidc-login`, run inside +the provisioner pod; no token is read. Option 2 (an operator credential of its +own on the provisioner) stays open for a later version. `warden case +check-type` now reports only `keycape-client-secret-generate` +(railiance-platform) as missing. 89 tests pass. + +Hub decision `e418263e` was still open, so memo r4 +(`nk-wp-0048-t05-oidc-browser-relying-party-r4`, packet `sha256:452ea421…`) +replaces r3; it passes informed-decision's and the dispatcher's validation. The +founder queues it with the same command, returns r2/r3 if still open with a +comment that r4 supersedes them, then answers r4. + +Prerequisites for T06 are now: lane `keycape-client-secret-generate` +(railiance-platform), and a founder-approved rollout of an identity-provisioner +image containing 630ebfd. + +2026-10-09: done. The founder queued r4 (`pending`, `queued`), returned r3 as +superseded and accepted r4 in informed-decision. informed-decision's hub +write-back is off in production (`INFD_HUB_WRITEBACK` unset), so net-kingdom +resolved hub decision `e418263e` from the founder's report, naming memo r4 in +the rationale. The type is `acknowledged`; it becomes `implemented` with T06. + +```task +id: NK-WP-0048-T06 +status: wait +depends_on: [NK-WP-0048-T05, NK-WP-0048-T08, NK-WP-0048-T09, NK-WP-0048-T12, NK-WP-0048-T13, NK-WP-0048-T14, NK-WP-0048-T15, NK-WP-0048-T16, NK-WP-0048-T17, NK-WP-0048-T18, NK-WP-0048-T20, MASON-WP-0010-T03, WARDEN-WP-0044-T03] +blocking_reason: "Type1.2 architecture has a confirmed source-only founder acknowledgment; canonical1.1 remains unchanged/default and the1.2 reference case stays proposed. Needs explicit version selection/reference-source integration without normal admission bypass, closed owner adapters plus global/native receipt verifier (WARDEN-WP-0044-T03), independently verified six-object structural materialization and CCR42 claims/created-only provenance, exact broker/case/source reconciliation, then separately authorized native mint/delivery and attended registry/consumer verification. Source acknowledgment, a bundle or local tests do not prove implemented/materialized/live status." +priority: high +state_hub_task_id: "d9b26bcf-a7c6-59a2-92a0-f913d76a203c" +``` + +### T06 — First KnownSecurityCase: Forgejo + +Write `security-cases/forgejo-netkingdom-oidc.yaml` from the parameters the +founder accepted in KEY-WP-0038-T01 (`key-cape/docs/forgejo-oidc-client-request.yaml`), +so that acceptance carries over as the case acceptance. ops-mason materializes it; +ops-warden follows through and verifies it. The type becomes `implemented` once +this reference case is live. + +This replaces the hand-built path proposed for KEY-WP-0038-T02. + +2026-10-09: case written, `security-cases/forgejo-netkingdom-oidc.yaml`, status +`accepted`: the example's parameters plus the founder's 2026-10-08 acceptance of +the key-cape request (owner and founder), with the custody-path derivation +covered by the type's acknowledgment (memo r4). It validates and renders (plan +`execution.permitted: false`; three attended steps on `key-cape-oidc-login`); +it needs `--allow-unimplemented` until it is live, since it is the case that +makes the type `implemented`. A test keeps it equal to the type's example. +Still open before it runs: ops-mason renders and builds it (MASON-WP-0010-T02, +T03, unblocked by T05), ops-warden plans and runs it (WARDEN-WP-0044-T02, T03), +railiance-platform's `keycape-client-secret-generate` lane (asked by ops-mason +`789feb39` and ops-warden `d9f889b1`, both unread), and a founder-approved +identity-provisioner rollout containing 630ebfd. + +2026-10-09: identity-provisioner rolled out, founder-approved in session: +`main-630ebfd` (`sha256:bafb4860…`, built by the image workflow) replaces +`main-6c4fcaf` (`sha256:ffacd5d7…`; only change: 630ebfd, additive). Applied +with `kubectl set image` on the Deployment only (generation 17 → 18, 1/1 Ready); +the file's Service, NetworkPolicies and Ingress were not reapplied. Verified in +the pod: `ensure_service_groups` and `revoke_service_groups` present, `/readyz` +200; no token used, no group changed. Rollback: `kubectl -n sso set image +deploy/identity-provisioner provisioner=forgejo.coulomb.social/coulomb/identity-provisioner@sha256:ffacd5d790a5b7800e0535f3aa95b7de52c7a68e4f575b9192c3e1622fa672c2`. +The pin in `sso-mfa/k8s/identity-provisioner/deployment.yaml` follows. + +2026-10-09: ops-warden closed WARDEN-WP-0044-T01 and shipped `warden case plan` +(T02, message `06303d1d`); the accepted Forgejo case is refused until ops-mason +materializes it, and a materialized copy plans cleanly once +`keycape-client-secret-generate` exists. Its observation that `bind-env` carries +a literal `KEYCAPE__CLIENT_SECRET`: the validator now renders a +`{param:env}` format spec (upper case, `-` as `_`, as `keycape-client.py` +derives the name) and rejects unknown specs, and follow-through and rollback +text is now checked for unknown placeholders too (patch-level, canon section 6). +The type keeps the literal until ops-warden's planner (`text.format`) renders the +spec as well; asked of ops-warden. 53 tests pass. + +2026-10-10: ops-warden rendered `{param:env}` in `warden case plan` +(23ba584, message `c1df14b7`; other specs and `!conversion` refused). The type +adopts it as a 1.0 patch (canon section 6): `bind-env` and its rollback now read +`KEYCAPE_{client_id:env}_CLIENT_SECRET`. ops-mason reports the Forgejo case +rendered and built (message `1ebddae9`; CCR drafts handed to railiance-platform), +so T06 now waits on the platform apply, the mint-secret lane and the attended +register-client session. + +2026-10-10: key-cape adopted the type's custody path (key-cape ab5cccd, message +`88a4559c`): `docs/forgejo-oidc-client-request.yaml` and KEY-WP-0038-T02 name +`platform/workloads/keycape/forgejo`, field `CLIENT_SECRET`, delivered as +`sso/keycape-forgejo-client` through `external-secrets-keycape-forgejo`, and the +`forgejo/netkingdom-oidc-client` proposal is withdrawn. This matches the type and +the Forgejo example; no change needed here. + +2026-10-10: key-cape's type-composition review (key-cape 6038483, message +`8e5ed5f6`) found the composition sound with two blocking findings, taken as a +1.0 patch (stricter validation and documentation, canon section 6): +R1, redirect URIs now refuse `?` and `#` in the type pattern and in +`keycape-client.py`'s `REDIRECT` (KeyCape refuses `?` at startup and the single +replica would stop); R2, `allowed_scopes` always includes `groups`, the renderer +refuses `access_groups` without it, and `access_groups` now says the consumer +enforces the gate because KeyCape has none; R3, `mfa_required` "false" means the +per-user privacyIDEA policy; R4, register-client's justification records the +restart for every client, the quiet window, and that the rendered registry must +pass KeyCape's client validation before it. The accepted Forgejo case and both +examples still validate; 116 tests pass. +Open, needs a decision: R2's verification step that the consumer enforces the +group gate is a new verification step, hence 1.1 (minor), and the validator pins +cases to the exact type version, so the accepted 1.0 Forgejo case would need +re-pinning. Also open with key-cape: a KeyCape entry point that validates a +rendered client registry without starting the server; until then +`keycape-client.py` mirrors the redirect rule. + +2026-10-10: founder go for 1.1, so no 1.0 run overlaps. The type adds +verification `consumer-enforces-groups`, and hand-over now requires the consumer +to enforce `access_groups` (minor, canon section 6; risk class unchanged, no new +acknowledgment; history in the type README). The accepted Forgejo case and both +examples are re-pinned to `oidc-browser-relying-party@1.1` before any apply; the +acknowledgment intake keeps `@1.0` as the record of what was acknowledged. +ops-mason's build and ops-warden's case-ref digest predate this and need a +re-render. + +2026-10-10: ops-mason re-rendered the Forgejo case from `@1.1` (message +`22c6bba6`; plan digest `af1f4f81…`, no collisions) and rebuilt the bundle. The +rendered OpenBao objects are identical to 1.0, so the already applied +CCR-2026-0041 stands; 1.1 changes only consumer-side steps. key-cape shipped +`keycape check-config` (c528daa, message `a7b0aeff`): KeyCape's startup checks +without secret values, including the new duplicate-clientId rule. +`keycape-client.py --check-config ` now runs it on the live and the +proposed registry, fed on stdin, and apply refuses a proposed registry that +fails; register-client's entry point names the option (1.1 patch). The deployed +image predates c528daa, so the binary is built from key-cape source for now. +Before the next KeyCape rollout (Forgejo register-client or the CCR-2026-0018 +window), the attended operator runs `inspect --check-config` so the live +registry is checked too. + +```task +id: NK-WP-0048-T07 +status: wait +depends_on: [NK-WP-0048-T06] +blocking_reason: "The next types follow once the first one is proven end to end." +priority: medium +state_hub_task_id: "c3c9c3ae-4f23-5ba7-9e6f-e63bcf29b9f7" +``` + +### T07 — Queue the next types + +From the T02 ranking, open the next type drafts (likely the confidential service +client and the workload KV read lane), each to be acknowledged on its own. +Record which existing hand-built instances get adopted as cases, without +rewriting them in place. + +```task +id: NK-WP-0048-T08 +status: done +priority: high +state_hub_task_id: "8e519082-dc8b-5e46-b660-03d03e55dcf6" +``` + +### T08 — identity-provisioner: ensure service-access groups + +The type's `ensure-groups` step calls `identity-provisioner groups ensure --groups + --members `. The provisioner already has idempotent +`_ensure_group` and `_add_group`, but exposes only tenant-scoped operations. Add +the general operation (create if absent, add the listed memberships, never +remove others), its rollback (remove only this case's memberships), tests, and +the ops-warden route for its service identity. + +2026-10-08: done. `identity-provisioner/provisioner.py` gained +`ensure_service_groups` (`POST /v1/groups/ensure`) and `revoke_service_groups` +(`POST /v1/groups/revoke`), behind the existing service-token check. Names +matching `tenant*`, `netkingdom-*` and `lldap_*` are reserved; members must +already exist; everything is validated before any change; memberships are read +back before success; nothing else is ever removed; groups are deleted only when +asked and empty. 7 new tests (39 in the provisioner suite). The type's +`ensure-groups` step and its rollback now name these endpoints. The ops-warden +route for the provisioner's service token belongs to WARDEN-WP-0044-T01. + +```task +id: NK-WP-0048-T09 +status: done +priority: high +state_hub_task_id: "0ee12dfc-8260-5038-bd39-cc7fb4113be0" +``` + +### T09 — The `keycape-client` entry point and its declaration + +Planned first as key-cape KEY-WP-0038-T04. Moved here because the machinery a +live registration needs already lives in net-kingdom, where KeyCape is deployed +(`sso-mfa/k8s/keycape/`): the contained kubectl, the cluster-identity pin and the +issuer pin. A copy in key-cape would drift. + +2026-10-08: done. `sso-mfa/k8s/keycape/keycape-client.py` derives the KeyCape +client record from a case (`client-from-case`). It adds or removes exactly one +client with the existing safeguards (byte-preserving merge, exact match or +refuse, shared-reference refusal, compare-and-swap, read-back, contained errors), +requires the Deployment env binding first for confidential clients, and requires +the case acceptance record for `apply` instead of a per-client founder decision +id. 15 tests, including a regression showing that the vergabe case reproduces +its hand-built registration exactly; all 71 helper tests pass. Declaration +`capabilities/playbooks/net-kingdom.keycape-client-registration.yaml` (contract +PASS, `maturity: implemented`) replaces key-cape's draft. The type now pins it, +and for confidential clients adds `deliver-secret` (delivery from custody into +the sso namespace) and `bind-env` (Deployment env), attended in the same session +as `register-client`. The per-client helpers stay until their clients are +adopted as cases. + +2026-10-10 — NetKingdom owner review of the execution seam, source only: +ops-warden/docs/security-case-execution-proposal.md SHA256 78ab1439e4c5beb205aeccf15b1b2e706511be55ab195c5a3aa682f326c7c77c +was reviewed against INTENT, SecurityCase canon, acknowledged type1.1, current +case and owner source. docs/security-case-execution-owner-review.md supports +the closed adapter/receipt direction with explicit versioned schema, structural +materialization provenance, unchanged caller/session boundaries, safe CAS +reconciliation and exact-created-object rollback requirements. This is owner +review, not approval. Supporting file digests are in the adjacent sources JSON. + +Current source exposes a circular wait: ops-mason T03 waits on mint while Warden +and the broker refuse a non-materialized case. Structural acceptance therefore +needs its own native pinned receipt before mint, not a successful mint before +materialized. The platform broker additionally pins type1.0 while Forgejo is +accepted at1.1; platform-owner alignment and tests are required, not an unchecked +version bypass. T06 remains wait. No case/type lifecycle status, grant, authority +or live runtime changed by this review. A proposed informed-decision would +adopt the source contract only; native materialization and execution acceptance +stay distinct. + +Final proposal re-review: staged Warden proposal SHA256 78ab1439e4c5beb205aeccf15b1b2e706511be55ab195c5a3aa682f326c7c77c +adds only the explicitly local reducer appendix, not an accepted wire protocol +or executor. The exact-final review and sources JSON supersede the earlier +1035f049... proposal review. Platform staged the exact type1.1 broker correction +with ten fake-backend subprocess checks (script SHA256 +9576cd211cfc06526ec4cc9bd0a5b06f0f59287a68931bb2d6e3592a951ddc7d). +The next source work is the versioned closed adapter/receipt/materialization +contract, not another relaxation of the broker's status gate. Native work still +requires installed broker provenance, structural reader receipts, exact new +materialized-case bytes, caller grant/session revocation and verified execution. +No installed/native acceptance is inferred from that staged correction. + +2026-10-11 — new source-only type1.2 architecture acknowledgment: +Confirmed native founder ACCEPT of infd-20261011-forgejo-type12-source-r1@1 +at06:47:39Z, approval8e9332c8-754a-420c-b8b7-445cb4fe6765. Exact frozen packet +0b377d647ca748cd03c92f9792396412048055d4bde9f7bb06ff6d413f7acd68 and submission +585cee731de30d2b37883a57abfd9eb32f023ee694e8d911989109d5caf80569; native receipt +retained in docs/evidence/2026-10-11-forgejo-type12-source-acknowledgment/. +The complete acknowledged1.2 source package is isolated under +security-case-type-revisions/1.2/oidc-browser-relying-party; default loader and +current accepted1.1 case remain untouched because load_type is single-version. +The new proposed1.2 case is NOT accepted/materialized/live and has no acceptance +fields. Actual reference-migration design approval is a separate Apps owner +receipt; no1.1 approval is inherited. Source-recording review/test proof and exact +next gates are in docs/forgejo-type12-source-acknowledgment-followthrough.md. +T06 remains wait and T07 remains its existing dependent task; type is NOT +implemented and no first-case/native grant or broader workplan finish is asserted. + +2026-10-11 — bounded explicit version selection source preparation for T06: +The validator now offers optional exact version_roots/--version-root VERSION=PATH +selection with duplicate/mismatch/traversal/symlink refusal and no fallback. The +default1.1 source and historicalacceptedcase hashes/ordinaryrefusal/preparation +render stayunchanged; actual1.1 is acknowledged, not implemented. Acknowledged1.2 +ordinaryadmission also refuses; optionalpreparation remains nonexecuting.43local +validatorchecks pass and original1.1 CLIrenderbytes match exactly. Makerproof: +docs/evidence/2026-10-11-explicit-type-version-selection/source-integration-validation.json. +FormalNetownerreview/reference-source integration and all existing native adapter, +provenance/broker/materialization/attendedproof gates remain; T06 stayswait, no +new residual or firstcase/typeimplementation/native grant is inferred. + + +2026-10-16 — isolated source preparation for T06 (canonical integration pending): +Added `check-evidence` to the existing validator CLI. It reuses exact version +selection and ordinary type/case/render admission, checks actual Mason structural +request source/inventory/projection pins and reads actual Warden journal rows +read-only. Successful rows require exact type-declared descriptors and attempt/ +revocation fingerprints. Existing acknowledged types without machine descriptors +remain plan-only. The compatibility result never claims authenticated native +completion: Request and journal fingerprints are not portable native evidence. +Owner authentication/status binding and actual native gates remain unresolved; +T06/T07 statuses and both type/case lifecycles remain unchanged. No dispatch, +credential access or authority expansion is introduced. See tool README for the +existing owner protocol boundaries and source integration tests. + +Concrete next Warden owner integration: current `Executor.admit` refuses every +case parameter whose sensitivity is not public/operational, so browser +`redirect_uris`, `allowed_scopes`, `client_type`, `mfa_required` (and 1.2 +`consumer_namespace`) fail after otherwise prepared admission. The sensitive +classification is a security-change review level, not secret content. The +Warden owner must validate through NetKingdom's existing exact-version case/type +validator, then project only descriptor-declared safe target metadata; do not +remove the credential/value refusal or copy complete parameters into journals. +Actual owner descriptor acknowledgment and independent evidence admission remain +prerequisites, with normal admission still refusing unimplemented types. + + +## T10 — Source compatibility checker for Mason and Warden evidence + +```task +id: NK-WP-0048-T10 +status: done +priority: high +state_hub_task_id: "4b06ca97-c1e4-5680-bf22-ab75ab1646a4" +``` + +Completed 2026-10-16 in published source `c31d21ba`. The read-only +`check-evidence` command checks the actual Mason structural request and Warden +journal source protocols against an exact version/render. Independent source +review passed 103 tests at that checkpoint. It always reports native completion +false and execution prohibited. Fixtures and local journal fingerprints do not +provide authenticated owner/native evidence. This records completed source scope +previously described under T06; it does not duplicate native acceptance credit. + +## T11 — Validate the optional machine-descriptor pin contract + +```task +id: NK-WP-0048-T11 +status: done +priority: high +state_hub_task_id: "ef2a0119-f59e-5e45-9519-115da9df7b85" +``` + +Completed 2026-10-16. Reproduced the JSON schema rejecting a valid +`execution_descriptors` map while the Python validator accepted malformed maps. +The schema now supports the existing Warden optional exact-byte pin map; semantic +validation binds keys to declared steps, bounds the map and checks digest shape. +The direct evidence API refuses malformed maps before accessing them. Twenty-one +new checks and all 127 affected source checks passed. No current type/case bytes, +status, owner descriptors or native acceptance changed. Source evidence and +publication receipt: Custodian +`docs/changes/netkingdom-target-2026-10-16/browser-acceptance-next/`. + +## T12 — Prepare NetKingdom-owned attended step adapters + +```task +id: NK-WP-0048-T12 +status: todo +priority: high +state_hub_task_id: "7ce4eee3-cd47-55a9-bfa5-4f1835d4d6fd" +``` + +Owner: NetKingdom. Retained scope: prepare bounded attended Deployment env, +config verification and restart/readiness steps around the existing helpers. +Next action: identify exact current entry points and their revision/readback +contracts, then implement fixed source-pinned callbacks or receipt-only attended +steps. Completion requires positive/refusal checks, exact target/source pins and +uncertainty behavior without acquiring user-engine runtime identity or exposing +registry/client secrets. Existing caller/session, cluster/issuer, CAS/readback +and status-only output boundaries remain mandatory. + +2026-10-16 task refinement: the original broad adapter scope is split into T13 +(completed registration source candidate), T14 (group creation provenance), T15 +(durable registration recovery) and T16 (descriptor/artifact selection and owner +review). This preserves T12's task ID and Hub UUID while giving each remaining +outcome an owner and completion gate. T06 now names every source dependency; +its native/reference lifecycle acceptance scope remains unchanged. Completion +of any source task supplies no Warden, Platform or Apps assent and no native +execution authority. + +## T13 — Prepare the fixed registration adapter source candidate + +```task +id: NK-WP-0048-T13 +status: done +priority: high +state_hub_task_id: "b264c10b-565c-5d29-b788-03cf5fbd2883" +``` + +Completed 2026-10-16, source implementation and synthetic fixture proof only. +Added an injection-only adapter around actual `keycape-client.run`: fixed +case/principal/human/lane/source/acceptance binding, existing CAS/readback, +metadata-only owner evidence and per-attempt parent-session revocation boundary. +The descriptor source composition pins the exact checker executable digest +alongside adapter/helper source. Creation-only rollback authenticates its +creation receipt and refuses changed postcreation UID/resourceVersion; +pre-existing clients confer no rollback authority. Missing readback, evidence, +revocation or process-local creation provenance cannot become retry-safe success. + +Evidence: Custodian `docs/changes/netkingdom-target-2026-10-16/browser-adapter-next/` +R3 candidate, explicit patch and postimages, retained R1 rejected custody finding +and R2 revision, and 36 passing source checks (16 new, 20 existing). Three checks +use actual Warden kernel admission/dispatch/rollback with published Warden +`d97652a3bb5fa733b063d71a1b74068efcccf572` producer pins unchanged. Owner trust, +descriptor/type/case and Kubernetes objects remain synthetic fixtures. This +records a completed source deliverable, not independent review, publication, +type acknowledgment, exercised procedure, identity admission or native browser +acceptance. Independent root source review: Custodian browser-adapter-next/coordinator-review-r3.json. Source integration and normal publication/synchronization receipts: Custodian browser-adapter-next/canonical-integration.json. These receipts supply no other-owner assent or native authority. + +Source publication: `0775c2bfa41af236301155bb5a69bbf088bdf823`, independently +reviewed by the Custodian coordinator before integration. The required initial +projection and ordinary UUID writeback both completed with zero failures and +zero automation errors. Generated-only brief commits were refused by the normal +hook; exact pre-existing staged/working brief bytes were restored. The separate +canonical integration receipt retains those refusals and projection evidence. +Native admission and all other-owner acceptance remain open. + +## T14 — Admit governed group rollback against native owner boundaries + +```task +id: NK-WP-0048-T14 +status: progress +depends_on: [NK-WP-0048-T20, NK-WP-0048-T21] +priority: high +state_hub_task_id: "fce95440-a25b-5f27-8ef3-a3d182099113" +``` + +Owner: NetKingdom. Next action: bind the completed T21 PostgreSQL journal to +an admitted dedicated CNPG consumer through the existing `rapp-postgres` +database-per-consumer contract. Identify the actual deployment/package and +custody owner, admitted placement/capacity and role/renewable lease/TLS target; +implement the independently retained exact content checkpoint and authoritative +tenant/case/source/principal callbacks before enabling governed group operations. +The injection-only backend and fixture callbacks do not supply production scope +or authorization. Existing service tokens, caller-supplied JSON and provenance +receipts confer no new grant. The default production endpoint remains disabled +without the trusted integration. SQLite remains local/disposable only; any +production exception requires explicit scoped governance under ADR-0015. + +2026-10-17 owner-integration refinement: T23 records the completed source/package +placement review, distinct from T21's source/disposable-SQL proof. Its dedicated +`rapp-identity-provisioner` recommendation is draft and unbound, not an accepted +package or existing repository. The full six-consumer rapp-postgres renderer +accepts the inert candidate on platform-pg-2 as its third of four declared +consumers; first-cell placement is refused as a fifth. Neither the estimated +four-consumer ceiling nor source requests establish native headroom or backup. + +Next independent owner contracts: NetKingdom/package/substrate owners accept +exact deployment/rollback fate; rapp-postgres admits the dedicated consumer, +roles, five-connection budget and actual backup/restore; Platform admits exact +renewable runtime/migration delivery and TLS/CA/SAN; network owners scope SQL, +broker and checkpoint paths without assuming a narrow policy subtracts additive +same-namespace access. Protected caller owners must provide authoritative +GroupJournalBinding construction and current authorization; an independent +existing holder must authenticate and atomically advance the exact content +checkpoint, not a counter or ordinary Audit receipt. Directory/runtime owners +must select and prove either an exclusive all-writer maintenance barrier or +provider-supported CAS/generation, including established sessions, lifecycle +cascades and remove/readd ABA. No source review establishes those owner facts. + +The default PostgreSQL activation and destructive native rollback remain refused. +Storage/lease acceptance can be proposed separately from LDAP mutation only after +exact owner source/target/custody/verification/recovery and cost/risk review; +State Hub guard approval grants none of it. Source-only integration review and +native acceptance matrix: Custodian native-storage-r1/OWNER-REVIEW.md. T14's +existing status, UUID, dependencies and native completion gate are retained. + +2026-10-17 refinement: T20 retains the historical durable SQLite source and +actual disposable LLDAP proof. T21 extracts the completed PostgreSQL source and +bounded real disposable SQL compatibility proof. T14 remains `progress` for +native CNPG admission/recovery, protected owner integration and exclusion of all +external LDAP writers. Separate source publication/projection and independent +cleanup receipts belong to coordinator follow-through; no missing native assent +is represented as received. + +Completion still requires independently reviewed/admitted ADR-0015-conforming +CNPG storage (or an explicit governed exception), backup/lost-store recovery and +migration of legacy requests; a native +writer-isolation/fencing or provider CAS/version contract that closes external +writer races and remove/re-add ABA; exact case/source/principal and current +native object bindings for protected callbacks; and actual per-attempt evidence, +revocation and readback/refusal verification through the existing owner paths. +Only independently retained confirmed creations may be undone. Every +pre-existing/shared group and membership must remain preserved; unresolved +intents never expire into retry authority. The disposable fixture supplies none +of these native custody, authorization, owner-acceptance or production claims. + +## T15 — Define authenticated recovery for lost registration process state + +```task +id: NK-WP-0048-T15 +status: wait +depends_on: [NK-WP-0048-T31] +blocking_reason: "Source candidate 061461e is merged. Waiting on the owner to select the real authenticated original-attempt holder and native readback, and on independent re-review of the changed T13 adapter source." +priority: high +state_hub_task_id: "1b825705-4848-5edc-832f-b1622cd9bdb7" +``` + +2026-10-17 source part merged (061461e via 65559ef). `build()` takes optional +paired `holder`/`observe` capabilities and installs `reconcile_original`; the T31 +fixtures now run through the adapter's own path. Rollback after restart is still +refused, and there is no add replay. This changes `keycape-registration-adapter.py`, +so the revision reviewed under Custodian `browser-adapter-next/coordinator-review-r3.json` +is superseded. The new revision has no independent review yet and must not be +pinned on the strength of the old one. + +2026-10-17: T31 fixtures done (74adcd7). What remains for T15: the owner +selects the real authenticated original-attempt holder, and the T13 adapter +gains the holder capability, `reconcile_original` and reconcile-aware `verify` +described in T31. + +Owner: NetKingdom for registration state, with Warden owning kernel evidence +admission. T22 records the completed source review and exact existing-seam gaps; +T15 retains implementation and authenticated restart/lost-receipt acceptance. +Next action: select and admit the actual owner publisher/authenticator and bounded +original-attempt readback contract for the merged holder/observe adapter seam. +Warden's original-intent persistence/interface (`a45cf475`) and additive validation +(`117fec9241e7b985dfb187b992e173d0a5dc3700`) are now published and projected. +The local Journal retains admitted nonsecret original context, validates original +actor/attempt and metadata linkage to the original running receipt, and supplies +it separately from the new reconciliation attempt. This local consistency is not +independent original-holder authorization or creation provenance; neither the +journal nor a current matching registry entry reconstructs creation authority. + +The owner contract must bind the original Invocation, case/type/descriptor/catalog/ +acceptance pins, source, principal and admitted tenant/realm provenance, separately +from the new reconciliation attempt and its independently revoked parent session. +Use an existing authenticated holder/readback; Audit Core's custody API is a +candidate only until its actual registration source/class, load-bearing emission +contract and separate scoped reader are admitted. No new broker or receipt trust +root is proposed. A missing original record, ambiguous publication, NO_CHANGE, +changed native revision or lost readback stays uncertain; no add replay or undo. + +Completion requires restart/lost-receipt fixtures against the selected actual owner +contract: independently authenticated original created-only provenance, original +exact client entry and unchanged current postcreation UID/resourceVersion before +any undo, with wrong attempt/case/source/principal and unavailable-holder refusals. +The merged T13 adapter exposes reconciliation only through paired injected +holder/observe capabilities and still refuses post-restart rollback. Existing +source review, JSON receipts and synthetic trust do not satisfy independent +holder authorization/provenance or native admission, or authorize attended recovery. +Exact remaining owner facts: Custodian native-registration-r1/original-attempt-review.json. + +2026-10-17 check (net-kingdom-worker): Warden's original-intent lookup interface +is not published — ops-warden head is `d97652a`, with no WARDEN-WP-0044-T03 +commit, and the net-kingdom inbox holds no announcement. No restart/lost-receipt +fixture or readback seam was added this session; the work is deferred behind +T16's decomposition under the same token budget. Remains todo, gated on Warden +publishing the reviewed lookup/context interface and on owner selection of the +authenticated original-attempt holder. + +2026-10-17 current-source correction: the earlier same-day `d97652a` lookup +checkpoint and T31 adapter-next-action note above are historical and superseded +by the published Warden interface/validation and merged `061461e` adapter seam. +The 54 focused Warden checks establish source behavior only. Current admission +leaves tenant/realm empty; no admitted tenant/realm provenance is inferred. +T15 remains wait for actual independently authenticated owner-holder/readback +selection, independent review of the changed adapter, and native restart/lost- +receipt acceptance. Existing task metadata, owner gates and historical reviews +are unchanged. + +## T16 — Select and review the actual machine descriptor composition + +```task +id: NK-WP-0048-T16 +status: todo +depends_on: [NK-WP-0048-T24, NK-WP-0048-T25, NK-WP-0048-T26, NK-WP-0048-T27, NK-WP-0048-T28, NK-WP-0048-T29, NK-WP-0048-T30] +priority: high +state_hub_task_id: "200bf500-5084-5ae7-be26-3033fe1f296e" +``` + +2026-10-17 coordinator review r4 approved the 1.3 candidate at 1920b13 with no +findings (the-custodian `nk48-adapters-1.2-review/coordinator-review-r4.json`). The founder chose +option A of the T16 owner-review packet (`nk48-t16-owner-review/founder-option-decision.md`): +1.3 with execution descriptors for all seven steps. Owner reviews for A are open +in the-custodian `docs/changes/netkingdom-target-2026-10-17/nk48-1.3-owner-review/` (net-kingdom, +railiance-platform, railiance-apps, ops-warden, key-cape). The owner-review packet +supersedes the r1 composition pointer: T16's exact composition is now +`sso-mfa/k8s/keycape/descriptor-composition-1.3.candidate.json`. + +2026-10-17 successor candidate prepared (source only, `proposed`): +`security-case-type-revisions/1.3/oidc-browser-relying-party/` is the 1.2 package plus +an `execution_descriptors` map of the seven composed descriptors, with examples +pinned to `@1.3` and no acknowledgment. ensure-groups, hand-over, +deliver-consumer-secret and the composer accept 1.3 (835680c, merged acda26c). +`test_admit_1_3_type.py` runs Warden's real admission against the committed 1.3 type: +the proposed type is refused; an acknowledged copy is refused because ops-warden +pins parameter fingerprints only for 1.1 and 1.2; and with only a 1.3 pin (equal to +1.2's fingerprint) all seven are admitted. This is a major change under canon +section 6. Next: r4 source review of the changed adapters and the map, then owner +reviews, including the ops-warden 1.3 pin, the mint-secret warden_executes/human +question and the owner-run steps question, then the founder's Decision Memo. + +Owner: NetKingdom for descriptor/type source and exact checker artifact; Warden +independently owns global provenance/admission. T22 records the completed seven-step +source1.2 inventory and regenerated register-client descriptor using the delivered +checker and current sealed-snapshot source; T16 retains exact owner review, +complete descriptor composition and admission. Next action: bind actual native +publisher/authenticator, original/current session verification and revocation, +executable storage/custody and config pins, then obtain the six missing fixed +owner descriptors/adapters for ensure-groups, mint-secret, deliver-secret, +bind-env, deliver-consumer-secret and hand-over. The inventory identifies each +existing owner seam, exact missing contract and created-only rollback requirement; +it is not an executable bundle. T14 and T15 remain independent prerequisites. + +Review the dedicated consumer source1.2 composition only through the existing +explicit version-root selection. Keep canonical1.1/default and its accepted case +unchanged, and the source-only acknowledged1.2 reference case proposed without +acceptance fields. New descriptor bytes require a reviewed exact successor +revision/version under canon section6; they do not inherit historical source +acknowledgment. Changed authentication/materialization/trust needs the prescribed +informed-decision acknowledgment. Do not insert a partial descriptor map or use +--allow-unimplemented preparation as ordinary case/native admission. The registry +helper reports restart_required; separately review quiet-window restart/readiness +and actual consumer verification rather than infer activation from registry CAS. +Exact composition: Custodian native-registration-r1/descriptor-composition.json. +Completion requires separate owner source review of exact machine descriptors, +artifact/source/config pins, normal type/version admission and independent +evidence-verification boundaries. Warden d97652a refreshes producer validator +pins for NetKingdom 015694ee; it does not attest T13's new adapter. Pinning any +machine descriptor into an acknowledged type is a separately reviewed source +change. Platform owns structural/mint/broker/delivery evidence; Apps owns actual +consumer login/group enforcement. Neither their assent nor native acceptance is +supplied by this task. + +2026-10-16 source checkpoint: T19 below extracts the completed per-attempt +executable snapshot implementation and reviewed fixture proof. T16 retains +native executable storage/custody, exact owner evidence/session callbacks, +complete descriptor composition and ordinary type/version admission. The +successor descriptor/source pins are proposed only; the earlier descriptor +history is preserved. T14 group provenance and T15 durable restart/recovery +remain independent open requirements. No native acceptance is counted here. + +2026-10-17 budget checkpoint (net-kingdom-worker): no source change made. The +T13 registration adapter alone is 217 source and 317 test lines plus an +independent review; six further owner descriptors/adapters cannot be completed +within one per-task token budget (soft 8000 / hard 10000), so the task was +stopped below 50% and is decomposed rather than pushed through. Proposed split, +one source-candidate task each with positive/refusal fixtures, canonical1.1 +default unchanged and no --allow-unimplemented admission: (a) ensure-groups, +bound to T14's journal/provenance seam; (b) mint-secret and (c) deliver-secret, +Platform-owned evidence seams; (d) bind-env and (e) deliver-consumer-secret; +(f) hand-over, Apps-owned consumer verification; then (g) descriptor composition +over the reviewed set. Each candidate needs its owner's source review before +pinning; none is authored here as owner-accepted. Status stays todo. + +2026-10-17 task refinement after coordinator r5: completed independent mint- +guard regression coverage is extracted as T32. T33 tracks the exact Platform +issuer-store source/reference correction; T34 tracks the Apps configuration +inverse reachable without secret or hand-over resource creation. T16 retains +final exact seven-descriptor composition, independent owner reviews and admission; +its status and existing dependencies are preserved. The kernel branch also needs +its own KR1-F1/F2 admission/dispatch corrections and independent review under +WARDEN-WP-0044-T03 before any 1.3 pin. Historical r4 acceptance does not supersede +r5's findings or establish native readiness. + +## T17 — Build and exercise the exact offline config-checker artifact + +```task +id: NK-WP-0048-T17 +status: done +priority: high +state_hub_task_id: "8c3e4baa-a218-5996-af9e-fe1153a46dac" +``` + +Completed 2026-10-16, isolated artifact/source fixture proof only. Built the +existing `key-cape/src/cmd/keycape` command from published clean source revision +`3c71226a1a7b8a2bdb710e9c497e1a1f7f8a3987`, source tree +`f0010b9cab17dbc3a787628a29657d98b900320f`, with cached Go 1.23.0, +CGO disabled, Linux/amd64 v1, trimmed paths, disabled VCS stamping and offline +read-only module selection. The full retained closure pins 108 source files, +9876 toolchain files and ten used module source directories. Three isolated +build locations produced identical 13633409-byte artifacts: +`sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5`. + +Eight disposable checks use the actual executable and maintained helper/kernel, +with complete synthetic configs and a minimal environment: add/created-only +removal, normal pinned producer admission, rollback, lost-readback uncertainty, +stale revisions, substituted checker refusal, invalid startup config and missing +secret-env refusal. No checker stub or producer-pin override remains. The +artifact-bound descriptor proposal is +`sha256:76b1153d188062ece53fcd5e8d35290fdbfd02a69dd79d4b001fc42781afcdc3`. +Evidence: Custodian +`docs/changes/netkingdom-target-2026-10-16/browser-checker-artifact-next/`. +The first two build attempts succeeded but their closure collection failed; +both failures are retained, as is refusal of the older incomplete synthetic +fixture. No production config, credentials or cluster mutation was used. + +This extracts completed build/fixture scope from T16 without claiming KeyCape +owner endorsement, native checker selection/storage custody, acknowledged type +integration, native evidence/session callbacks or attended browser acceptance. +T16 retains exact owner review and composition/admission scope. The attended +registration procedure remains unexercised. + +## T18 — Make checker input and executable selection deterministic + +```task +id: NK-WP-0048-T18 +status: done +priority: high +state_hub_task_id: "9c45da71-fb4c-5f20-9065-90f448f37c64" +``` + +Completed 2026-10-16, isolated source correction and real-artifact fixture proof +only; independent integration/publication remain separately recorded. KeyCape +source review identified non-secret `KEYCAPE_ACCOUNT_PORTAL_URL` and +`KEYCAPE_BROWSER_LOGOUT_URL` overrides in config.Load. The original helper +inherited ambient environment, allowing valid supplied configuration to be +rejected or invalid supplied URL configuration to be admitted. A bare relative +checker filename could also be replaced by PATH lookup after the adapter had +hashed the selected local file. All three counterexamples are retained against +the unchanged predecessor. + +The existing helper now resolves the selected checker file to an absolute path +and passes an explicit empty subprocess environment. Three opt-in real-checker +regressions verify both URL-verdict directions and relative-file selection under +a non-checker PATH decoy. All 39 affected checks pass with the exact supplied +artifact, as do 11 real-artifact helper/kernel scenarios. Source evidence: +Custodian `docs/changes/netkingdom-target-2026-10-16/browser-checker-environment-r2/`. +Historical descriptors remain retained; the helper correction changes successor +source-composition pins and requires their separate review/admission. An absolute +path is not immutable custody and does not eliminate file replacement races; +T16 retains native executable storage/custody and callback/type admission. +No production configuration, credentials or cluster mutation was used. + +Source integration and publication: `916ba4b33e03179274d03b78bd898a4843e8653f`, following independent +Custodian source review in browser-checker-environment-r2/coordinator-review.json. +The ordinary protected projection pass assigned T17/T18 UUIDs with zero failures +and zero automation errors; generated-only brief commit refusal is retained. +The exact prior staged/working brief bytes were restored. Final source/publication/ +projection evidence is retained in Custodian browser-checker-environment-r2/ +canonical-integration.json. These source receipts do not admit native executable +custody, owner callbacks, acknowledged type changes or browser identities. + +## T19 — Bind checker execution to verified immutable attempt bytes + +```task +id: NK-WP-0048-T19 +status: done +priority: high +state_hub_task_id: "f50fdcd1-00be-5c3c-be0c-345aa2126032" +``` + +Completed 2026-10-16, independently reviewed source implementation and synthetic +fixture proof only. The registration adapter now opens a bounded regular checker +artifact without following its terminal symlink, verifies the reviewed digest, +and snapshots the exact bytes into a write/grow/shrink/seal-removal-sealed Linux +memfd before helper access. Live and proposed config checks execute that same fd +through procfs with the existing empty environment; the fd closes on completion +or failure. Unsupported snapshot/seal/exec policy refuses through the existing +parent-session revocation and uncertainty boundaries. The earlier unbounded +pre-snapshot path read was removed during independent review; actual adapter +symlink/FIFO/oversize refusal tests verify helper access never starts. + +Evidence: Custodian `docs/changes/netkingdom-target-2026-10-16/browser-resume-r1/`, +including exact base/preimages/postimages/patch, proposed descriptor, coordinator +source review and canonical integration receipt. Independent Custodian checks +passed 49 affected source tests and 12 actual Go checker/helper/kernel scenarios; +the sets overlap and are not separate acceptance counts. Existing published +Warden d97652a producer pins remain unchanged. The exact KeyCape artifact remains +`sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5`. +The predecessor path-replacement refusal and the first expanded reopened-fd test +failure are retained; the latter fixture was corrected to restore write mode +before independently proving seals block reopened-fd writes and shared mmap. + +This source task adds no native owner custody, callback, evidence trust, type +acknowledgment, credential access, consumer sign-in or rollback acceptance. +Executable memfds, Linux seals and usable procfs are explicit runtime dependencies +and still require native admission. This is an extracted source outcome from +T16, not completion of T16; T12/T14/T15 and all external-owner gates remain open. + + +Publication verified by the coordinator after the source worker usage limit: +`8790dd18ae83c4651ef3d1d923312a118a5b436b` is the actual remote main revision. +All five canonical source hashes match the reviewed packet. Normal synchronization +completed with zero failures/automation errors; all 19 task statuses match the +projection. T19's assigned UUID is retained. The original staged and working brief +bytes were restored and independently compared. The exact source, projection and +publication checks are in Custodian browser-resume-r1/canonical-integration.json. +Native acceptance remains open under T16 and the other named owner tasks. + + +## T20 — Prepare durable group provenance and prove disposable LLDAP compatibility + +```task +id: NK-WP-0048-T20 +status: done +priority: high +state_hub_task_id: "863fcbdb-e246-51ba-87ca-a2f44d01d6f8" +``` + +Completed 2026-10-17, source candidate preparation and bounded synthetic +compatibility proof only. This extracts evidenced implementation/fixture scope +from T14; T14 retains native storage, writer isolation, protected callback and +owner-acceptance gates. Source integration/publication and State Hub projection +are pending the coordinator's separate receipts; no revision or task UUID is +invented here. + +The existing identity-provisioner group ensure/revoke interface now has a +reviewed candidate for a bounded owner-private SQLite journal, proven only in +local/disposable use. The initial storage instructions wrongly suggested a native +persistent-volume path; source review against accepted ADR-0015 corrected them +before publication. Production SQLite-on-a-PVC is not admitted: T14 retains +CNPG/rapp-postgres storage admission or a separately governed exception. +The local journal saves +complete prestate and intent before each attempted directory mutation, inventories +only confirmed new groups/memberships, binds original ensure idempotency and +correlation to the exact request digest, and refuses unsigned caller inventories +or legacy broad revoke requests. Replays never recreate removed state. Missing, +replaced or untrusted storage and missing intent rows stop execution; definite +before-mutation refusals retain evidence without stranding unrelated valid work. +Interrupted writes/readback remain unresolved across reopening. Revoke validates +all targeted native ids and complete member postimages before destructive work, +removes only confirmed creations and never deletes a preexisting empty group. +Server/configuration wiring, image-copy closure and owner storage/request +migration instructions are included. The existing endpoint's caller +authentication remains the existing boundary, not a new grant. + +The candidate was prepared against NetKingdom +`878abc93588e12b6da1bac055cfbb3abb8d7adf1`; exact source patch digest +`sha256:1f3f3ca94c46dadac8f24896053d4d23179de795e50a24298a0cfbcc46cca30e`. +The independent Custodian review passed all 65 provisioner checks. The earlier +62-check candidate, two independent-review findings and subsequent fixes remain +retained rather than overwritten. Seven additional fixture-plan checks exercise +the preparation boundary; these counts overlap the same candidate and do not +measure task-completion percentage or independent acceptance. + +A separately reviewed bounded fixture then exercised the exact candidate against +cached pinned disposable LLDAP and Python images, through actual GraphQL. All 14 +closed compatibility/containment oracles passed: exact creation inventory, +separate-process SQLite reopening/replay/revoke, complete preexisting directory +preservation including empty/shared groups and memberships, refusal of shared +membership drift, retained uncertainty after a lost response following a real +addition, and refusal of unknown/cross-case receipt bindings. The fixture used +only newly generated synthetic users/passwords/key material in private tmpfs, +with a network-none anchor and shared loopback helper, no host ports/mounts, +no image pulls and no production or actual credential contact. The coordinator's +safe receipt reports both exact owned containers absent after cleanup; final +independent cleanup verification remains the coordinator's integration duty. + +Evidence: Custodian +`docs/changes/netkingdom-target-2026-10-16/group-provenance-r1/`, including exact +source base/pre/postimages, patch/manifest, independent review and retained +refinements. Native fixture manifest +`sha256:8a0514f5f14137355972400cd4852f48c892316d28e3abd3c86635d7cb81eef2`; +retained safe result `native-fixture/execution-result.json` (original +`/tmp/nk48-groups-native-review-5pywb19z/result.json`). The source task supplies +no native owner assent, production rollout, protected session/evidence callbacks, +ordinary type admission or consumer login proof. LLDAP has no conditional +membership mutation or generation token here: exact readback cannot exclude +ABA or a concurrent external writer, so T14 remains open. + +2026-10-17 verified source follow-through: source commit `4f65e41` passed normal +local scanning and all 65 canonical provisioner tests. The actual disposable +LLDAP receipt passed all 14 oracles; independent verification on the pinned +daemon found both exact names and the run label absent. Source integration +includes the ADR-0015 documentation correction; the journal remains local-only. + +T14 source preparation is underway. Twenty-three pinned public sources identify +NetKingdom implementation/reconciliation, Platform custody/database governance +and rapp-postgres consumer provisioning; the inspected runtime binding does not +assign identity-provisioner a package. The existing User Engine runtime token +and pod route are not a protected-case caller lane. The native proposal preserves +the same journal seam on a dedicated CNPG consumer and requires authoritative +scope binding, admitted role/lease/placement/recovery and all LDAP writers fenced. +The declared exclusive maintenance window is not mechanical exclusion of WebUI, +helper or lifecycle writers. Capacity placement and EUR cost/risk remain owner +decisions. No package, database, credential, rollout or owner assent was created. +Custodian evidence: group-provenance-r1/native-storage-proposal-r1; final source, +projection and cleanup review: resume-integration-r1/publication-verification.json. + + +## T21 — Implement the PostgreSQL journal and prove disposable SQL compatibility + +```task +id: NK-WP-0048-T21 +status: done +depends_on: [NK-WP-0048-T20] +priority: high +state_hub_task_id: "afe78e4d-408a-516a-ab92-e212e8a2d11d" +``` + +Completed 2026-10-17: bounded source preparation and actual disposable PostgreSQL +compatibility only. T14 retains native storage, custody, callbacks, authorization, +all-writer isolation and production admission. Coordinator source publication and +projection remain separate follow-through; no source revision or task UUID is +invented here. T20 remains the historical local SQLite/actual LLDAP proof. + +The eight-path source candidate adds an injection-only PostgreSQL implementation +behind the existing owner journal seam, with explicit trusted tenant/directory/ +case/source/principal/epoch binding and independent continuity callbacks. It +persists bounded intent/created-only receipts, exact-one version updates, durable +active fences, and a content-bound journal chain. SQL commits precede independent +exact-marker acknowledgment; lost replies/checkpoints poison continuation and +retain uncertainty. A counter-only checkpoint is explicitly insufficient for +divergent clones. Migration does not create database/schema/credential, admit an +epoch or clear quarantine; production HTTP activation is absent pending trusted +callbacks. Pinned psycopg package/image-copy closure is included, without claiming +an image build or native dependency admission. + +Candidate base `6cb43c0cc55212363a5406b02db046e2384a7c40`; final eight-path patch +`sha256:5549d2982b61ff70aba4b3928fecd5639db0f1a732ab2f8630f678e7acf4d34d`. +All 82 source tests pass, alongside 13 fixture plan/diagnostic checks and two +source-backed snapshot regressions. Counts overlap the same source and fixture; +they are not additive native acceptance or completion percentages. + +The independently reviewed R5 fixture ran the actual SQL migration/backend and +existing provisioner path against cached pinned disposable PostgreSQL. Directory +operations deliberately used the existing synthetic LLDAP test double. All +manifest-declared phase oracles passed: creation-only inventory and DDL refusal; +separate-process replay/revoke with complete preexisting/shared visible-state +preservation; foreign-context refusal; concurrent exactly-once reservation and +stale version refusal; actual database fork with divergent bodies at the same +counter and fresh-object rejection of the losing exact checkpoint; retained +uncertainty after checkpoint/directory/SQL response loss; and actual pg_dump/ +pg_restore rollback refusal against the independently retained fixture checkpoint. +The checkpoint is fixture-only, not an admitted native owner evidence holder. + +Only generated credentials/state were used, with two nonroot/read-only containers +on private loopback, bounded tmpfs/CPU/memory/PIDs/lifetimes, no host ports/mounts, +no pulls and no production contact. The safe receipt reports both exact owned +containers absent, with no daemon uncertainty. Independent final pinned-daemon +cleanup verification remains coordinator follow-through. + +Failed R2/R3/R4 receipts and source revisions remain retained. R2's helper failure +subphase is unknown; R3 exposed a real backend bug where replacing nested receipt +objects lost the created ID held by ensure, fixed by acknowledging only the backend +version after commit/checkpoint. R4 verified that fix through actual SQL bootstrap, +then exposed fixture snapshot aliasing and empty deleted-group backing entries; +source-backed regressions corrected the snapshot without weakening complete +visible-prestate equality, and reject nonempty orphan membership. These refinements +belong to one trial, not extra native acceptance successes. + +Custodian evidence: `docs/changes/netkingdom-target-2026-10-16/group-postgres-r1/`; +exact source/pre/postimages and retained predecessors; native R5 manifest +`sha256:d51f90816616848b93bcdc482e10a98d07061deb01eeed9e50700fc6e68b6051`; +`final-integration-r1/typed-execution-evidence.json` and byte-exact safe receipt +(original `/tmp/nk48-postgres-native-review-sguj7t8p/result.json`). No CNPG native +storage/HA/backup/lease/TLS/capacity/restore admission, authoritative protected +callbacks, real LDAP writer fencing/CAS/ABA exclusion, owner assent or production +endpoint activation is claimed. Those remain live T14 work. + + +## T22 — Establish registration recovery source gaps and complete descriptor review inventory + +```task +id: NK-WP-0048-T22 +status: done +priority: high +state_hub_task_id: "ea50d93b-0d04-55d2-98c4-9b6c3fe925b1" +``` + +Completed 2026-10-17: source-only owner-contract review and complete review +inventory. Inspected the actual registration adapter, Warden Journal/Executor, +NetKingdom evidence compatibility checker and Audit Core custody/read surfaces. +No existing admitted holder/readback supplies authenticated original-attempt +recovery: payload/creation are process-local, persisted evidence references are +hashed, and reconcile receives a new attempt without original context. The exact +four-owner contract requirements and non-replayable missing/ambiguous cases are +recorded; no recovery callback, publisher, credential grant or native trust root +was installed. T15 retains implementation and actual acceptance. + +The complete source1.2 inventory maps all seven follow-through steps to their +existing owners, missing exact contracts and created-only rollback requirements. +The actual maintained adapter regenerated the sole existing register-client +machine descriptor against the delivered 13,633,409-byte checker and current +sealed-memfd snapshot source. The checker rehash and Warden Descriptor.decode +round-trip passed; six owner descriptors remain absent. Actual source commands +render canonical1.1 and explicitly selected1.2 with execution.permitted false; +ordinary1.2 case admission still refuses its acknowledged/unimplemented type. +Canonical type/case/acknowledgment bytes were hash-checked unchanged. No tests were +added or rerun, no native configuration or effect occurred, and no owner assent +or complete machine bundle is claimed. T16 retains native executable custody, +complete exact descriptors, independent source review and normal version/type +admission. This extracted outcome supplies no native gate completion credit. + +Evidence in the-custodian: +`docs/changes/netkingdom-target-2026-10-17/native-registration-r1/`, especially +original-attempt-review.json, descriptor-composition.json, source-verification.json, +source-manifest.json and manifest.json. The prior sixteen-gate audit remains +immutable. Publication, normal task UUID allocation and projection are separate +coordinator follow-through; no Hub UUID is assigned by this source record. + + +## T23 — Review native journal package assignment and storage integration boundaries + +```task +id: NK-WP-0048-T23 +status: done +priority: high +state_hub_task_id: "6e7cd483-c7af-53a2-9d0a-3d76b6fb49ee" +``` + +Completed 2026-10-17: source/package placement and protected integration review +only, separate from T21's completed PostgreSQL source and disposable-SQL proof. +The owner review recommends a dedicated independently rolled-back +`rapp-identity-provisioner`, owned by NetKingdom on rail-kubernetes, with a +schema-valid draft declaration and no reef binding. No repository, registry +entry, native package assignment or owner assent was created. Existing +rapp-user-engine ownership/token delivery does not assign it the provisioner. + +The complete current rapp-postgres catalog has six declared consumers: four on +platform-pg and two on platform-pg-2. The inert renderer-valid provisioner +candidate fits platform-pg-2 at three of four, requesting one migration plus +four runtime connections; placing it on the first cell is refused as a fifth. +Normative package schema and full-catalog capacity/render checks passed. The +four-consumer ceiling is estimated, not measured native headroom, and no current +SQL session, backup or restore acceptance is claimed. + +The exact review identifies remaining package/substrate, SQL role/lease/TLS, +network and backup/recovery contracts; independently authenticated protected +scope callbacks; an external content-bound checkpoint holder with atomic +advance/loss handling; and all-LDAP-writer exclusion or provider CAS/generation, +including lifecycle cascades and remove/readd ABA. Generic Audit custody is not +that checkpoint service. A database-only fence, final reread or one replica +cannot exclude foreign directory writers. The native acceptance/recovery matrix +keeps storage/lease admission separate from separately approved directory +mutation; the production activation remains disabled pending trusted integration. + +Evidence in the-custodian: +`docs/changes/netkingdom-target-2026-10-17/native-storage-r1/OWNER-REVIEW.md`, +source-validation.json and hash-bound source-references.json, plus the inert +proposed declaration/consumer and renderer outputs. No native resource, lease, +credential, deployment, destructive effect, independent holder or native owner +acceptance was delivered. T14 retains these live gates with its original UUID +and progress status. This completed review adds no duplicate T21 acceptance +credit; publication, task UUID allocation and projection remain coordinator +follow-through and no UUID is hand-assigned here. + +## T24 — Ensure-groups adapter source candidate + +```task +id: NK-WP-0048-T24 +status: done +priority: high +state_hub_task_id: "1a3931ee-3b5f-52fc-9295-4073804f4bd2" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): ensure-groups-adapter.py, 8 tests (commit 5a2e7d6). Binds to the T14 PostgreSQL journal and refuses SQLite or a foreign binding. It accepts only canonical 1.1 cases, so T30 must add an explicit 1.2 path. It calls the provisioner's private `_group_binding`; a public helper is the cleaner shared edit. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Bind group creation to T14's journal/provenance seam; refuse without trusted journal callbacks. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. NetKingdom (directory) owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T25 — Mint-secret adapter source candidate + +```task +id: NK-WP-0048-T25 +status: done +priority: high +state_hub_task_id: "0de2a7d9-874d-578b-a076-f653fe42e30b" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): mint-secret-adapter.py, 9 tests (commit 558c5bc). Value-free receipts only. The receipt schema `railiance-platform.custody-mint.v1` and the mint/destroy capability interface are proposals that Platform must confirm. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Platform-owned custody evidence seam: the adapter records value-free mint evidence only and never handles secret values. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. Platform owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T26 — Deliver-secret adapter source candidate + +```task +id: NK-WP-0048-T26 +status: done +priority: high +state_hub_task_id: "94b3cbf0-c908-5ac6-b0db-67385c3e021c" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): deliver-secret-adapter.py, 8 tests (commit 1b60f6e). The lane `platform-secret-delivery` and the schema `netkingdom.deliver-secret.v1` are proposals that Platform must confirm. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Platform-owned delivery evidence seam (ESO/custody), value-free. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. Platform owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T27 — Bind-env adapter source candidate + +```task +id: NK-WP-0048-T27 +status: done +priority: high +state_hub_task_id: "e56365f8-29b5-5c89-a329-8115f9f3b2a7" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): bind-env-adapter.py, 5 tests (commit 6fbce73). Binds references only. To fit the budget it does not yet wrap a full Warden `Adapter` like T13 (source-digest pin, authenticated evidence, parent-session revocation); it returns `(reference, run, rollback)`. That wrapping is a prerequisite for T30. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Bind the issuer Deployment env reference to the delivered secret reference, without values. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. NetKingdom runtime owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T28 — Deliver-consumer-secret adapter source candidate + +```task +id: NK-WP-0048-T28 +status: done +priority: high +state_hub_task_id: "6dab281c-ea9a-5a17-a83f-e8e9a4d4484f" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): deliver-consumer-secret-adapter.py, 5 tests (commit 650c1ac). Type 1.2 only. It assumes the owner has validated ESO TokenRequest and the controller-RBAC admission; that stays an owner gate. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Consumer-side delivery evidence seam, value-free. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. Platform and Apps owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T29 — Hand-over adapter source candidate + +```task +id: NK-WP-0048-T29 +status: done +priority: high +state_hub_task_id: "129db41d-4560-5e20-9f3b-c3c91e0a5601" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): handover-adapter.py, 8 tests (commit ec63539). The owner `apps` and lane `apps-consumer-handover` are proposals that the Apps owner must confirm. It has no reconcile path; restart handling follows T15. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Apps-owned consumer verification and hand-over receipt seam. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. Apps owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T30 — Compose the descriptor set over the reviewed candidates + +```task +id: NK-WP-0048-T30 +status: done +depends_on: [NK-WP-0048-T24, NK-WP-0048-T25, NK-WP-0048-T26, NK-WP-0048-T27, NK-WP-0048-T28, NK-WP-0048-T29] +priority: high +state_hub_task_id: "6f6073ac-52dd-5b70-8874-6d76d4c072e4" +``` + +2026-10-17 done: coordinator review r3 (the-custodian `nk48-adapters-1.2-review/coordinator-review-r3.json`, +fd07eaa) approved all nine files at ff8f597, with R2-F1..F3 resolved, an independent +reconstruction of 117 passing and no open findings. This is a source review only: +it grants no owner admission, pin or native authority. Owner review and admission +continue under T16, which also takes the r2 observations, including the +`warden_executes: false` steps that carry execution descriptors. + +2026-10-17 coordinator review r2 (the-custodian `nk48-adapters-1.2-review/coordinator-review-r2.json`) +approved five files and rejected three, plus the artifact. The fixes are merged in +2ee4ed0: R2-F1, mint-secret revokes the session and the broker grant +independently (eeed8e1); R2-F2, deliver-secret binds to the admitted case and +derives its Secret and custody path, with no caller reference (640292c); R2-F3, +bind-env pins its five-file closure, and a new closure-completeness test checks +every adapter (d16db30). Each regression test failed on 68f4bbb. The artifact is +regenerated, and the full suite including kernel admission passed 117. Next is +the r3 review. Open for owner review under T16: the type marks four steps +`warden_executes: false`, yet each has an execution descriptor. + +2026-10-17 founder confirmed every proposed lane and schema name for T25-T29 +as-is. The artifact records them as `names_confirmed` (by founder, 2026-10-17), +and no step is still `owner_confirmation_required`. Next: independent source +review of the seven adapters. + +2026-10-17 founder decision (supersedes the `agent` decision below): the +mint-secret actor is `human`. Coordinator review r1 (the-custodian +`docs/changes/netkingdom-target-2026-10-17/nk48-adapters-1.2-review/coordinator-review-r1.json`, +finding NK48-R1-F1) showed that unchanged kernel a45cf47 refuses every +`effect: mint` admission whose actor is not `human` ("agent mint is +forbidden"), so the `agent` descriptor could never be admitted. Adapter, tests +and composer comment updated and the artifact regenerated (mint-secret +descriptor digest now `sha256:8c40c2884f8ba15e8cb6c98f33419c395e54fce8ef33d6e1a34782cf3f1fcfa9`); +98 tests pass against a45cf47. The set needs an independent r2 review. + +2026-10-17 `test_admit_1_2_adapter_descriptors.py` runs Warden's own +`Executor.admit` on all seven composed 1.2 descriptors, with the real 1.2 +type, the 1.2 forgejo example case, the reviewed `BrowserInputs` validator and +fixture-only trust (stand-in adapters, nothing dispatched). It also pins that +an agent mint descriptor is refused ("agent mint is forbidden") and that a +wrong lane is refused for every step. Against the old `agent` revision +(582ab9f) it fails as expected. Combined suite: 102 passed on ops-warden a45cf47 +and on current ops-warden. Fixture admission is not owner admission or a pin. + +2026-10-17 founder decision: the mint-secret actor is `agent`, not `warden`. +The kernel is unchanged. The adapter, its test and the composer were updated and +the artifact regenerated; all seven steps pass `Descriptor.decode` and +`complete_executable_descriptor_set` is true (98 tests passed). The artifact +stays `not_an_admission`, with no owner review, admission or dispatch permission. + +2026-10-17 composer merged (60b41a1 via 3c62bec) with follow-up 376b44b (merged; +combined suite 98 passed). `compose-1.2-descriptors.py` loads 1.2 only through an +explicit version root and refuses partial, duplicate, unknown or mismatched maps. +`descriptor-composition-1.2.candidate.json` is a reviewable candidate, marked +`not_an_admission`, with canonical 1.1 unchanged. ensure-groups and hand-over now +carry and honour `parent-session` revocation, and the hand-over owner is +parameterised (`railiance-apps` for Forgejo). Six of the seven steps pass +`Descriptor.decode`. mint-secret is still refused: its actor `warden` is outside +the kernel's human/agent set, and Platform (with ops-warden, if the kernel should +change) must decide. Five steps carry `owner_confirmation_required` names. The +set is complete only after both. Owner review, the canon section 6 successor +revision and admission remain T16's. + +2026-10-17 prerequisites merged (65559ef; combined suite 78 passed): +ensure-groups accepts 1.2 via an explicit `version_root='1.2'` (531151b), with +1.1 still the default. bind-env is now a full Warden v1 `Adapter` (7442d21); its +kernel-level fixture tests like T13's are still missing, and its `build()` +signature changed. Composition is unblocked in source. Owner confirmation of +the proposed step, lane and schema names remains before pinning. + +2026-10-17 inputs from T24–T29 that composition must resolve: T24 accepts +only 1.1 while T28 accepts only 1.2, so add an explicit 1.2 ensure-groups path; +T27 still needs full Warden `Adapter` wrapping; the lane, schema and owner names +proposed in T25, T26 and T29 need owner confirmation before pinning. + +Split from T16 on 2026-10-17. Compose the seven-step source 1.2 descriptor set +through the existing explicit version-root selection over T13 and T24–T29. No +partial descriptor map, canonical 1.1 stays the default, and new descriptor bytes +need a reviewed successor revision under canon section 6. Owner review and +admission remain T16's. + +## T31 — Restart and lost-receipt fixtures against Warden's original-intent interface + +```task +id: NK-WP-0048-T31 +status: done +priority: high +state_hub_task_id: "ed1ccd87-89a0-5e69-885c-0eaf5ab0bb5a" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): test_registration_original_intent_reconcile.py, 8 tests (commit 74adcd7), runs against the unmodified ops-warden a45cf47. The holder is a test-only in-memory store. For real T15 support the T13 adapter's `build()` needs an injected holder/readback capability, a `reconcile_original` callback, and a `verify` that accepts reconcile results. Rollback after restart stays refused until there is an owner contract. + +Split from T15 on 2026-10-17. ops-warden published the original-intent +lookup/context interface in `src/warden/case_run.py` (`OriginalIntent`, +`Journal.original_intent`, `Adapter.reconcile_original`; commit `a45cf47`). +Build T15's restart/lost-receipt fixtures for the registration adapter against +it: the original intent is kept separate from the reconcile attempt; wrong +attempt/case/source/principal and unavailable-holder cases refuse; and a missing +or ambiguous record stays uncertain, with no add replay or undo. The interface +is Warden's own dispatch record, not owner-authenticated created-only provenance. +Selecting the actual authenticated holder stays a T15 owner gate. + + +## T32 — Restore independent agent-mint admission regression coverage + +```task +id: NK-WP-0048-T32 +status: done +priority: high +state_hub_task_id: "c6d0a27e-f6a7-5df0-95f6-3e7473d38bb5" +``` + +Completed 2026-10-17, source tests only. Extracted from T16's coordinator r5 +finding NK48-R5-F1; no earlier adapter outcome is counted again. The real 1.3 +admission test now separately checks the committed descriptor map, an in-memory +fixture map acknowledging the changed agent descriptor to reach the independent +mint prohibition, and the human descriptor under an explicit fixture agent +runtime marker. Only `sso-mfa/k8s/keycape/test_admit_1_3_type.py` changes. + +Against frozen Warden `117fec9241e7b985dfb187b992e173d0a5dc3700`, the new +suite passes 10 tests / 32 subtests. Independent mutation evidence removes only +the mint admission guard in scratch: both new guard tests fail while eight +controls pass; the old suite passed that mutant. Custodian independently reran +the canonical successor: 10 tests / 32 subtests pass. Evidence: +`the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-r5-f1-implementation-r1/` +(patch, frozen/mutant results and canonical-validation.json). No descriptor, +parameter pin, catalog, acknowledgment, kernel or native execution changed. +T16 still owns actual composition and admission; F2/F3 follow below. + +## T33 — Close the issuer-store reference finding with Platform source + +```task +id: NK-WP-0048-T33 +status: todo +priority: high +state_hub_task_id: "5ace28ff-a4cb-5647-a8f6-3cd54bb9d0a5" +``` + +Owner: Platform for the fixed store/template source and its delivery boundary; +NetKingdom for the 1.3 type reference. Split from T16's current coordinator r5 +finding NK48-R5-F2. Next action: independently review the prepared Platform +candidate and publish a concrete owner-controlled issuer store kind/name/scope +and template reference, then integrate only that exact proposed source into the +1.3 deliver-secret entry point and regenerate its composition artifact. Candidate +and current review evidence are under Custodian +`docs/changes/netkingdom-target-2026-10-17/nk48-r5-f2-implementation-r1/` +and `nk48-r5-f2-review-r1/`. + +Completion requires exact committed source, a passing independent source review +and unchanged type parameter bytes. No consumer store may be inferred as issuer +store, and no source declaration supplies owner assent, installed ESO support, +CCR/grant changes or a real delivery capability. Those remain existing +RPF-1.3-T4 and T16 admission/native requirements. + +## T34 — Close the consumer configuration inverse finding + +```task +id: NK-WP-0048-T34 +status: todo +priority: high +state_hub_task_id: "37f43c40-d014-544e-aa0b-5219dd4a6b93" +``` + +Owner: Apps for consumer configuration and inverse; NetKingdom for exact type +placement. Split from T16's coordinator r5 finding NK48-R5-F3. Next action: +independently review and implement the owner transaction/inverse through the +existing RAPPS-WP-0016-T05 path, with authenticated durable before/after release +provenance, exclusive serialization of all release writers and a fresh authorized +attended session for every inverse attempt after the hand-over session is revoked. +The inverse must remain reachable for public clients, confidential NO_CHANGE +secret delivery and verification failure before a hand-over receipt exists. + +Completion requires real owner configuration/inverse source bindings and +independent regressions, then exact reviewed 1.3 entry/rollback text and composed +artifact. A synthetic wrapper with an injected backend alone is insufficient. +Keep hand-over receipt rollback receipt-only and secret deletion created-only; +preexisting or drifted resources must refuse unsafe inverse. Candidate evidence: +Custodian `docs/changes/netkingdom-target-2026-10-17/nk48-r5-f3-implementation-r1/` +and `nk48-r5-f3-review-r1/`. Source review, owner acknowledgment and native proof +remain distinct. T16's final composition/admission and T06's native first case +are not completed by this refinement. + +## T35 — Align source admission fixtures with the authenticated catalog and attended-session API + +```task +id: NK-WP-0048-T35 +status: done +priority: high +``` + +Completed 2026-10-17, source fixture compatibility only. Distinct from T32's +independent agent-mint regression repair: both remaining opaque catalog byte +placeholders now use one well-formed synthetic catalog whose exact bytes are +bound by the fixture evidence verifier. The fixture mirrors the six relevant +Warden lane shapes; four draft statuses are hypothetically active, while both +Apps establishing login references remain unresolved. No real catalog entry, +owner login choice or production parameter pin changes. + +Against the reviewed mode-aware Warden source now integrated at +`ae7bc73b4f4bac22454144959b870d161498e0af`, scratch validation passes 31 tests +and 53 subtests. Five resolvable 1.3 descriptors conditionally admit under +fixture-only acknowledgment and pinning; both Apps attended steps refuse before +execution. Changed catalog bytes refuse, all independent mint-guard tests still +reach their intended guard, and the registration fixture's actual kernel +run/rollback and uncertain-result paths pass with synthetic owner callbacks. +The registration fixture explicitly aligns its in-memory proposed type lane +with its current descriptor; canonical 1.1 is unchanged. + +The same tests against predecessor `117fec9241e7b985dfb187b992e173d0a5dc3700` +pass 31 tests and 51 subtests, with only the two new Apps refusal assertions +failing because that predecessor lacks the attended-session catalog check. +Tests target the reviewed current API; the parser or Apps gate is not weakened +for predecessor compatibility. Evidence and root source review: +`the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-update-r1/` +and `nk48-catalog-fixture-publication-r1/`. Canonical validation/publication +receipts belong in the latter packet when performed. This records source +fixture work, not native T03, owner assent, exact-type acknowledgment, PIN-1, +composition/admission completion under T16 or the native first case under T06. +T33 and T34 retain their existing issuer-store and consumer-inverse work. diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/workplan.preimage.md b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/workplan.preimage.md new file mode 100644 index 00000000..16914fc6 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/workplan.preimage.md @@ -0,0 +1,1609 @@ +--- +id: NK-WP-0048 +type: workplan +title: "Establish SecurityCaseTypes so that known security cases are light" +domain: infotech +repo: net-kingdom +status: active +flavor: implementation +owner: claude-code +topic_slug: netkingdom +created: "2026-10-08" +updated: "2026-10-17" +depends_on: [] +related_repos: + - ops-mason + - ops-warden + - key-cape + - railiance-platform + - informed-decision +state_hub_workstream_id: "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb" +--- + +# NK-WP-0048 - Establish SecurityCaseTypes so that known security cases are light + +## Why + +The founder's direction (2026-10-08): setting up a security integration of a +kind that has been done before should be easy, meaning accept the case, then +ops-mason arranges it and ops-warden follows through. Setting up a new kind +needs ample documentation and tests and an informed-decision, because its shape +is part of the security architecture. + +Today every integration is hand-built: per-client helper scripts, per-lane +custody, founder checklists. The trigger was KEY-WP-0038 (Forgejo as an OIDC +client), whose next step was going to be yet another hand-written rollout +script. + +This plan continues the pattern work of NK-WP-0008 (pattern infospace), +NK-WP-0009 (tutorials) and NK-WP-0030 (scenario composition). It turns patterns +into **SecurityCaseTypes** that ops-mason and ops-warden can execute. Canon: +`canon/standards/security-case-types_v0.1.md` (proposed). + +Companion plans: ops-mason `MASON-WP-0010` (materialization) and ops-warden +`WARDEN-WP-0044` (follow-through). + +## Tasks + +```task +id: NK-WP-0048-T01 +status: done +priority: high +state_hub_task_id: "930ac3e9-20ec-5473-98cd-3fe8fddb730f" +``` + +### T01 — Accept the terminology and the canon + +Founder review of `canon/standards/security-case-types_v0.1.md`, including its +section 10 open questions. On acceptance the canon status goes from `proposed` +to `accepted`. + +2026-10-08: accepted by the founder (in session). Canon status `accepted`; +section 10's open questions are carried forward to the first type (T04, T05). + +```task +id: NK-WP-0048-T02 +status: done +priority: high +state_hub_task_id: "19c25d96-a55c-58f0-9168-3fdbc4955fc2" +``` + +### T02 — Inventory the de-facto types already built by hand + +Read-only. List every security integration built so far and group them by shape. +Known starting points: + +- browser OIDC relying parties on key-cape: informed-decision-approver, + coulomb-social, user-engine portal, openbao-admin, and Forgejo (pending) +- confidential service clients with `client_credentials`: secrets-engine + approval, requester and openbao clients, approval-engine operator +- workload KV read lanes on OpenBao: the railiance-platform credential lane + designs and CCRs, for example `railiance-backup-offsite-lane` +- short-lived SSH certificates through ops-warden (`warden sign`) +- tunnelled operator access (ops-bridge) + +For each: the repositories involved, the hand-built steps, attended human steps, +custody paths, verification evidence, and rollback (if any). Output +`docs/security-case-type-inventory.md`, ranking candidate types by how often the +shape recurs and how much manual work each instance costs today. + +2026-10-08: done, `docs/security-case-type-inventory.md`. 36 of 37 CCRs are +already `request_type: workload-kv-read`, a de-facto type reviewed each time as +if it were new. Browser clients: 5 hand-built plus Forgejo, each with its own +rollout script. Confidential service clients need a registration plus two or +three KV-read CCRs each. A forge read identity is needed in bulk by +ORGREF-WP-0002-T06. Recommendation: oidc-browser-relying-party first (unblocks +the forge), workload-kv-read second (largest payoff), then forge-read-identity. + +```task +id: NK-WP-0048-T03 +status: done +depends_on: [NK-WP-0048-T01] +priority: high +state_hub_task_id: "e487975b-73b1-516c-971d-da4cbbb93063" +``` + +### T03 — Schema, template and validator + +- `canon/schemas/security-case-type_v0.1.schema.json` and + `security-case_v0.1.schema.json` +- `security-case-types/_template/` with `type.yaml`, `README.md` and tests to copy +- a validator, extending `tools/security-scenario-composer/`, that checks a type, + checks a case against its type, and renders the case into the composer's + deterministic plan (still `execution.permitted: false`) + +Acceptance: the validator rejects missing sections, secret-shaped parameter +values, unpinned providers and cases against non-`implemented` types, with tests +for each. + +2026-10-08: done. `canon/schemas/security-case-type_v0.1.schema.json` and +`security-case_v0.1.schema.json`; `tools/security-case-types/security_case_validator.py` +(`validate-type`, `validate-case`, `render`, reusing the scenario composer); +`security-case-types/_template/` (a valid, runnable example type over +`net-kingdom.local-identity`, with README sections, an example case and tests that +travel with every copy). 31 tests pass, including the composer's existing suite. + +```task +id: NK-WP-0048-T04 +status: done +depends_on: [NK-WP-0048-T02, NK-WP-0048-T03] +priority: high +state_hub_task_id: "2fffe112-7d55-5680-9952-78d74f44f87f" +``` + +### T04 — Define the first type: browser OIDC relying party + +`security-case-types/oidc-browser-relying-party/`, version 1.0: + +- parameters: client id, display name, exact redirect URIs, scopes, client type + (confidential or public), MFA pin, the groups the consuming service maps, + custody path for the secret (confidential only), consuming service and its + owner +- composition: key-cape client registration (key-cape declares it as a playbook + capability), secret minting into custody (railiance-platform), LLDAP group + existence and membership (net-kingdom identity-provisioner), handover to the + consuming service +- materialization (ops-mason) and follow-through (ops-warden) sections +- verification: discovery lists the redirect URI; a test sign-in returns the + expected claims for one human; anonymous access to the custody path is denied +- rollback: remove exactly this client and its custody path +- README: threat model, MFA rationale, why redirect URIs are exact, which steps + still need an attended login and how that is minimised +- reference instances: informed-decision-approver, coulomb-social, user-engine + portal, openbao-admin + +Acceptance: complete per canon section 3, tests green, status `proposed`. + +2026-10-08: done. `security-case-types/oidc-browser-relying-party/` 1.0 (proposed): +`type.yaml` with 12 parameters (the custody reference is required only for +confidential clients), composition over key-cape's new +`key-cape.oidc-client-registration` declaration (contract PASS, `maturity: +planned`), materialization and follow-through, verification and rollback, all +conditional on client type where it matters. One attended step, +`register-client`, justified by the live registry being a Kubernetes Secret. +README with threat model, alternatives, an honest fit table (portal and vergabe +fit; Forgejo is the first confidential case; openbao-admin, coulomb.social and +informed-decision-approver do not fit 1.0), and known limits. Examples: Forgejo +(checked against the accepted request) and a public portal. The validator gained +`when` / `required_when` conditions and provider discovery. 43 tests pass. +ops-mason's and ops-warden's sections are drafted in the type. Their owners +review them in MASON-WP-0010-T01 and WARDEN-WP-0044-T01 before acknowledgment +(T05). + +```task +id: NK-WP-0048-T05 +status: done +depends_on: [NK-WP-0048-T04, MASON-WP-0010-T01, WARDEN-WP-0044-T01] +priority: high +state_hub_task_id: "3d987d3d-0797-538b-86e4-51185a327ae2" +``` + +### T05 — Acknowledge the type through informed-decision + +Prepare the Decision Memo from the type's README and `type.yaml` and submit it +through informed-decision's production intake. On acknowledgment the type +moves to `acknowledged`. + +2026-10-08: Decision Memo prepared. Hub decision `e418263e-a71f-4f01-a970-c87c9e187c09`. +`security-case-types/oidc-browser-relying-party/decision/`: `packet.md` (question, +one act, what acknowledging does not do, the shape, alternatives, attended +steps, limits, evidence), `build_intake.py` and the built `intake.json` (memo +class `decision-record`, review group `net-kingdom-admins`, resolves the hub +decision on answer). The envelope passes informed-decision's own +`validate_submission`. Queuing it is an attended operator step, a write inside +the production dispatcher pod: + + kubectl -n state-hub exec -i deploy/state-hub-memo-dispatch -- \ + python -m api.services.memo_dispatch --queue /data/private enqueue --envelope /dev/stdin \ + < security-case-types/oidc-browser-relying-party/decision/intake.json + +The answer then appears for review in informed-decision. + +2026-10-08: queued by the founder (`pending`, `queued`) after one refusal: the +first envelope's idempotency key was not State Hub's stable +`state-hub..` form, and the builder now validates against both +sides. The dispatcher delivered it to informed-decision (ledger 7 → 8 +delivered). T05 waits for the founder's answer in informed-decision, which +resolves hub decision `e418263e`. + +2026-10-08: ops-mason's review (MASON-WP-0010-T01) folded into the type, still +1.0 `proposed`: `secret_ref` is no longer a parameter, the type derives +`platform/workloads/keycape/{client_id}`; policies are +`workload-kv-read-keycape-{client_id}-eso` and +`workload-kv-read-keycape-{client_id}-{consuming_service}`, each with a templated +body (`read` on that one data path); new `openbao_role` +`external-secrets-keycape-{client_id}` (Kubernetes auth, ESO service account, +15m, no default policy); catalog entry `{consuming_service}-keycape-client`; +the two rollback steps on the KV path collapse into one metadata delete. The +schema and validator now require a `body` on policy and role items. 105 tests +pass. Two consequences: the delivered memo describes the type before these +changes (a case-set custody reference, two differently named policies, no ESO +role), so the founder answers on a superseded shape unless the memo is +re-sent; and Forgejo's custody path moves from the accepted request's proposed +`platform/workloads/forgejo/netkingdom-oidc-client` to +`platform/workloads/keycape/forgejo`, which key-cape (KEY-WP-0038) and +railiance-apps (RAPPS-WP-0016-T02) need to adopt in T06. ops-warden's review +(WARDEN-WP-0044-T01) is still in progress. + +2026-10-08: revised memo `nk-wp-0048-t05-oidc-browser-relying-party-r2` built +(`packet.md`, `intake.json`, packet `sha256:af6435e2…`); it states that it +supersedes the first memo and passes informed-decision's and the dispatcher's +validation. It needs a new memo id because the dispatcher refuses new content +under a delivered idempotency key (`idempotency_conflict`). Queuing it is the +same attended step as above. Both memos serve hub decision `e418263e`; the +first answer resolves it, so the first memo must not stay open: an accept on it +would acknowledge the superseded shape, and a decline would resolve the +decision against r2. Close it with `return` (a reviewer verb that requests a +new revision and does not resolve the hub decision; only accept and decline +do), commenting that r2 supersedes it, then answer r2. `withdraw` exists in +the vocabulary but is not offered to reviewers, and lifecycle `revise` only +applies to lifecycle-registered memos, not intake-delivered ones. + +2026-10-09: the founder reports r2 enqueued and the first memo returned. At +close, hub decision `e418263e` still showed `open` (not verified whether r2 +was answered or the answer is still in transit; the dispatcher ledger was not +read). ops-warden's review (WARDEN-WP-0044-T01, ops-warden +`history/2026-10-08-oidc-rp-follow-through-review.md`, d470f2e) arrived at +21:25, before r2 was built, and is not in r2. Required before WARDEN-WP-0044-T02: +R1 a per-step `lane` (missing: identity-provisioner caller credential, +railiance-platform broker grant), R2 canon meaning of `warden_executes: true` +(caller proxy, caller identity, no standing ops-warden token; ADR-0002), R3 a +per-step `value_handling`. Refinements R4 (one type-level catalog lane instead +of a per-case entry, which conflicts with ops-mason's item 5), R5 (ESO Ready gate +before bind-env), R6 (exact accepted memberships), R7 (mfa-pinned and +secret-delivered checks). Next: if r2 was accepted, fold R1-R3 and R5-R7 in as +a follow-up and settle R4 between ops-warden and ops-mason before T06; if not, +hold r2, fold them in and build r3. + key-cape and railiance-apps were told about Forgejo's new custody +path. + +2026-10-09: r2 was not answered (hub decision `e418263e` open; dispatcher 9 +delivered), so r2 is held and r3 replaces it. ops-warden withdrew R4 for R4′ +(message a66a9204): one catalog entry per case with its body templated in the +type. Folded in: + +- Canon section 3: a narrow meaning of `warden_executes: true` (caller proxy, + caller identity, no standing credential; ops-warden ADR-0002), plus per-step + `lane`, `value_handling` and an optional `ready_check`. A catalog entry body is + now required, like policy and role bodies. +- Schema and validator enforce all of these. +- The type: lanes `identity-provisioner-groups` and + `keycape-client-secret-generate` (both new) and `key-cape-oidc-login`; + `mint-secret` is `generated_in_custody`; a Ready gate on `deliver-secret`; + `ensure-groups` adds exactly the accepted case's memberships; new checks + `secret-delivered` and `mfa-pinned`; the catalog-entry body follows R4′. +- 110 tests pass. + +Memo r3 (`nk-wp-0048-t05-oidc-browser-relying-party-r3`, packet +`sha256:726dfc01…`) passes informed-decision's and the dispatcher's validation. +The founder queues it with the same command, returns r2 with a comment that r3 +supersedes it, then answers r3. + +Prerequisites for T06, not for T05: +- the two new lanes, each through its owner; +- a founder-approved rollout of an identity-provisioner image containing + 630ebfd (the deployed one is main-6c4fcaf from 2026-09-24, without + `/v1/groups/ensure`). + +ops-mason's request to create LLDAP group `fluid-telegram-operators` (message +259ec26d) was answered: not possible from here by that path; the founder creates +it in the LLDAP admin UI. + +2026-10-09: ops-warden finished its side of WARDEN-WP-0044-T01 (message +`58d33f40`, commit 0e7ceb8): the revised type conforms to `warden case +check-type`, with no further changes asked of the type. This acknowledges that +review. Its later addendum R8 (message `af274783`, ops-warden +`history/2026-10-08-oidc-rp-follow-through-review.md`) showed that lane +`identity-provisioner-groups` cannot exist as declared: the provisioner's only +HTTP credential is user-engine's runtime token, and its NetworkPolicy admits +only user-engine pods, so a caller-proxy lane would act as user-engine. Taken +option 1 (ops-warden's recommendation): `ensure-groups` and its rollback are +attended, in the `register-client` session on `key-cape-oidc-login`, run inside +the provisioner pod; no token is read. Option 2 (an operator credential of its +own on the provisioner) stays open for a later version. `warden case +check-type` now reports only `keycape-client-secret-generate` +(railiance-platform) as missing. 89 tests pass. + +Hub decision `e418263e` was still open, so memo r4 +(`nk-wp-0048-t05-oidc-browser-relying-party-r4`, packet `sha256:452ea421…`) +replaces r3; it passes informed-decision's and the dispatcher's validation. The +founder queues it with the same command, returns r2/r3 if still open with a +comment that r4 supersedes them, then answers r4. + +Prerequisites for T06 are now: lane `keycape-client-secret-generate` +(railiance-platform), and a founder-approved rollout of an identity-provisioner +image containing 630ebfd. + +2026-10-09: done. The founder queued r4 (`pending`, `queued`), returned r3 as +superseded and accepted r4 in informed-decision. informed-decision's hub +write-back is off in production (`INFD_HUB_WRITEBACK` unset), so net-kingdom +resolved hub decision `e418263e` from the founder's report, naming memo r4 in +the rationale. The type is `acknowledged`; it becomes `implemented` with T06. + +```task +id: NK-WP-0048-T06 +status: wait +depends_on: [NK-WP-0048-T05, NK-WP-0048-T08, NK-WP-0048-T09, NK-WP-0048-T12, NK-WP-0048-T13, NK-WP-0048-T14, NK-WP-0048-T15, NK-WP-0048-T16, NK-WP-0048-T17, NK-WP-0048-T18, NK-WP-0048-T20, MASON-WP-0010-T03, WARDEN-WP-0044-T03] +blocking_reason: "Type1.2 architecture has a confirmed source-only founder acknowledgment; canonical1.1 remains unchanged/default and the1.2 reference case stays proposed. Needs explicit version selection/reference-source integration without normal admission bypass, closed owner adapters plus global/native receipt verifier (WARDEN-WP-0044-T03), independently verified six-object structural materialization and CCR42 claims/created-only provenance, exact broker/case/source reconciliation, then separately authorized native mint/delivery and attended registry/consumer verification. Source acknowledgment, a bundle or local tests do not prove implemented/materialized/live status." +priority: high +state_hub_task_id: "d9b26bcf-a7c6-59a2-92a0-f913d76a203c" +``` + +### T06 — First KnownSecurityCase: Forgejo + +Write `security-cases/forgejo-netkingdom-oidc.yaml` from the parameters the +founder accepted in KEY-WP-0038-T01 (`key-cape/docs/forgejo-oidc-client-request.yaml`), +so that acceptance carries over as the case acceptance. ops-mason materializes it; +ops-warden follows through and verifies it. The type becomes `implemented` once +this reference case is live. + +This replaces the hand-built path proposed for KEY-WP-0038-T02. + +2026-10-09: case written, `security-cases/forgejo-netkingdom-oidc.yaml`, status +`accepted`: the example's parameters plus the founder's 2026-10-08 acceptance of +the key-cape request (owner and founder), with the custody-path derivation +covered by the type's acknowledgment (memo r4). It validates and renders (plan +`execution.permitted: false`; three attended steps on `key-cape-oidc-login`); +it needs `--allow-unimplemented` until it is live, since it is the case that +makes the type `implemented`. A test keeps it equal to the type's example. +Still open before it runs: ops-mason renders and builds it (MASON-WP-0010-T02, +T03, unblocked by T05), ops-warden plans and runs it (WARDEN-WP-0044-T02, T03), +railiance-platform's `keycape-client-secret-generate` lane (asked by ops-mason +`789feb39` and ops-warden `d9f889b1`, both unread), and a founder-approved +identity-provisioner rollout containing 630ebfd. + +2026-10-09: identity-provisioner rolled out, founder-approved in session: +`main-630ebfd` (`sha256:bafb4860…`, built by the image workflow) replaces +`main-6c4fcaf` (`sha256:ffacd5d7…`; only change: 630ebfd, additive). Applied +with `kubectl set image` on the Deployment only (generation 17 → 18, 1/1 Ready); +the file's Service, NetworkPolicies and Ingress were not reapplied. Verified in +the pod: `ensure_service_groups` and `revoke_service_groups` present, `/readyz` +200; no token used, no group changed. Rollback: `kubectl -n sso set image +deploy/identity-provisioner provisioner=forgejo.coulomb.social/coulomb/identity-provisioner@sha256:ffacd5d790a5b7800e0535f3aa95b7de52c7a68e4f575b9192c3e1622fa672c2`. +The pin in `sso-mfa/k8s/identity-provisioner/deployment.yaml` follows. + +2026-10-09: ops-warden closed WARDEN-WP-0044-T01 and shipped `warden case plan` +(T02, message `06303d1d`); the accepted Forgejo case is refused until ops-mason +materializes it, and a materialized copy plans cleanly once +`keycape-client-secret-generate` exists. Its observation that `bind-env` carries +a literal `KEYCAPE__CLIENT_SECRET`: the validator now renders a +`{param:env}` format spec (upper case, `-` as `_`, as `keycape-client.py` +derives the name) and rejects unknown specs, and follow-through and rollback +text is now checked for unknown placeholders too (patch-level, canon section 6). +The type keeps the literal until ops-warden's planner (`text.format`) renders the +spec as well; asked of ops-warden. 53 tests pass. + +2026-10-10: ops-warden rendered `{param:env}` in `warden case plan` +(23ba584, message `c1df14b7`; other specs and `!conversion` refused). The type +adopts it as a 1.0 patch (canon section 6): `bind-env` and its rollback now read +`KEYCAPE_{client_id:env}_CLIENT_SECRET`. ops-mason reports the Forgejo case +rendered and built (message `1ebddae9`; CCR drafts handed to railiance-platform), +so T06 now waits on the platform apply, the mint-secret lane and the attended +register-client session. + +2026-10-10: key-cape adopted the type's custody path (key-cape ab5cccd, message +`88a4559c`): `docs/forgejo-oidc-client-request.yaml` and KEY-WP-0038-T02 name +`platform/workloads/keycape/forgejo`, field `CLIENT_SECRET`, delivered as +`sso/keycape-forgejo-client` through `external-secrets-keycape-forgejo`, and the +`forgejo/netkingdom-oidc-client` proposal is withdrawn. This matches the type and +the Forgejo example; no change needed here. + +2026-10-10: key-cape's type-composition review (key-cape 6038483, message +`8e5ed5f6`) found the composition sound with two blocking findings, taken as a +1.0 patch (stricter validation and documentation, canon section 6): +R1, redirect URIs now refuse `?` and `#` in the type pattern and in +`keycape-client.py`'s `REDIRECT` (KeyCape refuses `?` at startup and the single +replica would stop); R2, `allowed_scopes` always includes `groups`, the renderer +refuses `access_groups` without it, and `access_groups` now says the consumer +enforces the gate because KeyCape has none; R3, `mfa_required` "false" means the +per-user privacyIDEA policy; R4, register-client's justification records the +restart for every client, the quiet window, and that the rendered registry must +pass KeyCape's client validation before it. The accepted Forgejo case and both +examples still validate; 116 tests pass. +Open, needs a decision: R2's verification step that the consumer enforces the +group gate is a new verification step, hence 1.1 (minor), and the validator pins +cases to the exact type version, so the accepted 1.0 Forgejo case would need +re-pinning. Also open with key-cape: a KeyCape entry point that validates a +rendered client registry without starting the server; until then +`keycape-client.py` mirrors the redirect rule. + +2026-10-10: founder go for 1.1, so no 1.0 run overlaps. The type adds +verification `consumer-enforces-groups`, and hand-over now requires the consumer +to enforce `access_groups` (minor, canon section 6; risk class unchanged, no new +acknowledgment; history in the type README). The accepted Forgejo case and both +examples are re-pinned to `oidc-browser-relying-party@1.1` before any apply; the +acknowledgment intake keeps `@1.0` as the record of what was acknowledged. +ops-mason's build and ops-warden's case-ref digest predate this and need a +re-render. + +2026-10-10: ops-mason re-rendered the Forgejo case from `@1.1` (message +`22c6bba6`; plan digest `af1f4f81…`, no collisions) and rebuilt the bundle. The +rendered OpenBao objects are identical to 1.0, so the already applied +CCR-2026-0041 stands; 1.1 changes only consumer-side steps. key-cape shipped +`keycape check-config` (c528daa, message `a7b0aeff`): KeyCape's startup checks +without secret values, including the new duplicate-clientId rule. +`keycape-client.py --check-config ` now runs it on the live and the +proposed registry, fed on stdin, and apply refuses a proposed registry that +fails; register-client's entry point names the option (1.1 patch). The deployed +image predates c528daa, so the binary is built from key-cape source for now. +Before the next KeyCape rollout (Forgejo register-client or the CCR-2026-0018 +window), the attended operator runs `inspect --check-config` so the live +registry is checked too. + +```task +id: NK-WP-0048-T07 +status: wait +depends_on: [NK-WP-0048-T06] +blocking_reason: "The next types follow once the first one is proven end to end." +priority: medium +state_hub_task_id: "c3c9c3ae-4f23-5ba7-9e6f-e63bcf29b9f7" +``` + +### T07 — Queue the next types + +From the T02 ranking, open the next type drafts (likely the confidential service +client and the workload KV read lane), each to be acknowledged on its own. +Record which existing hand-built instances get adopted as cases, without +rewriting them in place. + +```task +id: NK-WP-0048-T08 +status: done +priority: high +state_hub_task_id: "8e519082-dc8b-5e46-b660-03d03e55dcf6" +``` + +### T08 — identity-provisioner: ensure service-access groups + +The type's `ensure-groups` step calls `identity-provisioner groups ensure --groups + --members `. The provisioner already has idempotent +`_ensure_group` and `_add_group`, but exposes only tenant-scoped operations. Add +the general operation (create if absent, add the listed memberships, never +remove others), its rollback (remove only this case's memberships), tests, and +the ops-warden route for its service identity. + +2026-10-08: done. `identity-provisioner/provisioner.py` gained +`ensure_service_groups` (`POST /v1/groups/ensure`) and `revoke_service_groups` +(`POST /v1/groups/revoke`), behind the existing service-token check. Names +matching `tenant*`, `netkingdom-*` and `lldap_*` are reserved; members must +already exist; everything is validated before any change; memberships are read +back before success; nothing else is ever removed; groups are deleted only when +asked and empty. 7 new tests (39 in the provisioner suite). The type's +`ensure-groups` step and its rollback now name these endpoints. The ops-warden +route for the provisioner's service token belongs to WARDEN-WP-0044-T01. + +```task +id: NK-WP-0048-T09 +status: done +priority: high +state_hub_task_id: "0ee12dfc-8260-5038-bd39-cc7fb4113be0" +``` + +### T09 — The `keycape-client` entry point and its declaration + +Planned first as key-cape KEY-WP-0038-T04. Moved here because the machinery a +live registration needs already lives in net-kingdom, where KeyCape is deployed +(`sso-mfa/k8s/keycape/`): the contained kubectl, the cluster-identity pin and the +issuer pin. A copy in key-cape would drift. + +2026-10-08: done. `sso-mfa/k8s/keycape/keycape-client.py` derives the KeyCape +client record from a case (`client-from-case`). It adds or removes exactly one +client with the existing safeguards (byte-preserving merge, exact match or +refuse, shared-reference refusal, compare-and-swap, read-back, contained errors), +requires the Deployment env binding first for confidential clients, and requires +the case acceptance record for `apply` instead of a per-client founder decision +id. 15 tests, including a regression showing that the vergabe case reproduces +its hand-built registration exactly; all 71 helper tests pass. Declaration +`capabilities/playbooks/net-kingdom.keycape-client-registration.yaml` (contract +PASS, `maturity: implemented`) replaces key-cape's draft. The type now pins it, +and for confidential clients adds `deliver-secret` (delivery from custody into +the sso namespace) and `bind-env` (Deployment env), attended in the same session +as `register-client`. The per-client helpers stay until their clients are +adopted as cases. + +2026-10-10 — NetKingdom owner review of the execution seam, source only: +ops-warden/docs/security-case-execution-proposal.md SHA256 78ab1439e4c5beb205aeccf15b1b2e706511be55ab195c5a3aa682f326c7c77c +was reviewed against INTENT, SecurityCase canon, acknowledged type1.1, current +case and owner source. docs/security-case-execution-owner-review.md supports +the closed adapter/receipt direction with explicit versioned schema, structural +materialization provenance, unchanged caller/session boundaries, safe CAS +reconciliation and exact-created-object rollback requirements. This is owner +review, not approval. Supporting file digests are in the adjacent sources JSON. + +Current source exposes a circular wait: ops-mason T03 waits on mint while Warden +and the broker refuse a non-materialized case. Structural acceptance therefore +needs its own native pinned receipt before mint, not a successful mint before +materialized. The platform broker additionally pins type1.0 while Forgejo is +accepted at1.1; platform-owner alignment and tests are required, not an unchecked +version bypass. T06 remains wait. No case/type lifecycle status, grant, authority +or live runtime changed by this review. A proposed informed-decision would +adopt the source contract only; native materialization and execution acceptance +stay distinct. + +Final proposal re-review: staged Warden proposal SHA256 78ab1439e4c5beb205aeccf15b1b2e706511be55ab195c5a3aa682f326c7c77c +adds only the explicitly local reducer appendix, not an accepted wire protocol +or executor. The exact-final review and sources JSON supersede the earlier +1035f049... proposal review. Platform staged the exact type1.1 broker correction +with ten fake-backend subprocess checks (script SHA256 +9576cd211cfc06526ec4cc9bd0a5b06f0f59287a68931bb2d6e3592a951ddc7d). +The next source work is the versioned closed adapter/receipt/materialization +contract, not another relaxation of the broker's status gate. Native work still +requires installed broker provenance, structural reader receipts, exact new +materialized-case bytes, caller grant/session revocation and verified execution. +No installed/native acceptance is inferred from that staged correction. + +2026-10-11 — new source-only type1.2 architecture acknowledgment: +Confirmed native founder ACCEPT of infd-20261011-forgejo-type12-source-r1@1 +at06:47:39Z, approval8e9332c8-754a-420c-b8b7-445cb4fe6765. Exact frozen packet +0b377d647ca748cd03c92f9792396412048055d4bde9f7bb06ff6d413f7acd68 and submission +585cee731de30d2b37883a57abfd9eb32f023ee694e8d911989109d5caf80569; native receipt +retained in docs/evidence/2026-10-11-forgejo-type12-source-acknowledgment/. +The complete acknowledged1.2 source package is isolated under +security-case-type-revisions/1.2/oidc-browser-relying-party; default loader and +current accepted1.1 case remain untouched because load_type is single-version. +The new proposed1.2 case is NOT accepted/materialized/live and has no acceptance +fields. Actual reference-migration design approval is a separate Apps owner +receipt; no1.1 approval is inherited. Source-recording review/test proof and exact +next gates are in docs/forgejo-type12-source-acknowledgment-followthrough.md. +T06 remains wait and T07 remains its existing dependent task; type is NOT +implemented and no first-case/native grant or broader workplan finish is asserted. + +2026-10-11 — bounded explicit version selection source preparation for T06: +The validator now offers optional exact version_roots/--version-root VERSION=PATH +selection with duplicate/mismatch/traversal/symlink refusal and no fallback. The +default1.1 source and historicalacceptedcase hashes/ordinaryrefusal/preparation +render stayunchanged; actual1.1 is acknowledged, not implemented. Acknowledged1.2 +ordinaryadmission also refuses; optionalpreparation remains nonexecuting.43local +validatorchecks pass and original1.1 CLIrenderbytes match exactly. Makerproof: +docs/evidence/2026-10-11-explicit-type-version-selection/source-integration-validation.json. +FormalNetownerreview/reference-source integration and all existing native adapter, +provenance/broker/materialization/attendedproof gates remain; T06 stayswait, no +new residual or firstcase/typeimplementation/native grant is inferred. + + +2026-10-16 — isolated source preparation for T06 (canonical integration pending): +Added `check-evidence` to the existing validator CLI. It reuses exact version +selection and ordinary type/case/render admission, checks actual Mason structural +request source/inventory/projection pins and reads actual Warden journal rows +read-only. Successful rows require exact type-declared descriptors and attempt/ +revocation fingerprints. Existing acknowledged types without machine descriptors +remain plan-only. The compatibility result never claims authenticated native +completion: Request and journal fingerprints are not portable native evidence. +Owner authentication/status binding and actual native gates remain unresolved; +T06/T07 statuses and both type/case lifecycles remain unchanged. No dispatch, +credential access or authority expansion is introduced. See tool README for the +existing owner protocol boundaries and source integration tests. + +Concrete next Warden owner integration: current `Executor.admit` refuses every +case parameter whose sensitivity is not public/operational, so browser +`redirect_uris`, `allowed_scopes`, `client_type`, `mfa_required` (and 1.2 +`consumer_namespace`) fail after otherwise prepared admission. The sensitive +classification is a security-change review level, not secret content. The +Warden owner must validate through NetKingdom's existing exact-version case/type +validator, then project only descriptor-declared safe target metadata; do not +remove the credential/value refusal or copy complete parameters into journals. +Actual owner descriptor acknowledgment and independent evidence admission remain +prerequisites, with normal admission still refusing unimplemented types. + + +## T10 — Source compatibility checker for Mason and Warden evidence + +```task +id: NK-WP-0048-T10 +status: done +priority: high +state_hub_task_id: "4b06ca97-c1e4-5680-bf22-ab75ab1646a4" +``` + +Completed 2026-10-16 in published source `c31d21ba`. The read-only +`check-evidence` command checks the actual Mason structural request and Warden +journal source protocols against an exact version/render. Independent source +review passed 103 tests at that checkpoint. It always reports native completion +false and execution prohibited. Fixtures and local journal fingerprints do not +provide authenticated owner/native evidence. This records completed source scope +previously described under T06; it does not duplicate native acceptance credit. + +## T11 — Validate the optional machine-descriptor pin contract + +```task +id: NK-WP-0048-T11 +status: done +priority: high +state_hub_task_id: "ef2a0119-f59e-5e45-9519-115da9df7b85" +``` + +Completed 2026-10-16. Reproduced the JSON schema rejecting a valid +`execution_descriptors` map while the Python validator accepted malformed maps. +The schema now supports the existing Warden optional exact-byte pin map; semantic +validation binds keys to declared steps, bounds the map and checks digest shape. +The direct evidence API refuses malformed maps before accessing them. Twenty-one +new checks and all 127 affected source checks passed. No current type/case bytes, +status, owner descriptors or native acceptance changed. Source evidence and +publication receipt: Custodian +`docs/changes/netkingdom-target-2026-10-16/browser-acceptance-next/`. + +## T12 — Prepare NetKingdom-owned attended step adapters + +```task +id: NK-WP-0048-T12 +status: todo +priority: high +state_hub_task_id: "7ce4eee3-cd47-55a9-bfa5-4f1835d4d6fd" +``` + +Owner: NetKingdom. Retained scope: prepare bounded attended Deployment env, +config verification and restart/readiness steps around the existing helpers. +Next action: identify exact current entry points and their revision/readback +contracts, then implement fixed source-pinned callbacks or receipt-only attended +steps. Completion requires positive/refusal checks, exact target/source pins and +uncertainty behavior without acquiring user-engine runtime identity or exposing +registry/client secrets. Existing caller/session, cluster/issuer, CAS/readback +and status-only output boundaries remain mandatory. + +2026-10-16 task refinement: the original broad adapter scope is split into T13 +(completed registration source candidate), T14 (group creation provenance), T15 +(durable registration recovery) and T16 (descriptor/artifact selection and owner +review). This preserves T12's task ID and Hub UUID while giving each remaining +outcome an owner and completion gate. T06 now names every source dependency; +its native/reference lifecycle acceptance scope remains unchanged. Completion +of any source task supplies no Warden, Platform or Apps assent and no native +execution authority. + +## T13 — Prepare the fixed registration adapter source candidate + +```task +id: NK-WP-0048-T13 +status: done +priority: high +state_hub_task_id: "b264c10b-565c-5d29-b788-03cf5fbd2883" +``` + +Completed 2026-10-16, source implementation and synthetic fixture proof only. +Added an injection-only adapter around actual `keycape-client.run`: fixed +case/principal/human/lane/source/acceptance binding, existing CAS/readback, +metadata-only owner evidence and per-attempt parent-session revocation boundary. +The descriptor source composition pins the exact checker executable digest +alongside adapter/helper source. Creation-only rollback authenticates its +creation receipt and refuses changed postcreation UID/resourceVersion; +pre-existing clients confer no rollback authority. Missing readback, evidence, +revocation or process-local creation provenance cannot become retry-safe success. + +Evidence: Custodian `docs/changes/netkingdom-target-2026-10-16/browser-adapter-next/` +R3 candidate, explicit patch and postimages, retained R1 rejected custody finding +and R2 revision, and 36 passing source checks (16 new, 20 existing). Three checks +use actual Warden kernel admission/dispatch/rollback with published Warden +`d97652a3bb5fa733b063d71a1b74068efcccf572` producer pins unchanged. Owner trust, +descriptor/type/case and Kubernetes objects remain synthetic fixtures. This +records a completed source deliverable, not independent review, publication, +type acknowledgment, exercised procedure, identity admission or native browser +acceptance. Independent root source review: Custodian browser-adapter-next/coordinator-review-r3.json. Source integration and normal publication/synchronization receipts: Custodian browser-adapter-next/canonical-integration.json. These receipts supply no other-owner assent or native authority. + +Source publication: `0775c2bfa41af236301155bb5a69bbf088bdf823`, independently +reviewed by the Custodian coordinator before integration. The required initial +projection and ordinary UUID writeback both completed with zero failures and +zero automation errors. Generated-only brief commits were refused by the normal +hook; exact pre-existing staged/working brief bytes were restored. The separate +canonical integration receipt retains those refusals and projection evidence. +Native admission and all other-owner acceptance remain open. + +## T14 — Admit governed group rollback against native owner boundaries + +```task +id: NK-WP-0048-T14 +status: progress +depends_on: [NK-WP-0048-T20, NK-WP-0048-T21] +priority: high +state_hub_task_id: "fce95440-a25b-5f27-8ef3-a3d182099113" +``` + +Owner: NetKingdom. Next action: bind the completed T21 PostgreSQL journal to +an admitted dedicated CNPG consumer through the existing `rapp-postgres` +database-per-consumer contract. Identify the actual deployment/package and +custody owner, admitted placement/capacity and role/renewable lease/TLS target; +implement the independently retained exact content checkpoint and authoritative +tenant/case/source/principal callbacks before enabling governed group operations. +The injection-only backend and fixture callbacks do not supply production scope +or authorization. Existing service tokens, caller-supplied JSON and provenance +receipts confer no new grant. The default production endpoint remains disabled +without the trusted integration. SQLite remains local/disposable only; any +production exception requires explicit scoped governance under ADR-0015. + +2026-10-17 owner-integration refinement: T23 records the completed source/package +placement review, distinct from T21's source/disposable-SQL proof. Its dedicated +`rapp-identity-provisioner` recommendation is draft and unbound, not an accepted +package or existing repository. The full six-consumer rapp-postgres renderer +accepts the inert candidate on platform-pg-2 as its third of four declared +consumers; first-cell placement is refused as a fifth. Neither the estimated +four-consumer ceiling nor source requests establish native headroom or backup. + +Next independent owner contracts: NetKingdom/package/substrate owners accept +exact deployment/rollback fate; rapp-postgres admits the dedicated consumer, +roles, five-connection budget and actual backup/restore; Platform admits exact +renewable runtime/migration delivery and TLS/CA/SAN; network owners scope SQL, +broker and checkpoint paths without assuming a narrow policy subtracts additive +same-namespace access. Protected caller owners must provide authoritative +GroupJournalBinding construction and current authorization; an independent +existing holder must authenticate and atomically advance the exact content +checkpoint, not a counter or ordinary Audit receipt. Directory/runtime owners +must select and prove either an exclusive all-writer maintenance barrier or +provider-supported CAS/generation, including established sessions, lifecycle +cascades and remove/readd ABA. No source review establishes those owner facts. + +The default PostgreSQL activation and destructive native rollback remain refused. +Storage/lease acceptance can be proposed separately from LDAP mutation only after +exact owner source/target/custody/verification/recovery and cost/risk review; +State Hub guard approval grants none of it. Source-only integration review and +native acceptance matrix: Custodian native-storage-r1/OWNER-REVIEW.md. T14's +existing status, UUID, dependencies and native completion gate are retained. + +2026-10-17 refinement: T20 retains the historical durable SQLite source and +actual disposable LLDAP proof. T21 extracts the completed PostgreSQL source and +bounded real disposable SQL compatibility proof. T14 remains `progress` for +native CNPG admission/recovery, protected owner integration and exclusion of all +external LDAP writers. Separate source publication/projection and independent +cleanup receipts belong to coordinator follow-through; no missing native assent +is represented as received. + +Completion still requires independently reviewed/admitted ADR-0015-conforming +CNPG storage (or an explicit governed exception), backup/lost-store recovery and +migration of legacy requests; a native +writer-isolation/fencing or provider CAS/version contract that closes external +writer races and remove/re-add ABA; exact case/source/principal and current +native object bindings for protected callbacks; and actual per-attempt evidence, +revocation and readback/refusal verification through the existing owner paths. +Only independently retained confirmed creations may be undone. Every +pre-existing/shared group and membership must remain preserved; unresolved +intents never expire into retry authority. The disposable fixture supplies none +of these native custody, authorization, owner-acceptance or production claims. + +## T15 — Define authenticated recovery for lost registration process state + +```task +id: NK-WP-0048-T15 +status: wait +depends_on: [NK-WP-0048-T31] +blocking_reason: "Source candidate 061461e is merged. Waiting on the owner to select the real authenticated original-attempt holder and native readback, and on independent re-review of the changed T13 adapter source." +priority: high +state_hub_task_id: "1b825705-4848-5edc-832f-b1622cd9bdb7" +``` + +2026-10-17 source part merged (061461e via 65559ef). `build()` takes optional +paired `holder`/`observe` capabilities and installs `reconcile_original`; the T31 +fixtures now run through the adapter's own path. Rollback after restart is still +refused, and there is no add replay. This changes `keycape-registration-adapter.py`, +so the revision reviewed under Custodian `browser-adapter-next/coordinator-review-r3.json` +is superseded. The new revision has no independent review yet and must not be +pinned on the strength of the old one. + +2026-10-17: T31 fixtures done (74adcd7). What remains for T15: the owner +selects the real authenticated original-attempt holder, and the T13 adapter +gains the holder capability, `reconcile_original` and reconcile-aware `verify` +described in T31. + +Owner: NetKingdom for registration state, with Warden owning kernel evidence +admission. T22 records the completed source review and exact existing-seam gaps; +T15 retains implementation and authenticated restart/lost-receipt acceptance. +Next action: select and admit the actual owner publisher/authenticator and bounded +original-attempt readback contract for the merged holder/observe adapter seam. +Warden's original-intent persistence/interface (`a45cf475`) and additive validation +(`117fec9241e7b985dfb187b992e173d0a5dc3700`) are now published and projected. +The local Journal retains admitted nonsecret original context, validates original +actor/attempt and metadata linkage to the original running receipt, and supplies +it separately from the new reconciliation attempt. This local consistency is not +independent original-holder authorization or creation provenance; neither the +journal nor a current matching registry entry reconstructs creation authority. + +The owner contract must bind the original Invocation, case/type/descriptor/catalog/ +acceptance pins, source, principal and admitted tenant/realm provenance, separately +from the new reconciliation attempt and its independently revoked parent session. +Use an existing authenticated holder/readback; Audit Core's custody API is a +candidate only until its actual registration source/class, load-bearing emission +contract and separate scoped reader are admitted. No new broker or receipt trust +root is proposed. A missing original record, ambiguous publication, NO_CHANGE, +changed native revision or lost readback stays uncertain; no add replay or undo. + +Completion requires restart/lost-receipt fixtures against the selected actual owner +contract: independently authenticated original created-only provenance, original +exact client entry and unchanged current postcreation UID/resourceVersion before +any undo, with wrong attempt/case/source/principal and unavailable-holder refusals. +The merged T13 adapter exposes reconciliation only through paired injected +holder/observe capabilities and still refuses post-restart rollback. Existing +source review, JSON receipts and synthetic trust do not satisfy independent +holder authorization/provenance or native admission, or authorize attended recovery. +Exact remaining owner facts: Custodian native-registration-r1/original-attempt-review.json. + +2026-10-17 check (net-kingdom-worker): Warden's original-intent lookup interface +is not published — ops-warden head is `d97652a`, with no WARDEN-WP-0044-T03 +commit, and the net-kingdom inbox holds no announcement. No restart/lost-receipt +fixture or readback seam was added this session; the work is deferred behind +T16's decomposition under the same token budget. Remains todo, gated on Warden +publishing the reviewed lookup/context interface and on owner selection of the +authenticated original-attempt holder. + +2026-10-17 current-source correction: the earlier same-day `d97652a` lookup +checkpoint and T31 adapter-next-action note above are historical and superseded +by the published Warden interface/validation and merged `061461e` adapter seam. +The 54 focused Warden checks establish source behavior only. Current admission +leaves tenant/realm empty; no admitted tenant/realm provenance is inferred. +T15 remains wait for actual independently authenticated owner-holder/readback +selection, independent review of the changed adapter, and native restart/lost- +receipt acceptance. Existing task metadata, owner gates and historical reviews +are unchanged. + +## T16 — Select and review the actual machine descriptor composition + +```task +id: NK-WP-0048-T16 +status: todo +depends_on: [NK-WP-0048-T24, NK-WP-0048-T25, NK-WP-0048-T26, NK-WP-0048-T27, NK-WP-0048-T28, NK-WP-0048-T29, NK-WP-0048-T30] +priority: high +state_hub_task_id: "200bf500-5084-5ae7-be26-3033fe1f296e" +``` + +2026-10-17 coordinator review r4 approved the 1.3 candidate at 1920b13 with no +findings (the-custodian `nk48-adapters-1.2-review/coordinator-review-r4.json`). The founder chose +option A of the T16 owner-review packet (`nk48-t16-owner-review/founder-option-decision.md`): +1.3 with execution descriptors for all seven steps. Owner reviews for A are open +in the-custodian `docs/changes/netkingdom-target-2026-10-17/nk48-1.3-owner-review/` (net-kingdom, +railiance-platform, railiance-apps, ops-warden, key-cape). The owner-review packet +supersedes the r1 composition pointer: T16's exact composition is now +`sso-mfa/k8s/keycape/descriptor-composition-1.3.candidate.json`. + +2026-10-17 successor candidate prepared (source only, `proposed`): +`security-case-type-revisions/1.3/oidc-browser-relying-party/` is the 1.2 package plus +an `execution_descriptors` map of the seven composed descriptors, with examples +pinned to `@1.3` and no acknowledgment. ensure-groups, hand-over, +deliver-consumer-secret and the composer accept 1.3 (835680c, merged acda26c). +`test_admit_1_3_type.py` runs Warden's real admission against the committed 1.3 type: +the proposed type is refused; an acknowledged copy is refused because ops-warden +pins parameter fingerprints only for 1.1 and 1.2; and with only a 1.3 pin (equal to +1.2's fingerprint) all seven are admitted. This is a major change under canon +section 6. Next: r4 source review of the changed adapters and the map, then owner +reviews, including the ops-warden 1.3 pin, the mint-secret warden_executes/human +question and the owner-run steps question, then the founder's Decision Memo. + +Owner: NetKingdom for descriptor/type source and exact checker artifact; Warden +independently owns global provenance/admission. T22 records the completed seven-step +source1.2 inventory and regenerated register-client descriptor using the delivered +checker and current sealed-snapshot source; T16 retains exact owner review, +complete descriptor composition and admission. Next action: bind actual native +publisher/authenticator, original/current session verification and revocation, +executable storage/custody and config pins, then obtain the six missing fixed +owner descriptors/adapters for ensure-groups, mint-secret, deliver-secret, +bind-env, deliver-consumer-secret and hand-over. The inventory identifies each +existing owner seam, exact missing contract and created-only rollback requirement; +it is not an executable bundle. T14 and T15 remain independent prerequisites. + +Review the dedicated consumer source1.2 composition only through the existing +explicit version-root selection. Keep canonical1.1/default and its accepted case +unchanged, and the source-only acknowledged1.2 reference case proposed without +acceptance fields. New descriptor bytes require a reviewed exact successor +revision/version under canon section6; they do not inherit historical source +acknowledgment. Changed authentication/materialization/trust needs the prescribed +informed-decision acknowledgment. Do not insert a partial descriptor map or use +--allow-unimplemented preparation as ordinary case/native admission. The registry +helper reports restart_required; separately review quiet-window restart/readiness +and actual consumer verification rather than infer activation from registry CAS. +Exact composition: Custodian native-registration-r1/descriptor-composition.json. +Completion requires separate owner source review of exact machine descriptors, +artifact/source/config pins, normal type/version admission and independent +evidence-verification boundaries. Warden d97652a refreshes producer validator +pins for NetKingdom 015694ee; it does not attest T13's new adapter. Pinning any +machine descriptor into an acknowledged type is a separately reviewed source +change. Platform owns structural/mint/broker/delivery evidence; Apps owns actual +consumer login/group enforcement. Neither their assent nor native acceptance is +supplied by this task. + +2026-10-16 source checkpoint: T19 below extracts the completed per-attempt +executable snapshot implementation and reviewed fixture proof. T16 retains +native executable storage/custody, exact owner evidence/session callbacks, +complete descriptor composition and ordinary type/version admission. The +successor descriptor/source pins are proposed only; the earlier descriptor +history is preserved. T14 group provenance and T15 durable restart/recovery +remain independent open requirements. No native acceptance is counted here. + +2026-10-17 budget checkpoint (net-kingdom-worker): no source change made. The +T13 registration adapter alone is 217 source and 317 test lines plus an +independent review; six further owner descriptors/adapters cannot be completed +within one per-task token budget (soft 8000 / hard 10000), so the task was +stopped below 50% and is decomposed rather than pushed through. Proposed split, +one source-candidate task each with positive/refusal fixtures, canonical1.1 +default unchanged and no --allow-unimplemented admission: (a) ensure-groups, +bound to T14's journal/provenance seam; (b) mint-secret and (c) deliver-secret, +Platform-owned evidence seams; (d) bind-env and (e) deliver-consumer-secret; +(f) hand-over, Apps-owned consumer verification; then (g) descriptor composition +over the reviewed set. Each candidate needs its owner's source review before +pinning; none is authored here as owner-accepted. Status stays todo. + +2026-10-17 task refinement after coordinator r5: completed independent mint- +guard regression coverage is extracted as T32. T33 tracks the exact Platform +issuer-store source/reference correction; T34 tracks the Apps configuration +inverse reachable without secret or hand-over resource creation. T16 retains +final exact seven-descriptor composition, independent owner reviews and admission; +its status and existing dependencies are preserved. The kernel branch also needs +its own KR1-F1/F2 admission/dispatch corrections and independent review under +WARDEN-WP-0044-T03 before any 1.3 pin. Historical r4 acceptance does not supersede +r5's findings or establish native readiness. + +## T17 — Build and exercise the exact offline config-checker artifact + +```task +id: NK-WP-0048-T17 +status: done +priority: high +state_hub_task_id: "8c3e4baa-a218-5996-af9e-fe1153a46dac" +``` + +Completed 2026-10-16, isolated artifact/source fixture proof only. Built the +existing `key-cape/src/cmd/keycape` command from published clean source revision +`3c71226a1a7b8a2bdb710e9c497e1a1f7f8a3987`, source tree +`f0010b9cab17dbc3a787628a29657d98b900320f`, with cached Go 1.23.0, +CGO disabled, Linux/amd64 v1, trimmed paths, disabled VCS stamping and offline +read-only module selection. The full retained closure pins 108 source files, +9876 toolchain files and ten used module source directories. Three isolated +build locations produced identical 13633409-byte artifacts: +`sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5`. + +Eight disposable checks use the actual executable and maintained helper/kernel, +with complete synthetic configs and a minimal environment: add/created-only +removal, normal pinned producer admission, rollback, lost-readback uncertainty, +stale revisions, substituted checker refusal, invalid startup config and missing +secret-env refusal. No checker stub or producer-pin override remains. The +artifact-bound descriptor proposal is +`sha256:76b1153d188062ece53fcd5e8d35290fdbfd02a69dd79d4b001fc42781afcdc3`. +Evidence: Custodian +`docs/changes/netkingdom-target-2026-10-16/browser-checker-artifact-next/`. +The first two build attempts succeeded but their closure collection failed; +both failures are retained, as is refusal of the older incomplete synthetic +fixture. No production config, credentials or cluster mutation was used. + +This extracts completed build/fixture scope from T16 without claiming KeyCape +owner endorsement, native checker selection/storage custody, acknowledged type +integration, native evidence/session callbacks or attended browser acceptance. +T16 retains exact owner review and composition/admission scope. The attended +registration procedure remains unexercised. + +## T18 — Make checker input and executable selection deterministic + +```task +id: NK-WP-0048-T18 +status: done +priority: high +state_hub_task_id: "9c45da71-fb4c-5f20-9065-90f448f37c64" +``` + +Completed 2026-10-16, isolated source correction and real-artifact fixture proof +only; independent integration/publication remain separately recorded. KeyCape +source review identified non-secret `KEYCAPE_ACCOUNT_PORTAL_URL` and +`KEYCAPE_BROWSER_LOGOUT_URL` overrides in config.Load. The original helper +inherited ambient environment, allowing valid supplied configuration to be +rejected or invalid supplied URL configuration to be admitted. A bare relative +checker filename could also be replaced by PATH lookup after the adapter had +hashed the selected local file. All three counterexamples are retained against +the unchanged predecessor. + +The existing helper now resolves the selected checker file to an absolute path +and passes an explicit empty subprocess environment. Three opt-in real-checker +regressions verify both URL-verdict directions and relative-file selection under +a non-checker PATH decoy. All 39 affected checks pass with the exact supplied +artifact, as do 11 real-artifact helper/kernel scenarios. Source evidence: +Custodian `docs/changes/netkingdom-target-2026-10-16/browser-checker-environment-r2/`. +Historical descriptors remain retained; the helper correction changes successor +source-composition pins and requires their separate review/admission. An absolute +path is not immutable custody and does not eliminate file replacement races; +T16 retains native executable storage/custody and callback/type admission. +No production configuration, credentials or cluster mutation was used. + +Source integration and publication: `916ba4b33e03179274d03b78bd898a4843e8653f`, following independent +Custodian source review in browser-checker-environment-r2/coordinator-review.json. +The ordinary protected projection pass assigned T17/T18 UUIDs with zero failures +and zero automation errors; generated-only brief commit refusal is retained. +The exact prior staged/working brief bytes were restored. Final source/publication/ +projection evidence is retained in Custodian browser-checker-environment-r2/ +canonical-integration.json. These source receipts do not admit native executable +custody, owner callbacks, acknowledged type changes or browser identities. + +## T19 — Bind checker execution to verified immutable attempt bytes + +```task +id: NK-WP-0048-T19 +status: done +priority: high +state_hub_task_id: "f50fdcd1-00be-5c3c-be0c-345aa2126032" +``` + +Completed 2026-10-16, independently reviewed source implementation and synthetic +fixture proof only. The registration adapter now opens a bounded regular checker +artifact without following its terminal symlink, verifies the reviewed digest, +and snapshots the exact bytes into a write/grow/shrink/seal-removal-sealed Linux +memfd before helper access. Live and proposed config checks execute that same fd +through procfs with the existing empty environment; the fd closes on completion +or failure. Unsupported snapshot/seal/exec policy refuses through the existing +parent-session revocation and uncertainty boundaries. The earlier unbounded +pre-snapshot path read was removed during independent review; actual adapter +symlink/FIFO/oversize refusal tests verify helper access never starts. + +Evidence: Custodian `docs/changes/netkingdom-target-2026-10-16/browser-resume-r1/`, +including exact base/preimages/postimages/patch, proposed descriptor, coordinator +source review and canonical integration receipt. Independent Custodian checks +passed 49 affected source tests and 12 actual Go checker/helper/kernel scenarios; +the sets overlap and are not separate acceptance counts. Existing published +Warden d97652a producer pins remain unchanged. The exact KeyCape artifact remains +`sha256:be37738fe1c08259fb4f9ca0daf0f9301bfffc237e5bb38435525dfbf11ccff5`. +The predecessor path-replacement refusal and the first expanded reopened-fd test +failure are retained; the latter fixture was corrected to restore write mode +before independently proving seals block reopened-fd writes and shared mmap. + +This source task adds no native owner custody, callback, evidence trust, type +acknowledgment, credential access, consumer sign-in or rollback acceptance. +Executable memfds, Linux seals and usable procfs are explicit runtime dependencies +and still require native admission. This is an extracted source outcome from +T16, not completion of T16; T12/T14/T15 and all external-owner gates remain open. + + +Publication verified by the coordinator after the source worker usage limit: +`8790dd18ae83c4651ef3d1d923312a118a5b436b` is the actual remote main revision. +All five canonical source hashes match the reviewed packet. Normal synchronization +completed with zero failures/automation errors; all 19 task statuses match the +projection. T19's assigned UUID is retained. The original staged and working brief +bytes were restored and independently compared. The exact source, projection and +publication checks are in Custodian browser-resume-r1/canonical-integration.json. +Native acceptance remains open under T16 and the other named owner tasks. + + +## T20 — Prepare durable group provenance and prove disposable LLDAP compatibility + +```task +id: NK-WP-0048-T20 +status: done +priority: high +state_hub_task_id: "863fcbdb-e246-51ba-87ca-a2f44d01d6f8" +``` + +Completed 2026-10-17, source candidate preparation and bounded synthetic +compatibility proof only. This extracts evidenced implementation/fixture scope +from T14; T14 retains native storage, writer isolation, protected callback and +owner-acceptance gates. Source integration/publication and State Hub projection +are pending the coordinator's separate receipts; no revision or task UUID is +invented here. + +The existing identity-provisioner group ensure/revoke interface now has a +reviewed candidate for a bounded owner-private SQLite journal, proven only in +local/disposable use. The initial storage instructions wrongly suggested a native +persistent-volume path; source review against accepted ADR-0015 corrected them +before publication. Production SQLite-on-a-PVC is not admitted: T14 retains +CNPG/rapp-postgres storage admission or a separately governed exception. +The local journal saves +complete prestate and intent before each attempted directory mutation, inventories +only confirmed new groups/memberships, binds original ensure idempotency and +correlation to the exact request digest, and refuses unsigned caller inventories +or legacy broad revoke requests. Replays never recreate removed state. Missing, +replaced or untrusted storage and missing intent rows stop execution; definite +before-mutation refusals retain evidence without stranding unrelated valid work. +Interrupted writes/readback remain unresolved across reopening. Revoke validates +all targeted native ids and complete member postimages before destructive work, +removes only confirmed creations and never deletes a preexisting empty group. +Server/configuration wiring, image-copy closure and owner storage/request +migration instructions are included. The existing endpoint's caller +authentication remains the existing boundary, not a new grant. + +The candidate was prepared against NetKingdom +`878abc93588e12b6da1bac055cfbb3abb8d7adf1`; exact source patch digest +`sha256:1f3f3ca94c46dadac8f24896053d4d23179de795e50a24298a0cfbcc46cca30e`. +The independent Custodian review passed all 65 provisioner checks. The earlier +62-check candidate, two independent-review findings and subsequent fixes remain +retained rather than overwritten. Seven additional fixture-plan checks exercise +the preparation boundary; these counts overlap the same candidate and do not +measure task-completion percentage or independent acceptance. + +A separately reviewed bounded fixture then exercised the exact candidate against +cached pinned disposable LLDAP and Python images, through actual GraphQL. All 14 +closed compatibility/containment oracles passed: exact creation inventory, +separate-process SQLite reopening/replay/revoke, complete preexisting directory +preservation including empty/shared groups and memberships, refusal of shared +membership drift, retained uncertainty after a lost response following a real +addition, and refusal of unknown/cross-case receipt bindings. The fixture used +only newly generated synthetic users/passwords/key material in private tmpfs, +with a network-none anchor and shared loopback helper, no host ports/mounts, +no image pulls and no production or actual credential contact. The coordinator's +safe receipt reports both exact owned containers absent after cleanup; final +independent cleanup verification remains the coordinator's integration duty. + +Evidence: Custodian +`docs/changes/netkingdom-target-2026-10-16/group-provenance-r1/`, including exact +source base/pre/postimages, patch/manifest, independent review and retained +refinements. Native fixture manifest +`sha256:8a0514f5f14137355972400cd4852f48c892316d28e3abd3c86635d7cb81eef2`; +retained safe result `native-fixture/execution-result.json` (original +`/tmp/nk48-groups-native-review-5pywb19z/result.json`). The source task supplies +no native owner assent, production rollout, protected session/evidence callbacks, +ordinary type admission or consumer login proof. LLDAP has no conditional +membership mutation or generation token here: exact readback cannot exclude +ABA or a concurrent external writer, so T14 remains open. + +2026-10-17 verified source follow-through: source commit `4f65e41` passed normal +local scanning and all 65 canonical provisioner tests. The actual disposable +LLDAP receipt passed all 14 oracles; independent verification on the pinned +daemon found both exact names and the run label absent. Source integration +includes the ADR-0015 documentation correction; the journal remains local-only. + +T14 source preparation is underway. Twenty-three pinned public sources identify +NetKingdom implementation/reconciliation, Platform custody/database governance +and rapp-postgres consumer provisioning; the inspected runtime binding does not +assign identity-provisioner a package. The existing User Engine runtime token +and pod route are not a protected-case caller lane. The native proposal preserves +the same journal seam on a dedicated CNPG consumer and requires authoritative +scope binding, admitted role/lease/placement/recovery and all LDAP writers fenced. +The declared exclusive maintenance window is not mechanical exclusion of WebUI, +helper or lifecycle writers. Capacity placement and EUR cost/risk remain owner +decisions. No package, database, credential, rollout or owner assent was created. +Custodian evidence: group-provenance-r1/native-storage-proposal-r1; final source, +projection and cleanup review: resume-integration-r1/publication-verification.json. + + +## T21 — Implement the PostgreSQL journal and prove disposable SQL compatibility + +```task +id: NK-WP-0048-T21 +status: done +depends_on: [NK-WP-0048-T20] +priority: high +state_hub_task_id: "afe78e4d-408a-516a-ab92-e212e8a2d11d" +``` + +Completed 2026-10-17: bounded source preparation and actual disposable PostgreSQL +compatibility only. T14 retains native storage, custody, callbacks, authorization, +all-writer isolation and production admission. Coordinator source publication and +projection remain separate follow-through; no source revision or task UUID is +invented here. T20 remains the historical local SQLite/actual LLDAP proof. + +The eight-path source candidate adds an injection-only PostgreSQL implementation +behind the existing owner journal seam, with explicit trusted tenant/directory/ +case/source/principal/epoch binding and independent continuity callbacks. It +persists bounded intent/created-only receipts, exact-one version updates, durable +active fences, and a content-bound journal chain. SQL commits precede independent +exact-marker acknowledgment; lost replies/checkpoints poison continuation and +retain uncertainty. A counter-only checkpoint is explicitly insufficient for +divergent clones. Migration does not create database/schema/credential, admit an +epoch or clear quarantine; production HTTP activation is absent pending trusted +callbacks. Pinned psycopg package/image-copy closure is included, without claiming +an image build or native dependency admission. + +Candidate base `6cb43c0cc55212363a5406b02db046e2384a7c40`; final eight-path patch +`sha256:5549d2982b61ff70aba4b3928fecd5639db0f1a732ab2f8630f678e7acf4d34d`. +All 82 source tests pass, alongside 13 fixture plan/diagnostic checks and two +source-backed snapshot regressions. Counts overlap the same source and fixture; +they are not additive native acceptance or completion percentages. + +The independently reviewed R5 fixture ran the actual SQL migration/backend and +existing provisioner path against cached pinned disposable PostgreSQL. Directory +operations deliberately used the existing synthetic LLDAP test double. All +manifest-declared phase oracles passed: creation-only inventory and DDL refusal; +separate-process replay/revoke with complete preexisting/shared visible-state +preservation; foreign-context refusal; concurrent exactly-once reservation and +stale version refusal; actual database fork with divergent bodies at the same +counter and fresh-object rejection of the losing exact checkpoint; retained +uncertainty after checkpoint/directory/SQL response loss; and actual pg_dump/ +pg_restore rollback refusal against the independently retained fixture checkpoint. +The checkpoint is fixture-only, not an admitted native owner evidence holder. + +Only generated credentials/state were used, with two nonroot/read-only containers +on private loopback, bounded tmpfs/CPU/memory/PIDs/lifetimes, no host ports/mounts, +no pulls and no production contact. The safe receipt reports both exact owned +containers absent, with no daemon uncertainty. Independent final pinned-daemon +cleanup verification remains coordinator follow-through. + +Failed R2/R3/R4 receipts and source revisions remain retained. R2's helper failure +subphase is unknown; R3 exposed a real backend bug where replacing nested receipt +objects lost the created ID held by ensure, fixed by acknowledging only the backend +version after commit/checkpoint. R4 verified that fix through actual SQL bootstrap, +then exposed fixture snapshot aliasing and empty deleted-group backing entries; +source-backed regressions corrected the snapshot without weakening complete +visible-prestate equality, and reject nonempty orphan membership. These refinements +belong to one trial, not extra native acceptance successes. + +Custodian evidence: `docs/changes/netkingdom-target-2026-10-16/group-postgres-r1/`; +exact source/pre/postimages and retained predecessors; native R5 manifest +`sha256:d51f90816616848b93bcdc482e10a98d07061deb01eeed9e50700fc6e68b6051`; +`final-integration-r1/typed-execution-evidence.json` and byte-exact safe receipt +(original `/tmp/nk48-postgres-native-review-sguj7t8p/result.json`). No CNPG native +storage/HA/backup/lease/TLS/capacity/restore admission, authoritative protected +callbacks, real LDAP writer fencing/CAS/ABA exclusion, owner assent or production +endpoint activation is claimed. Those remain live T14 work. + + +## T22 — Establish registration recovery source gaps and complete descriptor review inventory + +```task +id: NK-WP-0048-T22 +status: done +priority: high +state_hub_task_id: "ea50d93b-0d04-55d2-98c4-9b6c3fe925b1" +``` + +Completed 2026-10-17: source-only owner-contract review and complete review +inventory. Inspected the actual registration adapter, Warden Journal/Executor, +NetKingdom evidence compatibility checker and Audit Core custody/read surfaces. +No existing admitted holder/readback supplies authenticated original-attempt +recovery: payload/creation are process-local, persisted evidence references are +hashed, and reconcile receives a new attempt without original context. The exact +four-owner contract requirements and non-replayable missing/ambiguous cases are +recorded; no recovery callback, publisher, credential grant or native trust root +was installed. T15 retains implementation and actual acceptance. + +The complete source1.2 inventory maps all seven follow-through steps to their +existing owners, missing exact contracts and created-only rollback requirements. +The actual maintained adapter regenerated the sole existing register-client +machine descriptor against the delivered 13,633,409-byte checker and current +sealed-memfd snapshot source. The checker rehash and Warden Descriptor.decode +round-trip passed; six owner descriptors remain absent. Actual source commands +render canonical1.1 and explicitly selected1.2 with execution.permitted false; +ordinary1.2 case admission still refuses its acknowledged/unimplemented type. +Canonical type/case/acknowledgment bytes were hash-checked unchanged. No tests were +added or rerun, no native configuration or effect occurred, and no owner assent +or complete machine bundle is claimed. T16 retains native executable custody, +complete exact descriptors, independent source review and normal version/type +admission. This extracted outcome supplies no native gate completion credit. + +Evidence in the-custodian: +`docs/changes/netkingdom-target-2026-10-17/native-registration-r1/`, especially +original-attempt-review.json, descriptor-composition.json, source-verification.json, +source-manifest.json and manifest.json. The prior sixteen-gate audit remains +immutable. Publication, normal task UUID allocation and projection are separate +coordinator follow-through; no Hub UUID is assigned by this source record. + + +## T23 — Review native journal package assignment and storage integration boundaries + +```task +id: NK-WP-0048-T23 +status: done +priority: high +state_hub_task_id: "6e7cd483-c7af-53a2-9d0a-3d76b6fb49ee" +``` + +Completed 2026-10-17: source/package placement and protected integration review +only, separate from T21's completed PostgreSQL source and disposable-SQL proof. +The owner review recommends a dedicated independently rolled-back +`rapp-identity-provisioner`, owned by NetKingdom on rail-kubernetes, with a +schema-valid draft declaration and no reef binding. No repository, registry +entry, native package assignment or owner assent was created. Existing +rapp-user-engine ownership/token delivery does not assign it the provisioner. + +The complete current rapp-postgres catalog has six declared consumers: four on +platform-pg and two on platform-pg-2. The inert renderer-valid provisioner +candidate fits platform-pg-2 at three of four, requesting one migration plus +four runtime connections; placing it on the first cell is refused as a fifth. +Normative package schema and full-catalog capacity/render checks passed. The +four-consumer ceiling is estimated, not measured native headroom, and no current +SQL session, backup or restore acceptance is claimed. + +The exact review identifies remaining package/substrate, SQL role/lease/TLS, +network and backup/recovery contracts; independently authenticated protected +scope callbacks; an external content-bound checkpoint holder with atomic +advance/loss handling; and all-LDAP-writer exclusion or provider CAS/generation, +including lifecycle cascades and remove/readd ABA. Generic Audit custody is not +that checkpoint service. A database-only fence, final reread or one replica +cannot exclude foreign directory writers. The native acceptance/recovery matrix +keeps storage/lease admission separate from separately approved directory +mutation; the production activation remains disabled pending trusted integration. + +Evidence in the-custodian: +`docs/changes/netkingdom-target-2026-10-17/native-storage-r1/OWNER-REVIEW.md`, +source-validation.json and hash-bound source-references.json, plus the inert +proposed declaration/consumer and renderer outputs. No native resource, lease, +credential, deployment, destructive effect, independent holder or native owner +acceptance was delivered. T14 retains these live gates with its original UUID +and progress status. This completed review adds no duplicate T21 acceptance +credit; publication, task UUID allocation and projection remain coordinator +follow-through and no UUID is hand-assigned here. + +## T24 — Ensure-groups adapter source candidate + +```task +id: NK-WP-0048-T24 +status: done +priority: high +state_hub_task_id: "1a3931ee-3b5f-52fc-9295-4073804f4bd2" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): ensure-groups-adapter.py, 8 tests (commit 5a2e7d6). Binds to the T14 PostgreSQL journal and refuses SQLite or a foreign binding. It accepts only canonical 1.1 cases, so T30 must add an explicit 1.2 path. It calls the provisioner's private `_group_binding`; a public helper is the cleaner shared edit. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Bind group creation to T14's journal/provenance seam; refuse without trusted journal callbacks. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. NetKingdom (directory) owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T25 — Mint-secret adapter source candidate + +```task +id: NK-WP-0048-T25 +status: done +priority: high +state_hub_task_id: "0de2a7d9-874d-578b-a076-f653fe42e30b" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): mint-secret-adapter.py, 9 tests (commit 558c5bc). Value-free receipts only. The receipt schema `railiance-platform.custody-mint.v1` and the mint/destroy capability interface are proposals that Platform must confirm. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Platform-owned custody evidence seam: the adapter records value-free mint evidence only and never handles secret values. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. Platform owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T26 — Deliver-secret adapter source candidate + +```task +id: NK-WP-0048-T26 +status: done +priority: high +state_hub_task_id: "94b3cbf0-c908-5ac6-b0db-67385c3e021c" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): deliver-secret-adapter.py, 8 tests (commit 1b60f6e). The lane `platform-secret-delivery` and the schema `netkingdom.deliver-secret.v1` are proposals that Platform must confirm. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Platform-owned delivery evidence seam (ESO/custody), value-free. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. Platform owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T27 — Bind-env adapter source candidate + +```task +id: NK-WP-0048-T27 +status: done +priority: high +state_hub_task_id: "e56365f8-29b5-5c89-a329-8115f9f3b2a7" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): bind-env-adapter.py, 5 tests (commit 6fbce73). Binds references only. To fit the budget it does not yet wrap a full Warden `Adapter` like T13 (source-digest pin, authenticated evidence, parent-session revocation); it returns `(reference, run, rollback)`. That wrapping is a prerequisite for T30. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Bind the issuer Deployment env reference to the delivered secret reference, without values. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. NetKingdom runtime owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T28 — Deliver-consumer-secret adapter source candidate + +```task +id: NK-WP-0048-T28 +status: done +priority: high +state_hub_task_id: "6dab281c-ea9a-5a17-a83f-e8e9a4d4484f" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): deliver-consumer-secret-adapter.py, 5 tests (commit 650c1ac). Type 1.2 only. It assumes the owner has validated ESO TokenRequest and the controller-RBAC admission; that stays an owner gate. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Consumer-side delivery evidence seam, value-free. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. Platform and Apps owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T29 — Hand-over adapter source candidate + +```task +id: NK-WP-0048-T29 +status: done +priority: high +state_hub_task_id: "129db41d-4560-5e20-9f3b-c3c91e0a5601" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): handover-adapter.py, 8 tests (commit ec63539). The owner `apps` and lane `apps-consumer-handover` are proposals that the Apps owner must confirm. It has no reconcile path; restart handling follows T15. + +Split from T16 on 2026-10-17 so each candidate fits one per-task budget. Apps-owned consumer verification and hand-over receipt seam. +Source candidate only, modelled on the T13 registration adapter +(`sso-mfa/k8s/keycape/keycape-registration-adapter.py`, its tests and +`registration-adapter.md`). Requires positive and refusal fixtures and +created-only rollback. Keeps canonical 1.1 as the default and uses no +`--allow-unimplemented` admission. Done means the candidate and its tests are +committed. Apps owner source review before pinning, and any native action, +stay separate gates and are not supplied by this task. + +## T30 — Compose the descriptor set over the reviewed candidates + +```task +id: NK-WP-0048-T30 +status: done +depends_on: [NK-WP-0048-T24, NK-WP-0048-T25, NK-WP-0048-T26, NK-WP-0048-T27, NK-WP-0048-T28, NK-WP-0048-T29] +priority: high +state_hub_task_id: "6f6073ac-52dd-5b70-8874-6d76d4c072e4" +``` + +2026-10-17 done: coordinator review r3 (the-custodian `nk48-adapters-1.2-review/coordinator-review-r3.json`, +fd07eaa) approved all nine files at ff8f597, with R2-F1..F3 resolved, an independent +reconstruction of 117 passing and no open findings. This is a source review only: +it grants no owner admission, pin or native authority. Owner review and admission +continue under T16, which also takes the r2 observations, including the +`warden_executes: false` steps that carry execution descriptors. + +2026-10-17 coordinator review r2 (the-custodian `nk48-adapters-1.2-review/coordinator-review-r2.json`) +approved five files and rejected three, plus the artifact. The fixes are merged in +2ee4ed0: R2-F1, mint-secret revokes the session and the broker grant +independently (eeed8e1); R2-F2, deliver-secret binds to the admitted case and +derives its Secret and custody path, with no caller reference (640292c); R2-F3, +bind-env pins its five-file closure, and a new closure-completeness test checks +every adapter (d16db30). Each regression test failed on 68f4bbb. The artifact is +regenerated, and the full suite including kernel admission passed 117. Next is +the r3 review. Open for owner review under T16: the type marks four steps +`warden_executes: false`, yet each has an execution descriptor. + +2026-10-17 founder confirmed every proposed lane and schema name for T25-T29 +as-is. The artifact records them as `names_confirmed` (by founder, 2026-10-17), +and no step is still `owner_confirmation_required`. Next: independent source +review of the seven adapters. + +2026-10-17 founder decision (supersedes the `agent` decision below): the +mint-secret actor is `human`. Coordinator review r1 (the-custodian +`docs/changes/netkingdom-target-2026-10-17/nk48-adapters-1.2-review/coordinator-review-r1.json`, +finding NK48-R1-F1) showed that unchanged kernel a45cf47 refuses every +`effect: mint` admission whose actor is not `human` ("agent mint is +forbidden"), so the `agent` descriptor could never be admitted. Adapter, tests +and composer comment updated and the artifact regenerated (mint-secret +descriptor digest now `sha256:8c40c2884f8ba15e8cb6c98f33419c395e54fce8ef33d6e1a34782cf3f1fcfa9`); +98 tests pass against a45cf47. The set needs an independent r2 review. + +2026-10-17 `test_admit_1_2_adapter_descriptors.py` runs Warden's own +`Executor.admit` on all seven composed 1.2 descriptors, with the real 1.2 +type, the 1.2 forgejo example case, the reviewed `BrowserInputs` validator and +fixture-only trust (stand-in adapters, nothing dispatched). It also pins that +an agent mint descriptor is refused ("agent mint is forbidden") and that a +wrong lane is refused for every step. Against the old `agent` revision +(582ab9f) it fails as expected. Combined suite: 102 passed on ops-warden a45cf47 +and on current ops-warden. Fixture admission is not owner admission or a pin. + +2026-10-17 founder decision: the mint-secret actor is `agent`, not `warden`. +The kernel is unchanged. The adapter, its test and the composer were updated and +the artifact regenerated; all seven steps pass `Descriptor.decode` and +`complete_executable_descriptor_set` is true (98 tests passed). The artifact +stays `not_an_admission`, with no owner review, admission or dispatch permission. + +2026-10-17 composer merged (60b41a1 via 3c62bec) with follow-up 376b44b (merged; +combined suite 98 passed). `compose-1.2-descriptors.py` loads 1.2 only through an +explicit version root and refuses partial, duplicate, unknown or mismatched maps. +`descriptor-composition-1.2.candidate.json` is a reviewable candidate, marked +`not_an_admission`, with canonical 1.1 unchanged. ensure-groups and hand-over now +carry and honour `parent-session` revocation, and the hand-over owner is +parameterised (`railiance-apps` for Forgejo). Six of the seven steps pass +`Descriptor.decode`. mint-secret is still refused: its actor `warden` is outside +the kernel's human/agent set, and Platform (with ops-warden, if the kernel should +change) must decide. Five steps carry `owner_confirmation_required` names. The +set is complete only after both. Owner review, the canon section 6 successor +revision and admission remain T16's. + +2026-10-17 prerequisites merged (65559ef; combined suite 78 passed): +ensure-groups accepts 1.2 via an explicit `version_root='1.2'` (531151b), with +1.1 still the default. bind-env is now a full Warden v1 `Adapter` (7442d21); its +kernel-level fixture tests like T13's are still missing, and its `build()` +signature changed. Composition is unblocked in source. Owner confirmation of +the proposed step, lane and schema names remains before pinning. + +2026-10-17 inputs from T24–T29 that composition must resolve: T24 accepts +only 1.1 while T28 accepts only 1.2, so add an explicit 1.2 ensure-groups path; +T27 still needs full Warden `Adapter` wrapping; the lane, schema and owner names +proposed in T25, T26 and T29 need owner confirmation before pinning. + +Split from T16 on 2026-10-17. Compose the seven-step source 1.2 descriptor set +through the existing explicit version-root selection over T13 and T24–T29. No +partial descriptor map, canonical 1.1 stays the default, and new descriptor bytes +need a reviewed successor revision under canon section 6. Owner review and +admission remain T16's. + +## T31 — Restart and lost-receipt fixtures against Warden's original-intent interface + +```task +id: NK-WP-0048-T31 +status: done +priority: high +state_hub_task_id: "ed1ccd87-89a0-5e69-885c-0eaf5ab0bb5a" +``` + +2026-10-17 done (source candidate only; merged in 7dbe75f; combined suite 69 passed): test_registration_original_intent_reconcile.py, 8 tests (commit 74adcd7), runs against the unmodified ops-warden a45cf47. The holder is a test-only in-memory store. For real T15 support the T13 adapter's `build()` needs an injected holder/readback capability, a `reconcile_original` callback, and a `verify` that accepts reconcile results. Rollback after restart stays refused until there is an owner contract. + +Split from T15 on 2026-10-17. ops-warden published the original-intent +lookup/context interface in `src/warden/case_run.py` (`OriginalIntent`, +`Journal.original_intent`, `Adapter.reconcile_original`; commit `a45cf47`). +Build T15's restart/lost-receipt fixtures for the registration adapter against +it: the original intent is kept separate from the reconcile attempt; wrong +attempt/case/source/principal and unavailable-holder cases refuse; and a missing +or ambiguous record stays uncertain, with no add replay or undo. The interface +is Warden's own dispatch record, not owner-authenticated created-only provenance. +Selecting the actual authenticated holder stays a T15 owner gate. + + +## T32 — Restore independent agent-mint admission regression coverage + +```task +id: NK-WP-0048-T32 +status: done +priority: high +state_hub_task_id: "c6d0a27e-f6a7-5df0-95f6-3e7473d38bb5" +``` + +Completed 2026-10-17, source tests only. Extracted from T16's coordinator r5 +finding NK48-R5-F1; no earlier adapter outcome is counted again. The real 1.3 +admission test now separately checks the committed descriptor map, an in-memory +fixture map acknowledging the changed agent descriptor to reach the independent +mint prohibition, and the human descriptor under an explicit fixture agent +runtime marker. Only `sso-mfa/k8s/keycape/test_admit_1_3_type.py` changes. + +Against frozen Warden `117fec9241e7b985dfb187b992e173d0a5dc3700`, the new +suite passes 10 tests / 32 subtests. Independent mutation evidence removes only +the mint admission guard in scratch: both new guard tests fail while eight +controls pass; the old suite passed that mutant. Custodian independently reran +the canonical successor: 10 tests / 32 subtests pass. Evidence: +`the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-r5-f1-implementation-r1/` +(patch, frozen/mutant results and canonical-validation.json). No descriptor, +parameter pin, catalog, acknowledgment, kernel or native execution changed. +T16 still owns actual composition and admission; F2/F3 follow below. + +## T33 — Close the issuer-store reference finding with Platform source + +```task +id: NK-WP-0048-T33 +status: todo +priority: high +state_hub_task_id: "5ace28ff-a4cb-5647-a8f6-3cd54bb9d0a5" +``` + +Owner: Platform for the fixed store/template source and its delivery boundary; +NetKingdom for the 1.3 type reference. Split from T16's current coordinator r5 +finding NK48-R5-F2. Next action: independently review the prepared Platform +candidate and publish a concrete owner-controlled issuer store kind/name/scope +and template reference, then integrate only that exact proposed source into the +1.3 deliver-secret entry point and regenerate its composition artifact. Candidate +and current review evidence are under Custodian +`docs/changes/netkingdom-target-2026-10-17/nk48-r5-f2-implementation-r1/` +and `nk48-r5-f2-review-r1/`. + +Completion requires exact committed source, a passing independent source review +and unchanged type parameter bytes. No consumer store may be inferred as issuer +store, and no source declaration supplies owner assent, installed ESO support, +CCR/grant changes or a real delivery capability. Those remain existing +RPF-1.3-T4 and T16 admission/native requirements. + +## T34 — Close the consumer configuration inverse finding + +```task +id: NK-WP-0048-T34 +status: todo +priority: high +state_hub_task_id: "37f43c40-d014-544e-aa0b-5219dd4a6b93" +``` + +Owner: Apps for consumer configuration and inverse; NetKingdom for exact type +placement. Split from T16's coordinator r5 finding NK48-R5-F3. Next action: +independently review and implement the owner transaction/inverse through the +existing RAPPS-WP-0016-T05 path, with authenticated durable before/after release +provenance, exclusive serialization of all release writers and a fresh authorized +attended session for every inverse attempt after the hand-over session is revoked. +The inverse must remain reachable for public clients, confidential NO_CHANGE +secret delivery and verification failure before a hand-over receipt exists. + +Completion requires real owner configuration/inverse source bindings and +independent regressions, then exact reviewed 1.3 entry/rollback text and composed +artifact. A synthetic wrapper with an injected backend alone is insufficient. +Keep hand-over receipt rollback receipt-only and secret deletion created-only; +preexisting or drifted resources must refuse unsafe inverse. Candidate evidence: +Custodian `docs/changes/netkingdom-target-2026-10-17/nk48-r5-f3-implementation-r1/` +and `nk48-r5-f3-review-r1/`. Source review, owner acknowledgment and native proof +remain distinct. T16's final composition/admission and T06's native first case +are not completed by this refinement. diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/apply_prepare.py b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/apply_prepare.py new file mode 100644 index 00000000..771fde3a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/apply_prepare.py @@ -0,0 +1,92 @@ +"""Prepared source integration only. Root runs --execute; no commit/projection here.""" +from pathlib import Path +import argparse +import hashlib +import json +import re +import subprocess +import sys + +PACKET = Path(__file__).resolve().parent +ROOT = Path('/home/worsch/net-kingdom') +WARDEN = Path('/home/worsch/ops-warden') + +def sha(data): + return 'sha256:' + hashlib.sha256(data).hexdigest() + +def git(root, *args): + return subprocess.check_output(['git', '-C', str(root), *args], text=True).strip() + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('--execute', action='store_true') + args = parser.parse_args() + manifest = json.loads((PACKET / 'publication-inputs.json').read_text()) + assert git(ROOT, 'rev-parse', '--abbrev-ref', 'HEAD') == 'main' + assert git(ROOT, 'rev-parse', 'HEAD') == manifest['base_revision'] + assert git(WARDEN, 'rev-parse', 'HEAD') == manifest['warden_revision'] + workplan = ROOT / manifest['workplan'] + original = workplan.read_bytes() + candidate = (PACKET / 'workplan.candidate.md').read_bytes() + assert sha(original) == manifest['workplan_preimage_sha256'] + assert sha(candidate) == manifest['workplan_candidate_sha256'] + assert sha((PACKET / 'task-T35.md').read_bytes()) == manifest['task_addition_sha256'] + assert candidate == original + (PACKET / 'task-T35.md').read_bytes() + assert len(re.findall(rb'^```task$', original, re.M)) == 34 + assert len(re.findall(rb'^```task$', candidate, re.M)) == 35 + assert b'id: NK-WP-0048-T35' not in original + assert sha((PACKET / 'candidate.patch').read_bytes()) == manifest['patch_sha256'] + for row in manifest['files']: + path = ROOT / row['path'] + if row['preimage_sha256'] is None: + assert not path.exists() and not path.is_symlink(), str(path) + else: + assert sha(path.read_bytes()) == row['preimage_sha256'], str(path) + protected_before = {name: sha((ROOT / name).read_bytes()) for name in manifest['protected_files']} + assert protected_before == manifest['protected_files'], 'Operator brief/index changed: refresh the prepared inputs first.' + # Preserve the original index exactly; this script never stages anything. + index = git(ROOT, 'ls-files', '--stage', '-z') + assert sha(Path('/home/worsch/repo-manager/src/repo_manager/identifiers.py').read_bytes()) == manifest['repo_manager_identifiers_sha256'] + sys.path.insert(0, '/home/worsch/repo-manager/src') + from repo_manager.identifiers import ensure_missing_work_record_identifiers + before = ensure_missing_work_record_identifiers(ROOT, execute=False) + assert before['ok'] and before['assignments'] == [] and before['files_changed'] == [] + subprocess.run(['git', 'apply', '--check', str(PACKET / 'candidate.patch')], cwd=ROOT, check=True) + if not args.execute: + print(json.dumps({'prepared_only': True, 'preimages_verified': True, 'files': 4, + 'next': 'Run this script with --execute, then run_validation.py --execute.'})) + return + subprocess.run(['git', 'apply', str(PACKET / 'candidate.patch')], cwd=ROOT, check=True) + for row in manifest['files']: + assert sha((ROOT / row['path']).read_bytes()) == row['sha256'], row['path'] + workplan.write_bytes(candidate) + preview = ensure_missing_work_record_identifiers(ROOT, execute=False) + (PACKET / 'identifier-preview.json').write_text(json.dumps(preview, indent=2) + '\n') + assert preview['ok'] and preview['files_changed'] == [manifest['workplan']] + assert len(preview['assignments']) == 1 + assignment = preview['assignments'][0] + assert (assignment['kind'], assignment['record_id'], assignment['path']) == ( + 'task', 'NK-WP-0048-T35', manifest['workplan']) + # UUID comes only from the ordinary allocator, never from this packet. + actual = ensure_missing_work_record_identifiers(ROOT, execute=True) + assert actual['assignments'] == preview['assignments'] + assert actual['files_changed'] == [manifest['workplan']] + (PACKET / 'identifier-assignment.json').write_text(json.dumps(actual, indent=2) + '\n') + allocated = workplan.read_bytes() + assert allocated.startswith(original), 'Existing workplan bytes must be preserved.' + assert len(re.findall(rb'^```task$', allocated, re.M)) == 35 + assert allocated.count(b'id: NK-WP-0048-T35\n') == 1 + assert not ensure_missing_work_record_identifiers(ROOT, execute=False)['assignments'] + assert git(ROOT, 'ls-files', '--stage', '-z') == index, 'Index must remain unchanged.' + assert {name: sha((ROOT / name).read_bytes()) for name in manifest['protected_files']} == protected_before + (PACKET / 'workplan.allocated.md').write_bytes(allocated) + publication = {'owner': 'net-kingdom', 'base_revision': manifest['base_revision'], + 'message': manifest['message'], 'files': [ + {'path': row['path'], 'sha256': sha((ROOT / row['path']).read_bytes()).removeprefix('sha256:')} + for row in manifest['files'] + [{'path': manifest['workplan']}]]} + (PACKET / 'publication-inputs.allocated.json').write_text(json.dumps(publication, indent=2) + '\n') + print(json.dumps({'source_applied': True, 'task_count': 35, 'allocated_only': assignment['record_id'], + 'files': len(publication['files']), 'commit_and_projection': 'Root handles separately.'})) + +if __name__ == '__main__': + main() diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/candidate.patch b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/candidate.patch new file mode 100644 index 00000000..671f3e21 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/candidate.patch @@ -0,0 +1,243 @@ +diff --git a/sso-mfa/k8s/keycape/test_admit_1_3_type.py b/sso-mfa/k8s/keycape/test_admit_1_3_type.py +--- a/sso-mfa/k8s/keycape/test_admit_1_3_type.py ++++ b/sso-mfa/k8s/keycape/test_admit_1_3_type.py +@@ -8,7 +8,9 @@ + acknowledged 1.3 is still refused until ops-warden adds a 1.3 pin. That is an + ops-warden owner change, and it is not made here. The tests show that 1.3's + parameters carry 1.2's pinned fingerprint, and that with only that one pin added in +-memory the committed map admits exactly the composed descriptors and nothing else. ++memory the five resolvable steps admit. The two Apps attended steps remain refused ++because their establishing login is unresolved in the synthetic catalog. Four real ++draft lane shapes are hypothetically active in that fixture; no catalog is promoted. + Trust is fixture-only, nothing is dispatched, and none of this is owner admission + or an acknowledgment. + """ +@@ -37,6 +39,8 @@ + TYPE_DIR = REPO / 'security-case-type-revisions/1.3/oidc-browser-relying-party' + TYPE_BYTES = (TYPE_DIR / 'type.yaml').read_bytes() + ARTIFACT = json.loads((ROOT / 'descriptor-composition-1.3.candidate.json').read_text()) ++CATALOG = (ROOT / 'kernel-catalog.fixture.yaml').read_bytes() ++UNRESOLVED_APPS = {'deliver-consumer-secret', 'hand-over'} + EVIDENCE = {'fixture-acceptance', 'fixture-materialization', 'fixture-descriptor', 'fixture-session'} + + +@@ -74,12 +78,13 @@ + ARTIFACT['params']['consumer_owner_repo'], + version='1.3')) + +- def admit(self, desc, type_source, *, actor=None, lane=None, agent_id=None): ++ def admit(self, desc, type_source, *, actor=None, lane=None, agent_id=None, catalog=CATALOG): + desc_bytes = c.encode(desc) + adapter = Adapter(desc.adapter, desc.adapter_source, unused, unused) + executor = Executor(Journal(Path(self.temp.name) / desc.step), + {adapter.reference: adapter}, +- lambda purpose, source, evidence: evidence in EVIDENCE, ++ lambda purpose, source, evidence: (evidence in EVIDENCE and ++ (purpose != 'catalog-routing-acceptance' or source == digest(CATALOG))), + browser_inputs=inputs.BrowserInputs(REPO)) + with mock.patch.dict(os.environ): + if agent_id is None: +@@ -87,7 +92,7 @@ + else: + os.environ['WARDEN_AGENT_ID'] = agent_id + return executor.admit(self.case_source, type_source, desc_bytes, +- b'fixture-only-catalog', principal='founder', actor=actor or desc.actor, ++ catalog, principal='founder', actor=actor or desc.actor, + lane=lane or desc.lane, + acceptance_evidence='fixture-acceptance', + materialization_evidence='fixture-materialization', +@@ -112,18 +117,33 @@ + self.assertEqual(parameter_fingerprint(TYPE_BYTES), inputs.PARAMETER_PINS['1.2']) + acknowledged = with_status('acknowledged') + for step, desc in self.descriptors.items(): ++ if step in UNRESOLVED_APPS: ++ continue # The attended session gate correctly precedes parameter validation. + with self.subTest(step=step), self.assertRaisesRegex( + Refused, 'failed exact-version validation'): + self.admit(desc, acknowledged) + +- def test_committed_map_admits_every_descriptor_once_acknowledged_and_pinned(self): ++ def test_committed_map_conditionally_admits_five_resolvable_steps(self): + acknowledged = with_status('acknowledged') + for step, desc in self.descriptors.items(): ++ if step in UNRESOLVED_APPS: ++ continue + with self.subTest(step=step), pinned_13(): + admitted, invocation, _ = self.admit(desc, acknowledged) + self.assertEqual(admitted, desc) + self.assertEqual((invocation.step, invocation.actor, invocation.target), + (desc.step, desc.actor, 'forgejo')) ++ ++ def test_unresolved_apps_sessions_refused_even_once_acknowledged_and_pinned(self): ++ for step in sorted(UNRESOLVED_APPS): ++ with self.subTest(step=step), pinned_13(), self.assertRaisesRegex( ++ Refused, 'does not resolve to an active, reviewed login lane'): ++ self.admit(self.descriptors[step], with_status('acknowledged')) ++ ++ def test_catalog_evidence_is_bound_to_exact_fixture_bytes(self): ++ mint = self.descriptors['mint-secret'] ++ with pinned_13(), self.assertRaisesRegex(Refused, 'independent owner evidence not verified'): ++ self.admit(mint, with_status('acknowledged'), catalog=CATALOG + b'\n# changed source\n') + + def test_descriptor_outside_the_map_is_refused(self): + acknowledged = with_status('acknowledged') +diff --git a/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py b/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py +--- a/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py ++++ b/sso-mfa/k8s/keycape/test_keycape_registration_adapter.py +@@ -259,8 +259,13 @@ + case_source = yaml.safe_dump(case).encode() + typ = yaml.safe_load((root / 'security-case-types/oidc-browser-relying-party/type.yaml').read_bytes()) + typ['spec']['execution_descriptors'] = {'register-client': digest(self.desc_bytes)} ++ # Fixture-only successor lane for the adapter's current descriptor. ++ # Canonical 1.1 still names the earlier login lane and is not edited. ++ typ['spec']['follow_through'] = [ ++ dict(step, lane=self.admitted.lane) if step['id'] == 'register-client' else step ++ for step in typ['spec']['follow_through']] + type_source = yaml.safe_dump(typ).encode() +- catalog = b'fixture-only-catalog' ++ catalog = (ROOT / 'kernel-catalog.fixture.yaml').read_bytes() + sheet = json.dumps(['register-client', 'net-kingdom', 'forgejo', 'human', + 'founder', 'keycape-attended-case-change', 'fixture-acceptance', 'fixture-materialization', + 'fixture-descriptor', 'fixture-session'], separators=(',', ':')).encode() +@@ -270,6 +275,8 @@ + adapter = a.build(**dict(self.kw, admitted=invocation, case_source=case_source, + case_acceptance='fixture-acceptance')) + def fixture_verifier(purpose, source, evidence): ++ if purpose == 'catalog-routing-acceptance': ++ return source == digest(catalog) and evidence == 'fixture-descriptor' + if purpose.startswith('session-revocation:'): + _, lane, operation, attempt = purpose.split(':') + return source == digest(case_source) and lane == invocation.lane and evidence == ( +diff --git a/sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml b/sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml +new file mode 100644 +--- /dev/null ++++ b/sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml +@@ -0,0 +1,128 @@ ++# TEST ONLY: synthetic subset shaped after ops-warden 5abde817 catalog. ++# Four draft entries are hypothetically active; Apps session_lane remains unresolved. ++# Not an authenticated owner catalog, promotion, login choice or native authority. ++entries: ++- id: key-cape-oidc-login ++ risk: standard ++ owner_repo: key-cape ++ warden_executes: false ++ reviewed: '2026-06-27' ++ status: active ++ delegation: ++ mode: interim ++ intended_owner: key-cape ++ reviewed: '2026-09-08' ++ blocked_on: fixture-only; no native authority ++ lane: login ++ title: Synthetic key-cape-oidc-login ++ need_keywords: ++ - key-cape-oidc-login ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: keycape-client-secret-generate ++ risk: high ++ owner_repo: railiance-platform ++ warden_executes: false ++ reviewed: '2026-10-10' ++ status: active ++ delegation: ++ mode: native ++ intended_owner: railiance-platform ++ reviewed: '2026-10-10' ++ lane: secret ++ title: Synthetic keycape-client-secret-generate ++ need_keywords: ++ - keycape-client-secret-generate ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: keycape-attended-case-change ++ lane: attended-change ++ session_lane: key-cape-oidc-login ++ risk: high ++ owner_repo: key-cape/net-kingdom ++ warden_executes: false ++ reviewed: '2026-10-17' ++ status: active ++ delegation: ++ mode: interim ++ intended_owner: key-cape ++ reviewed: '2026-10-17' ++ blocked_on: fixture-only; no native authority ++ title: Synthetic keycape-attended-case-change ++ need_keywords: ++ - keycape-attended-case-change ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: platform-secret-delivery ++ risk: high ++ owner_repo: railiance-platform ++ warden_executes: false ++ reviewed: '2026-10-17' ++ status: active ++ delegation: ++ mode: native ++ intended_owner: railiance-platform ++ reviewed: '2026-10-17' ++ title: Synthetic platform-secret-delivery ++ need_keywords: ++ - platform-secret-delivery ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: consumer-owner-deployment ++ lane: attended-change ++ session_lane: pending-owner-confirmation ++ risk: high ++ owner_repo: railiance-apps ++ warden_executes: false ++ reviewed: '2026-10-17' ++ status: active ++ delegation: ++ mode: native ++ intended_owner: railiance-apps ++ reviewed: '2026-10-17' ++ title: Synthetic consumer-owner-deployment ++ need_keywords: ++ - consumer-owner-deployment ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. ++- id: apps-consumer-handover ++ lane: attended-change ++ session_lane: pending-owner-confirmation ++ risk: high ++ owner_repo: railiance-apps ++ warden_executes: false ++ reviewed: '2026-10-17' ++ status: active ++ delegation: ++ mode: native ++ intended_owner: railiance-apps ++ reviewed: '2026-10-17' ++ title: Synthetic apps-consumer-handover ++ need_keywords: ++ - apps-consumer-handover ++ subsystem: synthetic source test ++ wiki_ref: fixture-only ++ canon_ref: fixture-only ++ workload_ref: ++ applicability: not-applicable ++ reason: Synthetic source test; no workload or native authority. diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/canonical-validation.json b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/canonical-validation.json new file mode 100644 index 00000000..dbb901eb --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/canonical-validation.json @@ -0,0 +1,15 @@ +{ + "executed": true, + "counts_verified": true, + "returncode": 0, + "warden_revision": "922c26da0f3fcb0182352ea83e6ae06f29878580", + "net_kingdom_head": "342a6f25af5cdc602841948f42759ea52ef1c8f5", + "verified_public_source_files": 105, + "tests": [ + "sso-mfa/k8s/keycape/test_admit_1_3_type.py", + "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py" + ], + "log_sha256": "sha256:2ac155ce37c15bfd4f24483304036fec725bc3f166c0963d56280dea1d43ae73", + "scratch": "/tmp/nk48-catalog-canonical-validation-ntdpunql", + "limitations": "Source fixture tests only; no native owner execution, acceptance, catalog promotion or pin." +} diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/identifier-assignment.json b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/identifier-assignment.json new file mode 100644 index 00000000..c3c67313 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/identifier-assignment.json @@ -0,0 +1,20 @@ +{ + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "net-kingdom", + "namespace": "helixforge", + "assignments": [ + { + "kind": "task", + "record_id": "NK-WP-0048-T35", + "uuid": "cf1d6ab3-846e-53ea-8575-d6347b6f4769", + "path": "workplans/NK-WP-0048-security-case-types.md" + } + ], + "historical_invalid_identifiers": [], + "historical_identity_collisions": [], + "files_changed": [ + "workplans/NK-WP-0048-security-case-types.md" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/identifier-preview.json b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/identifier-preview.json new file mode 100644 index 00000000..b0c23570 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/identifier-preview.json @@ -0,0 +1,20 @@ +{ + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": false, + "repo": "net-kingdom", + "namespace": "helixforge", + "assignments": [ + { + "kind": "task", + "record_id": "NK-WP-0048-T35", + "uuid": "cf1d6ab3-846e-53ea-8575-d6347b6f4769", + "path": "workplans/NK-WP-0048-security-case-types.md" + } + ], + "historical_invalid_identifiers": [], + "historical_identity_collisions": [], + "files_changed": [ + "workplans/NK-WP-0048-security-case-types.md" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/preparation.json b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/preparation.json new file mode 100644 index 00000000..20770873 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/preparation.json @@ -0,0 +1,36 @@ +{ + "schema": "custodian.nk48-catalog-fixture-publication-preparation.v1", + "status": "prepared only; canonical apply and validation runners not executed, including dry-run", + "owner_base": "342a6f25af5cdc602841948f42759ea52ef1c8f5", + "warden_base": "ae7bc73b4f4bac22454144959b870d161498e0af", + "root_source_review": "Root explicitly accepted fixture patch SHA256 df69fb2ec9f1e1cf0dd94194e3c046c995ed8a7deabf65a8e9bec34662adb501 for source integration; no owner/native assent inferred.", + "task_refinement": "Append completed T35 for distinct current authenticated-catalog/mode-aware fixture compatibility; preserve exact original workplan bytes, all34 existing task blocks/frontmatter/status/UUID. Normal allocator preview must yield exactlyT35 before execution; no manual UUID.", + "root_commands": [ + "python3 /home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/apply_prepare.py --execute", + "python3 /home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r1/run_validation.py --execute", + "Root normal scoped commit using publication-inputs.allocated.json; normal owner projection afterwards." + ], + "mutation_scope": [ + "Exactly the three reviewed fixture files plus the appended T35 workplan task.", + "No git stage,commit,push,projection,brief refresh or index generation in prepared scripts.", + "Preexisting operator .custodian-brief.md/WORK-RECORDS.md remain byte-identical; unrelated dirty/untracked paths are never read or written by the apply script." + ], + "validation_scope": "Canonical NK test and source files against Warden mainae7bc73;105 explicit public source hashes checked before and after. Two scoped test modules only; expected31 tests/53 subtests; no skip/deselection accepted. EmptyHOME and allowlisted environment; fresh redirected Python caches; pytest cache/conftest discovery disabled. Network denied. Native processes denied except exact pinned offline metadata validator with guarded empty-environment child. Reads from /home or /root denied except exact prehashed public source files; canonical writes denied.", + "unverified_limits": [ + "Prepared runner has only been AST-parsed; root must execute and inspect logs.", + "Python audit controls are bounded to reviewed test execution and do not claim operating-system credential isolation or an autopilot grant.", + "Warden code is source-only; 1.3 parameter pin, draft promotion, pending Apps login, nativeT03 and downstream acceptance remain gated.", + "Existing adverse review history remains unchanged." + ], + "files": { + "apply_prepare.py": "sha256:b294e6339e8c9af9ba911667646dd0ab52e75cf798de93238d84d1057c8a9e70", + "run_validation.py": "sha256:16236aa55a774f8ea6d66da4ee17f7737c6d1b013d844ca9b9759e02b615af51", + "validation-guard.py": "sha256:13611f4de25dc7d01348905c4b365a0ffbb95fd93a61c75c8faf38d705c54f50", + "workplan.preimage.md": "sha256:f92962c5aa21aade0fc2f6b4f8d9a95932fe85b107413cdd2824b6ebe72c36d9", + "publication-inputs.json": "sha256:d9bf5555013aa9e399037672c80a72af23c6815db03088bee3db4c8583197146", + "candidate.patch": "sha256:df69fb2ec9f1e1cf0dd94194e3c046c995ed8a7deabf65a8e9bec34662adb501", + "task-T35.md": "sha256:7d14d261ffbab2a930c4a3ff962cec786060cad6177280773cf1c0b0f006127f", + "validation-child.py": "sha256:6bd4e3cda22e65f90bbb4006b403270405947293be2ae8bf8fdade0abed61f45", + "workplan.candidate.md": "sha256:3bce122c5b83d9044b142fc2cabc48de5558ab0d65dc0223a8ed0325f219e981" + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/publication-inputs.allocated.json b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/publication-inputs.allocated.json new file mode 100644 index 00000000..2a6bfed1 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/publication-inputs.allocated.json @@ -0,0 +1,23 @@ +{ + "owner": "net-kingdom", + "base_revision": "342a6f25af5cdc602841948f42759ea52ef1c8f5", + "message": "test: align security case fixtures with authenticated catalog admission", + "files": [ + { + "path": "sso-mfa/k8s/keycape/test_admit_1_3_type.py", + "sha256": "2186eab00b000a534ab1452f14fa7b1a7ed352d5b27c400687c1c8ec7c4c3019" + }, + { + "path": "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py", + "sha256": "86268e082763c388528e5175184fd32362167c3441716436e4b1cab150c3e79a" + }, + { + "path": "sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml", + "sha256": "7885b8c380c03ccb0198e540532ce80c791c8e86698521d7173642e0c7a56e53" + }, + { + "path": "workplans/NK-WP-0048-security-case-types.md", + "sha256": "53f9e5826bd7e34287d59f46089ee50c31598ba1a56bcf6d3249525f7e23bb9b" + } + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/publication-inputs.json b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/publication-inputs.json new file mode 100644 index 00000000..17da5816 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/nk48-catalog-fixture-publication-r2/publication-inputs.json @@ -0,0 +1,176 @@ +{ + "schema": "custodian.nk48-catalog-fixture-publication-inputs.v1", + "prepared_only": true, + "owner": "net-kingdom", + "base_revision": "342a6f25af5cdc602841948f42759ea52ef1c8f5", + "warden_revision": "922c26da0f3fcb0182352ea83e6ae06f29878580", + "message": "test: align security case fixtures with authenticated catalog admission", + "workplan": "workplans/NK-WP-0048-security-case-types.md", + "workplan_preimage_sha256": "sha256:f92962c5aa21aade0fc2f6b4f8d9a95932fe85b107413cdd2824b6ebe72c36d9", + "workplan_candidate_sha256": "sha256:3bce122c5b83d9044b142fc2cabc48de5558ab0d65dc0223a8ed0325f219e981", + "task_addition_sha256": "sha256:7d14d261ffbab2a930c4a3ff962cec786060cad6177280773cf1c0b0f006127f", + "patch_sha256": "sha256:df69fb2ec9f1e1cf0dd94194e3c046c995ed8a7deabf65a8e9bec34662adb501", + "files": [ + { + "path": "sso-mfa/k8s/keycape/test_admit_1_3_type.py", + "preimage_sha256": "sha256:c512ba00513d066fd1ca8af08fd6bf106fbd7a132981b1dcc5af80a745ab03f0", + "sha256": "sha256:2186eab00b000a534ab1452f14fa7b1a7ed352d5b27c400687c1c8ec7c4c3019" + }, + { + "path": "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py", + "preimage_sha256": "sha256:4d0126416522e54eec1ae4c83b5488e09ff11ffb97ec1ee6d234548780c60f63", + "sha256": "sha256:86268e082763c388528e5175184fd32362167c3441716436e4b1cab150c3e79a" + }, + { + "path": "sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml", + "preimage_sha256": null, + "sha256": "sha256:7885b8c380c03ccb0198e540532ce80c791c8e86698521d7173642e0c7a56e53" + } + ], + "allocation": { + "method": "repo_manager.identifiers.ensure_missing_work_record_identifiers", + "manual_uuid": false, + "preexisting_assignments": [], + "expected_new_record_ids": [ + "NK-WP-0048-T35" + ], + "expected_files_changed": [ + "workplans/NK-WP-0048-security-case-types.md" + ], + "expected_task_count": 35, + "concrete_postallocation_manifest": "publication-inputs.allocated.json" + }, + "protected_files": { + ".custodian-brief.md": "sha256:3eb7f91f2443090c9b859a716d83711310364897b6144dcf10d3254342fec3d1", + "WORK-RECORDS.md": "sha256:a1fec217a6e380f528778d781dbea1fc5a836fdefa1dd4dd0308100fbe08112a" + }, + "validation": { + "tests": [ + "sso-mfa/k8s/keycape/test_admit_1_3_type.py", + "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py" + ], + "expected_result": "31 passed,53 subtests passed; no skipped or deselected tests", + "python": "/tmp/warden-kernel-review-r1/final/.venv/bin/python", + "source_hashes": { + "net-kingdom": { + "sso-mfa/k8s/keycape/test_vergabe_client_rollout.py": "sha256:f9b7defc312b0fea24ded92ef479dcc8aef063f7a66a8245760918bcf44c4af1", + "sso-mfa/k8s/keycape/test_compose_1_2_descriptors.py": "sha256:9a4b9fb0141221d6e5bcb72b3656613afda54d16ede300bffa8f71956ae6fd2c", + "sso-mfa/k8s/keycape/test_keycape_client.py": "sha256:9572044679feaedfe732e15a2b6f8ef6b41a8fe2e4430257f309a3e83e97736c", + "sso-mfa/k8s/keycape/openbao-negative-node-wrapper.py": "sha256:76ac013d1a676a0dfa58aea1ce87b0c3e72483ccd21f586a22c5475e9132f6c1", + "sso-mfa/k8s/keycape/portal-client-rollout.py": "sha256:158e1d36eb881cdd0a2eda91b472adea5e8fde5061e00d26dda368580aeb871f", + "sso-mfa/k8s/keycape/test_playwright_activation.py": "sha256:6fc22d091f27a76c32d2fb0a7fc3c6e18e54ff98d242699c518b2f9dc9fd4cbd", + "sso-mfa/k8s/keycape/exercise-approval-clients.py": "sha256:e2d3dd741ac52af28dce752344227a4443b78fedd4cfcc06ba902e679dfc9351", + "sso-mfa/k8s/keycape/keycape-client.py": "sha256:4b63161cf3365d34dd684a3116e2c935baaf7f6aa4b30983f6883546db3d6591", + "sso-mfa/k8s/keycape/test_openbao_negative_session.py": "sha256:01e23f2b4fc77824a161a57acb3a52d19aad846b3b6c0fd3abd81afa1dc2985c", + "sso-mfa/k8s/keycape/authentication-policy-rollout.py": "sha256:2c1bd23fded4855bae1eb3a08dbc4510d7f60f2bc4d625d60e471ab78f6f0251", + "sso-mfa/k8s/keycape/handover-adapter.py": "sha256:bad7c1132258f2140b0d83548031ac86eecea4f4019f34adedc1e9e3774a3832", + "sso-mfa/k8s/keycape/openbao-signin-diagnosis-rollout.py": "sha256:a57b957d6eed9e8fb09d2a7aa7405a39deeafd9aaf57a9e6dc907afabd380371", + "sso-mfa/k8s/keycape/test_handover_adapter.py": "sha256:cd1fb0eb64a777699221ebdfcd6fea96bafb9b27ec388e95dcfe66189eac8ca2", + "sso-mfa/k8s/keycape/test_authentication_policy_rollout.py": "sha256:11c10039d99a34d2819b09146a966c8b7cba6095e7a8b51c055a01e7167e3ed5", + "sso-mfa/k8s/keycape/test_deliver_consumer_secret_adapter.py": "sha256:f4e6c6acd75a36f675007d2f62a7c7c4f7bfe2951cbb5e3e4cdde8b53f17f473", + "sso-mfa/k8s/keycape/bind-env-adapter.py": "sha256:fa17fae21776b5c620ee9782adf050649c3a28719a6687d2524ff67ca7ad1925", + "sso-mfa/k8s/keycape/test_keycape_checker_snapshot.py": "sha256:9271f25c760ad732c257d59d259b5c767436a2dc2d5ba24fca259bc57761d6d1", + "sso-mfa/k8s/keycape/test_openbao_signin_diagnosis_rollout.py": "sha256:25d46fe7caca2ad4c262bd2a25188c91847304b6b051c4f3b3705c69f2803f01", + "sso-mfa/k8s/keycape/test_openbao_private_ready.py": "sha256:8a7a033b1c509ba21397d1d74580c44f24592045b2b9de50fe87638607224277", + "sso-mfa/k8s/keycape/test_mint_secret_adapter.py": "sha256:8110b6a8abd8e9a1f5e1feae11ec09c4e28cb7486c759b0e8459da1fb1b7144d", + "sso-mfa/k8s/keycape/playwright-activation.py": "sha256:5ac683b3324b00e6253f6040f4c73057027b1f98f7071160a6153794ba522757", + "sso-mfa/k8s/keycape/test_admit_1_3_type.py": "sha256:2186eab00b000a534ab1452f14fa7b1a7ed352d5b27c400687c1c8ec7c4c3019", + "sso-mfa/k8s/keycape/test_openbao_node_route.py": "sha256:1c57053be6e8472174e4034fdfbf34b3e1729f5e239b3a9af89d9e59a08d6cb6", + "sso-mfa/k8s/keycape/test_secrets_engine_openbao_client_rollout.py": "sha256:e6f86fb7712c1b9c01d9b684f26d5cc949649b823d2732eced132d59acd3fe01", + "sso-mfa/k8s/keycape/openbao-client-config.py": "sha256:1b908b4c36134212d78f9fbe7a2a201eb3ced06d31bb1dcea4a59d80689d84b1", + "sso-mfa/k8s/keycape/test_registration_original_intent_reconcile.py": "sha256:e2897b8200ec97445fc4a26c55ad82651fcb1a4d22efe7fe59d0fcfc5cd8ec71", + "sso-mfa/k8s/keycape/test_ensure_groups_adapter.py": "sha256:c8754a2ba735116edc6fe257aa993d0530cea9ca9f954ea5a621e38694906be2", + "sso-mfa/k8s/keycape/test_keycape_checker_environment.py": "sha256:35f316eed168d3df588498faf24ab9377733a7d857ddfa5e0e4322a6287c93ff", + "sso-mfa/k8s/keycape/test_bind_env_adapter.py": "sha256:a1e5e7a631a4843f9a0d2310a3942b26936103d786aeae47a142ff7c7b2fdbdb", + "sso-mfa/k8s/keycape/create-secrets.py": "sha256:5da672fff36eb94101741ad99e2a1a96ae81fea15ed1871304c40e63ce27c787", + "sso-mfa/k8s/keycape/approval-clients-rollout.py": "sha256:488d5cc59e081993dd2b5fc6d9e46bbddcaec4f5170b8f7a5ad0aae3a211a790", + "sso-mfa/k8s/keycape/vergabe-client-rollout.py": "sha256:8cee6cc5ff3e3e8617304055263d04b393d0e005c34d9af12cb7e8bc685bac1a", + "sso-mfa/k8s/keycape/keycape-registration-adapter.py": "sha256:a53beea4dbbe373ce7a5b84d55e79be8407ab9688037c7ee057afcc7be576047", + "sso-mfa/k8s/keycape/compose-1.2-descriptors.py": "sha256:39021cac900b11a59d00c5a1d5491b1ee4c639955cde07d07854c3db8bc04958", + "sso-mfa/k8s/keycape/test_approval_clients_rollout.py": "sha256:745316d42c3aba6b59b562d3bbcd4b2cb92871fb5e51a954e2254e2e550bb408", + "sso-mfa/k8s/keycape/register-user-engine-portal.py": "sha256:67173edc44f5457e7b6a3e0fb2321b398159cfce5dea8ead01eabf835fb38d76", + "sso-mfa/k8s/keycape/test_issuer_pin.py": "sha256:e471ed815af246633c0b21ac2cf5cae94d0dbdeff9e6ce801b4ddd033097dc20", + "sso-mfa/k8s/keycape/openbao-negative-session.py": "sha256:24b7b803e4eb7e6e7c0700a069dad0ec315ee7eb5538a88b9e56147f8fab5cdd", + "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py": "sha256:86268e082763c388528e5175184fd32362167c3441716436e4b1cab150c3e79a", + "sso-mfa/k8s/keycape/deliver-consumer-secret-adapter.py": "sha256:65db5386cdf08a1aa932886c046abed20330a36c96e63d4267adb8341b23da42", + "sso-mfa/k8s/keycape/test_portal_client_rollout.py": "sha256:a16cd4bf278970c10de2e1b1025597b3872c9515713dd947ac6b50cb78feea1f", + "sso-mfa/k8s/keycape/test_deliver_secret_adapter.py": "sha256:24cedec29071b62fc2c2458950ed244feeff542bc20a7d480667dd99cda16b03", + "sso-mfa/k8s/keycape/deliver-secret-adapter.py": "sha256:cd1a515a1ae2def2093660ed2a810a9c66d1d4cf7126f573ee7e9c4c42afb98d", + "sso-mfa/k8s/keycape/test_openbao_private_input.py": "sha256:84277edb5bd7858885173dea802b6bdc4f0f0c7785d6e200ee9a98d8553891a1", + "sso-mfa/k8s/keycape/register-coulomb-social.py": "sha256:b40ff4bdba71b797f8f393e79cb3c9d73b790045a0f7df6ecea35803369793c7", + "sso-mfa/k8s/keycape/mint-secret-adapter.py": "sha256:246323c7243ded18229ab063956577e151d56d9be485d3bd44fc38e5af0edf3c", + "sso-mfa/k8s/keycape/test_adapter_source_closure.py": "sha256:63cb442636d996fcf1c36b7b746ed860106a7da35dbaeb1c5129a41420ca4155", + "sso-mfa/k8s/keycape/secrets-engine-openbao-client-rollout.py": "sha256:8b834e5f0353a5e11797637420609e06e7bf7de47777c7e78b774f74d4a6afbd", + "sso-mfa/k8s/keycape/test_openbao_client_config.py": "sha256:7104a73fb936aca4829ef8046e39497d0b7347d3e74810f672e4d4ddc3346457", + "sso-mfa/k8s/keycape/ensure-groups-adapter.py": "sha256:6cba5b07a9262a8e0bf445dc4095ba03b31ddc15e2efbfe374e93f4f78b6aed4", + "sso-mfa/k8s/keycape/verify-user-engine-portal.py": "sha256:ccd5106395bd5d7b4f3dbbcbad449e3793aff217d4429b5d5af9e52ab9a58103", + "sso-mfa/k8s/keycape/test_playwright_registration.py": "sha256:b97ea8619ac768f520e4058aeb50b0b1e8ef6d2e9a1a0fff932a151a3d4b61ae", + "sso-mfa/k8s/keycape/playwright-registration.py": "sha256:bf2d6b83d93629df8ddaf6c31d6c7408ae3866969d63895714df0e08a570da99", + "identity-provisioner/group_provenance_postgres.py": "sha256:2a0111e83ad7b611076a1b45634e7f698b3d2e9acc473320b4a8ba009ebd0932", + "identity-provisioner/password_setup.py": "sha256:53012fc708384fc9cd0fff4f3fa5f204ab85866db91d726457dd130799e88ca0", + "identity-provisioner/provisioner.py": "sha256:19d1b837cbafeeacb1aa815856cd68091e6702281d72b1d860230fa320e1725b", + "identity-provisioner/copy-client-secret.py": "sha256:0f1907a9f16688148aede9fceb53a55cfd0504bcb8552f158d0fa77e9ad960c8", + "identity-provisioner/group_provenance.py": "sha256:405e08eaaab7c21d618dff4db5970607806f32ab6c461effb81c737e32182b10", + "identity-provisioner/server.py": "sha256:b61c83da6c7ce20fa2790d5bb00aeca6a91dccd133526bc559ed26562f90eb29", + "security-case-types/oidc-browser-relying-party/type.yaml": "sha256:f705c64e4875e9b8e18a912fb51c135e77898926d6a451f5cb74ab3c0cbe4d1c", + "security-case-type-revisions/1.2/oidc-browser-relying-party/type.yaml": "sha256:9e60ff569fb0d860a2bbde7bbb0991a54d4b0688f62b56df0fa5d161fd624578", + "security-case-type-revisions/1.3/oidc-browser-relying-party/type.yaml": "sha256:e75fe94110ef9fb7fb18072fe2856941b33507c99cb406d36576046481485d0a", + "security-case-type-revisions/1.3/oidc-browser-relying-party/examples/forgejo.yaml": "sha256:546aad5cf26842c484fc6ba99940d56697b85531afea11872556761008923c94", + "security-cases/forgejo-netkingdom-oidc.yaml": "sha256:bcc2c6d5bae0d28242b3cdb71e74d8ca297c2afe04766b55d53597f86893351d", + "sso-mfa/k8s/keycape/descriptor-composition-1.3.candidate.json": "sha256:773daa1df72cc7cf6a6d8aa082208181ca2438cdecc9179b1bc5b1c3a09099c2", + "sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml": "sha256:7885b8c380c03ccb0198e540532ce80c791c8e86698521d7173642e0c7a56e53", + "tools/security-case-types/security_case_evidence.py": "sha256:da8efa59c52ad73283397ebe639ae259d0cb9c6348b5cb829135c24230dcdc75", + "tools/security-case-types/security_case_validator.py": "sha256:1bcc62e9bc374c711363295549f3cd5bb0b32952671ed4b08fddc7f74742959b", + "tools/security-scenario-composer/security_scenario_composer.py": "sha256:9f0cc69930aa8ee2cc3fb92236e6a99728df17b8c0fe36e1250241c38fc01c4f", + "tools/playbook-capability-contract/playbook_contract_validator.py": "sha256:2e1e0c809d4bc9d64c2d974cc23fecd1c5636785154c2554edd9191852fd926d" + }, + "ops-warden": { + "src/warden/ca.py": "sha256:d5282819c5d29386fd59a7dc46d1abdc01e99fc6838a1a6637f90868389fe557", + "src/warden/inventory.py": "sha256:9401db92d7cbf3bea962b97e83ef2c252a19c69ab94ce4836ba58f68638cb311", + "src/warden/memory.py": "sha256:ecf5f7ccabb669b56bfca3a109b10bbe8437bdd2ea30a47a4c08570f97d7be2a", + "src/warden/case_inputs.py": "sha256:1334b0cd9897e763cfea2d306e997c659f3f284ecc3f9612140c2104835da7c7", + "src/warden/audit.py": "sha256:6b5b8fe053064d3905294bfde1b691fcca8a0806c889e52a49494470d29c24a0", + "src/warden/case_type.py": "sha256:7b659b8d682863cd28df24025be4b10dd7ca3df724350a22d360c6af9615bca7", + "src/warden/vault.py": "sha256:860b8c9f498b3955b363a74dd74087b6d0c399599ef22b951a076ee33c95929f", + "src/warden/taint.py": "sha256:8c3d161d18d429d026aad715ac01e2d33e0f4e84ac03fbaea3cea15017ad39a1", + "src/warden/case_run.py": "sha256:1bc73e30ac718fd75bbaff2a739495fc051aeaec73802ac71f0583cb2d53ab0a", + "src/warden/vault_hints.py": "sha256:0d158ffcc3a93d5442df5fbe13d4c1e3b3159dd60301530bbdae6db9bc9c709e", + "src/warden/access.py": "sha256:258d45d2f84b54b2464373ad4d7d6df6ff95b8e8d60f5e85ceb2d962fcfa8a61", + "src/warden/clock_attribution.py": "sha256:5fcf07a2525a6a250442e14b6f6229f7db2a6ca02fc6aac23cdaa4c1a78c63eb", + "src/warden/case_plan.py": "sha256:9352ae8683d1181980c4ff38524582e4be448d33c85b558f60582c1e5bb5bbaa", + "src/warden/caller_identity.py": "sha256:747edfaceecd470981949253bda0c3bd2f487d40a9a2f77c2cc1eff3f34f04f7", + "src/warden/policy.py": "sha256:aac46f538e986731cd841581c91efe004b8c1940966b954ef635780a719dada4", + "src/warden/case_receipt_state.py": "sha256:a2cda7f187e77bd76d4d209505638de44a587fae0bc033ec75c23ee9ea9f73bc", + "src/warden/config.py": "sha256:8a857faa3811b00303d4d5c904d69255ebdaff3239e8516f97e6606e53b46924", + "src/warden/openbao_caller.py": "sha256:7e6d07827d00eae7de3b2367c97bdcda1a13d6559627201a4ba09a0e42d46a17", + "src/warden/doubles.py": "sha256:5460e07f5bd0f51a81d3f3c0ac84efde65ca9130b1039f94ee22ca484976a9de", + "src/warden/posture.py": "sha256:1bb60c4dd4634ea42cb130ae1325d7415adf43096906bde2515396c368256e33", + "src/warden/cli.py": "sha256:196cd829d3dbfbd2333598a983687bde1f9bcdfadef95b2fd1d237c4a5f060a9", + "src/warden/proxy.py": "sha256:69649bcf8979e4ed7f9104e927b458827a355c4846143367f4cd49c8b89b96da", + "src/warden/plan.py": "sha256:001b3197e644221344d52e6b1594eb8eae78d10e73d18ed31273505909f3916b", + "src/warden/worker.py": "sha256:d7c2b391b36033d44d8c6841b9bce18a05c74b41ef2910b91689820b6a1cb44e", + "src/warden/mask.py": "sha256:0876412d453fa84109dc8ee0468449f40cf4d3421b056f30fc205f0f59ec494b", + "src/warden/models.py": "sha256:f4100b02c5d96d537980e00d4b874159cd5822ba8219f1f533a2516912b7bd85", + "src/warden/__init__.py": "sha256:047e0feba479474235f0707a207655ecfddfb33cd4f54069134419b8ca4ea24a", + "src/warden/scorecard.py": "sha256:0fa5aef34aeb004fa7fcfabc287759cc47421ca5244c1f31fc467b22a653353c", + "src/warden/desk.py": "sha256:2499120392a5a1c0fd8f423d5b5c787c75a4efb9a986a1b7bcb85eae13423e85", + "src/warden/routing/scaffold.py": "sha256:5079c8e51f8d487eae3f322a66324bd70cefb637bb28f46c861032de8ec54aa2", + "src/warden/routing/models.py": "sha256:b85372b2572a49af62e9534f26a33963b894633c7cd43dd2a28416b8959cba3e", + "src/warden/routing/__init__.py": "sha256:e9124811ebe11ad32c98ab462b2eed634d4ddca08792981d0f353b223a239902", + "src/warden/routing/catalog.py": "sha256:5b95810df9e6102a33d3a116a096cd75292c8572bad721fe6baa772caacc9bc3", + "src/warden/scripts/ops_ssh_wrapper.py": "sha256:e8c289882f2ad439d2eb32f9a871967420fefaffe745c9271c1a2e948fbdfe50", + "src/warden/scripts/__init__.py": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + } + } + }, + "repo_manager_identifiers_sha256": "sha256:4e35fcd009c20822574fd33171176bd14a1ff2dd5af8b0bb2820954974593a2a", + "authorization": "Root accepted the exact source fixture patch for source integration. This packet adds no owner/native authority or catalog/pin promotion. No prepared script has been executed.", + "publishable": false, + "requires_allocated_manifest": true, + "publication_file_paths": [ + "sso-mfa/k8s/keycape/test_admit_1_3_type.py", + "sso-mfa/k8s/keycape/test_keycape_registration_adapter.py", + "sso-mfa/k8s/keycape/kernel-catalog.fixture.yaml", + "workplans/NK-WP-0048-security-case-types.md" + ] +}