fix(runtime): derive expected repository identity independently of configured root (Closes #973)

This commit is contained in:
2026-07-29 14:44:50 -04:00
parent 7978008709
commit 9d96cf4cfa
5 changed files with 146 additions and 32 deletions
+28 -6
View File
@@ -500,12 +500,37 @@ def _resolve_preflight_workspace_path(worktree_path: str | None = None) -> str:
return workspace
def _process_root_git_remote_url(remote_name: str) -> str | None:
"""Best-effort local ``git remote get-url`` strictly inside ``PROJECT_ROOT``.
#973 (B8): Must derive expected repository identity from an authority
independent of the candidate configured canonical root.
"""
try:
proc = subprocess.run(
["git", "remote", "get-url", remote_name],
capture_output=True,
text=True,
cwd=PROJECT_ROOT,
)
if proc.returncode != 0:
return None
url = (proc.stdout or "").strip()
return url or None
except Exception:
return None
def _resolve_expected_repository_slug(
remote: str | None = None,
org: str | None = None,
repo: str | None = None,
) -> str | None:
"""Resolve expected repository slug from parameters, session context, or remote URL."""
"""Resolve expected repository slug from parameters, session context, or process root.
Must derive expected repository identity ONLY from trusted sources independent
of the candidate configured canonical root (#973 B8).
"""
if org and repo:
return session_ctx.format_repository_slug(org, repo)
bound = session_ctx.get_session_context() or {}
@@ -515,7 +540,7 @@ def _resolve_expected_repository_slug(
return session_ctx.format_repository_slug(b_org, b_repo)
eff_remote = remote or bound.get("remote") or _effective_remote()
parsed = remote_repo_guard.parse_org_repo_from_remote_url(
_local_git_remote_url(eff_remote)
_process_root_git_remote_url(eff_remote)
)
if parsed:
return session_ctx.format_repository_slug(parsed[0], parsed[1])
@@ -969,10 +994,7 @@ def _enforce_canonical_repository_root(
if not configured_value:
return
bound = session_ctx.get_session_context() or {}
expected_slug = session_ctx.format_repository_slug(
bound.get("org"), bound.get("repository")
)
expected_slug = _resolve_expected_repository_slug(remote)
assessment = crr.assess_canonical_repository_root(
configured_value=configured_value,
source=source,