You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(repo): a committed conflict block sits in a tracked file on main, and no gate rejects conflict markers #17297
docs/.obsidian/workspace.json is tracked and contains a committed merge-conflict block on origin/main. The file is not valid JSON, so anything that parses it fails.
Verified at origin/main = aec5e09cfbbf0ff1101adbe72828f362598b4b67. Found by the end-of-session
conflict-marker gate while working an unrelated docs branch; my own commit touched only docs/research/_index.md and one new research file.
Two things this says
The markers are Updated upstream / Stashed changes — this came from a git stash pop
conflict that was staged and committed without resolution, not from a merge or rebase. The git
stash stack is shared across every worktree in this repo, which is precisely the hazard that
makes a blind pop dangerous.
No gate caught it. Sessions are told to grep '^<<<<<<< ' before a final push, but that is
a convention, not an enforced check — so it only fires when someone remembers. A committed
conflict marker reaching the default branch is the evidence that it did not fire here.
Acceptance criteria
docs/.obsidian/workspace.json is valid JSON on main — resolved to the intended content,
not merely to whichever side parses.
Decide whether this file belongs in version control at all: it is Obsidian per-user editor
state (open panes, cursor positions), which is per-developer and conflicts by nature. If it
is not needed, .gitignore it and remove it — that removes the conflict class permanently.
A pre-commit or pre-push hook rejects ^<<<<<<< , ^======= and ^>>>>>>> in any staged
or pushed file, so the convention becomes a gate.
A one-off sweep confirms no other tracked file on main carries conflict markers, and the
sweep output is posted — a nil result stated as a nil result, not as silence.
👋 Auto-triage could not confidently classify this issue (no confident signal). Could a maintainer add the appropriate labels (frontend, backend, infrastructure, docs, testing and good-first-issue, intermediate, advanced)?
PR #17407 merged as fbe46dbaf3 with Closes #17297. Evidence read from merged code, not the PR diff.
The marker is gone from the tree ✅
git grep -l '^<<<<<<< ' origin/main -> 0 files
Before the merge there was exactly one: docs/.obsidian/workspace.json:182, <<<<<<< Updated upstream, tracked since 2026-04-03. That file is untracked now, and .gitignore:509 already matched it — the rule was there and inert, because .gitignore does not apply to a tracked path. So it cannot come back.
This is the substance of the issue. check-merge-conflict returns 0 unless the repo is mid-merge — it checks for MERGE_MSG plus MERGE_HEAD/rebase-* and exits before reading a single line otherwise. A git stash pop conflict creates none of those, so the markers it leaves were invisible to a hook that reported "Passed" on every commit for five months.
A guard exists and cannot pass by not looking ✅
test_the_sweep_actually_reaches_the_tree
test_no_tracked_file_carries_a_conflict_marker
test_the_hook_is_still_armed
test_the_detector_recognises_each_marker_shape (parametrised per marker)
SCANNED_FILES carries a population floor, so "no markers found" is distinguishable from "no files read" — which is the failure this issue is an instance of, and the reason the original hook was useless rather than merely weak.
Recorded because a tick should not imply more than it covers
test_the_detector_recognises_each_marker_shapedid not bind when first written. Its docstring said it asserted through _conflict_sites' own predicate; the assertion re-implemented that predicate inline and never called it. Dropping the bare-======= clause from the real detector left all three parametrised cases passing — including the separator case the docstring named as the easy miss.
Repaired before merge: it now git-inits a throwaway repo under tmp_path, writes a file carrying the marker, stages it so git ls-files reports it, and asserts _conflict_sites returns that site. Mutation-proved in both directions — dropping the separator predicate fails 1 case, dropping the outer-prefix predicate fails 2, each caught by its own parametrisation.
Worth keeping: the file said out loud that it was not re-implementing the predicate, and then did. A docstring claiming a test binds is not evidence that it does.
Activity
github-actions commentedon Sep 22, 2026
👋 Auto-triage could not confidently classify this issue (no confident signal). Could a maintainer add the appropriate labels (
frontend,backend,infrastructure,docs,testingandgood-first-issue,intermediate,advanced)?test(repo): run the conflict detector instead of restating it (#17297)
fix(secrets): drop the baseline entries stranded by untracking worksp…
mrveiss commentedon Sep 24, 2026
AC verification against merged
mainatfbe46dbaf3PR #17407 merged as
fbe46dbaf3withCloses #17297. Evidence read from merged code, not the PR diff.The marker is gone from the tree ✅
Before the merge there was exactly one:
docs/.obsidian/workspace.json:182,<<<<<<< Updated upstream, tracked since 2026-04-03. That file is untracked now, and.gitignore:509already matched it — the rule was there and inert, because.gitignoredoes not apply to a tracked path. So it cannot come back.The hook is armed ✅
git show origin/main:.pre-commit-config.yamlThis is the substance of the issue.
check-merge-conflictreturns 0 unless the repo is mid-merge — it checks forMERGE_MSGplusMERGE_HEAD/rebase-*and exits before reading a single line otherwise. Agit stash popconflict creates none of those, so the markers it leaves were invisible to a hook that reported "Passed" on every commit for five months.A guard exists and cannot pass by not looking ✅
SCANNED_FILEScarries a population floor, so "no markers found" is distinguishable from "no files read" — which is the failure this issue is an instance of, and the reason the original hook was useless rather than merely weak.Recorded because a tick should not imply more than it covers
test_the_detector_recognises_each_marker_shapedid not bind when first written. Its docstring said it asserted through_conflict_sites' own predicate; the assertion re-implemented that predicate inline and never called it. Dropping the bare-=======clause from the real detector left all three parametrised cases passing — including the separator case the docstring named as the easy miss.Repaired before merge: it now git-inits a throwaway repo under
tmp_path, writes a file carrying the marker, stages it sogit ls-filesreports it, and asserts_conflict_sitesreturns that site. Mutation-proved in both directions — dropping the separator predicate fails 1 case, dropping the outer-prefix predicate fails 2, each caught by its own parametrisation.Worth keeping: the file said out loud that it was not re-implementing the predicate, and then did. A docstring claiming a test binds is not evidence that it does.
fix(guards): reach floors bound by a fraction of the tree, not a cons…