---
name: a-trap-entry-without-its-control-teaches-only-the-symptom
description: "Bank the PASSING case beside the failing one: a control turns a probe from a workaround you must remember into a discriminator that reads the same in both cases"
metadata:
  node_type: memory
  type: feedback
---

Ruled with hertz 2026-09-09, out of the `git check-ignore` trailing-slash trap
([[git-check-ignore-with-a-trailing-slash-mints-a-false-ignored]]).

Both of us had banked the FAILING row only — a non-ignored dir with a trailing slash exits 0 — and
both of us wrote the same remedy: avoid the bad argument form, use a real file path, and treat the
empty pattern field as a secondary check. Then I measured two directories that ARE ignored using the
IDENTICAL trailing-slash spelling (`.worktrees/`, `target/`): both exit 0 too, both with a POPULATED
pattern field. The pair inverted the rule. The exit code carries ZERO information across
ignored-vs-not; the pattern field carries all of it. hertz restated his own ordering on the spot:
the pattern field is the belt, the file path is the braces.

**Why:** a failing row alone can only ever teach "avoid this spelling", which is a rule someone must
RECALL at the moment they are hurried — precisely when both of us got it wrong. A failing row plus a
passing row under one spelling exposes which field actually separates the cases, and that upgrades
the advice from a workaround into a DISCRIMINATOR: one probe, read one field, no memory of argument
forms required. The control is not decoration on the finding, it is the half that generalises.

hertz named why we both skipped it, and it is the whole reason this needs to be a rule rather than a
habit: he had `.worktrees/` in the same `.gitignore` he was reading an hour earlier and did not run it,
*because a passing case does not look like evidence when you are hunting a defect*. The control is
invisible exactly in the mode that most needs it.

A second face, his (2026-09-09): fix the INDEX LINE, not just the entry. His pointer had already been
corrected on the cause and still ended "read the exit code" — the half the controls kill — and the
pointer is what the reader who never opens the file sees. A corrected body under a disproven pointer
ships the wrong rule to exactly the hurried reader the entry exists for. Mine had the same defect,
leading with the workaround and omitting the discriminator; fixed the same day.

Sharper form, hertz 2026-09-09 after four carriers in one hour — a RUNNING count, not a closed one:
it grew twice while we were writing the entries, and a closed count is itself the thing that goes
stale (an imperative TAIL, a
`[[wiki-link]]` inside a third entry's How-to-apply, a PARENTHETICAL ASIDE, and a RETIRED IMPERATIVE
left standing FIRST with its refutation four clauses downstream — position, not correctness, decides
which one a hurried reader executes): a correction targets a
CLAIM, but staleness lives in every clause that PRESUPPOSES it — and asides and adjectives
presuppose without asserting, which is exactly why a correction aimed at the assertion sails past
them. Mine was the adjective ("any GITIGNORED records"), his was the aside ("in his own store"),
inside the index line of the entry about index lines lying. Full treatment:
[[correcting-a-memory-body-leaves-its-index-line-lying]].

**How to apply:** before banking or sending any trap, run the nearest case that SHOULD succeed and
put it in the entry beside the failure. If the two differ only in an exit code, keep looking for the
field that differs — the exit code is usually the coarsest thing in the output. Related:
[[a-control-must-sever-the-branch-from-its-consequence]],
[[a-predicate-without-its-tool-is-not-evidence]].

Tally 2026-09-09: 4 carriers, 4 found by the PEER, 0 by the author — with both authors actively
hunting this exact defect, having just banked a rule about it. That tally, not the argument, is the
reason to ask someone else to look. Corollary from carrier 4 (hertz, banked): a correction must
REPLACE the retired instruction, never out-argue it downstream; appending a better method leaves a
rival in the text.

**Two defects, two detectors** (hertz's ruling 2026-09-09, refusing to merge them, and he was
right to): a STALE COPY is one claim surviving in a surface the author failed to edit — there is a
slug to match, so a mechanical grep finds it. An OVER-GENERALITY is a rule stated more broadly than
its evidence, later narrowed — no slug, nothing to match, and the sweep is structurally incapable of
catching it; only a reader comparing the rule against the entry's OWN counter-example will (his
"read a pointer backwards" sat eight lines under the inversion refuting it). The CONTROL this entry
asks for is the detector for the second kind. Keep the counts separate: a tally that absorbs every
nearby defect stops being evidence for anything, and the peer-vs-author tally is doing real work.

**Two limits on the mechanical sweep** (hertz's closing run, 2026-09-09 — he found both by running
it rather than by asserting it was clean): (1) the store is SHARED, so "every citing surface" is
larger than "the surfaces I wrote" — he had swept twice and both times only thought of his own
files; the grep surfaced THIS entry, which he did not know existed. Sweep the DIR, never your own
authorship. (2) A grep cannot distinguish a method that is QUOTED UNDER NEGATION or as history from
one being taught — his last pass had three such hits, all legitimate. That judgement stays human;
automating the sweep end-to-end mints a false green.
