checkpoint: dedup session-metadata mutation and test slice assertion · Entire
checkpoint: dedup session-metadata mutation and test slice assertion
4a360d8→main·
Soph·2w ago·2 files·+59 added/-77 removed
Extract updateSessionMetadata, the read-modify-write-blob pattern shared by replaceSkillEvents and setCompactTranscriptStart, so both express only their field mutation. Reading from the entries blob (not an in-memory copy) is kept, so sequential finalize-path mutations still see each other's changes.
Generalize the test helper assertCodexSliceIsGamma into assertCompactSliceScoped (parameterized absent/present strings), used by both the Claude and Codex slice-scoping assertions.
Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com
Sessions
0aa2d57378e2View transcript
[?
Compact Transcript Storage and Boundary MarkersClaude Code·Opus 4.8[1m]·3 steps](/content/gh/entireio/cli/session/78b0fe12-1b0c-46e0-ae16-2534880690c7#timeline-0aa2d57378e2/index.html)
Changes
2
cmd/entire/cli/checkpoint
Mpersistent.go+43/-56
Mpersistent_compact_transcript_test.go+16/-21
1666 unmodified lines
return s.setPrimaryRef(newCommitHash)
}
// updateSessionMetadata reads the session metadata blob from entries, applies
// mutate, and rewrites the blob. Reading from the blob (rather than an in-memory
// copy) keeps it correct when several finalize-path steps mutate the same
// metadata in sequence — each sees the prior step's changes.
func (s *GitStore) updateSessionMetadata(sessionPath string, entries map[string]object.TreeEntry, mutate func(*Metadata)) error {
metadataPath := sessionPath + paths.MetadataFileName
entry, exists := entries[metadataPath]
if !exists {
return fmt.Errorf("session metadata not found at %s", metadataPath)
}
metadata, err := s.readMetadataFromBlob(entry.Hash)
if err != nil {
return fmt.Errorf("read session metadata: %w", err)
}
mutate(metadata)
metadataJSON, err := jsonutil.MarshalIndentWithNewline(metadata, "", " ")
if err != nil {
return fmt.Errorf("marshal session metadata: %w", err)
}
metadataHash, err := CreateBlobFromContent(s.repo, metadataJSON)
if err != nil {
return err
}
entries[metadataPath] = object.TreeEntry{
Name: metadataPath,
Mode: filemode.Regular,
Hash: metadataHash,
}
return nil
}
func (s *GitStore) replaceSkillEvents(skillEvents []agent.SkillEvent, sessionPath string, entries map[string]object.TreeEntry) error {
metadataPath := sessionPath + paths.MetadataFileName
entry, exists := entries[metadataPath]
if !exists {
return fmt.Errorf("session metadata not found at %s", metadataPath)
}
metadata, err := s.readMetadataFromBlob(entry.Hash)
if err != nil {
return fmt.Errorf("read session metadata: %w", err)
}
metadata.SkillEventsVersion = skillEventsVersion(skillEvents)
metadata.SkillEvents = skillEvents
metadataJSON, err := jsonutil.MarshalIndentWithNewline(metadata, "", " ")
if err != nil {
return fmt.Errorf("marshal session metadata: %w", err)
}
metadataHash, err := CreateBlobFromContent(s.repo, metadataJSON)
if err != nil {
return err
}
entries[metadataPath] = object.TreeEntry{
Name: metadataPath,
Mode: filemode.Regular,
Hash: metadataHash,
}
return nil
}
// replaceTranscript writes the full transcript content, replacing any existing
// setCompactTranscriptStart reads the session metadata blob from entries, sets
// CompactTranscriptStart, and rewrites it. Used by the OPF rewrite path so the
// finalized session metadata reflects the regenerated compact transcript.
func (s *GitStore) setCompactTranscriptStart(sessionPath string, start int, entries map[string]object.TreeEntry) error {
metadataPath := sessionPath + paths.MetadataFileName
entry, exists := entries[metadataPath]
if !exists {
return fmt.Errorf("session metadata not found at %s", metadataPath)
}
metadata, err := s.readMetadataFromBlob(entry.Hash)
if err != nil {
return fmt.Errorf("read session metadata: %w", err)
}
metadata.CompactTranscriptStart = &start
metadataJSON, err := jsonutil.MarshalIndentWithNewline(metadata, "", " ")
if err != nil {
return fmt.Errorf("marshal session metadata: %w", err)
}
metadataHash, err := CreateBlobFromContent(s.repo, metadataJSON)
if err != nil {
return err
}
entries[metadataPath] = object.TreeEntry{
Name: metadataPath,
Mode: filemode.Regular,
Hash: metadataHash,
}
return nil
}
// PrecomputeTranscriptBlobs chunks the given transcript and writes each chunk
Mcmd/entire/cli/checkpoint/persistent.go+43/-56
146 unmodified lines
// assertCodexSliceIsGamma checks that slicing the full compact transcript at the
// marker yields only the checkpoint-scoped content ("gamma"), excluding the
// pre-start "beta".
func assertCodexSliceIsGamma(t *testing.T, compactContent string, marker int) {
// assertCompactSliceScoped checks that slicing the full compact transcript at
// the marker yields exactly this checkpoint's content: every wantAbsent string
// (pre-start content) is gone and every wantPresent string is retained.
func assertCompactSliceScoped(t *testing.T, compactContent string, marker int, wantAbsent, wantPresent []string) {
t.Helper()
lines := strings.Split(strings.TrimRight(compactContent, "\n"), "\n")
if marker > len(lines) {
t.Fatalf("marker %d out of range for %d compact lines", marker, len(lines))
}
slice := strings.Join(lines[marker:], "\n")
if strings.Contains(slice, "beta") {
}
}
if !strings.Contains(slice, "gamma") {
...
}
}