centralize checkpoint mirror ref updates · Entire

centralize checkpoint mirror ref updates

5203300→main·pfleidi·1mo ago·8 files·+121 added/-206 removed

Move v1.1 committed metadata mirroring into the strategy package so CLI and hook callers share one implementation.

The mirror now points directly at the v1 primary ref, matching its local-only mirror role.

Sessions

555ddb60c8cbView transcript

Changes

8

317 unmodified lines

318
319
320
321
321
322
323
324

317 unmodified lines

}

if refs := opts.committedRefs(ctx); refs.HasMirror() {
    if err := mirrorToV1CustomRef(refs, repo); err != nil {
        if err := strategy.MirrorCommittedMetadataRef(ctx, repo, refs); err != nil {
            return fmt.Errorf("checkpoint was written to %s, but failed to mirror to %s: %w", refs.Primary, refs.Mirror, err)
        }
    }
}

Mcmd/entire/cli/attach.go+1/-1

925 unmodified lines

926
927
928
929
929
930
931
932

925 unmodified lines

if refs := checkpoint.ResolveCommittedRefs(ctx); refs.HasMirror() {
    if err := mirrorToV1CustomRef(refs, store.Repository()); err != nil {
        if err := strategy.MirrorCommittedMetadataRef(ctx, store.Repository(), refs); err != nil {
            return fmt.Errorf("summary was written to %s, but failed to mirror to %s: %w", refs.Primary, refs.Mirror, err)
        }
    }
}

Mcmd/entire/cli/explain.go+1/-1

262 unmodified lines

263
264
265
266
266
267
268
269

262 unmodified lines

// Mirror the committed write to the v1 custom ref when opted in
// (local-only, never pushed; failures are logged, not fatal).
mirrorMetadataToV1CustomRef(ctx, repo)
MirrorCommittedMetadataRefBestEffort(ctx, repo)

logging.Debug(logCtx, "condense timings",
    slog.String("session_id", state.SessionID),

Mcmd/entire/cli/strategy/manual_commit_condensation.go+1/-1

1156 unmodified lines

1157
1158
1159
1160
1160
1161
1162
1163
1651 unmodified lines

2815
2816
2817
2818
2818
2819
2820
2821

1156 unmodified lines

// Combined attribution is a committed write in the post-commit hook, so the
// v1 custom ref must track it too when opted in (local-only, never pushed).
mirrorMetadataToV1CustomRef(ctx, repo)
MirrorCommittedMetadataRefBestEffort(ctx, repo)

return nil

}
1651 unmodified lines

// Mirror the finalized v1 metadata to the v1 custom ref when opted in
// (local-only, never pushed; failures are logged, not fatal). Once after the
// loop is enough — it tracks v1's final commit.
mirrorMetadataToV1CustomRef(ctx, repo)
MirrorCommittedMetadataRefBestEffort(ctx, repo)

// Clear turn checkpoint IDs. Do NOT update CheckpointTranscriptStart here — it was
// already set correctly by PostCommit: condenseAndUpdateState sets it to the total

Mcmd/entire/cli/strategy/manual_commit_hooks.go+2/-2

1 unmodified line

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
16
17
18
19
19
20
21
22
23
24
24
25
26
27
25
26
27
28
29
30
30
31
32
33
34
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

1 unmodified line

import (
    "context"
    "errors"
    "fmt"

log/slog"

git "github.com/go-git/go-git/v6"
    "github.com/go-git/go-git/v6/plumbing"

"github.com/entireio/cli/cmd/entire/cli/checkpoint"
    "github.com/entireio/cli/cmd/entire/cli/logging"
)

// mirrorMetadataToV1CustomRef advances the topology's mirror to the primary's
// commit when a mirror is configured. Call after a successful primary write; a
// mirror failure must not affect that write, so problems are logged, not returned.
func mirrorMetadataToV1CustomRef(ctx context.Context, repo *git.Repository) {
    refs := checkpoint.ResolveCommittedRefs(ctx)
// MirrorCommittedMetadataRef points the committed-metadata mirror at the primary
// ref's tip. No-op when the topology has no mirror.
func MirrorCommittedMetadataRef(ctx context.Context, repo *git.Repository, refs checkpoint.CommittedRefs) error {
    if !refs.HasMirror() {
        return
    }
    return nil
}

primaryRef, err := repo.Reference(refs.Primary, true)
    if err != nil {
        // No primary metadata ref yet — nothing to mirror. Expected on first use.
        logging.Debug(ctx, "committed-ref mirror skipped: primary metadata ref unavailable",
            slog.String("error", err.Error()))
        return
    if errors.Is(err, plumbing.ErrReferenceNotFound) {
        return fmt.Errorf("primary metadata ref %s missing: %w", refs.Primary, err)
    }
    return fmt.Errorf("read primary metadata ref %s: %w", refs.Primary, err)
}

if err := SafelyAdvanceLocalRef(ctx, repo, refs.Mirror, primaryRef.Hash()); err != nil {
    logging.Warn(ctx, "committed-ref mirror failed",
        slog.String("ref", refs.Mirror.String()),
        slog.String("error", err.Error()))
    return
}
if err := repo.Storer.SetReference(plumbing.NewHashReference(refs.Mirror, primaryRef.Hash())); err != nil {
    return fmt.Errorf("set mirror ref %s to %s: %w", refs.Mirror, primaryRef.Hash(), err)
}

logging.Debug(ctx, "committed-ref mirror updated",
    slog.String("ref", refs.Mirror.String()),
    slog.String("hash", primaryRef.Hash().String()))
return nil
}

