feat(pipeline): report when a re-ingest disagrees with the page on disk (#104) #129

Merged
mathias merged 2 commits from fix/104-surface-merge-conflicts-v2 into main 2026-09-23 05:22:28 +00:00
Owner

Replaces #127, which was based on fix/105-source-drift-on-main (now merged as #126 via squash — same ancestry-break as the #109→#126 replacement earlier in this sprint, so a straight retarget wasn't mergeable). Same single commit, rebased onto current main.

The rebase hit a tangled conflict in ingestion/internal/wiki/merge_test.go: both #126 (4 review rounds, several new tests added at the same insertion point) and #104's own commit added tests immediately after TestMerge_GeneratorOwnedFrontmatterFieldsAreRefreshed, so git's diff3 conflict markers interleaved content from both sides mid-function. Resolved by reconstructing from clean versions of each side (git show <ref>:path) rather than trusting the markers: took main's full file (all 5 of #126's review-driven tests) and appended #104's two own tests (TestMerge_ReportsSectionsWhereTheFreshVersionWasDiscarded, TestMerge_ReportsNothingWhenTheFreshVersionAgrees) verbatim at the end. merge.go itself auto-merged cleanly (no manual resolution needed there).

Full module go build ./... && go vet ./... && go test ./... -race -count=1 green after resolution.

Closes #104.


Created via git-mcp on behalf of @mathias

Replaces #127, which was based on `fix/105-source-drift-on-main` (now merged as #126 via squash — same ancestry-break as the #109→#126 replacement earlier in this sprint, so a straight retarget wasn't mergeable). Same single commit, rebased onto current `main`. The rebase hit a tangled conflict in `ingestion/internal/wiki/merge_test.go`: both #126 (4 review rounds, several new tests added at the same insertion point) and #104's own commit added tests immediately after `TestMerge_GeneratorOwnedFrontmatterFieldsAreRefreshed`, so git's diff3 conflict markers interleaved content from both sides mid-function. Resolved by reconstructing from clean versions of each side (`git show <ref>:path`) rather than trusting the markers: took `main`'s full file (all 5 of #126's review-driven tests) and appended #104's two own tests (`TestMerge_ReportsSectionsWhereTheFreshVersionWasDiscarded`, `TestMerge_ReportsNothingWhenTheFreshVersionAgrees`) verbatim at the end. `merge.go` itself auto-merged cleanly (no manual resolution needed there). Full module `go build ./... && go vet ./... && go test ./... -race -count=1` green after resolution. Closes #104. --- _Created via git-mcp on behalf of @mathias_
mathias added 1 commit 2026-09-23 05:12:04 +00:00
feat(pipeline): report when a re-ingest disagrees with the page on disk (#104)
CI / Lint / Test / Vet (pull_request) Successful in 32s
CI / Mirror to GitHub (pull_request) Skipped
719eb8c2d6
The asymmetry that makes unattended ingest safe (#103) also discarded a
real signal. When a fresh extraction produced a different version of a
section already on disk, the on-disk version won and the model's version
went in the bin without a word — so "the source is unchanged" and "the
source changed its mind and we ignored it" were indistinguishable.

wiki.MergeReport now returns the headings where the incoming version
disagreed and lost, and the ingest run reports them as warnings, which
AppendLog already writes into log.md.

This is the simplified answer to contradiction flagging at ingest. The
issue proposed calling brain-gardener's Judge from the ingest path, which
needs either a shared Go module across two repos or an HTTP service that
does not exist — and puts an LLM call on the write path, where a timeout
must neither fail the ingest nor silently mark nothing as contested.

None of that is necessary to get the signal. The merge already computes
the disagreement; it was throwing it away. Surfacing it costs nothing,
needs no model, no cue-word matcher, no cross-repo dependency, and is
deterministic.

Deliberately textual disagreement, not semantic contradiction. Deciding
whether a disagreement is a genuine contradiction stays with the
Judge-gated enrich pass that already runs hourly and is approval-gated by
design (brain-gardener#175). Detection here, adjudication there.

Merge is kept as a thin wrapper over MergeReport so existing callers are
untouched.

Refs #104, #103, brain-gardener#175, brain#21.
mathias added 1 commit 2026-09-23 05:20:43 +00:00
fix(wiki): canonicalize whitespace across a whole section, not just its ends
CI / Lint / Test / Vet (pull_request) Successful in 38s
CI / Mirror to GitHub (pull_request) Skipped
b05e9c48f4
Review of PR #129 found MergeReport's disagreement check compared
strings.TrimSpace(sA.content) against strings.TrimSpace(sB.content) --
only leading/trailing whitespace is tolerated. Every other content
comparison in this file (appendNew, mergeBullets) already canonicalizes
internal whitespace runs too, because a re-extraction's exact spacing
isn't byte-stable (#103). A mid-line double-space would false-positive
as a "disagreement" here even though the file's own established
tolerance says it shouldn't.

canonicalBlock applies the existing canonicalLine per line of a
multi-line section body. A genuine content difference is still caught
(TestMerge_ReportsSectionsWhereTheFreshVersionWasDiscarded stays green);
only internal-whitespace-only variants stop false-positiving.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Author
Owner

DECISION NEEDED (posted on this PR and #104) resolved by Mathias: Option A — ship the textual-diff-only version as-is. Semantic contradiction detection via brain-gardener's Judge stays out of scope for now (no cross-repo dependency needed yet; that path is still open later through brain-enrich's existing Judge-gated pass).

New commit b05e9c4 also fixes the minor non-blocking finding from the review (internal-whitespace-only differences no longer false-positive as a disagreement — canonicalBlock, mirroring the whitespace tolerance appendNew/mergeBullets already have).


Created via git-mcp on behalf of @mathias

DECISION NEEDED (posted on this PR and #104) resolved by Mathias: **Option A** — ship the textual-diff-only version as-is. Semantic contradiction detection via brain-gardener's Judge stays out of scope for now (no cross-repo dependency needed yet; that path is still open later through brain-enrich's existing Judge-gated pass). New commit `b05e9c4` also fixes the minor non-blocking finding from the review (internal-whitespace-only differences no longer false-positive as a disagreement — `canonicalBlock`, mirroring the whitespace tolerance `appendNew`/`mergeBullets` already have). --- _Created via git-mcp on behalf of @mathias_
mathias merged commit cdafdf6e0f into main 2026-09-23 05:22:28 +00:00
Sign in to join this conversation.