adr/004-recursive-cheat-directory-search.md
.cheat Directory SearchDate: 2026-02-15
Accepted
Previously, cheat only checked the current working directory for a .cheat
subdirectory to use as a directory-scoped cheatpath. If a user was in
~/projects/myapp/src/handlers/ but the .cheat directory lived at
~/projects/myapp/.cheat, it would not be found. Users requested (#602) that
cheat walk up the directory hierarchy to find the nearest .cheat
directory, mirroring the discovery pattern used by git for .git
directories.
Walk upward from the current working directory to the filesystem root, and
stop at the first .cheat directory found. Only directories are matched (a
file named .cheat is ignored).
.cheat foundRather than collecting multiple .cheat directories from ancestor directories:
.git discovery semantics, which users already understand"cwd" code without structural
changes.cheat directories
exist in the ancestor chaincheat already supports multiple cheatpaths via conf.yml for users who
want that; directory-scoped .cheat serves the project-context use case$HOME)Rather than stopping the search at $HOME:
/etc, /srv, /var, or other paths
outside $HOME.cheat found anywhere),
where the cost is a few extra stat calls.cheat at their project root and it works from any
subdirectory, matching their mental model.cheat directories continue to
work identically.cheat directory in an unexpected ancestor could be picked up
unintentionally, though this is unlikely in practice and matches how .git
works"cwd" regardless of which ancestor the .cheat
was found in$HOMERejected: Adds platform-specific complexity for minimal benefit. The only
downside of walking to root is a few extra stat calls on the failure path.
.cheat directoriesRejected: Introduces precedence and naming complexity. Users who want
multiple cheatpaths can configure them in conf.yml.
findLocalCheatpath() in internal/config/new.go