The current implementation is a single script:
build_ledger.py
Its pipeline is:
- load config
- discover candidate roots
- score/include candidates
- extract filesystem and git metadata
- merge sidecar metadata
- emit CSV, JSON, and Markdown artifacts
This is correct enough for a prototype but too monolithic for long-term extension.
Refactor toward a small package with explicit boundaries.
project-ledger/
ledger/
__init__.py
cli.py
config.py
models.py
discovery.py
identity.py
sidecar.py
merge.py
reporters.py
exporters/
csv_exporter.py
json_exporter.py
markdown_exporter.py
extractors/
filesystem.py
git.py
obsidian.py
tests/
build_ledger.py
build_ledger.py should become a thin entrypoint over package code.
A configured filesystem path plus a discovery mode and exclusions.
A directory that might represent a meaningful project, repo, vault, or idea container.
Metadata produced from one machine's scan of one project root.
A merged identity representing the same project across one or more observed records.
A human-maintained metadata overlay stored inside the project root.
config
-> discovery
-> candidate scoring
-> metadata extractors
-> sidecar overlay
-> identity resolution
-> outputs
Future merge mode:
machine ledgers
-> identity matching
-> conflict resolution
-> canonical master ledger
-> review report
The prototype currently uses:
- sidecar
project_keywhen available - normalized remote URL when available
- fallback slug/name-derived key otherwise
This is not sufficient for long-term cross-machine matching by itself.
Use layered identity evidence:
- explicit sidecar
project_key - normalized remote URL
- repo root name plus README hash plus title similarity
- path aliases and machine-specific aliases
- manual override table for ambiguous cases
The system should distinguish:
- stable canonical identity
- machine-local observation identity
- candidate duplicate relationships
SCHEMA.md is the source of truth for field definitions.
If code and schema diverge, the agent making the change must reconcile them in the same task.
Human-friendly and spreadsheet-friendly.
Canonical machine-readable artifact for scripts and merge flows.
Quick review table with direct links to paths and READMEs.
- SQLite
- change reports
- issue queue / review queue files
Small unittest coverage around candidate detection, links, and git/sidecar extraction.
Introduce fixture-based tests for:
- nested git repos
- obsidian-only vaults
- low-signal docs-only projects
- malformed sidecars
- multiple root configurations
- merge behavior once implemented
- target roots may be large
- some directories may be inaccessible
- some roots may be imported backups rather than live projects
- git remote information may be missing or stale
- Windows path behavior must remain a first-class concern
- Read-only scanning
- Deterministic outputs
- Human-overridable identity
- Small, explicit modules
- Clear separation between observed machine data and canonical merged data