---
name: core-internals
description: Provides guidance and best practices on concurrent synchronization, IPC, filesystem atomicity, git subprocess wrapping, XML manifests, and CLI argument parsing for git-repo.
---

# Git Repo Core Internals Engineering Guide

## Executive Summary

Welcome to the authoritative engineering guide for Git Repository Management
within the git-repo codebase. This repository of folk knowledge exists to
safeguard the intricate orchestration of our multi-repository synchronization
toolchain. Historically, complex operations such as parallelized network
fetches, layered manifest overrides, and interactive terminal rendering have
been vulnerable to subtle concurrency races, deadlocks, and fragile system
states. This guide captures these critical failure modes—ranging from IPC
serialization bottlenecks and filesystem lock contentions to non-hermetic test
pollution—and establishes rigid engineering constraints to prevent their
regression.

To maintain system stability, this guide enforces strict architectural
boundaries across the tooling ecosystem. It mandates stateless execution for
multiprocessing pools, guaranteed atomicity for worktree layout modifications,
and deterministic error translation for all standard Git subprocesses.
Furthermore, it defines the standard operating procedures for canonical manifest
object deduplication, the modernization of our hermetic testing frameworks, and
the delivery of consistent, machine-readable CLI interfaces. By adhering to
these paradigms, incoming engineers will ensure the reliability, performance,
and extensibility of git-repo's core repository management infrastructure.

## Summary

| Chapter Theme / Title                | Scope & Objective                     |
| :----------------------------------- | :------------------------------------ |
| **Concurrent Synchronization & IPC** | This domain governs the stable        |
:                                      : orchestration of parallel network     :
:                                      : fetches, local checkouts, and         :
:                                      : interleaved subprocess routines. It   :
:                                      : strictly enforces safe                :
:                                      : multiprocessing IPC, deterministic    :
:                                      : Git locking via exponential backoff,  :
:                                      : and state synchronization across      :
:                                      : concurrent pool workers.              :
| **Filesystem Atomicity & Worktree    | This domain governs the deterministic |
: Layout**                             : creation, migration, and cleanup of   :
:                                      : internal repository structures and    :
:                                      : Git worktrees. It relies on ephemeral :
:                                      : temporary directories, atomic rename  :
:                                      : operations, and robust error recovery :
:                                      : to prevent corrupted states during    :
:                                      : unexpected interruptions.             :
| **Subprocess Git Integration & Error | This chapter defines the constraints  |
: Translation**                        : for wrapping, executing, and          :
:                                      : translating standard Git subprocesses :
:                                      : within the Repo tooling ecosystem. It :
:                                      : mandates the use of centralized       :
:                                      : command abstractions, strict version  :
:                                      : gating, and deterministic stream      :
:                                      : handling to guarantee reliable        :
:                                      : repository state management and       :
:                                      : actionable error reporting.           :
| **Manifest Object Model &            | This chapter governs the parsing,     |
: Deduplication**                      : validation, and canonicalization of   :
:                                      : XML manifest components. It strictly  :
:                                      : enforces semantic immutability via    :
:                                      : NamedTuple implementations, defensive :
:                                      : copying for hierarchical override     :
:                                      : scoping, and deterministic            :
:                                      : JSON-backed file tracking across the  :
:                                      : subsystem.                            :
| **Hermetic Testing & Test            | This domain governs the migration of  |
: Modernization**                      : legacy unittest suites to modern      :
:                                      : pytest functional paradigms and the   :
:                                      : establishment of hermetic session     :
:                                      : fixtures. It enforces strict          :
:                                      : environment isolation to prevent      :
:                                      : global state pollution (e.g.,         :
:                                      : developer .gitconfig bleeding) while  :
:                                      : safely intercepting standard streams  :
:                                      : and filesystem paths.                 :
| **CLI Argument Parsing & UX          | This chapter governs the lifecycle,   |
: Consistency**                        : validation, and execution of          :
:                                      : command-line arguments, enforcing     :
:                                      : strict standardization for            :
:                                      : machine-readable serialization,       :
:                                      : unified logging, and deterministic,   :
:                                      : thread-safe terminal interactions.    :
| **Repo Hooks Framework**             | The Repo Hooks Framework governs the  |
:                                      : execution, parameter validation, and  :
:                                      : lifecycle management of user-defined  :
:                                      : scripts within the repository         :
:                                      : ecosystem. It ensures seamless        :
:                                      : integration of extensions like        :
:                                      : post-sync or pre-upload while         :
:                                      : strictly isolating their execution    :
:                                      : failures from core operational        :
:                                      : workflows.                            :

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

## Chapter: Concurrent Synchronization & IPC

**Context:** This domain governs the stable orchestration of parallel network
fetches, local checkouts, and interleaved subprocess routines. It strictly
enforces safe multiprocessing IPC, deterministic Git locking via exponential
backoff, and state synchronization across concurrent pool workers.

### Summary

| Rule ID   | Principle / Constraint    | Priority | Primary Symptom / Trap    |
| :-------- | :------------------------ | :------- | :------------------------ |
| **T1-01** | Stateless Class Methods   | High     | Passing bound instance    |
:           : for Parallel Pool Workers :          : methods to a parallel     :
:           :                           :          : executor, dragging        :
:           :                           :          : unnecessary state into    :
:           :                           :          : the multiprocessing       :
:           :                           :          : serialization pipeline.   :
| **T1-02** | Buffered Serialization of | High     | Executing terminal print  |
:           : Concurrent Standard       :          : calls directly from       :
:           : Output                    :          : within a parallelized     :
:           :                           :          : worker routine.           :
| **T1-03** | Interleaved Sync Path     | High     | Dispatching parallel      |
:           : Validation                :          : checkout jobs across all  :
:           :                           :          : project variants without  :
:           :                           :          : verifying layout types.   :
| **T1-04** | Guaranteed                | Critical | Placing save operations   |
:           : Synchronization State     :          : at the very end of an     :
:           : Persistence               :          : execution path without    :
:           :                           :          : exception guards.         :
| **T1-05** | Jittered Exponential      | Critical | Firing `git submodule     |
:           : Backoff for Git           :          : init` concurrently        :
:           : Configuration Locks       :          : without retry logic for   :
:           :                           :          : `config.lock` failures.   :
| **T1-06** | Exponential Backoff for   | High     | Failing a git command     |
:           : Concurrent Git Config     :          : immediately without       :
:           : Locks                     :          : evaluating standard       :
:           :                           :          : streams for transient     :
:           :                           :          : lock errors.              :
| **T1-07** | Hard Termination on       | Critical | Logging an error state    |
:           : Interleaved Sync Stalls   :          : inside a `while` loop but :
:           :                           :          : allowing the next loop    :
:           :                           :          : iteration to execute.     :
| **T1-08** | Resource Management via   | High     | Initializing proxy        |
:           : Context Handlers for IPC  :          : connections or            :
:           :                           :          : multiprocessing managers  :
:           :                           :          : as raw variable           :
:           :                           :          : assignments without a     :
:           :                           :          : guaranteed teardown       :
:           :                           :          : phase.                    :
| **T1-09** | Dual-Channel Error        | High     | Iterating over aggregated |
:           : Handling in Parallel      :          : data lists to decide if a :
:           : Processing                :          : parallel orchestration    :
:           :                           :          : should abort.             :
| **T1-10** | Minimum Process Pool Job  | Critical | Directly using            |
:           : Count Safeguard           :          : `min(target, len(items))` :
:           :                           :          : to determine pool size,   :
:           :                           :          : which breaks if the item  :
:           :                           :          : list is unexpectedly      :
:           :                           :          : empty.                    :
| **T1-11** | Safeguarding Object State | Critical | Truncating object         |
:           : Across Parallel Execution :          : payloads to scalar        :
:           : Boundaries                :          : indices during IPC        :
:           :                           :          : context setup without     :
:           :                           :          : updating the receiver     :
:           :                           :          : logic to rehydrate the    :
:           :                           :          : objects.                  :
| **T1-12** | Explicit Context          | High     | Assuming child workers    |
:           : Initialization for        :          : inherit updated class     :
:           : Multiprocessing Pools     :          : variables inherently      :
:           :                           :          : without explicit          :
:           :                           :          : initialization.           :
| **T1-13** | Dynamic Task Chunk Sizing | Medium   | Passing a hardcoded batch |
:           : in Parallel Execution     :          : integer to the            :
:           :                           :          : `chunksize` parameter.    :
| **T1-14** | Deferred Worktree         | High     | Returning early from the  |
:           : Operations in Sync Local  :          : sync phase without        :
:           : Half                      :          : applying required file    :
:           :                           :          : operations.               :

--------------------------------------------------------------------------------

### Rules

#### T1-01: Stateless Class Methods for Parallel Pool Workers

> **Rule:** Always implement multiprocessing pool targets as stateless class
> methods or standalone functions to bypass process serialization constraints.
>
> **What:** Worker execution targets within multiprocessing pools must be
> constructed as fully decoupled class methods or standalone functions to bypass
> process serialization constraints.
>
> **Applies To:** Multiprocessing process pools, concurrent task scheduling, and
> `ExecuteInParallel` implementations.
>
> **Why:** Command execution objects were heavily bound to system state.
> Attempting to pass instance methods (`self.method`) to a multiprocessing pool
> frequently caused `PicklingError` crashes, as the underlying Python
> serialization mechanism cannot cleanly isolate bound object graphs. Failing to
> adhere to this typically results in **IPC Serialization Error**.

**Trap 1: Passing bound instance methods to a parallel executor, dragging
unnecessary state into the multiprocessing serialization pipeline.**

**Don't:**

```python
class InfoCommand:
    def _worker_logic(self, project):
        pass

    def run(self):
        self.ExecuteInParallel(jobs, self._worker_logic, projects)
```

**Do:**

```python
class InfoCommand:
    @classmethod
    def _worker_logic(cls, project_idx):
        project = cls.get_parallel_context()["projects"][project_idx]
        pass

    def run(self):
        self.ExecuteInParallel(jobs, self._worker_logic, range(len(projects)))
```

**Exceptions:** Threading-based execution models where memory is shared and
pickling is not strictly enforced.

--------------------------------------------------------------------------------

#### T1-02: Buffered Serialization of Concurrent Standard Output

> **Rule:** Must capture standard output generated by concurrently executing
> tasks into isolated memory buffers for sequential display in the parent
> process.
>
> **What:** Data emitted by concurrently executing tasks must be captured into
> isolated memory buffers and returned to the parent process for sequential
> display.
>
> **Applies To:** Parallel process execution layers generating human-readable
> CLI output.
>
> **Why:** When command execution was parallelized, worker processes wrote
> directly to standard output. This created severe race conditions resulting in
> garbled, interleaved text output on the user's terminal. Failing to adhere to
> this typically results in **Interleaved Terminal Output**.

**Trap 1: Executing terminal print calls directly from within a parallelized
worker routine.**

**Don't:**

```python
@classmethod
def _DiffHelper(cls, project):
    print(f"Project: {project.name}")
    print(f"Revision: {project.rev}")
```

**Do:**

```python
@classmethod
def _DiffHelper(cls, project):
    buf = io.StringIO()
    buf.write(f"Project: {project.name}\n")
    buf.write(f"Revision: {project.rev}\n")
    return buf.getvalue()

# In main process:
for output in results:
    print(output, end="")
```

--------------------------------------------------------------------------------

#### T1-03: Interleaved Sync Path Validation

> **Rule:** Always validate the presence of a worktree when executing
> interleaved sync processes to prevent layout evaluation crashes.
>
> **What:** When executing interleaved sync processes (parallelized network
> fetches and checkouts), the operation must explicitly validate the presence of
> a worktree, as not all Git repository types (e.g., mirrors) maintain local
> file checkouts.
>
> **Applies To:** Concurrency logic within `sync.py`.
>
> **Why:** Changing the default mode of `repo sync` to interleaved parallelized
> checkout tasks indiscriminately. This immediately broke AOSP mirror syncing
> because mirrors lack local checkout paths, resulting in a `TypeError` when
> evaluating `NoneType` paths. Failing to adhere to this typically results in
> **TypeError / Sync Failure**.

**Trap 1: Dispatching parallel checkout jobs across all project variants without
verifying layout types.**

**Don't:**

*   Assuming `project.worktree` always contains an `os.PathLike` object during
    interleaved syncing.

**Do:**

*   Adding guard clauses to verify `project.worktree is not None` and handling
    `--mirror` modes explicitly before adding checkout tasks to the thread pool.

--------------------------------------------------------------------------------

#### T1-04: Guaranteed Synchronization State Persistence

> **Rule:** Must execute synchronization telemetry saving operations within
> `try...finally` blocks to guarantee data retention across execution
> interrupts.
>
> **What:** Core sync operations must wrap network and filesystem operations in
> `try...finally` blocks, ensuring that synchronization metadata (`_fetch_times`
> and `_local_sync_state`) is persisted even if the sync operation fails or is
> interrupted.
>
> **Applies To:** `subcmds/sync.py`, particularly the `_Fetch` logic and
> multiprocessing worker loops.
>
> **Why:** If a synchronization process encountered an error (like a fetch
> failure), the operation exited early, dropping valuable telemetry and
> optimization data (fetch times) for projects that successfully synced prior to
> the crash. Failing to adhere to this typically results in **Telemetry Loss /
> Sync State Inconsistency**.

**Trap 1: Placing save operations at the very end of an execution path without
exception guards.**

**Don't:**

```python
result = self._Fetch(to_fetch, opt, err_event)
if not result.success:
    raise SyncError("failed")

# BAD: Never reached if an error is raised
self._fetch_times.Save()
```

**Do:**

```python
try:
    result = self._Fetch(to_fetch, opt, err_event)
    if not result.success:
        raise SyncError("failed")
finally:
    # GOOD: Always saves telemetry state
    self._fetch_times.Save()
```

--------------------------------------------------------------------------------

#### T1-05: Jittered Exponential Backoff for Git Configuration Locks

> **Rule:** Always wrap concurrent Git mutations to shared configurations in an
> exponential backoff routine with jitter to mitigate transient filesystem
> locks.
>
> **What:** When initializing submodules concurrently (e.g., `git submodule
> init`), the system must employ an exponential backoff mechanism with
> randomized jitter to handle transient filesystem lock errors on `.git/config`.
>
> **Applies To:** Submodule initialization and any highly parallel Git
> subprocesses mutating shared configuration state.
>
> **Why:** Running `repo sync -j<N>` caused multiple child processes to
> simultaneously attempt `git submodule init`, which led to lock contention on
> the parent project's config file and caused the entire sync operation to fail.
> Failing to adhere to this typically results in **File Lock Contention / Sync
> Failure**.

**Trap 1: Firing `git submodule init` concurrently without retry logic for
`config.lock` failures.**

**Don't:**

```python
# BAD: Fails immediately if .git/config.lock exists
subprocess.run(["git", "submodule", "init", "--", path], check=True)
```

**Do:**

```python
# GOOD: Catch lock errors and retry with jitter
for attempt in range(MAX_RETRIES):
    p = subprocess.run(["git", "submodule", "init", "--", path], stderr=subprocess.PIPE)
    if p.returncode == 0:
        break
    if "could not lock config file" in p.stderr:
        time.sleep(base_delay * (2 ** attempt) + random.uniform(0, jitter))
```

**Exceptions:** Non-lock related Git errors should still fail immediately
without retrying.

--------------------------------------------------------------------------------

#### T1-06: Exponential Backoff for Concurrent Git Config Locks

> **Rule:** Must analyze captured Git error streams to detect config lock
> contention and orchestrate retries via structured logging instead of immediate
> process failure.
>
> **What:** Concurrent git operations modifying `.git/config` (such as submodule
> initialization) must utilize an exponential retry mechanism with jitter to
> handle transient filesystem lock contention. Standard output and error streams
> must be captured and parsed to detect these locks.
>
> **Applies To:** project.py, specifically concurrent `git submodule init`
> operations or any parallel processes altering local repository configuration.
>
> **Why:** When synchronizing with high job values (-j), multiple parallel
> processes modifying `.git/config` triggered race conditions, throwing 'could
> not lock config file' errors and aborting the sync. Failing to adhere to this
> typically results in **Transient Sync Failure / Lock Contention**.

**Trap 1: Failing a git command immediately without evaluating standard streams
for transient lock errors.**

**Don't:**

```python
# BAD: Fails immediately on lock contention
if GitCommand(self, cmd).Wait() != 0:
    raise GitError(f"{self.name} submodule init failed")
```

**Do:**

```python
# GOOD: Captures stdout/stderr and retries on 'lock' matches
git_cmd = GitCommand(None, cmd, capture_stdout=True, capture_stderr=True)
if git_cmd.Wait() != 0:
    error = git_cmd.stderr or git_cmd.stdout
    if "lock" in error:
        # apply exponential backoff + jitter logic
    else:
        git_cmd.VerifyCommand()  # Propagate real error
```

**Trap 2: Using raw `print` statements to log retry attempts, which breaks
structured output formats.**

**Don't:**

```python
# BAD: Unstructured print to stdout
print(f"Attempt {attempt+1}: git {' '.join(cmd)} failed. Sleeping...")
```

**Do:**

```python
# GOOD: Forwarded to centralized logger
logger.warning("Attempt %d/%d: git %s failed. Error: %s. Sleeping %.2fs before retrying.", attempt+1, max_retries, cmd, error, delay)
```

**Exceptions:** Non-lock related Git errors should break the retry loop and be
propagated immediately via `git_cmd.VerifyCommand()`.

--------------------------------------------------------------------------------

#### T1-07: Hard Termination on Interleaved Sync Stalls

> **Rule:** Must trigger a definitive execution break and flag error signals
> whenever an unresolvable stall is detected in an interleaved control loop.
>
> **What:** When an unresolvable stall is detected within an interleaved or
> parallel execution loop, the system must trigger a definitive state break
> (e.g., setting global events and breaking the loop) to prevent infinite
> deadlocks.
>
> **Applies To:** subcmds/sync.py, specifically `_SyncInterleaved` or any
> looping logic monitoring pending sets.
>
> **Why:** A bug existed where a stall was logged but the loop terminator
> (`break`) and error trigger (`err_event.set()`) were accidentally omitted.
> This allowed the sync routine to lock up infinitely when interdependent
> projects failed to checkout. Failing to adhere to this typically results in
> **Infinite Loop / Deadlock**.

**Trap 1: Logging an error state inside a `while` loop but allowing the next
loop iteration to execute.**

**Don't:**

```python
# BAD: Omitted termination control flow
if prev_pending == pending_relpaths:
    logger.error("Stall detected")
prev_pending = pending_relpaths
```

**Do:**

```python
# GOOD: Set event signals and immediately break
if prev_pending == pending_relpaths:
    logger.error("Stall detected")
    err_event.set()
    break
```

--------------------------------------------------------------------------------

#### T1-08: Resource Management via Context Handlers for IPC

> **Rule:** Always initialize multiprocessing components and background proxies
> within `with` statement context blocks to assure teardown semantics.
>
> **What:** Multiprocessing managers and SSH proxies initialized for parallel
> workflows must be wrapped in `with` block context managers to guarantee
> cleanup of background processes and multiplexing sockets.
>
> **Applies To:** Concurrent network operations and parallelized repository
> synchronization (`subcmds/sync.py`).
>
> **Why:** When adding an interleaved fetch/checkout feature, parallel
> operations required shared synchronization dictionaries and SSH connection
> multiplexing. Without context managers, exceptions or interrupts (e.g.,
> KeyboardInterrupt) would leave orphaned background processes and abandoned
> sockets. Failing to adhere to this typically results in **Resource Leaks /
> Orphaned Sockets**.

**Trap 1: Initializing proxy connections or multiprocessing managers as raw
variable assignments without a guaranteed teardown phase.**

**Don't:**

```python
# BAD: No guaranteed cleanup on exception
manager = multiprocessing.Manager()
ssh_proxy = ssh.ProxyManager(manager)
process_tasks(ssh_proxy)
```

**Do:**

```python
# GOOD: Context managers assure RAII semantics
with multiprocessing.Manager() as manager:
    with ssh.ProxyManager(manager) as ssh_proxy:
        process_tasks(ssh_proxy)
```

--------------------------------------------------------------------------------

#### T1-09: Dual-Channel Error Handling in Parallel Processing

> **Rule:** Must decouple fast-fail signaling events from aggregated batch data
> processing logic to ensure immediate worker termination across processes.
>
> **What:** In concurrent execution environments, inter-process signaling (for
> immediate control flow) must be strictly separated from data aggregation (for
> end-of-batch error reporting).
>
> **Applies To:** Multi-process synchronization pools (`_SyncInterleaved`,
> `_SyncPhased`) and worker callback processors.
>
> **Why:** Reviewers questioned why a separate event flag was used when an array
> of errors was already being populated. Using only an aggregated list prevented
> workers from rapidly terminating each other via fail-fast mechanisms. Failing
> to adhere to this typically results in **Delayed Worker Termination**.

**Trap 1: Iterating over aggregated data lists to decide if a parallel
orchestration should abort.**

**Don't:**

```python
# BAD: Waiting to process the whole batch before aborting
errors.append(result.error)
if errors and opt.fail_fast:
    pool.close()
```

**Do:**

```python
# GOOD: Using an IPC Event for immediate cross-process signaling
err_event.set()
errors.append(result.error)
if not ret and opt.fail_fast:
    pool.close()
```

--------------------------------------------------------------------------------

#### T1-10: Minimum Process Pool Job Count Safeguard

> **Rule:** Must bind dynamically computed multiprocessing job allocations to a
> minimum floor of 1 to prevent initialization crashes.
>
> **What:** When determining the number of worker processes for parallel
> execution based on a variable target length (e.g., an array of projects), the
> resulting worker count must be explicitly bound to a minimum of 1.
>
> **Applies To:** Network fetch logic and multiprocessing pool initializations
> (e.g., `_Fetch` in `sync.py`).
>
> **Why:** A regression occurred where passing an empty project list evaluated
> the worker count to 0. This crashed the multiprocessing pool initialization
> with a ValueError. Returning early was rejected as a fix because secondary
> side-effects (like state saves) within the function still needed to execute.
> Failing to adhere to this typically results in **ValueError / Process Pool
> Crash**.

**Trap 1: Directly using `min(target, len(items))` to determine pool size, which
breaks if the item list is unexpectedly empty.**

**Don't:**

```python
jobs = min(opt.jobs_network, len(projects_list))
```

**Do:**

```python
jobs = max(1, min(opt.jobs_network, len(projects_list)))
```

--------------------------------------------------------------------------------

#### T1-11: Safeguarding Object State Across Parallel Execution Boundaries

> **Rule:** Always transmit deeply serialized objects directly across parallel
> boundaries, or strictly reconstruct object relationships within the downstream
> worker.
>
> **What:** When offloading command execution to parallel processes, workers
> must receive properly serialized complex object data, not dissociated
> identifiers, unless the downstream API explicitly reconstructs the object
> state.
>
> **Applies To:** Parallel execution contexts (`ParallelContext`,
> `ExecuteInParallel`) within multi-project commands like `repo forall` and
> `repo upload`.
>
> **Why:** A refactoring attempt to optimize IPC by passing integer project
> indices instead of full project objects to parallel workers caused critical
> breakage. Worker processes subsequently attempted to access attributes (like
> `.manifest`) on integer types, leading to unhandled exceptions. Failing to
> adhere to this typically results in **AttributeError / Early Exit
> Regression**.

**Trap 1: Truncating object payloads to scalar indices during IPC context setup
without updating the receiver logic to rehydrate the objects.**

**Don't:**

```python
# Worker receives an integer index instead of a Project
manifests = {
    project.manifest.topdir: project.manifest
}
```

**Do:**

```python
# Worker receives fully serialized Project objects (or properly reconstructs them)
manifests = {
    project.manifest.topdir: project.manifest
}
```

--------------------------------------------------------------------------------

#### T1-12: Explicit Context Initialization for Multiprocessing Pools

> **Rule:** Must dictate shared states through an explicit `initializer`
> argument injected into the multiprocessing pool rather than implicitly relying
> on execution fork behavior.
>
> **What:** Shared parallel context must be managed using an explicit context
> manager and passed via `initializer` and `initargs` in `multiprocessing.Pool`,
> rather than relying on unvalidated class attributes or fork memory semantics.
>
> **Applies To:** Any command or module utilizing `multiprocessing.Pool` (e.g.,
> `ExecuteInParallel`).
>
> **Why:** Relying on `fork` memory semantics for sharing context works on some
> Linux systems but fails deterministically on environments (like macOS/Windows)
> where memory is not automatically shared or when the multiprocessing start
> method defaults to `spawn`. Failing to adhere to this typically results in
> **State Leakage / Uninitialized Context**.

**Trap 1: Assuming child workers inherit updated class variables inherently
without explicit initialization.**

**Don't:**

```python
# BAD: Implicit state sharing
cls.parallel_context = data
with multiprocessing.Pool(jobs) as pool:
    pool.imap_unordered(func, inputs)
```

**Do:**

```python
# GOOD: Explicit initializer passed to workers
with multiprocessing.Pool(
    jobs,
    initializer=cls._SetParallelContext,
    initargs=(cls._parallel_context,)
) as pool:
    pool.imap_unordered(func, inputs)
```

**Trap 2: A context manager directly yielding an internal dictionary, allowing
unvalidated and lingering usage.**

**Don't:**

```python
# BAD: Direct yield of state without lifecycle validation
@contextlib.contextmanager
def ParallelContext(cls):
    yield cls._parallel_context
```

**Do:**

```python
# GOOD: Lifecycle management and defensive assertions
@contextlib.contextmanager
def ParallelContext(cls):
    assert cls._parallel_context is None
    cls._parallel_context = {}
    try:
        yield
    finally:
        cls._parallel_context = None
```

