"sounds wrong, fix gitignore": When a User's Intuition Catches a Subtle Bug

The Message

User: "sounds wrong, fix gitignore"

This three-word message, sent at index 14 of a coding session on the Filecoin Gateway project, is a masterclass in concise, effective developer communication. On its surface, it is a simple correction request. But to understand its full weight, we must examine the chain of events that led to it, the incorrect assumptions it challenged, and the subtle but important .gitignore syntax bug it ultimately exposed.

Context: The Conversation So Far

The session began innocuously. At message 0, the user asked the assistant to "Add binaries to gitignore." The assistant read the existing .gitignore, found entries like ./ritool and ./gwcfg (using a ./ prefix pattern), and added ./kuri plus common binary extensions (*.exe, *.dll, etc.). The assistant then committed the change with the message "Add binaries to gitignore."

The user then asked to see git status (message 5), and the assistant showed that gwcfg and kuri still appeared as untracked files. The assistant explained this away in message 7 by saying "The binaries are showing as untracked because the .gitignore changes haven't been committed yet." The user then asked to commit (message 8), and the assistant did so.

After the commit, the user asked for status again (message 11). The assistant ran git status and found—to its apparent surprise—that gwcfg and kuri were still showing as untracked files, even after the commit. The assistant's reasoning in message 13 reveals a critical moment: instead of questioning the .gitignore pattern syntax, the assistant invented an incorrect explanation:

"Git doesn't automatically hide already-existing untracked files when you add them to .gitignore - it only prevents new files from being tracked."

This is where the user's message becomes the turning point.

Why "sounds wrong, fix gitignore" Was Written

The user's message was born from a mismatch between expectation and reality. The user had asked for binaries to be added to .gitignore. The assistant claimed to have done so. The user verified by running git status—twice. Both times, the binaries were still visible. The assistant's explanation that this was "expected behavior" because the files existed before the .gitignore update was, frankly, incorrect. Git does honor .gitignore for files that exist in the working directory but are not yet tracked—that is precisely one of the primary use cases of .gitignore. If a developer adds a pattern to .gitignore and the file is untracked, git status should immediately stop showing it.

The user sensed this contradiction. The phrase "sounds wrong" is telling—it is not a definitive statement of fact, but an expression of intuition. The user did not know why it was wrong, but they knew the assistant's explanation did not align with their understanding of how Git works. This is a hallmark of experienced developers: they trust their mental model of a tool over an agent's rationalization, especially when the rationalization seems to excuse broken behavior.

The Hidden Bug: ./ Prefix in .gitignore

The assistant's message 15 reveals what the assistant discovered upon re-reading the .gitignore file:

./ritool
./gwcfg
./kuri

The problem is the ./ prefix. In Git's .gitignore pattern syntax, a leading ./ is not a valid way to anchor a pattern to the root of the repository. The .gitignore documentation specifies that patterns starting with / are anchored to the directory containing the file, but ./ is treated as a literal path component—it matches a directory literally named . (dot), which is the current directory in shell terms but not a meaningful Git pattern. As a result, ./gwcfg does not match the file gwcfg in the repository root. The correct pattern is simply gwcfg (or /gwcfg to anchor it).

The assistant's initial edit (message 3) had preserved the ./ prefix from the existing entries, assuming they were correct because they were already in the file. This is a classic "cargo cult" error—the assistant copied the pattern without understanding its semantics, and then compounded the error by adding ./kuri in the same incorrect style.

Assumptions Made

Several assumptions were at play in this exchange:

The assistant's assumptions:

  1. That the existing ./ patterns in .gitignore were correct and functional (they were not).
  2. That Git does not hide already-existing untracked files when they match a new .gitignore pattern (this is false).
  3. That committing the .gitignore changes would resolve the visibility issue (it did not, because the patterns were broken).
  4. That the user would accept the explanation about "files existed before .gitignore was updated" without pushback. The user's assumptions:
  5. That the assistant would correctly implement the .gitignore changes.
  6. That git status should show the expected behavior after a correct .gitignore update.
  7. That the assistant's explanation was suspect and worth questioning.

Input Knowledge Required

To understand this message, a reader needs:

Output Knowledge Created

This message and its resolution produced several valuable pieces of knowledge:

  1. The corrected .gitignore: The assistant removed the ./ prefix, changing the patterns to bare names (ritool, gwcfg, kuri), which properly matched the untracked files.
  2. A lesson in .gitignore syntax: The ./ prefix is not a valid Git pattern for root-relative matching. The correct approaches are a bare name (matches anywhere) or /name (anchored to root).
  3. A corrected mental model: Git does hide untracked files when they match a .gitignore pattern, regardless of when the pattern was added. The assistant's earlier explanation was wrong and was corrected.
  4. A demonstration of effective user-agent collaboration: The user's skepticism and concise pushback led to the discovery of a real bug that the assistant had missed.

The Thinking Process

The assistant's reasoning in message 15 shows the moment of realization:

"The problem is the ./ prefix. In .gitignore, patterns with ./ don't work the same way as patterns without it. The ./ prefix is treated literally and doesn't match files in the root directory properly."

This is the key insight. The assistant had to re-examine its assumptions about Git's pattern matching. The earlier reasoning in message 13 was a confident but incorrect explanation—the assistant had convinced itself that the behavior was expected, rather than questioning whether the patterns themselves were valid.

Broader Significance

This exchange illustrates a recurring pattern in human-AI collaboration: the assistant is competent but not infallible, and the user's domain expertise is a critical corrective mechanism. The user did not need to know the exact syntax error—they only needed to know that something "sounds wrong." That intuition, combined with the willingness to push back concisely, saved the session from continuing with a broken configuration.

The message also highlights the importance of questioning inherited patterns. The assistant saw ./ritool and ./gwcfg already in the file and assumed they were correct. In reality, those patterns were likely also broken—they had been added by someone (or the assistant itself in an earlier session) who made the same mistake. The user's intervention broke this chain of incorrect assumptions.

Conclusion

"sounds wrong, fix gitignore" is a deceptively simple message that encapsulates a rich debugging story. It demonstrates the value of developer intuition, the danger of cargo-culting configuration syntax, and the importance of questioning explanations that don't match observed behavior. In three words, the user redirected the session from a dead-end rationalization toward a genuine fix, ultimately correcting not just the immediate issue but also the assistant's understanding of how .gitignore pattern matching works.