← Files Adaptive Codex OrchestratorARCHIVED FILE
hooks/lib/project_identity.py
2.4 KB · Sep 30, 2026 · 23:14 UTC
"""Privacy-preserving project identity without persisting a raw path."""
from __future__ import annotations
import hashlib
import ntpath
import os
from pathlib import Path
import posixpath
import subprocess
from typing import Callable, Optional, Sequence
def discover_repository_root(
cwd: str,
*,
runner: Callable[..., subprocess.CompletedProcess] = subprocess.run,
timeout: float = 1.5,
) -> str:
"""Return a Git root when safely available, otherwise the supplied CWD."""
fallback = cwd or os.curdir
try:
result = runner(
["git", "-C", fallback, "rev-parse", "--show-toplevel"],
shell=False,
capture_output=True,
text=True,
encoding="utf-8",
errors="replace",
timeout=timeout,
check=False,
)
except (FileNotFoundError, OSError, subprocess.SubprocessError):
return fallback
if result.returncode == 0 and isinstance(result.stdout, str) and result.stdout.strip():
return result.stdout.strip()
return fallback
def normalize_path(value: str, *, platform: Optional[str] = None) -> str:
"""Normalize Windows/POSIX forms deterministically without filesystem access."""
platform = platform or ("windows" if os.name == "nt" else "posix")
if platform == "windows":
normalized = ntpath.normpath(value.replace("/", "\\"))
normalized = ntpath.normcase(normalized)
# Hash representation uses one separator across hosts and removes the
# non-semantic trailing separator except for a drive root.
normalized = normalized.replace("\\", "/")
if len(normalized) > 3:
normalized = normalized.rstrip("/")
return normalized
normalized = posixpath.normpath(value.replace("\\", "/"))
if normalized != "/":
normalized = normalized.rstrip("/")
return normalized
def project_id(
cwd: str,
*,
platform: Optional[str] = None,
runner: Callable[..., subprocess.CompletedProcess] = subprocess.run,
timeout: float = 1.5,
) -> str:
root = discover_repository_root(cwd, runner=runner, timeout=timeout)
normalized = normalize_path(root, platform=platform)
return hashlib.sha256(normalized.encode("utf-8", "surrogatepass")).hexdigest()
__all__ = ["discover_repository_root", "normalize_path", "project_id"]
SHA-256: f32949db8e845de1c107f649de819cd6d9a947a08328be66576b10c538d5ed52