Skip to content

capture: optional full-file artifacts (old/new sides) alongside the hunk snapshot #479

Description

@kevinswiber

Context

The captured snapshot artifact stores hunks only — context/added/removed rows plus blob
OIDs — never full file contents. ADR-0025 §D5 chose per-hunk, side-separated highlight streams
as the correctness default and explicitly deferred option (a), blob-backed whole-file
highlighting
(fetch full blobs via old_oid/new_oid for correct cross-line state) as a
later upgrade.

That deferred upgrade is doubly gated today:

  • OID presence. Both oids are Option (src/model/file.rs, src/git/raw.rs): the default
    worktree review carries new_oid = None, added files carry old_oid = None, and synthetic
    untracked files carry both None — so whole sides have no blob to fetch even in principle.
  • Git object availability. Even a present oid only helps while the git object store is
    reachable and retains the object. The review record is supposed to outlive that: copied
    stores, store-only reading (no repo context), and gc'd objects all lose blob access while the
    captured record itself remains renderable.

The same gap surfaces beyond highlighting: any consumer that wants to validate or render
content outside the captured hunk rows (line-anchor drift checks, expanded context around a
hunk) has nothing to compare against, because out-of-hunk bytes were never captured.

Proposal

At capture time, optionally record full-file artifacts for the old and new sides of each
changed file, alongside (not replacing) the hunk snapshot:

  • The captured git diff remains the authoritative record of the revision — when git is the
    source, the actual diff is what was reviewed, and that does not change. Full files are
    supplementary, content-addressed artifacts in the existing artifact layer.
  • Worktree-side content (where new_oid = None) gets its artifact identity from the content
    hash of the captured bytes, consistent with how the snapshot itself is content-addressed.
  • Sides that have no meaningful content (deleted new side, added old side) record nothing.

What this unlocks

  • ADR-0025 §D5 option (a) — whole-file syntax highlighting with correct cross-line state —
    for every side captured with an artifact, independent of git object availability, and
    including the worktree/added/synthetic cases that have no oid at all. Every side without an
    artifact keeps the option-(b) side-stream fallback, unchanged.
  • Honest out-of-hunk validation. Anchors or selections that fall outside captured hunk rows
    can be verified against the captured full file instead of being unverifiable by construction.
  • Expanded-context rendering in review surfaces (showing surrounding lines of the reviewed
    state, not the live buffer's).

Considerations

  • Opt-in vs default, and size policy. Full files multiply capture size; likely an explicit
    capture flag (and/or a size cap per file) rather than a silent default. Binary files are
    excluded outright.
  • Existing capture policies apply unchanged: generated-file exclusions and sensitivity
    policy govern full-file artifacts exactly as they govern hunk content — a full file must
    never leak content the hunk-level policies would have excluded.
  • Dedup comes free from content addressing (unchanged sides across revisions share one
    artifact; the old side of a commit-range capture is the blob bytes).
  • Readback shape: full-file artifacts would ride the same artifact readback lane as the
    snapshot, as an additive document/field — no change to existing snapshot consumers.

Refs: ADR-0025 §D5 (docs/adr/adr-0025-read-time-diff-syntax-highlighting.md).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions