diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/offline-results.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/offline-results.json new file mode 100644 index 00000000..92869ec5 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/offline-results.json @@ -0,0 +1,104 @@ +{ + "adversarial_refusals": { + "detail": { + "controls": [ + { + "case": "outside-tmp", + "refused": true, + "returncode": 1 + }, + { + "case": "existing-workspace", + "refused": true, + "returncode": 1 + }, + { + "case": "archive-tamper", + "refused": true, + "returncode": 1 + }, + { + "case": "repeat-verification", + "refused": true, + "returncode": 1 + }, + { + "case": "dependency-lock-tamper", + "refused": true, + "returncode": 1 + }, + { + "case": "reviewed-source-tamper", + "refused": true, + "returncode": 1 + }, + { + "case": "binary-change-before-container", + "refused": true, + "returncode": 1 + } + ], + "no_build_container_or_network_action_in_controls": true + }, + "passed": true + }, + "artifact_reproduction_current_bytes": { + "detail": { + "binary_equal": true, + "bindata_sources_each": 4, + "frontend_files_each": 628, + "public_integrity_bound_npm_packages": 1150 + }, + "passed": true + }, + "fresh_bare_binary_asset_extraction": { + "detail": { + "all_public_options_templates_exact": true, + "architecture_approval": false, + "binary_sha256": "4df429454b0289c6df76d7fd95d41394ebc286191809349b2c1e655b6be494e4", + "embedded_file_manifest_sha256": "74a0ec278ab99ac86ee434d7620229dc4a70146efd51876a1e4738d2c9f4ffdb", + "embedded_files": 2234, + "native_admission": false, + "network": "bwrap --unshare-net", + "new_cli_flag_present": true, + "no_dynamic_interpreter": true, + "no_source_assets_libraries_or_host_config_mounted": true, + "source_locks_preserved": true + }, + "passed": true + }, + "frozen_packet": { + "detail": { + "exact_patch_and_map": true, + "frozen_entries": 71 + }, + "passed": true + }, + "independent_oci_structure_and_content": { + "detail": { + "all_compressed_blobs_and_uncompressed_diffids_checked": true, + "archive_digest": "e0e74653321383e133485191f0ac5af53aafb065fb5809e20ede2808cec91539", + "complete_original_base_manifest_layers_exact": true, + "config_digest": "sha256:e9e81da43c5ea6895a95b6304337a40874e3275833be5f21fc6ffc104f79a2af", + "daemon_or_registry_used": false, + "last_layer_binary_owner_mode_and_epoch_checked": true, + "manifest_digest": "sha256:9d12779f0936b9ccdbde402a9869eaad8bb91ba724d579b6c2983e8e58dabf96", + "rootless_config_exact": true + }, + "passed": true + }, + "patch_pre_postimages": { + "detail": { + "exact_six_postimages": 6, + "no_other_paths_created": true + }, + "passed": true + }, + "reviewed_source_binding": { + "detail": { + "both_workspace_outputs_current": true, + "prior_accepted_extension_bound": true + }, + "passed": true + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-argv-execution.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-argv-execution.json new file mode 100644 index 00000000..c0053a00 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-argv-execution.json @@ -0,0 +1,65 @@ +{ + "argv": [ + "/usr/bin/bwrap", + "--unshare-net", + "--unshare-pid", + "--new-session", + "--die-with-parent", + "--ro-bind", + "/usr", + "/usr", + "--ro-bind", + "/lib", + "/lib", + "--ro-bind", + "/lib64", + "/lib64", + "--symlink", + "usr/bin", + "/bin", + "--proc", + "/proc", + "--dev", + "/dev", + "--tmpfs", + "/tmp", + "--bind", + "/tmp/apps-release-proc-argv-ndafoxcu", + "/tmp/review", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-forgejo-release-build-r1", + "/proposal", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/forgejo-required-claim-values-review-r1", + "/prior-review", + "--ro-bind", + "/tmp/apps-forgejo-release-build-r1/source", + "/source1", + "--ro-bind", + "/tmp/apps-forgejo-release-repro-r1/source", + "/source2", + "--ro-bind", + "/tmp/apps-forgejo-release-repro-r1/image.oci.tar", + "/image.oci.tar", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-boundary-test.py", + "/review-offline.py", + "--chdir", + "/tmp/review", + "--clearenv", + "--setenv", + "PATH", + "/usr/bin:/bin", + "--setenv", + "HOME", + "/tmp/home", + "--", + "/usr/bin/python3", + "-I", + "/review-offline.py" + ], + "returncode": 0, + "workspace": "/tmp/apps-release-proc-argv-ndafoxcu", + "seconds": 0.86, + "owned_pid_terminal": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-boundary-execution.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-boundary-execution.json new file mode 100644 index 00000000..a3a333a3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-boundary-execution.json @@ -0,0 +1,65 @@ +{ + "argv": [ + "/usr/bin/bwrap", + "--unshare-net", + "--unshare-pid", + "--new-session", + "--die-with-parent", + "--ro-bind", + "/usr", + "/usr", + "--ro-bind", + "/lib", + "/lib", + "--ro-bind", + "/lib64", + "/lib64", + "--symlink", + "usr/bin", + "/bin", + "--proc", + "/proc", + "--dev", + "/dev", + "--tmpfs", + "/tmp", + "--bind", + "/tmp/apps-release-proc-boundary-50k3c4n3", + "/tmp/review", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-forgejo-release-build-r1", + "/proposal", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/forgejo-required-claim-values-review-r1", + "/prior-review", + "--ro-bind", + "/tmp/apps-forgejo-release-build-r1/source", + "/source1", + "--ro-bind", + "/tmp/apps-forgejo-release-repro-r1/source", + "/source2", + "--ro-bind", + "/tmp/apps-forgejo-release-repro-r1/image.oci.tar", + "/image.oci.tar", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-boundary-test.py", + "/review-offline.py", + "--chdir", + "/tmp/review", + "--clearenv", + "--setenv", + "PATH", + "/usr/bin:/bin", + "--setenv", + "HOME", + "/tmp/home", + "--", + "/usr/bin/python3", + "-I", + "/review-offline.py" + ], + "returncode": 0, + "workspace": "/tmp/apps-release-proc-boundary-50k3c4n3", + "seconds": 0.72, + "owned_pid_terminal": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-boundary-result-attempt1.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-boundary-result-attempt1.json new file mode 100644 index 00000000..0bf33855 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/proc-boundary-result-attempt1.json @@ -0,0 +1,16 @@ +{ + "public_synthetic_fixture_only": true, + "outer_PID_and_network_namespace_prevent_real_host_visibility": true, + "shipped_sandbox": { + "returncode": 1, + "stdout": "", + "stderr": "Traceback (most recent call last):\n File \"\", line 1, in \n File \"/usr/lib/python3.12/pathlib.py\", line 862, in exists\n self.stat(follow_symlinks=follow_symlinks)\n File \"/usr/lib/python3.12/pathlib.py\", line 842, in stat\n return os.stat(self, follow_symlinks=follow_symlinks)\n ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nPermissionError: [Errno 13] Permission denied: '/proc/2/root/tmp/review/outside-build-workspace-synthetic.txt'\n" + }, + "same_command_with_only_unshare_pid_added": { + "returncode": 0, + "stdout": "False\nDENIED\n", + "stderr": "" + }, + "shipped_sandbox_proc_parent_root_escape": false, + "unshare_pid_control_denies_fixture": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/public-archives.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/public-archives.json new file mode 100644 index 00000000..fe69d799 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/public-archives.json @@ -0,0 +1,20 @@ +{ + "source_archive_sha256": { + "path": "/tmp/forgejo-independent-r1/forgejo-v11.0.3-clean.tar.gz", + "sha256": "1ddd8c926ca07d40436897971458ace7dcf1d3496a0813ab9e0d869edef2365c", + "matches_lock": true + }, + "go_archive_sha256": { + "path": "/tmp/forgejo-independent-r1/go1.24.3.linux-amd64.tar.gz", + "sha256": "3333f6ea53afa971e9078895eaa4ac7204a8c6b5c68c10e6bc9a33e8e391bdd8", + "matches_lock": true + }, + "node_archive_sha256": { + "path": "/tmp/apps-forgejo-release-build-r1/node-v22.15.0-linux-x64.tar.xz", + "sha256": "dafe2e8f82cb97de1bd10db9e2ec4c07bbf53389b0799b1e095a918951e78fd4", + "matches_lock": true + }, + "official_source_pax_commit": "b81aa4d0807cc1e2d6a2fbafd0b75c46cc0ae237", + "official_node_checksum_file_contains_exact_archive": true, + "upstream_source_go_origin_independent_prior_review": "forgejo-required-claim-values-review-r1/provenance.json (accepted prior review, not re-fetched)" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/review-offline-attempt1.py b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/review-offline-attempt1.py new file mode 100644 index 00000000..60bb04b6 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/review-offline-attempt1.py @@ -0,0 +1,211 @@ +#!/usr/bin/env python3 +"""Independent public-only review. Execute only inside the recorded bwrap boundary.""" +import hashlib +import importlib.util +import json +import os +from pathlib import Path +import shutil +import subprocess +import tarfile + +P = Path('/proposal') +OUT = Path('/tmp/review') +OUT.mkdir(exist_ok=True) +ENV = {'PATH': '/usr/bin:/bin', 'HOME': '/tmp/home', 'GIT_CONFIG_NOSYSTEM': '1', + 'GIT_CONFIG_GLOBAL': '/dev/null', 'GIT_TERMINAL_PROMPT': '0'} +Path('/tmp/home').mkdir(exist_ok=True) +results = {} + +def digest(p): + h = hashlib.sha256() + with Path(p).open('rb') as f: + for b in iter(lambda: f.read(1024*1024), b''): + h.update(b) + return h.hexdigest() + +def save(): + (OUT/'results.json').write_text(json.dumps(results, indent=2, sort_keys=True)+'\n') + +def checked(name, fn): + try: + value = fn() + results[name] = {'passed': True, 'detail': value} + except Exception as exc: + results[name] = {'passed': False, 'error': repr(exc)} + save() + raise + save() + +def frozen(): + assert digest(P/'apps-release-build-source.patch') == 'f0bcb2903592874d355e2a403de0c22aeda79b00070f30e7ea02b45106dd67fa' + assert digest(P/'SHA256SUMS.json') == 'ec499038fa9a1e612bb81ed63bd67dad2ca52a178bb7bcb89a33bb64832880bb' + entries = json.loads((P/'SHA256SUMS.json').read_text()) + for name, expected in entries.items(): + assert digest(P/name) == expected, name + return {'frozen_entries': len(entries), 'exact_patch_and_map': True} + +checked('frozen_packet', frozen) +lock = json.loads((P/'owner-source/build/forgejo/inputs.lock.json').read_text()) + +def patch(): + target = OUT/'patch-target' + target.mkdir() + shutil.copyfile(P/'preimages/Makefile', target/'Makefile') + for args in [['apply', '--check'], ['apply']]: + subprocess.run(['/usr/bin/git']+args+[str(P/'apps-release-build-source.patch')], + cwd=target, env=ENV, check=True, capture_output=True) + outputs = json.loads((P/'source-inventory.json').read_text())['owner_postimages'] + for n, expected in outputs.items(): + assert digest(target/n) == expected == digest(P/'owner-source'/n), n + actual = {str(f.relative_to(target)) for f in target.rglob('*') if f.is_file()} + assert actual == set(outputs) + return {'exact_six_postimages': len(outputs), 'no_other_paths_created': True} + +checked('patch_pre_postimages', patch) + +def source_outputs(): + prior = json.loads(Path('/prior-review/review.json').read_text()) + assert lock['patch_sha256'] == prior['candidate_patch_sha256'] + assert lock['reviewed_outputs'] == prior['reviewed_outputs'] + for source in [Path('/source1'), Path('/source2')]: + for n, expected in lock['lockfiles'].items(): + assert digest(source/n) == expected + for record in lock['reviewed_outputs']: + assert digest(source/record['path']) == record['sha256'] + return {'prior_accepted_extension_bound': True, 'both_workspace_outputs_current': True} + +checked('reviewed_source_binding', source_outputs) + +def current_artifacts(): + expected = json.loads((P/'evidence/frontend-assets.json').read_text()) + binds = json.loads((P/'evidence/binary-reproduction.json').read_text())['generated_bindata_sources_identical'] + for source in [Path('/source1'), Path('/source2')]: + actual = {str(f.relative_to(source/'public/assets')): digest(f) + for f in (source/'public/assets').rglob('*') if f.is_file()} + assert actual == expected + for n, h in binds.items(): + assert digest(source/n) == h + assert digest(source/'gitea') == '4df429454b0289c6df76d7fd95d41394ebc286191809349b2c1e655b6be494e4' + assert (source/'gitea').stat().st_size == 110936928 + packages = json.loads(Path('/source2/package-lock.json').read_text())['packages'] + for name, p in packages.items(): + if name: + assert p['resolved'].startswith('https://registry.npmjs.org/') + assert p['integrity'].startswith('sha512-') + return {'frontend_files_each': len(expected), 'bindata_sources_each': len(binds), + 'binary_equal': True, 'public_integrity_bound_npm_packages': len(packages)-1} + +checked('artifact_reproduction_current_bytes', current_artifacts) + +spec = importlib.util.spec_from_file_location('reviewed_recipe', P/'owner-source/tools/forgejo-release-build.py') +recipe = importlib.util.module_from_spec(spec) +spec.loader.exec_module(recipe) +work = OUT/'verification' +(work/'source').mkdir(parents=True) +(work/'home').mkdir() +recipe.save(work/'prepared.json', {'lock_sha256': digest(P/'owner-source/build/forgejo/inputs.lock.json'), + 'module_cache': '/tmp/review/unused-cache'}) +for n in list(lock['lockfiles']) + [r['path'] for r in lock['reviewed_outputs']] + ['gitea']: + f = work/'source'/n + f.parent.mkdir(parents=True, exist_ok=True) + f.symlink_to(Path('/source2')/n) +for folder in ['public', 'options', 'templates']: + (work/'source'/folder).symlink_to(Path('/source2')/folder) + +def verify(): + recipe.verify(work) + actual = json.loads((work/'verification.json').read_text()) + expected = json.loads((P/'evidence/verification.json').read_text()) + assert actual == expected + assert json.loads((work/'embedded-files.json').read_text()) == json.loads((P/'evidence/embedded-files.json').read_text()) + return actual + +checked('fresh_bare_binary_asset_extraction', verify) + +def controls(): + cases = [] + def refused(name, args, expected): + p = subprocess.run(['/usr/bin/python3', '-I', str(P/'owner-source/tools/forgejo-release-build.py')]+args, + env=ENV, text=True, capture_output=True) + (OUT/(name+'.log')).write_text(p.stdout+p.stderr) + assert p.returncode != 0 and expected in p.stdout+p.stderr, name + cases.append({'case': name, 'refused': True, 'returncode': p.returncode}) + refused('outside-tmp', ['prepare','--workspace','/var/new'], 'must be under /tmp') + refused('existing-workspace', ['prepare','--workspace',str(work)], 'workspace must be new') + bad = OUT/'bad-archive'; bad.write_bytes(b'public synthetic bad archive') + target = OUT/'never-created' + refused('archive-tamper', ['prepare','--workspace',str(target),'--source-archive',str(bad), + '--go-archive',str(bad),'--node-archive',str(bad)], 'digest differs') + assert not target.exists() + refused('repeat-verification', ['verify','--workspace',str(work)], 'extraction target already exists') + f = work/'source/go.mod'; f.unlink(); f.write_text('synthetic tampered lock\n') + refused('dependency-lock-tamper', ['build','--workspace',str(work)], 'digest differs') + assert not (work/'verify-go-modules-result.json').exists() + f.unlink(); f.symlink_to('/source2/go.mod') + source = work/'source'/lock['reviewed_outputs'][0]['path'] + source.unlink(); source.write_text('synthetic tampered reviewed source\n') + refused('reviewed-source-tamper', ['build','--workspace',str(work)], 'digest differs') + assert not (work/'verify-go-modules-result.json').exists() + source.unlink(); source.symlink_to(Path('/source2')/lock['reviewed_outputs'][0]['path']) + f = work/'source/gitea'; f.unlink(); f.write_bytes(b'synthetic changed executable') + refused('binary-change-before-container', ['container','--workspace',str(work)], 'digest differs') + assert not (work/'container-context').exists() + assert not Path('/home/worsch').exists() + assert not Path('/var/run/docker.sock').exists() + assert os.listdir('/tmp/home') == [] + return {'controls': cases, 'no_build_container_or_network_action_in_controls': True} + +checked('adversarial_refusals', controls) + +def oci(): + proof = json.loads((P/'evidence/container-result.json').read_text()) + assert digest('/image.oci.tar') == proof['archive_sha256'] + with tarfile.open('/image.oci.tar') as a: + index = json.load(a.extractfile('index.json')) + assert len(index['manifests']) == 1 + d = index['manifests'][0] + assert d['platform'] == {'architecture':'amd64','os':'linux'} + assert d['digest'] == proof['image_manifest_digest'] + def blob(descriptor): + name = descriptor['digest'] + raw = a.extractfile('blobs/sha256/'+name.split(':')[1]).read() + assert 'sha256:'+hashlib.sha256(raw).hexdigest() == name + assert len(raw) == descriptor['size'] + return raw + manifest = json.loads(blob(d)) + config = json.loads(blob(manifest['config'])) + assert manifest['config']['digest'] == proof['config_digest'] + original = json.loads((P/'owner-source/build/forgejo/runtime-base-config.json').read_text()) + public_manifest = json.loads((P/'evidence/runtime-public-amd64-manifest.json').read_text()) + assert manifest['layers'][:-1] == public_manifest['layers'] + import gzip + import io + for i, desc in enumerate(manifest['layers']): + raw = blob(desc) + uncompressed = gzip.decompress(raw) if raw[:2] == b'\x1f\x8b' else raw + assert 'sha256:'+hashlib.sha256(uncompressed).hexdigest() == config['rootfs']['diff_ids'][i] + if i == len(manifest['layers'])-1: + with tarfile.open(fileobj=io.BytesIO(uncompressed)) as layer: + entries = layer.getmembers() + assert {m.name.lstrip('./') for m in entries} == {'app','app/gitea','app/gitea/gitea'} + binary = next(m for m in entries if m.name.lstrip('./') == 'app/gitea/gitea') + assert binary.isfile() and binary.uid == binary.gid == 0 and binary.mode == 0o755 + assert hashlib.sha256(layer.extractfile(binary).read()).hexdigest() == '4df429454b0289c6df76d7fd95d41394ebc286191809349b2c1e655b6be494e4' + assert all(m.mtime == proof['container_epoch'] for m in entries) + assert config['rootfs']['diff_ids'][:-1] == original['rootfs']['diff_ids'] + for key in ['User','Entrypoint','Cmd','Env','WorkingDir','Volumes']: + assert config['config'].get(key) == original['config'].get(key), key + assert config['config']['User'] == '1000:1000' + labels = dict(original['config'].get('Labels',{})) + labels.update({'org.opencontainers.image.version':lock['release_version'], + 'org.opencontainers.image.revision':lock['source_commit'], + 'org.railiance.source.patch.sha256':lock['patch_sha256']}) + assert config['config']['Labels'] == labels + return {'archive_digest':proof['archive_sha256'],'manifest_digest':proof['image_manifest_digest'], + 'config_digest':proof['config_digest'],'all_compressed_blobs_and_uncompressed_diffids_checked':True, + 'complete_original_base_manifest_layers_exact':True,'rootless_config_exact':True, + 'last_layer_binary_owner_mode_and_epoch_checked':True,'daemon_or_registry_used':False} + +checked('independent_oci_structure_and_content', oci) +print(json.dumps(results, indent=2, sort_keys=True)) diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/review-offline.py b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/review-offline.py new file mode 100644 index 00000000..52cd9144 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/review-offline.py @@ -0,0 +1,214 @@ +#!/usr/bin/env python3 +"""Independent public-only review. Execute only inside the recorded bwrap boundary.""" +import hashlib +import importlib.util +import json +import os +from pathlib import Path +import shutil +import subprocess +import tarfile + +P = Path('/proposal') +OUT = Path('/tmp/review') +OUT.mkdir(exist_ok=True) +ENV = {'PATH': '/usr/bin:/bin', 'HOME': '/tmp/home', 'GIT_CONFIG_NOSYSTEM': '1', + 'GIT_CONFIG_GLOBAL': '/dev/null', 'GIT_TERMINAL_PROMPT': '0'} +Path('/tmp/home').mkdir(exist_ok=True) +results = {} + +def digest(p): + h = hashlib.sha256() + with Path(p).open('rb') as f: + for b in iter(lambda: f.read(1024*1024), b''): + h.update(b) + return h.hexdigest() + +def save(): + (OUT/'results.json').write_text(json.dumps(results, indent=2, sort_keys=True)+'\n') + +def checked(name, fn): + try: + value = fn() + results[name] = {'passed': True, 'detail': value} + except Exception as exc: + results[name] = {'passed': False, 'error': repr(exc)} + save() + raise + save() + +def frozen(): + assert digest(P/'apps-release-build-source.patch') == 'f0bcb2903592874d355e2a403de0c22aeda79b00070f30e7ea02b45106dd67fa' + assert digest(P/'SHA256SUMS.json') == 'ec499038fa9a1e612bb81ed63bd67dad2ca52a178bb7bcb89a33bb64832880bb' + entries = json.loads((P/'SHA256SUMS.json').read_text()) + for name, expected in entries.items(): + assert digest(P/name) == expected, name + return {'frozen_entries': len(entries), 'exact_patch_and_map': True} + +checked('frozen_packet', frozen) +lock = json.loads((P/'owner-source/build/forgejo/inputs.lock.json').read_text()) + +def patch(): + target = OUT/'patch-target' + target.mkdir() + shutil.copyfile(P/'preimages/Makefile', target/'Makefile') + for args in [['apply', '--check'], ['apply']]: + subprocess.run(['/usr/bin/git']+args+[str(P/'apps-release-build-source.patch')], + cwd=target, env=ENV, check=True, capture_output=True) + outputs = json.loads((P/'source-inventory.json').read_text())['owner_postimages'] + for n, expected in outputs.items(): + assert digest(target/n) == expected == digest(P/'owner-source'/n), n + actual = {str(f.relative_to(target)) for f in target.rglob('*') if f.is_file()} + assert actual == set(outputs) + return {'exact_six_postimages': len(outputs), 'no_other_paths_created': True} + +checked('patch_pre_postimages', patch) + +def source_outputs(): + prior = json.loads(Path('/prior-review/review.json').read_text()) + assert lock['patch_sha256'] == prior['candidate_patch_sha256'] + assert lock['reviewed_outputs'] == prior['reviewed_outputs'] + for source in [Path('/source1'), Path('/source2')]: + for n, expected in lock['lockfiles'].items(): + assert digest(source/n) == expected + for record in lock['reviewed_outputs']: + assert digest(source/record['path']) == record['sha256'] + return {'prior_accepted_extension_bound': True, 'both_workspace_outputs_current': True} + +checked('reviewed_source_binding', source_outputs) + +def current_artifacts(): + expected = json.loads((P/'evidence/frontend-assets.json').read_text()) + binds = json.loads((P/'evidence/binary-reproduction.json').read_text())['generated_bindata_sources_identical'] + for source in [Path('/source1'), Path('/source2')]: + actual = {str(f.relative_to(source/'public/assets')): digest(f) + for f in (source/'public/assets').rglob('*') if f.is_file()} + assert actual == expected + for n, h in binds.items(): + assert digest(source/n) == h + assert digest(source/'gitea') == '4df429454b0289c6df76d7fd95d41394ebc286191809349b2c1e655b6be494e4' + assert (source/'gitea').stat().st_size == 110936928 + packages = json.loads(Path('/source2/package-lock.json').read_text())['packages'] + for name, p in packages.items(): + if name: + assert p['resolved'].startswith('https://registry.npmjs.org/') + assert p['integrity'].startswith('sha512-') + return {'frontend_files_each': len(expected), 'bindata_sources_each': len(binds), + 'binary_equal': True, 'public_integrity_bound_npm_packages': len(packages)-1} + +checked('artifact_reproduction_current_bytes', current_artifacts) + +spec = importlib.util.spec_from_file_location('reviewed_recipe', P/'owner-source/tools/forgejo-release-build.py') +recipe = importlib.util.module_from_spec(spec) +spec.loader.exec_module(recipe) +work = OUT/'verification' +(work/'source').mkdir(parents=True) +(work/'home').mkdir() +recipe.save(work/'prepared.json', {'lock_sha256': digest(P/'owner-source/build/forgejo/inputs.lock.json'), + 'module_cache': '/tmp/review/unused-cache'}) +for n in list(lock['lockfiles']) + [r['path'] for r in lock['reviewed_outputs']] + ['gitea']: + f = work/'source'/n + f.parent.mkdir(parents=True, exist_ok=True) + f.symlink_to(Path('/source2')/n) +for folder in ['public', 'options', 'templates']: + (work/'source'/folder).symlink_to(Path('/source2')/folder) + +def verify(): + recipe.verify(work) + actual = json.loads((work/'verification.json').read_text()) + expected = json.loads((P/'evidence/verification.json').read_text()) + assert actual == expected + assert json.loads((work/'embedded-files.json').read_text()) == json.loads((P/'evidence/embedded-files.json').read_text()) + return actual + +checked('fresh_bare_binary_asset_extraction', verify) + +def controls(): + cases = [] + def refused(name, args, expected): + p = subprocess.run(['/usr/bin/python3', '-I', str(P/'owner-source/tools/forgejo-release-build.py')]+args, + env=ENV, text=True, capture_output=True) + (OUT/(name+'.log')).write_text(p.stdout+p.stderr) + assert p.returncode != 0 and expected in p.stdout+p.stderr, name + cases.append({'case': name, 'refused': True, 'returncode': p.returncode}) + refused('outside-tmp', ['prepare','--workspace','/var/new'], 'must be under /tmp') + refused('existing-workspace', ['prepare','--workspace',str(work)], 'workspace must be new') + bad = OUT/'bad-archive'; bad.write_bytes(b'public synthetic bad archive') + target = OUT/'never-created' + refused('archive-tamper', ['prepare','--workspace',str(target),'--source-archive',str(bad), + '--go-archive',str(bad),'--node-archive',str(bad)], 'digest differs') + assert not target.exists() + refused('repeat-verification', ['verify','--workspace',str(work)], 'extraction target already exists') + f = work/'source/go.mod'; f.unlink(); f.write_text('synthetic tampered lock\n') + refused('dependency-lock-tamper', ['build','--workspace',str(work)], 'digest differs') + assert not (work/'verify-go-modules-result.json').exists() + f.unlink(); f.symlink_to('/source2/go.mod') + source = work/'source'/lock['reviewed_outputs'][0]['path'] + source.unlink(); source.write_text('synthetic tampered reviewed source\n') + refused('reviewed-source-tamper', ['build','--workspace',str(work)], 'digest differs') + assert not (work/'verify-go-modules-result.json').exists() + source.unlink(); source.symlink_to(Path('/source2')/lock['reviewed_outputs'][0]['path']) + f = work/'source/gitea'; f.unlink(); f.write_bytes(b'synthetic changed executable') + refused('binary-change-before-container', ['container','--workspace',str(work)], 'digest differs') + assert not (work/'container-context').exists() + assert not Path('/home/worsch').exists() + assert not Path('/var/run/docker.sock').exists() + assert os.listdir('/tmp/home') == [] + return {'controls': cases, 'no_build_container_or_network_action_in_controls': True} + +checked('adversarial_refusals', controls) + +def oci(): + proof = json.loads((P/'evidence/container-result.json').read_text()) + assert digest('/image.oci.tar') == proof['archive_sha256'] + with tarfile.open('/image.oci.tar') as a: + index = json.load(a.extractfile('index.json')) + assert len(index['manifests']) == 1 + d = index['manifests'][0] + assert d['platform'] == {'architecture':'amd64','os':'linux'} + assert d['digest'] == proof['image_manifest_digest'] + def blob(descriptor): + name = descriptor['digest'] + raw = a.extractfile('blobs/sha256/'+name.split(':')[1]).read() + assert 'sha256:'+hashlib.sha256(raw).hexdigest() == name + assert len(raw) == descriptor['size'] + return raw + manifest = json.loads(blob(d)) + config = json.loads(blob(manifest['config'])) + assert manifest['config']['digest'] == proof['config_digest'] + original = json.loads((P/'owner-source/build/forgejo/runtime-base-config.json').read_text()) + public_manifest = json.loads((P/'evidence/runtime-public-amd64-manifest.json').read_text()) + assert manifest['layers'][:-1] == public_manifest['layers'] + import gzip + import io + for i, desc in enumerate(manifest['layers']): + raw = blob(desc) + uncompressed = gzip.decompress(raw) if raw[:2] == b'\x1f\x8b' else raw + assert 'sha256:'+hashlib.sha256(uncompressed).hexdigest() == config['rootfs']['diff_ids'][i] + if i == len(manifest['layers'])-1: + with tarfile.open(fileobj=io.BytesIO(uncompressed)) as layer: + entries = layer.getmembers() + assert {m.name.lstrip('./') for m in entries} == {'app','app/gitea','app/gitea/gitea'} + binary = next(m for m in entries if m.name.lstrip('./') == 'app/gitea/gitea') + assert binary.isfile() and binary.uid == binary.gid == 0 and binary.mode == 0o755 + assert hashlib.sha256(layer.extractfile(binary).read()).hexdigest() == '4df429454b0289c6df76d7fd95d41394ebc286191809349b2c1e655b6be494e4' + # BuildKit rewrites future timestamps down to the epoch; + # older source/base timestamps are correctly preserved. + assert binary.mtime == proof['source_epoch'] + assert all(m.mtime <= proof['container_epoch'] for m in entries) + assert config['rootfs']['diff_ids'][:-1] == original['rootfs']['diff_ids'] + for key in ['User','Entrypoint','Cmd','Env','WorkingDir','Volumes']: + assert config['config'].get(key) == original['config'].get(key), key + assert config['config']['User'] == '1000:1000' + labels = dict(original['config'].get('Labels',{})) + labels.update({'org.opencontainers.image.version':lock['release_version'], + 'org.opencontainers.image.revision':lock['source_commit'], + 'org.railiance.source.patch.sha256':lock['patch_sha256']}) + assert config['config']['Labels'] == labels + return {'archive_digest':proof['archive_sha256'],'manifest_digest':proof['image_manifest_digest'], + 'config_digest':proof['config_digest'],'all_compressed_blobs_and_uncompressed_diffids_checked':True, + 'complete_original_base_manifest_layers_exact':True,'rootless_config_exact':True, + 'last_layer_binary_owner_mode_and_epoch_checked':True,'daemon_or_registry_used':False} + +checked('independent_oci_structure_and_content', oci) +print(json.dumps(results, indent=2, sort_keys=True)) diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/status.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/status.json new file mode 100644 index 00000000..d9aa42e9 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1/status.json @@ -0,0 +1,7 @@ +{ + "state": "complete", + "verdict": "changes-required", + "all_owned_handles_terminal": true, + "live_handles": [], + "source_integrated": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/README.md b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/README.md new file mode 100644 index 00000000..c29ca8b2 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/README.md @@ -0,0 +1,37 @@ +The exact six-path Apps build-source r2 is accepted for source integration. +Patch SHA256 is +`b7ad8f8fd908532800f4e7eb0f7ad85d77e21a0b729cb5115ade3d5fe3e4acd8`. +All postimages match, and the only source change from the reviewed r1 is adding +`--unshare-pid` to the build sandbox. Locks, application extension, release +version, build commands, runtime base and artifact handling are unchanged. + +The exact r2 `sandbox()` closes APPSBUILD-R1-F01. In an outer PID/network-isolated +public-only test, the exact r1 sandbox reads a synthetic unrelated process argv +canary; the exact r2 sandbox returns `DENIED`. Namespace inode checks confirm r2 +creates a new PID namespace and r1 shares its parent's. The environment remains +closed, the working directory is correct, host HOME and Docker socket are absent, +and the synthetic helper exits normally. No real host process arguments, +credentials, native endpoint, Docker daemon, registry or network were accessed. + +The initial r2 reviewer harness assumed the Python child would be PID1. Bubblewrap +correctly uses a PID1 reaper and the child is PID2. That failure and original +script are retained. The corrected test verifies the namespace inode differs, +which directly checks isolation without assuming an implementation-specific PID. +No candidate correction or additional build success is attributed to this +reviewer-only refinement. + +The r1 source packet and independent changes-required review remain frozen and +hash-exact. Their complete frontend, bindata, static executable and OCI artifact +proof remains evidence for the original r1 build profile. No full r2 frontend, +backend or image build was run, and no reproduced r2 binary/image is claimed. +The bounded namespace correction does not change compiler/build/artifact inputs; +no new evidence gap warrants another expensive build for source integration. + +Source integration acceptance supplies no formal owner assent, architecture +acceptance, operational image admission or deployment authority. All operational +gaps listed in the frozen r1 review remain: authenticated Access Engine decision, +private runtime secret input, current operation/inverse sessions, authenticated +journal, persisted application-state proof, writer exclusion, exact re-freeze, +browser/group/login probes, capacity and rollout. Canonical owner edits and any +publication remain with the root assignment; this reviewer changed only its own +review packets and public /tmp test workspaces. diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/SHA256SUMS.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/SHA256SUMS.json new file mode 100644 index 00000000..af5d1f1b --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/SHA256SUMS.json @@ -0,0 +1,14 @@ +{ + "README.md": "855805fc29c204052e1c5aa48f5531e547434bffbe72bcc9ba836be7ce278777", + "execution-attempt1.json": "df7fd4535c5c58f3285cf6258f1bf3f0dd5c398a0c973238f9ee1fd04042d09b", + "execution.json": "e0c9d4124107927274076df039d5651faa5a0177df1d9e0e20577fce612d7cc1", + "inputs.json": "9f4fdddccdfe5df01e93ff96895f411b4bfde42b47990de4d9a648abbcd6740f", + "namespace-review-attempt1.log": "eff8c6f66f4958f1fe19ae1a2f7d60ef2cc14fcacb8863fde5e27b0fbd31adbe", + "namespace-review.log": "232827ebb83148b32c67d81b943011f955c0a279604b6c7f764737d22e08c1e5", + "probe-records.json": "8dafa7916a75f57c4c367f02c2626bd4a784c07d73ded1ca72ed6d1174571945", + "results.json": "232827ebb83148b32c67d81b943011f955c0a279604b6c7f764737d22e08c1e5", + "review-namespace-refinement-attempt1.py": "5b3e0afc6e114457371e3914ba1f5ebf3b81e2753eb214e39dba3c21ed164d44", + "review-namespace-refinement.py": "b7526163dcd4bc68bec2f05ae9712134a833a740e6b7696c02e28a95599b07c6", + "review.json": "6f016d53a7ec9ece2f9da9686e76127c52d17066f2b3d371628832ac9537ac5c", + "status.json": "1f0bd85f6283d6da8a212852ce400e5d8a36fe457eced76805356423f56c0c64" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/execution-attempt1.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/execution-attempt1.json new file mode 100644 index 00000000..bf8153fe --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/execution-attempt1.json @@ -0,0 +1,59 @@ +{ + "argv": [ + "/usr/bin/bwrap", + "--unshare-net", + "--unshare-pid", + "--new-session", + "--die-with-parent", + "--ro-bind", + "/usr", + "/usr", + "--ro-bind", + "/lib", + "/lib", + "--ro-bind", + "/lib64", + "/lib64", + "--symlink", + "usr/bin", + "/bin", + "--proc", + "/proc", + "--dev", + "/dev", + "--tmpfs", + "/tmp", + "--bind", + "/tmp/apps-release-r2-independent-ponkb90l", + "/tmp/review", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-forgejo-release-build-r1", + "/proposal", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-forgejo-release-build-r2", + "/proposal2", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1", + "/r1-review", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/review-namespace-refinement.py", + "/review.py", + "--chdir", + "/tmp/review", + "--clearenv", + "--setenv", + "PATH", + "/usr/bin:/bin", + "--setenv", + "HOME", + "/tmp/home", + "--", + "/usr/bin/python3", + "-I", + "/review.py" + ], + "returncode": 1, + "workspace": "/tmp/apps-release-r2-independent-ponkb90l", + "seconds": 0.29, + "owned_pid_terminal": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/execution.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/execution.json new file mode 100644 index 00000000..35c6d043 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/execution.json @@ -0,0 +1,59 @@ +{ + "argv": [ + "/usr/bin/bwrap", + "--unshare-net", + "--unshare-pid", + "--new-session", + "--die-with-parent", + "--ro-bind", + "/usr", + "/usr", + "--ro-bind", + "/lib", + "/lib", + "--ro-bind", + "/lib64", + "/lib64", + "--symlink", + "usr/bin", + "/bin", + "--proc", + "/proc", + "--dev", + "/dev", + "--tmpfs", + "/tmp", + "--bind", + "/tmp/apps-release-r2-independent-attempt2-yd5yg8m8", + "/tmp/review", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-forgejo-release-build-r1", + "/proposal", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-forgejo-release-build-r2", + "/proposal2", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r1", + "/r1-review", + "--ro-bind", + "/home/worsch/the-custodian/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/review-namespace-refinement.py", + "/review.py", + "--chdir", + "/tmp/review", + "--clearenv", + "--setenv", + "PATH", + "/usr/bin:/bin", + "--setenv", + "HOME", + "/tmp/home", + "--", + "/usr/bin/python3", + "-I", + "/review.py" + ], + "returncode": 0, + "workspace": "/tmp/apps-release-r2-independent-attempt2-yd5yg8m8", + "seconds": 0.51, + "owned_pid_terminal": true +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/inputs.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/inputs.json new file mode 100644 index 00000000..8196603f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/inputs.json @@ -0,0 +1,11 @@ +{ + "apps-release-build-source.patch": "b7ad8f8fd908532800f4e7eb0f7ad85d77e21a0b729cb5115ade3d5fe3e4acd8", + "failed-patch-generation-r1.patch": "64c86ac86cf78715535b096cbf47204586a5c26b7e9c993cce2c136cb5ae2cee", + "owner-source/Makefile": "572d36e2dd3dee6321a5f6c4726f83991031672be5eb3480ae6173f8ce50ccdd", + "owner-source/build/forgejo/README.md": "c3d37b8e62a99c351b8630a31f875fb8f4afbf54ec2488460066c88148f76fa8", + "owner-source/build/forgejo/inputs.lock.json": "29f329b204a2a5f72084b50d59e8445486ff4799450097c6f3908c74e87a233a", + "owner-source/build/forgejo/required-claim-values.patch": "f2788b3f2bf84dbc0f94e232b6c9614a864b8123c09f9e44703d50d5e1b53257", + "owner-source/build/forgejo/runtime-base-config.json": "bc5a3df111729582faadebd01d126ba769e2b65d0c62f306f6bc79f4e562452b", + "owner-source/tools/forgejo-release-build.py": "7e28d9bd5adefaece96eb1d31a23e128ec8f448958e45d22467bf7acf476a9ba", + "source-refinement.json": "1e96b866284908299b6363c0ddd1363181bd8513ae63eb178967f636de008972" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/probe-records.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/probe-records.json new file mode 100644 index 00000000..7d439260 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/probe-records.json @@ -0,0 +1,119 @@ +{ + "r1": { + "argv": [ + "bwrap", + "--unshare-net", + "--ro-bind", + "/usr", + "/usr", + "--ro-bind", + "/lib", + "/lib", + "--ro-bind", + "/lib64", + "/lib64", + "--symlink", + "usr/bin", + "/bin", + "--proc", + "/proc", + "--dev", + "/dev", + "--tmpfs", + "/tmp", + "--bind", + "/tmp/review/sandbox-work", + "/tmp/review/sandbox-work", + "--ro-bind", + "/tmp/review/sandbox-work/cache", + "/tmp/review/sandbox-work/cache", + "--chdir", + "/tmp/review/sandbox-work/source", + "--", + "env", + "-i", + "PATH=/usr/bin:/bin", + "HOME=/tmp/review/sandbox-work/empty-home", + "GOMODCACHE=/tmp/review/sandbox-work/cache", + "LC_ALL=C", + "/usr/bin/python3", + "-I", + "-c", + "import pathlib,sys,os,json; p=pathlib.Path(sys.argv[1]); print(json.dumps({\"parent_argv\": p.read_text() if p.exists() else \"DENIED\", \"self_pid\":os.getpid(),\"pid_namespace\":os.readlink(\"/proc/self/ns/pid\"),\"cwd\":os.getcwd(),\"host_home_present\":pathlib.Path(\"/home/worsch\").exists(),\"docker_socket_present\":pathlib.Path(\"/var/run/docker.sock\").exists(),\"environment\":dict(os.environ)}))", + "/proc/5/cmdline" + ], + "result": { + "parent_argv": "/usr/bin/python3\u0000-I\u0000-c\u0000import sys;sys.stdin.read()\u0000PUBLIC-R2-SYNTHETIC-ARGV-CANARY\u0000", + "self_pid": 7, + "pid_namespace": "pid:[4026532379]", + "cwd": "/tmp/review/sandbox-work/source", + "host_home_present": false, + "docker_socket_present": false, + "environment": { + "PATH": "/usr/bin:/bin", + "HOME": "/tmp/review/sandbox-work/empty-home", + "GOMODCACHE": "/tmp/review/sandbox-work/cache", + "LC_ALL": "C" + } + } + }, + "r2": { + "argv": [ + "bwrap", + "--unshare-net", + "--unshare-pid", + "--ro-bind", + "/usr", + "/usr", + "--ro-bind", + "/lib", + "/lib", + "--ro-bind", + "/lib64", + "/lib64", + "--symlink", + "usr/bin", + "/bin", + "--proc", + "/proc", + "--dev", + "/dev", + "--tmpfs", + "/tmp", + "--bind", + "/tmp/review/sandbox-work", + "/tmp/review/sandbox-work", + "--ro-bind", + "/tmp/review/sandbox-work/cache", + "/tmp/review/sandbox-work/cache", + "--chdir", + "/tmp/review/sandbox-work/source", + "--", + "env", + "-i", + "PATH=/usr/bin:/bin", + "HOME=/tmp/review/sandbox-work/empty-home", + "GOMODCACHE=/tmp/review/sandbox-work/cache", + "LC_ALL=C", + "/usr/bin/python3", + "-I", + "-c", + "import pathlib,sys,os,json; p=pathlib.Path(sys.argv[1]); print(json.dumps({\"parent_argv\": p.read_text() if p.exists() else \"DENIED\", \"self_pid\":os.getpid(),\"pid_namespace\":os.readlink(\"/proc/self/ns/pid\"),\"cwd\":os.getcwd(),\"host_home_present\":pathlib.Path(\"/home/worsch\").exists(),\"docker_socket_present\":pathlib.Path(\"/var/run/docker.sock\").exists(),\"environment\":dict(os.environ)}))", + "/proc/5/cmdline" + ], + "result": { + "parent_argv": "DENIED", + "self_pid": 2, + "pid_namespace": "pid:[4026532441]", + "cwd": "/tmp/review/sandbox-work/source", + "host_home_present": false, + "docker_socket_present": false, + "environment": { + "PATH": "/usr/bin:/bin", + "HOME": "/tmp/review/sandbox-work/empty-home", + "GOMODCACHE": "/tmp/review/sandbox-work/cache", + "LC_ALL": "C" + } + } + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/review-namespace-refinement-attempt1.py b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/review-namespace-refinement-attempt1.py new file mode 100644 index 00000000..43f6f9a4 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/review-namespace-refinement-attempt1.py @@ -0,0 +1,66 @@ +"""Bounded exact r2 review, run only in outer public-only PID/net bwrap.""" +from pathlib import Path +import hashlib, importlib.util, json, os, shutil, subprocess +out=Path('/tmp/review');results={} +def sha(p):return hashlib.sha256(Path(p).read_bytes()).hexdigest() +old=Path('/proposal');new=Path('/proposal2') +assert sha(new/'apps-release-build-source.patch')=='b7ad8f8fd908532800f4e7eb0f7ad85d77e21a0b729cb5115ade3d5fe3e4acd8' +assert sha(old/'apps-release-build-source.patch')=='f0bcb2903592874d355e2a403de0c22aeda79b00070f30e7ea02b45106dd67fa' +assert sha('/r1-review/SHA256SUMS.json')=='9a2266ffa638ce771a5cc014e93b53c8e465270d351c502cf42c9c586409f7c9' +for root in [old,Path('/r1-review')]: + for name,h in json.loads((root/'SHA256SUMS.json').read_text()).items():assert sha(root/name)==h +manifest=json.loads((new/'source-refinement.json').read_text()) +expected=manifest['owner_postimages'];paths={str(p.relative_to(new/'owner-source')) for p in (new/'owner-source').rglob('*') if p.is_file()} +assert paths==set(expected) and len(paths)==6 +changed=[] +for n,h in expected.items(): + assert sha(new/'owner-source'/n)=='{}'.format(h.removeprefix('sha256:')) + if (old/'owner-source'/n).read_bytes()!=(new/'owner-source'/n).read_bytes():changed.append(n) +assert changed==['tools/forgejo-release-build.py'] +before=(old/'owner-source/tools/forgejo-release-build.py').read_bytes() +after=(new/'owner-source/tools/forgejo-release-build.py').read_bytes() +assert before.count(b"return ['bwrap','--unshare-net','--ro-bind'")==1 +assert before.replace(b"return ['bwrap','--unshare-net','--ro-bind'",b"return ['bwrap','--unshare-net','--unshare-pid','--ro-bind'")==after +results['exact_refinement']={'old_review_and_inputs_preserved':True,'six_paths':6,'only_change':'sandbox adds --unshare-pid','unchanged_locks_archives_patch_release_and_runtime_base':True} +env={'PATH':'/usr/bin:/bin','HOME':'/tmp/home','GIT_CONFIG_NOSYSTEM':'1','GIT_CONFIG_GLOBAL':'/dev/null'} +Path('/tmp/home').mkdir() +target=out/'patch';target.mkdir();shutil.copyfile(old/'preimages/Makefile',target/'Makefile') +for args in [['apply','--check'],['apply']]: + p=subprocess.run(['/usr/bin/git']+args+[str(new/'apps-release-build-source.patch')],cwd=target,env=env,capture_output=True,text=True) + assert p.returncode==0,p.stderr +assert {str(p.relative_to(target)) for p in target.rglob('*') if p.is_file()}==paths +for n,h in expected.items():assert sha(target/n)==h.removeprefix('sha256:') +results['patch_exact_six_postimages']=True +def load(name,path): + s=importlib.util.spec_from_file_location(name,path);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m +r1=load('r1',old/'owner-source/tools/forgejo-release-build.py') +r2=load('r2',new/'owner-source/tools/forgejo-release-build.py') +work=out/'sandbox-work';(work/'source').mkdir(parents=True);(work/'cache').mkdir() +inner={'PATH':'/usr/bin:/bin','HOME':str(work/'empty-home'),'GOMODCACHE':str(work/'cache')} +helper=subprocess.Popen(['/usr/bin/python3','-I','-c','import sys;sys.stdin.read()','PUBLIC-R2-SYNTHETIC-ARGV-CANARY'],stdin=subprocess.PIPE,env=env) +probe=['/usr/bin/python3','-I','-c', + 'import pathlib,sys,os,json; p=pathlib.Path(sys.argv[1]); print(json.dumps({"parent_argv": p.read_text() if p.exists() else "DENIED", "self_pid":os.getpid(),"cwd":os.getcwd(),"host_home_present":pathlib.Path("/home/worsch").exists(),"docker_socket_present":pathlib.Path("/var/run/docker.sock").exists(),"environment":dict(os.environ)}))', + '/proc/'+str(helper.pid)+'/cmdline'] +try: + records={} + for name,m in [('r1',r1),('r2',r2)]: + args=m.sandbox(work,inner)+probe + p=subprocess.run(args,env=env,capture_output=True,text=True) + assert p.returncode==0,(name,p.stderr) + records[name]={'argv':args,'result':json.loads(p.stdout)} + assert 'PUBLIC-R2-SYNTHETIC-ARGV-CANARY' in records['r1']['result']['parent_argv'] + assert records['r2']['result']['parent_argv']=='DENIED' + assert records['r2']['result']['self_pid']==1 + assert not records['r2']['result']['host_home_present'] + assert not records['r2']['result']['docker_socket_present'] + assert records['r2']['result']['cwd']==str(work/'source') + assert records['r2']['result']['environment']==inner + results['namespace_fix']=records +finally: + helper.stdin.close();helper.wait(timeout=10) +results['synthetic_helper_terminal_returncode']=helper.returncode +results['full_r2_build_or_image_build_performed']=False +results['r1_artifact_evidence_retains_r1_profile']=True +results['APPSBUILD-R1-F01_closed_for_exact_r2']=True +(out/'results.json').write_text(json.dumps(results,indent=2,sort_keys=True)+'\n') +print(json.dumps(results,indent=2,sort_keys=True)) diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/review-namespace-refinement.py b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/review-namespace-refinement.py new file mode 100644 index 00000000..8cfe1712 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/review-namespace-refinement.py @@ -0,0 +1,68 @@ +"""Bounded exact r2 review, run only in outer public-only PID/net bwrap.""" +from pathlib import Path +import hashlib, importlib.util, json, os, shutil, subprocess +out=Path('/tmp/review');results={} +def sha(p):return hashlib.sha256(Path(p).read_bytes()).hexdigest() +old=Path('/proposal');new=Path('/proposal2') +assert sha(new/'apps-release-build-source.patch')=='b7ad8f8fd908532800f4e7eb0f7ad85d77e21a0b729cb5115ade3d5fe3e4acd8' +assert sha(old/'apps-release-build-source.patch')=='f0bcb2903592874d355e2a403de0c22aeda79b00070f30e7ea02b45106dd67fa' +assert sha('/r1-review/SHA256SUMS.json')=='9a2266ffa638ce771a5cc014e93b53c8e465270d351c502cf42c9c586409f7c9' +for root in [old,Path('/r1-review')]: + for name,h in json.loads((root/'SHA256SUMS.json').read_text()).items():assert sha(root/name)==h +manifest=json.loads((new/'source-refinement.json').read_text()) +expected=manifest['owner_postimages'];paths={str(p.relative_to(new/'owner-source')) for p in (new/'owner-source').rglob('*') if p.is_file()} +assert paths==set(expected) and len(paths)==6 +changed=[] +for n,h in expected.items(): + assert sha(new/'owner-source'/n)=='{}'.format(h.removeprefix('sha256:')) + if (old/'owner-source'/n).read_bytes()!=(new/'owner-source'/n).read_bytes():changed.append(n) +assert changed==['tools/forgejo-release-build.py'] +before=(old/'owner-source/tools/forgejo-release-build.py').read_bytes() +after=(new/'owner-source/tools/forgejo-release-build.py').read_bytes() +assert before.count(b"return ['bwrap','--unshare-net','--ro-bind'")==1 +assert before.replace(b"return ['bwrap','--unshare-net','--ro-bind'",b"return ['bwrap','--unshare-net','--unshare-pid','--ro-bind'")==after +results['exact_refinement']={'old_review_and_inputs_preserved':True,'six_paths':6,'only_change':'sandbox adds --unshare-pid','unchanged_locks_archives_patch_release_and_runtime_base':True} +env={'PATH':'/usr/bin:/bin','HOME':'/tmp/home','GIT_CONFIG_NOSYSTEM':'1','GIT_CONFIG_GLOBAL':'/dev/null'} +Path('/tmp/home').mkdir() +target=out/'patch';target.mkdir();shutil.copyfile(old/'preimages/Makefile',target/'Makefile') +for args in [['apply','--check'],['apply']]: + p=subprocess.run(['/usr/bin/git']+args+[str(new/'apps-release-build-source.patch')],cwd=target,env=env,capture_output=True,text=True) + assert p.returncode==0,p.stderr +assert {str(p.relative_to(target)) for p in target.rglob('*') if p.is_file()}==paths +for n,h in expected.items():assert sha(target/n)==h.removeprefix('sha256:') +results['patch_exact_six_postimages']=True +def load(name,path): + s=importlib.util.spec_from_file_location(name,path);m=importlib.util.module_from_spec(s);s.loader.exec_module(m);return m +r1=load('r1',old/'owner-source/tools/forgejo-release-build.py') +r2=load('r2',new/'owner-source/tools/forgejo-release-build.py') +work=out/'sandbox-work';(work/'source').mkdir(parents=True);(work/'cache').mkdir() +inner={'PATH':'/usr/bin:/bin','HOME':str(work/'empty-home'),'GOMODCACHE':str(work/'cache'),'LC_ALL':'C'} +helper=subprocess.Popen(['/usr/bin/python3','-I','-c','import sys;sys.stdin.read()','PUBLIC-R2-SYNTHETIC-ARGV-CANARY'],stdin=subprocess.PIPE,env=env) +probe=['/usr/bin/python3','-I','-c', + 'import pathlib,sys,os,json; p=pathlib.Path(sys.argv[1]); print(json.dumps({"parent_argv": p.read_text() if p.exists() else "DENIED", "self_pid":os.getpid(),"pid_namespace":os.readlink("/proc/self/ns/pid"),"cwd":os.getcwd(),"host_home_present":pathlib.Path("/home/worsch").exists(),"docker_socket_present":pathlib.Path("/var/run/docker.sock").exists(),"environment":dict(os.environ)}))', + '/proc/'+str(helper.pid)+'/cmdline'] +try: + records={} + for name,m in [('r1',r1),('r2',r2)]: + args=m.sandbox(work,inner)+probe + p=subprocess.run(args,env=env,capture_output=True,text=True) + assert p.returncode==0,(name,p.stderr) + records[name]={'argv':args,'result':json.loads(p.stdout)} + (out/'probe-records.json').write_text(json.dumps(records,indent=2)+'\n') + assert 'PUBLIC-R2-SYNTHETIC-ARGV-CANARY' in records['r1']['result']['parent_argv'] + assert records['r2']['result']['parent_argv']=='DENIED' + assert records['r1']['result']['pid_namespace']==os.readlink('/proc/self/ns/pid') + assert records['r2']['result']['pid_namespace']!=os.readlink('/proc/self/ns/pid') + assert not records['r2']['result']['host_home_present'] + assert not records['r2']['result']['docker_socket_present'] + assert records['r2']['result']['cwd']==str(work/'source') + assert records['r2']['result']['environment']==inner + results['namespace_fix']=records +finally: + helper.stdin.close();helper.wait(timeout=10) +results['synthetic_helper_terminal_returncode']=helper.returncode +results['full_r2_build_or_image_build_performed']=False +results['r1_artifact_evidence_retains_r1_profile']=True +results['APPSBUILD-R1-F01_closed_for_exact_r2']=True +(out/'results.json').write_text(json.dumps(results,indent=2,sort_keys=True)+'\n') +print(json.dumps(results,indent=2,sort_keys=True)) diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/status.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/status.json new file mode 100644 index 00000000..9f0884f3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-independent-review-r2/status.json @@ -0,0 +1,7 @@ +{ + "state": "complete", + "verdict": "accept", + "source_integration_accepted": true, + "all_owned_handles_terminal": true, + "live_handles": [] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/consistency.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/consistency.json new file mode 100644 index 00000000..b6bcc318 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/consistency.json @@ -0,0 +1,426 @@ +{ + "repo_slug": "railiance-apps", + "repo_path": "/home/worsch/railiance-apps", + "source_revision": "c29408ae6747158a639dc876e6d7492680675658", + "source_revision_reason": null, + "issues": [ + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager warning: .repo-classification.yaml: category is project but slug is not prj-*; not every category:project is a prj- repo", + "file_path": ".repo-classification.yaml", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager missing: README.md: README.md is required for flavor project", + "file_path": "README.md", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager warning: workplans/: repository uses more than one workplan prefix: ['RAILIANCE-WP', 'RAPPS-WP']", + "file_path": "workplans/", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-1: task id 'RAILIANCE-WP-0004-I01' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-1", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-2: task id 'RAILIANCE-WP-0004-I02' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-2", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-3: task id 'RAILIANCE-WP-0004-I03' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-3", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-4: task id 'RAILIANCE-WP-0004-I04' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-4", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-5: task id 'RAILIANCE-WP-0004-I05' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-5", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-6: task id 'RAILIANCE-WP-0004-I06' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-6", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-7: task id 'RAILIANCE-WP-0004-I07' is not accepted by the canon kind registry", + "file_path": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-7", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-31", + "message": "[workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md] id 'RAILIANCE-WP-0004-I01' matches no kind in the canon work-record type registry \u2014 unregistered species become sidetracks needing manual reintegration (work-record-types_v0.1)", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-31", + "message": "[workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md] id 'RAILIANCE-WP-0004-I02' matches no kind in the canon work-record type registry \u2014 unregistered species become sidetracks needing manual reintegration (work-record-types_v0.1)", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-31", + "message": "[workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md] id 'RAILIANCE-WP-0004-I03' matches no kind in the canon work-record type registry \u2014 unregistered species become sidetracks needing manual reintegration (work-record-types_v0.1)", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-31", + "message": "[workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md] id 'RAILIANCE-WP-0004-I04' matches no kind in the canon work-record type registry \u2014 unregistered species become sidetracks needing manual reintegration (work-record-types_v0.1)", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-31", + "message": "[workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md] id 'RAILIANCE-WP-0004-I05' matches no kind in the canon work-record type registry \u2014 unregistered species become sidetracks needing manual reintegration (work-record-types_v0.1)", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-31", + "message": "[workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md] id 'RAILIANCE-WP-0004-I06' matches no kind in the canon work-record type registry \u2014 unregistered species become sidetracks needing manual reintegration (work-record-types_v0.1)", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-31", + "message": "[workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md] id 'RAILIANCE-WP-0004-I07' matches no kind in the canon work-record type registry \u2014 unregistered species become sidetracks needing manual reintegration (work-record-types_v0.1)", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-33", + "message": "WORK-RECORDS.md is missing or stale \u2014 regenerate via fix-consistency (CUST-WP-0061-T04 generated work-record index)", + "file_path": "WORK-RECORDS.md", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-39", + "message": "Wait task 'RAPPS-WP-0015-T04' in workplan 'RAPPS-WP-0015' has neither depends_on, needs_human: true, blocked_on: message-from:\u2026 nor wait_until \u2014 unqualified wait", + "file_path": "workplans/RAPPS-WP-0015-coulomb-personal-content-release.md#RAPPS-WP-0015-T04", + "db_id": "", + "file_value": "wait", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-20", + "message": "Workplan dependency target 'KEY-WP-0038' is not linked to State Hub", + "file_path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md", + "db_id": "", + "file_value": "KEY-WP-0038", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-39", + "message": "Human wait task 'RAPPS-WP-0016-T04' in workplan 'RAPPS-WP-0016' has needs_human: true without decision_id \u2014 unrouted human gate", + "file_path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md#RAPPS-WP-0016-T04", + "db_id": "", + "file_value": "needs_human: true", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-11", + "message": "Derived task 'RAPPS-WP-0016-T06' is absent from this projection", + "file_path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md#RAPPS-WP-0016-T06", + "db_id": "08ab8921-7801-5309-b84b-bc2a3ceea1e4", + "file_value": "", + "db_value": "", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-11", + "message": "Derived task 'RAPPS-WP-0016-T07' is absent from this projection", + "file_path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md#RAPPS-WP-0016-T07", + "db_id": "786d6584-6db1-5a10-9324-d7b94db0df94", + "file_value": "", + "db_value": "", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-11", + "message": "Derived task 'RAPPS-WP-0016-T08' is absent from this projection", + "file_path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md#RAPPS-WP-0016-T08", + "db_id": "4ab8a5e7-ab32-5ee2-aaf2-6da246d1b0c8", + "file_value": "", + "db_value": "", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-11", + "message": "Derived task 'RAPPS-WP-0016-T09' is absent from this projection", + "file_path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md#RAPPS-WP-0016-T09", + "db_id": "d3804638-c73d-5b9f-a456-4262f62f9e6b", + "file_value": "", + "db_value": "", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-20", + "message": "Workplan dependency target 'RPF-WP-0058' is not linked to State Hub", + "file_path": "workplans/RAPPS-WP-0017-reuse-private-reader-release.md", + "db_id": "", + "file_value": "RPF-WP-0058", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-20", + "message": "Workplan dependency target 'REUSE-WP-0025' is not linked to State Hub", + "file_path": "workplans/RAPPS-WP-0017-reuse-private-reader-release.md", + "db_id": "", + "file_value": "REUSE-WP-0025", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0006@retired-20260826' (id=1960b22b\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "1960b22b-82ae-4b67-9fff-397bd38bdd65", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0005@retired-20260826' (id=685f1c18\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "685f1c18-33c0-400d-a2b1-e1dae0f27c3e", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0009@retired-20260826' (id=21c3fcdc\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "21c3fcdc-f014-4858-8028-0ac3038212b7", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0011@retired-20260826' (id=98cf42ae\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "98cf42ae-9b64-4736-97e1-bae325ded1f9", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0008@retired-20260826' (id=41b9deea\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "41b9deea-a935-4372-8916-b3981336f597", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0018@retired-20260826' (id=1b9af4e8\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "1b9af4e8-7579-5141-837b-c736b85204a0", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0007@retired-20260826' (id=7da18dd8\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "7da18dd8-76b9-4a70-b9d7-de541afc65c0", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'railiance-wp-0010@retired-20260826' (id=a4f301bb\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "a4f301bb-3f49-450a-8dbd-5cf6a16b8e0f", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-28", + "message": "2 unread inbox message(s) older than 3 day(s): the-custodian:23172cb2, the-custodian:51e9eace", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-28", + "message": "2 unread message(s) lack thread_id for supersession tracking: the-custodian:23172cb2, the-custodian:51e9eace", + "file_path": "", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RAIL-AP-WP-0001' uses prefix 'RAIL-AP-WP' but repo canonical prefix is 'RAPPS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260605-RAIL-AP-WP-0001-gitea-container-registry.md", + "db_id": "", + "file_value": "RAIL-AP-WP-0001", + "db_value": "RAPPS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RAILIANCE-WP-0002' uses prefix 'RAILIANCE-WP' but repo canonical prefix is 'RAPPS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260702-railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md", + "db_id": "", + "file_value": "RAILIANCE-WP-0002", + "db_value": "RAPPS-WP", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'RAILIANCE-WP-0004' uses prefix 'RAILIANCE-WP' but repo canonical prefix is 'RAPPS-WP' \u2014 new plans must conform", + "file_path": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md", + "db_id": "", + "file_value": "RAILIANCE-WP-0004", + "db_value": "RAPPS-WP", + "fixable": false + } + ], + "fixes_applied": [ + "bindings: synced 20/20", + "C-17 cleared: pushed 1 backlogged commit(s)", + "C-33 fixed: regenerated WORK-RECORDS.md", + "C-11 fixed: task 'RAPPS-WP-0016-T06' \u2192 08ab8921\u2026", + "C-11 fixed: task 'RAPPS-WP-0016-T07' \u2192 786d6584\u2026", + "C-11 fixed: task 'RAPPS-WP-0016-T08' \u2192 4ab8a5e7\u2026", + "C-11 fixed: task 'RAPPS-WP-0016-T09' \u2192 d3804638\u2026", + "brief: .custodian-brief.md updated", + "push: pushed" + ], + "summary": { + "fail": 0, + "automation_error": 0, + "warn": 32, + "info": 8 + }, + "result": "warn" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/consistency.stderr.txt b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/consistency.stderr.txt new file mode 100644 index 00000000..3345563f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/consistency.stderr.txt @@ -0,0 +1 @@ +WARN: git commit failed for writeback: Generated-only commits rejected: staged diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/identifier-preview.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/identifier-preview.json new file mode 100644 index 00000000..fed4fb51 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/identifier-preview.json @@ -0,0 +1,74 @@ +{ + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": false, + "repo": "railiance-apps", + "namespace": "helixforge", + "assignments": [ + { + "kind": "task", + "record_id": "RAPPS-WP-0016-T06", + "uuid": "08ab8921-7801-5309-b84b-bc2a3ceea1e4", + "path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md" + }, + { + "kind": "task", + "record_id": "RAPPS-WP-0016-T07", + "uuid": "786d6584-6db1-5a10-9324-d7b94db0df94", + "path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md" + }, + { + "kind": "task", + "record_id": "RAPPS-WP-0016-T08", + "uuid": "4ab8a5e7-ab32-5ee2-aaf2-6da246d1b0c8", + "path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md" + }, + { + "kind": "task", + "record_id": "RAPPS-WP-0016-T09", + "uuid": "d3804638-c73d-5b9f-a456-4262f62f9e6b", + "path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md" + } + ], + "historical_invalid_identifiers": [ + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I01", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-1" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I02", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-2" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I03", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-3" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I04", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-4" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I05", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-5" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I06", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-6" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I07", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-7" + } + ], + "historical_identity_collisions": [], + "files_changed": [ + "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md" + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/preimage.md b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/preimage.md new file mode 100644 index 00000000..a1615e38 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/preimage.md @@ -0,0 +1,170 @@ +--- +id: RAPPS-WP-0016 +type: workplan +title: "Forgejo sign-in through NetKingdom, before the forge closes" +domain: infotech +repo: railiance-apps +status: active +flavor: implementation +owner: claude-code +topic_slug: railiance +created: "2026-10-08" +updated: "2026-10-08" +depends_on: + - KEY-WP-0038 +related_repos: + - prj-forgejo-org-refactor + - key-cape + - railiance-platform +state_hub_workstream_id: "f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b" +--- + +# RAPPS-WP-0016 - Forgejo sign-in through NetKingdom, before the forge closes + +## Why + +`forgejo.coulomb.social` is closing: private by default, no anonymous access +(prj-forgejo-org-refactor ORGREF-WP-0002, decision +`decisions/forge-visibility-policy.md`). The founder's condition is that sign-in +runs through NetKingdom first. railiance-apps owns the Forgejo Helm release +(`docs/forgejo-on-railiance01.md`: S5 Helm release, ingress, operator Makefile), +so the Forgejo side lands here. This plan is ORGREF-WP-0002-T05. The NetKingdom +side is key-cape `KEY-WP-0038`. + +## Boundaries + +- **Founder guardrail:** tighten gradually; never lock anyone out; never risk + assets; never reach a state that is hard to repair. Every step keeps the + current sign-in path working until the new one is proven. +- **No visibility change** in this plan. Repositories, packages and + `REQUIRE_SIGNIN_VIEW` are ORGREF-WP-0002-T08. +- **Configuration in git.** The authentication source is declared in + `helm/forgejo-values.yaml` (`gitea.oauth`), with its secret drawn from an + ExternalSecret over OpenBao. No click-ops, and no secret value in git. +- Open registration is already disabled (`service.DISABLE_REGISTRATION: true`). + This plan keeps it that way. + +## Tasks + +```task +id: RAPPS-WP-0016-T01 +status: done +priority: high +state_hub_task_id: "98004ed0-83e6-5f6e-9b18-15b8b2aec2e7" +``` + +### T01 — Make the local administrator a sealed break-glass + +Before anything about sign-in changes: confirm the local administrator account +works, keep its credential only in OpenBao, and document recovery (who, how, +where it is logged) in `docs/forgejo-on-railiance01.md`. Verify one break-glass +sign-in and record it without the credential. + +Acceptance: a recorded break-glass sign-in, with the recovery path written down. +This is the "never lock ourselves out" floor for every later step. + +Done 2026-10-17: founder sealed `forgejo_admin` into OpenBao +`platform/workloads/forgejo/break-glass-admin` (version 1) and verified a local +sign-in (HTTP 200, site admin): `docs/evidence/2026-10-17-forgejo-breakglass-signin.json`. +Recovery path: `docs/forgejo-on-railiance01.md` § Break-glass administrator. + +```task +id: RAPPS-WP-0016-T02 +status: wait +depends_on: [RAPPS-WP-0016-T01, KEY-WP-0038-T02] +blocking_reason: "Break-glass done (T01); needs the NetKingdom client registered with its secret in custody (KEY-WP-0038-T02)." +priority: high +state_hub_task_id: "13cd3aec-c87d-5d3f-a421-39d8ff131edd" +``` + +### T02 — Add the NetKingdom authentication source + +- an ExternalSecret delivering the `forgejo` client secret from OpenBao to a + Secret in the `forgejo` namespace. Custody path is + `platform/workloads/keycape/forgejo`, field `CLIENT_SECRET`, read by ESO through + Kubernetes-auth role `external-secrets-keycape-forgejo-forgejo`, which carries + only policy `workload-kv-read-keycape-forgejo-forgejo` (net-kingdom 074b3a0; + replaces the earlier `platform/workloads/forgejo/netkingdom-oidc-client` proposal). The + SA/SecretStore/ExternalSecret shape follows the NK-WP-0048 + `deliver-consumer-secret` receipt contract + (`docs/evidence/nk48-t16-owner-review/owner-review-railiance-apps.json`) +- `gitea.oauth`: name `netkingdom` (must match the redirect URI registered in + key-cape), provider `openidConnect`, auto-discovery from + `https://kc.coulomb.social/.well-known/openid-configuration`, scopes + `openid profile email groups`, group-claim name `groups` +- `oauth2_client` settings: no automatic account creation for unknown subjects; + account linking to existing local accounts by username after a successful + local sign-in (so the founder and agent accounts keep their history) +- Helm upgrade with the previous revision noted for rollback + +Local password sign-in stays enabled. + +Acceptance: the "Sign in with netkingdom" option appears. Local sign-in still +works. Rollback is one `helm rollback` to the noted revision. + +```task +id: RAPPS-WP-0016-T03 +status: wait +depends_on: [RAPPS-WP-0016-T02] +blocking_reason: "Linking and team mapping follow a working authentication source." +priority: high +state_hub_task_id: "81f072aa-c316-511e-a2cd-21dd1b1d0a00" +``` + +### T03 — Link accounts and map groups to teams + +- The founder links their account through NetKingdom (MFA), then signs in again + through NetKingdom only and sees the same repositories, organisations and + admin rights. +- Map NetKingdom groups (names agreed in KEY-WP-0038-T01) to organisation teams: + owners and readers at least. Create the read-only teams that + ORGREF-WP-0002-T06 consumers will use. +- Apply KEY-WP-0038-T03's decision on agents and services: NetKingdom sign-in, or + scoped tokens bound to service identities. + +Acceptance: founder and one agent work through NetKingdom; group-to-team mapping +verified by adding and removing one test membership; break-glass still works. + +```task +id: RAPPS-WP-0016-T04 +status: wait +depends_on: [RAPPS-WP-0016-T03] +needs_human: true +blocking_reason: "Restricting local password sign-in is a founder decision once NetKingdom sign-in is proven." +priority: medium +state_hub_task_id: "32c54737-c40f-5fde-9b91-163f8dcb0068" +``` + +### T04 — Decide on local password sign-in + +Once NetKingdom sign-in has been used for a while without problems, the founder +decides whether local password sign-in is turned off for everyone except +break-glass. This is not required to close the forge; it is the next tightening +step, taken separately. + +```task +id: RAPPS-WP-0016-T05 +status: wait +depends_on: [RAPPS-WP-0016-T02] +blocking_reason: "Waits for net-kingdom's answer to the Apps 1.3 needs-change record (the-custodian docs/changes/netkingdom-target-2026-10-17/nk48-1.3-owner-review/owner-review-railiance-apps.json: RAPPS-1.3-C1..C3) and the re-frozen 1.3 candidate." +priority: medium +state_hub_task_id: "728786c9-f1f9-5983-a6a4-dea21faf67f5" +``` + +### T05 — Apps owner seams for NK-WP-0048 consumer steps + +Implement the real Apps capabilities behind the `deliver-consumer-secret` and +`hand-over` adapters, as owner-run paths (option C): `owner_apply` / +`owner_remove` emitting `netkingdom.consumer-secret-delivery.v1` receipts from the +T02 objects; a consumer verifier that observes Forgejo sign-in and the T03 +positive/negative group probes; and a committed-evidence hand-over receipt store. +See the owner-review record for the contract. + +Acceptance: receipts produced from the live T02/T03 run validate against the +adapters' checks with no value-bearing keys. + +## Also in scope: stale node credential + +The k3s `registries.yaml` on railiance01 still holds a login for the frozen Gitea +host `92.205.130.254` (ORGREF-WP-0002-T02). Coordinate its removal with the node +owner when ORGREF-WP-0002-T06 adds the forge registry login, in the same change. diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/preparation.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/preparation.json new file mode 100644 index 00000000..748698af --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/preparation.json @@ -0,0 +1,13 @@ +{ + "owner": "railiance-apps", + "base": "git:944b30ad63ab054cc24617e374e177d34cd572da", + "existing_task_blocks_preserved": 5, + "new_tasks": { + "RAPPS-WP-0016-T06": "done, pending exact independent review acceptance before source apply", + "RAPPS-WP-0016-T07": "progress", + "RAPPS-WP-0016-T08": "progress", + "RAPPS-WP-0016-T09": "todo" + }, + "canonical_edits": false, + "native_actions": false +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/projection.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/projection.json new file mode 100644 index 00000000..9c0e0e66 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/projection.json @@ -0,0 +1,179 @@ +{ + "ok": true, + "status": "applied", + "repo_slug": "railiance-apps", + "commit": "c29408ae6747158a639dc876e6d7492680675658", + "requests": 2, + "elapsed_ms": 6799.5, + "git": { + "upstream": "origin/main", + "behind": 0, + "ahead": 0 + }, + "identifiers": { + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "railiance-apps", + "namespace": "helixforge", + "assignments": [], + "historical_invalid_identifiers": [ + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I01", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-1" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I02", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-2" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I03", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-3" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I04", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-4" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I05", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-5" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I06", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-6" + }, + { + "kind": "task", + "id": "RAILIANCE-WP-0004-I07", + "source": "workplans/archived/260702-railiance-apps-WP-0004-app-deployment-improvements.md#task-block-7" + } + ], + "historical_identity_collisions": [], + "files_changed": [] + }, + "receipt": { + "schema": "state-hub.repository-projection-reconcile.v1", + "instance_role": "primary", + "instance_label": "railiance01", + "expected_commit": "c29408ae6747158a639dc876e6d7492680675658", + "derived_commit": "c29408ae6747158a639dc876e6d7492680675658", + "outcome": { + "schema": "state-hub.projection-reset.v1", + "repo_slug": "railiance-apps", + "commit": "c29408ae6747158a639dc876e6d7492680675658", + "status": "applied", + "counts": { + "created": 0, + "updated": 20, + "retired": 0, + "refused": 0, + "released": 0, + "created_tasks": 0, + "updated_tasks": 6, + "cancelled_tasks": 0, + "created_edges": 0, + "removed_edges": 0, + "unresolved_edges": 0, + "external_edges": 5 + }, + "created": [], + "updated": [ + "RAIL-AP-WP-0001", + "RAILIANCE-WP-0002", + "RAILIANCE-WP-0004", + "RAPPS-WP-0001", + "RAPPS-WP-0002", + "RAPPS-WP-0003", + "RAPPS-WP-0004", + "RAPPS-WP-0005", + "RAPPS-WP-0006", + "RAPPS-WP-0007", + "RAPPS-WP-0008", + "RAPPS-WP-0009", + "RAPPS-WP-0010", + "RAPPS-WP-0011", + "RAPPS-WP-0012", + "RAPPS-WP-0013", + "RAPPS-WP-0014", + "RAPPS-WP-0015", + "RAPPS-WP-0016", + "RAPPS-WP-0017" + ], + "retired": [], + "released": [], + "created_tasks": [], + "updated_tasks": [ + "RAPPS-WP-0016-T01", + "RAPPS-WP-0016-T05", + "RAPPS-WP-0016-T06", + "RAPPS-WP-0016-T07", + "RAPPS-WP-0016-T08", + "RAPPS-WP-0016-T09" + ], + "cancelled_tasks": [], + "created_edges": [], + "removed_edges": [], + "unresolved_edges": [], + "external_edges": [ + { + "workplan": "RAPPS-WP-0016", + "from": "RAPPS-WP-0016-T02", + "target": "RAPPS-WP-0016-T01", + "relationship_type": "starts_after", + "from_workplan_id": "f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b", + "from_task_id": "13cd3aec-c87d-5d3f-a421-39d8ff131edd", + "to_workplan_id": null, + "to_task_id": "98004ed0-83e6-5f6e-9b18-15b8b2aec2e7" + }, + { + "workplan": "RAPPS-WP-0016", + "from": "RAPPS-WP-0016-T02", + "target": "KEY-WP-0038-T02", + "relationship_type": "starts_after", + "from_workplan_id": "f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b", + "from_task_id": "13cd3aec-c87d-5d3f-a421-39d8ff131edd", + "to_workplan_id": null, + "to_task_id": "ddcfb482-8f33-5c81-9ce8-84be8fa5dc30" + }, + { + "workplan": "RAPPS-WP-0016", + "from": "RAPPS-WP-0016-T04", + "target": "RAPPS-WP-0016-T03", + "relationship_type": "starts_after", + "from_workplan_id": "f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b", + "from_task_id": "32c54737-c40f-5fde-9b91-163f8dcb0068", + "to_workplan_id": null, + "to_task_id": "81f072aa-c316-511e-a2cd-21dd1b1d0a00" + }, + { + "workplan": "RAPPS-WP-0016", + "from": "RAPPS-WP-0016-T05", + "target": "RAPPS-WP-0016-T02", + "relationship_type": "starts_after", + "from_workplan_id": "f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b", + "from_task_id": "728786c9-f1f9-5983-a6a4-dea21faf67f5", + "to_workplan_id": null, + "to_task_id": "13cd3aec-c87d-5d3f-a421-39d8ff131edd" + }, + { + "workplan": "RAPPS-WP-0016", + "from": "RAPPS-WP-0016-T03", + "target": "RAPPS-WP-0016-T02", + "relationship_type": "starts_after", + "from_workplan_id": "f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b", + "from_task_id": "81f072aa-c316-511e-a2cd-21dd1b1d0a00", + "to_workplan_id": null, + "to_task_id": "13cd3aec-c87d-5d3f-a421-39d8ff131edd" + } + ], + "refused": [], + "notes": [] + } + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/projection.stderr.txt b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/projection.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/.custodian-brief.md.worktree b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/.custodian-brief.md.worktree new file mode 100644 index 00000000..1f9b6fae --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/.custodian-brief.md.worktree @@ -0,0 +1,47 @@ + +# Custodian Brief — railiance-apps + +**Domain:** financials +**Last synced:** 2026-10-17 10:13 UTC +**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* + +## Active Workstreams + +### Forgejo sign-in through NetKingdom, before the forge closes +Progress: 1/5 done | workplan_id: `f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b` + +**Open tasks:** +- ! T01 — Make the local administrator a sealed break-glass `13cd3aec` + *(wait: Break-glass done (T01); needs the NetKingdom client registered with its secret in custody (KEY-WP-0038-T02).)* +- ! T02 — Add the NetKingdom authentication source `81f072aa` + *(wait: Linking and team mapping follow a working authentication source.)* +- ! T03 — Link accounts and map groups to teams `32c54737` + *(wait: Restricting local password sign-in is a founder decision once NetKingdom sign-in is proven.)* +- ! T04 — Decide on local password sign-in `728786c9` + *(wait: Waits for net-kingdom's answer to the Apps 1.3 needs-change record (the-custodian docs/changes/netkingdom-target-2026-10-17/nk48-1.3-owner-review/owner-review-railiance-apps.json: RAPPS-1.3-C1..C3) and the re-frozen 1.3 candidate.)* + +### Coulomb-social persistent personal workspace release +Progress: 3/4 done | workplan_id: `79abacf8-361e-51ab-829d-40dec8e142d1` + +**Open tasks:** +- ! T04 — Personal sign-in and content acceptance `8bc4962a` + +### Deploy and recover the first invited Vergabe company pilot +Progress: 2/3 done | workplan_id: `c7fdaa7e-cab8-5d1d-86c2-f1aad7927c57` + +**Open tasks:** +- ! Demonstrate restart, isolated restore, rollback and operating ownership `dd069c6d` + *(wait: Await populated two-user/document workflow, coherent PostgreSQL/media/issue-state off-host recovery point, isolated restored workflow, rollback evidence and support ownership. September 25 proves database restore and restart only.)* + +## Inbox Hygiene + +**Stale unread:** 2 message(s) older than 3 day(s) — triage at session start. +**Missing thread_id:** 2 unread message(s) lack supersession chains. + +--- +## MCP Orientation (when available) + +If the state-hub MCP server is reachable, call: +`get_domain_summary("financials")` +This provides richer cross-domain context. +If the MCP call fails, use this file as your orientation source. diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/WORK-RECORDS.md.worktree b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/WORK-RECORDS.md.worktree new file mode 100644 index 00000000..89c6d25c --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/WORK-RECORDS.md.worktree @@ -0,0 +1,48 @@ +# Work Records — railiance-apps + +> Generated by `statehub fix-consistency` (CUST-WP-0061-T04, work-record +> stage 3). Do not edit by hand — edit the source file/block listed for +> each record and re-run fix-consistency to refresh this index. Archived +> workplans are omitted; closed decisions/intakes/engagements stay listed +> so recently-resolved work is still visible. [auto] + +| Kind | ID | Status | Lane | Source | +| --- | --- | --- | --- | --- | +| workplan | RAPPS-WP-0001 | finished | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | +| workplan | RAPPS-WP-0002 | finished | — | workplans/RAPPS-WP-0002-railiance01-activity-core-backup-automation.md | +| workplan | RAPPS-WP-0003 | finished | — | workplans/RAPPS-WP-0003-policy-nexus-production-binding.md | +| workplan | RAPPS-WP-0014 | blocked | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | +| workplan | RAPPS-WP-0015 | active | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | +| workplan | RAPPS-WP-0016 | active | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| workplan | RAPPS-WP-0017 | finished | — | workplans/RAPPS-WP-0017-reuse-private-reader-release.md | +| task | RAPPS-WP-0001-T01 | done | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | +| task | RAPPS-WP-0001-T02 | done | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | +| task | RAPPS-WP-0001-T03 | done | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | +| task | RAPPS-WP-0001-T04 | done | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | +| task | RAPPS-WP-0001-T05 | done | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | +| task | RAPPS-WP-0002-T01 | done | — | workplans/RAPPS-WP-0002-railiance01-activity-core-backup-automation.md | +| task | RAPPS-WP-0002-T02 | done | — | workplans/RAPPS-WP-0002-railiance01-activity-core-backup-automation.md | +| task | RAPPS-WP-0002-T03 | done | — | workplans/RAPPS-WP-0002-railiance01-activity-core-backup-automation.md | +| task | RAPPS-WP-0002-T04 | done | — | workplans/RAPPS-WP-0002-railiance01-activity-core-backup-automation.md | +| task | RAPPS-WP-0002-T05 | done | — | workplans/RAPPS-WP-0002-railiance01-activity-core-backup-automation.md | +| task | RAPPS-WP-0002-T06 | done | — | workplans/RAPPS-WP-0002-railiance01-activity-core-backup-automation.md | +| task | RAPPS-WP-0002-T07 | done | — | workplans/RAPPS-WP-0002-railiance01-activity-core-backup-automation.md | +| task | RAPPS-WP-0003-T01 | done | — | workplans/RAPPS-WP-0003-policy-nexus-production-binding.md | +| task | RAPPS-WP-0003-T02 | done | — | workplans/RAPPS-WP-0003-policy-nexus-production-binding.md | +| task | RAPPS-WP-0003-T03 | done | — | workplans/RAPPS-WP-0003-policy-nexus-production-binding.md | +| task | RAPPS-WP-0003-T04 | done | — | workplans/RAPPS-WP-0003-policy-nexus-production-binding.md | +| task | RAPPS-WP-0014-T01 | done | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | +| task | RAPPS-WP-0014-T02 | done | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | +| task | RAPPS-WP-0014-T03 | wait | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | +| task | RAPPS-WP-0015-T01 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | +| task | RAPPS-WP-0015-T02 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | +| task | RAPPS-WP-0015-T03 | done | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | +| task | RAPPS-WP-0015-T04 | wait | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | +| task | RAPPS-WP-0016-T01 | done | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| task | RAPPS-WP-0016-T02 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| task | RAPPS-WP-0016-T03 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| task | RAPPS-WP-0016-T04 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| task | RAPPS-WP-0016-T05 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| task | RAPPS-WP-0017-T01 | done | — | workplans/RAPPS-WP-0017-reuse-private-reader-release.md | +| task | RAPPS-WP-0017-T02 | done | — | workplans/RAPPS-WP-0017-reuse-private-reader-release.md | +| task | RAPPS-WP-0017-T03 | done | — | workplans/RAPPS-WP-0017-reuse-private-reader-release.md | diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/originals.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/originals.json new file mode 100644 index 00000000..415362e8 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-backup/originals.json @@ -0,0 +1,10 @@ +[ + { + "path": ".custodian-brief.md", + "index": "100644 1f9b6fae4362945f96aa9a2a9647be9c83d8296a 0\t.custodian-brief.md" + }, + { + "path": "WORK-RECORDS.md", + "index": "100644 89c6d25cfe29035a2e0ad71113c31b89338b0cc3 0\tWORK-RECORDS.md" + } +] diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-commit.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-commit.json new file mode 100644 index 00000000..9cd398f5 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-commit.json @@ -0,0 +1,37 @@ +{ + "exit_code": 0, + "commit": "c29408ae6747158a639dc876e6d7492680675658", + "base": "944b30ad63ab054cc24617e374e177d34cd572da", + "files": [ + { + "path": "Makefile", + "sha256": "572d36e2dd3dee6321a5f6c4726f83991031672be5eb3480ae6173f8ce50ccdd" + }, + { + "path": "build/forgejo/README.md", + "sha256": "c3d37b8e62a99c351b8630a31f875fb8f4afbf54ec2488460066c88148f76fa8" + }, + { + "path": "build/forgejo/inputs.lock.json", + "sha256": "29f329b204a2a5f72084b50d59e8445486ff4799450097c6f3908c74e87a233a" + }, + { + "path": "build/forgejo/required-claim-values.patch", + "sha256": "f2788b3f2bf84dbc0f94e232b6c9614a864b8123c09f9e44703d50d5e1b53257" + }, + { + "path": "build/forgejo/runtime-base-config.json", + "sha256": "bc5a3df111729582faadebd01d126ba769e2b65d0c62f306f6bc79f4e562452b" + }, + { + "path": "tools/forgejo-release-build.py", + "sha256": "7e28d9bd5adefaece96eb1d31a23e128ec8f448958e45d22467bf7acf476a9ba" + }, + { + "path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md", + "sha256": "0ac8db087247bf980339ef8661a26eeb817af82391e3e85038be773fe3c6fb3a" + } + ], + "stdout": "[main c29408a] Add pinned Forgejo release build path and track operational integration\n 7 files changed, 980 insertions(+), 1 deletion(-)\n create mode 100644 build/forgejo/README.md\n create mode 100644 build/forgejo/inputs.lock.json\n create mode 100644 build/forgejo/required-claim-values.patch\n create mode 100644 build/forgejo/runtime-base-config.json\n create mode 100644 tools/forgejo-release-build.py\n", + "stderr": "" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-inputs.json b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-inputs.json new file mode 100644 index 00000000..7075932d --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/apps-release-source-integration-r1/publication-inputs.json @@ -0,0 +1,35 @@ +{ + "owner": "railiance-apps", + "base_revision": "944b30ad63ab054cc24617e374e177d34cd572da", + "message": "Add pinned Forgejo release build path and track operational integration", + "files": [ + { + "path": "Makefile", + "sha256": "572d36e2dd3dee6321a5f6c4726f83991031672be5eb3480ae6173f8ce50ccdd" + }, + { + "path": "build/forgejo/README.md", + "sha256": "c3d37b8e62a99c351b8630a31f875fb8f4afbf54ec2488460066c88148f76fa8" + }, + { + "path": "build/forgejo/inputs.lock.json", + "sha256": "29f329b204a2a5f72084b50d59e8445486ff4799450097c6f3908c74e87a233a" + }, + { + "path": "build/forgejo/required-claim-values.patch", + "sha256": "f2788b3f2bf84dbc0f94e232b6c9614a864b8123c09f9e44703d50d5e1b53257" + }, + { + "path": "build/forgejo/runtime-base-config.json", + "sha256": "bc5a3df111729582faadebd01d126ba769e2b65d0c62f306f6bc79f4e562452b" + }, + { + "path": "tools/forgejo-release-build.py", + "sha256": "7e28d9bd5adefaece96eb1d31a23e128ec8f448958e45d22467bf7acf476a9ba" + }, + { + "path": "workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md", + "sha256": "0ac8db087247bf980339ef8661a26eeb817af82391e3e85038be773fe3c6fb3a" + } + ] +} diff --git a/docs/changes/netkingdom-target-2026-10-17/close-progress.json b/docs/changes/netkingdom-target-2026-10-17/close-progress.json new file mode 100644 index 00000000..443d9b6a --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/close-progress.json @@ -0,0 +1,14 @@ +{ + "workplan_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52", + "id": "054a23cc-c353-447b-bf78-6b28a2d95bb9", + "topic_id": null, + "task_id": "87637402-02f1-57c1-8fbc-4141598af8e3", + "decision_id": null, + "event_type": "note", + "summary": "CUST-WP-0080 checkpoint: published NetKingdom70f408ca (Pg backend/T21 and real-SOPS/T37), RepoManager9ebde0a9(T05 accepted), Secretsc59bbf56(WP15), StateHub51bc70d1 receiver and086d79a2 policy-compatible preflight/T08. Independent82canonicalprovisioner/65actualSOPS cases; realPg21oracles and migration10SQLshapeoracles passed with exactcleanup. Verified66NK/STATE plus9RMGR/Secrets taskbindings/remotes;4 coordination_receipt events attach ownerwaits withoutmessages/wakes. ClusterWP18 remainsunpublished behind correct historicalguard. PinnedCIimage c802... inspected233files86packagemetadata; exactpackagedreuse-valuesdryrun passes8identities/3imageonlychanges. Stable STATE95T06 proposal revision4/digest63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32 recordedpending/notexecuted; migration/recovery/unpricedriskexplicit. Scanner public-ID falsepositive retained then corrected explicitfieldformat; supervisionenum normalization retained. No liveupgrade, registraractivation, actualcredentialrecovery, rotation or authoritypromotion. All16nativeTSA gatesopen.", + "detail": null, + "author": "codex", + "session_id": null, + "created_at": "2026-10-16T23:48:26.768137Z", + "workstream_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/close-verification.json b/docs/changes/netkingdom-target-2026-10-17/close-verification.json new file mode 100644 index 00000000..b8861be4 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/close-verification.json @@ -0,0 +1,16 @@ +{ + "published_commit": "f8c7dfa2a9c7919879b62c77eb39582b3e23654e", + "remote_exact": true, + "required_consistency": { + "fail": 0, + "automation_error": 0, + "warn": 8, + "info": 4 + }, + "authoritative_projection": "applied_primary_railiance01_exact_revision", + "custodian_tasks_verified": 6, + "owner_tasks_verified": 75, + "preexisting_staged_brief_work_records_and_six_assessments_preserved": true, + "rollout_proposal_pending_not_executed": true, + "native_gates_closed": 0 +} diff --git a/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/.custodian-brief.md.worktree b/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/.custodian-brief.md.worktree new file mode 100644 index 00000000..f5952182 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/.custodian-brief.md.worktree @@ -0,0 +1,67 @@ + +# Custodian Brief — secrets-engine + +**Domain:** infotech +**Last synced:** 2026-10-16 19:07 UTC +**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* + +## Active Workstreams + +### Design and prove task-scoped protected OpenBao execution +Progress: 1/3 done | workplan_id: `5e38aecc-85ca-5f55-94c6-9fbb08604819` + +**Open tasks:** +- ! Define the exact mediated execution contract `b2f0d462` + *(wait: Independent Platform mediated-contract review and identity/approval/PDP owner returns remain required; D3 wrapped primitive source is implemented, no native entitlement is inferred.)* +- ! Implement and prove one native metadata action `5f8f7c41` + +### Constrain PDP transport and authenticate decision responses +Progress: 1/3 done | workplan_id: `7252469d-d7a5-5c18-8911-b511b8c6a736` + +**Open tasks:** +- ! Verify the admitted native consumer and rotation path `85aa4c78` + *(wait: Requires reviewed verification-key admission, source enforcement and exact native rollout receipt; no production trust change is proposed yet.)* +- ► Implement independently anchored responder authentication `877782e5` + +### Activate native Claude credential delivery for Glas +Progress: 2/3 done | workplan_id: `40ccc3b4-d046-5a58-8649-e7935f45c974` + +**Open tasks:** +- ! Activate the approved native lane and verify real owner delivery `f8069c8a` + *(wait: Next owner action: reconcile held parent reservation 6efa9436-6a91-47c0-94e5-b31b5a0e7e3a (EUR 10, observed USD still null) from existing provider records. No corrected runtime digest is admitted; do not retry or replay consumed approvals.)* + +### Adopt concrete OpenBao credential lanes from ops-warden +Progress: 4/6 done | workplan_id: `31f7f8ea-7f73-516c-8877-f03a13f1db82` + +**Open tasks:** +- ! Stage live apply and verification `fb103f1e` + *(wait: Owner work first: publish a reviewed scoped-apply command per lane. Per-lane approvals are no longer needed (D1 standing rule); each lane with a command enters the attended window.)* +- ! Reconcile routing ownership and retire interim proxies `1431edae` + *(wait: Needs owner-agreed routing/proxy retirement for each verified lane and custody disposition of the legacy npm pointer; a single approved OpenRouter key-check does not authorize broader routing cutover.)* + +### Evolve the Lifecycle engine to the accepted security layer model +Progress: 5/6 done | workplan_id: `9c9e5164-b2f5-5ea2-a557-5368d65e9fe0` + +**Open tasks:** +- ! No standing engine credential `d7bc8bdc` + *(wait: Published JWT contract and positive login/revocation are delivered. Native KEY-WP-0039-T02 claim negatives, CCR-2026-0038 effective-policy/capability/expiry/use checks and MASON-WP-0009-T05 remain. Login-self-only grants no protected-operation authority: agree and implement separately reviewed task-scoped backend execution entitlement, then prove functional steady-state service-identity adoption without bootstrap/env fallback.)* + +### Production-safe provisioning, authorization, and lifecycle hardening +Progress: 6/7 done | workplan_id: `68a39be1-bd9c-5133-ad64-e7bca892aaf3` + +**Open tasks:** +- ! Resume native production lane adoption `a0a1dd92` + *(wait: Engine approval hardening is complete. Remaining per-lane cutover includes native routing/proxy retirement with ops-warden under SECRETS-WP-0006-T05/T06; the exact OpenRouter key-check receipt does not establish broader recipient readiness.)* + +## Inbox Hygiene + +**Stale unread:** 3 message(s) older than 3 day(s) — triage at session start. +**Missing thread_id:** 2 unread message(s) lack supersession chains. + +--- +## MCP Orientation (when available) + +If the state-hub MCP server is reachable, call: +`get_domain_summary("infotech")` +This provides richer cross-domain context. +If the MCP call fails, use this file as your orientation source. diff --git a/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/WORK-RECORDS.md.worktree b/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/WORK-RECORDS.md.worktree new file mode 100644 index 00000000..4d1cfb6d --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/WORK-RECORDS.md.worktree @@ -0,0 +1,95 @@ +# Work Records — secrets-engine + +> Generated by `statehub fix-consistency` (CUST-WP-0061-T04, work-record +> stage 3). Do not edit by hand — edit the source file/block listed for +> each record and re-run fix-consistency to refresh this index. Archived +> workplans are omitted; closed decisions/intakes/engagements stay listed +> so recently-resolved work is still visible. [auto] + +| Kind | ID | Status | Lane | Source | +| --- | --- | --- | --- | --- | +| workplan | SECRETS-WP-ADHOC-2026-08-21 | finished | — | workplans/ADHOC-2026-08-21.md | +| workplan | SECRETS-WP-ADHOC-2026-08-23 | finished | — | workplans/ADHOC-2026-08-23.md | +| workplan | SECRETS-WP-0001 | finished | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md | +| workplan | SECRETS-WP-0002 | finished | — | workplans/SECRETS-WP-0002-bootstrap.md | +| workplan | SECRETS-WP-0004 | finished | — | workplans/SECRETS-WP-0004-warden-sign-token-lane.md | +| workplan | SECRETS-WP-0005 | finished | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md | +| workplan | SECRETS-WP-0006 | blocked | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md | +| workplan | SECRETS-WP-0007 | blocked | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | +| workplan | SECRETS-WP-0008 | blocked | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md | +| workplan | SECRETS-WP-0009 | blocked | — | workplans/SECRETS-WP-0009-glas-claude-native-delivery.md | +| workplan | SECRETS-WP-0010 | finished | — | workplans/SECRETS-WP-0010-openrouter-native-access.md | +| workplan | SECRETS-WP-0011 | finished | — | workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md | +| workplan | SECRETS-WP-0012 | finished | — | workplans/SECRETS-WP-0012-keycape-openbao-consumer-custody.md | +| workplan | SECRETS-WP-0013 | proposed | — | workplans/SECRETS-WP-0013-task-scoped-openbao-execution.md | +| workplan | SECRETS-WP-0014 | active | — | workplans/SECRETS-WP-0014-pdp-transport-and-responder-authentication.md | +| task | SECRETS-WP-ADHOC-2026-08-21-T01 | done | — | workplans/ADHOC-2026-08-21.md | +| task | SECRETS-WP-ADHOC-2026-08-23-T01 | done | — | workplans/ADHOC-2026-08-23.md | +| task | SECRETS-WP-0001-T01 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md | +| task | SECRETS-WP-0001-T02 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md | +| task | SECRETS-WP-0001-T03 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md | +| task | SECRETS-WP-0002-T01 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T02 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T03 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T04 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T05 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T06 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T07 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T08 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T09 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0002-T10 | done | — | workplans/SECRETS-WP-0002-bootstrap.md | +| task | SECRETS-WP-0004-T01 | done | — | workplans/SECRETS-WP-0004-warden-sign-token-lane.md | +| task | SECRETS-WP-0004-T02 | done | — | workplans/SECRETS-WP-0004-warden-sign-token-lane.md | +| task | SECRETS-WP-0004-T03 | done | — | workplans/SECRETS-WP-0004-warden-sign-token-lane.md | +| task | SECRETS-WP-0004-T04 | done | — | workplans/SECRETS-WP-0004-warden-sign-token-lane.md | +| task | SECRETS-WP-0004-T05 | done | — | workplans/SECRETS-WP-0004-warden-sign-token-lane.md | +| task | SECRETS-WP-0005-T01 | done | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md | +| task | SECRETS-WP-0005-T02 | done | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md | +| task | SECRETS-WP-0005-T03 | done | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md | +| task | SECRETS-WP-0005-T04 | done | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md | +| task | SECRETS-WP-0005-T05 | done | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md | +| task | SECRETS-WP-0005-T06 | done | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md | +| task | SECRETS-WP-0005-T07 | done | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md | +| task | SECRETS-WP-0006-T01 | done | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md | +| task | SECRETS-WP-0006-T02 | done | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md | +| task | SECRETS-WP-0006-T03 | done | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md | +| task | SECRETS-WP-0006-T04 | done | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md | +| task | SECRETS-WP-0006-T05 | wait | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md | +| task | SECRETS-WP-0006-T06 | wait | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md | +| task | SECRETS-WP-0007-T01 | done | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | +| task | SECRETS-WP-0007-T02 | done | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | +| task | SECRETS-WP-0007-T03 | done | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | +| task | SECRETS-WP-0007-T04 | done | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | +| task | SECRETS-WP-0007-T05 | done | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | +| task | SECRETS-WP-0007-T06 | done | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | +| task | SECRETS-WP-0007-T07 | wait | — | workplans/SECRETS-WP-0007-production-lifecycle-hardening.md | +| task | SECRETS-WP-0008-T01 | done | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md | +| task | SECRETS-WP-0008-T02 | done | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md | +| task | SECRETS-WP-0008-T03 | done | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md | +| task | SECRETS-WP-0008-T04 | done | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md | +| task | SECRETS-WP-0008-T05 | done | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md | +| task | SECRETS-WP-0008-T06 | wait | — | workplans/SECRETS-WP-0008-layer-model-lifecycle-conformance.md | +| task | SECRETS-WP-0009-T01 | done | — | workplans/SECRETS-WP-0009-glas-claude-native-delivery.md | +| task | SECRETS-WP-0009-T02 | done | — | workplans/SECRETS-WP-0009-glas-claude-native-delivery.md | +| task | SECRETS-WP-0009-T03 | wait | — | workplans/SECRETS-WP-0009-glas-claude-native-delivery.md | +| task | SECRETS-WP-0010-T01 | done | — | workplans/SECRETS-WP-0010-openrouter-native-access.md | +| task | SECRETS-WP-0010-T02 | done | — | workplans/SECRETS-WP-0010-openrouter-native-access.md | +| task | SECRETS-WP-0010-T03 | done | — | workplans/SECRETS-WP-0010-openrouter-native-access.md | +| task | SECRETS-WP-0011-T01 | done | — | workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md | +| task | SECRETS-WP-0011-T02 | done | — | workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md | +| task | SECRETS-WP-0011-T03 | done | — | workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md | +| task | SECRETS-WP-0011-T04 | done | — | workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md | +| task | SECRETS-WP-0011-T05 | done | — | workplans/SECRETS-WP-0011-multi-lane-exec-owner-delivery.md | +| task | SECRETS-WP-0012-T01 | done | — | workplans/SECRETS-WP-0012-keycape-openbao-consumer-custody.md | +| task | SECRETS-WP-0012-T02 | cancel | — | workplans/SECRETS-WP-0012-keycape-openbao-consumer-custody.md | +| task | SECRETS-WP-0012-T03 | done | — | workplans/SECRETS-WP-0012-keycape-openbao-consumer-custody.md | +| task | SECRETS-WP-0012-T04 | done | — | workplans/SECRETS-WP-0012-keycape-openbao-consumer-custody.md | +| task | SECRETS-WP-0013-T01 | wait | — | workplans/SECRETS-WP-0013-task-scoped-openbao-execution.md | +| task | SECRETS-WP-0013-T02 | done | — | workplans/SECRETS-WP-0013-task-scoped-openbao-execution.md | +| task | SECRETS-WP-0013-T03 | wait | — | workplans/SECRETS-WP-0013-task-scoped-openbao-execution.md | +| task | SECRETS-WP-0014-T01 | done | — | workplans/SECRETS-WP-0014-pdp-transport-and-responder-authentication.md | +| task | SECRETS-WP-0014-T02 | progress | — | workplans/SECRETS-WP-0014-pdp-transport-and-responder-authentication.md | +| task | SECRETS-WP-0014-T03 | wait | — | workplans/SECRETS-WP-0014-pdp-transport-and-responder-authentication.md | +| intake | SECRETS-IN-0001 | closed | — | intakes/intakes.md | +| intake | SECRETS-IN-0002 | closed | — | intakes/intakes.md | +| intake | SECRETS-IN-0003 | closed | — | intakes/intakes.md | diff --git a/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/originals.json b/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/originals.json new file mode 100644 index 00000000..8771b02f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/consumer-outage-owner-followthrough-r1/secrets-engine-publication-backup/originals.json @@ -0,0 +1 @@ +{".custodian-brief.md": "100644 f5952182bbfde84b60c85c4155da8c65f12ba0ab 0\t.custodian-brief.md\n", "WORK-RECORDS.md": "100644 70e5831d75b067c0d05efa3fab37a76a029cf9e9 0\tWORK-RECORDS.md\n"} \ No newline at end of file diff --git a/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.stderr.txt b/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.stderr.txt new file mode 100644 index 00000000..3345563f --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-consistency.stderr.txt @@ -0,0 +1 @@ +WARN: git commit failed for writeback: Generated-only commits rejected: staged diff --git a/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-projection.stderr.txt b/docs/changes/netkingdom-target-2026-10-17/corrected-client-cluster-projection.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/docs/changes/netkingdom-target-2026-10-17/custodian-consistency.json b/docs/changes/netkingdom-target-2026-10-17/custodian-consistency.json new file mode 100644 index 00000000..66d387ad --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/custodian-consistency.json @@ -0,0 +1,142 @@ +{ + "repo_slug": "the-custodian", + "repo_path": "/home/worsch/the-custodian", + "source_revision": "f8c7dfa2a9c7919879b62c77eb39582b3e23654e", + "source_revision_reason": null, + "issues": [ + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager warning: workplans/: repository uses more than one workplan prefix: ['CUST-WP', 'THE-WP']", + "file_path": "workplans/", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-35", + "message": "Repo Manager contradictory: workplans/ADHOC-2026-08-25-retired.md: workplan id 'CUST-WP-ADHOC-2026-08-25-RETIRED' is not accepted by the canon kind registry", + "file_path": "workplans/ADHOC-2026-08-25-retired.md", + "db_id": "", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-05", + "message": "Title drift in 'cust-wp-0010': file='Domain and Repository Goals' db='Workplan Lifecycle Documentation' (file wins)", + "file_path": "workplans/CUST-WP-0010b-domain-and-repo-goals.md", + "db_id": "def8455a-9de4-4891-a15a-5b09ca98ab1e", + "file_value": "Domain and Repository Goals", + "db_value": "Workplan Lifecycle Documentation", + "fixable": true + }, + { + "severity": "WARN", + "check_id": "C-20", + "message": "Workplan dependency target 'STATE-WP-0092' is not linked to State Hub", + "file_path": "workplans/CUST-WP-0072-fleet-flavor-and-depends-on-backfill.md", + "db_id": "", + "file_value": "STATE-WP-0092", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-40", + "message": "blocker satisfied, task still wait: 'CUST-WP-0073-T05' in workplan 'CUST-WP-0073' \u2014 decision 1591daa1-6e85-4dfd-aadd-5a9fe1ef47fa is resolved", + "file_path": "workplans/CUST-WP-0073-agent-credential-separation.md#CUST-WP-0073-T05", + "db_id": "", + "file_value": "1591daa1-6e85-4dfd-aadd-5a9fe1ef47fa", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-39", + "message": "Human wait task 'CUST-WP-0079-T06' in workplan 'CUST-WP-0079' has needs_human: true without decision_id \u2014 unrouted human gate", + "file_path": "workplans/CUST-WP-0079-deterministic-security-flow.md#CUST-WP-0079-T06", + "db_id": "", + "file_value": "needs_human: true", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-22", + "message": "Task description drift 'CUST-WP-0080-T06': file content differs from DB (file wins)", + "file_path": "workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md#CUST-WP-0080-T06", + "db_id": "6aca534c-5c7a-556f-b6b6-406433670c29", + "file_value": "Founder implementation request, 2026-10-16. Document the optimized target and\ncoordinate GPT-6.1-Sol medium agents again", + "db_value": "Founder implementation request, 2026-10-16. Document the optimized target and\ncoordinate GPT-6.1-Sol medium agents again", + "fixable": true + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Closed DB workstream 'cust-wp-0010b' (id=416ff571\u2026, status=finished) has no backing workplan file", + "file_path": "", + "db_id": "416ff571-18cf-5cb2-9c8b-836f68a301b3", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'interactive-the-custodian@retired-20260828' (id=370c2481\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "370c2481-6806-41eb-a917-f8874f03184f", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'the-custodian-adhoc-2026-07-02@retired-20260827' (id=5c53733b\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "5c53733b-c077-4a93-be66-9c3af8f9b6fd", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "INFO", + "check_id": "C-08", + "message": "Retired DB workstream 'adhoc-2026-05-02@retired-20260827' (id=3f54ce9c\u2026, status=finished) has no backing workplan file \u2014 projection tombstone, not live work", + "file_path": "", + "db_id": "3f54ce9c-1f95-42de-894f-0f81a52ba2e8", + "file_value": "", + "db_value": "", + "fixable": false + }, + { + "severity": "WARN", + "check_id": "C-26", + "message": "Workplan id 'THE-WP-0001' uses prefix 'THE-WP' but repo canonical prefix is 'CUST-WP' \u2014 new plans must conform", + "file_path": "workplans/THE-WP-0001-federation-interface.md", + "db_id": "", + "file_value": "THE-WP-0001", + "db_value": "CUST-WP", + "fixable": false + } + ], + "fixes_applied": [ + "bindings: synced 89/89", + "C-17 cleared: pushed 2 backlogged commit(s)", + "C-05 fixed: workstream def8455a\u2026 title \u2192 'Domain and Repository Goals'", + "C-22 fixed: task 6aca534c\u2026 description updated", + "push: pushed" + ], + "summary": { + "fail": 0, + "automation_error": 0, + "warn": 8, + "info": 4 + }, + "result": "warn" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/custodian-consistency.stderr.txt b/docs/changes/netkingdom-target-2026-10-17/custodian-consistency.stderr.txt new file mode 100644 index 00000000..047afc64 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/custodian-consistency.stderr.txt @@ -0,0 +1 @@ +WARN: working-memory commit failed: Generated-only commits rejected: staged diff --git a/docs/changes/netkingdom-target-2026-10-17/custodian-projection.json b/docs/changes/netkingdom-target-2026-10-17/custodian-projection.json new file mode 100644 index 00000000..3acef2d4 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/custodian-projection.json @@ -0,0 +1,291 @@ +{ + "ok": true, + "status": "applied", + "repo_slug": "the-custodian", + "commit": "f8c7dfa2a9c7919879b62c77eb39582b3e23654e", + "requests": 2, + "elapsed_ms": 9278.0, + "git": { + "upstream": "origin/main", + "behind": 0, + "ahead": 0 + }, + "identifiers": { + "schema": "repo-manager.identifier-assignment.v1", + "ok": true, + "executed": true, + "repo": "the-custodian", + "namespace": "helixforge", + "assignments": [], + "historical_invalid_identifiers": [ + { + "kind": "workplan", + "id": "CUST-WP-ADHOC-2026-08-25-RETIRED", + "source": "workplans/ADHOC-2026-08-25-retired.md" + } + ], + "files_changed": [] + }, + "receipt": { + "schema": "state-hub.repository-projection-reconcile.v1", + "instance_role": "primary", + "instance_label": "railiance01", + "expected_commit": "f8c7dfa2a9c7919879b62c77eb39582b3e23654e", + "derived_commit": "f8c7dfa2a9c7919879b62c77eb39582b3e23654e", + "outcome": { + "schema": "state-hub.projection-reset.v1", + "repo_slug": "the-custodian", + "commit": "f8c7dfa2a9c7919879b62c77eb39582b3e23654e", + "status": "applied", + "counts": { + "created": 0, + "updated": 88, + "retired": 0, + "refused": 0, + "released": 0, + "created_tasks": 0, + "updated_tasks": 0, + "cancelled_tasks": 0, + "created_edges": 0, + "removed_edges": 0, + "unresolved_edges": 0, + "external_edges": 13 + }, + "created": [], + "updated": [ + "CUST-WP-0000", + "CUST-WP-0000b", + "CUST-WP-0000c", + "CUST-WP-0001", + "CUST-WP-0002", + "CUST-WP-0004", + "CUST-WP-0005", + "CUST-WP-0006", + "CUST-WP-0007", + "CUST-WP-0008", + "CUST-WP-0009", + "CUST-WP-0010", + "CUST-WP-0010b", + "CUST-WP-0013", + "CUST-WP-0014", + "CUST-WP-0015", + "CUST-WP-0016", + "CUST-WP-0017", + "CUST-WP-0017-LEGACY", + "CUST-WP-0018", + "CUST-WP-0019", + "CUST-WP-0020", + "CUST-WP-0021", + "CUST-WP-0022", + "CUST-WP-0023", + "CUST-WP-0024", + "CUST-WP-0025", + "CUST-WP-0026", + "CUST-WP-0027", + "CUST-WP-0028", + "CUST-WP-0029", + "CUST-WP-0030", + "CUST-WP-0031", + "CUST-WP-0032", + "CUST-WP-0033", + "CUST-WP-0034", + "CUST-WP-0035", + "CUST-WP-0036", + "CUST-WP-0037", + "CUST-WP-0039", + "CUST-WP-0040", + "CUST-WP-0041", + "CUST-WP-0043", + "CUST-WP-0044", + "CUST-WP-0045", + "CUST-WP-0046", + "CUST-WP-0047", + "CUST-WP-0048", + "CUST-WP-0049", + "CUST-WP-0050", + "CUST-WP-0051", + "CUST-WP-0052", + "CUST-WP-0053", + "CUST-WP-0053-LEGACY", + "CUST-WP-0054", + "CUST-WP-0055", + "CUST-WP-0056", + "CUST-WP-0057", + "CUST-WP-0058", + "CUST-WP-0059", + "CUST-WP-0060", + "CUST-WP-0061", + "CUST-WP-0062", + "CUST-WP-0063", + "CUST-WP-0064", + "CUST-WP-0065", + "CUST-WP-0066", + "CUST-WP-0067", + "CUST-WP-0068", + "CUST-WP-0069", + "CUST-WP-0070", + "CUST-WP-0071", + "CUST-WP-0072", + "CUST-WP-0073", + "CUST-WP-0074", + "CUST-WP-0075", + "CUST-WP-0076", + "CUST-WP-0077", + "CUST-WP-0078", + "CUST-WP-0079", + "CUST-WP-0080", + "CUST-WP-0081", + "CUST-WP-ADHOC-2026-03-29", + "CUST-WP-ADHOC-2026-05-02", + "CUST-WP-ADHOC-2026-07-02", + "CUST-WP-ADHOC-2026-08-25", + "CUST-WP-ADHOC-2026-09-06", + "THE-WP-0001" + ], + "retired": [], + "released": [], + "created_tasks": [], + "updated_tasks": [], + "cancelled_tasks": [], + "created_edges": [], + "removed_edges": [], + "unresolved_edges": [], + "external_edges": [ + { + "workplan": "CUST-WP-0071", + "from": "CUST-WP-0071-T05", + "target": "CUST-WP-0071-T04", + "relationship_type": "starts_after", + "from_workplan_id": "2249bddb-7524-5add-bd5c-c4163a6ca0f3", + "from_task_id": "20ddd4d7-d85d-5b95-bb0a-7b0ca8af76ca", + "to_workplan_id": null, + "to_task_id": "944f98e2-7e42-5894-925b-752423f3a1cc" + }, + { + "workplan": "CUST-WP-0071", + "from": "CUST-WP-0071-T03", + "target": "CUST-WP-0071-T01", + "relationship_type": "starts_after", + "from_workplan_id": "2249bddb-7524-5add-bd5c-c4163a6ca0f3", + "from_task_id": "6dc67558-eb1e-5bb6-a667-986f884dd495", + "to_workplan_id": null, + "to_task_id": "4ae8eb8d-f8c5-5256-ae50-c323cfd73d7a" + }, + { + "workplan": "CUST-WP-0071", + "from": "CUST-WP-0071-T03", + "target": "CUST-WP-0071-T02", + "relationship_type": "starts_after", + "from_workplan_id": "2249bddb-7524-5add-bd5c-c4163a6ca0f3", + "from_task_id": "6dc67558-eb1e-5bb6-a667-986f884dd495", + "to_workplan_id": null, + "to_task_id": "82192370-2fd7-5363-88d2-3c67889d3d68" + }, + { + "workplan": "CUST-WP-0071", + "from": "CUST-WP-0071-T02", + "target": "CUST-WP-0071-T01", + "relationship_type": "starts_after", + "from_workplan_id": "2249bddb-7524-5add-bd5c-c4163a6ca0f3", + "from_task_id": "82192370-2fd7-5363-88d2-3c67889d3d68", + "to_workplan_id": null, + "to_task_id": "4ae8eb8d-f8c5-5256-ae50-c323cfd73d7a" + }, + { + "workplan": "CUST-WP-0071", + "from": "CUST-WP-0071-T02", + "target": "RAPPS-WP-0014-T03", + "relationship_type": "starts_after", + "from_workplan_id": "2249bddb-7524-5add-bd5c-c4163a6ca0f3", + "from_task_id": "82192370-2fd7-5363-88d2-3c67889d3d68", + "to_workplan_id": null, + "to_task_id": "dd069c6d-fcc1-5bac-b233-976f2f0d5cd1" + }, + { + "workplan": "CUST-WP-0071", + "from": "CUST-WP-0071-T04", + "target": "CUST-WP-0071-T03", + "relationship_type": "starts_after", + "from_workplan_id": "2249bddb-7524-5add-bd5c-c4163a6ca0f3", + "from_task_id": "944f98e2-7e42-5894-925b-752423f3a1cc", + "to_workplan_id": null, + "to_task_id": "6dc67558-eb1e-5bb6-a667-986f884dd495" + }, + { + "workplan": "CUST-WP-0073", + "from": "CUST-WP-0073-T02", + "target": "GLAS-WP-0012", + "relationship_type": "blocks", + "from_workplan_id": "a98a9f34-83b4-5c8c-8107-e05f7806d50d", + "from_task_id": "4b88b0b7-dc7e-5612-aa5d-1a08f0530c35", + "to_workplan_id": "170bf1ae-337f-5553-8d1e-03b07100e08f", + "to_task_id": null + }, + { + "workplan": "CUST-WP-0073", + "from": "CUST-WP-0073-T04", + "target": "CUST-WP-0073-T02", + "relationship_type": "starts_after", + "from_workplan_id": "a98a9f34-83b4-5c8c-8107-e05f7806d50d", + "from_task_id": "90725511-4e31-549f-b567-47feff1a9ca4", + "to_workplan_id": null, + "to_task_id": "4b88b0b7-dc7e-5612-aa5d-1a08f0530c35" + }, + { + "workplan": "CUST-WP-0079", + "from": "CUST-WP-0079-T03", + "target": "ACTIVITY-WP-0047", + "relationship_type": "blocks", + "from_workplan_id": "ab288f92-d364-5c24-9362-aee451f266c3", + "from_task_id": "1be0569c-221d-5925-a0ff-fd2af88e52b1", + "to_workplan_id": "ee97869b-dca2-54c9-aa18-0b479c244fb3", + "to_task_id": null + }, + { + "workplan": "CUST-WP-0079", + "from": "CUST-WP-0079-T04", + "target": "PNEX-WP-0006", + "relationship_type": "blocks", + "from_workplan_id": "ab288f92-d364-5c24-9362-aee451f266c3", + "from_task_id": "5dd52156-09a8-5781-b288-99ae822f59a6", + "to_workplan_id": "774c5037-a3d0-5e65-893c-d18970acd66a", + "to_task_id": null + }, + { + "workplan": "CUST-WP-0080", + "from": "CUST-WP-0080-T04", + "target": "CUST-WP-0080-T03", + "relationship_type": "starts_after", + "from_workplan_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52", + "from_task_id": "82378b0f-7004-5c2f-9683-b356a1227576", + "to_workplan_id": null, + "to_task_id": "87637402-02f1-57c1-8fbc-4141598af8e3" + }, + { + "workplan": "CUST-WP-0080", + "from": "CUST-WP-0080-T05", + "target": "RPF-WP-0056", + "relationship_type": "blocks", + "from_workplan_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52", + "from_task_id": "ed8b909a-23bf-5e5f-b600-e477fbae136b", + "to_workplan_id": "31933d08-c877-5fda-aff9-6220c3705c92", + "to_task_id": null + }, + { + "workplan": "CUST-WP-0080", + "from": "CUST-WP-0080-T05", + "target": "RAPP-PLAYWRIGHT-WP-0004", + "relationship_type": "blocks", + "from_workplan_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52", + "from_task_id": "ed8b909a-23bf-5e5f-b600-e477fbae136b", + "to_workplan_id": "f9280c40-201e-59b5-a6f0-1aace8e0e2e2", + "to_task_id": null + } + ], + "refused": [], + "notes": [ + "Preserved bound historical row and task UUIDs: CUST-WP-ADHOC-2026-08-25-RETIRED" + ] + } + } +} diff --git a/docs/changes/netkingdom-target-2026-10-17/custodian-projection.stderr.txt b/docs/changes/netkingdom-target-2026-10-17/custodian-projection.stderr.txt new file mode 100644 index 00000000..e69de29b diff --git a/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/.custodian-brief.md.worktree b/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/.custodian-brief.md.worktree new file mode 100644 index 00000000..6aad3a57 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/.custodian-brief.md.worktree @@ -0,0 +1,62 @@ + +# Custodian Brief — the-custodian + +**Domain:** infotech +**Last synced:** 2026-10-15 23:45 UTC +**State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* + +## Active Workstreams + +### NetKingdom target security architecture and SEC-DSM implementation +Progress: 2/6 done | workplan_id: `dfadb19b-445e-59c6-bcd6-48e87b912c52` + +**Open tasks:** +- ► Close source defects and reconcile uncovered lifecycle gaps `87637402` +- ► Coordinate self-service Playwright identity delivery `ed8b909a` +- ► Establish the target architecture and drive the restructuring `6aca534c` +- · Verify native closure against every requirement `82378b0f` + +### Separate agent credentials and establish supervised privileged execution +Progress: 2/5 done | workplan_id: `a98a9f34-83b4-5c8c-8107-e05f7806d50d` + +**Open tasks:** +- ! Build and hand out the agent identity `4b88b0b7` + *(wait: Await GLAS-WP-0012 (glas-harness) production acceptance of the local supervised profile; then railiance-platform RBAC, railiance-enablement k3s config, railiance-infra principal mapping and ops-warden certificate issuance.)* +- ! Fleet guidance and harness guards `90725511` + *(wait: Await CUST-WP-0073-T02: the verified agent identity and execution path must exist before it can be documented; Codex/Grok read-denial guard needs glas-harness or harness-owner delivery.)* +- ! Rotate what was exposed `1b41b532` + *(wait: Deferred by founder decision 2026-09-24; reopened only by the founder on one of the three triggers below, in one attended rotation window.)* + +### Size Railiance workloads from actual demand and establish a weekly allocation review +Progress: 1/5 done | workplan_id: `2249bddb-7524-5add-bd5c-c4163a6ca0f3` + +**Open tasks:** +- ! Measure the Vergabe prototype under representative pilot use `82192370` + *(wait: Await RAPPS-WP-0014-T03 (blocked, needs_human): populated two-user/document workflow run by Bernd and the company contact, giving representative load for p95 <= 2s / zero failures.)* +- ! Review ecosystem allocations and reserve operating room `6dc67558` + *(wait: Await CUST-WP-0071-T02 representative sample; Forgejo/runner demand and zero-request workload review need owner input (railiance-cluster, railiance-forge, resource-control).)* +- ! Apply accepted sizing changes and verify their effects `944f98e2` + *(wait: Await reviewed allocation proposals and applicable workload-owner authority.)* +- ! Establish the regular weekly workload-demand and allocation assessment `20ddd4d7` + *(wait: Await the repeatable observation and accepted sizing/review procedure.)* + +### Deterministic security flow: standing authorizations, flow report, and agent re-engagement +Progress: 3/7 done | workplan_id: `ab288f92-d364-5c24-9362-aee451f266c3` + +**Open tasks:** +- ! Schedule the flow report and decision sync `1be0569c` + *(wait: Activity Core accepted the schedule in ACTIVITY-WP-0047. Await claiming rein workstation/hub acceptance, owner activation and the first unassisted fire with report/checkpoint evidence.)* +- ! Encode the standing change rule as a policy-nexus guardrail `5dd52156` + *(wait: policy-nexus owns guardrail publication; handoff written as PNEX-WP-0006.)* +- ! Stop agent-authored index and sync commits `8a3dc219` + *(wait: Local guard and repeatable shared-hook installation are implemented. Fleet generator adoption and the required full week of clean history remain unverified; repo-manager owner acceptance is needed.)* +- ! Attended window #1 `e3da807f` + *(wait: Partly done 2026-10-11: list cut from 14 to 3; U05-U07 accepted, U08 waits on KEY-WP-0040-T01. Remaining founder acts: USER-WP-0026-T03 readback, RPF-WP-0044-T08 coulombcore check, the U08 re-run, and Sol's added RPF-WP-0044-T04 issuer login.)* + +--- +## MCP Orientation (when available) + +If the state-hub MCP server is reachable, call: +`get_domain_summary("infotech")` +This provides richer cross-domain context. +If the MCP call fails, use this file as your orientation source. diff --git a/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/WORK-RECORDS.md.worktree b/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/WORK-RECORDS.md.worktree new file mode 100644 index 00000000..6dc81634 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/WORK-RECORDS.md.worktree @@ -0,0 +1,536 @@ +# Work Records — the-custodian + +> Generated by `statehub fix-consistency` (CUST-WP-0061-T04, work-record +> stage 3). Do not edit by hand — edit the source file/block listed for +> each record and re-run fix-consistency to refresh this index. Archived +> workplans are omitted; closed decisions/intakes/engagements stay listed +> so recently-resolved work is still visible. [auto] + +| Kind | ID | Status | Lane | Source | +| --- | --- | --- | --- | --- | +| workplan | CUST-WP-ADHOC-2026-05-02 | done | — | workplans/ADHOC-2026-05-02.md | +| workplan | CUST-WP-ADHOC-2026-07-02 | finished | — | workplans/ADHOC-2026-07-02.md | +| workplan | CUST-WP-ADHOC-2026-08-25-RETIRED | finished | — | workplans/ADHOC-2026-08-25-retired.md | +| workplan | CUST-WP-ADHOC-2026-08-25 | finished | — | workplans/ADHOC-2026-08-25.md | +| workplan | CUST-WP-ADHOC-2026-09-06 | finished | — | workplans/ADHOC-2026-09-06.md | +| workplan | CUST-WP-0000 | finished | — | workplans/CUST-WP-0000-state-hub-v0.1-build-deploy.md | +| workplan | CUST-WP-0000b | finished | — | workplans/CUST-WP-0000b-state-hub-v0.2-decisions-dependencies.md | +| workplan | CUST-WP-0001 | done | — | workplans/CUST-WP-0001-custodian-agent-runtime.md | +| workplan | CUST-WP-0002 | finished | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| workplan | CUST-WP-0004 | finished | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| workplan | CUST-WP-0005 | finished | — | workplans/CUST-WP-0005-dynamic-domains.md | +| workplan | CUST-WP-0006 | done | — | workplans/CUST-WP-0006-gems-state-hub.md | +| workplan | CUST-WP-0007 | finished | — | workplans/CUST-WP-0007-gems-migration.md | +| workplan | CUST-WP-0008 | done | — | workplans/CUST-WP-0008-consistency-engine.md | +| workplan | CUST-WP-0009 | finished | — | workplans/CUST-WP-0009-human-interventions.md | +| workplan | CUST-WP-0010 | finished | — | workplans/CUST-WP-0010-workstream-lifecycle-docs.md | +| workplan | CUST-WP-0010b | finished | — | workplans/CUST-WP-0010b-domain-and-repo-goals.md | +| workplan | CUST-WP-0013 | finished | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| workplan | CUST-WP-0015 | done | — | workplans/CUST-WP-0015-agent-inbox.md | +| workplan | CUST-WP-0016 | done | — | workplans/CUST-WP-0016-kaizen-agentic-integration.md | +| workplan | CUST-WP-0017 | done | — | workplans/CUST-WP-0017-scope-md-agent-and-coverage.md | +| workplan | CUST-WP-0018 | done | — | workplans/CUST-WP-0018-api-hardening-code-quality.md | +| workplan | CUST-WP-0019 | done | — | workplans/CUST-WP-0019-dashboard-ux-polish.md | +| workplan | CUST-WP-0020 | done | — | workplans/CUST-WP-0020-test-suite.md | +| workplan | CUST-WP-0021 | done | — | workplans/CUST-WP-0021-multi-host-repo-paths.md | +| workplan | CUST-WP-0022 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| workplan | CUST-WP-0023 | done | — | workplans/CUST-WP-0023-tpsc.md | +| workplan | CUST-WP-0024 | done | — | workplans/CUST-WP-0024-repo-doi-gate.md | +| workplan | CUST-WP-0026 | done | — | workplans/CUST-WP-0026-distributed-consistency.md | +| workplan | CUST-WP-0027 | done | — | workplans/CUST-WP-0027-capability-request-dispute.md | +| workplan | CUST-WP-0029 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| workplan | CUST-WP-0030 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| workplan | CUST-WP-0031 | done | — | workplans/CUST-WP-0031-capability-registry.md | +| workplan | CUST-WP-0032 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| workplan | CUST-WP-0033 | done | — | workplans/CUST-WP-0033-interface-change-registry.md | +| workplan | CUST-WP-0039 | done | — | workplans/CUST-WP-0039-dashboard-poll-optimization.md | +| workplan | CUST-WP-0040 | finished | — | workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md | +| workplan | CUST-WP-0041 | done | — | workplans/CUST-WP-0041-api-performance.md | +| workplan | CUST-WP-0043 | finished | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| workplan | CUST-WP-0044 | finished | — | workplans/CUST-WP-0044-daily-statehub-wsjf-triage.md | +| workplan | CUST-WP-0045 | finished | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| workplan | CUST-WP-0069 | finished | — | workplans/CUST-WP-0045-cutover-runbook.md | +| workplan | CUST-WP-0046 | finished | — | workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md | +| workplan | CUST-WP-0047 | finished | — | workplans/CUST-WP-0047-ops-hub-service-inventory-now-view.md | +| workplan | CUST-WP-0048 | finished | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| workplan | CUST-WP-0049 | finished | — | workplans/CUST-WP-0049-interhub-bootstrap-access-lane.md | +| workplan | CUST-WP-0050 | finished | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| workplan | CUST-WP-0051 | finished | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| workplan | CUST-WP-0052 | finished | — | workplans/CUST-WP-0052-core-hub-fos-reset.md | +| workplan | CUST-WP-0053 | finished | — | workplans/CUST-WP-0053-coordination-hygiene-improvements.md | +| workplan | CUST-WP-0055 | finished | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| workplan | CUST-WP-0056 | finished | — | workplans/CUST-WP-0056-daily-todo-md-stale-review.md | +| workplan | CUST-WP-0059 | finished | — | workplans/CUST-WP-0059-forgejo-ci-publish-cutover-tail.md | +| workplan | CUST-WP-0060 | finished | — | workplans/CUST-WP-0060-work-record-canonization.md | +| workplan | CUST-WP-0061 | finished | — | workplans/CUST-WP-0061-work-record-stage3-intake-promotion-index.md | +| workplan | CUST-WP-0062 | finished | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md | +| workplan | CUST-WP-0063 | finished | — | workplans/CUST-WP-0063-inbox-governance-packets.md | +| workplan | CUST-WP-0064 | finished | — | workplans/CUST-WP-0064-sbom-controlled-scan-inputs.md | +| workplan | CUST-WP-0065 | finished | — | workplans/CUST-WP-0065-reclassify-repos-and-guidance-docs-to-the-new-sector-domain.md | +| workplan | CUST-WP-0066 | finished | — | workplans/CUST-WP-0066-repository-qualified-ad-hoc-identifiers.md | +| workplan | CUST-WP-0067 | finished | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| workplan | CUST-WP-0068 | finished | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| workplan | CUST-WP-0070 | finished | — | workplans/CUST-WP-0070-publication-repo-category.md | +| workplan | CUST-WP-0071 | blocked | — | workplans/CUST-WP-0071-measured-workload-sizing-and-weekly-review.md | +| workplan | CUST-WP-0072 | finished | — | workplans/CUST-WP-0072-fleet-flavor-and-depends-on-backfill.md | +| workplan | CUST-WP-0073 | blocked | — | workplans/CUST-WP-0073-agent-credential-separation.md | +| workplan | CUST-WP-0074 | finished | — | workplans/CUST-WP-0074-qualified-wait-states.md | +| workplan | CUST-WP-0075 | finished | — | workplans/CUST-WP-0075-dependency-graph-driven-unblocking.md | +| workplan | CUST-WP-0076 | finished | — | workplans/CUST-WP-0076-provisioning-window-cadence.md | +| workplan | CUST-WP-0077 | finished | — | workplans/CUST-WP-0077-dependency-root-execution-wave.md | +| workplan | CUST-WP-0078 | finished | — | workplans/CUST-WP-0078-security-collaboration-consolidation.md | +| workplan | CUST-WP-0079 | blocked | — | workplans/CUST-WP-0079-deterministic-security-flow.md | +| workplan | CUST-WP-0080 | active | — | workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md | +| workplan | CUST-WP-0081 | finished | — | workplans/CUST-WP-0081-netkingdom-architecture-review-and-reuse.md | +| workplan | THE-WP-0001 | finished | — | workplans/THE-WP-0001-federation-interface.md | +| task | CUST-WP-ADHOC-2026-05-02-T01 | done | — | workplans/ADHOC-2026-05-02.md | +| task | CUST-WP-ADHOC-2026-07-02-T01 | done | — | workplans/ADHOC-2026-07-02.md | +| task | ADHOC-2026-08-25-T01 | done | — | workplans/ADHOC-2026-08-25-retired.md | +| task | CUST-WP-ADHOC-2026-08-25-T01 | done | — | workplans/ADHOC-2026-08-25.md | +| task | CUST-WP-ADHOC-2026-09-06-T01 | done | — | workplans/ADHOC-2026-09-06.md | +| task | CUST-WP-0001-T01 | done | — | workplans/CUST-WP-0001-custodian-agent-runtime.md | +| task | CUST-WP-0001-T02 | done | — | workplans/CUST-WP-0001-custodian-agent-runtime.md | +| task | CUST-WP-0002-T01 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T02 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T03 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T04 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T05 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T06 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T07 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T08 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T09 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T10 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T11 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T12 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T13 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T14 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0002-T15 | done | — | workplans/CUST-WP-0002-contribution-tracking-sbom.md | +| task | CUST-WP-0004-T01 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T02 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T03 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T04 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T05 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T06 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T07 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T08 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T09 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0004-T10 | done | — | workplans/CUST-WP-0004-ep-td-tracking.md | +| task | CUST-WP-0005-T01 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T02 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T03 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T04 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T05 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T06 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T07 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T08 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T09 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T10 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | CUST-WP-0005-T11 | done | — | workplans/CUST-WP-0005-dynamic-domains.md | +| task | T01 | done | — | workplans/CUST-WP-0006-gems-state-hub.md | +| task | T02 | done | — | workplans/CUST-WP-0006-gems-state-hub.md | +| task | T03 | done | — | workplans/CUST-WP-0006-gems-state-hub.md | +| task | T04 | done | — | workplans/CUST-WP-0006-gems-state-hub.md | +| task | T05 | done | — | workplans/CUST-WP-0006-gems-state-hub.md | +| task | T01 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T02 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T03 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T04 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T05 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T06 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T07 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T08 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T09 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T10 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T11 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T12 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T13 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T14 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T15 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T16 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | T17 | done | — | workplans/CUST-WP-0007-gems-migration.md | +| task | CUST-WP-0008-T01 | done | — | workplans/CUST-WP-0008-consistency-engine.md | +| task | CUST-WP-0008-T02 | done | — | workplans/CUST-WP-0008-consistency-engine.md | +| task | CUST-WP-0008-T03 | done | — | workplans/CUST-WP-0008-consistency-engine.md | +| task | CUST-WP-0008-T04 | done | — | workplans/CUST-WP-0008-consistency-engine.md | +| task | CUST-WP-0009-T1 | done | — | workplans/CUST-WP-0009-human-interventions.md | +| task | CUST-WP-0009-T2 | done | — | workplans/CUST-WP-0009-human-interventions.md | +| task | CUST-WP-0009-T3 | done | — | workplans/CUST-WP-0009-human-interventions.md | +| task | CUST-WP-0010-T1 | done | — | workplans/CUST-WP-0010-workstream-lifecycle-docs.md | +| task | CUST-WP-0010-T2 | done | — | workplans/CUST-WP-0010-workstream-lifecycle-docs.md | +| task | CUST-WP-0010-T3 | done | — | workplans/CUST-WP-0010-workstream-lifecycle-docs.md | +| task | CUST-WP-0010b-T01 | done | — | workplans/CUST-WP-0010b-domain-and-repo-goals.md | +| task | CUST-WP-0010b-T02 | done | — | workplans/CUST-WP-0010b-domain-and-repo-goals.md | +| task | CUST-WP-0013-T01 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T02 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T03 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T04 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T05 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T06 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T07 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T08 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T09 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T10 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T11 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T12 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T13 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0013-T14 | done | — | workplans/CUST-WP-0013-sbom-infra-expansion.md | +| task | CUST-WP-0015-T01 | done | — | workplans/CUST-WP-0015-agent-inbox.md | +| task | CUST-WP-0015-T02 | done | — | workplans/CUST-WP-0015-agent-inbox.md | +| task | CUST-WP-0015-T03 | done | — | workplans/CUST-WP-0015-agent-inbox.md | +| task | CUST-WP-0015-T04 | done | — | workplans/CUST-WP-0015-agent-inbox.md | +| task | CUST-WP-0015-T05 | done | — | workplans/CUST-WP-0015-agent-inbox.md | +| task | CUST-WP-0016-T01 | done | — | workplans/CUST-WP-0016-kaizen-agentic-integration.md | +| task | CUST-WP-0016-T02 | done | — | workplans/CUST-WP-0016-kaizen-agentic-integration.md | +| task | CUST-WP-0016-T03 | done | — | workplans/CUST-WP-0016-kaizen-agentic-integration.md | +| task | CUST-WP-0016-T04 | done | — | workplans/CUST-WP-0016-kaizen-agentic-integration.md | +| task | CUST-WP-0016-T05 | done | — | workplans/CUST-WP-0016-kaizen-agentic-integration.md | +| task | CUST-WP-0017-T01 | done | — | workplans/CUST-WP-0017-scope-md-agent-and-coverage.md | +| task | CUST-WP-0017-T02 | done | — | workplans/CUST-WP-0017-scope-md-agent-and-coverage.md | +| task | CUST-WP-0017-T03 | done | — | workplans/CUST-WP-0017-scope-md-agent-and-coverage.md | +| task | CUST-WP-0017-T04 | done | — | workplans/CUST-WP-0017-scope-md-agent-and-coverage.md | +| task | CUST-WP-0017-T05 | done | — | workplans/CUST-WP-0017-scope-md-agent-and-coverage.md | +| task | CUST-WP-0017-T06 | done | — | workplans/CUST-WP-0017-scope-md-agent-and-coverage.md | +| task | CUST-WP-0018-T01 | done | — | workplans/CUST-WP-0018-api-hardening-code-quality.md | +| task | CUST-WP-0018-T02 | done | — | workplans/CUST-WP-0018-api-hardening-code-quality.md | +| task | CUST-WP-0018-T03 | done | — | workplans/CUST-WP-0018-api-hardening-code-quality.md | +| task | CUST-WP-0018-T04 | done | — | workplans/CUST-WP-0018-api-hardening-code-quality.md | +| task | CUST-WP-0018-T05 | done | — | workplans/CUST-WP-0018-api-hardening-code-quality.md | +| task | CUST-WP-0018-T06 | done | — | workplans/CUST-WP-0018-api-hardening-code-quality.md | +| task | CUST-WP-0018-T07 | done | — | workplans/CUST-WP-0018-api-hardening-code-quality.md | +| task | CUST-WP-0019-T01 | done | — | workplans/CUST-WP-0019-dashboard-ux-polish.md | +| task | CUST-WP-0019-T02 | done | — | workplans/CUST-WP-0019-dashboard-ux-polish.md | +| task | CUST-WP-0019-T03 | done | — | workplans/CUST-WP-0019-dashboard-ux-polish.md | +| task | CUST-WP-0020-T01 | done | — | workplans/CUST-WP-0020-test-suite.md | +| task | CUST-WP-0020-T02 | done | — | workplans/CUST-WP-0020-test-suite.md | +| task | CUST-WP-0020-T03 | done | — | workplans/CUST-WP-0020-test-suite.md | +| task | CUST-WP-0020-T04 | done | — | workplans/CUST-WP-0020-test-suite.md | +| task | CUST-WP-0020-T05 | done | — | workplans/CUST-WP-0020-test-suite.md | +| task | CUST-WP-0021-T01 | done | — | workplans/CUST-WP-0021-multi-host-repo-paths.md | +| task | CUST-WP-0021-T02 | done | — | workplans/CUST-WP-0021-multi-host-repo-paths.md | +| task | CUST-WP-0021-T03 | done | — | workplans/CUST-WP-0021-multi-host-repo-paths.md | +| task | CUST-WP-0021-T04 | done | — | workplans/CUST-WP-0021-multi-host-repo-paths.md | +| task | CUST-WP-0021-T05 | done | — | workplans/CUST-WP-0021-multi-host-repo-paths.md | +| task | CUST-WP-0022-T01 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T02 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T03 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T04 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T05 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T06 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T07 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T08 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T09 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0022-T10 | done | — | workplans/CUST-WP-0022-capability-requests.md | +| task | CUST-WP-0023-T01 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T02 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T03 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T04 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T05 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T06 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T07 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T08 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T09 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0023-T10 | done | — | workplans/CUST-WP-0023-tpsc.md | +| task | CUST-WP-0024-T01 | done | — | workplans/CUST-WP-0024-repo-doi-gate.md | +| task | CUST-WP-0024-T02 | done | — | workplans/CUST-WP-0024-repo-doi-gate.md | +| task | CUST-WP-0024-T03 | done | — | workplans/CUST-WP-0024-repo-doi-gate.md | +| task | CUST-WP-0024-T04 | done | — | workplans/CUST-WP-0024-repo-doi-gate.md | +| task | CUST-WP-0024-T05 | done | — | workplans/CUST-WP-0024-repo-doi-gate.md | +| task | CUST-WP-0026-T01 | done | — | workplans/CUST-WP-0026-distributed-consistency.md | +| task | CUST-WP-0026-T02 | done | — | workplans/CUST-WP-0026-distributed-consistency.md | +| task | CUST-WP-0026-T03 | done | — | workplans/CUST-WP-0026-distributed-consistency.md | +| task | CUST-WP-0026-T04 | done | — | workplans/CUST-WP-0026-distributed-consistency.md | +| task | CUST-WP-0026-T05 | done | — | workplans/CUST-WP-0026-distributed-consistency.md | +| task | CUST-WP-0027-T01 | done | — | workplans/CUST-WP-0027-capability-request-dispute.md | +| task | CUST-WP-0027-T02 | done | — | workplans/CUST-WP-0027-capability-request-dispute.md | +| task | CUST-WP-0027-T03 | done | — | workplans/CUST-WP-0027-capability-request-dispute.md | +| task | CUST-WP-0027-T04 | done | — | workplans/CUST-WP-0027-capability-request-dispute.md | +| task | CUST-WP-0027-T05 | done | — | workplans/CUST-WP-0027-capability-request-dispute.md | +| task | CUST-WP-0029-T01 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| task | CUST-WP-0029-T02 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| task | CUST-WP-0029-T03 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| task | CUST-WP-0029-T04 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| task | CUST-WP-0029-T05 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| task | CUST-WP-0029-T06 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| task | CUST-WP-0029-T07 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| task | CUST-WP-0029-T08 | done | — | workplans/CUST-WP-0029-token-consumption-tracking.md | +| task | T01 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T02 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T03 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T04 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T05 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T06 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T07 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T08 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T09 | done | — | workplans/CUST-WP-0030-dashboard-entity-list-ux.md | +| task | T01 | done | — | workplans/CUST-WP-0031-capability-registry.md | +| task | T02 | done | — | workplans/CUST-WP-0031-capability-registry.md | +| task | T03 | done | — | workplans/CUST-WP-0031-capability-registry.md | +| task | T04 | done | — | workplans/CUST-WP-0031-capability-registry.md | +| task | T05 | done | — | workplans/CUST-WP-0031-capability-registry.md | +| task | T06 | done | — | workplans/CUST-WP-0031-capability-registry.md | +| task | T07 | done | — | workplans/CUST-WP-0031-capability-registry.md | +| task | CUST-WP-0032-T01 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T02 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T03 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T04 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T05 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T06 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T07 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T08 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T09 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T10 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T11 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T12 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T13 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T14 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0032-T15 | done | — | workplans/CUST-WP-0032-haskell-build-machine.md | +| task | CUST-WP-0033-T01 | done | — | workplans/CUST-WP-0033-interface-change-registry.md | +| task | CUST-WP-0033-T02 | done | — | workplans/CUST-WP-0033-interface-change-registry.md | +| task | CUST-WP-0033-T03 | done | — | workplans/CUST-WP-0033-interface-change-registry.md | +| task | CUST-WP-0033-T04 | done | — | workplans/CUST-WP-0033-interface-change-registry.md | +| task | CUST-WP-0033-T05 | done | — | workplans/CUST-WP-0033-interface-change-registry.md | +| task | CUST-WP-0033-T06 | done | — | workplans/CUST-WP-0033-interface-change-registry.md | +| task | CUST-WP-0039-T1 | done | — | workplans/CUST-WP-0039-dashboard-poll-optimization.md | +| task | CUST-WP-0039-T2 | done | — | workplans/CUST-WP-0039-dashboard-poll-optimization.md | +| task | CUST-WP-0039-T3 | done | — | workplans/CUST-WP-0039-dashboard-poll-optimization.md | +| task | CUST-WP-0039-T4 | done | — | workplans/CUST-WP-0039-dashboard-poll-optimization.md | +| task | CUST-WP-0039-T5 | done | — | workplans/CUST-WP-0039-dashboard-poll-optimization.md | +| task | CUST-WP-0039-T6 | done | — | workplans/CUST-WP-0039-dashboard-poll-optimization.md | +| task | T01 | done | — | workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md | +| task | T02 | done | — | workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md | +| task | T03 | done | — | workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md | +| task | T04 | done | — | workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md | +| task | T05 | done | — | workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md | +| task | T06 | done | — | workplans/CUST-WP-0040-state-hub-nats-activity-core-integration.md | +| task | CUST-WP-0041-T1 | done | — | workplans/CUST-WP-0041-api-performance.md | +| task | CUST-WP-0041-T2 | done | — | workplans/CUST-WP-0041-api-performance.md | +| task | CUST-WP-0041-T3 | done | — | workplans/CUST-WP-0041-api-performance.md | +| task | CUST-WP-0041-T4 | done | — | workplans/CUST-WP-0041-api-performance.md | +| task | CUST-WP-0043-T01 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0043-T02 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0043-T03 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0043-T04 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0043-T05 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0043-T06 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0043-T07 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0043-T08 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0043-T09 | done | — | workplans/CUST-WP-0043-state-hub-repo-extraction.md | +| task | CUST-WP-0044-T01 | done | — | workplans/CUST-WP-0044-daily-statehub-wsjf-triage.md | +| task | CUST-WP-0044-T02 | done | — | workplans/CUST-WP-0044-daily-statehub-wsjf-triage.md | +| task | CUST-WP-0044-T03 | done | — | workplans/CUST-WP-0044-daily-statehub-wsjf-triage.md | +| task | CUST-WP-0044-T04 | done | — | workplans/CUST-WP-0044-daily-statehub-wsjf-triage.md | +| task | CUST-WP-0044-T05 | done | — | workplans/CUST-WP-0044-daily-statehub-wsjf-triage.md | +| task | CUST-WP-0044-T06 | done | — | workplans/CUST-WP-0044-daily-statehub-wsjf-triage.md | +| task | CUST-WP-0045-T01 | done | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| task | CUST-WP-0045-T02 | done | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| task | CUST-WP-0045-T03 | done | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| task | CUST-WP-0045-T04 | done | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| task | CUST-WP-0045-T05 | done | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| task | CUST-WP-0045-T06 | done | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| task | CUST-WP-0045-T07 | done | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| task | CUST-WP-0045-T08 | done | — | workplans/CUST-WP-0045-activity-core-daily-triage-runner.md | +| task | CUST-WP-0046-T01 | done | — | workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md | +| task | CUST-WP-0046-T02 | done | — | workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md | +| task | CUST-WP-0046-T03 | done | — | workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md | +| task | CUST-WP-0046-T04 | done | — | workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md | +| task | CUST-WP-0046-T05 | done | — | workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md | +| task | CUST-WP-0046-T06 | done | — | workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md | +| task | CUST-WP-0046-T07 | done | — | workplans/CUST-WP-0046-hourly-recently-on-scope-activity-core.md | +| task | CUST-WP-0047-T01 | done | — | workplans/CUST-WP-0047-ops-hub-service-inventory-now-view.md | +| task | CUST-WP-0047-T02 | done | — | workplans/CUST-WP-0047-ops-hub-service-inventory-now-view.md | +| task | CUST-WP-0047-T03 | done | — | workplans/CUST-WP-0047-ops-hub-service-inventory-now-view.md | +| task | CUST-WP-0047-T04 | done | — | workplans/CUST-WP-0047-ops-hub-service-inventory-now-view.md | +| task | CUST-WP-0047-T05 | cancel | — | workplans/CUST-WP-0047-ops-hub-service-inventory-now-view.md | +| task | CUST-WP-0047-T06 | done | — | workplans/CUST-WP-0047-ops-hub-service-inventory-now-view.md | +| task | CUST-WP-0047-T07 | done | — | workplans/CUST-WP-0047-ops-hub-service-inventory-now-view.md | +| task | CUST-WP-0048-T01 | done | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| task | CUST-WP-0048-T02 | done | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| task | CUST-WP-0048-T03 | done | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| task | CUST-WP-0048-T04 | done | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| task | CUST-WP-0048-T05 | done | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| task | CUST-WP-0048-T06 | done | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| task | CUST-WP-0048-T07 | done | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| task | CUST-WP-0048-T08 | done | — | workplans/CUST-WP-0048-hub-core-state-hub-import-refactor.md | +| task | CUST-WP-0049-T01 | done | — | workplans/CUST-WP-0049-interhub-bootstrap-access-lane.md | +| task | CUST-WP-0049-T02 | done | — | workplans/CUST-WP-0049-interhub-bootstrap-access-lane.md | +| task | CUST-WP-0049-T03 | done | — | workplans/CUST-WP-0049-interhub-bootstrap-access-lane.md | +| task | CUST-WP-0049-T04 | done | — | workplans/CUST-WP-0049-interhub-bootstrap-access-lane.md | +| task | CUST-WP-0049-T05 | done | — | workplans/CUST-WP-0049-interhub-bootstrap-access-lane.md | +| task | CUST-WP-0049-T06 | cancel | — | workplans/CUST-WP-0049-interhub-bootstrap-access-lane.md | +| task | CUST-WP-0050-T01 | done | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T02 | done | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T03 | cancel | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T04 | cancel | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T05 | cancel | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T06 | cancel | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T07 | cancel | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T08 | cancel | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T09 | cancel | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T10 | cancel | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0050-T11 | done | — | workplans/CUST-WP-0050-repo-classification-registration-redesign.md | +| task | CUST-WP-0051-T01 | done | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| task | CUST-WP-0051-T02 | done | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| task | CUST-WP-0051-T03 | done | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| task | CUST-WP-0051-T04 | done | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| task | CUST-WP-0051-T05 | done | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| task | CUST-WP-0051-T06 | done | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| task | CUST-WP-0051-T07 | done | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| task | CUST-WP-0051-T08 | done | — | workplans/CUST-WP-0051-infrastructure-stabilization-metaplan.md | +| task | CUST-WP-0052-T01 | done | — | workplans/CUST-WP-0052-core-hub-fos-reset.md | +| task | CUST-WP-0052-T02 | done | — | workplans/CUST-WP-0052-core-hub-fos-reset.md | +| task | CUST-WP-0052-T03 | done | — | workplans/CUST-WP-0052-core-hub-fos-reset.md | +| task | CUST-WP-0052-T04 | done | — | workplans/CUST-WP-0052-core-hub-fos-reset.md | +| task | CUST-WP-0052-T05 | done | — | workplans/CUST-WP-0052-core-hub-fos-reset.md | +| task | CUST-WP-0052-T06 | done | — | workplans/CUST-WP-0052-core-hub-fos-reset.md | +| task | CUST-WP-0052-T07 | done | — | workplans/CUST-WP-0052-core-hub-fos-reset.md | +| task | CUST-WP-0053-T01 | done | — | workplans/CUST-WP-0053-coordination-hygiene-improvements.md | +| task | CUST-WP-0053-T02 | done | — | workplans/CUST-WP-0053-coordination-hygiene-improvements.md | +| task | CUST-WP-0053-T03 | done | — | workplans/CUST-WP-0053-coordination-hygiene-improvements.md | +| task | CUST-WP-0053-T04 | done | — | workplans/CUST-WP-0053-coordination-hygiene-improvements.md | +| task | CUST-WP-0053-T05 | done | — | workplans/CUST-WP-0053-coordination-hygiene-improvements.md | +| task | CUST-WP-0055-T01 | done | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| task | CUST-WP-0055-T02 | done | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| task | CUST-WP-0055-T03 | done | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| task | CUST-WP-0055-T04 | done | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| task | CUST-WP-0055-T05 | done | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| task | CUST-WP-0055-T06 | done | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| task | CUST-WP-0055-T07 | done | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| task | CUST-WP-0055-T08 | done | — | workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md | +| task | CUST-WP-0056-T01 | done | — | workplans/CUST-WP-0056-daily-todo-md-stale-review.md | +| task | CUST-WP-0056-T02 | done | — | workplans/CUST-WP-0056-daily-todo-md-stale-review.md | +| task | CUST-WP-0056-T03 | done | — | workplans/CUST-WP-0056-daily-todo-md-stale-review.md | +| task | CUST-WP-0059-T01 | done | — | workplans/CUST-WP-0059-forgejo-ci-publish-cutover-tail.md | +| task | CUST-WP-0059-T02 | done | — | workplans/CUST-WP-0059-forgejo-ci-publish-cutover-tail.md | +| task | CUST-WP-0059-T03 | done | — | workplans/CUST-WP-0059-forgejo-ci-publish-cutover-tail.md | +| task | CUST-WP-0059-T04 | done | — | workplans/CUST-WP-0059-forgejo-ci-publish-cutover-tail.md | +| task | CUST-WP-0059-T05 | done | — | workplans/CUST-WP-0059-forgejo-ci-publish-cutover-tail.md | +| task | CUST-WP-0059-T06 | done | — | workplans/CUST-WP-0059-forgejo-ci-publish-cutover-tail.md | +| task | CUST-WP-0060-T01 | done | — | workplans/CUST-WP-0060-work-record-canonization.md | +| task | CUST-WP-0060-T02 | done | — | workplans/CUST-WP-0060-work-record-canonization.md | +| task | CUST-WP-0060-T03 | done | — | workplans/CUST-WP-0060-work-record-canonization.md | +| task | CUST-WP-0060-T04 | done | — | workplans/CUST-WP-0060-work-record-canonization.md | +| task | CUST-WP-0060-T05 | done | — | workplans/CUST-WP-0060-work-record-canonization.md | +| task | CUST-WP-0060-T06 | done | — | workplans/CUST-WP-0060-work-record-canonization.md | +| task | CUST-WP-0060-T07 | done | — | workplans/CUST-WP-0060-work-record-canonization.md | +| task | CUST-WP-0061-T01 | done | — | workplans/CUST-WP-0061-work-record-stage3-intake-promotion-index.md | +| task | CUST-WP-0061-T02 | done | — | workplans/CUST-WP-0061-work-record-stage3-intake-promotion-index.md | +| task | CUST-WP-0061-T03 | done | — | workplans/CUST-WP-0061-work-record-stage3-intake-promotion-index.md | +| task | CUST-WP-0061-T04 | done | — | workplans/CUST-WP-0061-work-record-stage3-intake-promotion-index.md | +| task | CUST-WP-0061-T05 | done | — | workplans/CUST-WP-0061-work-record-stage3-intake-promotion-index.md | +| task | CUST-WP-0061-T06 | done | — | workplans/CUST-WP-0061-work-record-stage3-intake-promotion-index.md | +| task | CUST-WP-0062-T01 | done | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md | +| task | CUST-WP-0062-T02 | done | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md | +| task | CUST-WP-0062-T03 | done | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md | +| task | CUST-WP-0062-T04 | done | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md | +| task | CUST-WP-0062-T05 | done | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md | +| task | CUST-WP-0062-T06 | done | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md | +| task | CUST-WP-0063-T01 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md | +| task | CUST-WP-0063-T02 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md | +| task | CUST-WP-0063-T03 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md | +| task | CUST-WP-0063-T04 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md | +| task | CUST-WP-0063-T05 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md | +| task | CUST-WP-0064-T01 | done | — | workplans/CUST-WP-0064-sbom-controlled-scan-inputs.md | +| task | CUST-WP-0064-T02 | done | — | workplans/CUST-WP-0064-sbom-controlled-scan-inputs.md | +| task | CUST-WP-0064-T03 | done | — | workplans/CUST-WP-0064-sbom-controlled-scan-inputs.md | +| task | CUST-WP-0064-T04 | done | — | workplans/CUST-WP-0064-sbom-controlled-scan-inputs.md | +| task | CUST-WP-0065-T01 | done | — | workplans/CUST-WP-0065-reclassify-repos-and-guidance-docs-to-the-new-sector-domain.md | +| task | CUST-WP-0065-T02 | done | — | workplans/CUST-WP-0065-reclassify-repos-and-guidance-docs-to-the-new-sector-domain.md | +| task | CUST-WP-0065-T03 | done | — | workplans/CUST-WP-0065-reclassify-repos-and-guidance-docs-to-the-new-sector-domain.md | +| task | CUST-WP-0065-T04 | done | — | workplans/CUST-WP-0065-reclassify-repos-and-guidance-docs-to-the-new-sector-domain.md | +| task | CUST-WP-0066-T01 | done | — | workplans/CUST-WP-0066-repository-qualified-ad-hoc-identifiers.md | +| task | CUST-WP-0066-T02 | done | — | workplans/CUST-WP-0066-repository-qualified-ad-hoc-identifiers.md | +| task | CUST-WP-0066-T03 | done | — | workplans/CUST-WP-0066-repository-qualified-ad-hoc-identifiers.md | +| task | CUST-WP-0067-T01 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T02 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T03 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T04 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T05 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T06 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T07 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T08 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T09 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0067-T10 | done | — | workplans/CUST-WP-0067-hub-authority-target-resolution.md | +| task | CUST-WP-0068-T01 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0068-T02 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0068-T03 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0068-T04 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0068-T05 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0068-T06 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0068-T07 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0068-T08 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0068-T09 | done | — | workplans/CUST-WP-0068-cache-only-work-record-recovery.md | +| task | CUST-WP-0070-T01 | done | — | workplans/CUST-WP-0070-publication-repo-category.md | +| task | CUST-WP-0070-T02 | done | — | workplans/CUST-WP-0070-publication-repo-category.md | +| task | CUST-WP-0070-T03 | done | — | workplans/CUST-WP-0070-publication-repo-category.md | +| task | CUST-WP-0071-T01 | done | — | workplans/CUST-WP-0071-measured-workload-sizing-and-weekly-review.md | +| task | CUST-WP-0071-T02 | wait | — | workplans/CUST-WP-0071-measured-workload-sizing-and-weekly-review.md | +| task | CUST-WP-0071-T03 | wait | — | workplans/CUST-WP-0071-measured-workload-sizing-and-weekly-review.md | +| task | CUST-WP-0071-T04 | wait | — | workplans/CUST-WP-0071-measured-workload-sizing-and-weekly-review.md | +| task | CUST-WP-0071-T05 | wait | — | workplans/CUST-WP-0071-measured-workload-sizing-and-weekly-review.md | +| task | CUST-WP-0072-T01 | done | — | workplans/CUST-WP-0072-fleet-flavor-and-depends-on-backfill.md | +| task | CUST-WP-0072-T02 | done | — | workplans/CUST-WP-0072-fleet-flavor-and-depends-on-backfill.md | +| task | CUST-WP-0072-T03 | done | — | workplans/CUST-WP-0072-fleet-flavor-and-depends-on-backfill.md | +| task | CUST-WP-0072-T04 | done | — | workplans/CUST-WP-0072-fleet-flavor-and-depends-on-backfill.md | +| task | CUST-WP-0073-T01 | done | — | workplans/CUST-WP-0073-agent-credential-separation.md | +| task | CUST-WP-0073-T02 | wait | — | workplans/CUST-WP-0073-agent-credential-separation.md | +| task | CUST-WP-0073-T03 | done | — | workplans/CUST-WP-0073-agent-credential-separation.md | +| task | CUST-WP-0073-T04 | wait | — | workplans/CUST-WP-0073-agent-credential-separation.md | +| task | CUST-WP-0073-T05 | wait | — | workplans/CUST-WP-0073-agent-credential-separation.md | +| task | CUST-WP-0074-T01 | done | — | workplans/CUST-WP-0074-qualified-wait-states.md | +| task | CUST-WP-0074-T02 | done | — | workplans/CUST-WP-0074-qualified-wait-states.md | +| task | CUST-WP-0074-T03 | done | — | workplans/CUST-WP-0074-qualified-wait-states.md | +| task | CUST-WP-0074-T04 | done | — | workplans/CUST-WP-0074-qualified-wait-states.md | +| task | CUST-WP-0074-T05 | done | — | workplans/CUST-WP-0074-qualified-wait-states.md | +| task | CUST-WP-0074-T06 | done | — | workplans/CUST-WP-0074-qualified-wait-states.md | +| task | CUST-WP-0075-T01 | done | — | workplans/CUST-WP-0075-dependency-graph-driven-unblocking.md | +| task | CUST-WP-0075-T02 | done | — | workplans/CUST-WP-0075-dependency-graph-driven-unblocking.md | +| task | CUST-WP-0075-T03 | done | — | workplans/CUST-WP-0075-dependency-graph-driven-unblocking.md | +| task | CUST-WP-0075-T04 | done | — | workplans/CUST-WP-0075-dependency-graph-driven-unblocking.md | +| task | CUST-WP-0075-T05 | done | — | workplans/CUST-WP-0075-dependency-graph-driven-unblocking.md | +| task | CUST-WP-0075-T06 | done | — | workplans/CUST-WP-0075-dependency-graph-driven-unblocking.md | +| task | CUST-WP-0076-T01 | done | — | workplans/CUST-WP-0076-provisioning-window-cadence.md | +| task | CUST-WP-0077-T01 | done | — | workplans/CUST-WP-0077-dependency-root-execution-wave.md | +| task | CUST-WP-0077-T02 | done | — | workplans/CUST-WP-0077-dependency-root-execution-wave.md | +| task | CUST-WP-0077-T03 | done | — | workplans/CUST-WP-0077-dependency-root-execution-wave.md | +| task | CUST-WP-0077-T04 | done | — | workplans/CUST-WP-0077-dependency-root-execution-wave.md | +| task | CUST-WP-0077-T05 | done | — | workplans/CUST-WP-0077-dependency-root-execution-wave.md | +| task | CUST-WP-0078-T01 | done | — | workplans/CUST-WP-0078-security-collaboration-consolidation.md | +| task | CUST-WP-0078-T02 | done | — | workplans/CUST-WP-0078-security-collaboration-consolidation.md | +| task | CUST-WP-0078-T03 | done | — | workplans/CUST-WP-0078-security-collaboration-consolidation.md | +| task | CUST-WP-0078-T04 | done | — | workplans/CUST-WP-0078-security-collaboration-consolidation.md | +| task | CUST-WP-0079-T01 | done | — | workplans/CUST-WP-0079-deterministic-security-flow.md | +| task | CUST-WP-0079-T02 | done | — | workplans/CUST-WP-0079-deterministic-security-flow.md | +| task | CUST-WP-0079-T03 | wait | — | workplans/CUST-WP-0079-deterministic-security-flow.md | +| task | CUST-WP-0079-T04 | wait | — | workplans/CUST-WP-0079-deterministic-security-flow.md | +| task | CUST-WP-0079-T05 | wait | — | workplans/CUST-WP-0079-deterministic-security-flow.md | +| task | CUST-WP-0079-T06 | wait | — | workplans/CUST-WP-0079-deterministic-security-flow.md | +| task | CUST-WP-0079-T07 | done | — | workplans/CUST-WP-0079-deterministic-security-flow.md | +| task | CUST-WP-0080-T01 | done | — | workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md | +| task | CUST-WP-0080-T02 | done | — | workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md | +| task | CUST-WP-0080-T03 | progress | — | workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md | +| task | CUST-WP-0080-T04 | todo | — | workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md | +| task | CUST-WP-0080-T05 | progress | — | workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md | +| task | CUST-WP-0080-T06 | progress | — | workplans/CUST-WP-0080-netkingdom-security-blueprint-and-gap-closure.md | +| task | CUST-WP-0081-T01 | done | — | workplans/CUST-WP-0081-netkingdom-architecture-review-and-reuse.md | +| task | CUST-WP-0081-T02 | done | — | workplans/CUST-WP-0081-netkingdom-architecture-review-and-reuse.md | +| task | CUST-WP-0081-T03 | done | — | workplans/CUST-WP-0081-netkingdom-architecture-review-and-reuse.md | +| task | THE-WP-0001-T01 | done | — | workplans/THE-WP-0001-federation-interface.md | +| task | THE-WP-0001-T02 | done | — | workplans/THE-WP-0001-federation-interface.md | +| intake | CUST-IN-0001 | closed | green | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0002 | closed | green | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0003 | closed | green | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0004 | routed | green | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0005 | closed | green | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0006 | closed | green | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0007 | closed | green | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0008 | closed | blue | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0009 | closed | blue | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0010 | closed | green | intake-legacy-suggestions-migration.md | +| intake | CUST-IN-0011 | routed | red | intakes.md | +| intake | CUST-IN-0012 | closed | green | intakes.md | +| intake | CUST-IN-0013 | closed | blue | intakes.md | +| intake | CUST-IN-0014 | closed | blue | intakes.md | +| intake | CUST-IN-0015 | open | blue | intakes.md | +| intake | CUST-IN-0016 | open | green | intakes.md | +| intake | CUST-IN-0017 | open | green | intakes.md | +| intake | CUST-IN-0018 | open | green | intakes.md | diff --git a/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/originals.json b/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/originals.json new file mode 100644 index 00000000..82d0dc78 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/custodian-publication-backup/originals.json @@ -0,0 +1 @@ +{".custodian-brief.md": "100644 6aad3a5788fad3abd60c0f1270f160062dc0168b 0\t.custodian-brief.md\n", "WORK-RECORDS.md": "100644 d535e0f2dcc3d454e041a8f1b547b5dea4493380 0\tWORK-RECORDS.md\n"} \ No newline at end of file diff --git a/docs/changes/netkingdom-target-2026-10-17/final-progress.json b/docs/changes/netkingdom-target-2026-10-17/final-progress.json new file mode 100644 index 00000000..ac8ff511 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/final-progress.json @@ -0,0 +1,14 @@ +{ + "workplan_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52", + "id": "f0a63cac-9b78-4331-82a9-b96747e4e71b", + "topic_id": null, + "task_id": null, + "decision_id": null, + "event_type": "note", + "summary": "Published Custodian checkpoint f8c7dfa2a9c7919879b62c77eb39582b3e23654e with exact pending State Hub rollout proposal (revision 4, digest 63a02e8296d126c0158b7eb2c4ce79c7eeb6f8d6f61298d473c1065c7557ba32). Required consistency and primary/railiance01 projection pass. All 81 task bindings checked across Custodian, NetKingdom, State Hub, Repo Manager and Secrets; original staged brief, work records and six assessments preserved. Published owner milestones NK48-T21, NK49-T37, RMGR21-T05, SECRETS-WP-0015 and STATE95-T05/T08. RCLUSTER-WP-0018 awaits verified receiving rollout before lawful publication. All 16 native target gates remain open. No live rollout, registrar activation, original credential recovery, rotation or authority promotion. Founder review is the next State Hub rollout gate; foreign waits have four coordination receipts without messages or worker wakes.", + "detail": null, + "author": "codex", + "session_id": null, + "created_at": "2026-10-16T23:51:19.540708Z", + "workstream_id": "dfadb19b-445e-59c6-bcd6-48e87b912c52" +} diff --git a/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/README.md b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/README.md new file mode 100644 index 00000000..a761e474 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/README.md @@ -0,0 +1,97 @@ +# Forgejo private client-secret input: separate source revision + +This packet implements `--secret-file` in the actual Forgejo 11.0.3 add/update +OAuth handlers and patches the actual Gitea chart 12.5.0. Apply the unchanged +reviewed seven-path any-of patch first, then this incremental Forgejo patch. +The original candidate and completed release-build packets remain unchanged. +No canonical owner implementation, case/type, authority, image or deployment is +changed. The new backend executable is test evidence, not an admitted image. + +The existing three-group exact any-of gate and mandatory current-UserInfo guard +remain in the reviewed implementation. Six reviewed non-CLI source paths retain +exact hashes. Actual cmd/oauth2 package tests exercise them again. The exact shared database +confidentiality dependency is documented in [SQL-CONFIDENTIALITY.md](SQL-CONFIDENTIALITY.md); +apply it once when composing source candidates. Both handlers refuse raw SQL +logging, mark queries for hook/trace redaction, and private-file persistence +failures return fixed errors. Update without +secret flags preserves the stored secret; selecting a private input completes +its checks before DB initialization or source mutation. Explicit legacy +`--secret` behavior is preserved. Both flags together, including an empty legacy +flag, refuse. The file value never enters the CLI context, argv or environment. + +On Linux the reader walks absolute, normalized paths with descriptor-relative +non-following opens, rejects writable-by-group/other parents and foreign-owned +parents, and opens the leaf nonblocking so FIFO input cannot hang. It requires a +single-link regular file, root/euid ownership, no write/execute/special/other-read +bits, an admitted process group for group-readable files, and an actual read-only +mount. It bounds the read at 65 bytes and compares file identity/size/ownership/ +mode/mtime/ctime and the named leaf after reading. Read-induced atime is allowed. +Every file-input failure has the same fixed error without path or value. Other +platforms fail closed. The accepted format matches the actual mint implementation: +48 random bytes encoded by `secrets.token_urlsafe`, exactly 64 ASCII base64url +characters with no padding or newline. Values are preserved exactly; no trimming +occurs. The transient read buffer is cleared; the existing DB/provider string +custody and process memory remain the existing software contract. + +The chart helper suppresses automatic `--secret` when `secretFile` is present. +It refuses `secret`, `existingSecret`, indexed secret env collisions, multiple +private entries, a different path, conflicting extra mounts/volume and a different +fsGroup. Its bounded private route emits the fixed path and mounts existing +`forgejo-netkingdom-oidc-client` key `CLIENT_SECRET` read-only by file `subPath` +into **configure-gitea only**, with mode 0440 and pod fsGroup 1000. No alias key, +new secret read/ACL, value-bearing env or value-bearing agent command is added. +Legacy sources retain their existing automatic argument behavior. Exact public +release values are deliberately not emitted by these synthetic controls. + +Linux Kubernetes Secret volumes normally retain root UID. The fsGroup ownership +pass changes GID and adds read permissions, so root:1000 mode 0440 is expected; +requiring euid ownership would incorrectly refuse this case. The retained public +[Kubernetes ownership implementation](https://github.com/kubernetes/kubernetes/blob/v1.34.1/pkg/volume/volume_linux.go) +and [Secret volume implementation](https://github.com/kubernetes/kubernetes/blob/v1.34.1/pkg/volume/secret/secret.go) +show those details. File subPath bind mounting avoids the projected symlink leaf; +[Secret subPath mounts do not receive automatic updates](https://kubernetes.io/docs/concepts/configuration/secret/#using-secrets-as-files-from-a-pod). +An owner-controlled restart/refresh is required on rotation. These public source +findings are not observations of the estate's running kubelet or pod. + +DAC and a read-only mount cannot identify a Kubernetes namespace, Secret object, +operation session, or authorized reader set. The reader intentionally makes no +such admission claim. Actual runtime admission must bind the exact owner +workload, image, namespace, mount/parent ownership, UID/GID/mode, reader set, +rotation and current authenticated operation. Arbitrary privileged code or a +malicious workload owner remains outside this input reader's protection. +T34 persistence/readback/CAS, durable journal, writer exclusion, operation/inverse +sessions and the application-state inverse remain separate owner work. A Helm +rollback alone does not reverse persisted source state. + +The retained checks compile the actual complete backend and execute actual +binary CLI subprocesses against a synthetic SQLite database. They cover add, +replacement, omission, preservation of unrelated configuration and guarded +three-group fields, bad-path/input refusals and conflicts without DB changes, +and absence of values in argv/env/stdout/stderr. Actual Linux descriptor tests +exercise opened-inode/name replacement, while metadata controls include +root:fsGroup 0440 and prohibited modes. Actual Helm rendering covers both command +forms, the Secret/mount references, legacy behavior, and refusal without leaking +a conflicting synthetic marker. Guard tests use in-memory HTTP transports. The +CLI guarded-update persistence control uses an inactive source to avoid discovery; +it is not a browser login or an active OIDC registration proof. + +Final decisive build/test profiles use bwrap PID and network isolation, public-only source/cache +mounts, an empty test HOME and a closed environment. No host HOME/config, +credentials, cluster, OpenBao, registry publication, model call or live secret is +used. No full frontend/container/image rebuild was launched. Earlier profiles without PID isolation, initial fixture and +sandbox harness failures, a reproduced synthetic SQL leak before correction, +and the earlier-revision replay failure are retained, as is the initial chart metadata mismatch +and its exact published-metadata reconstruction; none is counted as a successful +runtime trial. + +Run a fresh reconstruction and all actual checks with the retained public cache: + +```sh +python3 tests/replay_offline.py --public-cache /tmp/forgejo-independent-r1 +``` + +This creates fresh `/tmp` source/work/evidence, applies both exact patches, and +builds only a backend test executable. It needs bwrap, patch, Python/PyYAML, the +existing Helm executable and the already retained public Go/module cache. The +packet includes only changed source pre/postimages, small public provenance, +patches and tests; no vendored full source, binary or image is included. diff --git a/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/SQL-CONFIDENTIALITY.md b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/SQL-CONFIDENTIALITY.md new file mode 100644 index 00000000..38474ae3 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/SQL-CONFIDENTIALITY.md @@ -0,0 +1,33 @@ +# Shared database confidentiality dependency + +Private-file input was insufficient by itself: an actual previous-revision CLI +add with `database.LOG_SQL=true` exposed the synthetic client secret in XORM +output. `evidence/sql-leak-before.log` retains the failed leak assertion without +printing the captured value. This is an implementation finding, not an accepted +runtime trial. Disabling raw SQL output alone also leaves the existing slow, +error and runtime trace hooks, which include query arguments/driver errors. + +The common dependency is exactly the separately prepared Apps operation-backend +implementation, not a competing helper. Its API is `db.WithSensitiveSQL(ctx)`. +The actual SQL/slow/error/trace hooks redact statement/arguments/driver errors +when that context marker is present. The dependency's actual hook tests retain +positive unredacted controls, including a real runtime trace buffer. Custom +DB/server audit outside this process remains an owner custody concern. + +Apply `shared-db-confidentiality.patch` exactly once when composing both source +candidates. Its three postimages must match the operation-backend source: + +| Path | SHA-256 | +| --- | --- | +| `models/db/engine.go` | `43683804d0c5bc6ead1dba0344c69dd196825cf3d5eb502af8d932a7b8207b96` | +| `models/db/sensitive_sql.go` | `8d4e6b3f08e9fdd919e97e47bd857cbd8935fdcbf367d20b5b8c545f279e796e` | +| `models/db/sensitive_sql_test.go` | `f0f74c09a9e96a6529db7b9ce459a2ea37e204de38c5ad01855b80c9a992a769` | + +Both actual OAuth CLI handlers preserve the marked context through database +queries. They refuse configured raw SQL logging **and** actual XORM logger +ShowSQL before source reads/writes; a configuration boolean alone is insufficient. +Private-file persistence failures return fixed errors. This deliberately refuses +debug SQL logging for these handlers instead of pretending it is a private path. +The legacy secret flag and update omission semantics otherwise remain intact. +Final controls include actual `LOG_SQL=true` refusal, low-threshold slow-query +hooks, and a real SQLite-triggered write failure with unchanged stored source. diff --git a/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/chart-private-input.patch b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/chart-private-input.patch new file mode 100644 index 00000000..53661e14 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/chart-private-input.patch @@ -0,0 +1,90 @@ +diff --git a/templates/_helpers.tpl b/templates/_helpers.tpl +--- a/templates/_helpers.tpl ++++ b/templates/_helpers.tpl +@@ -201,7 +201,15 @@ + {{- $_ := set $values "key" (printf "${GITEA_OAUTH_KEY_%d}" $idx) -}} + {{- end -}} + +-{{- if not (hasKey $values "secret") -}} ++{{- if hasKey $values "secretFile" -}} ++{{- if or (hasKey $values "secret") (hasKey $values "existingSecret") -}} ++{{- fail "OAuth secretFile conflicts with secret or existingSecret" -}} ++{{- end -}} ++{{- if ne $values.secretFile "/run/forgejo-oidc/CLIENT_SECRET" -}} ++{{- fail "OAuth secretFile requires the admitted mount path" -}} ++{{- end -}} ++{{- end -}} ++{{- if and (not (hasKey $values "secret")) (not (hasKey $values "secretFile")) -}} + {{- $_ := set $values "secret" (printf "${GITEA_OAUTH_SECRET_%d}" $idx) -}} + {{- end -}} + +@@ -471,3 +479,28 @@ + {{- define "gitea.metrics-secret-name" -}} + {{ default (printf "%s-metrics-secret" (include "gitea.fullname" .)) }} + {{- end -}} ++ ++{{/* Bounded first-case source continuation; no Secret value or alias key. */}} ++{{- define "gitea.oauth_private_validate" -}} ++{{- $private := 0 -}} ++{{- range $idx, $value := .Values.gitea.oauth -}} ++{{- if hasKey $value "secretFile" -}} ++{{- $private = add1 $private -}} ++{{- range $.Values.deployment.env -}} ++{{- if eq .name (printf "GITEA_OAUTH_SECRET_%d" $idx) -}} ++{{- fail "OAuth secretFile conflicts with indexed secret environment" -}} ++{{- end -}} ++{{- end -}} ++{{- end -}} ++{{- end -}} ++{{- if gt $private 1 -}}{{- fail "Only one private OAuth mount is supported" -}}{{- end -}} ++{{- if gt $private 0 -}} ++{{- if ne (int .Values.podSecurityContext.fsGroup) 1000 -}}{{- fail "Private OAuth mount requires fsGroup 1000" -}}{{- end -}} ++{{- range .Values.extraVolumes -}} ++{{- if eq .name "oauth-private-client" -}}{{- fail "Private OAuth volume conflict" -}}{{- end -}} ++{{- end -}} ++{{- range concat .Values.extraVolumeMounts .Values.extraInitVolumeMounts .Values.extraContainerVolumeMounts -}} ++{{- if or (eq .name "oauth-private-client") (hasPrefix "/run/forgejo-oidc" .mountPath) -}}{{- fail "Private OAuth mount conflict" -}}{{- end -}} ++{{- end -}} ++{{- end -}} ++{{- end -}} +diff --git a/templates/gitea/deployment.yaml b/templates/gitea/deployment.yaml +--- a/templates/gitea/deployment.yaml ++++ b/templates/gitea/deployment.yaml +@@ -1,3 +1,4 @@ ++{{- include "gitea.oauth_private_validate" . -}} + apiVersion: apps/v1 + kind: Deployment + metadata: +@@ -260,6 +261,14 @@ + {{- toYaml .Values.deployment.env | nindent 12 }} + {{- end }} + volumeMounts: ++ {{- range .Values.gitea.oauth }} ++ {{- if hasKey . "secretFile" }} ++ - name: oauth-private-client ++ mountPath: /run/forgejo-oidc/CLIENT_SECRET ++ subPath: CLIENT_SECRET ++ readOnly: true ++ {{- end }} ++ {{- end }} + - name: init + mountPath: {{ .Values.initContainersScriptsVolumeMountPath }} + - name: temp +@@ -388,6 +397,17 @@ + {{- toYaml .Values.dnsConfig | nindent 8 }} + {{- end }} + volumes: ++ {{- range .Values.gitea.oauth }} ++ {{- if hasKey . "secretFile" }} ++ - name: oauth-private-client ++ secret: ++ secretName: forgejo-netkingdom-oidc-client ++ defaultMode: 288 ++ items: ++ - key: CLIENT_SECRET ++ path: CLIENT_SECRET ++ {{- end }} ++ {{- end }} + - name: init + secret: + secretName: {{ include "gitea.fullname" . }}-init diff --git a/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/evidence/build-result-before-fd-helper.json b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/evidence/build-result-before-fd-helper.json new file mode 100644 index 00000000..5143d220 --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/evidence/build-result-before-fd-helper.json @@ -0,0 +1,15 @@ +{ + "returncode": 0, + "seconds": 79.25860216701403, + "argv": [ + "go", + "build", + "-p", + "4", + "-tags", + "sqlite sqlite_unlock_notify", + "-o", + "/tmp/forgejo-private-work/forgejo", + "." + ] +} \ No newline at end of file diff --git a/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/evidence/build-result-before-sql-hooks.json b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/evidence/build-result-before-sql-hooks.json new file mode 100644 index 00000000..18b96cae --- /dev/null +++ b/docs/changes/netkingdom-target-2026-10-17/forgejo-private-input-r1/evidence/build-result-before-sql-hooks.json @@ -0,0 +1,15 @@ +{ + "returncode": 0, + "seconds": 50.04432745499071, + "argv": [ + "go", + "build", + "-p", + "4", + "-tags", + "sqlite sqlite_unlock_notify", + "-o", + "/tmp/forgejo-private-work/forgejo", + "." + ] +} \ No newline at end of file