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

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") {
        ...
    }
}