diff --git a/harness/tests/test_evidence_cli.py b/harness/tests/test_evidence_cli.py index 919490e0..975f7644 100644 --- a/harness/tests/test_evidence_cli.py +++ b/harness/tests/test_evidence_cli.py @@ -1,10 +1,21 @@ import json +import subprocess from typer.testing import CliRunner from tht.cli import app +def test_evidence_authoring_accepts_a_canonical_workspace_inside_the_git_worktree(tmp_path): + from tht.cli.evidence_cmd import _canonical_worktree + + subprocess.run(["git", "init", "--quiet", str(tmp_path)], check=True) + workspace_root = tmp_path / "psd-clinical" + workspace_root.mkdir() + + assert _canonical_worktree(workspace_root) == workspace_root.resolve() + + def test_evidence_authoring_commands_are_distinct_from_runtime_preprocessing(): result = CliRunner().invoke(app, ["evidence", "--help"]) diff --git a/harness/tht/cli/evidence_cmd.py b/harness/tht/cli/evidence_cmd.py index cf20166a..910c549a 100644 --- a/harness/tht/cli/evidence_cmd.py +++ b/harness/tht/cli/evidence_cmd.py @@ -23,9 +23,10 @@ evidence_app = typer.Typer(help="Prepare and validate workspace Evidence", no_ar def _canonical_worktree(workspace_root: Path) -> Path: - if workspace_root.is_symlink(): - raise typer.BadParameter("workspace-root must not be a symlink") + requested = workspace_root.absolute() root = workspace_root.resolve() + if workspace_root.is_symlink() or requested != root: + raise typer.BadParameter("workspace-root must not be a symlink") result = subprocess.run( ["git", "rev-parse", "--show-toplevel"], cwd=root, @@ -33,8 +34,15 @@ def _canonical_worktree(workspace_root: Path) -> Path: capture_output=True, text=True, ) - if result.returncode != 0 or Path(result.stdout.strip()).resolve() != root: - raise typer.BadParameter("workspace-root must be the root of a canonical Git worktree") + if result.returncode != 0: + raise typer.BadParameter("workspace-root must be inside a canonical Git worktree") + git_root = Path(result.stdout.strip()).resolve() + try: + root.relative_to(git_root) + except ValueError as error: + raise typer.BadParameter( + "workspace-root must be inside a canonical Git worktree", + ) from error return root