Retain verified original file receipts through scoped adapters

SI
13d ago
+637-0

Original files need a retained source/version receipt without letting callers assert a digest or turning a save into accepted analysis. This adds unused server register/read adapters: registration verifies private bytes and workspace access first, calls the real allowed Database #94 transaction, and validates returned scope and byte metadata. Lost replies and malformed post-write receipts retain the original recovery identity as uncertain; the adapter never retries automatically.

Depends on API #986 and Database #94, both separately awaiting approval. This branch includes the reviewed #986 commits; refresh main after that release to remove dependency overlap. No endpoint, MCP action, upload, signed read, provider call, charge or customer intake is connected. Immutable bounded acquisition, staging/orphan handling and current-access original retrieval remain required.

Validation: 25 new real-adapter tests plus 18 verifier/storage tests pass; full lint, scoped TypeScript, formatting and diff checks pass. New suites failed for missing modules before implementation. Synthetic boundaries only, no production operations. See lib/context/originals/ORIGINAL-REGISTRATION.md for recovery and acquisition limits.

Part of recoupable/app#2116 and recoupable/app#2140.


Summary by cubic

Adds unused server adapters that retain verified private original files through scoped registration/read calls without letting callers assert a digest or turning a save into accepted analysis.

  • verifyContextOriginal authorizes current workspace access before and after reading private bytes, derives SHA-256 and size from the stored file, preserves context-private as the verified bucket, normalizes UUIDs to lowercase, and rejects empty, oversized, foreign, or malformed keys before any scope check or read.
  • Legacy .pdf/.csv keys enforce their suffix-selected type; neutral .original keys derive the type from the actual bytes. The verifier accepts no declared type, and the download utility does not authorize callers on its own.
  • registerContextOriginal calls register_context_original after verification and rejects mismatched receipt scope or byte metadata; callContextRpc allowlists both new RPCs.
  • readContextOriginalRegistration returns metadata only after re-authorizing current access; SQL stays authoritative for withdrawal and exact-key replay.
  • Lost replies, storage errors after dispatch, and malformed post-write receipts throw ContextOriginalNeedsReconciliation carrying the original owner/source/retry key; the adapter never retries automatically.
  • Recovery identity fields are non-enumerable and immutable, so generic serialization never discloses them. A future coordinator must reconcile using the same identity and never report a confirmed failed save.
  • No endpoint, MCP action, upload, signed read, provider call, charge, or customer intake is connected.
  • Depends on API #986 and Database #94; the branch includes the reviewed #986 commits, so refresh main after that release to drop the overlap.