diff --git a/src/config.py b/src/config.py index 0e93ae2..4c7fc52 100644 --- a/src/config.py +++ b/src/config.py @@ -291,6 +291,33 @@ class Settings(BaseSettings): coverage_tool_fail_closed: bool = False coverage_run_timeout_s: int = 900 + # ORCH-057: legacy root-owned file ownership detect + actionable worktree error + # (follow-up ORCH-040). Three additive, kill-switch-reversible layers: (1) an + # actionable RuntimeError in git_worktree.ensure_worktree when a worktree fails + # to be created because of legacy root-owned files (Permission denied), (2) a + # cheap, TTL-cached, never-raise detect leaf src/fs_normalize.py that finds files + # with uid != target_uid across the infra roots (/repos/_wt, /.git, data/runs) + # and surfaces a startup WARNING/Telegram + GET /queue fs_ownership block, (3) an + # opt-in chown (normalize) ONLY when the process has CAP_CHOWN/root (under uid 1000 + # a no-op + honest log; the real fix is the operator procedure in INFRA.md). No + # STAGE_TRANSITIONS / QG_CHECKS / check_* / machine-verdict / schema change. See + # ADR-001-legacy-ownership-normalization.md / adr-0031. + # fs_normalize_enabled -> SINGLE kill-switch; False -> all code inert, behaviour + # 1:1 as before ORCH-057 (the actionable error too). + # Env ORCH_FS_NORMALIZE_ENABLED. + # fs_normalize_repos -> CSV of repos the layer is REAL for; empty -> only the + # self-hosting repo (orchestrator). Mirrors coverage_gate_repos. + # fs_target_uid -> target uid fallback when os.getuid() is unavailable. + # fs_normalize_auto -> detect-only (False) | attempt chown when privileged (True). + # fs_scan_roots -> CSV override of the scan roots (empty -> default roots). + # fs_scan_cache_ttl_s -> TTL of the detect cache (mirrors preflight_cache_ttl). + fs_normalize_enabled: bool = True + fs_normalize_repos: str = "" + fs_target_uid: int = 1000 + fs_normalize_auto: bool = False + fs_scan_roots: str = "" + fs_scan_cache_ttl_s: int = 300 + # ORCH-061: tolerate KNOWN sandbox-infra FAILs (C9a/C9b) in the staging suite. # The self-hosting deploy-staging stage looped because scripts/staging_check.py # exited non-zero on ANY failed check, so two infra-only failures (sandbox bot