91 lines
4.8 KiB
Python
91 lines
4.8 KiB
Python
"""Apply coordinator-reviewed exact patches; never deploy or enable registrar."""
|
|
from pathlib import Path
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
import subprocess
|
|
|
|
BASE = Path(__file__).resolve().parent
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('lane', choices=['receiver', 'sops-record', 'postgres', 'receiver-readiness'])
|
|
args = parser.parse_args()
|
|
|
|
def sha(path):
|
|
return hashlib.sha256(path.read_bytes()).hexdigest()
|
|
|
|
if args.lane == 'receiver':
|
|
packet = BASE.parent / 'netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r2'
|
|
frozen = json.loads((packet / 'review-freeze.json').read_text())
|
|
assert sha(packet / 'review-freeze.json') == 'eac2671eb3ac08e2a1eacc333482fc2638ccb895041781b04e8733b4b7d5a0f8'
|
|
for item in frozen['files']:
|
|
assert sha(packet / item['path']) == item['sha256'].removeprefix('sha256:')
|
|
expected = json.loads((packet / 'source-patch-manifest.json').read_text())['repos']['state-hub']
|
|
root = Path('/home/worsch/state-hub')
|
|
patch = packet / 'state-hub.patch'
|
|
revision = expected['base_revision']
|
|
pin = expected['patch_sha256']
|
|
pre = {x['path']: x['base_sha256'] for x in expected['files']}
|
|
post = {x['path']: x['candidate_sha256'] for x in expected['files']}
|
|
elif args.lane == 'sops-record':
|
|
packet = BASE / 'wp49-sops-successor-r1'
|
|
expected = json.loads((packet / 'manifest.json').read_text())
|
|
root = Path('/home/worsch/net-kingdom')
|
|
patch = packet / 'owner-refinement.patch'
|
|
revision = expected['owner_head']
|
|
pin = '5364b1966334869c71a58ff2d90194db45c7ea6f3e60d57327a231f558437641'
|
|
pre = {expected['path']: expected['preimage_sha256']}
|
|
post = {expected['path']: expected['result_sha256']}
|
|
elif args.lane == 'postgres':
|
|
packet = BASE.parent / 'netkingdom-target-2026-10-16/group-postgres-r1'
|
|
expected = json.loads((packet / 'source-manifest.json').read_text())
|
|
root = Path('/home/worsch/net-kingdom')
|
|
patch = packet / 'source.patch'
|
|
revision = expected['base_revision']
|
|
pin = '5549d2982b61ff70aba4b3928fecd5639db0f1a732ab2f8630f678e7acf4d34d'
|
|
pre = {x['path']: x['preimage_sha256'] for x in expected['files']}
|
|
post = {x['path']: x['postimage_sha256'] for x in expected['files']}
|
|
else:
|
|
packet = BASE.parent / 'netkingdom-target-2026-10-16/cluster-historical-publication-r1/revisions/r3-readiness'
|
|
assert sha(packet / 'review-freeze.json') == 'ab5c12f71a75101184ae9e722d3c4f3145aad37d3c868879a26fa384de099483'
|
|
frozen = json.loads((packet / 'review-freeze.json').read_text())
|
|
for item in frozen['files']:
|
|
assert sha(packet / item['path']) == item['sha256'].removeprefix('sha256:')
|
|
expected = json.loads((packet / 'source-patch-manifest.json').read_text())
|
|
root = Path('/home/worsch/state-hub')
|
|
patch = packet / 'state-hub-readiness.patch'
|
|
revision = expected['base_revision']
|
|
pin = '4c52fd5a102df43ceb8e007d93d34efe861a3b321527cf5f3e195e35113c36a0'
|
|
pre = {x['path']: x['base_sha256'] for x in expected['files']}
|
|
post = {x['path']: x['candidate_sha256'] for x in expected['files']}
|
|
|
|
def git(*argv):
|
|
return subprocess.check_output(['git', '-C', str(root), *argv], stderr=subprocess.PIPE)
|
|
|
|
assert git('rev-parse', 'HEAD').decode().strip() == revision
|
|
assert sha(patch) == pin
|
|
paths = [line[6:] for line in patch.read_text().splitlines() if line.startswith('+++ b/')]
|
|
assert len(paths) == len(set(paths)) and set(paths) == set(post)
|
|
index = git('ls-files', '--stage', '-z')
|
|
for name in paths:
|
|
assert not Path(name).is_absolute() and '..' not in Path(name).parts
|
|
assert not git('status', '--porcelain', '--', name).strip()
|
|
assert (sha(root / name) if (root / name).exists() else None) == pre[name]
|
|
git('apply', '--check', str(patch))
|
|
git('apply', str(patch))
|
|
if args.lane == 'postgres':
|
|
wp = packet / 'final-integration-r1/workplan.patch'
|
|
assert sha(wp) == 'af9f720fba1b931679f866a29e8b3bc7d08f24a7f653db48daf485e35cb16eea'
|
|
name = 'workplans/NK-WP-0048-security-case-types.md'
|
|
assert not git('status', '--porcelain', '--', name).strip()
|
|
assert sha(root / name) == '08215f6dc91a89706bf456a897d77de4032d47a21cd0252d202249619def135d'
|
|
git('apply', '--check', str(wp))
|
|
git('apply', str(wp))
|
|
post[name] = sha(packet / 'final-integration-r1/workplan.postimage.md')
|
|
assert git('ls-files', '--stage', '-z') == index
|
|
for name, digest in post.items():
|
|
assert sha(root / name) == digest
|
|
receipt = {'owner': root.name, 'base_revision': revision, 'patch_sha256': pin,
|
|
'files': post, 'index_unchanged': True, 'production_mutation': False,
|
|
'registrar_enabled': False, 'status': 'applied_source_only'}
|
|
(BASE / (args.lane + '-followthrough-integration.json')).write_text(json.dumps(receipt, indent=2) + '\n')
|
|
print(json.dumps({'owner': root.name, 'status': receipt['status'], 'files': len(post)}))
|