Skip to content

fix(remediate): keep out-of-scope pages' canonical markdown on a flagged run - #7

Open
Rl0007 wants to merge 1 commit into
bwhtech:mainfrom
Rl0007:fix/remediate-flagged-canonical
Open

fix(remediate): keep out-of-scope pages' canonical markdown on a flagged run#7
Rl0007 wants to merge 1 commit into
bwhtech:mainfrom
Rl0007:fix/remediate-flagged-canonical

Conversation

@Rl0007

@Rl0007 Rl0007 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Problem

remediate_pdf() seeded canonical markdown from the baseline for every page:

canon_md = {p["page_no"]: p["baseline_markdown"] or "" for p in pages}
canon_comp = {p["page_no"]: p["composite"] for p in pages}
canon_src = {p["page_no"]: "baseline" for p in pages}

Only pages in targets override those seeds, but the tail writes canonical for all pages:

for p in pages:
    store.set_canonical(p["name"], stitched[pno], canon_comp[pno], canon_src[pno])

scope="flagged" only targets non-pass pages, so every pass page — already remediated by the
parse job's scope="all" pass, and possibly hand-fixed since via reparse_page / the finalize
furniture strip — was silently reset to its raw baseline, together with its composite and
provenance. flagged is the default scope of wikify.api.imports.trigger_remediation, so the
UI's Remediate action hits this: on a 357-page import with 282 adopted remediations, one click
throws away all 282.

Fix

A page in the scope still starts from its baseline (so a remediation only becomes canonical
when this run adopts it). A page outside the scope keeps the canonical markdown, composite and
provenance it already carries, falling back to baseline when it has none. scope="all" targets
every page, so its behaviour is unchanged.

store.get_pages() now also selects the three canonical fields. The run summary's adopted count
is now counted in the adoption loop, so it keeps meaning "adopted by this run" rather than
picking up historical adoptions from out-of-scope pages.

Test

test_flagged_run_keeps_an_out_of_scope_page_canonical runs scope="all" with a cleanup that
marks its output, then a scope="flagged" run, and asserts the out-of-scope pass page's
canonical markdown, source and composite are untouched. Verified red before the fix:

 x  test_flagged_run_keeps_an_out_of_scope_page_canonical
AssertionError: '# Wi[53 chars]tive text page with plenty of selectable text. \n\n' != '# Wi[53 chars]tive text page with plenty of selectable text. \n\n\n\nCLEANED'
Ran 6 tests in 10.929s
FAILED (failures=1)

Full suite with the fix (bench --site wikify.localhost run-tests --app wikify):

 x  test_renders_with_wiki_renderer
 FAIL  test_renders_with_wiki_renderer (wikify.tests.test_wiki_preview.TestWikiPreview.test_renders_with_wiki_renderer)
AssertionError: '<pre class="mermaid">' not found in ...
Ran 182 tests in 59.295s
FAILED (failures=1)

test_renders_with_wiki_renderer also fails on main (the installed wiki app no longer emits
<pre class="mermaid">); it is unrelated to this change. Everything else passes.

🤖 Generated with Claude Code

https://claude.ai/code/session_0126A9jCM6LTxnmCPH3hWbTR

…ged run

`remediate_pdf` seeded canonical markdown from the raw baseline for *every*
page and then wrote canonical back for every page, so a `scope="flagged"` run
(the default of `trigger_remediation`) reverted every already-remediated
`pass` page to its baseline, discarding the adopted cleanup/VLM output.

Pages outside the scope now keep the canonical markdown, composite and
provenance they already carry; `scope="all"` is unchanged.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0126A9jCM6LTxnmCPH3hWbTR
@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown

Greptile Summary

This PR preserves the existing canonical Markdown, score, and provenance of pages outside a scoped remediation run and changes the adopted count to include only adoptions from the current run.

  • Adds scope-aware canonical seeding.
  • Extends page retrieval with canonical fields.
  • Adds a regression test for preserving a non-table passing page.
  • Leaves out-of-scope pages exposed to mutation by the all-page table-stitching pass.

Confidence Score: 4/5

The PR should not merge until flagged remediation also prevents table stitching from rewriting out-of-scope pages.

A passing page adjacent to a targeted page can have its accepted canonical table content merged or stripped because stitching and canonical write-back still operate over every page.

Files Needing Attention: wikify/engine/remediate.py, wikify/tests/test_remediate_pipeline.py

Important Files Changed

Filename Overview
wikify/engine/remediate.py Adds scope-aware canonical seeding and per-run adoption counting, but all-page table stitching can still rewrite out-of-scope canonical content.
wikify/engine/store.py Extends the remediation page query with the canonical fields required by the new seeding behavior.
wikify/tests/test_remediate_pipeline.py Covers preservation of a non-table passing page but does not cover cross-scope table stitching.

Fix all with Greploop Fix All in Claude Code Fix All in Codex

Prompt To Fix All With AI
### Issue 1
wikify/engine/remediate.py:102-103
**Stitching rewrites preserved pages**

When a passing page and an adjacent remediation target contain compatible cross-page tables, the all-page stitching pass mutates both pages and writes both results back, causing the out-of-scope page's accepted canonical table content to be merged or stripped.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(remediate): keep out-of-scope pages'..." | Re-trigger Greptile

Comment on lines +102 to +103
canon_src: dict[int, str] = {}
for p in pages:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Stitching rewrites preserved pages

When a passing page and an adjacent remediation target contain compatible cross-page tables, the all-page stitching pass mutates both pages and writes both results back, causing the out-of-scope page's accepted canonical table content to be merged or stripped.

Knowledge Base Used: Remediation and verification

Prompt To Fix With AI
This is a comment left during a code review.
Path: wikify/engine/remediate.py
Line: 102-103

Comment:
**Stitching rewrites preserved pages**

When a passing page and an adjacent remediation target contain compatible cross-page tables, the all-page stitching pass mutates both pages and writes both results back, causing the out-of-scope page's accepted canonical table content to be merged or stripped.

**Knowledge Base Used:** [Remediation and verification](https://app.greptile.com/bwh-tech/-/custom-context/knowledge-base/bwhtech/wikify/-/docs/remediation-and-verification.md)

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Fix in Claude Code Fix in Codex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant