# attribution: surface session fallback and unreadable session metadata

`cf66e7a`→[main](/content/gh/entireio/cli/commits/main/index.html)·
  
Soph·1mo ago·2 files·+66 added/-0 removed

Two silent-degradation paths in readCheckpointContext gave the user false
confidence:

- When a blamed file matched none of a checkpoint's sessions (e.g. it was
renamed after the checkpoint), session selection silently fell back to the
first session and presented its agent/prompt as exact. Track whether the
match was by file, and when it was a multi-session fallback set a new
SessionFallback flag; `entire why` now prints a "may have been renamed" hint.

- When a checkpoint's sessions all failed to read (summary present, per-session
metadata unreadable), the line kept a confident [AI] tag with blank
agent/model/prompt and no indication. Set MetadataMissing in that case so the
existing "trailer-level attribution only" hint shows and the why path retries
via remote fetch.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

## Sessions

7f9d62c609b2View transcript

## Changes

2

- cmd/entire/cli

- Mattribution.go+30

- Mattribution_test.go+36

```
    65 unmodified lines
    ```

```go
package attribution

type fileAttributionResult struct {
    Lines []lineAttribution `json:"lines"`
}

type lineAttribution struct {
    Prompt          string                 `json:"prompt,omitempty"`
    Intent          string                 `json:"intent,omitempty"`
    MetadataMissing bool                   `json:"metadata_missing,omitempty"`
    SessionFallback bool                   `json:"session_fallback,omitempty"`
    Content         string                 `json:"content"`
    Candidates      []attributionCandidate `json:"candidates,omitempty"`
}
```

## Tests

### TestAttributionFlagsSessionFallbackForUnmatchedFile
```go
func TestAttributionFlagsSessionFallbackForUnmatchedFile(t *testing.T) {
    repoRoot := newAttributionRepo(t)
    writeAttributionCheckpoint(t, repoRoot, "aab2c3d4e5f6", checkpoint.WriteCommittedOptions{
        SessionID:        "session-one-12345678",
        Prompts:          []string{"Edit the first file."},
        FilesTouched:     []string{"old_name.py"},
        Agent:            agent.AgentTypeClaudeCode,
        CheckpointsCount: 1,
    })
}
```

### TestRunGitBlameWrapsExecError
```go
func TestRunGitBlameWrapsExecError(t *testing.T) {
    repoRoot := newAttributionRepo(t)
}
```
