Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a070b5-4994-7271-bd8b-7c3dbcedec4b
73 lines
4 KiB
Python
73 lines
4 KiB
Python
"""Reproduce T06 ledger/import/provenance checks; requires Python 3 and PyYAML."""
|
|
import argparse
|
|
import hashlib
|
|
import json
|
|
from pathlib import Path
|
|
import re
|
|
import subprocess
|
|
|
|
import yaml
|
|
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('--commerce-repo', type=Path, required=True)
|
|
parser.add_argument('--info-tech-repo', type=Path, required=True)
|
|
args = parser.parse_args()
|
|
commerce = args.commerce_repo.resolve()
|
|
upstream = args.info_tech_repo.resolve()
|
|
evidence = Path(__file__).resolve().parent
|
|
project = evidence.parents[1]
|
|
ledger = json.loads((project / 'ledger/concept-ownership.json').read_text())
|
|
model_path = commerce / 'infospace/models/counterparty/CommerceCanonCounterpartyModel.md'
|
|
model = model_path.read_text()
|
|
fm = yaml.safe_load(model.split('---')[1])
|
|
assigned = [t for e in ledger['entries'] for t in e['targets'] if t['owner']['canon'] == 'commerce-canon']
|
|
owned = {t['concept'] for t in assigned if t['kind'] == 'concept'}
|
|
assert set(fm['owned_concepts']) == owned
|
|
assert len(fm['owned_concepts']) == len(owned) == 18
|
|
assert set(fm['convenience_terms']) == {t['concept'] for t in assigned if t['kind'] == 'convenience_term'}
|
|
assert set(re.findall(r'^### 2\.\d+ (.+)$', model, re.M)) == owned
|
|
registry = yaml.safe_load((commerce / 'canon.yaml').read_text())
|
|
assert len(registry['models']) == 1
|
|
entry = registry['models'][0]
|
|
assert commerce / entry['path'] == model_path
|
|
for key in ['id', 'version', 'status']: assert entry[key] == fm[key]
|
|
manifest = json.loads(model_path.with_name('imports.json').read_text())
|
|
assert set(fm['imports']) == {row['model'] for row in manifest['imports']}
|
|
imports = set()
|
|
upstream_drift = []
|
|
for row in manifest['imports']:
|
|
data = (upstream / row['path']).read_bytes()
|
|
historical = subprocess.check_output(['git', 'show', manifest['source_commit'] + ':' + row['path']], cwd=upstream)
|
|
assert hashlib.sha256(historical).hexdigest() == row['sha256'], 'reviewed commit differs: ' + row['path']
|
|
if data != historical:
|
|
upstream_drift.append(row['path'])
|
|
text = historical.decode()
|
|
if text.startswith('---\n'):
|
|
upstream_fm = yaml.safe_load(text.split('---')[1])
|
|
upstream_owned = set(upstream_fm.get('owned_concepts', []))
|
|
# Organization frontmatter records only its incremental social extension.
|
|
# Include explicit legacy definitions, never bare imported anchors.
|
|
upstream_owned.update(re.findall(r'^(?:An? )?\*\*(.+?)\*\* is\b', text, re.M))
|
|
else:
|
|
upstream_owned = set(re.findall(r'^## \d+\.\d+[a-z]? (.+)$', text, re.M))
|
|
assert set(row['concepts']) <= upstream_owned, set(row['concepts']) - upstream_owned
|
|
imports.update(row['concepts'])
|
|
assert owned.isdisjoint(imports)
|
|
for concept in ['Evidence', 'Evidence Source', 'Adjudication Outcome', 'Evidence strength', 'Identifier', 'Scoped Identifier']:
|
|
assert concept in imports and concept not in owned
|
|
protected = json.loads((evidence / '2026-09-05-counterparty-protected-hashes.json').read_text())
|
|
for path, digest in protected.items():
|
|
assert hashlib.sha256((commerce / path).read_bytes()).hexdigest() == digest, path
|
|
links = 0
|
|
for relative in ['README.md', 'docs/RepositoryLayout.md', 'infospace/kernel/CommerceCanonCore.md',
|
|
'infospace/models/README.md', 'infospace/models/counterparty/CommerceCanonCounterpartyModel.md',
|
|
'workplans/COMMERCE-WP-0002-counterparty-model.md']:
|
|
path = commerce / relative
|
|
for link in re.findall(r'\]\(([^)]+)\)', path.read_text()):
|
|
if '://' in link or link.startswith('#'): continue
|
|
assert (path.parent / link.split('#')[0]).exists(), (relative, link)
|
|
links += 1
|
|
print(json.dumps({'owned_concepts': len(owned), 'convenience_terms': 2,
|
|
'imported_models': len(manifest['imports']), 'imported_concepts': len(imports),
|
|
'upstream_commit': manifest['source_commit'], 'upstream_changes_since_review': upstream_drift, 'protected_files_unchanged': len(protected),
|
|
'links_checked': links, 'registry_and_boundaries': 'pass'}, indent=2))
|