Advance dependency roots with guarded source implementations
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a10391-6355-7b41-b0fa-3e14e874f091
This commit is contained in:
parent
9572518310
commit
c41d36c2ef
3 changed files with 143 additions and 1 deletions
85
src/repo_manager/historical_sources.py
Normal file
85
src/repo_manager/historical_sources.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
"""Reviewed closed-source exceptions; enable only after receiving deployment.
|
||||
|
||||
No aliases, new IDs, binding replacement or source edits are authorized.
|
||||
Strict identity scans retain nonconformance findings for these legacy labels.
|
||||
"""
|
||||
from hashlib import sha256
|
||||
import json
|
||||
|
||||
BINDINGS = json.loads(r'''[
|
||||
{
|
||||
"repo": "activity-core",
|
||||
"path": "workplans/archived/260707-custodian-WP-0003-event-bridge.md",
|
||||
"sha256": "83ea8bcb151e003419b73c59dbd028f4a1ce3d1120a82e4a128a772503ff3b76",
|
||||
"record_id": "custodian-WP-0003",
|
||||
"uuid": "b4eb45a9-69e3-4ab0-b00c-67a53c3117c5",
|
||||
"parent_record_id": "custodian-WP-0003"
|
||||
},
|
||||
{
|
||||
"repo": "activity-core",
|
||||
"path": "workplans/custodian-WP-0001-temporal-backbone.md",
|
||||
"sha256": "020e2eac973f2daa41c1687f8e867da9d521f945547e6aa82c87993b3ff6fc64",
|
||||
"record_id": "custodian-WP-0001",
|
||||
"uuid": "e22516cc-4fdf-4dad-a928-a9e04a9fa7c7",
|
||||
"parent_record_id": "custodian-WP-0001"
|
||||
},
|
||||
{
|
||||
"repo": "activity-core",
|
||||
"path": "workplans/custodian-WP-0002-triggers-ops.md",
|
||||
"sha256": "d8cbc61631c01b6f11a03a63f2fb6275fc853ff7f7459ce65973ed1a233daa01",
|
||||
"record_id": "custodian-WP-0002",
|
||||
"uuid": "3a4f47d9-8bc1-434e-acb4-bed5d4dacda0",
|
||||
"parent_record_id": "custodian-WP-0002"
|
||||
},
|
||||
{
|
||||
"repo": "activity-core",
|
||||
"path": "workplans/custodian-WP-0003a-event-bridge-model-rules-registry.md",
|
||||
"sha256": "ffa6682e9ba3aaf559bd44203d561c90dea69bcf1b1e778209a7b209e6e5cdd3",
|
||||
"record_id": "custodian-WP-0003a",
|
||||
"uuid": "b4eb45a9-69e3-4ab0-b00c-67a53c3117c5",
|
||||
"parent_record_id": "custodian-WP-0003"
|
||||
},
|
||||
{
|
||||
"repo": "activity-core",
|
||||
"path": "workplans/custodian-WP-0003b-event-bridge-parser-workflow-triggers.md",
|
||||
"sha256": "4fc34e0f821e2df51e5c08c7ab34da35b65690381d01f0cfdf55d00c970b414c",
|
||||
"record_id": "custodian-WP-0003b",
|
||||
"uuid": "b4eb45a9-69e3-4ab0-b00c-67a53c3117c5",
|
||||
"parent_record_id": "custodian-WP-0003"
|
||||
},
|
||||
{
|
||||
"repo": "activity-core",
|
||||
"path": "workplans/custodian-WP-0003c-event-bridge-context-integration.md",
|
||||
"sha256": "b6cd62b26515e509670ca39736b6bcec9633beedd46c9bd8f7598c06bac7276b",
|
||||
"record_id": "custodian-WP-0003c",
|
||||
"uuid": "b4eb45a9-69e3-4ab0-b00c-67a53c3117c5",
|
||||
"parent_record_id": "custodian-WP-0003"
|
||||
},
|
||||
{
|
||||
"repo": "activity-core",
|
||||
"path": "workplans/custodian-WP-0004-railiance-ops.md",
|
||||
"sha256": "20df02eea740e109c937130e7f8801a636fc0990ed8c6d2ced55659f8957adb1",
|
||||
"record_id": "custodian-WP-0004",
|
||||
"uuid": "759b1255-aa78-42b5-8fab-c5fcf168f5f4",
|
||||
"parent_record_id": "custodian-WP-0004"
|
||||
},
|
||||
{
|
||||
"repo": "the-custodian",
|
||||
"path": "workplans/ADHOC-2026-08-25-retired.md",
|
||||
"sha256": "344a1293dbb3a67a944eb34ca4a0337487d8f047226027a2107922346fbab2dd",
|
||||
"record_id": "CUST-WP-ADHOC-2026-08-25-RETIRED",
|
||||
"uuid": "1c53d3db-6633-5e2d-987f-10706d73be9e",
|
||||
"parent_record_id": "CUST-WP-ADHOC-2026-08-25-RETIRED"
|
||||
}
|
||||
]''')
|
||||
|
||||
|
||||
def historical_source_paths(repo_root):
|
||||
entries = [entry for entry in BINDINGS if entry["repo"] == repo_root.name]
|
||||
paths = set()
|
||||
for entry in entries:
|
||||
path = repo_root / entry["path"]
|
||||
if path.is_symlink() or not path.is_file() or sha256(path.read_bytes()).hexdigest() != entry["sha256"]:
|
||||
raise ValueError("Historical source binding requires owner review: " + entry["path"])
|
||||
paths.add(entry["path"])
|
||||
return paths
|
||||
|
|
@ -854,7 +854,8 @@ def ensure_missing_work_record_identifiers(
|
|||
# allocation candidates. Keep conformance reporting strict while allowing
|
||||
# ordinary registration to preserve those bindings. Local aliases still
|
||||
# require the explicit parent allowlist in the kind registry.
|
||||
historical_sources: set[str] = set()
|
||||
from repo_manager.historical_sources import historical_source_paths
|
||||
historical_sources: set[str] = historical_source_paths(repo_root)
|
||||
for path in iter_workplan_files(repo_root):
|
||||
parsed = parse_workplan_file(path, repo_root=repo_root)
|
||||
if parsed.status not in {"finished", "archived", "completed"} or not parsed.id:
|
||||
|
|
|
|||
56
tests/test_historical_sources.py
Normal file
56
tests/test_historical_sources.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
"""Exact frozen sources retain bytes and bindings while new work stays canonical."""
|
||||
import hashlib
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
from repo_manager import historical_sources as hs
|
||||
from repo_manager.identifiers import ensure_missing_work_record_identifiers
|
||||
from repo_manager.record_identity import scan_record_identities
|
||||
|
||||
|
||||
def _fixture(tmp_path,monkeypatch,repo='activity-core'):
|
||||
root=tmp_path/repo
|
||||
path=root/'workplans/old.md';path.parent.mkdir(parents=True)
|
||||
rid='custodian-WP-0001' if repo=='activity-core' else 'CUST-WP-ADHOC-2026-08-25-RETIRED'
|
||||
data=(f'---\nid: {rid}\ntype: workplan\nrepo: {repo}\nstatus: finished\n'
|
||||
'state_hub_workstream_id: e22516cc-4fdf-4dad-a928-a9e04a9fa7c7\n---\n').encode()
|
||||
path.write_bytes(data)
|
||||
monkeypatch.setattr(hs,'BINDINGS',[dict(repo=repo,path='workplans/old.md',sha256=hashlib.sha256(data).hexdigest())])
|
||||
prefix='ACTIVITY' if repo=='activity-core' else 'CUST'
|
||||
current=root/'workplans/current.md'
|
||||
current.write_text(f'---\nid: {prefix}-WP-9999\ntype: workplan\nstatus: active\n---\n')
|
||||
return root,path,current,data
|
||||
|
||||
|
||||
@pytest.mark.parametrize('repo',['activity-core','the-custodian'])
|
||||
def test_frozen_source_retains_bytes_and_existing_uuid(tmp_path,monkeypatch,repo):
|
||||
root,path,current,data=_fixture(tmp_path,monkeypatch,repo)
|
||||
report=ensure_missing_work_record_identifiers(root)
|
||||
assert path.read_bytes()==data
|
||||
assert len(report['historical_invalid_identifiers'])==1
|
||||
assert len(report['assignments'])==1 and report['assignments'][0]['path']=='workplans/current.md'
|
||||
assert not scan_record_identities(root)['ok']
|
||||
assert ensure_missing_work_record_identifiers(root)['assignments']==[]
|
||||
|
||||
|
||||
@pytest.mark.parametrize('change',['id','uuid','status','missing','symlink','extra'])
|
||||
def test_unreviewed_history_refuses_before_any_allocation(tmp_path,monkeypatch,change):
|
||||
root,path,current,data=_fixture(tmp_path,monkeypatch)
|
||||
original=current.read_bytes()
|
||||
if change=='id':path.write_bytes(data.replace(b'custodian-WP-0001',b'custodian-WP-0002'))
|
||||
elif change=='uuid':path.write_bytes(data.replace(b'e22516cc',b'f22516cc'))
|
||||
elif change=='status':path.write_bytes(data.replace(b'finished',b'active'))
|
||||
elif change=='missing':path.unlink()
|
||||
elif change=='symlink':
|
||||
path.unlink();target=root/'other.md';target.write_bytes(data);path.symlink_to(target)
|
||||
else:(root/'workplans/unreviewed.md').write_bytes(data.replace(b'custodian-WP-0001',b'custodian-WP-0099'))
|
||||
with pytest.raises(ValueError):ensure_missing_work_record_identifiers(root)
|
||||
assert current.read_bytes()==original
|
||||
|
||||
|
||||
def test_other_repo_cannot_inherit_frozen_exception(tmp_path,monkeypatch):
|
||||
root,path,current,data=_fixture(tmp_path,monkeypatch)
|
||||
other=root.with_name('other-repo');root.rename(other)
|
||||
with pytest.raises(ValueError,match='identities are not safe'):
|
||||
ensure_missing_work_record_identifiers(other)
|
||||
Loading…
Add table
Add a link
Reference in a new issue