"""E2E vertical slice: observe → index → command → git evidence → rebuild.""" from __future__ import annotations import json import subprocess from pathlib import Path from repo_manager.commands.task_status import update_task_status from repo_manager.gitops import head_sha from repo_manager.index_store import default_index_path, load_index from repo_manager.observe import observe_repository WORKPLAN = """--- id: DEMO-WP-0001 type: workplan title: "Demo workplan" status: active --- # Demo workplan ## First task ```task id: DEMO-WP-0001-T01 status: todo priority: high ``` Do the thing. """ def _git(repo: Path, *args: str) -> None: subprocess.run(["git", *args], cwd=repo, check=True, capture_output=True) def _init_fixture(tmp_path: Path) -> Path: repo = tmp_path / "demo-repo" repo.mkdir() _git(repo, "init") _git(repo, "config", "user.email", "test@example.com") _git(repo, "config", "user.name", "Test") (repo / "workplans").mkdir() (repo / "workplans" / "DEMO-WP-0001-demo.md").write_text(WORKPLAN, encoding="utf-8") (repo / ".repo-classification.yaml").write_text( "repo_classification:\n category: experimental\n domain: infotech\n", encoding="utf-8", ) (repo / "INTENT.md").write_text("# INTENT\n\nDemo fixture repository.\n", encoding="utf-8") _git(repo, "add", ".") _git(repo, "commit", "-m", "seed") return repo def test_e2e_vertical_slice(tmp_path: Path): repo = _init_fixture(tmp_path) before = head_sha(repo) assert before # 1–2. Observe + index declared work snap, index = observe_repository(repo, slug="demo-repo") assert snap["slug"] == "demo-repo" assert snap["classification"]["category"] == "experimental" assert snap["index"]["workplan_count"] == 1 assert snap["index"]["task_count"] == 1 tasks = [r for r in index.work_records if r.kind == "task"] assert tasks[0].id == "DEMO-WP-0001-T01" assert tasks[0].status == "todo" # 3–4. Apply governed file-backed transition + git evidence result = update_task_status( repo, "DEMO-WP-0001-T01", "progress", correlation_id="00000000-0000-4000-8000-000000000001", reason="e2e proof", ) assert result.status == "applied", result assert result.evidence.get("git_sha") assert result.evidence["git_sha"] != before assert result.evidence["files_touched"] == ["workplans/DEMO-WP-0001-demo.md"] # File content updated text = (repo / "workplans" / "DEMO-WP-0001-demo.md").read_text(encoding="utf-8") assert "status: progress" in text # 5. Rebuilt projection snap2, index2 = observe_repository(repo, slug="demo-repo") task2 = next(r for r in index2.work_records if r.id == "DEMO-WP-0001-T01") assert task2.status == "progress" assert snap2["revision"]["head_sha"] == result.evidence["git_sha"] # Index on disk includes command event (normalized change) idx_path = default_index_path(repo) assert idx_path.is_file() stored = load_index(idx_path) types = [e.get("type") for e in stored.events] assert "repo.command.applied" in types applied = next(e for e in stored.events if e.get("type") == "repo.command.applied") assert applied["correlation_id"] == "00000000-0000-4000-8000-000000000001" assert applied["git_sha"] == result.evidence["git_sha"] # Proof artifact for humans proof = { "slice": "RMGR-WP-0001-T05", "repo_slug": "demo-repo", "before_sha": before, "after_sha": result.evidence["git_sha"], "command": result.to_dict(), "snapshot_after": snap2, } proof_path = tmp_path / "e2e-proof.json" proof_path.write_text(json.dumps(proof, indent=2), encoding="utf-8") assert proof_path.stat().st_size > 0