Preserve closed Railiance item bindings during routine sync

Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
tegwick 2026-09-11 16:53:59 +02:00
parent 8735a3549b
commit cb60a00ee1
3 changed files with 90 additions and 1 deletions

View file

@ -862,7 +862,18 @@ def ensure_missing_work_record_identifiers(
for number, task in enumerate(parsed.tasks, start=1):
if task.status not in {"done", "cancel"} or not task.state_hub_task_id:
continue
if not re.fullmatch(re.escape(parsed.id) + r"-T[0-9]{2}[a-z]", task.id or ""):
# RAILIANCE-WP-0004 is a closed historical workplan whose source
# used the old I01..I07 item labels. These exact, UUID-bound
# labels are preserved like the older suffix records below; they
# must not become a general I-suffix grandfather rule.
legacy_item = (
parsed.id == "RAILIANCE-WP-0004"
and re.fullmatch(r"RAILIANCE-WP-0004-I(?:0[1-7])", task.id or "")
)
if not (
re.fullmatch(re.escape(parsed.id) + r"-T[0-9]{2}[a-z]", task.id or "")
or legacy_item
):
continue
try:
uuid.UUID(task.state_hub_task_id)

View file

@ -61,3 +61,42 @@ def test_historical_collision_still_blocks(tmp_path):
with pytest.raises(ValueError, match='collisions='):
ensure_missing_work_record_identifiers(tmp_path)
assert live.read_bytes() == before
def _railiance_item(root: Path, *, parent="RAILIANCE-WP-0004", status="finished",
task_status="done", task_id="RAILIANCE-WP-0004-I01",
binding="44444444-4444-4444-8444-444444444444") -> Path:
path = root / "workplans" / "archived" / "railiance.md"
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(
f'---\nid: {parent}\nstatus: {status}\n'
'state_hub_workstream_id: "33333333-3333-4333-8333-333333333333"\n---\n'
f'\n```task\nid: {task_id}\nstatus: {task_status}\n'
f'state_hub_task_id: "{binding}"\n```\n',
encoding="utf-8",
)
return path
def test_railiance_historical_item_labels_preserve_uuid(tmp_path: Path) -> None:
path = _railiance_item(tmp_path)
before = path.read_bytes()
result = ensure_missing_work_record_identifiers(tmp_path, execute=False)
assert result["assignments"] == []
assert result["files_changed"] == []
assert path.read_bytes() == before
@pytest.mark.parametrize("kwargs", [
{"status": "active"},
{"task_status": "todo"},
{"parent": "RAILIANCE-WP-0005", "task_id": "RAILIANCE-WP-0005-I01"},
{"binding": ""},
{"binding": "not-a-uuid"},
{"task_id": "RAILIANCE-WP-0004-I08"},
{"task_id": "OTHER-WP-0004-I01"},
])
def test_railiance_item_label_preservation_is_bounded(tmp_path: Path, kwargs) -> None:
_railiance_item(tmp_path, **kwargs)
with pytest.raises(ValueError, match="identities are not safe"):
ensure_missing_work_record_identifiers(tmp_path)

View file

@ -0,0 +1,39 @@
---
id: RMGR-WP-ADHOC-2026-09-11
type: workplan
title: "Preserve seven bound historical Railiance task labels during routine sync"
domain: infotech
repo: repo-manager
status: finished
owner: codex
topic_slug: infotech
created: "2026-09-11"
updated: "2026-09-11"
---
## Preserve closed historical item labels without identity migration
```task
id: RMGR-WP-ADHOC-2026-09-11-T01
status: done
priority: medium
```
Routine Railiance Apps sync stopped on seven completed, UUID-bound historical
RAILIANCE-WP-0004-I01..I07 tasks while publishing the invited Vergabe pilot
contract. Extend the existing historical-binding preservation path for exactly
this closed parent and these labels. Conformance reporting remains strict;
active/unfinished tasks, unbound or invalid UUIDs, other parents and I labels
outside the observed set still refuse. Preserve existing source IDs, UUIDs,
statuses and historical references. New records continue to require canonical
IDs. No Hub identity mutation or sealed UUID migration is involved.
The attempted label-only normalization was withdrawn before commit/projection:
ordinary sync does not rename nonblank task record IDs, and changing the UUIDs
would enlarge the task without improving the pilot. This explicit historical
preservation resolves the routine sync blocker. Canonical migration remains the
existing RMGR-WP-0005 programme, not a new pilot prerequisite.
Validation: targeted historical/identity regression suite and Ruff, plus an
actual Railiance Apps dry run preserving all seven bindings without assigning
new UUIDs to them. Parent return is RAPPS-WP-0014 and HFACT-WP-0001.