old current extraction + pinned anchors
→ project the new extraction pages
→ exact text occurs once: mapped (confidence 1.0)
→ exact text absent or repeated: unresolved (reason recorded)
→ persist one outcome per old pinned anchor
→ mark downstream artifacts stale
→ atomically make the new extraction current
| Surface | Rule |
|---|---|
documents.document_versions |
Append-only rendition history with a server-derived storage key, converter identity/version, and an authenticated matters:write actor required for every re-conversion after version 1. |
documents.extraction_versions.document_version_id |
Pins each extraction to the exact Original or converted rendition it observed. |
documents.anchor_remaps |
Append-only mapped, unresolved, or retired outcomes. Automated migration treats every old anchor as pinned, so it emits only mapped or unresolved. |
test_er11_pin_never_moves_silently proves unique text maps across pages while duplicated and missing text stay unresolved, with exactly one outcome per pin.test_er33_reconversion_migrates_every_pin proves normal render redelivery does not re-convert, while an explicit counsel action mints converter version 2 and runs the same complete pin migration.test_reconversion_requires_write_permission_and_matter_rls proves a read-only or unassigned actor cannot reserve or read a version.test_failed_reconversion_retry_mints_next_version_with_derived_key proves a failed version 2 leaves version 1 current and a retry safely mints version 3 at a server-derived key.test_persistence_uses_one_json_bind_for_1821_anchors proves a large ledger stays one bounded SQL operation.A pin never guesses. One exact destination earns a mapped row; every unsafe case stays unresolved and visible.