// MirrorCommittedMetadataRefBestEffort mirrors committed metadata for callers
// where mirror failure must not affect the primary operation.
func MirrorCommittedMetadataRefBestEffort(ctx context.Context, repo *git.Repository) {
    refs := checkpoint.ResolveCommittedRefs(ctx)
    if !refs.HasMirror() {
        return
    }

if err := MirrorCommittedMetadataRef(ctx, repo, refs); err != nil {
        if errors.Is(err, plumbing.ErrReferenceNotFound) {
            // No primary metadata ref yet — nothing to mirror. Expected on first use.
            logging.Debug(ctx, "committed-ref mirror skipped: primary metadata ref unavailable",
                slog.String("error", err.Error()))
            return
        }
        logging.Warn(ctx, "committed-ref mirror failed",
            slog.String("ref", refs.Mirror.String()),
            slog.String("error", err.Error()))
        return
    }
}

Mcmd/entire/cli/strategy/v1_custom_ref_mirror.go+36/-15

1
2
3
4
5
6
7
1 unmodified line

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
64 unmodified lines

100
101
102
103
104
105
106
107
108
109
110
111
91
112
113
114
115
95
116
117
118
119
1 unmodified line

121
122
123
103
124
125
126
127
107
128
129
130
131
132
133
134
135
136
137
114
138
139
140
141
7 unmodified lines

149
150
151
128
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
69 unmodified lines

254
255
256
210
257
258
259
213
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288

package strategy

import (
    "errors"
    "os"
    "path/filepath"
    "testing"

git "github.com/go-git/go-git/v6"
    "github.com/go-git/go-git/v6/plumbing"
    "github.com/go-git/go-git/v6/storage"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/require"

"github.com/entireio/cli/cmd/entire/cli/checkpoint"
    "github.com/entireio/cli/cmd/entire/cli/checkpoint/id"
    "github.com/entireio/cli/cmd/entire/cli/paths"
    "github.com/entireio/cli/cmd/entire/cli/session"
    "github.com/entireio/cli/cmd/entire/cli/testutil"
)

type setReferenceErrorStorer struct {
    storage.Storer

err error
}

func (s setReferenceErrorStorer) SetReference(*plumbing.Reference) error {
    return s.err
}

// setupV1CustomRefRepo creates an isolated repo with one commit, writes settings
// with the given checkpoints_version (empty string omits the option), chdirs
// in, and returns the open repo.
func setupV1CustomRefRepo(t *testing.T) *git.Repository {
    t.Helper()
    tmpDir := t.TempDir()
    testutil.InitRepo(t, tmpDir)
    testutil.WriteFile(t, tmpDir, "f.txt", "init")
    testutil.GitAdd(t, tmpDir, "f.txt")
    testutil.GitCommit(t, tmpDir, "init")

t.Chdir(tmpDir)
    repo, err := git.PlainOpen(tmpDir)
    require.NoError(t, err)
    return repo
}

func v1CustomRefsForTest() checkpoint.CommittedRefs {
    return checkpoint.CommittedRefs{
        Primary: plumbing.NewBranchReferenceName(paths.MetadataBranchName),
        Read:    plumbing.ReferenceName(paths.MetadataRefName),
        Mirror:  plumbing.ReferenceName(paths.MetadataRefName),
    }
}

// Not parallel: uses t.Chdir().
func TestMirrorMetadataToV1CustomRef_CreatesRefWhenEnabled(t *testing.T) {
    repo := setupV1CustomRefRepo(t, `"1.1"`)
    v1Hash := setV1MetadataBranch(t, repo)

mirrorMetadataToV1CustomRef(t.Context(), repo)
    require.NoError(t, MirrorCommittedMetadataRef(t.Context(), repo, v1CustomRefsForTest()))

got, ok := v1CustomRefHash(t, repo)
    require.True(t, ok, "expected %s to exist", paths.MetadataRefName)
    assert.Equal(t, v1Hash, got)
}