--------------------------------------------------------------------------------

#### T1-13: Dynamic Task Chunk Sizing in Parallel Execution

> **Rule:** Always formulate the `chunksize` of mapping workers dynamically
> based on the dataset to job ratio to avoid workload serialization blocks.
>
> **What:** When utilizing `multiprocessing.Pool.imap_unordered`, the
> `chunksize` must be dynamically calculated based on the ratio of inputs to
> worker jobs, rather than statically hardcoded.
>
> **Applies To:** Parallel task dispatch mechanisms (`ExecuteInParallel`,
> synchronization loops).
>
> **Why:** Using a statically hardcoded chunk size (e.g., `WORKER_BATCH_SIZE =
> 32`) forced all tasks onto a single worker thread when the total number of
> projects in the manifest was fewer than 32, completely negating the benefit of
> parallelism for smaller workloads. Failing to adhere to this typically results
> in **Thread Serialization / Under-utilization**.

**Trap 1: Passing a hardcoded batch integer to the `chunksize` parameter.**

**Don't:**

```python
# BAD: Hardcoded chunksize leads to serialization for small input lists
submit(func, inputs, chunksize=WORKER_BATCH_SIZE)
```

**Do:**

```python
# GOOD: Dynamic chunking balances load across workers
calc_chunk = min(max(1, len(inputs) // jobs), WORKER_BATCH_SIZE)
submit(func, inputs, chunksize=calc_chunk)
```

**Exceptions:** When evaluating specifically within tests that forcefully
isolate to a single job execution (`jobs=1`).

--------------------------------------------------------------------------------

#### T1-14: Deferred Worktree Operations in Sync Local Half

> **Rule:** Must enqueue manifest copy and link actions into the synchronization
> buffer explicitly prior to issuing early return signals for up-to-date
> repositories.
>
> **What:** File link (`linkfile`) and copy (`copyfile`) directives must be
> scheduled using the synchronization buffer (`syncbuf.later1`) within the
> `Sync_LocalHalf` execution phase. They must not be bypassed if the repository
> exits its sync early due to being up-to-date.
>
> **Applies To:** Local synchronization logic of projects (`project.py` ->
> `Sync_LocalHalf`).
>
> **Why:** A bug existed where if a project had published commits in Gerrit
> (meaning its local state was merged), the sync process would return early and
> entirely skip applying the manifest's `linkfile` and `copyfile` operations,
> leading to missing or stale files in the developer's worktree. Failing to
> adhere to this typically results in **Worktree Desync / Missing Files**.

**Trap 1: Returning early from the sync phase without applying required file
operations.**

**Don't:**

```python
# BAD: Skipped file modifications when commits are published
if pub == head:
    return
```

**Do:**

```python
# GOOD: Schedule file operations via syncbuf before returning
if pub == head:
    syncbuf.later1(self, _doff, not verbose)
    return
```

--------------------------------------------------------------------------------

### Cross-Domain Dependencies

*   **Upstream:** T3 | Subprocess Git Integration & Error Translation -
    *Standardizes Git command stream capturing and exception typing, enabling
    reliable lock contention detection.*
*   **Downstream:** T2 | Filesystem Atomicity & Worktree Layout - *Relies on
    parallel execution guard clauses to ensure worktrees exist before checkout
    operations are dispatched.*
*   **Downstream:** T6 | CLI Argument Parsing & UX Consistency - *Requires
    buffered standard outputs and structured logger directives from parallel
    tasks to maintain coherent terminal formatting.*

## Chapter: Filesystem Atomicity & Worktree Layout

**Context:** This domain governs the deterministic creation, migration, and
cleanup of internal repository structures and Git worktrees. It relies on
ephemeral temporary directories, atomic rename operations, and robust error
recovery to prevent corrupted states during unexpected interruptions.

### Summary

| Rule ID   | Principle / Constraint        | Priority | Primary Symptom /     |
:           :                               :          : Trap                  :
| :-------- | :---------------------------- | :------- | :-------------------- |
| **T2-01** | Unique Subproject Keys in     | High     | Using the git         |
:           : Worktree Environments         :          : directory or          :
:           :                               :          : repository name as a  :
:           :                               :          : unique hash key for   :
:           :                               :          : deduplicating project :
:           :                               :          : objects.              :
| **T2-02** | Non-Destructive Bottom-Up     | High     | Using aggressive      |
:           : Directory Pruning             :          : recursive delete      :
:           :                               :          : calls to wipe an old  :
:           :                               :          : link destination      :
:           :                               :          : without verifying its :
:           :                               :          : internal contents.    :
| **T2-03** | Guaranteed Cleanup of         | Critical | Running destructive   |
:           : Temporary Git Artifacts       :          : or state-modifying    :
:           :                               :          : operations without    :
:           :                               :          : wrapping the cleanup  :
:           :                               :          : routine in a          :
:           :                               :          : `finally` block.      :
| **T2-04** | Atomic Directory              | High     | Initializing a        |
:           : Initialization via Temporary  :          : complex directory     :
:           : Worktrees                     :          : structure directly at :
:           :                               :          : its final target path :
:           :                               :          : without atomicity     :
:           :                               :          : guarantees.           :
| **T2-05** | Pathlib Adoption over os.path | Medium   | Relying on heavily    |
:           :                               :          : nested string-based   :
:           :                               :          : os.path               :
:           :                               :          : constructions.        :
| **T2-06** | Atomic Directory              | Critical | Creating and mutating |
:           : Initialization via Temporary  :          : a system directory at :
:           : Renames                       :          : its final, visible    :
:           :                               :          : destination.          :
| **T2-07** | Encapsulation of Transient    | High     | Swapping out instance |
:           : Configuration State           :          : configuration         :
:           :                               :          : variables back and    :
:           :                               :          : forth during setup.   :
| **T2-08** | Explicit Temporary Resource   | Critical | Keeping a stale       |
:           : Ownership and Release         :          : variable reference to :
:           :                               :          : a temporary directory :
:           :                               :          : after it has been     :
:           :                               :          : renamed, allowing a   :
:           :                               :          : deferred cleanup      :
:           :                               :          : routine to operate on :
:           :                               :          : an unowned path.      :
| **T2-09** | Configuration Object          | High     | Using a temporary     |
:           : Invalidation Post-Rename      :          : config object to set  :
:           :                               :          : flags after the       :
:           :                               :          : underlying directory  :
:           :                               :          : has been renamed.     :
| **T2-10** | Granular Safety Checks for    | Critical | Deleting a shared     |
:           : Destructive Worktree          :          : object directory      :
:           : Operations                    :          : immediately upon      :
:           :                               :          : deleting a single     :
:           :                               :          : project that uses it. :
| **T2-11** | Explicit Warnings for Legacy  | Critical | Silently executing a  |
:           : Garbage Collection Fallbacks  :          : legacy fallback for   :
:           :                               :          : repository safety     :
:           :                               :          : configurations        :
:           :                               :          : without informing the :
:           :                               :          : user of the potential :
:           :                               :          : unreliability.        :
| **T2-12** | Atomic Commits for Filesystem | High     | Bundling filesystem   |
:           : Restructuring                 :          : path migrations,      :
:           :                               :          : structural            :
:           :                               :          : re-designs, and       :
:           :                               :          : initialization logic  :
:           :                               :          : changes into a single :
:           :                               :          : Pull                  :
:           :                               :          : Request/Patchset.     :
| **T2-13** | Precise Symlink Target        | High     | Using a generic       |
:           : Replacement During Submodule  :          : string `.replace()`   :
:           : Migration                     :          : to update a portion   :
:           :                               :          : of a file path.       :
| **T2-14** | Isolating Filesystem          | High     | Executing internal    |
:           : Migrations from Network-Only  :          : directory migrations  :
:           : Operations                    :          : globally prior to     :
:           :                               :          : downloading network   :
:           :                               :          : changes.              :
| **T2-15** | Idempotent Cross-Platform     | High     | Relying on standard   |
:           : File Cleanup                  :          : library file removal  :
:           :                               :          : and failing to handle :
:           :                               :          : the scenario where    :
:           :                               :          : the file no longer    :
:           :                               :          : exists.               :
| **T2-16** | Self-Healing Binary JSON      | High     | Opening JSON state    |
:           : Deserialization               :          : files in text mode    :
:           :                               :          : without validating    :
:           :                               :          : structure, allowing   :
:           :                               :          : exceptions to bubble  :
:           :                               :          : up and break the CLI. :
| **T2-17** | Atomic File Writes for        | Critical | Using the standard    |
:           : Repository Configurations     :          : python `open()`       :
:           :                               :          : context manager and   :
:           :                               :          : `print()` to mutate   :
:           :                               :          : core git directories. :
| **T2-18** | File Descriptor Lock Scope    | Medium   | Processing strings    |
:           : Minimization                  :          : and building          :
:           :                               :          : directory paths       :
:           :                               :          : inside the file       :
:           :                               :          : reading scope.        :
| **T2-19** | Two-Phase Atomic Deletion for | High     | Directly triggering   |
:           : Worktrees                     :          : `rmtree` on a live    :
:           :                               :          : repository path.      :
| **T2-20** | Conditional Absolute Path     | High     | Blindly deleting and  |
:           : Resolution for Git Worktrees  :          : rewriting the         :
:           :                               :          : `gitdir` file using   :
:           :                               :          : `os.path.relpath`     :
:           :                               :          : without checking if   :
:           :                               :          : the source path is    :
:           :                               :          : absolute first.       :
| **T2-21** | Independent Manifest          | High     | Defaulting to a       |
:           : Repository Shallow Cloning    :          : shallow clone for     :
:           :                               :          : configuration         :
:           :                               :          : repositories, causing :
:           :                               :          : subsequent            :
:           :                               :          : initialization/branch :
:           :                               :          : switching commands to :
:           :                               :          : fail due to missing   :
:           :                               :          : objects.              :

--------------------------------------------------------------------------------

### Rules

#### T2-01: Unique Subproject Keys in Worktree Environments

> **Rule:** Always use repository-relative paths instead of git directory names
> as unique deduplication keys to prevent collisions in worktree environments.
>
> **What:** Repository-relative paths must be used instead of git directory
> names as unique deduplication keys to prevent collisions in environments
> utilizing git worktrees.
>
> **Applies To:** Subproject iteration and deduplication logic, primarily within
> `command.py` or project discovery utilities.
>
> **Why:** When tracking derived subprojects, the system originally used
> `gitdir` as a unique identifier. In git worktree setups, multiple distinct
> project instances can share the same underlying `gitdir`, leading to silent
> data collisions and missed projects during sync operations. Failing to adhere
> to this typically results in **Data Collision / Omission**.

**Trap 1: Using the git directory or repository name as a unique hash key for
deduplicating project objects.**

**Don't:**

```python
derived_projects.update(
    (p.gitdir, p) for p in project.GetDerivedSubprojects()
)
```

**Do:**

```python
derived_projects.update(
    (p.RelPath(local=False), p) for p in project.GetDerivedSubprojects()
)
```

#### T2-02: Non-Destructive Bottom-Up Directory Pruning

> **Rule:** Always utilize non-destructive, bottom-up directory iteration that
> exclusively targets empty directories and symlinks during legacy path cleanup.
>
> **What:** Legacy path cleanup must utilize non-destructive, bottom-up
> directory iteration that specifically targets empty directories and symlinks,
> avoiding recursive tree destruction.
>
> **Applies To:** Workspace migration, obsolete symlink cleanup, and
> `platform_utils` file deletion wrappers.
>
> **Why:** When a subproject's destination directory changed, the
> synchronization tool utilized aggressive recursive deletion (`rmtree`) to
> remove the previous location. This routinely endangered untracked developer
> code or extraneous files housed inside the obsolete tree. Failing to adhere to
> this typically results in **Accidental Data Deletion**.

**Trap 1: Using aggressive recursive delete calls to wipe an old link
destination without verifying its internal contents.**

**Don't:**

```python
if platform_utils.isdir(absDest):
    platform_utils.rmtree(absDest)
```

**Do:**

```python
# Use a safe helper that only removes empty dirs/symlinks bottom-up
platform_utils.removedirs(absDest)
```

**Trap 2: Attempting directory deletion without explicitly pruning stale
manifest files first.**

**Don't:**

```python
platform_utils.removedirs(need_remove_path)
# Misses files entirely as removedirs stops at regular files
```

**Do:**

```python
if os.path.isfile(need_remove_path) or os.path.islink(need_remove_path):
    platform_utils.remove(need_remove_path)
platform_utils.removedirs(os.path.dirname(need_remove_path))
```

**Exceptions:** Explicitly defined cases where a directory is formally tracked
and deleted from the manifest metadata, explicitly commanding removal.

#### T2-03: Guaranteed Cleanup of Temporary Git Artifacts

> **Rule:** Must wrap any operation mutating the local `.git` repository with
> temporary states inside a `try/finally` block to guarantee restoration.
>
> **What:** Operations mutating the local `.git` repository with temporary
> states (e.g., tracking alt refs during fetch) must wrap the operation in a
> `try/finally` block to guarantee state restoration.
>
> **Applies To:** Subprocess network operations and filesystem interactions
> affecting the `.git` database.
>
> **Why:** If a network operation threw an exception (like a `GitAuthError`
> prompting for credentials), the cleanup logic was bypassed. This left orphaned
> references in the object database and corrupted future repository syncs.
> Failing to adhere to this typically results in **Stale Repository State**.

**Trap 1: Running destructive or state-modifying operations without wrapping the
cleanup routine in a `finally` block.**

**Don't:**

```python
setup_temporary_refs()
run_git_fetch() # Might throw GitAuthError
cleanup_temporary_refs()
```

**Do:**

```python
setup_temporary_refs()
try:
    run_git_fetch()
finally:
    cleanup_temporary_refs()
```

#### T2-04: Atomic Directory Initialization via Temporary Worktrees

> **Rule:** Always perform directory initialization via temporary directories
> and an atomic rename to prevent fragmented repository states.
>
> **What:** Directory initialization processes must use temporary directories
> and atomic renames to prevent partial or corrupted states upon unexpected
> interruption.
>
> **Applies To:** Filesystem operations involving git repository setup,
> specifically superproject initialization and dot-git dir creation.
>
> **Why:** Historically, initializing git directories directly in their final
> path left behind broken, partially-initialized structures if the user or
> system interrupted the process. This caused subsequent workflow executions to
> fail permanently. Failing to adhere to this typically results in **Corrupt
> State / Initialization Failure**.

**Trap 1: Initializing a complex directory structure directly at its final
target path without atomicity guarantees.**

**Don't:**

```python
os.makedirs(final_git_dir, exist_ok=True)
subprocess.run(['git', 'init', final_git_dir])
```

**Do:**

```python
temp_dir = tempfile.mkdtemp(dir=target_base)
try:
    subprocess.run(['git', 'init', temp_dir])
    platform_utils.rename(temp_dir, final_git_dir)
finally:
    platform_utils.rmtree(temp_dir, ignore_errors=True)
```

#### T2-05: Pathlib Adoption over os.path

> **Rule:** Avoid legacy `os.path` APIs; prefer modern `pathlib.Path` structures
> for traversing, joining, and creating files.
>
> **What:** Use modern Python `pathlib.Path` paradigms for traversing, joining,
> and creating files instead of the legacy `os.path` APIs.
>
> **Applies To:** Filesystem and worktree directory manipulation.
>
> **Why:** Chaining `os.path.join` and calling `os.mkdir` repeatedly bloated the
> codebase, was less readable, and invited platform separator path bugs. Failing
> to adhere to this typically results in **Pathing Errors / High Complexity**.

**Trap 1: Relying on heavily nested string-based os.path constructions.**

**Don't:**

```python
manifest_dir = os.path.join(self.repodir, 'manifests')
os.mkdir(manifest_dir)
with open(os.path.join(manifest_dir, 'config'), 'w') as fp:
    fp.write(data)
```

**Do:**

```python
manifest_dir = self.repodir / 'manifests'
manifest_dir.mkdir(parents=True, exist_ok=True)
(manifest_dir / 'config').write_text(data)
```

**Exceptions:** Legacy modules pending modernization where intermingling
`os.path` strings and `Path` objects would break typing contracts.

#### T2-06: Atomic Directory Initialization via Temporary Renames

> **Rule:** Never construct complex internal `.git` directories in-situ; execute
> initialization inside an ephemeral directory and atomically rename it upon
> completion.
>
> **What:** Complex directory structures (like internal `.git` directories) must
> be constructed inside an ephemeral temporary directory on the same filesystem
> volume, and only moved to their final path via an atomic rename once fully
> validated.
>
> **Applies To:** Filesystem creation (`os.makedirs`) and repository
> initialization (`_InitGitDir`).
>
> **Why:** Interrupted or failed operations left partially initialized `.git`
> directories in-situ. Follow-up operations encountered corrupt directory trees,
> which the legacy recovery logic could not reliably clean up. Failing to adhere
> to this typically results in **Corrupt Repository State**.

**Trap 1: Creating and mutating a system directory at its final, visible
destination.**

**Don't:**

```python
os.makedirs(self.gitdir)
self._ReferenceGitDir(self.objdir, self.gitdir)
```

**Do:**

```python
tmp_gitdir = create_tmp_dir(os.path.dirname(self.gitdir))
os.makedirs(tmp_gitdir)
self._ReferenceGitDir(self.objdir, tmp_gitdir)
platform_utils.rename(tmp_gitdir, self.gitdir)
```

#### T2-07: Encapsulation of Transient Configuration State

> **Rule:** Never reassign class-level instance attributes to intermediate paths
> during object setup; use local variables for temporary state tracking.
>
> **What:** Never temporarily reassign class-level instance attributes (e.g.,
> `self.config`) to point to intermediate or ephemeral paths. Use local
> variables for temporary objects during setup, assigning the final result to
> the class instance only upon success.
>
> **Applies To:** Object initialization workflows within `project.py`.
>
> **Why:** During atomic `.git` directory initialization, `self.config` was
> temporarily overwritten to point to a temporary working directory. If the
> operation crashed, the object was left in an invalid state, pointing to a
> deleted transient path. Failing to adhere to this typically results in
> **Corrupt Instance State**.

**Trap 1: Swapping out instance configuration variables back and forth during
setup.**

**Don't:**

```python
self.config = GitConfig.ForRepository(gitdir=tmp_gitdir)
# initialization steps
platform_utils.rename(tmp_gitdir, self.gitdir)
self.config = GitConfig.ForRepository(gitdir=self.gitdir)
```

**Do:**

```python
tmp_config = GitConfig.ForRepository(gitdir=tmp_gitdir)
# apply setup using tmp_config
platform_utils.rename(tmp_gitdir, self.gitdir)
self.config = GitConfig.ForRepository(gitdir=self.gitdir)
```

#### T2-08: Explicit Temporary Resource Ownership and Release

> **Rule:** Always nullify references to a temporary directory immediately after
> successfully renaming it to its permanent destination.
>
> **What:** When executing atomic directory initializations via temporary paths,
> the reference to the temporary directory must be explicitly nullified
> immediately after successfully renaming it to its final destination.
>
> **Applies To:** Filesystem operations, specifically in `project.py` atomic Git
> directory initializations (`_InitGitDir`).
>
> **Why:** If a temporary directory reference was maintained after being
> atomic-renamed, the subsequent error-handling or `finally` cleanup block could
> mistakenly delete the directory. In parallel environments, another concurrent
> job could validly create a new temporary directory at that exact freed path,
> causing the current process to inadvertently nuke an active resource belonging
> to another job. Failing to adhere to this typically results in **Data Loss /
> Race Condition**.

**Trap 1: Keeping a stale variable reference to a temporary directory after it
has been renamed, allowing a deferred cleanup routine to operate on an unowned
path.**

**Don't:**

```python
try:
    tmp_gitdir = tempfile.mkdtemp()
    # ... initialize ...
    platform_utils.rename(tmp_gitdir, self.gitdir)
    # BAD: tmp_gitdir still holds the path string
finally:
    if tmp_gitdir and os.path.exists(tmp_gitdir):
        platform_utils.rmtree(tmp_gitdir) # Risk of race condition
```

**Do:**

```python
try:
    tmp_gitdir = tempfile.mkdtemp()
    # ... initialize ...
    platform_utils.rename(tmp_gitdir, self.gitdir)
    tmp_gitdir = None  # GOOD: explicitly release ownership of the path
finally:
    if tmp_gitdir and os.path.exists(tmp_gitdir):
        platform_utils.rmtree(tmp_gitdir)
```

#### T2-09: Configuration Object Invalidation Post-Rename

> **Rule:** Must discard intermediate configuration instances bound to temporary
> paths once the underlying directory is atomic-renamed.
>
> **What:** Configuration instances (e.g., `GitConfig`) bound to a temporary
> filesystem path must be abandoned after the path is atomic-renamed. A new
> instance tracking the permanent directory path must be used for subsequent
> settings.
>
> **Applies To:** Git config lifecycle management across atomic filesystem
> boundary events.
>
> **Why:** Applying configuration changes like `gc.pruneExpire` using an object
> instantiated against a temporary path resulted in IO errors or lost state if
> the operations occurred after the directory was moved to its final, permanent
> location. Failing to adhere to this typically results in **Lost Configuration
> / IO Error**.

**Trap 1: Using a temporary config object to set flags after the underlying
directory has been renamed.**

**Don't:**

```python
curr_config = GitConfig.ForRepository(gitdir=tmp_gitdir)
platform_utils.rename(tmp_gitdir, self.gitdir)
curr_config.SetString("gc.pruneExpire", "never")  # BAD: Path no longer valid
```

**Do:**

```python
curr_config = GitConfig.ForRepository(gitdir=tmp_gitdir)
platform_utils.rename(tmp_gitdir, self.gitdir)
self.config.SetString("gc.pruneExpire", "never")  # GOOD: Using permanent config tracking self.gitdir
```

#### T2-10: Granular Safety Checks for Destructive Worktree Operations

> **Rule:** Must evaluate explicit dependency subsets and prompt overrides
> before wiping shared object directories.
>
> **What:** Destructive operations (like wiping directories) must separately
> evaluate and prompt overrides for distinct risk categories (uncommitted local
> changes vs. shared object directories), and only delete a shared object
> directory if all dependent projects are successfully wiped.
>
> **Applies To:** Commands modifying or deleting project directories and
> `.repo/project-objects`.
>
> **Why:** Deleting shared `.repo` state indiscriminately could leave other
> referencing projects broken if they relied on the same object directory,
> requiring strict subset checks before `rmtree` execution. Failing to adhere to
> this typically results in **Repository Corruption / Data Loss**.

**Trap 1: Deleting a shared object directory immediately upon deleting a single
project that uses it.**

**Don't:**

```python
# BAD: Deletes shared objdir, breaking other projects
project.DeleteWorktree(force=True)
if os.path.exists(project.objdir):
    platform_utils.rmtree(project.objdir)
```

**Do:**

```python
# GOOD: Verify all users of the objdir are deleted first
project.DeleteWorktree(force=True)
successful_wipes.add(project.relpath)

# Later...
if users.issubset(successful_wipes):
    platform_utils.rmtree(objdir)
```

#### T2-11: Explicit Warnings for Legacy Garbage Collection Fallbacks

> **Rule:** Must emit a visible warning to `sys.stderr` when disabling Git
> garbage collection via legacy fallback configurations.
>
> **What:** When disabling Git garbage collection for shared network
> repositories using legacy mechanisms (`gc.pruneExpire=never`), the tooling
> must emit a visible `sys.stderr` warning due to the unreliability of older Git
> clients.
>
> **Applies To:** Git configuration manipulation and local filesystem management
> (`_GCProjects`).
>
> **Why:** Older Git clients (pre 2.7.0) do not natively support the
> `extensions.preciousObjects` flag. To prevent garbage collection from
> corrupting shared objects, `repo` forces `gc.pruneExpire` to `never`. Because
> this is imperfect, it can lead to unreliable repository states, requiring
> explicit user notification. Failing to adhere to this typically results in
> **Data Loss / Corruption**.

**Trap 1: Silently executing a legacy fallback for repository safety
configurations without informing the user of the potential unreliability.**

**Don't:**

```python
# BAD: Silent fallback to legacy GC directive
if git_require((2, 7, 0)):
    project.config.SetString('extensions.preciousObjects', 'true')
else:
    project.config.SetString('gc.pruneExpire', 'never')
```

**Do:**

```python
# GOOD: Alerting the user to the legacy system risk
if git_require((2, 7, 0)):
    project.config.SetString('extensions.preciousObjects', 'true')
else:
    print('WARNING: shared projects are unreliable when using old versions of git...', file=sys.stderr)
    project.config.SetString('gc.pruneExpire', 'never')
```

#### T2-12: Atomic Commits for Filesystem Restructuring

> **Rule:** Always strictly isolate structural filesystem modifications and
> migrations into single atomic commits to maintain bisectability.
>
> **What:** Refactoring critical filesystem paths (like migrating internal
> `.git` submodule structures) must be strictly isolated into atomic commits to
> preserve bisectability.
>
> **Applies To:** Worktree layout updates, `.git` metadata migrations, and
> submodule structure changes.
>
> **Why:** A monolithic commit attempted to restructure how submodules were
> stored (from `subprojects/` to `modules/`), update initialization logic, and
> alter fetching. This density made code review difficult and created a high
> risk of regressions that would be impossible to bisect cleanly. Failing to
> adhere to this typically results in **Unbisectable Regressions**.

**Trap 1: Bundling filesystem path migrations, structural re-designs, and
initialization logic changes into a single Pull Request/Patchset.**

**Don't:**

*   Submit 1 patchset: [Refactor] Move submodules to modules/, update git config
    flags, and modify sync --init behaviors.

**Do:**

*   Submit 3 sequential patchsets: 1) Isolate init flag changes. 2) Migrate
    filesystem directories from `subprojects` to `modules`. 3) Enable Git
    recurse submodules integration.

#### T2-13: Precise Symlink Target Replacement During Submodule Migration

> **Rule:** Always use explicit path prefixes instead of generic substring
> replacements to update symlink targets during legacy layout migrations.
>
> **What:** Symlink updates during filesystem layout migrations must use exact
> path prefixes rather than global substring replacements to update relative
> targets safely.
>
> **Applies To:** Repository migration logic (`project.py`); specifically
> `_MigrateSubprojectLinks` or similar symlink target modifications.
>
> **Why:** During the migration of legacy submodule directories, using generic
> string replacement (`target.replace`) on symlink paths unintentionally
> corrupted paths if a user's directory structure legitimately contained the
> target string (e.g., `subproject-objects`) in a higher-level parent directory
> name. Failing to adhere to this typically results in **Broken Symlinks /
> Corruption**.

**Trap 1: Using a generic string `.replace()` to update a portion of a file
path.**

**Don't:**

```python
if "subproject-objects" in target:
    new_target = target.replace(
        "subproject-objects", "module-objects"
    )
```

**Do:**

```python
if target.startswith("../../subproject-objects/"):
    new_target = target.replace(
        "../../subproject-objects/", "../../module-objects/"
    )
```

#### T2-14: Isolating Filesystem Migrations from Network-Only Operations

> **Rule:** Never execute internal repository layout migrations as part of
> network fetch iterations.
>
> **What:** Internal repository layout migrations must only execute during local
> worktree initialization phases, never during network fetch iterations.
>
> **Applies To:** Repository sync operations (`subcmds/sync.py`) and worktree
> checkout logic (`project.py`).
>
> **Why:** Binding irreversible filesystem layout migrations to the `sync`
> command's network-fetch loop risked partially migrating the repository if the
> process was interrupted, or if a user requested a network-only sync, leaving
> the local workspace out of sync with internal references. Failing to adhere to
> this typically results in **Repository Corruption**.

**Trap 1: Executing internal directory migrations globally prior to downloading
network changes.**

**Don't:**

```python
# In subcmds/sync.py during network fetching
for p in all_projects:
    p._MigrateOldSubprojectDirs()
    # ... fetch logic
```

**Do:**

```python
# Inside project.py during _InitWorkTree() or checkout
def _InitWorkTree(self):
    self._MigrateOldSubmoduleDirs()
    # ... symlink creation and checkout logic
```

#### T2-15: Idempotent Cross-Platform File Cleanup

> **Rule:** Must employ `platform_utils.remove()` for file cleanup to safely
> absorb OS access violations and gracefully swallow `ENOENT`.
>
> **What:** File cleanup operations must use the internal
> `platform_utils.remove()` instead of the standard `os.remove()` to handle
> Windows-specific OS limitations. Furthermore, cleanup must be idempotent by
> explicitly catching and swallowing `errno.ENOENT` errors.
>
> **Applies To:** Local worktree operations, internal state file cleanup (e.g.,
> deleting obsolete copyfiles or linkfiles).
>
> **Why:** Sync operations would abruptly crash on Windows due to unhandled
> `EACCES` issues on read-only files/symlinks with native `os.remove()`.
> Furthermore, if a tracking file was already deleted manually by the user or a
> prior interrupted run, unhandled `ENOENT` exceptions would needlessly fail the
> operation. Failing to adhere to this typically results in **Crash on
> Missing/Locked File**.

**Trap 1: Relying on standard library file removal and failing to handle the
scenario where the file no longer exists.**

**Don't:**

```python
if path:
  try:
    os.remove(path)
  except OSError as error:
    print(f'error: remove {path} failed.')
    return 1
```

**Do:**

```python
try:
  platform_utils.remove(path)
except OSError as e:
  if e.errno == errno.ENOENT:
    # File does not exist, safe to ignore
    pass
```

#### T2-16: Self-Healing Binary JSON Deserialization

> **Rule:** Always read internal JSON state files in binary mode (`rb`) and
> implement explicit error catching to seamlessly discard corrupted states.
>
> **What:** Internal JSON tracking files must be read in binary mode (`rb`) to
> allow the JSON parser to detect text encoding safely. Additionally, parsing
> must be wrapped in a `try/except` block to automatically delete the file and
> recover if the JSON is corrupted.
>
> **Applies To:** Manifest metadata tracking files, internal cache parsing
> (e.g., `copy-link-files.json`).
>
> **Why:** When the operating system's default text encoding did not match the
> file's encoding, a `UnicodeDecodeError` could occur. Additionally, if the JSON
> state file was corrupted (e.g., due to an abrupt power loss or killed
> process), `repo sync` would permanently fail until the user manually
> discovered and deleted the corrupted state file. Failing to adhere to this
> typically results in **Corrupt State Deadlock**.

**Trap 1: Opening JSON state files in text mode without validating structure,
allowing exceptions to bubble up and break the CLI.**

**Don't:**

```python
with open(copylinkfiles_path, 'r') as fd:
  old_copylinkfiles_path = json.load(fd)
```

**Do:**

```python
with open(copylinkfiles_path, 'rb') as fp:
  try:
    old_copylinkfiles_path = json.load(fp)
  except:
    print('error: %s is not a json formatted file.' % copylinkfiles_path, file=sys.stderr)
    platform_utils.remove(copylinkfiles_path)
    return False
```

#### T2-17: Atomic File Writes for Repository Configurations

> **Rule:** Must utilize atomic file writes rather than standard contexts when
> generating core `.git` configuration files.
>
> **What:** System state modifications, specifically writing the `.git` pointer
> files for submodules, must be performed using an atomic write pattern (e.g.,
> writing to a lockfile and renaming) rather than standard file descriptors.
>
> **Applies To:** All file I/O operations directly modifying `.git` contents,
> worktrees, or manifest definitions.
>
> **Why:** Using standard `open()` and writing to `.git` files directly leaves
> the repository vulnerable to corruption if the process is interrupted (e.g.,
> via Ctrl+C or SIGTERM) during the write loop, resulting in a partially written
> pointer. Failing to adhere to this typically results in **Corrupted Git
> Worktree**.

**Trap 1: Using the standard python `open()` context manager and `print()` to
mutate core git directories.**

**Don't:**

```python
with open(dotgit, "w") as fp:
    print(f"gitdir: {rel_path}", file=fp)
```

**Do:**

```python
_lwrite(dotgit, f"gitdir: {rel_path}\n")
```

#### T2-18: File Descriptor Lock Scope Minimization

> **Rule:** Minimize file descriptor lock retention by executing string and
> state logic outside of standard reading contexts.
>
> **What:** Data processing and variable manipulation must be extracted out of
> file descriptor lock contexts (`with open(...)`) to minimize resource
> retention.
>
> **Applies To:** Any block parsing local text or configuration files.
>
> **Why:** Holding file descriptors open while executing CPU-bound string
> manipulations increases lock contention probability and expands the attack
> surface for race conditions when multiple concurrent processes read/write
> repository states. Failing to adhere to this typically results in **Resource
> Lock Contention**.

**Trap 1: Processing strings and building directory paths inside the file
reading scope.**

**Don't:**

```python
with open(dotgit) as fp:
    setting = fp.read()
    gitdir = setting.split(":")[1].strip()
    dotgit_path = os.path.normpath(os.path.join(self.worktree, gitdir))
```

**Do:**

```python
with open(dotgit) as fp:
    setting = fp.read()

# Lock released, safe to process
gitdir = setting.split(":")[1].strip()
dotgit_path = os.path.normpath(os.path.join(self.worktree, gitdir))
```

#### T2-19: Two-Phase Atomic Deletion for Worktrees

> **Rule:** Must enact permanent `.git` and worktree removal via a two-phase
> destruction pattern utilizing a temporary trash path.
>
> **What:** When permanently removing a `.git` directory or worktree, the system
> must first perform an atomic rename to a temporary trash path before
> initiating the recursive deletion.
>
> **Applies To:** Garbage collection (`gc.py`), worktree cleanup, and submodule
> removal logic.
>
> **Why:** Recursive deletion is not instantaneous. If a user forcefully
> interrupted (Ctrl+C) the `rmtree` operation, the directory was left in a
> 'wedged' (partially deleted but still registered) state, permanently breaking
> future syncs for that repository. Failing to adhere to this typically results
> in **Wedged / Orphaned Worktree**.

**Trap 1: Directly triggering `rmtree` on a live repository path.**

**Don't:**

```python
for path in to_delete:
    platform_utils.rmtree(path)
```

**Do:**

```python
for path in to_delete:
    temp_path = rename_to_trash(path)
    platform_utils.rmtree(temp_path)
```

#### T2-20: Conditional Absolute Path Resolution for Git Worktrees

> **Rule:** Always independently verify if a tracked worktree path is absolute
> before initiating internal path recreation procedures.
>
> **What:** Updates to `.git` directory reference files (e.g., `gitdir:`) must
> verify whether the stored worktree path is absolute before attempting to
> recreate it as a relative path to avoid path corruption and permissions
> errors.
>
> **Applies To:** Internal Git directory layout management, specifically
> cross-platform Git worktree initialization (`project.py`).
>
> **Why:** On certain platforms like Windows, modifying the internal `dotgit`
> file in situ fails due to file permissions. Code was added to delete and
> recreate the file using relative paths. However, depending on the Git version,
> the initial path could already be relative, making conversion unsafe without
> an `isabs()` check. Failing to adhere to this typically results in
> **Permission Denied / Path Corruption**.

**Trap 1: Blindly deleting and rewriting the `gitdir` file using
`os.path.relpath` without checking if the source path is absolute first.**

**Don't:**

```python
platform_utils.remove(dotgit)
with open(dotgit, "w", newline="\n") as fp:
    print("gitdir:", os.path.relpath(git_worktree_path, self.worktree), file=fp)
```

**Do:**

```python
if os.path.isabs(git_worktree_path):
    platform_utils.remove(dotgit)
    with open(dotgit, "w", newline="\n") as fp:
        print("gitdir:", os.path.relpath(git_worktree_path, self.worktree), file=fp)
```

#### T2-21: Independent Manifest Repository Shallow Cloning

> **Rule:** Never propagate the primary manifest `--depth` flag to govern the
> core manifest repository's clone boundaries.
>
> **What:** The depth configuration for cloning the central manifest repository
> must be explicitly decoupled from the depth configuration applied to the child
> projects it governs, and its default must not regress existing multi-stage
> init workflows.
>
> **Applies To:** Repo initialization commands (`repo init`, `subcmds/init.py`).
>
> **Why:** Using the global `--depth` flag inadvertently forced shallow clones
> on all child projects. Introducing a dedicated `--manifest-depth` option fixed
> this, but defaulting it to 1 caused a regression during 'double repo init'
> workflows (where subsequent checkouts failed against truncated manifest
> histories). Failing to adhere to this typically results in **Workflow
> Regression / History Truncation**.

**Trap 1: Defaulting to a shallow clone for configuration repositories, causing
subsequent initialization/branch switching commands to fail due to missing
objects.**

**Don't:**

```python
group.add_option('--manifest-depth', type='int', default=1, metavar='DEPTH',
                 help='create a shallow clone of the manifest repo')
```

**Do:**

```python
group.add_option('--manifest-depth', type='int', default=0, metavar='DEPTH',
                 help='create a shallow clone of the manifest repo')
```

--------------------------------------------------------------------------------

### Cross-Domain Dependencies

*   **Upstream:** T3 | Subprocess Git Integration & Error Translation - *Network
    operations and git process invocations require safe staging paths and
    catchable exceptions to trigger filesystem cleanups.*
*   **Downstream:** T1 | Concurrent Synchronization & IPC - *Parallel checkout
    operations depend heavily on atomic path modifications and lock-free
    directory states to prevent race conditions.*
*   **Downstream:** T4 | Manifest Object Model & Deduplication - *Filesystem
    migrations and subproject tree building directly parse and reflect
    canonicalized XML manifest declarations.*

## Chapter: Subprocess Git Integration & Error Translation

**Context:** This chapter defines the constraints for wrapping, executing, and
translating standard Git subprocesses within the Repo tooling ecosystem. It
mandates the use of centralized command abstractions, strict version gating, and
deterministic stream handling to guarantee reliable repository state management
and actionable error reporting.

### Summary

| Rule ID   | Principle / Constraint    | Priority | Primary Symptom / Trap    |
| :-------- | :------------------------ | :------- | :------------------------ |
| **T3-01** | Unborn Branch Resolution  | High     | Catching a `rev-parse`    |
:           : via Symbolic-Ref          :          : GitError and immediately  :
:           :                           :          : falling back to manual    :
:           :                           :          : file system reads or      :
:           :                           :          : emitting warnings.        :
| **T3-02** | Centralized GitCommand    | Medium   | Wrapping `subprocess.run` |
:           : Abstraction Usage         :          : manually inside a class   :
:           :                           :          : to invoke Git.            :
| **T3-03** | NUL-Byte Delimiters for   | High     | Formatting git fields     |
:           : Git Output Parsing        :          : with tabs and defending   :
:           :                           :          : against length            :
:           :                           :          : variations.               :
| **T3-04** | Subprocess Execution      | Medium   | Stringifying Path         |
:           : Context and Native Path   :          : objects, using            :
:           : Passing                   :          : Git-specific directory    :
:           :                           :          : shifts, and suppressing   :
:           :                           :          : piped output.             :
| **T3-05** | Runtime Git Version       | High     | Invoking a modern git CLI |
:           : Constraints for Promisor  :          : flag without ensuring     :
:           : Packs                     :          : compatibility first.      :
| **T3-06** | Centralized Dependency    | Medium   | Catching missing binary   |
:           : Availability Caching      :          : exceptions to terminate   :
:           :                           :          : the process instead of    :
:           :                           :          : returning control to the  :
:           :                           :          : caller.                   :
| **T3-07** | Subprocess Return Code    | High     | Calling a non-existent    |
:           : Validation                :          : subprocess execution      :
:           :                           :          : method on an already      :
:           :                           :          : completed process object. :
| **T3-08** | Strict Git Version        | High     | Injecting convenient,     |
:           : Compatibility             :          : modern CLI flags into     :
:           :                           :          : subprocess wrappers.      :
| **T3-09** | Rebase Override for       | High     | Throwing a                |
:           : Published Local Branches  :          : `LocalSyncFail` when an   :
:           :                           :          : upstream gain exists,     :
:           :                           :          : completely ignoring the   :
:           :                           :          : `force_rebase` argument.  :
| **T3-10** | SSO Authentication        | High     | Treating all exit code    |
:           : Failure Translation       :          : 128 errors equally        :
:           :                           :          : without sniffing stdout   :
:           :                           :          : for authentication prompt :
:           :                           :          : aborts.                   :
| **T3-11** | Direct Read Fallback for  | High     | Raising a fatal internal  |
:           : Unborn Git HEAD           :          : exception immediately     :
:           :                           :          : upon a `GitError` when    :
:           :                           :          : checking for the HEAD     :
:           :                           :          : reference.                :
| **T3-12** | Safe Git Subprocess       | Critical | Assuming subprocess       |
:           : Output Handling           :          : success and attempting to :
:           :                           :          : return an output variable :
:           :                           :          : that hasn't been          :
:           :                           :          : initialized.              :
| **T3-13** | Shallow Clone SHA-1 Fetch | Critical | Assuming a fetch of an    |
:           : Fallback                  :          : arbitrary SHA-1 will      :
:           :                           :          : unconditionally succeed   :
:           :                           :          : if `--depth` is used.     :
| **T3-14** | Validating Gerrit Push    | High     | Constructing push options |
:           : Option Syntax             :          : with incorrect,           :
:           :                           :          : unverified key strings.   :
| **T3-15** | Submodule Initialization  | Critical | Blindly initializing      |
:           : Guard Under Git Worktrees :          : submodules without        :
:           :                           :          : verifying if the          :
:           :                           :          : underlying Git worktree   :
:           :                           :          : feature is active.        :
| **T3-16** | XDG Compliant Git         | High     | Hardcoding the user's     |
:           : Configuration Resolution  :          : home directory as the     :
:           :                           :          : sole location for         :
:           :                           :          : `.gitconfig`.             :
| **T3-17** | Strongly-Typed Subprocess | High     | Catching a subprocess     |
:           : Error Contexting          :          : failure and re-raising it :
:           :                           :          : as a generic git error    :
:           :                           :          : with a concatenated       :
:           :                           :          : string message.           :
| **T3-18** | Line-Based Log Extraction | Medium   | Truncating stdout to a    |
:           : for Subprocess            :          : fixed number of           :
:           : Diagnostics               :          : characters and ignoring   :
:           :                           :          : stderr entirely.          :

--------------------------------------------------------------------------------

### Rules

#### T3-01: Unborn Branch Resolution via Symbolic-Ref

> **Rule:** Always attempt `git symbolic-ref` before falling back to manual file
> parsing to correctly resolve unborn branches.
>
> **What:** When querying local Git branch structures, `git symbolic-ref` must
> be attempted as a fallback before file parsing to correctly identify unborn
> branches where `rev-parse` fails.
>
> **Applies To:** Subprocess Git integrations resolving `HEAD` or local refs.
>
> **Why:** Freshly initialized repositories and orphan branches present 'unborn'
> states where standard `rev-parse` commands returned errors, triggering
> false-positive warnings or crashing the client. Failing to adhere to this
> typically results in **Incorrect Branch Detection**.

**Trap 1: Catching a `rev-parse` GitError and immediately falling back to manual
file system reads or emitting warnings.**

**Don't:**

```python
try:
    return rev_parse(HEAD)
except GitError:
    logger.warning("Unparseable HEAD")
    return parse_file(HEAD)
```

**Do:**

```python
try:
    return rev_parse(HEAD)
except GitError:
    try:
        return run_git_command("symbolic-ref", "-q", HEAD)
    except GitError:
        pass
    return parse_file(HEAD)
```

--------------------------------------------------------------------------------

#### T3-02: Centralized GitCommand Abstraction Usage

> **Rule:** Strictly use the internal `GitCommand` abstraction for local Git
> operations instead of invoking raw `subprocess.run`.
>
> **What:** Use the internal `GitCommand` abstraction for executing Git
> operations rather than raw `subprocess.run` to guarantee consistent tracing,
> environment handling, and error translations.
>
> **Applies To:** Any module interacting with local git binaries, such as
> `git_refs.py`.
>
> **Why:** Developers bypassing the centralized wrapper led to duplicated
> subprocess execution logic, loss of global tracing capabilities (e.g.,
> `REPO_TRACE`), and fragmented error handling across the codebase. Failing to
> adhere to this typically results in **Missing Tracing / Environment Bugs**.

**Trap 1: Wrapping `subprocess.run` manually inside a class to invoke Git.**

**Don't:**

```python
def _Run(self, *cmd):
    return subprocess.run(
        ['git', f'--git-dir={self._gitdir}', *cmd],
        stdout=subprocess.PIPE,
        stderr=subprocess.DEVNULL
    )
```

**Do:**

```python
from git_command import GitCommand

def _Run(self, cmd):
    p = GitCommand(
        None,
        cmd,
        capture_stdout=True,
        capture_stderr=True,
        bare=True,
        gitdir=self._gitdir,
    )
    p.Wait()
    return p
```

**Exceptions:** Low-level testing utilities isolated from the core application
state, where bypassing `GitCommand` is necessary to bootstrap a test repository.

--------------------------------------------------------------------------------

#### T3-03: NUL-Byte Delimiters for Git Output Parsing

> **Rule:** Always specify NUL-byte delimiters (`%00`) when parsing Git command
> output to prevent splitting errors.
>
> **What:** When parsing Git formatted output, utilize the NUL byte (`%00`)
> instead of tabs or spaces, and leverage precise tuple unpacking without length
> validation.
>
> **Applies To:** Parsing output from Git commands like `git for-each-ref` or
> `git status`.
>
> **Why:** Using whitespace or tabs to split field data exposed the parser to
> failures if reference names or other entities inherently included those
> characters. NUL delimiters guarantee absolute safety and allow removal of
> defensive parsing loops. Failing to adhere to this typically results in **Data
> Parsing Failure**.

**Trap 1: Formatting git fields with tabs and defending against length
variations.**

**Don't:**

```python
# Using tab delimiter and checking len
subprocess.run(['git', 'for-each-ref', '--format=%(objectname)\t%(refname)'])
for line in output.splitlines():
    fields = line.split('\t')
    if len(fields) < 2:
        continue
    ref_id, name = fields[:2]
```

**Do:**

```python
# Using NUL delimiter and direct unpacking
GitCommand(..., ['for-each-ref', '--format=%(objectname)%00%(refname)%00%(symref)'])
for line in output.splitlines():
    ref_id, name, symref = line.split('\0')
```

--------------------------------------------------------------------------------

#### T3-04: Subprocess Execution Context and Native Path Passing

> **Rule:** Pass native `pathlib.Path` objects via the `cwd` argument rather
> than stringifying them or utilizing Git's `-C` flag.
>
> **What:** Execute subprocesses with correct internal API paradigms: omit Git's
> `-C` in favor of the `cwd=` parameter, pass `pathlib.Path` objects inherently,
> and drop `-q` when actively capturing output.
>
> **Applies To:** Subprocess command building and execution in test scaffolding
> and Git interactions.
>
> **Why:** Passing `-C` combined with forced string casting of paths created
> redundant logic. Additionally, suppressing underlying git output via `-q`
> completely masked the root cause of errors captured within the internal stream
> buffers. Failing to adhere to this typically results in **Obscured
> Diagnostics**.

**Trap 1: Stringifying Path objects, using Git-specific directory shifts, and
suppressing piped output.**

**Don't:**

```python
subprocess.check_call(
    ['git', '-C', str(git_dir), 'init', '-q'],
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)
```

**Do:**

```python
subprocess.check_call(
    ['git', 'init'],
    cwd=git_dir,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE
)
```

--------------------------------------------------------------------------------

#### T3-05: Runtime Git Version Constraints for Promisor Packs

> **Rule:** Explicitly verify local Git version compatibility before injecting
> modern CLI flags into subprocess calls.
>
> **What:** Operations utilizing modern Git arguments like
> `--missing=allow-promisor` must be explicitly gated by a minimal supported
> version check against the local executable.
>
> **Applies To:** Subprocess handlers for `git rev-list` and repacking
> mechanisms on partial clones.
>
> **Why:** Git 2.17.0 introduced advanced promisor arguments. Hardcoding these
> arguments in the execution engine crashed older repository clients on machines
> where Git had been downgraded or not updated. Failing to adhere to this
> typically results in **Subprocess Crash**.

**Trap 1: Invoking a modern git CLI flag without ensuring compatibility first.**

**Don't:**

```python
if opt.repack:
    return self.repack_projects(projects, opt)
```

**Do:**

```python
if opt.repack:
    git_require((2, 17, 0), fail=True, msg="--repack")
    return self.repack_projects(projects, opt)
```

--------------------------------------------------------------------------------

#### T3-06: Centralized Dependency Availability Caching

> **Rule:** Centralize and cache external dependency checks to fail gracefully
> without abruptly terminating the calling process.
>
> **What:** External dependency checks (e.g., verifying SSH installation) must
> be centralized, cached internally, and fail gracefully without forcibly
> exiting the calling process.
>
> **Applies To:** System API wrappers and subprocess managers (e.g.,
> `ProxyManager`, `ssh.py`).
>
> **Why:** Deep utility functions checking for external binaries previously
> called `sys.exit(1)` upon `FileNotFoundError`. This abruptly terminated the
> execution for users in environments missing the dependency, even if their
> specific workflow did not actually require it. Failing to adhere to this
> typically results in **Unexpected Process Termination**.

**Trap 1: Catching missing binary exceptions to terminate the process instead of
returning control to the caller.**

**Don't:**

```python
def version():
    try:
        return _parse_ssh_version()
    except FileNotFoundError:
        print("fatal: ssh not installed", file=sys.stderr)
        sys.exit(1)
```

**Do:**

```python
def version():
    try:
        return _parse_ssh_version()
    except FileNotFoundError as e:
        print("warn: ssh not installed", file=sys.stderr)
        raise e
```

**Trap 2: Duplicating inline `try-except` blocks for missing binaries across
multiple execution methods rather than centralizing state.**

**Don't:**

```python
def run_command1(self):
    try:
        subprocess.Popen(['ssh'])
    except FileNotFoundError:
        return False

def run_command2(self):
    try:
        subprocess.Popen(['ssh'])
    except FileNotFoundError:
        return False
```

**Do:**

```python
def __enter__(self):
    try:
        version()
        self._ssh_installed = True
    except FileNotFoundError:
        self._ssh_installed = False
    return self

def run_command(self):
    if not self._ssh_installed:
        return False
    subprocess.Popen(['ssh'])
```

--------------------------------------------------------------------------------

#### T3-07: Subprocess Return Code Validation

> **Rule:** Validate subprocess success strictly using `check_returncode()` on
> the completed process object.
>
> **What:** When utilizing the standard Python `subprocess` library, the correct
> method to validate execution success on a `CompletedProcess` object is
> `check_returncode()`. Do not call `check_call()` on the returned object.
>
> **Applies To:** Any Python code wrapping git commands and handling
> `subprocess.CompletedProcess` results.
>
> **Why:** Legacy code inadvertently called `check_call()` on the result of
> `run_command`, which triggered a runtime `AttributeError` instead of raising
> the expected `subprocess.CalledProcessError` on failure. Failing to adhere to
> this typically results in **AttributeError**.

**Trap 1: Calling a non-existent subprocess execution method on an already
completed process object.**

**Don't:**

```python
ret = subprocess.run(cmd, capture_output=True)
ret.check_call()  # Raises AttributeError
```

**Do:**

```python
ret = subprocess.run(cmd, capture_output=True)
# This will raise subprocess.CalledProcessError for us
ret.check_returncode()
```

--------------------------------------------------------------------------------

#### T3-08: Strict Git Version Compatibility

> **Rule:** Never pass Git flags that are unsupported by the minimum required
> Git version listed in the project's manifest.
>
> **What:** Do not pass modern CLI flags to subprocess Git operations if those
> flags are not supported by the minimum required Git version listed in the
> project's dependency manifest.
>
> **Applies To:** Git subprocess string assembly in `project.py`.
>
> **Why:** The `--no-auto-gc` flag was appended to clone commands to prevent
> deadlocks, but this flag did not exist in Git 1.7.9, immediately breaking
> checkout operations for environments restricted to the minimum supported
> baseline. Failing to adhere to this typically results in **Unknown Option
> Error**.

**Trap 1: Injecting convenient, modern CLI flags into subprocess wrappers.**

**Don't:**

```python
cmd.append("--no-auto-gc")
```

**Do:**

*   Disabling auto-gc via configuration setters (`self.config.SetInt("gc.auto",
    0)`) that are safely interpreted across legacy Git versions.

--------------------------------------------------------------------------------

#### T3-09: Rebase Override for Published Local Branches

> **Rule:** Allow rewriting of published local commits by respecting the
> `force_rebase` argument during sync operations.
>
> **What:** When a local branch is published but not yet merged upstream, `repo
> sync --rebase` must respect the `force_rebase` argument to allow rewriting
> published commits, rather than unconditionally throwing a sync failure.
>
> **Applies To:** `project.py`, specifically `_Rebase` and `_FastForward` path
> execution during sync.
>
> **Why:** The tool previously threw an error instructing the user to run with
> `--rebase`, but didn't actually execute the rebase when the flag was provided,
> forcing developers to manually fix the state. Failing to adhere to this
> typically results in **Broken UX / Unhandled Rebase State**.

**Trap 1: Throwing a `LocalSyncFail` when an upstream gain exists, completely
ignoring the `force_rebase` argument.**

**Don't:**

```python
if upstream_gain and not force_rebase:
    # Fails even if force_rebase is TRUE due to logic gap
    fail(LocalSyncFail("branch is published... rerun with the --rebase option"))
```

**Do:**

```python
if upstream_gain:
    if force_rebase:
        syncbuf.later1(self, _dorebase, not verbose)
    else:
        fail(LocalSyncFail("branch is published... rerun with the --rebase option"))
```

--------------------------------------------------------------------------------

#### T3-10: SSO Authentication Failure Translation

> **Rule:** Intercept Git exit code 128 and translate it to a typed
> `GitAuthError` when stdout indicates an SSO session abort.
>
> **What:** Git commands that fail with exit code 128 due to an SSO session
> abort must be explicitly intercepted and translated into a typed
> `GitAuthError`, preventing them from being masked as a missing reference.
>
> **Applies To:** project.py, Git Subprocess Wrappers evaluating `gitcmd.stdout`
> and return codes (specifically fetch/sync operations interacting with SSO
> remote helpers).
>
> **Why:** In non-interactive environments, an expired SSO token caused Git to
> fail with a generic exit code 128. The tool misinterpreted this as a missing
> upstream reference, leading to confusing error logs that obscured the
> underlying authentication requirement. Failing to adhere to this typically
> results in **Ambiguous Auth Failure**.

**Trap 1: Treating all exit code 128 errors equally without sniffing stdout for
authentication prompt aborts.**

**Don't:**

```python
# BAD: Ambiguous handling of 128
elif current_branch_only and is_sha1 and ret == 128:
    # Assuming missing upstream reference
    raise GitError("Couldn't find the ref you asked for")
```

**Do:**

```python
# GOOD: Explicit trap for SSO helpers
elif ret == 128 and gitcmd.stdout and "remote helper 'sso' aborted session" in gitcmd.stdout:
    raise GitAuthError(gitcmd.stdout)
```

**Exceptions:** Repositories containing multiple remotes where an auth failure
on a secondary remote might be non-fatal. (Currently flagged for future review
but translation stands).

--------------------------------------------------------------------------------

#### T3-11: Direct Read Fallback for Unborn Git HEAD

> **Rule:** Implement a direct file system read of `.git/HEAD` as a fallback
> when standard sub-commands fail to resolve the reference.
>
> **What:** When standard Git commands fail to resolve the current HEAD (e.g.,
> throwing a `GitError`), the system must fall back to directly reading the
> internal `.git/HEAD` file from the filesystem before propagating a fatal
> error.
>
> **Applies To:** project.py, `GetHead()` implementations traversing repository
> state.
>
> **Why:** Empty repositories or states featuring unborn branches caused `git
> rev-parse HEAD` to fail outright. Without a fallback, this cascaded into a
> `NoManifestException` and aborted the entire synchronization process. Falling
> back to the raw `.git/HEAD` text bypassed the strict ref checks. Failing to
> adhere to this typically results in **Hard Crash / NoManifestException**.

**Trap 1: Raising a fatal internal exception immediately upon a `GitError` when
checking for the HEAD reference.**

**Don't:**

```python
# BAD: Strict reliance on git sub-commands
try:
    return self.rev_parse(HEAD)
except GitError as e:
    path = self.GetDotgitPath(subpath=HEAD)
    raise NoManifestException(path, str(e))
```

**Do:**

```python
# GOOD: Fallback text parsing mechanism
try:
    return self.rev_parse(HEAD)
except GitError as e:
    path = self.GetDotgitPath(subpath=HEAD)
    try:
        with open(path) as fd:
            # Read branch manually
    except OSError:
        raise NoManifestException(path, str(e))
```

**Exceptions:** If the physical `.git/HEAD` file raises an `OSError` (meaning it
truly does not exist on disk), a `NoManifestException` is necessary and valid.

--------------------------------------------------------------------------------

#### T3-12: Safe Git Subprocess Output Handling

> **Rule:** Always validate the return code of a Git subprocess before accessing
> its standard output properties.
>
> **What:** Git subprocess output wrappers must explicitly handle non-zero exit
> codes to prevent accessing uninitialized variables, and stream properties must
> be spell-checked against the underlying class definitions.
>
> **Applies To:** Git subprocess wrappers (`git_superproject.py`, `GitCommand`)
> and any execution context capturing stdout/stderr.
>
> **Why:** When a Git command (like `git rev-parse`) failed, the code attempted
> to return a variable (`data`) that was only initialized on success, causing an
> `UnboundLocalError`. Furthermore, error logging attempts crashed due to a typo
> accessing `p.stdwerr` instead of `p.stderr`. Failing to adhere to this
> typically results in **Runtime Crash / UnboundLocalError**.

**Trap 1: Assuming subprocess success and attempting to return an output
variable that hasn't been initialized.**

**Don't:**

```python
# BAD: data is unbound if retval != 0
retval = p.Wait()
if retval == 0:
    data = p.stdout
else:
    log_error("Failed")
return data
```

**Do:**

```python
# GOOD: Explicit error handling with early return
retval = p.Wait()
if retval != 0:
    log_error(f"Failed: {p.stderr}")
    return None
return p.stdout
```

**Trap 2: Typo in the attribute name for capturing standard error from the
`GitCommand` class.**

**Don't:**

```python
# BAD: Invalid attribute triggers AttributeError
self._LogWarning("Error: {}", p.stdwerr)
```

**Do:**

```python
# GOOD: Correct attribute reference
self._LogWarning("Error: {}", p.stderr)
```

--------------------------------------------------------------------------------

#### T3-13: Shallow Clone SHA-1 Fetch Fallback

> **Rule:** Provide a full-sync fallback when shallow fetch requests for
> specific SHA-1s are rejected by server policies.
>
> **What:** Git fetch requests targeting specific SHA-1s with `--depth` enabled
> must handle graceful fallbacks, as server-side policies often restrict
> unadvertised object fetching.
>
> **Applies To:** Git fetch routines in `project.py`, specifically during
> incremental or optimized shallow clones.
>
> **Why:** When optimizing syncs by directly fetching specific SHA-1s with a
> depth limitation, operations failed silently or returned generic errors
> because some Git servers do not advertise all objects, explicitly rejecting
> such requests. Failing to adhere to this typically results in **Sync
> Failure**.

**Trap 1: Assuming a fetch of an arbitrary SHA-1 will unconditionally succeed if
`--depth` is used.**

**Don't:**

```python
# BAD: Missing fallback for unadvertised objects
ret = fetch_sha1(depth=1)
if ret < 0:
    break
```

**Do:**

```python
# GOOD: Explicit fallback to a full sync (depth-less) if the specific SHA-1 is rejected
ret = fetch_sha1(depth=1)
if depth and is_sha1 and ret == 1:
    # Server may not allow fetching unadvertised refs, fallback to full sync
    break
```

**Exceptions:** Servers specifically configured to allow
`uploadpack.allowReachableSHA1InWant` or similar parameters, though the client
cannot assume this.

--------------------------------------------------------------------------------

#### T3-14: Validating Gerrit Push Option Syntax

> **Rule:** Pass custom Gerrit push options strictly using the documented
> `custom-keyed-value` parameter syntax.
>
> **What:** When passing custom metadata to Gerrit via Git push options,
> strictly adhere to the `custom-keyed-value` syntax as defined by the remote
> server documentation.
>
> **Applies To:** `upload.py` operations mapping superproject state to `git push
> -o`.
>
> **Why:** The client attempted to attach superproject metadata to push
> operations using `custom-key-value`, which was ignored by the Gerrit server
> because the documented parameter was `custom-keyed-value`. Failing to adhere
> to this typically results in **Metadata Loss / Server Rejection**.

**Trap 1: Constructing push options with incorrect, unverified key strings.**

**Don't:**

```python
# BAD: Incorrect key format
push_options.append(f"custom-key-value=rootRepo:{host}/{sp_name}")
```

**Do:**

```python
# GOOD: Matches external documentation
push_options.append(f"custom-keyed-value=rootRepo:{host}/{sp_name}")
```

--------------------------------------------------------------------------------

#### T3-15: Submodule Initialization Guard Under Git Worktrees

> **Rule:** Skip Git submodule initialization sequences if the repository is
> actively utilizing Git worktrees.
>
> **What:** Submodule initialization operations (`git submodule init`) must be
> explicitly skipped if the repository is configured to use Git worktrees.
>
> **Applies To:** Git command wrappers, worktree initialization sequences, and
> submodule lifecycle operations in `project.py`.
>
> **Why:** Upstream Git has known bugs and incomplete feature support regarding
> the use of submodules within worktrees. Attempting to initialize submodules
> under these conditions leads to undefined behavior and broken repository
> states. Failing to adhere to this typically results in **Upstream Git Bug /
> Inconsistency**.

**Trap 1: Blindly initializing submodules without verifying if the underlying
Git worktree feature is active.**

**Don't:**

```python
self._InitWorkTree(force_sync=force_sync, submodules=submodules)
if self.has_subprojects:
    self._InitSubmodules()
```

**Do:**

```python
self._InitWorkTree(force_sync=force_sync, submodules=submodules)
# Avoid doing a submodule init when using worktrees as the support for
# submodules is incomplete.
if self.has_subprojects and not self.use_git_worktrees:
    self._InitSubmodules()
```

--------------------------------------------------------------------------------

#### T3-16: XDG Compliant Git Configuration Resolution

> **Rule:** Resolve user Git configuration files natively honoring the
> `XDG_CONFIG_HOME` environment variable before defaulting to legacy paths.
>
> **What:** Git configuration lookups must natively respect the
> `XDG_CONFIG_HOME` environment variable, falling back to `~/.config/git/config`
> before finally querying the legacy `~/.gitconfig` location.
>
> **Applies To:** Git configuration parsing, environment setup, and hermetic
> tests.
>
> **Why:** Users who migrated their dotfiles to the XDG Base Directory
> Specification experienced issues because internal tooling rigidly expected
> `~/.gitconfig` to exist, bypassing user intentions and leading to
> unauthenticated or unconfigured repository actions. Failing to adhere to this
> typically results in **Orphaned Configuration State**.

**Trap 1: Hardcoding the user's home directory as the sole location for
`.gitconfig`.**

**Don't:**

```python
def _getUserConfig():
    return os.path.expanduser("~/.gitconfig")
```

**Do:**

```python
def _getUserConfig():
    """This matches git: https://git-scm.com/docs/git-config#FILES"""
    xdg_config_home = os.getenv("XDG_CONFIG_HOME", os.path.expanduser("~/.config"))
    xdg_config_file = os.path.join(xdg_config_home, "git", "config")
    if os.path.exists(xdg_config_file):
        return xdg_config_file
    return os.path.expanduser("~/.gitconfig")
```

--------------------------------------------------------------------------------

#### T3-17: Strongly-Typed Subprocess Error Contexting

> **Rule:** Raise strongly-typed `GitCommandError` exceptions with granular
> state context instead of generic Git errors.
>
> **What:** Git commands that yield non-zero exit codes must raise a specialized
> `GitCommandError` containing granular execution context, rather than a generic
> `GitError`.
>
> **Applies To:** Subprocess execution wrappers within `git_command.py` and
> downstream consumers handling Git process states.
>
> **Why:** When commands failed silently or raised generic errors, downstream
> handlers could not differentiate between configuration errors and actual
> subprocess failures, leading to loss of arguments and return codes. Failing to
> adhere to this typically results in **Lost Diagnostic Context**.

**Trap 1: Catching a subprocess failure and re-raising it as a generic git error
with a concatenated string message.**

**Don't:**

```python
if self.rc != 0:
    raise GitError("%s: %s" % (command[1], e))
```

**Do:**

```python
if self.rc != 0:
    raise GitCommandError(
        message="git command failure",
        project=project.name,
        command_args=self.cmdv,
        git_rc=self.rc,
        git_stdout=stdout,
    )
```

--------------------------------------------------------------------------------

#### T3-18: Line-Based Log Extraction for Subprocess Diagnostics

> **Rule:** Extract and log the first meaningful line of both standard output
> and error streams rather than enforcing arbitrary truncation limits.
>
> **What:** When capturing subprocess logs for error reporting, extract the
> first meaningful line of `stdout` and `stderr` instead of relying on arbitrary
> character limits.
>
> **Applies To:** Error truncation logic for Git subprocesses in `Wait()`
> blocks.
>
> **Why:** Truncating output by an arbitrary number of characters (e.g., 80
> chars) occasionally cut off the actual error string. Furthermore, ignoring
> `stderr` hid the root cause of the subprocess failure. Failing to adhere to
> this typically results in **Obfuscated Error Logs**.

**Trap 1: Truncating stdout to a fixed number of characters and ignoring stderr
entirely.**

**Don't:**

```python
stdout = self.stdout[:80] if self.stdout else None
```

**Do:**

```python
# Prefer extracting the first full line and including stderr
stdout_line = self.stdout.splitlines()[0] if self.stdout else None
stderr_line = self.stderr.splitlines()[0] if self.stderr else None
```

--------------------------------------------------------------------------------

### Cross-Domain Dependencies

*   **Upstream:** T2 | Filesystem Atomicity & Worktree Layout - *Subprocess
    executions must coordinate with filesystem atomicity rules, particularly
    regarding submodule paths and worktree usage to prevent upstream Git bugs.*
*   **Downstream:** T5 | Hermetic Testing & Test Modernization - *Testing
    frameworks depend on hermetic GitCommand wrappers and mocked stream capture
    to validate subprocess behaviors safely.*

## Chapter: Manifest Object Model & Deduplication

**Context:** This chapter governs the parsing, validation, and canonicalization
of XML manifest components. It strictly enforces semantic immutability via
`NamedTuple` implementations, defensive copying for hierarchical override
scoping, and deterministic JSON-backed file tracking across the subsystem.

### Summary

| Rule ID   | Principle / Constraint    | Priority | Primary Symptom / Trap    |
| :-------- | :------------------------ | :------- | :------------------------ |
| **T4-01** | Strict Traversal Prefix   | High     | Using broad substring     |
:           : Matching for Relative     :          : matching to detect        :
:           : URLs                      :          : relative traversal        :
:           :                           :          : sequences.                :
| **T4-02** | Extend-Project            | High     | Omitting group            |
:           : Inheritance Scoping       :          : inheritance constraints   :
:           :                           :          : for dynamically           :
:           :                           :          : overridden node elements. :
| **T4-03** | Tuple Immutability in     | Medium   | Instantiating transient   |
:           : Membership Checks         :          : list objects inside loop  :
:           :                           :          : conditions.               :
| **T4-04** | Defensive Copying of      | High     | Assigning a shared        |
:           : Shared Collections Prior  :          : collection reference and  :
:           : to In-Place Mutation      :          : immediately using an      :
:           :                           :          : in-place operator,        :
:           :                           :          : unknowingly mutating the  :
:           :                           :          : original source.          :
| **T4-05** | Immutable NamedTuples for | High     | Overriding `__hash__` and |
:           : Hashable Object           :          : `__eq__` on a standard    :
:           : Deduplication             :          : mutable Python class to   :
:           :                           :          : allow set insertion.      :
| **T4-06** | Strict Empty Set          | Critical | Falling back to the empty |
:           : Initialization Over       :          : bracket literal when a    :
:           : Dictionary Literals       :          : null set is encountered   :
:           :                           :          : prior to a union          :
:           :                           :          : operation.                :
| **T4-07** | Immutable Manifest        | High     | Implementing custom       |
:           : Elements for Reliable     :          : `__eq__` and `__hash__`   :
:           : Deduplication             :          : on mutable classes and    :
:           :                           :          : using `list.append()`     :
:           :                           :          : which allows duplicates   :
:           :                           :          : to accrue.                :
| **T4-08** | Mutually Exclusive XML    | Medium   | Independent `if`          |
:           : Node Parsing              :          : conditions checking       :
:           :                           :          : `nodeName` sequentially   :
:           :                           :          : in a loop.                :
| **T4-09** | JSON Serialization for    | High     | Dumping file paths        |
:           : File Path State Tracking  :          : sequentially into a flat  :
:           :                           :          : text file using newlines  :
:           :                           :          : as the only delimiter.    :
| **T4-10** | Set Operations for File   | Medium   | Using manual for-loops    |
:           : Deltas                    :          : and list appends to       :
:           :                           :          : calculate the difference  :
:           :                           :          : between two collections.  :
| **T4-11** | Upstream Base Revision    | Medium   | Overriding a project      |
:           : Validation in Layered     :          : revision without          :
:           : Manifests                 :          : asserting the previous    :
:           :                           :          : expected state.           :

--------------------------------------------------------------------------------

### Rules

#### T4-01: Strict Traversal Prefix Matching for Relative URLs

> **Rule:** Always explicitly evaluate exact path-traversal prefixes (`./` or
> `../`) when resolving relative URLs. Never rely on generic substring matching.
>
> **What:** Relative URL path detection must explicitly evaluate exact
> path-traversal prefixes to avoid inadvertently capturing hidden files or
> custom naming structures.
>
> **Applies To:** URL string manipulation and Git submodule path resolution.
>
> **Why:** The path parser attempted to identify relative submodule paths by
> checking if the URL started with a dot (`.`). This excessively broad
> evaluation failed on identically named hidden repositories or custom
> sub-namespaces (e.g., `.foo`), improperly joining them to the base URL.
> Failing to adhere to this typically results in **Invalid Path Resolution**.

**Trap 1: Using broad substring matching to detect relative traversal
sequences.**

**Don't:**

```python
if url.startswith("."):
    url = urllib.parse.urljoin("%s/" % self.remote.url, url)
```

**Do:**

```python
if url.startswith("./") or url.startswith("../"):
    url = urllib.parse.urljoin("%s/" % self.remote.url, url)
```

--------------------------------------------------------------------------------

#### T4-02: Extend-Project Inheritance Scoping

> **Rule:** Must explicitly restrict `extend-project` XML nodes from
> automatically inheriting contextually local execution scopes (`local:` groups)
> from root parents.
>
> **What:** When managing XML manifestation directives, `extend-project` nodes
> must be actively restricted from inheriting contextually local execution
> scopes (`local:` groups).
>
> **Applies To:** XML manifest engine mappings and override properties.
>
> **Why:** Without explicit protection, extended project entities
> unintentionally inherited top-level project local groups, confusing the
> inclusion and exclusion scoping directives that drive synchronization
> boundaries. Failing to adhere to this typically results in **Scope
> Contamination**.

**Trap 1: Omitting group inheritance constraints for dynamically overridden node
elements.**

**Don't:**

*   Allow XML logic to process `extend-project` the exact same way it processes
    raw `project` roots without negative test coverage.

**Do:**

*   Implement testing and parsing guards proving that elements processed under
    `extend-project` actively strip `local:` group attributes.

--------------------------------------------------------------------------------

#### T4-03: Tuple Immutability in Membership Checks

> **Rule:** Always use immutable tuples instead of list literals for membership
> tests against constant sequences within hot loops.
>
> **What:** Utilize immutable tuples `()` instead of list literals `[]` when
> performing membership tests (the `in` operator) against constant sequences to
> minimize reallocation overhead and adhere to idiomatic Python.
>
> **Applies To:** XML manifest parsing logic (`manifest_xml.py`) and hot loops
> across the codebase.
>
> **Why:** During recursive node parsing, list literals were instantiated on
> every iteration solely to check if a node name matched fixed schema elements.
> Failing to adhere to this typically results in **Performance Degradation**.

**Trap 1: Instantiating transient list objects inside loop conditions.**

**Don't:**

```python
if node.nodeName in ["include", "project"]:
```

**Do:**

```python
if node.nodeName in ("include", "project"):
```

--------------------------------------------------------------------------------

#### T4-04: Defensive Copying of Shared Collections Prior to In-Place Mutation

> **Rule:** Must defensively copy shared parent collections before applying
> in-place update operators (`|=`), strictly handling null-safety during the
> process.
>
> **What:** When propagating inherited collections (e.g., manifest group sets)
> to child nodes, shared parent sets must be defensively copied prior to
> applying in-place union or update operators (`|=`). Null-safety must be
> handled during the copy.
>
> **Applies To:** XML Manifest Parsing (`manifest_xml.py`); hierarchical state
> propagation where child elements inherit and augment parent states.
>
> **Why:** Assigning a parent's group set directly to a child and then using the
> in-place union operator (`|=`) modified the original parent set in memory.
> This caused the child's specific groups to 'leak' into unrelated sibling nodes
> processed subsequently. Failing to adhere to this typically results in **State
> Corruption / Group Leakage**.

**Trap 1: Assigning a shared collection reference and immediately using an
in-place operator, unknowingly mutating the original source.**

**Don't:**

```python
# BAD: In-place modification mutates the shared parent_groups object
nodeGroups = parent_groups
if node.hasAttribute("groups"):
    nodeGroups |= self._ParseSet(node.getAttribute("groups"))
```

**Do:**

```python
# GOOD: Create a localized copy before mutation
nodeGroups = parent_groups.copy() if parent_groups else set()
if node.hasAttribute("groups"):
    nodeGroups |= self._ParseSet(node.getAttribute("groups"))
```

**Trap 2: Falling back to an empty set instantiation after a copy call without
guarding against a null reference.**

**Don't:**

```python
# BAD: Raises AttributeError if parent_groups is None
include_groups = parent_groups.copy() or set()
```

**Do:**

```python
# GOOD: Null-safe default evaluation prior to the copy invocation
include_groups = (parent_groups or set()).copy()
```

--------------------------------------------------------------------------------

#### T4-05: Immutable NamedTuples for Hashable Object Deduplication

> **Rule:** Always subclass `NamedTuple` to define custom objects stored in
> hash-based collections. Never implement manual `__hash__` and `__eq__`
> functions on mutable classes.
>
> **What:** Custom objects stored in hash-based collections (like `set` or used
> as `dict` keys) for deduplication must guarantee immutability. Avoid manually
> implementing `__eq__` and `__hash__` on mutable classes; instead, subclass
> `NamedTuple`.
>
> **Applies To:** Manifest deduplication logic (`project.py`); specifically
> elements like `_CopyFile` and `_LinkFile` stored in sets.
>
> **Why:** Manually implementing `__hash__` on a standard class based on its
> mutable `__dict__` attributes created a landmine. If the object's properties
> changed after insertion into a set, the hash mismatched, rendering the object
> unreachable and breaking deduplication. Failing to adhere to this typically
> results in **Memory Leak / Deduplication Failure**.

**Trap 1: Overriding `__hash__` and `__eq__` on a standard mutable Python class
to allow set insertion.**

**Don't:**

```python
# BAD: Properties can mutate, altering the hash post-insertion
class _CopyFile:
    def __init__(self, src, dest):
        self.src = src
        self.dest = dest
    def __hash__(self):
        return hash(repr(sorted(self.__dict__.items())))
    def __eq__(self, other):
        return self.__dict__ == other.__dict__
```

**Do:**

```python
# GOOD: Use typing.NamedTuple to guarantee immutability
from typing import NamedTuple

class _CopyFile(NamedTuple):
    src: str
    dest: str
```

--------------------------------------------------------------------------------

#### T4-06: Strict Empty Set Initialization Over Dictionary Literals

> **Rule:** Must explicitly invoke `set()` when initializing empty collections
> meant for set operations. Never fall back to the empty bracket literal `{}`.
>
> **What:** When initializing or providing a fallback empty collection meant for
> set operations (such as union `|` or `|=`), explicitly instantiate a `set()`
> rather than using the empty literal `{}`.
>
> **Applies To:** Python collection management globally; prominently surfaced
> during list-to-set manifest group migrations.
>
> **Why:** During a migration from lists to sets for group parsing, an empty
> default was incorrectly represented as `{}`. Since `{}` evaluates to a `dict`
> in Python, attempting a set union between a valid set and the empty dict threw
> an immediate, fatal `TypeError`. Failing to adhere to this typically results
> in **Runtime Crash / TypeError**.

