docs(storage): incorporate upload-session consistency model (#102)

What

Incorporates the strict crash-recovery model from work item #102 (closed) into the S06 storage-layer spec, replacing the optimistic "self-heal on offset divergence" prose with a terminate-on-divergence contract.

  • upload_sessions.dirty poison-bit column; StorageDriver.Exists probe; Writer(offset>0) offset-mismatch guard; FileWriter flush errors as terminal *PartialFlushError.
  • New typed errors: OffsetDivergenceError, PartialFlushError, ErrSessionFinalizeOnly, ErrSessionUnrecoverable.
  • ResumeSession recovery branches (normal / offset-divergence / finalize-only / DB-finalize-only / unrecoverable), keyed off Writer(PathNotFound) + Exists(staging/dest) probes; CAS on size_bytes; Close flushes then persists (DB never ahead of the backend); commit-time dirty re-read; terminal-vs-recoverable Commit taxonomy.
  • New "Consistency & Crash-Recovery Model" section: flush lifecycle, 12 cross-cutting invariants, canonical cleanup, dirty poison-pill, and the full A/B/D/G failure scenario catalog.
  • Acceptance criteria, observability (upload_session_dirty_discard_total metric + outcome enums), error cases, testing, and resolutions updated.
  • Refreshes the storage-layer plan's offset-divergence test note to point at the S06 model and catalog.

Consumer-spec mapping (S12 OCI, S10 Maven) deferred to a follow-up.

Notes for reviewers

  • Docs-only change (no Go). The failure scenario catalog (Groups A/B/D/G) is the conformance/integration test target for the follow-on implementation plan.
  • The dirty poison-pill is explicitly defense-in-depth, not airtight: the dirty-read and Move are not atomic, leaving a narrow B1 silent-corruption window on the content-addressed path. Closing it fully needs a durable-byte verify (streamed CRC vs native object checksum), scoped out here. Reachable only by a client that violates the OCI sequential-chunk contract with concurrent writes to one upload_id. Flagging for explicit acceptance for MVP given cross-format dedup fan-out.
  • Diff is ~742 lines but is a single cohesive consistency model + scenario catalog that does not split cleanly.

Closes #102 (closed).

🤖 Generated with Claude Code

Merge request reports

Loading
Loading