// Not parallel: uses t.Chdir().
func TestMirrorMetadataToV1CustomRef_DisabledNoOp(t *testing.T) {
    repo := setupV1CustomRefRepo(t, "") // v1 only
    setV1MetadataBranch(t, repo)

mirrorMetadataToV1CustomRef(t.Context(), repo)
    require.NoError(t, MirrorCommittedMetadataRef(t.Context(), repo, checkpoint.CommittedRefs{
        Primary: plumbing.NewBranchReferenceName(paths.MetadataBranchName),
        Read:    plumbing.NewBranchReferenceName(paths.MetadataBranchName),
    }))

_, ok := v1CustomRefHash(t, repo)
    assert.False(t, ok, "v1 custom ref must not be created when not opted in")
}

// Not parallel: uses t.Chdir().
func TestMirrorMetadataToV1CustomRef_AdvancesExistingRef(t *testing.T) {
    repo := setupV1CustomRefRepo(t, `"1.1"`)
    oldHash := setV1MetadataBranch(t, repo)
    require.NoError(t, repo.Storer.SetReference(
        plumbing.NewHashReference(plumbing.ReferenceName(paths.MetadataRefName), oldHash)))

newHash := setV1MetadataBranch(t, repo)
    require.NotEqual(t, oldHash, newHash)

mirrorMetadataToV1CustomRef(t.Context(), repo)
    require.NoError(t, MirrorCommittedMetadataRef(t.Context(), repo, v1CustomRefsForTest()))

got, ok := v1CustomRefHash(t, repo)
    require.True(t, ok)
    assert.Equal(t, newHash, got)
}

// Not parallel: uses t.Chdir().
func TestMirrorCommittedMetadataRef_ReplacesLocallyAheadMirror(t *testing.T) {
    repo := setupV1CustomRefRepo(t, `"1.1"`)
    v1Hash := setV1MetadataBranch(t, repo)

cwd, err := os.Getwd()
    require.NoError(t, err)
    testutil.WriteFile(t, cwd, "f2.txt", "more")
    testutil.GitAdd(t, cwd, "f2.txt")
    testutil.GitCommit(t, cwd, "second")
    head, err := repo.Head()
    require.NoError(t, err)
    require.NotEqual(t, v1Hash, head.Hash())
    require.NoError(t, repo.Storer.SetReference(
        plumbing.NewHashReference(plumbing.ReferenceName(paths.MetadataRefName), head.Hash())))

require.NoError(t, MirrorCommittedMetadataRef(t.Context(), repo, v1CustomRefsForTest()))

got, ok := v1CustomRefHash(t, repo)
    require.True(t, ok)
    assert.Equal(t, v1Hash, got)
}

// Not parallel: uses t.Chdir().
func TestMirrorCommittedMetadataRef_V1MissingNoOp(t *testing.T) {
    repo := setupV1CustomRefRepo(t, `"1.1"`) // no v1 metadata branch created

mirrorMetadataToV1CustomRef(t.Context(), repo)
    err := MirrorCommittedMetadataRef(t.Context(), repo, v1CustomRefsForTest())
    require.Error(t, err)
    assert.Contains(t, err.Error(), paths.MetadataBranchName)

_, ok := v1CustomRefHash(t, repo)
    assert.False(t, ok, "v1 custom ref must not be created when v1 metadata branch is absent")
}

// Not parallel: uses t.Chdir().
func TestMirrorCommittedMetadataRef_SetReferenceErrorNamesTarget(t *testing.T) {
    repo := setupV1CustomRefRepo(t, `"1.1"`)
    v1Hash := setV1MetadataBranch(t, repo)
    storerErr := errors.New("set failed")
    repo.Storer = setReferenceErrorStorer{Storer: repo.Storer, err: storerErr}

err := MirrorCommittedMetadataRef(t.Context(), repo, v1CustomRefsForTest())
    require.ErrorIs(t, err, storerErr)
    assert.Contains(t, err.Error(), paths.MetadataRefName)
    assert.Contains(t, err.Error(), v1Hash.String())
}

// Not parallel: uses t.Chdir().
func TestMirrorCommittedMetadataRefBestEffort_V1MissingNoOp(t *testing.T) {
    repo := setupV1CustomRefRepo(t, `"1.1"`) // no v1 metadata branch created

MirrorCommittedMetadataRefBestEffort(t.Context(), repo)

_, ok := v1CustomRefHash(t, repo)
    assert.False(t, ok, "v1 custom ref must not be created when v1 metadata branch is absent")
}

Dcmd/entire/cli/v1_custom_ref_mirror.go-29

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149