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).
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_oidfor correct cross-line state) as alater upgrade.
That deferred upgrade is doubly gated today:
Option(src/model/file.rs,src/git/raw.rs): the defaultworktree review carries
new_oid = None, added files carryold_oid = None, and syntheticuntracked files carry both
None— so whole sides have no blob to fetch even in principle.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:
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.
new_oid = None) gets its artifact identity from the contenthash of the captured bytes, consistent with how the snapshot itself is content-addressed.
What this unlocks
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.
can be verified against the captured full file instead of being unverifiable by construction.
state, not the live buffer's).
Considerations
capture flag (and/or a size cap per file) rather than a silent default. Binary files are
excluded outright.
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.
artifact; the old side of a commit-range capture is the blob bytes).
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).