**Trap 1: Falling back to the empty bracket literal when a null set is
encountered prior to a union operation.**

**Don't:**

```python
# BAD: '{}' creates an empty dictionary, throwing a TypeError upon union
expanded_project_groups = {"all"} | (self.groups or {})
```

**Do:**

```python
# GOOD: Explicitly initialize an empty set
expanded_project_groups = {"all"} | (self.groups or set())
```

--------------------------------------------------------------------------------

#### T4-07: Immutable Manifest Elements for Reliable Deduplication

> **Rule:** Always represent manifest file operations as inherently immutable
> structures to guarantee safe, order-preserving deduplication.
>
> **What:** Manifest elements representing file operations must be implemented
> as immutable structures (e.g., `NamedTuple`) to ensure safe deduplication and
> deterministic order preservation, avoiding manual string-based hashing.
>
> **Applies To:** Manifest parsing models, specifically `<copyfile>` and
> `<linkfile>` abstractions.
>
> **Why:** Previously, manifest objects were stored in mutable lists, relying on
> manual string representations (`repr`) and sorted dictionary items for
> hashing. This risked state corruption and failed to cleanly deduplicate
> repeated entries while maintaining the relative declaration sequence. Failing
> to adhere to this typically results in **Silent Data Corruption / Redundant
> File Operations**.

**Trap 1: Implementing custom `__eq__` and `__hash__` on mutable classes and
using `list.append()` which allows duplicates to accrue.**

**Don't:**

```python
class _CopyFile:
    def __hash__(self):
        # BAD: Manual serialization of mutable dictionary
        return hash(repr(sorted(self.__dict__.items())))

self.copyfiles.append(_CopyFile(src, dest))
```

**Do:**

```python
class _CopyFile(NamedTuple):
    # GOOD: Inherently immutable and hashable
    src: str
    dest: str

# GOOD: Using a dict to deduplicate while preserving insertion order
self.copyfiles[_CopyFile(src, dest)] = True
```

--------------------------------------------------------------------------------

#### T4-08: Mutually Exclusive XML Node Parsing

> **Rule:** Always chain mutually exclusive XML node type checks using an
> `if-elif` structure rather than independent sequential statements.
>
> **What:** When parsing mutually exclusive XML node types, use an `if-elif`
> structure to avoid redundant condition evaluations.
>
> **Applies To:** XML parsing loops (e.g., iterating over `node.childNodes` in
> `manifest_xml.py`).
>
> **Why:** A sequence of independent `if` statements forced unnecessary string
> comparisons even after a matching node name was found. Failing to adhere to
> this typically results in **CPU Overhead / Inefficient Parsing**.

**Trap 1: Independent `if` conditions checking `nodeName` sequentially in a
loop.**

**Don't:**

```python
if n.nodeName == "copyfile":
    self._ParseCopyFile(p, n)
if n.nodeName == "linkfile":
    self._ParseLinkFile(p, n)
```

**Do:**

```python
if n.nodeName == "copyfile":
    self._ParseCopyFile(p, n)
elif n.nodeName == "linkfile":
    self._ParseLinkFile(p, n)
```

--------------------------------------------------------------------------------

#### T4-09: JSON Serialization for File Path State Tracking

> **Rule:** Must persist dynamically generated manifest file outputs using
> structured JSON serialization. Never use newline-delimited plaintext for path
> lists.
>
> **What:** Persistent tracking mechanisms for manifest-generated file
> operations must use structured JSON serialization instead of newline-delimited
> plaintext to support special characters in paths.
>
> **Applies To:** Manifest state management (`subcmds/sync.py`), internal
> `.repo` tracking files (e.g., `copy-link-files.json`).
>
> **Why:** Tracking `<copyfile>` and `<linkfile>` operations via flat,
> newline-delimited text files broke serialization and cleanup when file paths
> legally contained newline (`\n`) characters. Structured JSON protects against
> these bounds issues. Failing to adhere to this typically results in **Parsing
> Errors / Orphaned Files**.

**Trap 1: Dumping file paths sequentially into a flat text file using newlines
as the only delimiter.**

**Don't:**

```python
with open('linkfile.list', 'w') as fd:
    for path in new_linkfiles:
        fd.write(path + '\n')
```

**Do:**

```python
with open('copy-link-files.json', 'w') as fd:
    json.dump({'linkfile': new_linkfiles, 'copyfile': new_copyfiles}, fd)
```

--------------------------------------------------------------------------------

#### T4-10: Set Operations for File Deltas

> **Rule:** Always compute the delta between unordered lists of file paths using
> native Python set operations (`-`).
>
> **What:** When computing the delta between lists of file paths (e.g., figuring
> out which obsolete files to remove), utilize Python set operations rather than
> manual iterations with truthiness and membership checks.
>
> **Applies To:** Deduplicating objects, comparing manifest states, computing
> file differences.
>
> **Why:** Calculating the difference between historical tracking data and new
> target paths was done using O(N*M) nested iterations with redundant truthiness
> checks, leading to verbose and less performant code. Failing to adhere to this
> typically results in **Algorithmic Inefficiency**.

**Trap 1: Using manual for-loops and list appends to calculate the difference
between two collections.**

**Don't:**

```python
need_remove_files = []
for old_path in old_dict.get('linkfile', []):
  if old_path and old_path not in new_paths:
    need_remove_files.append(old_path)
```

**Do:**

```python
need_remove_files = []
need_remove_files.extend(
    set(old_dict.get('linkfile', [])) -
    set(new_paths)
)
```

**Exceptions:** Ordered constraints where file evaluation sequence matters (sets
are unordered).

--------------------------------------------------------------------------------

#### T4-11: Upstream Base Revision Validation in Layered Manifests

> **Rule:** Must assert multi-layer manifest overrides (`extend-project`)
> against the parent project's expected state by utilizing a `base-rev`
> attribute.
>
> **What:** When overriding (`extend-project`) or removing (`remove-project`)
> projects in a layered manifest structure, changes should be validated against
> the expected state of the parent project via a `base-rev` attribute.
>
> **Applies To:** XML Manifest parsing logic (`manifest_xml.py`) during
> multi-manifest ingestion.
>
> **Why:** Downstream projects using layered manifests would unknowingly apply
> overrides (like custom revisions) to upstream components that had drastically
> changed their underlying state or branches, resulting in 'undead patches' that
> silently masked critical upstream changes. Failing to adhere to this typically
> results in **Silent Configuration Divergence**.

**Trap 1: Overriding a project revision without asserting the previous expected
state.**

**Don't:**

```xml
<!-- BAD: Blind override leaves system vulnerable to upstream changes -->
<extend-project name="my-project" revision="refs/changes/123" />
```

**Do:**

```xml
<!-- GOOD: Base-rev acts as a guardrail -->
<extend-project name="my-project" base-rev="upstream_hash" revision="refs/changes/123" />
```

**Trap 2: Checking string-based manifest attributes using implicit truthiness.**

**Don't:**

```python
# BAD: Implicit truthiness skips validation if revisionExpr is unexpectedly empty
if base and p.revisionExpr and p.revisionExpr != base:
    raise Error()
```

**Do:**

```python
# GOOD: Strict comparison catches empty/None states if a base is declared
if base and p.revisionExpr != base:
    raise Error()
```

**Exceptions:** The `base-rev` attribute is optional to maintain backward
compatibility for users migrating to the new manifest schema.

--------------------------------------------------------------------------------

### Cross-Domain Dependencies

*   **Upstream:** T2 | Filesystem Atomicity & Worktree Layout - *File path
    extraction and submodule path resolution mapped here strictly govern
    worktree creation and legacy migration algorithms downstream.*
*   **Downstream:** T6 | CLI Argument Parsing & UX Consistency - *Structured
    JSON serialization outputted from manifest paths sets the direct format
    constraint for CLI UX and tooling integrations.*

## Chapter: Hermetic Testing & Test Modernization

**Context:** This domain governs the migration of legacy `unittest` suites to
modern `pytest` functional paradigms and the establishment of hermetic session
fixtures. It enforces strict environment isolation to prevent global state
pollution (e.g., developer `.gitconfig` bleeding) while safely intercepting
standard streams and filesystem paths.

### Summary

| Rule ID   | Principle / Constraint          | Priority | Primary Symptom /   |
:           :                                 :          : Trap                :
| :-------- | :------------------------------ | :------- | :------------------ |
| **T5-01** | Idiomatic Truthiness Validation | Medium   | Asserting strict    |
:           : in Tests                        :          : identity against    :
:           :                                 :          : Python boolean      :
:           :                                 :          : singletons.         :
| **T5-02** | Pytest Over Legacy Unittest     | High     | Subclassing         |
:           : Framework                       :          : `unittest.TestCase` :
:           :                                 :          : and configuring     :
:           :                                 :          : state inside a      :
:           :                                 :          : `setUp` method for  :
:           :                                 :          : new test files.     :
| **T5-03** | Dedicated Test Utilities for    | Medium   | Copy-pasting        |
:           : API Helpers                     :          : utility functions   :
:           :                                 :          : across test modules :
:           :                                 :          : or placing standard :
:           :                                 :          : functions into      :
:           :                                 :          : pytest conftest     :
:           :                                 :          : files.              :
| **T5-04** | Test Framework Modernization to | High     | Modifying           |
:           : Pytest                          :          : environment         :
:           :                                 :          : variables globally  :
:           :                                 :          : at module load to   :
:           :                                 :          : support tests.      :
| **T5-05** | Standard Output Capture via     | Medium   | Using the mock      |
:           : Context Managers                :          : framework to        :
:           :                                 :          : intercept a core    :
:           :                                 :          : language stream.    :
| **T5-06** | Direct Helper Functions Over    | Medium   | Defining a pytest   |
:           : Fixture Factories               :          : fixture that yields :
:           :                                 :          : a nested function   :
:           :                                 :          : to bypass global    :
:           :                                 :          : state limitations.  :
| **T5-07** | Elimination of Redundant Path   | Medium   | Chaining explicit   |
:           : Assertions                      :          : existence checks    :
:           :                                 :          : before access       :
:           :                                 :          : checks.             :
| **T5-08** | Pathlib Utility Constants for   | Medium   | Using nested        |
:           : Test Path Resolution            :          : `os.path.dirname`   :
:           :                                 :          : and `os.path.join`  :
:           :                                 :          : to traverse back to :
:           :                                 :          : the parent          :
:           :                                 :          : directory.          :
| **T5-09** | Pytest Adoption for Test Suite  | High     | Creating test case  |
:           : Definition                      :          : classes that        :
:           :                                 :          : inherit from        :
:           :                                 :          : `unittest.TestCase` :
:           :                                 :          : and asserting via   :
:           :                                 :          : `self.assertEqual`. :
| **T5-10** | Minimal Mocking Isolation for   | High     | Using stacked patch |
:           : Test Reliability                :          : decorators for      :
:           :                                 :          : non-relevant        :
:           :                                 :          : sub-routines (e.g., :
:           :                                 :          : standard error      :
:           :                                 :          : outputs or          :
:           :                                 :          : colorizers) just to :
:           :                                 :          : trigger an embedded :
:           :                                 :          : autocorrection      :
:           :                                 :          : flow.               :
| **T5-11** | Canonical Resolution for System | Medium   | Patching            |
:           : Library Mocks                   :          : `time.sleep` by     :
:           :                                 :          : referencing the     :
:           :                                 :          : specific host       :
:           :                                 :          : application file    :
:           :                                 :          : where it was        :
:           :                                 :          : locally imported.   :
| **T5-12** | Memoized Function Cache         | High     | Mocking the         |
:           : Clearing in Setup               :          : underlying behavior :
:           :                                 :          : of a cached         :
:           :                                 :          : function but        :
:           :                                 :          : leaving the LRU     :
:           :                                 :          : cache intact across :
:           :                                 :          : tests.              :
| **T5-13** | Idiomatic Standard Stream       | Medium   | Using `mock.patch`  |
:           : Redirection                     :          : to manually inject  :
:           :                                 :          : a `StringIO` object :
:           :                                 :          : over `sys.stderr`.  :
| **T5-14** | Context Manager Nesting         | Medium   | Adding a new level  |
:           : Consolidation                   :          : of indentation for  :
:           :                                 :          : every context       :
:           :                                 :          : manager invoked.    :
| **T5-15** | Anti-Change Detector Tests      | Medium   | Asserting exact     |
:           :                                 :          : equality of string  :
:           :                                 :          : outputs including   :
:           :                                 :          : standardized        :
:           :                                 :          : prefixes.           :
| **T5-16** | Infrastructure Prebuilts via    | Medium   | Relying on tools    |
:           : vpython                         :          : that dynamically    :
:           :                                 :          : build Python from   :
:           :                                 :          : source to test      :
:           :                                 :          : across multiple     :
:           :                                 :          : versions.           :
| **T5-17** | Modernized Filesystem Paths via | Medium   | Using               |
:           : Pathlib                         :          : `os.path.join` and  :
:           :                                 :          : `with open(...,     :
:           :                                 :          : 'w')` for basic     :
:           :                                 :          : text file creation  :
:           :                                 :          : in tests.           :
| **T5-18** | Standardized Module-Level Mock  | Medium   | Importing specific  |
:           : Imports                         :          : classes or          :
:           :                                 :          : exceptions directly :
:           :                                 :          : from test targets   :
:           :                                 :          : or standard         :
:           :                                 :          : libraries.          :
| **T5-19** | Pytest Adoption for New Test    | High     | Creating subclasses |
:           : Modules                         :          : of                  :
:           :                                 :          : `unittest.TestCase` :
:           :                                 :          : and using           :
:           :                                 :          : `self.assertEqual`. :
| **T5-20** | High-Fidelity Test Targets over | High     | Using `MagicMock`   |
:           : Permissive Mocks                :          : to bypass           :
:           :                                 :          : instantiating core  :
:           :                                 :          : models.             :
| **T5-21** | Session-Scoped Hermetic Git     | Medium   | Executing `git      |
:           : Identity Injection              :          : config` inside      :
:           :                                 :          : individual test     :
:           :                                 :          : setup blocks to     :
:           :                                 :          : fake a user         :
:           :                                 :          : identity.           :
| **T5-22** | Automated Lifecycle Management  | High     | Spawning detached   |
:           : for Test Filesystem Artifacts   :          : temporary           :
:           :                                 :          : directories and     :
:           :                                 :          : manually            :
:           :                                 :          : maintaining cleanup :
:           :                                 :          : blocks.             :
| **T5-23** | Idiomatic String Evaluation in  | Medium   | Iterating over raw  |
:           : Mocked Test Streams             :          : string splits and   :
:           :                                 :          : manually validating :
:           :                                 :          : line length to      :
:           :                                 :          : count valid output  :
:           :                                 :          : strings.            :
| **T5-24** | Hermetic Isolation of Git       | High     | Relying on default  |
:           : Configuration Directories in    :          : system paths for    :
:           : Tests                           :          : the home directory  :
:           :                                 :          : during test         :
:           :                                 :          : execution.          :
| **T5-25** | Scope Hierarchy Enforcement in  | Medium   | Injecting           |
:           : Pytest Fixtures                 :          : `tmp_path` into a   :
:           :                                 :          : fixture decorated   :
:           :                                 :          : with                :
:           :                                 :          : `scope="session"`.  :
| **T5-26** | Strict Python Version           | Medium   | Adding modern       |
:           : Compatibility for Third-Party   :          : third-party test    :
:           : Plugins                         :          : dependencies to     :
:           :                                 :          : legacy-supported    :
:           :                                 :          : projects without    :
:           :                                 :          : validating the      :
:           :                                 :          : minimum required    :
:           :                                 :          : Python constraints. :
| **T5-27** | Hermetic Isolation of Terminal  | High     | Relying on the      |
:           : UI Color Configurations         :          : default state of    :
:           :                                 :          : the `Coloring`      :
:           :                                 :          : class without       :
:           :                                 :          : forcing it during   :
:           :                                 :          : setup, implicitly   :
:           :                                 :          : depending on        :
:           :                                 :          : environmental       :
:           :                                 :          : variables.          :
| **T5-28** | Abstract Intent Documentation   | Medium   | Documenting exact   |
:           : in Unit Tests                   :          : data values being   :
:           :                                 :          : asserted directly   :
:           :                                 :          : in the test         :
:           :                                 :          : docstring.          :

--------------------------------------------------------------------------------

### Rules

#### T5-01: Idiomatic Truthiness Validation in Tests

> **Rule:** Always use implicit truthiness or falsiness evaluations in test
> assertions unless strict type matching is explicitly required.
>
> **What:** Test suites must use implicit truthy/falsy validations rather than
> asserting strict identity against boolean singletons unless exact type
> enforcement is necessary.
>
> **Applies To:** Python assertions in test frameworks (pytest, unittest).
>
> **Why:** Tests relying on strict boolean identity (`is True`) became brittle
> when refactoring configurations or flag implementations that returned
> alternative truthy values. Failing to adhere to this typically results in
> **Brittle Assertions**.

**Trap 1: Asserting strict identity against Python boolean singletons.**

**Don't:**

```python
assert opts.include_summary is True
```

**Do:**

```python
assert opts.include_summary
```

**Exceptions:** Situations where distinguishing between None and False is
structurally critical to the application logic.

--------------------------------------------------------------------------------

#### T5-02: Pytest Over Legacy Unittest Framework

> **Rule:** Must implement new test suites using modular `pytest` definitions
> instead of propagating `unittest.TestCase` boilerplate.
>
> **What:** New test modules must be implemented using standalone `pytest`
> functional constructs rather than inheriting from `unittest.TestCase` to avoid
> heavy class-based boilerplate.
>
> **Applies To:** Test module architecture (`tests/test_*.py`).
>
> **Why:** The project previously utilized deeply nested `unittest.TestCase`
> structures with complex `setUp` inheritance, which obfuscated test
> initialization and hindered code reusability. Failing to adhere to this
> typically results in **High Boilerplate / Lock-In**.

**Trap 1: Subclassing `unittest.TestCase` and configuring state inside a `setUp`
method for new test files.**

**Don't:**

```python
class InfoCommand(unittest.TestCase):
    def setUp(self):
        self.cmd = build_cmd()
```

**Do:**

```python
def _get_cmd():
    return build_cmd()

def test_command_defaults():
    cmd = _get_cmd()
    assert cmd.is_valid()
```

--------------------------------------------------------------------------------

#### T5-03: Dedicated Test Utilities for API Helpers

> **Rule:** Never overload `conftest.py` with generic API helpers; always place
> reusable test queries in dedicated utility modules.
>
> **What:** Shared test APIs and environment-probing logic (e.g., checking Git
> feature support) must be placed in dedicated utility modules (like
> `utils_for_test.py`) rather than duplicated or shoved into `conftest.py`.
>
> **Applies To:** Test suite architecture and environment scaffolding.
>
> **Why:** Developers were duplicating identical environment checks across
> different test files or misusing `conftest.py` (which should only contain
> fixtures) to store functional APIs. Failing to adhere to this typically
> results in **Test Code Duplication**.

**Trap 1: Copy-pasting utility functions across test modules or placing standard
functions into pytest conftest files.**

**Don't:**

```python
# Inside test_project.py AND test_git_refs.py
def _SupportsReftable():
    return check_git_support()
```

**Do:**

```python
# Inside tests/utils_for_test.py
def supports_reftable():
    return check_git_support()

# Inside test_project.py
import utils_for_test
@unittest.skipUnless(utils_for_test.supports_reftable(), "...")
```

**Exceptions:** Test fixtures (such as initialized directories or mock
generators) which belong in `conftest.py`.

--------------------------------------------------------------------------------

#### T5-04: Test Framework Modernization to Pytest

> **Rule:** Avoid global module-level environment mutations; consistently
> leverage `pytest` global configuration fixtures.
>
> **What:** Legacy `unittest.TestCase` structures must be migrated to functional
> `pytest` paradigms, leveraging global configuration fixtures over class-based
> `setUp` and `tearDown` methods.
>
> **Applies To:** Entire Python test suite and all new unit tests.
>
> **Why:** Heavy inheritance and isolated setup code within `unittest.TestCase`
> resulted in repeated environment mutation logic, obscured dependencies, and an
> inability to easily share global setup mechanisms like dummy user identities
> or tracing control. Failing to adhere to this typically results in **Global
> State Pollution**.

**Trap 1: Modifying environment variables globally at module load to support
tests.**

**Don't:**

```python
import os
os.environ['REPO_TRACE'] = '0'

class GitRefsTest(unittest.TestCase):
    def setUp(self):
        self.tempdir = tempfile.TemporaryDirectory()
```

**Do:**

```python
# Rely on conftest.py fixtures automatically handling environments.
def test_git_refs(tmp_path, disable_repo_trace, setup_user_identity):
    gitdir = tmp_path / '.git'
    # Run assertions using standard assert statements
    assert head == refs.get('HEAD')
```

--------------------------------------------------------------------------------

#### T5-05: Standard Output Capture via Context Managers

> **Rule:** Must utilize `contextlib.redirect_stdout` to capture standard output
> streams rather than injecting raw stream mocks.
>
> **What:** Use the standard library `contextlib.redirect_stdout` for capturing
> command output in test scopes, instantiated directly as a one-liner, rather
> than utilizing the `unittest.mock` framework to patch system streams.
>
> **Applies To:** Python test suites (Pytest/Unittest) intercepting CLI stdout
> payloads.
>
> **Why:** Tests were previously relying on `@mock.patch` for `sys.stdout` or
> utilizing multi-line context manager instantiations, which unnecessarily
> coupled output capture to the mocking engine and added boilerplate. Failing to
> adhere to this typically results in **Unnecessary Mocking / Test Bloat**.

**Trap 1: Using the mock framework to intercept a core language stream.**

**Don't:**

```python
@mock.patch("sys.stdout", new_callable=io.StringIO)
def test_something(self, mock_stdout):
    # test logic
```

**Do:**

```python
import contextlib
import io

def test_something():
    with contextlib.redirect_stdout(io.StringIO()) as stdout:
        # test logic
```

**Trap 2: Creating the string buffer variable outside the context manager scope
unnecessarily.**

**Don't:**

```python
stdout = io.StringIO()
with contextlib.redirect_stdout(stdout):
    _run_status(manifest, ["-o"])
```

**Do:**

```python
with contextlib.redirect_stdout(io.StringIO()) as stdout:
    _run_status(manifest, ["-o"])
```

--------------------------------------------------------------------------------

#### T5-06: Direct Helper Functions Over Fixture Factories

> **Rule:** Avoid defining dummy `pytest` fixtures solely to return nested
> function callbacks; use straightforward module-level helpers instead.
>
> **What:** Do not abuse the Pytest fixture system to generate and return local
> functions. If a utility does not benefit from the fixture lifecycle management
> (setup/teardown), it should be a standard module-level or private helper
> function.
>
> **Applies To:** Pytest files requiring test data initialization or repetitive
> setup procedures.
>
> **Why:** Test frameworks became overly complex when developers wrapped simple
> initialization logic in `@pytest.fixture` annotations just to yield a callable
> function to the test case. Failing to adhere to this typically results in
> **Fixture Graph Bloat**.

**Trap 1: Defining a pytest fixture that yields a nested function to bypass
global state limitations.**

**Don't:**

```python
@pytest.fixture
def init_temp_git_tree():
    def _init_temp_git_tree(git_dir: Path) -> None:
        # init logic
    return _init_temp_git_tree
```

**Do:**

```python
def _init_temp_git_tree(git_dir: Path) -> None:
    # init logic
```

--------------------------------------------------------------------------------

#### T5-07: Elimination of Redundant Path Assertions

> **Rule:** Never prepend path existence assertions prior to invoking
> permissions or loading assertions that implicitly validate existence.
>
> **What:** Do not assert the existence of a file prior to asserting its
> specific permissions or state. Subsequent OS-level operations implicitly
> validate path existence.
>
> **Applies To:** Python unittests validating filesystem layouts, binary
> configurations, or hook executable permissions.
>
> **Why:** Tests contained boilerplate blocks invoking `os.path.isfile()` purely
> to offer a custom string format failure, even though the immediate next line
> invoking `os.access()` would fail correctly with an implicit lack of
> existence. Failing to adhere to this typically results in **Test
> Boilerplate**.

**Trap 1: Chaining explicit existence checks before access checks.**

**Don't:**

```python
self.assertTrue(os.path.isfile(repo_path), f"{repo_path} does not exist")
self.assertTrue(os.access(repo_path, os.X_OK), f"{repo_path} is not executable")
```

**Do:**

```python
self.assertTrue(os.access(repo_path, os.X_OK), f"{repo_path} is not executable")
```

--------------------------------------------------------------------------------

#### T5-08: Pathlib Utility Constants for Test Path Resolution

> **Rule:** Always resolve test filesystem boundaries using centralized
> `pathlib` objects instead of string-concatenating legacy `os.path` operations.
>
> **What:** Path constructions in test files should utilize modern pathlib
> objects via centralized utility constants (e.g., `utils_for_test.THIS_DIR`)
> instead of verbose `os.path` operations.
>
> **Applies To:** Python test suites interacting with the file system.
>
> **Why:** Manual path constructions using nested `os.path.dirname(__file__)`
> calls created verbose, hard-to-read boilerplate that cluttered the test logic.
> Failing to adhere to this typically results in **Verbose Code Base**.

**Trap 1: Using nested `os.path.dirname` and `os.path.join` to traverse back to
the parent directory.**

**Don't:**

```python
repo_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "repo")
```

**Do:**

```python
repo_path = utils_for_test.THIS_DIR.parent / "repo"
```

--------------------------------------------------------------------------------

#### T5-09: Pytest Adoption for Test Suite Definition

> **Rule:** Must author all file-level test assertions utilizing `pytest` syntax
> constructs over legacy `unittest` equivalents.
>
> **What:** Test files must be defined using the modern `pytest` framework,
> avoiding class-based `unittest.TestCase` inheritance and relying on standard
> `assert` semantics.
>
> **Applies To:** The entire Python testing suite.
>
> **Why:** The legacy `unittest` structure required extensive, verbose
> boilerplate for state setup, test case classes, and specific assertion methods
> that restricted readability. Failing to adhere to this typically results in
> **Test Verbosity**.

**Trap 1: Creating test case classes that inherit from `unittest.TestCase` and
asserting via `self.assertEqual`.**

**Don't:**

```python
import unittest
class RepoTests(unittest.TestCase):
    def test_example(self):
        self.assertEqual(a, b)
```

**Do:**

```python
# Standalone pytest functions
def test_example():
    assert a == b
```

--------------------------------------------------------------------------------

#### T5-10: Minimal Mocking Isolation for Test Reliability

> **Rule:** Avoid deeply nested or exhaustively mocked test wrappers; isolate
> and invoke inner target logic primitives instead.
>
> **What:** Mock usage must be limited strictly to necessary external
> intercepts. Exhaustive mock environments must not be created just to drive a
> small piece of inner logic; instead, structural refactoring must isolate the
> logical boundary.
>
> **Applies To:** Test suites involving deep API structures and side-effects.
>
> **Why:** Relying on heavily nested, brittle 'house of cards' mock
> configurations meant tests frequently failed when unrelated code modifications
> broke the strict internal mock assumptions, turning tests into throwaway
> artifacts. Failing to adhere to this typically results in **Fragile Mock
> Collapse**.

**Trap 1: Using stacked patch decorators for non-relevant sub-routines (e.g.,
standard error outputs or colorizers) just to trigger an embedded autocorrection
flow.**

**Don't:**

```python
with mock.patch("main.RepoClient", return_value=mock_client):
    with mock.patch("main.SetDefaultColoring"):
        repo._RunLong("tart", gopts, argv, log)
```

**Do:**

*   Isolate the logic into `_autocorrect_command_name()` and test it by passing
    minimal data primitives: `res = self.repo._autocorrect_command_name("tart",
    mock_config)`.

**Exceptions:** Testing hard, native OS-level boundary bindings.

--------------------------------------------------------------------------------

#### T5-11: Canonical Resolution for System Library Mocks

> **Rule:** Always patch standard libraries at their canonical origin namespace
> rather than targeting the local module import resolution boundary.
>
> **What:** Standard library functions must be targeted for testing patches at
> their canonical origin namespace rather than the local import footprint of the
> target module.
>
> **Applies To:** Test configuration defining `mock.patch` paths.
>
> **Why:** Patching against the local module import representation strictly
> coupled tests to a given file's exact inclusion syntax. Minor refactors
> altering module import aliases completely disabled testing verification.
> Failing to adhere to this typically results in **Brittle Patch Routing**.

**Trap 1: Patching `time.sleep` by referencing the specific host application
file where it was locally imported.**

**Don't:**

```python
@mock.patch("main.time.sleep")
```

**Do:**

```python
@mock.patch("time.sleep")
```

--------------------------------------------------------------------------------

#### T5-12: Memoized Function Cache Clearing in Setup

> **Rule:** Always flush the `lru_cache` of mocked globally-accessible memoized
> functions within the test initialization sequence.
>
> **What:** When mocking globally accessible functions decorated with
> `@functools.lru_cache`, the cache must be explicitly cleared in the test
> suite's `setUp` routine.
>
> **Applies To:** Unit test suites interacting with memoized functions.
>
> **Why:** Failing to clear the `lru_cache` of globally executed functions
> during testing caused subsequent tests in the runner to receive cached mock
> results injected by prior tests, leading to non-deterministic, cascading
> failures. Failing to adhere to this typically results in **State Contamination
> / Flaky Tests**.

**Trap 1: Mocking the underlying behavior of a cached function but leaving the
LRU cache intact across tests.**

**Don't:**

```python
class SshTests(unittest.TestCase):
    def test_version(self):
        with mock.patch("ssh._run_ssh_version", return_value="OpenSSH_1.2\n"):
            self.assertEqual(ssh.version(), (1, 2))
```

**Do:**

```python
class SshTests(unittest.TestCase):
    def setUp(self):
        ssh.version.cache_clear()

    def test_version(self):
        with mock.patch("ssh._run_ssh_version", return_value="OpenSSH_1.2\n"):
            self.assertEqual(ssh.version(), (1, 2))
```

--------------------------------------------------------------------------------

#### T5-13: Idiomatic Standard Stream Redirection

> **Rule:** Always employ `contextlib.redirect_stderr` directly instead of
> overwriting standard stream objects globally using patch frameworks.
>
> **What:** To intercept `stderr` or `stdout` in testing, utilize the standard
> library's context managers (`contextlib.redirect_stderr`) instead of
> overriding the stream objects globally using `mock.patch`.
>
> **Applies To:** Unit testing standard output logs and error streams.
>
> **Why:** Using generic mocks to replace `sys.stderr` creates brittle tests
> with broader side effects. The standard library provides dedicated tools
> strictly designed for capturing stream text safely. Failing to adhere to this
> typically results in **Non-Idiomatic Tooling / Brittle Mocks**.

**Trap 1: Using `mock.patch` to manually inject a `StringIO` object over
`sys.stderr`.**

**Don't:**

```python
with mock.patch("sys.stderr", new=io.StringIO()) as mock_stderr:
    run_command()
```

**Do:**

```python
f = io.StringIO()
with contextlib.redirect_stderr(f):
    run_command()
```

--------------------------------------------------------------------------------

#### T5-14: Context Manager Nesting Consolidation

> **Rule:** Consolidate contiguous mock or context manager deployments into
> single-line definitions to minimize indentation footprints.
>
> **What:** Contiguous, deeply nested context managers (`with` blocks) should be
> consolidated into a single `with` statement to reduce horizontal indentation
> and structural complexity.
>
> **Applies To:** Complex test fixtures or code paths requiring multiple
> synchronized states or file handles.
>
> **Why:** Individual context managers per line resulted in excessive code
> indentation (pyramid of doom), harming readability and consuming unnecessary
> screen space. Failing to adhere to this typically results in **Excessive
> Indentation / Pyramid of Doom**.

**Trap 1: Adding a new level of indentation for every context manager invoked.**

**Don't:**

```python
with mock.patch("sys.stderr") as mock_stderr:
    with mock.patch("socket.socket") as ms:
        run_test()
```

**Do:**

```python
with mock.patch("sys.stderr") as mock_stderr, mock.patch("socket.socket") as ms:
    run_test()
```

--------------------------------------------------------------------------------

#### T5-15: Anti-Change Detector Tests

> **Rule:** Avoid exact full-string assertions when evaluating formatted logs or
> stringified error conditions to prevent brittle side-effect maintenance.
>
> **What:** When verifying error logging or outputs, tests must assert on
> flexible core substrings rather than exact line matches, and exceptions
> configured as mock side effects should use class types rather than
> instantiated string objects.
>
> **Applies To:** Unit testing string outputs, logs, and simulated mock
> failures.
>
> **Why:** Tests acting as 'change detectors' failed unnecessarily when minor
> formatting, capitalization, or prefix strings (e.g., 'WARNING' vs 'warning')
> were updated in the underlying code, despite the core logic remaining
> functional. Failing to adhere to this typically results in **Brittle Tests /
> Extraneous Boilerplate**.

**Trap 1: Asserting exact equality of string outputs including standardized
prefixes.**

**Don't:**

```python
self.assertEqual(stderr.getvalue(), "repo: warning: git trace2 logging failed: Mock error")
```

**Do:**

```python
self.assertIn("git trace2 logging failed", stderr.getvalue())
```

**Trap 2: Instantiating an exception with a dummy string for a simple
side-effect mock.**

**Don't:**

```python
mock_socket.connect.side_effect = OSError("Mock error")
```

**Do:**

```python
mock.patch("socket.socket", side_effect=OSError)
```

**Exceptions:** Tests explicitly verifying exact formatting serialization (e.g.,
JSON schema adherence).

--------------------------------------------------------------------------------

#### T5-16: Infrastructure Prebuilts via vpython

> **Rule:** Must execute continuous integration environments using `vpython`
> wrappers instead of relying on legacy source-compiling orchestration
> frameworks like `pyenv`.
>
> **What:** Leverage `vpython` for multi-version Python testing rather than
> `tox` combined with `pyenv` to utilize prebuilt binaries and minimize
> environment setup overhead.
>
> **Applies To:** Hermetic testing setups, CI pipelines, and multi-version
> coverage scripts.
>
> **Why:** Using `pyenv` and `tox` forced CI and local test runs to download and
> compile Python versions from source on the fly, adding minutes of overhead to
> every test run. Shifting to `vpython` leveraged prebuilt infrastructure
> runtimes. Failing to adhere to this typically results in **Slow CI Builds**.

**Trap 1: Relying on tools that dynamically build Python from source to test
across multiple versions.**

**Don't:**

*   Using `tox.ini` with `pyenv` to orchestrate matrix testing across Python
    versions, incurring source-compilation penalties.

**Do:**

*   Invoking tests via `vpython`, which provisions hermetic virtual environments
    rapidly using precompiled infrastructure binaries.

--------------------------------------------------------------------------------

#### T5-17: Modernized Filesystem Paths via Pathlib

> **Rule:** Always employ `pathlib` objects for mock file I/O operations rather
> than manual string handling and context managers.
>
> **What:** Test case file system operations should use the modern `pathlib`
> library rather than legacy `os.path` and manual file handles.
>
> **Applies To:** Unit tests and file system operations across the codebase.
>
> **Why:** Legacy tests relied heavily on `os.path.join` and `with open(...)`
> which led to verbose, repetitive boilerplate when constructing mock repository
> states. Failing to adhere to this typically results in **Verbose Boilerplate /
> Maintainability Overhead**.

**Trap 1: Using `os.path.join` and `with open(..., 'w')` for basic text file
creation in tests.**

**Don't:**

```python
# BAD: Verbose manual file writing
root_m = os.path.join(self.manifest_dir, "root.xml")
with open(root_m, "w") as fp:
    fp.write("<manifest>...")
```

**Do:**

```python
# GOOD: Pathlib usage for concise writes
root_m = self.manifest_dir / "root.xml"
root_m.write_text("<manifest>...")
```

--------------------------------------------------------------------------------

#### T5-18: Standardized Module-Level Mock Imports

> **Rule:** Import external test dependencies and internal domain targets as
> complete module spaces rather than cherry-picking precise classes.
>
> **What:** Test files must import `mock` as a module (`from unittest import
> mock`) and internal targets as a module (`from subcmds import wipe`), rather
> than importing specific classes directly.
>
> **Applies To:** All unit tests.
>
> **Why:** Direct class imports caused namespace pollution and deviated from the
> Google Python Style Guide, making it harder to track the origin of
> dependencies. Failing to adhere to this typically results in **Style Guide
> Violation / Namespace Pollution**.

**Trap 1: Importing specific classes or exceptions directly from test targets or
standard libraries.**

**Don't:**

```python
from unittest.mock import MagicMock
from subcmds.wipe import Wipe, WipeError

mock_obj = MagicMock()
```

**Do:**

```python
from unittest import mock
from subcmds import wipe

mock_obj = mock.MagicMock()
```

--------------------------------------------------------------------------------

#### T5-19: Pytest Adoption for New Test Modules

> **Rule:** Must restrict the creation of new `unittest.TestCase` files strictly
> unless explicitly bypassing native pytest infrastructure constraints.
>
> **What:** New test modules must be written using the `pytest` framework rather
> than the legacy `unittest` structure.
>
> **Applies To:** All newly added test files.
>
> **Why:** The project was modernizing its testing infrastructure, aiming to
> eliminate `unittest` boilerplate and leverage native `pytest` fixtures for
> global state management. Failing to adhere to this typically results in
> **Technical Debt / Legacy Test Framework Propagation**.

**Trap 1: Creating subclasses of `unittest.TestCase` and using
`self.assertEqual`.**

**Don't:**

```python
class WipeUnitTest(unittest.TestCase):
    def test_wipe(self):
        self.assertTrue(os.path.exists(path))
```

**Do:**

```python
def test_wipe(tmp_path):
    assert os.path.exists(path)
```

**Exceptions:** Unless a compelling reason exists requiring native `unittest`
mechanics.

--------------------------------------------------------------------------------

#### T5-20: High-Fidelity Test Targets over Permissive Mocks

> **Rule:** Avoid stubbing robust architectural models like `Project` or
> `Manifest` via permissive `MagicMock` allocations; instantiate genuine domain
> classes instead.
>
> **What:** Tests should instantiate and utilize real domain objects (e.g., the
> `Project` class) rather than relying heavily on generic `MagicMock` instances,
> to ensure test fidelity.
>
> **Applies To:** Unit testing, particularly for core models like `Project` or
> `Manifest`.
>
> **Why:** Overuse of `MagicMock` led to tests passing despite broken
> implementations because the mocks lacked side-effects and realistic attribute
> validation. Failing to adhere to this typically results in **False Positive
> Test Results**.

**Trap 1: Using `MagicMock` to bypass instantiating core models.**

**Don't:**

```python
# BAD: Mocks won't fail if the API changes
proj = mock.MagicMock()
proj.name = "test"
proj.DeleteWorktree.side_effect = lambda: True
```

**Do:**

```python
# GOOD: Using actual domain objects for accurate side-effects
proj = Project(manifest=mock_manifest, name="test", ...)
```

**Exceptions:** External network calls or complex, deeply decoupled subsystems
where instantiating the real object is prohibitively difficult.

--------------------------------------------------------------------------------

#### T5-21: Session-Scoped Hermetic Git Identity Injection

> **Rule:** Must inject pseudo Git commit identities as session-scoped
> environment variables rather than manually rewriting local Git configurations
> per test.
>
> **What:** Automated test suites must globally stub Git's author and committer
> identities using session-scoped environment variables to ensure execution in
> clean or unconfigured environments.
>
> **Applies To:** Pytest configuration (`tests/conftest.py`) and all tests
> executing raw Git subprocess commands.
>
> **Why:** Tests interacting with local Git repositories crashed with
> `GitCommandError` on CI runners or clean developer machines lacking a global
> `user.name` and `user.email`. Patching this locally in tests via `git config`
> calls introduced I/O overhead and redundant code. Failing to adhere to this
> typically results in **GitCommandError / Test Flakiness**.

**Trap 1: Executing `git config` inside individual test setup blocks to fake a
user identity.**

**Don't:**

```python
def test_commit(self):
    subprocess.run(["git", "config", "user.name", "Foo Bar"])
    subprocess.run(["git", "config", "user.email", "foo@bar.com"])
    # Run test logic
```

**Do:**

```python
@pytest.fixture(autouse=True, scope="session")
def setup_user_identity(monkeysession):
    """Set env variables for author and committer name and email."""
    monkeysession.setenv("GIT_AUTHOR_NAME", "Foo Bar")
    monkeysession.setenv("GIT_COMMITTER_NAME", "Foo Bar")
    monkeysession.setenv("GIT_AUTHOR_EMAIL", "foo@bar.baz")
    monkeysession.setenv("GIT_COMMITTER_EMAIL", "foo@bar.baz")
```

--------------------------------------------------------------------------------

#### T5-22: Automated Lifecycle Management for Test Filesystem Artifacts

> **Rule:** Must utilize automated `TemporaryDirectory` constructs integrated
> securely into test teardown sequences instead of performing unmanaged manual
> disk sweeps.
>
> **What:** Test fixtures must use state-managed temporary directory constructs
> (e.g., `tempfile.TemporaryDirectory`) whose lifecycle is explicitly bound to
> standard unit test teardown phases, avoiding manual unmanaged path allocation
> and raw removal.
>
> **Applies To:** All test suites performing filesystem mock operations or Git
> repository initialization (`tests/test_subcmds_forall.py`).
>
> **Why:** Tests were manually allocating paths via `tempfile.mkdtemp` and
> issuing raw `shutil.rmtree` calls. This pattern proved fragile, resulting in
> leaked directories across runs or skipped cleanup phases if a test failed
> early. Failing to adhere to this typically results in **Orphaned Artifacts /
> Resource Leaks**.

**Trap 1: Spawning detached temporary directories and manually maintaining
cleanup blocks.**

**Don't:**

```python
def setUp(self):
    self.tempdir = tempfile.mkdtemp()

def tearDown(self):
    shutil.rmtree(self.tempdir, ignore_errors=True)
```

**Do:**

```python
def setUp(self):
    self.tempdirobj = tempfile.TemporaryDirectory(prefix="forall_tests")
    self.tempdir = self.tempdirobj.name

def tearDown(self):
    self.tempdirobj.cleanup()
```

--------------------------------------------------------------------------------

#### T5-23: Idiomatic String Evaluation in Mocked Test Streams

> **Rule:** Avoid manually slicing and measuring length properties for string
> evaluations; consistently evaluate standard streams using built-in truthiness
> routines.
>
> **What:** Evaluating outputs from captured stdout or stderr in tests must
> utilize Pythonic abstractions like `splitlines()` and implicit truthiness
> evaluation, rather than raw newline splitting and explicit length checks.
>
> **Applies To:** Hermetic Test suites executing mock command line calls and
> inspecting `sys.stdout`.
>
> **Why:** Legacy test code relied on manual string manipulation like
> `split("\n")` and boolean evaluations like `len(line) > 0`. This approach was
> unidiomatic, fragile against cross-platform line endings, and bloated test
> suite verbosity. Failing to adhere to this typically results in **Fragile
> Tests / Unidiomatic Logic**.

**Trap 1: Iterating over raw string splits and manually validating line length
to count valid output strings.**

**Don't:**

```python
line_count = 0
for line in mock_stdout.getvalue().split("\n"):
    if len(line) > 0:
        line_count += 1
```

**Do:**

```python
line_count = sum(1 if x else 0 for x in mock_stdout.getvalue().splitlines())
```

--------------------------------------------------------------------------------

#### T5-24: Hermetic Isolation of Git Configuration Directories in Tests

> **Rule:** Always isolate Git initialization by injecting temporary dummy
> directories via environment overrides (`HOME` / `USERPROFILE`) to restrict
> test interference.
>
> **What:** Tests utilizing local git operations must hermetically isolate
> environment variables like `HOME` and `USERPROFILE` to prevent developers'
> global configurations from leaking into test executions.
>
> **Applies To:** Global test initialization routines (`conftest.py`, Pytest
> fixtures, class-level test setup).
>
> **Why:** Historically, if a developer's global `.gitconfig` required GPG
> signing (`commit.gpgsign=true`), a git subprocess spawned during test setup
> would unexpectedly open an interactive prompt (e.g., vim) to solicit a signing
> key, causing the test suite to deadlock permanently. Failing to adhere to this
> typically results in **Test Deadlock / State Bleed**.

**Trap 1: Relying on default system paths for the home directory during test
execution.**

**Don't:**

```python
# BAD: Allows test subprocesses to read ~/.gitconfig
subprocess.run(['git', 'tag', '--annotate'])
```

**Do:**

```python
# GOOD: Override environment variables to an isolated temp directory
@pytest.fixture(autouse=True, scope="session")
def alt_home(tmp_path_factory, monkeysession):
    var = "USERPROFILE" if platform_utils.isWindows() else "HOME"
    monkeysession.setenv(var, str(tmp_path_factory.mktemp("home")))
```

**Exceptions:** Tests that explicitly exist to validate the parsing logic of a
user's real, existing `.gitconfig` (which is highly discouraged).

--------------------------------------------------------------------------------

#### T5-25: Scope Hierarchy Enforcement in Pytest Fixtures

> **Rule:** Never propagate lower-scoped test fixtures (e.g., function-scoped
> states) into global session-scoped initialization procedures.
>
> **What:** A session-scoped Pytest fixture cannot depend on lower-scoped
> fixtures (such as a function-scoped `tmp_path`). To create temporary paths at
> the session level, `tmp_path_factory.mktemp` must be utilized.
>
> **Applies To:** Pytest fixture definitions, specifically within `conftest.py`.
>
> **Why:** A session-scoped setup mechanism attempted to use the function-scoped
> `tmp_path` fixture. This caused pytest initialization failures. Furthermore,
> reusing function-scoped directories for session-level state caused unintended
> disk thrashing as the directory was continually wiped at the teardown of every
> function. Failing to adhere to this typically results in **Scope Mismatch /
> State Masking**.

**Trap 1: Injecting `tmp_path` into a fixture decorated with
`scope="session"`.**

**Don't:**

```python
# BAD: Session fixture depending on function fixture
@pytest.fixture(scope="session")
def session_tmp_homedir(tmp_path):
    return tmp_path
```

**Do:**

```python
# GOOD: Using the factory to generate a session-level path
@pytest.fixture(scope="session")
def session_tmp_homedir(tmp_path_factory):
    return tmp_path_factory.mktemp("home")
```

--------------------------------------------------------------------------------

#### T5-26: Strict Python Version Compatibility for Third-Party Plugins

> **Rule:** Must strictly align test dependency injection configurations against
> the underlying project's absolute minimum supported Python versions.
>
> **What:** Test tooling dependencies must strictly align with the project's
> minimum supported Python version. External plugin implementation logic should
> be inlined with proper attribution if the plugin requires a newer Python
> version than the project supports.
>
> **Applies To:** Dependency management (`tox.ini`), `conftest.py`, and CI
> environments.
>
> **Why:** A developer introduced a new Pytest plugin to manage isolated home
> directories. However, the plugin required Python 3.8+, while the project
> maintained compatibility down to Python 3.6+. This mismatch caused post-submit
> CI pipeline checks to crash upon test environment installation. Failing to
> adhere to this typically results in **CI Installation Failure**.

**Trap 1: Adding modern third-party test dependencies to legacy-supported
projects without validating the minimum required Python constraints.**

**Don't:**

```ini
# BAD: tox.ini adds dependency unsupported by CI target
deps =
    pytest
    pytest-home >= 0.4
```

**Do:**

```python
# GOOD: Inline the logic and remove the external dependency
# adapted from pytest-home 0.5.1
@pytest.fixture(autouse=True, scope="session")
def session_tmp_homedir(tmp_path_factory, monkeysession):
    # implementation logic here
```

**Exceptions:** When the project's minimum supported Python version is
officially bumped to match the plugin's requirement.

--------------------------------------------------------------------------------

#### T5-27: Hermetic Isolation of Terminal UI Color Configurations

> **Rule:** Must aggressively lock default terminal coloring states when
> generating UI tests to isolate regressions from variable environment
> pipelines.
>
> **What:** Unit tests that assert on UI or logging text containing ANSI color
> codes must explicitly force the coloring state to prevent ambient git
> configurations or CI terminal limitations from altering test outcomes.
>
> **Applies To:** Unit tests interacting with the `color` or `repo_logging`
> modules.
>
> **Why:** Tests validating color outputs failed non-deterministically based on
> the ambient environment (e.g., CI runners lacking a TTY, or developers having
> `color.ui=false` in their global `.gitconfig`). Failing to adhere to this
> typically results in **Flaky Tests / Non-Deterministic Failures**.

**Trap 1: Relying on the default state of the `Coloring` class without forcing
it during setup, implicitly depending on environmental variables.**

**Don't:**

```python
def setUp(self):
    config_fixture = fixture("test.gitconfig")
    self.config = git_config.GitConfig(config_fixture)
    self.color = color.Coloring(self.config, "status")
```

**Do:**

```python
def setUp(self):
    config_fixture = fixture("test.gitconfig")
    self.config = git_config.GitConfig(config_fixture)
    color.SetDefaultColoring("always")
    self.color = color.Coloring(self.config, "status")
```

--------------------------------------------------------------------------------

#### T5-28: Abstract Intent Documentation in Unit Tests

> **Rule:** Never embed exact literal assertions or explicit structural values
> directly inside unit test docstring commentary.
>
> **What:** Test docstrings should describe the behavioral intent or structural
> coverage of the test rather than hardcoding the exact assertion values or
> low-level implementation details.
>
> **Applies To:** Python `unittest` module docstrings.
>
> **Why:** Docstrings that hardcoded exact ANSI escape sequences or config
> values became stale and misleading whenever the underlying mappings or
> formatting codes were updated. Failing to adhere to this typically results in
> **Documentation Rot / Maintenance Overhead**.

**Trap 1: Documenting exact data values being asserted directly in the test
docstring.**

**Don't:**

```python
def test_Color_Parse_first_parameter_none(self):
    """fg is black(30), bg is red(31+10=41), attr is ul(4)"""
    val = self.color._parse(None, 'black', 'red', 'ul')
    self.assertEqual('\x1b[4;30;41m', val)
```

**Do:**

```python
def test_Color_Parse_first_parameter_none(self):
    """check fg & bg & attr"""
    val = self.color._parse(None, "black", "red", "ul")
    self.assertEqual("\x1b[4;30;41m", val)
```

--------------------------------------------------------------------------------

### Cross-Domain Dependencies

*   **Upstream:** T2 | Filesystem Atomicity & Worktree Layout - *Managing safe
    creation and atomic removal of temporary worktrees and `.git` directories
    supports reliable test state fixtures.*
*   **Downstream:** T3 | Subprocess Git Integration & Error Translation -
    *Hermetic test constraints directly dictate how standard git streams,
    configuration injections, and subprocess executions are mocked or
    intercepted.*
*   **Downstream:** T6 | CLI Argument Parsing & UX Consistency - *Strict
    terminal environment control in testing enforces deterministic verification
    of CLI autocorrect flows and standardized UI colorizations.*

## Chapter: CLI Argument Parsing & UX Consistency

**Context:** This chapter governs the lifecycle, validation, and execution of
command-line arguments, enforcing strict standardization for machine-readable
serialization, unified logging, and deterministic, thread-safe terminal
interactions.

### Summary

| Rule ID   | Principle /      | Priority | Primary Symptom /     |
:           : Constraint       :          : Trap                  :
| :-------- | :--------------- | :------- | :-------------------- |
| **T6-01** | Deterministic    | High     | Providing only        |
:           : Machine-Readable :          : aesthetically         :
:           : Output Formats   :          : formatted terminal    :
:           :                  :          : text for diagnostic   :
:           :                  :          : commands.             :
| **T6-02** | Elimination of   | Medium   | Assigning a short     |
:           : Niche Short      :          : option to a feature   :
:           : Options          :          : that isn't commonly   :
:           :                  :          : used by developers.   :
| **T6-03** | Extensible       | Medium   | Creating rigid,       |
:           : Boolean Toggle   :          : single-purpose        :
:           : Flags            :          : boolean switches for  :
:           :                  :          : granular output       :
:           :                  :          : components.           :
| **T6-04** | Context-Aware    | Medium   | Hardcoding visual     |
:           : CLI Output       :          : formatting elements   :
:           : Separators       :          : directly after a      :
:           :                  :          : primary block instead :
:           :                  :          : of conditionally      :
:           :                  :          : checking the next     :
:           :                  :          : block.                :
| **T6-05** | Output Format    | Medium   | Handling output       |
:           : Standardization  :          : formatting via raw    :
:           : via Enums        :          : string matching and   :
:           :                  :          : `print()` statements  :
:           :                  :          : without suppressing   :
:           :                  :          : the interactive       :
:           :                  :          : pager.                :
| **T6-06** | Symmetric        | Medium   | Mixing one output     |
:           : Execution        :          : format's dispatch     :
:           : Dispatching      :          : call with the inline  :
:           :                  :          : procedural logic of   :
:           :                  :          : the fallback format.  :
| **T6-07** | CLI Argument     | Medium   | Overriding a          |
:           : Simulation over  :          : configuration         :
:           : Internal State   :          : parameter directly on :
:           : Mutation         :          : the parsed namespace  :
:           :                  :          : object.               :
| **T6-08** | Deterministic    | Medium   | Iterating over a list |
:           : Sorting of       :          : of accumulated        :
:           : Parallel         :          : multi-process results :
:           : Execution        :          : without sorting.      :
:           : Results          :          :                       :
| **T6-09** | Strict Adherence | Medium   | Adding a              |
:           : to Feature       :          : `--force-jobs` CLI    :
:           : Requests         :          : bypass flag           :
:           :                  :          : simultaneously        :
:           :                  :          : alongside the new     :
:           :                  :          : `sync-j-max` manifest :
:           :                  :          : attribute.            :
| **T6-10** | Minimal Logic in | High     | Placing the entire    |
:           : Exception        :          : typo-correction       :
:           : Handlers         :          : logic, user prompts,  :
:           :                  :          : and command reloading :
:           :                  :          : inside `except        :
:           :                  :          : KeyError\:`.          :
| **T6-11** | Unified Logging  | Medium   | Outputting warnings   |
:           : Protocol via     :          : directly to the       :
:           : Standard Logger  :          : `sys.stderr` stream   :
:           :                  :          : using the built-in    :
:           :                  :          : `print` function.     :
| **T6-12** | Strict           | High     | Wrapping string-typed |
:           : Translation of   :          : configuration         :
:           : Configuration    :          : variables inside      :
:           : Booleans         :          : `int()` and catching  :
:           :                  :          : value exceptions to   :
:           :                  :          : deduce defaults.      :
| **T6-13** | Interruptibility | Critical | Placing raw time      |
:           : of Interactive   :          : suspension code       :
:           : Runtime Delays   :          : before a return       :
:           :                  :          : statement without     :
:           :                  :          : wrapping it in a trap :
:           :                  :          : for cancellation      :
:           :                  :          : overrides.            :
| **T6-14** | Strict           | Critical | Consuming CLI option  |
:           : Pre-Access       :          : flags before the      :
:           : Initialization   :          : shared initialization :
:           : of CLI Options   :          : pipeline populates    :
:           :                  :          : default properties.   :
| **T6-15** | Omission of      | Medium   | Redundantly           |
:           : Redundant        :          : configuring           :
:           : Optparse         :          : destination variables :
:           : Destinations     :          : in CLI arguments.     :
| **T6-16** | Subcommand       | Medium   | Writing               |
:           : Scoping in       :          : global-sounding       :
:           : Commit Messages  :          : commit messages for   :
:           :                  :          : isolated subcommand   :
:           :                  :          : patches.              :
| **T6-17** | Module-Scoped    | Medium   | Redundantly prefixing |
:           : Exception Naming :          : the exception name    :
:           :                  :          : with the module name  :
:           :                  :          : inside the module     :
:           :                  :          : definition.           :
| **T6-18** | Explicit         | High     | Using terms like      |
:           : Terminology in   :          : 'worktree' in help    :
:           : Destructive CLI  :          : text without explicit :
:           : Commands         :          : definition or         :
:           :                  :          : examples.             :
| **T6-19** | Fail-Fast        | Medium   | Checking for missing  |
:           : Argument         :          : positional arguments  :
:           : Validation in    :          : directly inside       :
:           : Subcommands      :          : `Execute()`.          :
| **T6-20** | Respect Global   | Medium   | Unconditionally       |
:           : Verbosity Flags  :          : printing progress     :
:           :                  :          : messages to stderr or :
:           :                  :          : stdout.               :
| **T6-21** | Thread-Safe      | Critical | Directly querying     |
:           : Terminal         :          : `sys.stderr.fileno()` :
:           : Querying during  :          : inside long-running   :
:           : IO Capture       :          : concurrent loops.     :
| **T6-22** | Global State via | Medium   | Adding environment    |
:           : Persistent       :          : variable mappings     :
:           : Configuration    :          : into command-line     :
:           : over Environment :          : parsers to support    :
:           : Variables        :          : 'headless'            :
:           :                  :          : configurations.       :
| **T6-23** | CLI Command      | Medium   | Adding project-wide   |
:           : Parity with Git  :          : or environmental      :
:           : Semantics        :          : metadata queries to   :
:           :                  :          : commands designed for :
:           :                  :          : local working-tree    :
:           :                  :          : analysis.             :
| **T6-24** | Context-Aware    | Medium   | Triggering an         |
:           : Sync Operation   :          : immediate system exit :
:           : Termination      :          : on an update failure. :
| **T6-25** | Explicit Exit    | High     | Using an empty        |
:           : Codes on CLI     :          : `return` to back out  :
:           : Cancellation     :          : of a declined CLI     :
:           :                  :          : confirmation prompt.  :
| **T6-26** | Non-Interactive  | Medium   | Hardcoding            |
:           : Safeties for     :          : interactive prompts   :
:           : Destructive      :          : without checking      :
:           : Commands         :          : configuration flags   :
:           :                  :          : for automation modes. :
| **T6-27** | Strict           | Medium   | Accepting dependent   |
:           : Interdependent   :          : modifier options      :
:           : Argument         :          : unconditionally       :
:           : Validation       :          : without checking      :
:           :                  :          : prerequisites.        :
| **T6-28** | Actionable CLI   | Medium   | Failing a sync        |
:           : Error Messages   :          : operation with a      :
:           : for              :          : descriptive but       :
:           : Synchronization  :          : non-actionable error  :
:           : Failures         :          : message.              :
| **T6-29** | Launcher Version | High     | Modifying the         |
:           : Bumping for      :          : standalone launcher   :
:           : Important        :          : script with important :
:           : Changes          :          : changes without       :
:           :                  :          : incrementing its      :
:           :                  :          : VERSION tuple.        :

--------------------------------------------------------------------------------

### Rules

#### T6-01: Deterministic Machine-Readable Output Formats

> **Rule:** Always expose strict, structured serialization options (e.g., JSON)
> for CLI tools used in automated pipelines to prevent reliance on brittle text
> parsing.
>
> **What:** CLI tools leveraged for inspection must expose strict, structured
> serialization (e.g., JSON) to negate reliance on unstable text parsing in
> CI/CD environments.
>
> **Applies To:** Command-line interface design, specifically subcommands
> utilized by build pipelines or external orchestrators.
>
> **Why:** Downstream automated pipelines were forced to retrieve configuration
> data by executing tools like `repo info` and using string matching (`grep`)
> against human-readable formatting, creating a brittle dependency susceptible
> to UI modifications. Failing to adhere to this typically results in **Pipeline
> Parsing Failure**.

**Trap 1: Providing only aesthetically formatted terminal text for diagnostic
commands.**

**Don't:**

*   Command executes and prints human-readable strings. Consumers must run `repo
    info | grep "Manifest revision"` to extract variables.

**Do:**

*   Integrate a `--format=json` command argument that bypasses human-readable
    display logic and cleanly serializes underlying data models directly to
    standard output.

**Exceptions:** Interactive-only terminal prompts that are heavily stateful and
fundamentally incompatible with automation.

--------------------------------------------------------------------------------

#### T6-02: Elimination of Niche Short Options

> **Rule:** Never assign single-character short options for niche or rarely used
> flags to preserve namespace availability.
>
> **What:** Avoid assigning single-character short options for niche or rarely
> used command-line flags to prevent namespace bloat.
>
> **Applies To:** CLI argument parsing (e.g., `optparse` or `argparse`
> definitions).
>
> **Why:** Short options were being added arbitrarily for specific data
> summaries, leading to a cluttered short-option namespace and hindering future
> expansion. Failing to adhere to this typically results in **Cluttered CLI
> UX**.

**Trap 1: Assigning a short option to a feature that isn't commonly used by
developers.**

**Don't:**

```python
p.add_option("-s", "--summary", action="store_true")
```

**Do:**

```python
p.add_option("--include-summary", action="store_true")
```

--------------------------------------------------------------------------------

#### T6-03: Extensible Boolean Toggle Flags

> **Rule:** Always implement paired positive/negative toggle flags for granular
> outputs rather than relying on rigid, single-purpose boolean switches.
>
> **What:** Conditional output sections must be controlled by paired
> positive/negative toggle flags (e.g., `--include-x` and `--no-include-x`)
> rather than single-purpose boolean flags.
>
> **Applies To:** CLI design and option definitions for output manipulation.
>
> **Why:** Rigid, single-purpose flags for rendering specific summaries limited
> extensibility and prevented developers from precisely tailoring outputs for
> scripts or automation. Failing to adhere to this typically results in **Rigid
> Output Rendering**.

**Trap 1: Creating rigid, single-purpose boolean switches for granular output
components.**

**Don't:**

```python
p.add_option("--summary", action="store_true", help="show only manifest summary")
```

**Do:**

```python
p.add_option("--include-summary", action="store_true", default=True)
p.add_option("--no-include-summary", dest="include_summary", action="store_false")
```

--------------------------------------------------------------------------------

#### T6-04: Context-Aware CLI Output Separators

> **Rule:** Must conditionally verify that succeeding content blocks will render
> before printing visual formatting elements like horizontal separators.
>
> **What:** Structural visual elements, such as horizontal separators or
> newlines, must only be printed if the succeeding content block is actually
> verified to render.
>
> **Applies To:** CLI output rendering logic.
>
> **Why:** Output formatting logic printed hardcoded line separators after
> summaries, resulting in dangling visual artifacts when subsequent project
> details were dynamically excluded by user flags. Failing to adhere to this
> typically results in **Redundant Output Noise**.

**Trap 1: Hardcoding visual formatting elements directly after a primary block
instead of conditionally checking the next block.**

**Don't:**

```python
print_summary()
print_separator()
if include_projects:
    print_projects()
```

**Do:**

```python
print_summary()
if not include_projects:
    return
print_separator()
print_projects()
```

--------------------------------------------------------------------------------

#### T6-05: Output Format Standardization via Enums

> **Rule:** Must manage and standardize target output formats using an explicit
> Python `Enum` class rather than brittle string matching.
>
> **What:** Command-line output formats (like TEXT or JSON) must be managed
> using an explicit Python Enum class and standardize formatting behaviors
> (e.g., disabling pagers for JSON, enforcing sort keys).
>
> **Applies To:** CLI data serialization and `OutputFormat` dispatching.
>
> **Why:** Unstandardized JSON serialization methods across subcommands resulted
> in inconsistent output spacing, failure to suppress interactive pagers, and
> brittle string-based format matching. Failing to adhere to this typically
> results in **Broken Machine Automation**.

**Trap 1: Handling output formatting via raw string matching and `print()`
statements without suppressing the interactive pager.**

**Don't:**

```python
if opt.format == "json":
    print(json.dumps(data))
```

**Do:**

```python
class OutputFormat(enum.Enum):
    TEXT = enum.auto()
    JSON = enum.auto()

if output_format == OutputFormat.JSON:
    sys.stdout.write(json.dumps(data, indent=2, sort_keys=True) + "\n")
```

--------------------------------------------------------------------------------

#### T6-06: Symmetric Execution Dispatching

> **Rule:** Must symmetrically separate procedural logic into format-specific
> handlers rather than mixing inline logic with format conditional statements.
>
> **What:** Complex commands handling multiple output formats must keep the main
> execution function clean by symmetrically dispatching logic to format-specific
> handlers (e.g., `_ExecuteText` and `_ExecuteJson`).
>
> **Applies To:** Command entry points (e.g., the `Execute` method in subcommand
> classes).
>
> **Why:** Inline output rendering mixed with conditional format dispatching
> created monolithic execution methods that were difficult to maintain and test.
> Failing to adhere to this typically results in **Spaghetti Logic**.

**Trap 1: Mixing one output format's dispatch call with the inline procedural
logic of the fallback format.**

**Don't:**

```python
def Execute(self, opt, args):
    if opt.format == 'json':
        return self._ExecuteJson(opt, args)
    # 50 lines of inline text rendering logic...
```

**Do:**

```python
def Execute(self, opt, args):
    if opt.format == OutputFormat.JSON:
        self._ExecuteJson(opt, args)
    else:
        self._ExecuteText(opt, args)
```

--------------------------------------------------------------------------------

#### T6-07: CLI Argument Simulation over Internal State Mutation

> **Rule:** Always inject simulated execution parameters into the command-line
> `argv` arguments list rather than manually overwriting parsed attribute states
> during tests.
>
> **What:** When executing a command programmatically within a test, operational
> parameters (e.g., job counts) must be injected into the simulated `argv`
> string list rather than manually mutating the parsed options object.
>
> **Applies To:** Command testing and execution harnesses where parameters alter
> system behavior (e.g., multiprocessing threads).
>
> **Why:** Test cases were bypassing the CLI parser and manually setting
> `opts.jobs = 1` to force single-threaded execution. This prevented the test
> from exercising the command's full option-parsing and validation lifecycle.
> Failing to adhere to this typically results in **Test Invalidation / False
> Positives**.

**Trap 1: Overriding a configuration parameter directly on the parsed namespace
object.**

**Don't:**

```python
opts, args = cmd.OptionParser.parse_args(argv)
cmd.CommonValidateOptions(opts, args)
opts.jobs = 1
cmd.Execute(opts, args)
```

**Do:**

```python
opts, args = cmd.OptionParser.parse_args(argv + ["--jobs=1"])
cmd.CommonValidateOptions(opts, args)
cmd.Execute(opts, args)
```

--------------------------------------------------------------------------------

#### T6-08: Deterministic Sorting of Parallel Execution Results

> **Rule:** Must explicitly sort accumulated payload data from asynchronous
> thread loops before broadcasting standard outputs or logs.
>
> **What:** Elements collected asynchronously from a multiprocessing pool must
> be explicitly sorted before being emitted to standard output or logging
> pipelines.
>
> **Applies To:** Command-line output rendering and any loop iterating over
> aggregated parallel results.
>
> **Why:** Warning messages regarding bloated project directories were printed
> based on the order that asynchronous threads returned their payload, leading
> to flaky UX and non-deterministic command outputs. Failing to adhere to this
> typically results in **Non-Deterministic Console Output**.

**Trap 1: Iterating over a list of accumulated multi-process results without
sorting.**

**Don't:**

```python
for project_name in self._bloated_projects:
    logger.warning(f'warning: Project {project_name} is bloated.')
```

**Do:**

```python
for project_name in sorted(self._bloated_projects):
    logger.warning(f'warning: Project {project_name} is bloated.')
```

--------------------------------------------------------------------------------

#### T6-09: Strict Adherence to Feature Requests

> **Rule:** Never implement speculative bypass flags, preemptive CLI overrides,
> or configurations without a documented and verifiable user request.
>
> **What:** Avoid preemptively implementing fallback features, command-line
> overrides, or configurations without a documented user request.
>
> **Applies To:** CLI argument parsers and manifest parsing engines.
>
> **Why:** Speculative feature additions, like bypass flags for manifest limits,
> caused feature creep and bloated the CLI toolset with unused, undocumented
> edge cases. Failing to adhere to this typically results in **Feature Creep**.

**Trap 1: Adding a `--force-jobs` CLI bypass flag simultaneously alongside the
new `sync-j-max` manifest attribute.**

**Don't:**

*   Implementing an override flag in `main.py` just in case users want to bypass
    the newly added manifest restriction.

**Do:**

*   Deploying the manifest constraint directly without a CLI override, and
    documenting it in `docs/manifest-format.md`. Wait for a bug tracker request
    for an override flag.

--------------------------------------------------------------------------------

#### T6-10: Minimal Logic in Exception Handlers

> **Rule:** Must restrict `try...except` blocks entirely to targeted error
> handling and never bury structural flow control or terminal loops within them.
>
> **What:** Exception handling blocks (`try...except`) must only contain the
> specific error-handling logic and never encapsulate complex business logic,
> terminal loops, or major execution routing.
>
> **Applies To:** Command dispatcher routing and system control flows.
>
> **Why:** Burying significant CLI routing tasks—like spelling suggestions,
> autocorrection countdowns, and subprocess recursion—inside a `KeyError`
> handler obscured program logic and suppressed nested tracebacks. Failing to
> adhere to this typically results in **Opaque Routing State**.

**Trap 1: Placing the entire typo-correction logic, user prompts, and command
reloading inside `except KeyError:`.**

**Don't:**

```python
try:
    cmd = self.commands[name]()
except KeyError:
    # 50 lines of complex autocorrection logic
    return self._RunLong(...)
```

**Do:**

```python
if name not in self.commands:
    name = self._autocorrect_command_name(name)
    if not name:
        return 1
# Execute minimal command logic outside exception
cmd = self.commands[name]()
```

--------------------------------------------------------------------------------

#### T6-11: Unified Logging Protocol via Standard Logger

> **Rule:** Dispatch all console messages using the standard centralized logging
> framework. Never rely on raw `print` statements mapped directly to terminal
> error streams.
>
> **What:** All console outputs must be dispatched via the system's centralized
> `RepoLogger` mechanism, completely replacing raw terminal standard-error
> prints.
>
> **Applies To:** CLI presentation logic and application-wide console
> communications.
>
> **Why:** The use of raw `print(file=sys.stderr)` bypassed the system's unified
> logging configuration, resulting in unformatted outputs and broken terminal
> interactivity. Failing to adhere to this typically results in **Unmanaged
> Output Spillage**.

**Trap 1: Outputting warnings directly to the `sys.stderr` stream using the
built-in `print` function.**

**Don't:**

```python
print(f"WARNING: You called a command named '{name}'", file=sys.stderr)
```

**Do:**

```python
logger.warning("You called a repo command named '%s'", name)
```

**Exceptions:** Prompts that require strict, synchronously unformatted
interaction via `input()`.

--------------------------------------------------------------------------------

#### T6-12: Strict Translation of Configuration Booleans

> **Rule:** Always cast string-based Git configurations to lowercase and map
> them strictly against Git's recognized array of boolean equivalents.
>
> **What:** Parsers querying Git configuration properties must implement strict
> hardcoding to safely capture Git's expansive list of non-standard boolean
> string representations (e.g., 'yes', 'on', 'true', 'off').
>
> **Applies To:** Configuration parsers mapping user `git config` state to
> internal state variables.
>
> **Why:** Using standard integer casts on retrieved git configuration strings
> caused runtime failures when users specified string-based boolean values
> sanctioned by the official Git system. Failing to adhere to this typically
> results in **Configuration Casting Panic**.

**Trap 1: Wrapping string-typed configuration variables inside `int()` and
catching value exceptions to deduce defaults.**

**Don't:**

```python
try:
    autocorrect = int(autocorrect)
except ValueError:
    autocorrect = 0
```

**Do:**

```python
autocorrect = str(autocorrect).lower()
if autocorrect in ("0", "false", "off", "no", "show"):
    autocorrect = 0
elif autocorrect in ("1", "true", "on", "yes", "immediate"):
    autocorrect = -1
```

--------------------------------------------------------------------------------

#### T6-13: Interruptibility of Interactive Runtime Delays

> **Rule:** Must wrap artificially injected execution delays in handlers that
> correctly detect and gracefully back out of operations upon a keyboard
> interrupt signal.
>
> **What:** Any thread-blocking delay generated by the system (e.g.,
> autocorrection warning timers) must actively handle thread interrupt signals
> so users can gracefully cancel impending state mutations.
>
> **Applies To:** Thread blocks, specifically interactive or automated execution
> delays.
>
> **Why:** Forced sequential time sleeps preceding an automated command
> execution trapped users. If a user detected an erroneous correction during the
> sleep interval, initiating a keyboard interrupt would fail to abort execution,
> resulting in destructive command routing. Failing to adhere to this typically
> results in **Irrevocable Execution**.

**Trap 1: Placing raw time suspension code before a return statement without
wrapping it in a trap for cancellation overrides.**

**Don't:**

```python
time.sleep(delay)
return assumed_command
```

**Do:**

```python
try:
    time.sleep(delay)
except KeyboardInterrupt:
    return None
return assumed_command
```

--------------------------------------------------------------------------------

#### T6-14: Strict Pre-Access Initialization of CLI Options

> **Rule:** Never retrieve attributes from a parsed options namespace until the
> shared subcommand option validation layer has fully completed processing.
>
> **What:** Command-line option attributes (e.g., `copts.verbose`) must strictly
> be accessed only after the options object has fully passed through the common
> subcommand validation layer.
>
> **Applies To:** CLI entry points (`main.py`) and option routing blocks.
>
> **Why:** Accessing attributes on the configuration options object prior to
> invoking `CommonValidateOptions` (which populates global defaults) resulted in
> `AttributeError` crashes, completely breaking primary application functions
> like `repo sync`. Failing to adhere to this typically results in
> **AttributeError / Process Crash**.

**Trap 1: Consuming CLI option flags before the shared initialization pipeline
populates default properties.**

**Don't:**

```python
git_trace2_event_log.verbose = copts.verbose
cmd.CommonValidateOptions(copts, cargs)
cmd.ValidateOptions(copts, cargs)
```

**Do:**

```python
cmd.CommonValidateOptions(copts, cargs)
cmd.ValidateOptions(copts, cargs)
git_trace2_event_log.verbose = copts.verbose
```

--------------------------------------------------------------------------------

#### T6-15: Omission of Redundant Optparse Destinations

> **Rule:** Avoid manually injecting `dest=` bindings in argument declarations
> if the implicit destination perfectly mirrors the target variable name.
>
> **What:** Do not explicitly pass `dest=` arguments in CLI option definitions
> if the value identically matches `optparse`'s implicit fallback behavior
> (which strips leading dashes and replaces inner dashes with underscores).
>
> **Applies To:** Command-line argument definitions using the `optparse` library
> within `subcmds/`.
>
> **Why:** Developers repeatedly specified `dest=` overrides that exactly
> mirrored the auto-generated variable name, adding unnecessary boilerplate and
> triggering automated regression test failures. Failing to adhere to this
> typically results in **Code Bloat / Test Failure**.

**Trap 1: Redundantly configuring destination variables in CLI arguments.**

**Don't:**

```python
p.add_option(
    "--no-interleaved",
    dest="no_interleaved",
    action="store_false",
)
```

**Do:**

```python
p.add_option(
    "--no-interleaved",
    action="store_false",
)
```

--------------------------------------------------------------------------------

#### T6-16: Subcommand Scoping in Commit Messages

> **Rule:** Always prefix your commit messages with the explicit CLI subcommand
> or modular subsystem the patch directly targets.
>
> **What:** Git commit message subject lines must explicitly scope changes to
> the CLI subcommand or module they affect (e.g., `sync: ` or `project: `).
>
> **Applies To:** Commit message authoring.
>
> **Why:** Vague commit messages such as 'Default to interleaved mode'
> obfuscated history. Scoping was mandated to ensure maintainers could quickly
> trace changes within the mono-repo. Failing to adhere to this typically
> results in **Unclear Git History**.

**Trap 1: Writing global-sounding commit messages for isolated subcommand
patches.**

**Don't:**

*   Default to interleaved mode

**Do:**

*   sync: Default to interleaved mode

**Exceptions:** Changes that structurally alter the core framework or affect
multiple commands concurrently.

--------------------------------------------------------------------------------

#### T6-17: Module-Scoped Exception Naming

> **Rule:** Declare isolated module exceptions natively as `Error` instead of
> prefixing them with the resident module's name.
>
> **What:** Custom exceptions specific to a module (especially subcommands)
> should be named `Error` rather than prefixing them with the module name.
>
> **Applies To:** Module-level exception definitions, specifically within
> subcommand implementations.
>
> **Why:** Developers inconsistently named module exceptions (e.g., `WipeError`
> in `wipe.py`), violating the style guide and polluting the namespace upon
> import. Failing to adhere to this typically results in **Style Guide Violation
> / API Inconsistency**.

**Trap 1: Redundantly prefixing the exception name with the module name inside
the module definition.**

**Don't:**

```python
# inside wipe.py
class WipeError(RepoExitError):
    pass
```

**Do:**

```python
# inside wipe.py
class Error(RepoExitError):
    pass
```

--------------------------------------------------------------------------------

#### T6-18: Explicit Terminology in Destructive CLI Commands

> **Rule:** Must rigorously define nuanced Git terminology natively within the
> terminal help output if a command has destructive capabilities.
>
> **What:** Destructive commands must clearly define ambiguous terms (like
> 'worktree') in their help documentation and provide concrete usage examples.
>
> **Applies To:** CLI help text, specifically `helpDescription` properties in
> `Command` subclasses executing file deletion.
>
> **Why:** Users misunderstood destructive operations because terminology
> overlapped with internal Git jargon, increasing the risk of accidental
> repository deletions. Failing to adhere to this typically results in
> **Accidental Data Loss**.

**Trap 1: Using terms like 'worktree' in help text without explicit definition
or examples.**

**Don't:**

*   helpDescription = "The repo wipe command removes the specified projects from
    the worktree."

**Do:**

*   helpDescription = "The repo wipe command removes the specified projects from
    the worktree (the checked out source code)... \n\nExamples:\n %prog
    <project>..."

--------------------------------------------------------------------------------

#### T6-19: Fail-Fast Argument Validation in Subcommands

> **Rule:** Must perform strict threshold checks for required argument counts at
> the validation layer before the command is permitted to execute.
>
> **What:** Validation checks for mandatory command-line arguments must occur in
> the `ValidateOptions` hook rather than within the core `Execute` block.
>
> **Applies To:** All `Command` subclasses.
>
> **Why:** Performing validation in the execution body delayed error feedback,
> triggering unnecessary setup logic and violating the command lifecycle
> architecture. Failing to adhere to this typically results in **Delayed
> Execution Errors / Architectural Inconsistency**.

**Trap 1: Checking for missing positional arguments directly inside
`Execute()`.**

**Don't:**

```python
def Execute(self, opt, args):
    if not args:
        raise UsageError("no projects specified")
    # ... execution logic
```

**Do:**

```python
def ValidateOptions(self, opt, args):
    if not args:
        self.OptionParser.error("no projects specified")

def Execute(self, opt, args):
    # ... execution logic safely assumes valid args
```

--------------------------------------------------------------------------------

#### T6-20: Respect Global Verbosity Flags

> **Rule:** Always wrap non-critical progress prints or logging updates behind
> global verbosity checks.
>
> **What:** Commands must remain silent by default. Output must be guarded by
> checking the global `opt.verbose` flag, preventing log noise during standard
> execution.
>
> **Applies To:** All `Command` subclasses executing file operations or progress
> updates.
>
> **Why:** Commands were unconditionally printing internal states (e.g.,
> directory deletions), cluttering terminal output for users expecting standard
> silent behavior. Failing to adhere to this typically results in **Terminal
> Spam / UX Degradation**.

**Trap 1: Unconditionally printing progress messages to stderr or stdout.**

**Don't:**

```python
print(f"Deleting objects directory: {objdir}", file=sys.stderr)
```

**Do:**

```python
if opt.verbose:
    print(f"Deleting objects directory: {objdir}", file=sys.stderr)
```

--------------------------------------------------------------------------------

#### T6-21: Thread-Safe Terminal Querying during IO Capture

> **Rule:** Must query terminal geometry using a safely cached baseline file
> descriptor to prevent crash failures when the standard error stream is
> redirected to memory buffers.
>
> **What:** Background threads that query terminal properties (like width) must
> reference a persistently cached file descriptor of the original `sys.stderr`,
> as the global stream can be temporarily redirected to in-memory objects
> lacking file descriptors.
>
> **Applies To:** progress.py, UI monitoring loops, and subprocesses executed
> during `stderr`/`stdout` redirection.
>
> **Why:** When running parallel processes that captured output into an
> `io.StringIO()` buffer, a background progress thread attempting to dynamically
> measure the terminal width via `sys.stderr.fileno()` triggered an
> `io.UnsupportedOperation: fileno` exception, crashing the entire UI loop.
> Failing to adhere to this typically results in **Thread Crash /
> io.UnsupportedOperation**.

**Trap 1: Directly querying `sys.stderr.fileno()` inside long-running concurrent
loops.**

**Don't:**

```python
# BAD: Fails if stderr is mocked to memory
col = os.get_terminal_size(sys.stderr.fileno()).columns
```

**Do:**

```python
# GOOD: Querying a module-level cached reference mapped at boot
col = os.get_terminal_size(_STDERR.fileno()).columns
```

--------------------------------------------------------------------------------

#### T6-22: Global State via Persistent Configuration over Environment Variables

> **Rule:** Never propagate novel OS-level environment variables to modify
> executable behavior, strictly enforcing the existing `.repoconfig/config`
> framework instead.
>
> **What:** Global user or CI settings (e.g., Git-LFS defaults) must be managed
> using the explicit `.repoconfig/config` framework. Do not introduce novel
> OS-level environment variables to modify executable behavior.
>
> **Applies To:** Configuration parsers, command-line argument mapping, and
> option handlers across the CLI.
>
> **Why:** A contributor attempted to add a `REPO_GIT_LFS` environment variable
> to ease CI automation. Maintainers rejected the patch, citing that the
> proliferation of disjointed environment variables builds technical debt
> compared to maintaining a single, consistent file-based configuration layer.
> Failing to adhere to this typically results in **Configuration Fragmentation /
> Tech Debt**.

**Trap 1: Adding environment variable mappings into command-line parsers to
support 'headless' configurations.**

**Don't:**

*   Read configuration defaults from `os.environ.get("REPO_GIT_LFS")` alongside
    CLI flags.

**Do:**

*   Instruct users to provision a `~/.repoconfig/config` file in automated
    setups instead of changing process environment logic.

**Exceptions:** Legacy environment variables (e.g., `REPO_URL`) remain supported
for backward compatibility but are explicitly designated as technical debt.

--------------------------------------------------------------------------------

#### T6-23: CLI Command Parity with Git Semantics

> **Rule:** Tightly bind local CLI utility semantics and argument definitions to
> match analogous Git operations explicitly.
>
> **What:** Internal CLI command responsibilities and user-facing terminology
> must align with established Git semantics and project-wide conventions.
>
> **Applies To:** Command-line interface modules (e.g., `subcmds/status.py`,
> `subcmds/info.py`).
>
> **Why:** Global metadata (like superproject commit IDs) was mistakenly added
> to `repo status`, which cluttered the local working-tree status. Additionally,
> the term 'hash' was used instead of the standard 'revision'. Failing to adhere
> to this typically results in **UX Inconsistency / Clutter**.

**Trap 1: Adding project-wide or environmental metadata queries to commands
designed for local working-tree analysis.**

**Don't:**

*   Injecting global repository state (e.g., `--superproject-hash`) into the
    `status` command, which breaks parity with `git status`.

**Do:**

*   Relocating environmental and global metadata display to the `info` command,
    integrating it cleanly into the default summary header.

**Trap 2: Using non-standard terminology for Git object identifiers in
user-facing CLI flags.**

**Don't:**

```python
# BAD: Using 'hash' which is inconsistent with existing repo terminology
p.add_option("--superproject-hash", help="print the superproject hash")
```

**Do:**

```python
# GOOD: Using 'revision'
p.add_option("--superproject-rev", help="print the superproject revision")
```

--------------------------------------------------------------------------------

#### T6-24: Context-Aware Sync Operation Termination

> **Rule:** Must catch and defer local sync iteration failures gracefully rather
> than forcing immediate unrecoverable exits across all active streams.
>
> **What:** Non-critical update failures during local sync iterations must set
> an error flag but must only force a hard exit if the user explicitly provided
> the `--fail-fast` CLI argument.
>
> **Applies To:** All local project iteration workflows within
> `subcmds/sync.py`.
>
> **Why:** A single project failing an isolated sub-task (like a symlink update)
> would immediately trigger `sys.exit(1)`, aborting the entire pipeline for all
> other projects and ignoring standard error aggregation strategies. Failing to
> adhere to this typically results in **Premature Pipeline Termination**.

**Trap 1: Triggering an immediate system exit on an update failure.**

**Don't:**

```python
if self.UpdateCopyLinkfileList():
  print('\nerror: Local update copyfile or linkfile failed.', file=sys.stderr)
  sys.exit(1)
```

**Do:**

```python
if not self.UpdateCopyLinkfileList():
  err_event.set()
  err_update_linkfiles = True
  if opt.fail_fast:
    print('\nerror: Local update copyfile or linkfile failed.', file=sys.stderr)
    sys.exit(1)
```

--------------------------------------------------------------------------------

#### T6-25: Explicit Exit Codes on CLI Cancellation

> **Rule:** Always force the process to yield a non-zero exit code if an
> interactive confirmation prompt is declined or cancelled.
>
> **What:** Interactive CLI workflows that are cancelled or declined by the user
> must immediately return a non-zero exit code to signal termination to parent
> processes.
>
> **Applies To:** All interactive subcommands (`gc`, `sync` with prompts, etc.).
>
> **Why:** If a tool cleanly exited (returning None / 0) after a user denied a
> destructive action prompt, shell automation wrappers and CI systems falsely
> assumed the destructive cleanup successfully completed. Failing to adhere to
> this typically results in **Silent Automation Failure**.

**Trap 1: Using an empty `return` to back out of a declined CLI confirmation
prompt.**

**Don't:**

```python
ask = input("Proceed? [y/N] ")
if ask.lower() != "y":
    return
```

**Do:**

```python
ask = input("Proceed? [y/N] ")
if ask.lower() != "y":
    return 1
```

--------------------------------------------------------------------------------

#### T6-26: Non-Interactive Safeties for Destructive Commands

> **Rule:** Must implement explicit automation bypass flags for any command
> capable of irreversibly destroying system state.
>
> **What:** Any command capable of destroying state (e.g., garbage collection,
> wiping local commits) must provide both a `--dry-run` and a `--yes` (or
> `--force`) flag to support safe CI automation.
>
> **Applies To:** Command-line definitions for potentially destructive
> operations.
>
> **Why:** Tools that rely exclusively on `input()` prompts block automated
> scripts indefinitely. By explicitly enforcing non-interactive modes, scripts
> can safely trigger automated cleanups or log dry-runs without freezing.
> Failing to adhere to this typically results in **Automation Hang / CI Pipeline
> Freeze**.

**Trap 1: Hardcoding interactive prompts without checking configuration flags
for automation modes.**

**Don't:**

*   Prompting the user with `input('Proceed?')` unconditionally before executing
    a destructive delete.

**Do:**

*   Checking `if opt.dry_run:` to skip execution, or `if opt.yes:` to skip the
    confirmation prompt.

--------------------------------------------------------------------------------

#### T6-27: Strict Interdependent Argument Validation

> **Rule:** Always enforce strict prerequisites checks when parsing command-line
> flags intended to modify or inherit context from other flags.
>
> **What:** Command-line options that exist solely to modify or qualify another
> specific command-line option must be explicitly validated to raise an error if
> their prerequisite option is absent.
>
> **Applies To:** CLI argument parsing routines (`subcmds/init.py`,
> `ValidateOptions`).
>
> **Why:** A new `--manifest-upstream-branch` argument was added to qualify a
> provided commit hash. However, without strict validation, users could supply
> it independently, leading to ambiguous or unhandled configuration states.
> Failing to adhere to this typically results in **CLI Ambiguity / Unhandled
> Option State**.

**Trap 1: Accepting dependent modifier options unconditionally without checking
prerequisites.**

**Don't:**

*   Accepting `--manifest-upstream-branch` in the CLI parser and directly
    assigning it to the internal state regardless of the presence of
    `--manifest-branch`.

**Do:**

*   Explicitly checking the parsed options and raising an `OptionParser.error`
    if the modifier is present but the target `--manifest-branch` is null.

--------------------------------------------------------------------------------

#### T6-28: Actionable CLI Error Messages for Synchronization Failures

> **Rule:** Embed direct, explicit commands and flag references within terminal
> error payloads to rescue users from failing execution states.
>
> **What:** When a terminal failure occurs during CLI operations, the error
> payload must provide specific, actionable flags or manual steps for the user
> to resolve the failing state.
>
> **Applies To:** Sync command error reporting (`subcmds/sync.py`,
> `project.py`).
>
> **Why:** When a local branch had published commits but was behind upstream,
> the sync failed with a generic 'punt' message, leaving users unaware that
> passing `--rebase` could force the sync. Failing to adhere to this typically
> results in **User Friction / Dead End**.

**Trap 1: Failing a sync operation with a descriptive but non-actionable error
message.**

**Don't:**

```python
fail(LocalSyncFail(
    "branch %s is published (but not merged) and is now %d commits behind"
    % (branch.name, len(upstream_gain)),
    project=self.name,
))
```

**Do:**

```python
fail(LocalSyncFail(
    "branch %s is published (but not merged) and is now %d commits behind. "
    "Fix this manually or rerun with the --rebase option to force a rebase."
    % (branch.name, len(upstream_gain)),
    project=self.name,
))
```

--------------------------------------------------------------------------------

#### T6-29: Launcher Script Version Upgrades for Important Changes

> **Rule:** Increment the `VERSION` tuple within the standalone `repo` launcher script when making important or significant functional changes.
>
> **What:** If you modify the standalone `repo` launcher file with an important or large change (e.g., updates to Python version checks, significant logic fixes, or major argument parsing updates), you must increment the `VERSION = (X, Y)` tuple.
>
> **Applies To:** Standalone `repo` launcher script, release engineering workflows.
>
> **Why:** The repo source code entry point (`main.py`) compares the runner wrapper version to the copy of the launcher in the source tree to prompt users to upgrade. If an important launcher modification is submitted without a corresponding version bump, users executing older wrappers won't receive the required update prompts. Failing to adhere to this typically results in **Launcher Version Skew / Missing Update Warnings**.
>
> **Exceptions:** Minor or cosmetic changes (like fixing typos in comments or minor docstrings) do not require a version bump.

**Trap 1: Submitting a major or important patch to the `repo` launcher script without updating its `VERSION` definition.**

**Don't:**

```python
# Making significant changes to Python version handling logic
# but leaving VERSION unchanged:
VERSION = (2, 65)
```

**Do:**

```python
# Incrementing the minor version tuple to signal the update:
VERSION = (2, 66)
```

--------------------------------------------------------------------------------

### Cross-Domain Dependencies

*   **Upstream:** T1 | Concurrent Synchronization & IPC - *CLI rendering relies
    on sorted, deterministic results emitted from asynchronous multiprocessing
    pools.*
*   **Downstream:** T3 | Subprocess Git Integration & Error Translation -
    *Command-line terminology and state configurations must tightly align with
    wrapped Git subprocess semantics.*

## Chapter: Repo Hooks Framework

**Context:** The Repo Hooks Framework governs the execution, parameter
validation, and lifecycle management of user-defined scripts within the
repository ecosystem. It ensures seamless integration of extensions like
`post-sync` or `pre-upload` while strictly isolating their execution failures
from core operational workflows.

### Summary

| Rule ID   | Principle /        | Priority | Primary Symptom / Trap           |
:           : Constraint         :          :                                  :
| :-------- | :----------------- | :------- | :------------------------------- |
| **T7-01** | Explicit           | Critical | Passing a new variable to        |
:           : Registration of    :          : `hook.Run()` without             :
:           : Hook Parameters in :          : whitelisting it in the           :
:           : API Contract       :          : `_API_ARGS` map.                 :
| **T7-02** | Floating-Point     | High     | Casting float calculations       |
:           : Precision for Hook :          : directly to integers before      :
:           : Telemetry Metrics  :          : passing to downstream systems.   :
| **T7-03** | Non-Blocking       | High     | Using raw `subprocess` calls to  |
:           : Post-Sync Hook     :          : run custom scripts and tying the :
:           : Integration        :          : command's exit code to the main  :
:           :                    :          : tool's exit code.                :
| **T7-04** | Dynamic CLI Option | Medium   | Bypassing standard option        |
:           : Injection for Repo :          : parsers by passing a mock object :
:           : Hooks              :          : with hardcoded values into hook  :
:           :                    :          : factory methods.                 :
| **T7-05** | Boolean Evaluation | High     | Wrapping a framework execution   |
:           : for Repo Hook      :          : method in a generic exception    :
:           : Execution Status   :          : handler.                         :
| **T7-06** | Universal Trigger  | High     | Documenting hook triggers based  |
:           : Specification for  :          : on an idealized use-case (a full :
:           : Execution          :          : checkout) rather than the        :
:           : Lifecycle          :          : literal programmatic trigger.    :
| **T7-07** | Forward-Compatible | High     | Defining a hook entrypoint with  |
:           : kwargs for Repo    :          : a strict argument list that      :
:           : Hooks Signatures   :          : cannot gracefully handle new     :
:           :                    :          : inputs.                          :

--------------------------------------------------------------------------------

### Rules

#### T7-01: Explicit Registration of Hook Parameters in API Contract

> **Rule:** Always register new metadata or arguments intended for user-defined
> lifecycle scripts within the internal `_API_ARGS` validation dictionary.
>
> **What:** Any new metadata or argument passed into user-defined lifecycle
> scripts must be explicitly defined in the hook's internal validation
> dictionary (`_API_ARGS`).
>
> **Applies To:** Repo Hooks Framework (`hooks.py` and Hook Runners).
>
> **Why:** New arguments sent to the post-sync execution context triggered
> internal exceptions because the core application strictly validates `**kwargs`
> against a registered list of supported arguments. Failing to adhere to this
> typically results in **Runtime Hook Failure**.

**Trap 1: Passing a new variable to `hook.Run()` without whitelisting it in the
`_API_ARGS` map.**

**Don't:**

```python
# In subcmds/sync.py
hook.Run(repo_topdir=self.client.topdir, sync_duration_seconds=dur)

# In hooks.py (Missing registration)
_API_ARGS = {
    'post-sync': {'repo_topdir'}
}
```

**Do:**

```python
# In hooks.py
_API_ARGS = {
    'post-sync': {'repo_topdir', 'sync_duration_seconds'}
}
```

#### T7-02: Floating-Point Precision for Hook Telemetry Metrics

> **Rule:** Must pass system telemetry and operational duration metrics to
> downstream extension hooks as precise floating-point values.
>
> **What:** System telemetry, specifically operational duration metrics, must be
> passed to downstream extension hooks as granular floating-point values. The
> executing system must not truncate or cast telemetry to integers.
>
> **Applies To:** Performance telemetry generation and hook contexts.
>
> **Why:** Internal performance timers originally cast their delta outputs to
> integers before emitting the context to the hook system. This caused a loss of
> sub-second precision, limiting telemetry usefulness. Failing to adhere to this
> typically results in **Telemetry Data Loss**.

**Trap 1: Casting float calculations directly to integers before passing to
downstream systems.**

**Don't:**

```python
sync_duration_seconds = time.time() - start_time
self._RunPostSyncHook(opt, sync_duration_seconds=int(sync_duration_seconds))
```

**Do:**

```python
sync_duration_seconds = time.time() - start_time
self._RunPostSyncHook(opt, sync_duration_seconds=sync_duration_seconds)
```

#### T7-03: Non-Blocking Post-Sync Hook Integration

> **Rule:** Never allow post-operation custom hooks to block or alter the
> success state of the core operation.
>
> **What:** Custom hooks executed strictly after an operation finishes (like
> `post-sync`) must run via the encapsulated `RepoHook` framework and be
> entirely non-blocking, so their failure does not negatively affect the core
> operation's recorded success state.
>
> **Applies To:** subcmds/sync.py and `RepoHook` integrations executing after
> repository data modifications.
>
> **Why:** Teams needed a reliable way to provision local Git `commit-msg` hooks
> even if developers bypassed `repo upload` with manual `git push`. A
> `post-sync` hook was added, but the rigid requirement was that if the user
> script failed, the actual project synchronization must still report as a
> success to avoid corrupting UX. Failing to adhere to this typically results in
> **Blocked Sync Operations**.

**Trap 1: Using raw `subprocess` calls to run custom scripts and tying the
command's exit code to the main tool's exit code.**

**Don't:**

```python
# BAD: Post-action failure corrupts the sync outcome
if subprocess.run(["run_hooks.sh"]).returncode != 0:
    raise SyncError("Hook failed")
```

**Do:**

```python
# GOOD: Managed execution safely wrapping and suppressing exceptions
hook = RepoHook("post-sync")
hook.Run() # Designed strictly to warn on failure
```

#### T7-04: Dynamic CLI Option Injection for Repo Hooks

> **Rule:** Always utilize the RepoHook option group injection framework for
> command-line integration rather than synthesizing dummy configuration objects.
>
> **What:** Command-line integration for new hooks must utilize the RepoHook
> option group injection framework rather than synthesizing dummy configuration
> objects.
>
> **Applies To:** Repo Hooks Framework; specifically subcommand definitions
> involving hook invocations (e.g., `subcmds/sync.py`).
>
> **Why:** When integrating the post-sync hook, a developer initially created a
> minimal 'DummyOpt' object to satisfy parameter checks because the sync command
> lacked native hook flags. This diverged from standard hook architecture and
> could cause attribute errors. Failing to adhere to this typically results in
> **AttributeError / Option Divergence**.

**Trap 1: Bypassing standard option parsers by passing a mock object with
hardcoded values into hook factory methods.**

**Don't:**

```python
# BAD: Using a dummy object to satisfy missing CLI arguments
class DummyOpt:
    bypass_hooks = False
    allow_all_hooks = True
    ignore_hooks = True

hook = RepoHook.FromSubcmd(opt=DummyOpt(), ...)
```

**Do:**

```python
# GOOD: Injecting the standard hook option group into the parser
RepoHook.AddOptionGroup(parser, 'post-sync')

# Later during execution, pass the actual resolved options:
hook = RepoHook.FromSubcmd(opt=actual_opt, ...)
```

#### T7-05: Boolean Evaluation for Repo Hook Execution Status

> **Rule:** Always evaluate hook execution success using the boolean return
> value of `Run()`, never by wrapping the call in external exception handlers.
>
> **What:** Execution wrappers for Repo Hooks must rely on the boolean return
> value of `Run()` to evaluate success, rather than wrapping the call in broad
> `try/except Exception` blocks.
>
> **Applies To:** Repo Hooks Framework; specifically the invocation layer for
> any hook type (`post-sync`, `pre-upload`).
>
> **Why:** A developer wrapped the hook execution in a broad Exception catch
> block. The hook framework inherently traps and standardizes exceptions
> internally; wrapping it externally duplicates logic, masks context, and leads
> to silent failure processing. Failing to adhere to this typically results in
> **Swallowed Exceptions / Logic Duplication**.

**Trap 1: Wrapping a framework execution method in a generic exception
handler.**

**Don't:**

```python
# BAD: Redundant outer try/except block swallowing state
try:
    hook.Run()
except Exception as e:
    print(f"Warning: hook failed: {e}")
```

**Do:**

```python
# GOOD: Relying on the established boolean return contract
success = hook.Run()
if not success:
    print("Warning: hook reported failure.")
```

#### T7-06: Universal Trigger Specification for Execution Lifecycle

> **Rule:** Must document the exact, literal programmatic triggers for hooks
> rather than relying on idealized use-cases like full checkouts.
>
> **What:** Hook documentation must strictly delineate the exact success states
> that trigger execution, explicitly noting conditions where operational state
> (like a local checkout) might be bypassed or skipped.
>
> **Applies To:** Repo Hooks API contracts and documentation
> (`docs/repo-hooks.md`).
>
> **Why:** Users of the new post-sync hook might assume it only runs after a
> complete workspace checkout. However, it effectively fires on any
> zero-exit-code sync operation, including network-only fetches where the local
> filesystem state remains completely untouched. Failing to adhere to this
> typically results in **State Assumption Bugs**.

**Trap 1: Documenting hook triggers based on an idealized use-case (a full
checkout) rather than the literal programmatic trigger.**

**Don't:**

*   Documenting that the hook is to install post-processing tasks specifically
    for successful full checkouts.

**Do:**

*   Documenting that the hook runs when `repo sync` completes without errors,
    explicitly warning that this does not guarantee all projects were synced or
    checked out (e.g., `repo sync -n` performs network fetches only).

#### T7-07: Forward-Compatible kwargs for Repo Hooks Signatures

> **Rule:** Always design hook script entrypoints to accept variable keyword
> arguments (`**kwargs`) to ensure forward compatibility with future framework
> expansions.
>
> **What:** All repository hook script entrypoints (`main` functions) must
> accept variable keyword arguments (`**kwargs`) to maintain forward
> compatibility with future API augmentations.
>
> **Applies To:** Repo Hooks scripts and internal examples (e.g.,
> `post-sync.py`, `pre-upload.py`).
>
> **Why:** Historically, if the `repo` tool evolved to pass new environmental
> context (like `repo_topdir`), user-defined scripts with strict function
> signatures would crash with a TypeError. Failing to adhere to this typically
> results in **TypeError / API Breakage**.

**Trap 1: Defining a hook entrypoint with a strict argument list that cannot
gracefully handle new inputs.**

**Don't:**

```python
# BAD: Strict signature that will crash on API update
def main(repo_topdir=None):
    print("Running tasks...")
```

**Do:**

```python
# GOOD: Accepts forward-compatible **kwargs
def main(repo_topdir=None, **kwargs):
    """
    Args:
      kwargs: Leave this here for forward-compatibility.
    """
    print("Running tasks...")
```

--------------------------------------------------------------------------------

### Cross-Domain Dependencies

*   **Upstream:** T6 | CLI Argument Parsing & UX Consistency - *The dynamic hook
    injection framework fundamentally relies on standardized option parsers to
    map CLI flags cleanly into hook runner contexts.*
