Architecture
Package layout
repairledger/
__init__.py Package version
constants.py Shared constants and enums (incl. global path config)
errors.py Structured error types
models.py Dataclass models (Workspace, Repair, ComponentSpec)
identity.py ID formatting, ref derivation, selector normalization
storage.py Filesystem operations, CRUD, version snapshots, locking
guardrails.py Validation for observed status
render.py Markdown rendering of repair artifacts
report.py Aggregate report generation
bundle.py Structured JSON bundle create/update
cli.py Typer CLI definition
launcher.py Entry point
Module dependencies
launcher → cli → { bundle, render, report, storage }
storage → { identity, constants, errors, models, guardrails }
bundle → { storage, identity, constants, errors }
render → { storage, identity, constants }
report → { storage, identity, constants }
identity → { constants } (via ledgercore refs)
Key design decisions
User-global config and data path: a single config at
${XDG_CONFIG_HOME:-~/.config}/ledger/repairledger.tomland a single data path at${XDG_DATA_HOME:-~/.local/share}/ledger/repairledger/. Agents log observations from any repository without writing into the current source tree.Global-only discovery: the local repository is never searched for a config. An absolute
REPAIRLEDGER_CONFIGoverride is the only way to point at a custom config.Flat package layout: No
src/directory. Package is directly under repo root.Dynamic versioning: Via
setuptools_scmfrom Git tags.Atomic writes: All file mutations use
ledgercore.atomichelpers.Version snapshots: Complete post-mutation copies under
versions/v000X/.Derived refs: Global and file refs are generated at render time, not stored.
Inter-process locking:
fcntl.flockagainst<data path>/.repairledger.lockserializes repair ID allocation, repair creation, and active-repair updates. Initialization uses a separate lock adjacent to the config file.Explicit repair selector for mutations: when multiple repairs exist, mutating commands (
repair status,repair archive,repair build,repair component set,repair component append) require an explicit--repair REPAIR_ID. The globalactive_repair_idis advisory only.Read-only commands stay read-only:
status,info,doctor, andnext-actionnever create files.missing_storageis reported instead of silently adopting or creating storage.ledgercore integration: Uses ledgercore for atomic I/O, YAML, ref parsing, timestamps, and hashing.