evidence-anchor/workplans/EANCH-WP-0002-anchor-resolution-hardening.md
tegwick 0871f79d2d EANCH-WP-0001 T06: register post-extraction gaps as follow-on workplans
Draft two proposed workplans instead of expanding this slice:
- EANCH-WP-0002 anchor-resolution-hardening (stale/orphan, fuzzy re-anchoring,
  promote PdfSpikeViewer to a production PDFViewerAdapter)
- EANCH-WP-0003 non-pdf-selectors (HTML/Markdown DomRange+Structural, non-PDF
  viewer adapter; starts with a citation-engine shared-type contract change)
Add an explicit gap map to WP-0001 T06. fix-consistency (C-06) will register
both in the hub during T07.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-08 21:11:24 +02:00

114 lines
3.7 KiB
Markdown

---
id: EANCH-WP-0002
type: workplan
title: "Anchor resolution hardening: stale/orphan semantics, fuzzy re-anchoring, production PDF adapter"
domain: infotech
repo: evidence-anchor
status: proposed
owner: codex
topic_slug: citation_evidence_mvp
created: "2026-07-08"
updated: "2026-07-08"
spec_refs:
- INTENT.md
- SCOPE.md
- ../citation-evidence/wiki/SharedContracts.md
- ../citation-evidence/wiki/ArchitectureOverview.md
---
# EANCH-WP-0002 — Anchor Resolution Hardening
## Goal
Close the resolution-quality gaps left open by the MVP extraction
(`EANCH-WP-0001`) on the **existing PDF/text path**. The extracted slice
resolves exact position/quote/PDF selectors with a fixed confidence ladder and
returns `resolved | ambiguous | unresolved`. `INTENT.md` promises more:
`stale` detection, orphaned-annotation handling, fuzzy/recovery re-anchoring,
and human-confirmation workflows for ambiguity. This workplan makes those real
without changing the shared selector *types* (those stay in `citation-engine`).
Non-goals: HTML/Markdown selectors (see `EANCH-WP-0003`); new persistence or
UI shell behavior.
## Background
Current extracted behavior (`src/selectors/resolve.ts`):
- confidence ladder 1.00 → 0.70 across TextPosition/TextQuote/PdfPageText/PdfRect
- multiple undisambiguated quote matches → `ambiguous` at 0.5
- nothing matches → `unresolved` at 0.0
- there is **no** `stale` path (the `AnnotationResolutionStatus` enum includes
`stale`, but resolve.ts never returns it) and **no** fuzzy matching
## Task Breakdown
## T01 — Stale vs. unresolved: distinguish "representation changed" from "never found"
```task
id: EANCH-WP-0002-T01
status: todo
priority: high
```
Return `stale` (not `unresolved`) when a previously-resolvable anchor no longer
matches because the representation's canonical text changed, while the stored
quote is still meaningful. Define the signal (e.g. position selector points
in-range but slice ≠ quote AND quote no longer found) and preserve the original
quote/context on the result. Add unit tests covering stale vs. unresolved.
## T02 — Orphaned-annotation detection surface
```task
id: EANCH-WP-0002-T02
status: todo
priority: medium
depends_on: [T01]
```
Give callers a way to identify annotations whose selectors can no longer be
placed at all (orphaned) versus stale-but-recoverable. Decide whether this is a
distinct status, a flag on `AnchorResolution`, or a helper. Keep the shared
enum unchanged unless a contract change is agreed in the umbrella wiki first.
## T03 — Fuzzy / recovery re-anchoring
```task
id: EANCH-WP-0002-T03
status: todo
priority: high
depends_on: [T01]
```
Add a fuzzy quote-matching fallback (bounded edit-distance / token overlap)
below the exact ladder, returning candidates at appropriately low confidence
with `ambiguous`/`stale` status. Must never silently emit a confident wrong
match (INTENT: "No Silent Misleading Match"). Add tests with lightly-edited
source text. Confirm the ladder's exact tiers are untouched above the fuzzy
floor.
## T04 — Promote the PDF spike to a production adapter
```task
id: EANCH-WP-0002-T04
status: todo
priority: medium
depends_on: [T03]
```
Turn `PdfSpikeViewer` into a supported `PDFViewerAdapter` that implements the
`DocumentViewerAdapter` contract cleanly (remove spike-only debug flags from the
public surface, or gate them), keep viewer libs behind `src/pdf/`, and keep the
umbrella green through the change. Update `evidence-anchor/pdf` exports and docs.
## T05 — Verification + close-out
```task
id: EANCH-WP-0002-T05
status: todo
priority: high
depends_on: [T02, T04]
```
`pnpm test`/`typecheck`/`lint` green here; umbrella typecheck/test/build green
after any contract-visible change; `fix-consistency` clean; progress note.