How It Works
The garden model, entry lifecycle, and how Hortora works in both local and GitHub-connected modes.
The garden model
A Hortora garden is a machine-wide library of hard-won technical knowledge stored at ~/.hortora/garden/. Every Claude Code session on your machine can read from it and contribute to it.
Entries come in three kinds:
- Gotchas — bugs that silently fail, behaviours that contradict documentation, workarounds that took hours to find
- Techniques — non-obvious approaches a skilled developer wouldn't naturally reach for, but would immediately value
- Undocumented — behaviours, options, or features that exist and work but aren't written down anywhere
Each entry targets a specific technology and describes exactly one thing. The editorial bar is intentionally high — that's what makes the garden worth consulting.
Entry lifecycle
Entries move through a governed pipeline from raw capture to live garden. Forage and harvest support two modes — choose based on your setup:
Local mode
- Capture — forage generates a collision-free GE-ID locally and queues a submission file in
~/.hortora/garden/submissions/ - Validate — harvest runs
validate_pr.pylocally; CRITICAL issues block integration - Integrate — harvest calls
integrate_entry.py, which updates indexes and commits directly to the local git clone - Deduplicate — harvest DEDUPE finds overlapping entries and resolves them, keeping the garden clean
GitHub mode
- Capture — forage generates a collision-free GE-ID locally and opens a PR against
Hortora/garden - CI validates — GitHub Actions runs
validate_pr.pyon every PR; failures block merge with a clear report - Integrate — on merge, a second workflow runs
integrate_entry.py; indexes update automatically, no manual step needed
Both modes use the same validation logic, the same entry format, and the same garden repository. You can work offline in local mode and push to sync, or use GitHub mode and let CI do the governance.
The separation between capture (lightweight, session-time) and integrate (thorough, maintenance-time) is intentional in both modes. It keeps forage fast and keeps the live garden authoritative.
GE-IDs
Every entry gets a stable identifier assigned by forage at submission time — no coordination with the garden required. The format is GE-YYYYMMDD-xxxxxx: the submission date plus 6 random hex characters (e.g. GE-20260410-a3f7c2). This guarantees uniqueness across concurrent submissions and across federated gardens without a shared counter. IDs are never reused.
Git-backed
The garden is a git repository — Hortora/garden on GitHub. Every entry is a commit. History is authoritative. No central server is required beyond git itself.
To use the garden locally, forage sets up a sparse blobless clone at ~/.hortora/garden/ during install. This gives you the full garden with minimal disk use, and works entirely offline once cloned.
To use the GitHub-connected workflow, point forage at the garden repo. Submissions become PRs, CI validates, and integration is automatic on merge. The same local clone stays in sync via git pull.
Both approaches share the same repository and entry format — switching between them requires no migration.