feat(consistency): rebuild deterministic projection IDs
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
This commit is contained in:
parent
cb1b028fd1
commit
697dd49390
6 changed files with 245 additions and 32 deletions
|
|
@ -36,6 +36,7 @@ from consistency_check import (
|
|||
_check_scope_freshness,
|
||||
_check_repo_manager_conformance,
|
||||
_detect_behind_remote,
|
||||
_derived_work_record_uuid,
|
||||
_git_pull,
|
||||
_patch_frontmatter_field,
|
||||
_patch_task_status_in_file,
|
||||
|
|
@ -1271,6 +1272,78 @@ class TestC20DependencyDetection:
|
|||
|
||||
|
||||
class TestC06WorkstreamCreation:
|
||||
def test_fix_repo_rebuilds_missing_projection_from_derived_file_ids(
|
||||
self, tmp_path, monkeypatch
|
||||
):
|
||||
repo = tmp_path / "repo"
|
||||
workplans = repo / "workplans"
|
||||
workplans.mkdir(parents=True)
|
||||
workplan_id = _derived_work_record_uuid("STATE-WP-0001")
|
||||
task_id = _derived_work_record_uuid("STATE-WP-0001-T01")
|
||||
wp = workplans / "STATE-WP-0001-demo.md"
|
||||
original = (
|
||||
"---\n"
|
||||
"id: STATE-WP-0001\n"
|
||||
"type: workplan\n"
|
||||
"title: Demo Workplan\n"
|
||||
"domain: financials\n"
|
||||
"repo: demo-repo\n"
|
||||
"status: ready\n"
|
||||
f'state_hub_workstream_id: "{workplan_id}"\n'
|
||||
"---\n\n"
|
||||
"## Implement Demo\n\n"
|
||||
"```task\n"
|
||||
"id: STATE-WP-0001-T01\n"
|
||||
"status: todo\n"
|
||||
"priority: high\n"
|
||||
f'state_hub_task_id: "{task_id}"\n'
|
||||
"```\n"
|
||||
)
|
||||
wp.write_text(original, encoding="utf-8")
|
||||
created = []
|
||||
|
||||
def fake_get(_api_base, path, params=None, **_kwargs):
|
||||
if path == "/repos/demo-repo":
|
||||
import socket
|
||||
|
||||
return {
|
||||
"id": "repo-1",
|
||||
"slug": "demo-repo",
|
||||
"local_path": str(repo),
|
||||
"host_paths": {socket.gethostname(): str(repo)},
|
||||
"domain_slug": "financials",
|
||||
}
|
||||
if path == "/topics":
|
||||
return [{"id": "topic-1", "domain_slug": "financials"}]
|
||||
if path == f"/workplans/{workplan_id}":
|
||||
return None
|
||||
if path == "/workplans" and params and "slug" in params:
|
||||
return []
|
||||
if path == "/workplans" and params:
|
||||
return []
|
||||
return []
|
||||
|
||||
def fake_post(_api_base, path, body):
|
||||
created.append((path, body))
|
||||
return body
|
||||
|
||||
monkeypatch.setattr("consistency_check._api_get", fake_get)
|
||||
monkeypatch.setattr("consistency_check._api_post", fake_post)
|
||||
monkeypatch.setattr("consistency_check._api_patch", lambda *args, **kwargs: {"ok": True})
|
||||
monkeypatch.setattr("consistency_check._detect_behind_remote", lambda _repo_path: False)
|
||||
monkeypatch.setattr("consistency_check._detect_ahead_of_remote", lambda _repo_path: 0)
|
||||
monkeypatch.setattr("consistency_check._write_custodian_brief", lambda *args, **kwargs: False)
|
||||
monkeypatch.setattr("consistency_check._git_push", lambda _repo_path: (True, "pushed"))
|
||||
monkeypatch.setenv("STATEHUB_REGISTRAR", "1")
|
||||
|
||||
report = fix_repo("http://unused", "demo-repo")
|
||||
|
||||
assert created[0][1]["id"] == workplan_id
|
||||
assert created[1][1]["id"] == task_id
|
||||
assert created[1][1]["workplan_id"] == workplan_id
|
||||
assert wp.read_text(encoding="utf-8") == original
|
||||
assert any("C-06 fixed" in fix for fix in report.fixes_applied)
|
||||
|
||||
def test_fix_repo_uses_repo_qualified_slug_when_base_slug_is_taken(self, tmp_path, monkeypatch):
|
||||
repo = tmp_path / "repo"
|
||||
workplans = repo / "workplans"
|
||||
|
|
@ -1342,10 +1415,12 @@ class TestC06WorkstreamCreation:
|
|||
report = fix_repo("http://unused", "demo-repo")
|
||||
|
||||
assert created_workstreams[0]["slug"] == "demo-repo-state-wp-0001"
|
||||
assert created_tasks[0]["workplan_id"] == "new-ws"
|
||||
expected_workplan_id = created_workstreams[0]["id"]
|
||||
expected_task_id = created_tasks[0]["id"]
|
||||
assert created_tasks[0]["workplan_id"] == expected_workplan_id
|
||||
patched = wp.read_text(encoding="utf-8")
|
||||
assert 'state_hub_workstream_id: "new-ws"' in patched
|
||||
assert 'state_hub_task_id: "new-task"' in patched
|
||||
assert f'state_hub_workstream_id: "{expected_workplan_id}"' in patched
|
||||
assert f'state_hub_task_id: "{expected_task_id}"' in patched
|
||||
assert any("C-06 fixed" in fix for fix in report.fixes_applied)
|
||||
|
||||
def test_fix_repo_skips_c06_mint_when_not_registrar(self, tmp_path, monkeypatch):
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ the FastAPI ASGI app.
|
|||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import uuid
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
|
|
@ -139,6 +141,30 @@ class TestTopics:
|
|||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestWorkstreams:
|
||||
async def test_create_preserves_authoritative_projection_ids(self, client):
|
||||
await _create_domain(client)
|
||||
repo = await _create_repo(client, slug="projection-id-repo")
|
||||
workplan_id = str(uuid.uuid4())
|
||||
workplan = await _create_workplan(
|
||||
client,
|
||||
repo["id"],
|
||||
slug="projection-id-wp",
|
||||
id=workplan_id,
|
||||
)
|
||||
assert workplan["id"] == workplan_id
|
||||
|
||||
task_id = str(uuid.uuid4())
|
||||
response = await client.post(
|
||||
"/tasks/",
|
||||
json={
|
||||
"id": task_id,
|
||||
"workplan_id": workplan_id,
|
||||
"title": "File-backed task",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 201, response.text
|
||||
assert response.json()["id"] == task_id
|
||||
|
||||
async def test_create_and_list_by_topic(self, client):
|
||||
await _create_domain(client)
|
||||
topic = await _create_topic(client)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue