69 lines
4.2 KiB
Python
69 lines
4.2 KiB
Python
"""Refresh the normal authoritative-forge cache without local UUID writeback.
|
|
|
|
The local CLI preview found unrelated missing historical UUIDs. Leave those
|
|
source files and identity decisions unchanged. This uses the very same receiving
|
|
endpoint and its independent derivation/collision/historical-preservation guards,
|
|
with retirement acknowledgement false. It neither patches task rows nor assigns
|
|
source identifiers.
|
|
"""
|
|
from pathlib import Path
|
|
import hashlib
|
|
import json
|
|
import subprocess
|
|
import urllib.error
|
|
import urllib.request
|
|
|
|
HERE = Path(__file__).resolve().parent
|
|
BASE = 'http://127.0.0.1:8000'
|
|
prior = json.loads((HERE / 'owner-bindings-refused-r2.json').read_text())
|
|
issues = [i for i in prior['issues'] if i['field'] == 'record_id']
|
|
assert all(i['actual'] is None for i in issues)
|
|
repos = sorted({i['repo'] for i in issues})
|
|
def git(root, *args):
|
|
return subprocess.check_output(['git', '--no-optional-locks', '-C', str(root), *args], stderr=subprocess.PIPE, timeout=40).decode().strip()
|
|
def get(path):
|
|
return json.load(urllib.request.urlopen(BASE + path, timeout=30))
|
|
health = get('/state/health')
|
|
assert (health['instance_role'], health['instance_label']) == ('primary', 'railiance01')
|
|
receipts = []
|
|
for repo in repos:
|
|
root = Path('/home/worsch') / repo
|
|
head = git(root, 'rev-parse', 'HEAD')
|
|
assert git(root, 'ls-remote', 'origin', 'refs/heads/main').split()[0] == head
|
|
selected = [r for r in prior['rows'] if r['repo'] == repo]
|
|
for row in selected:
|
|
assert hashlib.sha256(Path(row['path']).read_bytes()).hexdigest() == row['sha256']
|
|
assert git(root, 'show', head + ':' + str(Path(row['path']).relative_to(root))) == Path(row['path']).read_text().strip()
|
|
path = '/repos/' + repo + '/work-record-projection/reconcile'
|
|
body = {'expected_commit': head, 'acknowledge_retirements': False}
|
|
key = hashlib.sha256(json.dumps({'path': path, 'body': body, 'missing_records': [i['source'] for i in issues if i['repo'] == repo]}, sort_keys=True).encode()).hexdigest()
|
|
request = urllib.request.Request(BASE + path, data=json.dumps(body).encode(), method='POST',
|
|
headers={'Content-Type': 'application/json', 'Idempotency-Key': 'custodian-record-id-refresh-r1:' + key,
|
|
'X-StateHub-Component': 'the-custodian', 'X-StateHub-Source-Agent': 'the-custodian'})
|
|
try:
|
|
with urllib.request.urlopen(request, timeout=120) as response:
|
|
result = json.load(response)
|
|
except Exception as error:
|
|
failure = {'repo': repo, 'commit': head, 'status': 'failed_or_uncertain',
|
|
'exception_type': type(error).__name__, 'http_status': getattr(error, 'code', None), 'automatic_retry': False}
|
|
(HERE / (repo + '-receiving-refusal.json')).write_text(json.dumps(failure, indent=2) + '\n')
|
|
raise RuntimeError('normal receiving refused; retained metadata; no source mutation or automatic retry') from None
|
|
(HERE / (repo + '-receiving.json')).write_text(json.dumps(result, indent=2) + '\n')
|
|
assert result['expected_commit'] == result['derived_commit'] == head
|
|
assert (result['instance_role'], result['instance_label']) == ('primary', 'railiance01')
|
|
assert result['outcome']['status'] == 'applied' and not result['outcome']['refused']
|
|
snapshot = get('/repos/' + repo + '/work-record-projection/snapshot')
|
|
actual = {t['id']: t for t in snapshot['tasks']}
|
|
for row in selected:
|
|
for old in row['tasks']:
|
|
assert actual[old['uuid']]['status'] == old['status']
|
|
for issue in issues:
|
|
if issue['repo'] == repo:
|
|
assert actual[issue['uuid']]['record_id'] == issue['source']
|
|
assert git(root, 'rev-parse', 'HEAD') == head
|
|
receipts.append({'repo': repo, 'commit': head, 'status': 'applied', 'source_and_uuid_fields_unchanged': True})
|
|
output = {'status': 'verified', 'rows': receipts, 'record_ids_restored': len(issues),
|
|
'source_uuid_gaps': 'Local CLI preview refusal remains; no identity migration or source writeback was performed.',
|
|
'native_target_gates_closed': 0}
|
|
(HERE / 'committed-receiving-result.json').write_text(json.dumps(output, indent=2) + '\n')
|
|
print(json.dumps({'status': 'verified', 'repos': repos, 'record_ids_restored': len(issues)}))
|