docs: update sessions-and-checkpoints for the persistent/ephemeral split · Entire
docs: update sessions-and-checkpoints for the persistent/ephemeral split
a267dd8→main·
Soph·3w ago·2 files·+47 added/-51 removed
Rewrite the checkpoint storage interface section for the two-store facade (Stores.Persistent / Stores.Ephemeral()), the generic Read/Write/List surface, and the Write request unions. Update the Type enum, tables, and the CLAUDE.md one-liner to the persistent/ephemeral vocabulary.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
6ae608e3158bView transcript
[?
Review Checkpoint Commit f16b7101Codex·GPT-5.5·1 step](/content/gh/entireio/cli/session/019eefbd-bb6a-7f51-a909-feb4cd95588d#timeline-6ae608e3158b/index.html)
Changes
2
MCLAUDE.md+1/-1
docs/architecture
Msessions-and-checkpoints.md+46/-50
14 unmodified lines
15
16
17
18
18
19
20
21
14 unmodified lines
- `entire/cli/commands`: actual command implementations
- `entire/cli/agent`: agent implementations (Claude Code, Gemini CLI, OpenCode, Cursor, Factory AI Droid, Copilot CLI, Pi) - see [Agent Integration Checklist](docs/architecture/agent-integration-checklist.md) and [Agent Implementation Guide](docs/architecture/agent-guide.md)
- `entire/cli/strategy`: strategy implementation (manual-commit) - see section below
- `entire/cli/checkpoint`: checkpoint storage abstractions (temporary and committed)
- `entire/cli/checkpoint`: checkpoint storage abstractions (ephemeral and persistent)
- `entire/cli/session`: session state management
- `entire/cli/integration_test`: integration tests (simulated hooks)
- `e2e/`: E2E tests with real agent calls (see [e2e/README.md](e2e/README.md))
MCLAUDE.md+1/-1
41 unmodified lines
42
43
44
45
46
45
46
47
48
49
50
51
52
53
52
53
54
55
56
2 unmodified lines
59
60
61
62
63
64
62
63
64
65
66
67
68
68
69
70
71
72
73
74
75
76
77
78
79
71
72
73
74
75
80
81
82
83
84
85
86
87
77
78
79
80
81
82
83
88
89
90
91
92
93
94
95
87
96
97
98
99
90
91
92
93
94
95
96
97
98
99
100
101
100
101
102
103
103
104
105
106
107
108
109
110
111
112
113
114
104
105
106
107
117
108
109
110
111
112
113
114
115
116
26 unmodified lines
143
144
145
150
151
146
147
148
149
150
43 unmodified lines
194
195
196
201
197
198
199
200
32 unmodified lines
233
234
235
240
236
237
238
239
41 unmodified lines
type Type int
const (
Temporary Type = iota // Full state snapshot, shadow branch
Committed // Metadata + commit ref, entire/checkpoints/v1
Ephemeral Type = iota // Full state snapshot, shadow branch
Persistent // Metadata + commit ref, entire/checkpoints/v1
)
| Type | Contents | Use Case |
|------|----------|----------|
| Temporary | Full state (code + metadata) | Intra-session rewind, pre-commit |
| Committed | Metadata + commit reference | Permanent record, post-commit rewind |
| Ephemeral | Full state (code + metadata) | Intra-session rewind, pre-commit |
| Persistent | Metadata + commit reference | Permanent record, post-commit rewind |
## Interface
2 unmodified lines
`strategy/session.go` keeps the `Session` and `Checkpoint` data types used by
status/explain formatting. Active session state is read from `.git/entire-sessions/`
through `session.StateStore`; committed checkpoint/session content is read
through a `checkpoint.GitStore` built with resolved committed refs (for example,
`checkpoint.NewGitStore(repo, checkpoint.ResolveCommittedRefs(ctx))`) and
command-specific strategy methods such as `GetSessionInfo`.
through the checkpoint facade (`checkpoint.Open(ctx, repo, opts)`, which resolves
the ref topology and wires the blob fetcher) and command-specific strategy
methods such as `GetSessionInfo`.
### Checkpoint Storage (Low-Level)
The `checkpoint.Store` interface (from `checkpoint/checkpoint.go`) provides primitives for reading/writing checkpoints. Used by strategies.
`checkpoint.Open` returns a `*Stores` facade exposing two independent stores,
split by lifecycle:
- `stores.Persistent` — the permanent record on `entire/checkpoints/v1`
(a `PersistentStore`). This is the pluggable surface.
- `stores.Ephemeral()` — the git-only shadow-branch store for intra-session
state (an `EphemeralStore`).
Both present a symmetric generic surface — `Read` (differentiated by return
type), `Write` (a sealed request union), and `List`:
```go
type Store interface {
// Temporary checkpoint operations (shadow branches - full state)
WriteTemporary(ctx context.Context, opts WriteTemporaryOptions) (WriteTemporaryResult, error)
ReadTemporary(ctx context.Context, baseCommit, worktreeID string) (*ReadTemporaryResult, error)
ListTemporary(ctx context.Context) ([]TemporaryInfo, error)
type PersistentStore interface {
Read(ctx, checkpointID id.CheckpointID) (*CheckpointSummary, error)
List(ctx) ([]CheckpointInfo, error)
ReadSessionContent(ctx, checkpointID id.CheckpointID, sessionIndex int) (*SessionContent, error)
Write(ctx, req WriteRequest) error // WriteSession / BackfillTranscript / BackfillSummary / BackfillAttribution
// ...session reads
}
// Committed checkpoint operations (metadata only)
// Writes target v1. Reads use the configured committed-read ref.
WriteCommitted(ctx context.Context, opts WriteCommittedOptions) error
ReadCommitted(ctx context.Context, checkpointID id.CheckpointID) (*CheckpointSummary, error)
ReadSessionContent(ctx context.Context, checkpointID id.CheckpointID, sessionIndex int) (*SessionContent, error)
ReadSessionContentByID(ctx context.Context, checkpointID id.CheckpointID, sessionID string) (*SessionContent, error)
ListCommitted(ctx context.Context) ([]CommittedInfo, error)
type EphemeralStore interface {
Read(ctx, baseCommit, worktreeID string) (*ReadEphemeralResult, error)
List(ctx) ([]EphemeralInfo, error)
Write(ctx, req EphemeralWriteRequest) (WriteEphemeralResult, error) // WriteCheckpoint / WriteTask
// ...shadow-branch queries
}
```
Key option types (abbreviated):
Writes go through the request unions rather than per-operation methods, so a
mirror/fan-out store just forwards the request value:
```go
type WriteTemporaryOptions struct {
SessionID string
BaseCommit string
WorktreeID string // Internal git worktree identifier (empty for main)
ModifiedFiles []string
NewFiles []string
DeletedFiles []string
MetadataDir string // Relative path to metadata directory
MetadataDirAbs string // Absolute path
CommitMessage string
// ...
}
// Persistent: condensation, stop-time backfill, async summary, attribution
stores.Persistent.Write(ctx, checkpoint.WriteSession{CheckpointID: id, /* ... */})
stores.Persistent.Write(ctx, checkpoint.BackfillSummary{CheckpointID: id, Summary: s})
type WriteCommittedOptions struct {
CheckpointID id.CheckpointID
SessionID string
Strategy string
Branch string
Transcript []byte
Prompts []string
Context []byte
FilesTouched []string
TokenUsage *agent.TokenUsage
// ...
}
// Ephemeral: shadow-branch capture / task checkpoints
res, _ := stores.Ephemeral().Write(ctx, checkpoint.WriteCheckpoint{BaseCommit: base, /* ... */})
```
Token usage is defined in `agent/types.go`:
`WriteSession`/`BackfillTranscript` are defined types over the option structs
(`WriteOptions`/`UpdateOptions`); `WriteCheckpoint`/`WriteTask` over
`WriteEphemeralOptions`/`WriteEphemeralTaskOptions`.
Token usage and skill events live in the leaf `agent/types` package (so the
contract doesn't pull in the full `agent` package):
```go
type TokenUsage struct {
26 unmodified lines
| Type | Location | Contents |
|------|----------|----------|
| Session State | `.git/entire-sessions/<id>.json` | Active session tracking |
| Temporary | `entire/<commit[:7]>-<worktreeHash[:6]>` branch | Full state (code + metadata) |
| Committed | `entire/checkpoints/v1` branch (sharded) | Metadata + commit reference |
| Ephemeral | `entire/<commit[:7]>-<worktreeHash[:6]>` branch | Full state (code + metadata) |
| Persistent | `entire/checkpoints/v1` branch (sharded) | Metadata + commit reference |
|
### Session State
43 unmodified lines
<id[:2]>/<id[2:]>/
├── metadata.json # CheckpointSummary (aggregated stats)
├── 0/ # First session (0-based indexing)
│ ├── metadata.json # Session-specific CommittedMetadata
│ ├── metadata.json # Session-specific Metadata
│ ├── full.jsonl
│ ├── prompt.txt # Checkpoint-scoped user prompts
│ └── content_hash.txt
32 unmodified lines
`checkpoints_count` in the root summary is the aggregate displayed "steps" count: the sum of per-session prompt-window counts. Despite the historical name, it is not a count of checkpoint records.
**Session-level metadata.json (`CommittedMetadata`, abbreviated):**
**Session-level metadata.json (`Metadata`, abbreviated):**
```json
{
"checkpoint_id": "abc123def456",
```