Make entire why deterministic across clones and surface actionable checkpoint-metadata miss reasons#1
Make entire why deterministic across clones and surface actionable checkpoint-metadata miss reasons#1karthik-rameshkumar with Copilot wants to merge 3 commits into
entire why deterministic across clones and surface actionable checkpoint-metadata miss reasons#1Conversation
entire why deterministic across clones and surface actionable checkpoint-metadata miss reasons
There was a problem hiding this comment.
Pull request overview
This PR makes the entire why attribution path deterministic when checkpoint metadata is missing and surfaces concrete, actionable reasons instead of a generic "metadata missing" marker. It aligns entire why <file> with the line-level enrichment path (remote fetch-on-miss) while keeping entire blame local-only, and threads a new MetadataMissingReason through the line output, checkpoint context, human-readable renderers, and JSON.
Changes:
runAttributionWhynow resolves file attribution withfetchOnMiss=true, and a newmetadataMissingReason(...)helper builds a recovery hint (git fetch …+entire checkpoint explain <id>).- Added
MetadataMissingReasontoattributionLineandattributionCheckpointContext, propagated through candidate/preferred/render/JSON paths, and preserved the fetch-failure cause instead of swallowing it. - Added focused tests covering missing-metadata reasons (line/file, human/JSON), the successful local path, fetch-failure surfacing, and checkpoint-map stability across successive calls.
Show a summary per file
| File | Description |
|---|---|
| cmd/entire/cli/attribution.go | Adds MetadataMissingReason fields/helper, switches why to fetch-on-miss, preserves fetch-error cause, and renders the reason in text/JSON. |
| cmd/entire/cli/attribution_test.go | Adds tests for missing-metadata reasons, local-metadata path, fetch-failure surfacing, and checkpoint-map determinism. |
Notable review findings:
readCheckpointContextuses anelseafter areturn, whichrevive(superfluous-else/indent-error-flow, enabled by default) will flag and failmise run lint.TestAttributionResolverMissingMetadataIncludesReasonruns withfetchOnMiss=truewithout an isolated repo, so it opens the real checkout and performs a realgit fetch, violating test-isolation conventions and introducing network flakiness.- With
resolveFileAttribution(fetchOnMiss=true), the subsequentenrichAttributionLineWithFetchon thewhy <file>:<line>path becomes a redundant second remote fetch in the miss case.
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 3
- Review effort level: Medium
| resolver := &attributionResolver{ | ||
| ctx: context.Background(), | ||
| store: stubReader, | ||
| fetchOnMiss: true, | ||
| checkpointCache: make(map[string]attributionCheckpointContext), | ||
| } | ||
|
|
||
| ctx := resolver.readCheckpointContext(cpID, "auth.py") |
| if selected.MetadataMissing && selected.CheckpointID != "" { | ||
| if err := enrichAttributionLineWithFetch(ctx, result.File, selected, result.Checkpoints); err != nil { | ||
| // Remote metadata enrichment is best-effort; the trailer-level | ||
| // explanation is still useful and should remain available. | ||
| selected.MetadataMissing = true | ||
| selected.MetadataMissingReason = metadataMissingReason(ctx, selected.CheckpointID, err) | ||
| } | ||
| } |
|
do you mean to have this PR opened in the https://github.com/entireio/cli repository |
…sing; refine session-fallback caveat Addresses review feedback on entireio#1535. Karthik's report (community Discord + karthik-rameshkumar#1): `entire why` on a line whose checkpoint metadata is missing printed "Full context: entire checkpoint explain <id>", but running that command fails identically ("no checkpoint or commit found matching <id>") because the same remote fetch `why` attempts has already failed. The hint pointed at a command that immediately errors. - Resolve metadata-missing during attribution (resolveFileAttribution with fetchOnMiss) and record a MetadataMissingReason that states the cause and the actionable remedy: `git fetch <remote> entire/checkpoints/v1:...`, then re-run `entire checkpoint explain <id>`. Surfaced in the line and file `why` views and in JSON. Also drops the separate post-resolution enrich step, which left the checkpoint map non-deterministic across calls. (Mechanism and tests adapted from Karthik's PR.) - Suppress the bare "Full context: entire checkpoint explain <id>" hint when metadata is missing: it would fail the same way, and the reason line above now gives the fetch-then-explain sequence. - Refine the session-fallback caveat (Soph's review): flag the multi-session fallback whose chosen session has empty FilesTouched (one of several sessions, no path evidence) via `sessionsRead > 1 || len(FilesTouched) > 0`, while still suppressing the single-session empty-paths false positive. Tests for both. Co-authored-by: karthik-rameshkumar <6728802+karthik-rameshkumar@users.noreply.github.com>
|
Thanks for this @karthik-rameshkumar — solid diagnosis and a better fix than just hiding the hint. I've folded your One small addition on top of your change: I also suppress the bare |
…sing; refine session-fallback caveat Addresses review feedback on entireio#1535. Karthik's report (community Discord + karthik-rameshkumar#1): `entire why` on a line whose checkpoint metadata is missing printed "Full context: entire checkpoint explain <id>", but running that command fails identically ("no checkpoint or commit found matching <id>") because the same remote fetch `why` attempts has already failed. The hint pointed at a command that immediately errors. - Resolve metadata-missing during attribution (resolveFileAttribution with fetchOnMiss) and record a MetadataMissingReason that states the cause and the actionable remedy: `git fetch <remote> entire/checkpoints/v1:...`, then re-run `entire checkpoint explain <id>`. Surfaced in the line and file `why` views and in JSON. Also drops the separate post-resolution enrich step, which left the checkpoint map non-deterministic across calls. (Mechanism and tests adapted from Karthik's PR.) - Suppress the bare "Full context: entire checkpoint explain <id>" hint when metadata is missing: it would fail the same way, and the reason line above now gives the fetch-then-explain sequence. - Refine the session-fallback caveat (Soph's review): flag the multi-session fallback whose chosen session has empty FilesTouched (one of several sessions, no path evidence) via `sessionsRead > 1 || len(FilesTouched) > 0`, while still suppressing the single-session empty-paths false positive. Tests for both. Co-authored-by: karthik-rameshkumar <6728802+karthik-rameshkumar@users.noreply.github.com>
entire whycould produce divergent outputs for identical repos when checkpoint metadata was missing, and fetch failures during enrichment were being hidden behind generic “metadata missing” output. This change makes the behavior deterministic and exposes concrete, actionable miss reasons in both text and JSON output.Why-path metadata resolution parity
runAttributionWhynow resolves file attribution withfetchOnMiss=true, so file-levelentire why <file>follows the same enrichment path as line-level explain behavior.entire blameremains local-only/fast.Structured missing-metadata reason propagation
MetadataMissingReasonto:attributionLine(line output / JSON)attributionCheckpointContext(checkpoint map / JSON)suggestCheckpointFetchCommand(...), followed byentire checkpoint explain <id>guidance.Fetch-error path no longer swallowed
Determinism and regression coverage
MetadataMissingReason == ""),Checkpointsmap across successiveentire whycalls in the same process.