"""Deriving a projection from the forge (STATE-WP-0083-T01). The properties that matter are identity and determinism: a forge-derived projection must compute the same record identities as repo-manager, and the same commit must always yield the same projection. Without both, the reset in T03 cannot be verified against anything. """ from __future__ import annotations from pathlib import Path import pytest from api.services import forge_credential as fc from api.services import forge_projection as fp def test_identity_matches_the_fleet_derivation(): """Same namespace as ADR-007, so overlay and forge agree on identity.""" assert fp.derived_record_uuid("CUST-WP-0067") == "16249302-2767-55df-aec0-d92c2751c225" assert fp.derived_record_uuid("CUST-WP-0067-T01") == "f3608db4-20a5-58fb-a965-885eb14858af" def _repo(tmp_path: Path) -> Path: root = tmp_path / "demo" (root / "workplans" / "archived").mkdir(parents=True) (root / "workplans" / "DEMO-WP-0001-a.md").write_text( "---\nid: DEMO-WP-0001\ntype: workplan\ntitle: \"First\"\nstatus: active\n---\n\n" "## Do the thing\n\n```task\nid: DEMO-WP-0001-T01\nstatus: todo\npriority: high\n```\n\n" "## Do the other\n\n```task\nid: DEMO-WP-0001-T02\nstatus: done\npriority: low\n```\n", encoding="utf-8", ) (root / "workplans" / "archived" / "260101-DEMO-WP-0002-b.md").write_text( "---\nid: DEMO-WP-0002\ntype: workplan\ntitle: \"Second\"\nstatus: finished\n---\n\n# b\n", encoding="utf-8", ) (root / "workplans" / "NOTES.md").write_text( "---\nid: NOT-A-WORKPLAN\ntype: note\n---\n\n# not a workplan\n", encoding="utf-8" ) return root def test_derives_workplans_tasks_and_archived_flag(tmp_path): p = fp.derive_from_checkout(_repo(tmp_path), "demo", "abc123") assert [w.record_id for w in p.workplans] == ["DEMO-WP-0001", "DEMO-WP-0002"] first, second = p.workplans assert first.status == "active" and first.archived is False assert second.archived is True assert p.task_count == 2 assert [t.record_id for t in first.tasks] == ["DEMO-WP-0001-T01", "DEMO-WP-0001-T02"] def test_ignores_files_that_are_not_workplans(tmp_path): """Selection is by `type: workplan`; anything else is not this hub's business.""" p = fp.derive_from_checkout(_repo(tmp_path), "demo", "abc123") assert all(w.record_id != "NOT-A-WORKPLAN" for w in p.workplans) def test_task_titles_fall_back_to_the_preceding_heading(tmp_path): p = fp.derive_from_checkout(_repo(tmp_path), "demo", "abc123") titles = [t.title for t in p.workplans[0].tasks] assert titles == ["Do the thing", "Do the other"] def test_identifiers_are_derived_not_read_from_the_file(tmp_path): """A forge projection must not inherit whatever id a file happens to carry.""" root = _repo(tmp_path) f = root / "workplans" / "DEMO-WP-0001-a.md" f.write_text( f.read_text(encoding="utf-8").replace( "status: active", 'status: active\nstate_hub_workstream_id: "00000000-0000-4000-8000-000000000000"', ), encoding="utf-8", ) p = fp.derive_from_checkout(root, "demo", "abc123") assert p.workplans[0].uuid == fp.derived_record_uuid("DEMO-WP-0001") assert p.workplans[0].uuid != "00000000-0000-4000-8000-000000000000" def test_same_input_yields_identical_output(tmp_path): root = _repo(tmp_path) assert fp.derive_from_checkout(root, "demo", "abc").to_dict() == \ fp.derive_from_checkout(root, "demo", "abc").to_dict() def test_missing_workplans_directory_is_empty_not_an_error(tmp_path): (tmp_path / "bare").mkdir() p = fp.derive_from_checkout(tmp_path / "bare", "bare", "abc") assert p.workplans == [] and p.commit == "abc" def test_clone_failure_is_reported_not_swallowed(monkeypatch): def boom(*a, **k): raise fp.ForgeDeriveError("repository not found") monkeypatch.setattr(fp, "_run_git", boom) with pytest.raises(fp.ForgeDeriveError, match="not found"): fp.derive_from_forge("nope") class TestReset: """Applying the reset (STATE-WP-0083-T03). The properties worth guarding are the refusals, not the happy path. A reset that quietly retires a record someone still needs is worse than one that does nothing. """ @staticmethod def _derived(*records): wps = [] for rid, status, path in records: wps.append( fp.DerivedWorkplan( record_id=rid, uuid=fp.derived_record_uuid(rid), title=rid, status=status, relative_path=path, archived=False, tasks=[], ) ) return fp.DerivedProjection(repo_slug="demo", commit="c0ffee", workplans=wps) @pytest.mark.asyncio async def test_refuses_retirement_unless_acknowledged(self, monkeypatch): """A record that stops deriving may mean a deleted file — or a wrong branch.""" session = _FakeSession( repo=_Repo(), rows=[_Row(slug="demo-wp-0001", status="active", path="workplans/a.md")], ) out = await fp.reset_repository_projection( session, "demo", derived=self._derived() # forge has nothing ) assert out.status == "refused" assert out.refused and out.refused[0]["slug"] == "demo-wp-0001" assert out.retired == [] assert session.committed is False @pytest.mark.asyncio async def test_retires_when_acknowledged(self): row = _Row(slug="demo-wp-0001", status="active", path="workplans/a.md") session = _FakeSession(repo=_Repo(), rows=[row]) out = await fp.reset_repository_projection( session, "demo", derived=self._derived(), acknowledge_retirements=True ) assert out.status == "applied" and out.retired == ["demo-wp-0001"] assert row.projection_retired_at is not None assert row.projection_retired_reason == fp.RETIRE_REASON @pytest.mark.asyncio async def test_retirement_is_not_deletion(self): """Hub-native records reference workplans with RESTRICT; the row survives.""" row = _Row(slug="demo-wp-0001", status="active", path="workplans/a.md") session = _FakeSession(repo=_Repo(), rows=[row]) await fp.reset_repository_projection( session, "demo", derived=self._derived(), acknowledge_retirements=True ) assert row in session.rows assert session.deleted == [] @pytest.mark.asyncio async def test_unretires_a_record_that_derives_again(self): from datetime import datetime, timezone row = _Row(slug="demo-wp-0001", status="active", path="workplans/a.md") row.projection_retired_at = datetime.now(tz=timezone.utc) row.projection_retired_reason = fp.RETIRE_REASON session = _FakeSession(repo=_Repo(), rows=[row]) out = await fp.reset_repository_projection( session, "demo", derived=self._derived(("DEMO-WP-0001", "active", "workplans/a.md")), ) assert out.status == "applied" assert row.projection_retired_at is None @pytest.mark.asyncio async def test_unregistered_repository_is_refused_not_created(self): session = _FakeSession(repo=None, rows=[]) out = await fp.reset_repository_projection(session, "nope", derived=self._derived()) assert out.status == "refused" assert "not registered" in out.refused[0]["reason"] @pytest.mark.asyncio async def test_records_the_commit_it_derived_from(self): row = _Row(slug="demo-wp-0001", status="proposed", path="workplans/a.md") session = _FakeSession(repo=_Repo(), rows=[row]) await fp.reset_repository_projection( session, "demo", derived=self._derived(("DEMO-WP-0001", "active", "workplans/a.md")), ) assert row.derived_from_commit == "c0ffee" assert row.status == "active" class _Repo: def __init__(self): import uuid as _u self.id = _u.uuid4() self.topic_id = None class _Row: def __init__(self, slug, status, path): import uuid as _u self.id = _u.uuid4() self.slug = slug self.status = status self.backing_relative_path = path self.backing_filename = path.rsplit("/", 1)[-1] self.backing_archived = False self.projection_retired_at = None self.projection_retired_reason = None self.derived_from_commit = None class _FakeSession: """Stands in for AsyncSession: enough to prove intent without a database.""" def __init__(self, repo, rows, foreign=None, slug_clash=None): self._repo = repo self.rows = list(rows) self._foreign = list(foreign or []) self._slug_clash = list(slug_clash or []) self.added = [] self.deleted = [] self.committed = False self._calls = 0 async def execute(self, *_a, **_k): self._calls += 1 repo, rows = self._repo, self.rows # 1st call resolves the repo, 2nd loads its workplans, 3rd is the # foreign-identifier lookup. # 1 resolves the repo, 2 loads its workplans, 3 is the identifier # lookup, 4 the slug lookup. if self._calls == 2: payload = rows elif self._calls == 3: payload = self._foreign elif self._calls == 4: payload = self._slug_clash else: payload = [] class R: def scalar_one_or_none(self_inner): return repo def scalars(self_inner): return iter(payload) return R() def add(self, obj): self.added.append(obj) def delete(self, obj): self.deleted.append(obj) async def flush(self): return None async def commit(self): self.committed = True async def rollback(self): self.rolled_back = True class TestCollisionRefusal: """A colliding identifier must refuse, not raise (STATE-WP-0083-T03). net-kingdom's ADHOC-2026-08-23 derives to an identifier another repository already holds — the case CUST-WP-0066 documents. The reset previously failed on a database constraint, which tells the caller nothing they can act on. """ @staticmethod def _derived(rid="DEMO-WP-0001"): return fp.DerivedProjection( repo_slug="demo", commit="c0ffee", workplans=[fp.DerivedWorkplan( record_id=rid, uuid=fp.derived_record_uuid(rid), title=rid, status="active", relative_path="workplans/a.md", archived=False, tasks=[])], ) @pytest.mark.asyncio async def test_refuses_when_the_identifier_belongs_elsewhere(self): derived = self._derived() foreign = _Row(slug="held-by-someone-else", status="finished", path="workplans/x.md") foreign.id = __import__("uuid").UUID(derived.workplans[0].uuid) session = _FakeSession(repo=_Repo(), rows=[], foreign=[foreign]) out = await fp.reset_repository_projection(session, "demo", derived=derived) assert out.status == "refused" assert out.refused[0]["reason"].startswith("derived identifier already belongs") assert out.refused[0]["held_by_slug"] == "held-by-someone-else" assert out.created == [] and session.added == [] @pytest.mark.asyncio async def test_acknowledging_retirements_does_not_authorise_a_collision(self): """Different decision, different authorisation.""" derived = self._derived() foreign = _Row(slug="held-by-someone-else", status="finished", path="workplans/x.md") foreign.id = __import__("uuid").UUID(derived.workplans[0].uuid) session = _FakeSession(repo=_Repo(), rows=[], foreign=[foreign]) out = await fp.reset_repository_projection( session, "demo", derived=derived, acknowledge_retirements=True ) assert out.status == "refused" assert session.added == [] @pytest.mark.asyncio async def test_no_collision_still_creates(self): derived = self._derived() session = _FakeSession(repo=_Repo(), rows=[], foreign=[]) out = await fp.reset_repository_projection(session, "demo", derived=derived) assert out.status == "applied" and out.created == ["DEMO-WP-0001"] class TestFleetReset: """The fleet form must be a loop over the repository form (T04). Its value is entirely in what it does with failure: a wide reset that stops at the first refusal is one nobody can run, because there is always one unresolved repository somewhere. """ class _Factory: def __init__(self, sessions): self._sessions = list(sessions) def __call__(self): session = self._sessions.pop(0) class Ctx: async def __aenter__(self_inner): return session async def __aexit__(self_inner, *a): return False return Ctx() @staticmethod def _derived(rid): return fp.DerivedProjection( repo_slug="x", commit="c0ffee", workplans=[fp.DerivedWorkplan( record_id=rid, uuid=fp.derived_record_uuid(rid), title=rid, status="active", relative_path="workplans/a.md", archived=False, tasks=[])]) @pytest.mark.asyncio async def test_a_refusal_does_not_stop_the_pass(self, monkeypatch): calls = [] async def fake(session, slug, **kw): calls.append(slug) out = fp.ResetOutcome(repo_slug=slug, commit="c0ffee", status="applied") if slug == "bad": out.status = "refused" out.refused.append({"reason": "would be retired", "slug": "x"}) else: out.updated.append("A-WP-0001") return out monkeypatch.setattr(fp, "reset_repository_projection", fake) s = [_FakeSession(repo=_Repo(), rows=[]) for _ in range(3)] res = await fp.reset_fleet_projection(self._Factory(s), ["good", "bad", "also-good"]) assert calls == ["good", "bad", "also-good"] d = res.to_dict() assert d["by_status"] == {"applied": 2, "refused": 1} assert d["totals"]["updated"] == 2 @pytest.mark.asyncio async def test_an_error_does_not_stop_the_pass(self, monkeypatch): async def fake(session, slug, **kw): if slug == "boom": raise RuntimeError("clone failed") return fp.ResetOutcome(repo_slug=slug, commit="c", status="noop") monkeypatch.setattr(fp, "reset_repository_projection", fake) s = [_FakeSession(repo=_Repo(), rows=[]) for _ in range(3)] res = await fp.reset_fleet_projection(self._Factory(s), ["a", "boom", "b"]) d = res.to_dict() assert d["errored"] == 1 and "clone failed" in res.errors["boom"] assert set(res.results) == {"a", "b"} @pytest.mark.asyncio async def test_only_applied_repositories_are_committed(self, monkeypatch): async def fake(session, slug, **kw): out = fp.ResetOutcome(repo_slug=slug, commit="c", status="applied") if slug == "refuser": out.status = "refused" else: out.updated.append("A-WP-0001") return out monkeypatch.setattr(fp, "reset_repository_projection", fake) s = [_FakeSession(repo=_Repo(), rows=[]) for _ in range(2)] await fp.reset_fleet_projection(self._Factory(s), ["applier", "refuser"]) assert s[0].committed is True assert s[1].committed is False class TestSlugCollisionRefusal: """slug carries its own unique constraint (STATE-WP-0083-T04). Checking the identifier alone left disaster-control raising IntegrityError: two repositories can derive different identifiers whose slugs still collide. """ @pytest.mark.asyncio async def test_refuses_when_the_slug_belongs_elsewhere(self): derived = fp.DerivedProjection( repo_slug="demo", commit="c0ffee", workplans=[fp.DerivedWorkplan( record_id="REPO-WP-0001", uuid=fp.derived_record_uuid("REPO-WP-0001"), title="x", status="active", relative_path="workplans/a.md", archived=False, tasks=[])]) clash = _Row(slug="repo-wp-0001", status="finished", path="workplans/other.md") session = _FakeSession(repo=_Repo(), rows=[], foreign=[], slug_clash=[clash]) out = await fp.reset_repository_projection(session, "demo", derived=derived) assert out.status == "refused" assert out.refused[0]["reason"].startswith("slug already belongs") assert session.added == [] class TestUnreadableIsNotMissing: """STATE-WP-0084-T01. A repository central is not permitted to read and a repository whose records no longer derive authorise opposite things. Every test here exists to keep the retirement path unreachable from an answer that cannot support it — by construction, not by the reset happening to fail first. """ @pytest.mark.parametrize( "stderr", [ "fatal: could not read Username for 'https://forgejo.coulomb.social'", "remote: Invalid username or password.\nfatal: Authentication failed", "fatal: could not read Username for 'https://f': terminal prompts disabled", "fatal: repository 'https://forgejo.coulomb.social/rapp-openbao.git' not found", "fatal: unable to access '...': The requested URL returned error: 403", ], ) def test_permission_shaped_failures_are_classified_unreadable(self, stderr, monkeypatch): def boom(*a, **k): raise fp.ForgeDeriveError(stderr) monkeypatch.setattr(fp, "_run_git", boom) with pytest.raises(fp.ForgeUnreadableError): fp.derive_from_forge("rapp-openbao") def test_a_genuine_fault_stays_a_plain_error(self, monkeypatch): def boom(*a, **k): raise fp.ForgeDeriveError("fatal: early EOF\nfatal: index-pack failed") monkeypatch.setattr(fp, "_run_git", boom) with pytest.raises(fp.ForgeDeriveError) as exc: fp.derive_from_forge("demo") assert not isinstance(exc.value, fp.ForgeUnreadableError) def test_unreadable_is_a_derive_error_so_old_callers_still_catch_it(self): assert issubclass(fp.ForgeUnreadableError, fp.ForgeDeriveError) def test_a_checkout_without_workplans_cannot_evidence_absence(self, tmp_path): (tmp_path / "bare").mkdir() p = fp.derive_from_checkout(tmp_path / "bare", "bare", "abc") assert p.workplans == [] assert p.records_source_present is False assert p.retirement_eligible is False def test_a_real_checkout_can(self, tmp_path): p = fp.derive_from_checkout(_repo(tmp_path), "demo", "abc") assert p.records_source_present is True assert p.retirement_eligible is True def test_the_diff_withholds_stale_rather_than_computing_it(self): derived = fp.DerivedProjection( repo_slug="demo", commit="c0ffee", records_source_present=False ) hub = [{"id": "11111111-1111-1111-1111-111111111111", "slug": "demo-wp-0001", "status": "active", "backing_relative_path": "workplans/a.md"}] d = fp.diff_against_hub(derived, hub, {}) assert d.stale == [] assert d.would_remove == 0 assert d.stale_withheld @pytest.mark.asyncio async def test_an_empty_source_cannot_retire_even_when_acknowledged(self): derived = fp.DerivedProjection( repo_slug="demo", commit="c0ffee", records_source_present=False ) row = _Row(slug="demo-wp-0001", status="active", path="workplans/a.md") session = _FakeSession(repo=_Repo(), rows=[row]) out = await fp.reset_repository_projection( session, "demo", derived=derived, acknowledge_retirements=True ) assert out.status == "refused" assert out.retired == [] assert row.projection_retired_at is None assert out.refused[0]["reason"].startswith("source produced no records") @pytest.mark.asyncio async def test_an_unreadable_repository_reports_unreadable_not_error(self, monkeypatch): def boom(*a, **k): raise fp.ForgeUnreadableError("rapp-openbao could not be read from the forge") monkeypatch.setattr(fp, "derive_from_forge", boom) session = _FakeSession(repo=_Repo(), rows=[]) out = await fp.reset_repository_projection(session, "rapp-openbao") assert out.status == "unreadable" assert out.retired == [] and out.created == [] and out.updated == [] @pytest.mark.asyncio async def test_the_fleet_keeps_unreadable_out_of_the_error_bucket(self, monkeypatch): async def fake(session, slug, **kw): if slug == "private": out = fp.ResetOutcome(repo_slug=slug, commit="", status="unreadable") out.refused.append({"reason": "repository could not be read from the forge", "slug": slug, "detail": "could not read Username"}) return out if slug == "broken": raise RuntimeError("index-pack failed") out = fp.ResetOutcome(repo_slug=slug, commit="c0ffee", status="applied") out.updated.append("A-WP-0001") return out monkeypatch.setattr(fp, "reset_repository_projection", fake) sessions = [_FakeSession(repo=_Repo(), rows=[]) for _ in range(3)] outcome = await fp.reset_fleet_projection( TestFleetReset._Factory(sessions), ["ok", "private", "broken"] ) assert list(outcome.unreadable) == ["private"] assert list(outcome.errors) == ["broken"] assert "private" not in outcome.results d = outcome.to_dict() assert d["unreadable_count"] == 1 and d["errored"] == 1 assert d["repositories"] == 3 class TestForgeCredential: """Optional forge read credential (STATE-WP-0084-T03). Absent is a valid state: a hub with no credential must still derive every public repository. The credential must never reach argv, a log, or an exception — the places a secret leaks without anyone deciding to leak it. """ @pytest.fixture(autouse=True) def _clear_cache(self): """The resolved credential is cached for 5 minutes in production. That cache is deliberate — a fleet reset of 121 repositories must not authenticate to OpenBao 121 times — so tests clear it rather than disable it, and exercise the same code path production uses. """ fc.reset_cache() yield fc.reset_cache() def test_absent_credential_is_none_not_empty_string(self, monkeypatch): monkeypatch.delenv(fc.TOKEN_ENV, raising=False) monkeypatch.delenv(fc.TOKEN_FILE_ENV, raising=False) assert fc.forge_read_token() is None def test_a_file_is_preferred_over_the_environment(self, tmp_path, monkeypatch): """Kubernetes rotates a mounted file without a redeploy.""" f = tmp_path / "token" f.write_text("from-file\n", encoding="utf-8") monkeypatch.setenv(fc.TOKEN_ENV, "from-env") monkeypatch.setenv(fc.TOKEN_FILE_ENV, str(f)) assert fc.forge_read_token() == "from-file" def test_an_unreadable_token_file_does_not_fall_back_silently(self, monkeypatch): """Falling back to a stale env value would hide a broken mount.""" monkeypatch.setenv(fc.TOKEN_FILE_ENV, "/nonexistent/token") monkeypatch.setenv(fc.TOKEN_ENV, "from-env") assert fc.forge_read_token() is None def test_openbao_is_the_last_resort_not_the_first(self, tmp_path, monkeypatch): """A file or env value must not trigger a network call.""" f = tmp_path / "token" f.write_text("local", encoding="utf-8") monkeypatch.setenv(fc.TOKEN_FILE_ENV, str(f)) monkeypatch.setattr( fc, "_from_openbao", lambda: pytest.fail("OpenBao consulted unnecessarily") ) assert fc.forge_read_token() == "local" def test_openbao_failure_resolves_to_absent_not_an_exception(self, monkeypatch): """A hub that cannot reach OpenBao must still derive public repos. Raising here would turn "nine repositories are unreadable" into "the whole derivation pass failed" — the outcome STATE-WP-0084-T01 exists to prevent. """ monkeypatch.delenv(fc.TOKEN_FILE_ENV, raising=False) monkeypatch.delenv(fc.TOKEN_ENV, raising=False) monkeypatch.setenv(fc.OPENBAO_ADDR_ENV, "https://openbao.invalid") monkeypatch.setenv(fc.SECRET_PATH_ENV, "kv/data/forge") monkeypatch.setenv(fc.OPENBAO_ROLE_ENV, "state-hub-forge-derivation") monkeypatch.setenv(fc.OPENBAO_JWT_PATH_ENV, "/nonexistent/sa-token") assert fc.forge_read_token() is None def test_openbao_unwraps_kv_v2(self, tmp_path, monkeypatch): jwt = tmp_path / "sa" jwt.write_text("jwt-value", encoding="utf-8") monkeypatch.delenv(fc.TOKEN_FILE_ENV, raising=False) monkeypatch.delenv(fc.TOKEN_ENV, raising=False) monkeypatch.setenv(fc.OPENBAO_ADDR_ENV, "https://openbao.test") monkeypatch.setenv(fc.SECRET_PATH_ENV, "kv/data/forge") monkeypatch.setenv(fc.OPENBAO_ROLE_ENV, "state-hub-forge-derivation") monkeypatch.setenv(fc.OPENBAO_JWT_PATH_ENV, str(jwt)) class R: def __init__(self, payload): self._p = payload def raise_for_status(self): return None def json(self): return self._p class C: def __enter__(self): return self def __exit__(self, *a): return False def post(self, url, json): assert json["jwt"] == "jwt-value" assert json["role"] == "state-hub-forge-derivation" return R({"auth": {"client_token": "bao-token"}}) def get(self, url, headers): assert headers["X-Vault-Token"] == "bao-token" return R({"data": {"data": {"token": "forge-secret"}}}) monkeypatch.setattr(fc.httpx, "Client", lambda **kw: C()) assert fc.forge_read_token() == "forge-secret" def test_credential_never_appears_in_argv(self, monkeypatch): """`-c http.extraHeader=` would put the token in every ps listing.""" seen = {} class P: returncode = 0 stdout = "" stderr = "" def fake_run(cmd, **kw): seen["cmd"] = cmd seen["env"] = kw.get("env") or {} return P() monkeypatch.setattr(fp.subprocess, "run", fake_run) fp._run_git("clone", "url", "dir", token="s3cret") assert not any("s3cret" in part for part in seen["cmd"]) assert seen["env"]["GIT_CONFIG_COUNT"] == "1" assert "s3cret" not in seen["env"]["GIT_CONFIG_KEY_0"] def test_credential_is_redacted_from_failures(self, monkeypatch): class P: returncode = 128 stdout = "" stderr = "fatal: auth failed using s3cret" monkeypatch.setattr(fp.subprocess, "run", lambda *a, **k: P()) with pytest.raises(fp.ForgeDeriveError) as exc: fp._run_git("clone", token="s3cret") assert "s3cret" not in str(exc.value) and "***" in str(exc.value) def test_no_credential_still_runs(self, monkeypatch): class P: returncode = 0 stdout = "ok" stderr = "" seen = {} def fake_run(cmd, **kw): seen["env"] = kw.get("env") or {} return P() monkeypatch.setattr(fp.subprocess, "run", fake_run) assert fp._run_git("status") == "ok" assert "GIT_CONFIG_COUNT" not in seen["env"] class TestRekeyIsNotRename: """A changed identifier is a new record, not a moved file. The ad-hoc requalification (CUST-WP-0066) keeps the filename by design, so for those records a re-key never changes the path. Matching on path there cannot distinguish the two cases, and choosing rename updates a row whose UUID still encodes the old identifier — leaving the file and the hub disagreeing about what the record is called. """ class _Row: def __init__(self, id, slug, path): self.id = id self.slug = slug self.backing_relative_path = path self.projection_retired_at = None self.status = "finished" def test_a_derived_row_is_not_matched_by_path(self): """uuid5 means identity is a function of the identifier.""" import uuid as _u old = self._Row( _u.UUID(fp.derived_record_uuid("ADHOC-2026-08-25")), "adhoc-2026-08-25", "workplans/ADHOC-2026-08-25.md", ) assert fp._identity_is_derived(old) def test_a_legacy_row_keeps_path_matching(self): """v4 rows predate derived identity; there the identifier is a label.""" import uuid as _u legacy = self._Row(_u.uuid4(), "repo-wp-0001", "workplans/REPO-WP-0001.md") assert not fp._identity_is_derived(legacy) def test_the_two_uuids_actually_differ(self): """Guards the premise: if they were equal the distinction is moot.""" assert fp.derived_record_uuid("ADHOC-2026-08-25") != fp.derived_record_uuid( "CUST-WP-ADHOC-2026-08-25" ) @pytest.mark.parametrize( "slug", [ "adhoc-2026-07-02", # grandfathered daily ad-hoc "cust-wp-adhoc-2026-08-25", # qualified daily ad-hoc "net-kingdom-adhoc-2026-07-02", # repo-name-qualified legacy form "adhoc-llmc-2026-06-02", # another legacy qualification "rcluster-wp-0007", # ordinary workplan "cust-wp-0066-t01", # task ], ) def test_identifier_slugs_are_recognised(self, slug): """A slug that claims to be an identifier is one, whatever its UUID. 25 of 44 ad-hoc rows are legacy v4, so a UUID-version test alone would leave them path-matched and silently diverged from their files. """ assert fp._slug_is_identifier(slug) @pytest.mark.parametrize( "slug", ["three-phoenix-ha-cluster", "testdrive-jsui-publication", "state-hub-v0.1", ""], ) def test_title_slugs_keep_path_matching(self, slug): """Hub-first rows never claimed an identifier; the path is their only link.""" assert not fp._slug_is_identifier(slug) class TestRetirementReleasesTheIdentifier: """`slug` is unique table-wide, so retirement must free it. Retirement that only sets a timestamp leaves the identifier locked to a record nothing derives, and the repository that owns it can never claim it. """ def test_the_identifier_is_released(self): from datetime import datetime, timezone when = datetime(2026, 8, 28, tzinfo=timezone.utc) assert fp._tombstone_slug("repo-wp-0001", when) == "repo-wp-0001@retired-20260828" def test_re_retiring_does_not_stack_marks(self): """Otherwise the 100-char column overflows after a few passes.""" from datetime import datetime, timezone a = fp._tombstone_slug("repo-wp-0001", datetime(2026, 8, 28, tzinfo=timezone.utc)) b = fp._tombstone_slug(a, datetime(2026, 9, 1, tzinfo=timezone.utc)) assert b == "repo-wp-0001@retired-20260901" assert b.count(fp.RETIRED_SLUG_MARK) == 1 def test_a_long_slug_stays_within_the_column(self): from datetime import datetime, timezone out = fp._tombstone_slug("x" * 140, datetime(2026, 8, 28, tzinfo=timezone.utc)) assert len(out) <= 100 class _Retired: def __init__(self, slug, when, id=None): import uuid as _u self.id = id or _u.uuid4() self.slug = slug self.projection_retired_at = when self.projection_retired_reason = "x" self.backing_relative_path = None self.status = "finished" def test_rows_retired_before_the_stamp_existed_are_repaired(self): """`stale` excludes already-retired rows, so nothing else revisits them. The 32 rows retired earlier today still hold their identifiers; without this they would block the owning repository forever. """ from datetime import datetime, timezone when = datetime(2026, 8, 28, tzinfo=timezone.utc) row = self._Retired("repo-wp-0001", when) assert fp.RETIRED_SLUG_MARK not in row.slug row.slug = fp._tombstone_slug(row.slug, row.projection_retired_at) assert row.slug == "repo-wp-0001@retired-20260828" def test_an_already_stamped_row_is_left_alone(self): """Otherwise every reset rewrites the date and churns the row.""" from datetime import datetime, timezone row = self._Retired( "repo-wp-0001@retired-20260828", datetime(2026, 8, 28, tzinfo=timezone.utc) ) assert fp.RETIRED_SLUG_MARK in row.slug def test_a_release_is_committed_even_when_the_repo_refuses(self): """The fleet driver commits only on `applied` and rolls back otherwise. Moving the release ahead of the refusal returns achieves nothing if the rollback then discards it — which is the state railiance-cluster and inter-hub were in. """ import inspect src = inspect.getsource(fp.reset_fleet_projection) assert 'result.status == "applied" or result.released' in src class TestUuidMatchWins: """A row whose UUID is uuid5 of the identifier IS that record. `testdrive-jsui-publication` and `three-phoenix-ha-cluster` carry legacy title slugs while their UUIDs are derived from MARKITECT-WP-0002 and RCLUSTER-WP-0007. The slug-identifier rule alone reads them as re-keys and proposes retiring records that were correct all along. """ def test_a_title_slugged_row_is_still_its_derived_record(self): import uuid as _u rid = "MARKITECT-WP-0002" row_id = _u.UUID(fp.derived_record_uuid(rid)) # The slug says one thing, the UUID says another; the UUID is identity. assert not fp._slug_is_identifier("testdrive-jsui-publication") assert str(row_id) == fp.derived_record_uuid(rid) def test_uuid_match_is_checked_before_the_rekey_rules(self): import inspect src = inspect.getsource(fp.reset_repository_projection) uuid_at = src.index("want_by_uuid.get(str(row.id))") rekey_at = src.index("_identity_is_derived(row) or _slug_is_identifier") assert uuid_at < rekey_at, "UUID match must precede the re-key heuristics" class TestTaskIdentityIsQualified: """A bare `T01` is unique within its workplan, not in the fleet. Unqualified, `uuid5("T01")` is the same UUID for every workplan that has a T01 — llm-connect's 91 task blocks derive 49 distinct UUIDs, and creating its workplans dies on `duplicate key value violates unique constraint "tasks_pkey"`. """ BODY = """ ```task id: T01 status: done ``` ```task id: T02 status: todo ``` """ def test_short_ids_are_qualified_by_their_workplan(self): a = fp._parse_tasks(self.BODY, "LLM-WP-0001") b = fp._parse_tasks(self.BODY, "LLM-WP-0002") assert [t.record_id for t in a] == ["LLM-WP-0001-T01", "LLM-WP-0001-T02"] assert {t.uuid for t in a}.isdisjoint({t.uuid for t in b}) def test_an_already_qualified_id_is_left_alone(self): body = "```task\nid: LLM-WP-0009-T03\nstatus: todo\n```" assert fp._parse_tasks(body, "LLM-WP-0001")[0].record_id == "LLM-WP-0009-T03" def test_it_agrees_with_the_backfill(self): """Both must apply the same rule or they disagree on a task's name.""" from api.services.task_record_id_backfill import qualify_task_id got = fp._parse_tasks(self.BODY, "LLM-WP-0001")[0].record_id assert got == qualify_task_id("T01", "LLM-WP-0001") def test_uuid_follows_the_qualified_id(self): t = fp._parse_tasks(self.BODY, "LLM-WP-0001")[0] assert t.uuid == fp.derived_record_uuid("LLM-WP-0001-T01")