Ferralk / Architecture
ADR-0006: Git-normative ignore semantics
- Status: Accepted
- Date: 2026-08-18
Context
Git, the ignore crate (ripgrep), and zlob disagree in gitignore corner cases
(negation precedence, anchoring, ** inside ignore rules). One of them has to
be the reference the corpus treats as correct.
Decision
Git itself is normative: git check-ignore verdicts are the corpus oracle for
ignore semantics — this is the ground truth every user intuitively expects
("behaves like Git"). The ignore crate's Gitignore rule matcher is the
engine (its parallel walker is not reused, see ADR-0009). Where the engine
diverges from Git, the divergence is documented and we decide case by case
whether to patch. zlob's own ignore quirks are explicitly not inherited.
Consequences
- User-intuitive behavior, testable against a universally available oracle.
- Occasional maintenance cost when the
ignorecrate and Git disagree. - One more deliberate divergence class from zlob to document.
Amendment, 2026-08-20
The engine half of this decision is superseded by
ADR-0014: rule matching moves from the
ignore crate to a ferralk layer over ferralk-glob, because the borrowed
engine cannot reproduce Git's POSIX classes and the evaluation around it is
already ours. Git stays normative and git check-ignore stays the oracle —
that half is unchanged, and the maintenance cost named above turned out to be
the reason to stop paying it.
Amendment only; the normative-oracle decision above is unchanged.
Amendment, 2026-09-02
"Git" now means Git 2.52.0 or newer for local oracle replay, with Git 2.52.0
as the exact CI reference. Git 2.52 corrected the X**/Y pathname reading:
older releases could erase the separator and match fused literal components,
so an unversioned oracle made the same corpus pass or fail according to the
host distribution. The harness skips Git-backed replay with a diagnostic when
the installed release is older than 2.52.0, while a dedicated CI lane builds
and runs the pinned release.
This amendment versions the existing normative oracle; it does not change the choice of Git semantics.