Add ingestHtml and ingestMarkdown with ADR-0003 pageless offset semantics, PDF intrinsic metadata extraction with caller-wins merge (WP-0003), and citation recovery primitives including re-ingest reconcile, local quote search, and pluggable discovery hooks (ADR-0004). Mark all three workplans finished with contract tests (80 passing).
54 lines
No EOL
2.1 KiB
Markdown
54 lines
No EOL
2.1 KiB
Markdown
# ADR-0004 — Citation recovery boundary
|
|
|
|
- **Status:** accepted
|
|
- **Date:** 2026-07-09
|
|
- **Workplan:** ESRC-WP-0004 (T01)
|
|
|
|
## Context
|
|
|
|
`evidence-source` owns ingestion and representation generation. Citation
|
|
recovery spans stale-selector detection, local quote search, external source
|
|
discovery, and human confirmation — but selector resolution algorithms live in
|
|
`evidence-anchor`, and the `CitationRecoveryAttempt` type vocabulary lives in
|
|
`citation-engine`.
|
|
|
|
## Decision
|
|
|
|
### Owned by `evidence-source`
|
|
|
|
| Capability | Module | Notes |
|
|
| ---------- | ------ | ----- |
|
|
| Re-ingest + re-fingerprint | `src/recovery/re-ingest.ts` | Compare prior vs. fresh `Document.fingerprint`; flag `requiresReanchor` |
|
|
| Local canonical quote search | `src/recovery/local-search.ts` | Search `DocumentRepresentation.canonicalText` |
|
|
| Recovery attempt scaffold | `src/recovery/attempt.ts` | Local record using SharedContracts state vocabulary |
|
|
| Discovery hook interface | `src/recovery/discovery.ts` | Pluggable providers; **no network in core** |
|
|
|
|
### Owned elsewhere
|
|
|
|
| Capability | Owner |
|
|
| ---------- | ----- |
|
|
| Stale selector detection / resolution order | `evidence-anchor` |
|
|
| `CitationRecoveryAttempt` canonical type | `citation-engine` (future) |
|
|
| Human confirmation UX | `citation-work` / umbrella |
|
|
| External HTTP/API lookup implementations | Deployment-specific providers registered on the hook |
|
|
|
|
### Recovery flow
|
|
|
|
```text
|
|
CitationClue
|
|
→ createRecoveryAttempt (evidence-source)
|
|
→ local library search via searchCanonicalQuote (evidence-source)
|
|
→ optional SourceDiscoveryHook providers (registered by host)
|
|
→ reIngestAndCompare when fresh bytes arrive (evidence-source)
|
|
→ anchor layer re-resolves selectors when requiresReanchor is true
|
|
```
|
|
|
|
`evidence-source` **does not** decide whether a selector is stale. It supplies
|
|
primitives the anchor layer calls after it detects mismatch.
|
|
|
|
## Consequences
|
|
|
|
- No network coupling in the recovery core.
|
|
- Host apps register discovery providers explicitly (local-first default).
|
|
- Recovery state enum mirrors `wiki/SharedContracts.md` §2.6 locally until the
|
|
engine exports a shared `CitationRecoveryAttempt` type. |