block checkpoint data writers on policy · Entire
block checkpoint data writers on policy
c553b61→main·
pfleidi·2w ago·7 files·+112 added/-38 removed
Reject explicit checkpoint-data writes when the local checkpoint policy requires unsupported checkpoint versions.
Sessions
89792fc1526aView transcript
[?
Enforce Checkpoint Policies in CLICodex·GPT-5.5·2 steps](/content/gh/entireio/cli/session/019f05ad-eea0-7202-a508-ec34d069a2d2#timeline-89792fc1526a/index.html)
Changes
7
cmd/entire/cli
Mattach.go+4/-1
Mattach_test.go+18/-18
Mcheckpoint_policy_write.go+35/-6
Mexplain.go+4
Mexplain_test.go+17/-13
Mimport_cmd.go+4
Mimport_cmd_test.go+30
254 unmodified lines
255
256
257
258
258
259
260
261
262
263
264
254 unmodified lines
return nil
}
checkpointVersion := committedCheckpointVersion(ctx, repo)
checkpointVersion, err := checkpointVersionForNewCheckpoint(ctx, repo)
if err != nil {
return err
}
// Resolve agent and transcript path.
ag, transcriptPath, err := resolveAgentAndTranscript(logCtx, w, sessionID, agentName, existingState)
Mcmd/entire/cli/attach.go+4/-1
68 unmodified lines
69
70
71
72
72
73
74
75
1 unmodified line
77
78
79
80
81
82
83
84
85
80
81
82
83
84
2 unmodified lines
87
88
89
94
95
90
91
92
93
94
3 unmodified lines
98
99
100
105
106
107
108
109
110
111
112
113
101
102
103
104
105
1389 unmodified lines
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
68 unmodified lines
}
}
func TestAttachUsesDefaultWhenPolicyWriteUnsupported(t *testing.T) {
func TestAttachBlocksWhenPolicyWriteUnsupported(t *testing.T) {
setupAttachTestRepo(t)
repoRoot := mustGetwd(t)
1 unmodified line
if err != nil {
t.Fatal(err)
}
if _, err := checkpointpolicy.WriteLocal(context.Background(), repo, plumbing.ZeroHash, checkpointpolicy.Policy{
CheckpointVersion: "refs-v1",
CheckpointMinVersion: "branch-v1",
}); err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = repo.Close() })
writeUnsupportedCheckpointPolicyForCLITest(t, repo)
sessionID := "test-attach-policy-unsupported"
setupClaudeTranscript(t, sessionID, `{"type":"user","message":{"role":"user","content":"create a file"},"uuid":"uuid-1"}`
2 unmodified lines
var out bytes.Buffer
err = runAttach(context.Background(), &out, sessionID, agent.AgentNameClaudeCode, attachOptions{Force: true})
if err != nil {
t.Fatalf("runAttach failed: %v", err)
if err == nil || !strings.Contains(err.Error(), "checkpoint policy cannot be satisfied by this Entire CLI") {
t.Fatalf("runAttach error = %v, want unsupported checkpoint policy", err)
}
stateStore, err := session.NewStateStore(context.Background())
if err != nil {
3 unmodified lines
if err != nil {
t.Fatal(err)
}
if state == nil || state.LastCheckpointID.IsEmpty() {
t.Fatalf("expected attach to record checkpoint state, got %+v", state)
}
summary, err := cpkg.NewGitStore(repo, cpkg.DefaultV1Refs()).Read(context.Background(), state.LastCheckpointID)
if err != nil {
t.Fatalf("Read: %v", err)
}
if summary.CheckpointVersion != checkpointpolicy.DefaultCheckpointVersion() {
t.Fatalf("CheckpointVersion = %q, want %q", summary.CheckpointVersion, checkpointpolicy.DefaultCheckpointVersion())
if state != nil {
t.Fatalf("expected attach not to record checkpoint state, got %+v", state)
}
}
1389 unmodified lines
}
}
func writeUnsupportedCheckpointPolicyForCLITest(t *testing.T, repo *git.Repository) {
t.Helper()
_, err := checkpointpolicy.WriteLocal(t.Context(), repo, plumbing.ZeroHash, checkpointpolicy.Policy{
CheckpointVersion: "refs-v1",
CheckpointMinVersion: "branch-v1",
})
if err != nil {
t.Fatal(err)
}
}
// setupAttachTestRepo creates a temp git repo with one commit and enables Entire.
// Returns the repo directory. Caller must not use t.Parallel() (uses t.Chdir).
func setupAttachTestRepo(t *testing.T) {
Mcmd/entire/cli/attach_test.go+18/-18
1 unmodified line
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
12
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
15
16
38
39
18
40
20
41
42
22
43
44
45
46
47
48
49
50
51
52
1 unmodified line
import (
"context"
"errors"
"fmt"
"log/slog"
"strings"
"github.com/entireio/cli/cmd/entire/cli/checkpointpolicy"
"github.com/entireio/cli/cmd/entire/cli/logging"
"github.com/entireio/cli/cmd/entire/cli/versioncheck"
"github.com/entireio/cli/cmd/entire/cli/versioninfo"
"github.com/go-git/go-git/v6"
)
func committedCheckpointVersion(ctx context.Context, repo *git.Repository) string {
var errUnsupportedCheckpointPolicy = errors.New("checkpoint policy cannot be satisfied by this Entire CLI")
func checkpointVersionForNewCheckpoint(ctx context.Context, repo *git.Repository) (string, error) {
policy := localCheckpointPolicyForNewCheckpoint(ctx, repo)
if !checkpointpolicy.CanSatisfyPolicy(policy) {
return "", unsupportedCheckpointPolicyError(policy)
}
return checkpointpolicy.CheckpointVersion(policy), nil
}
func ensureCheckpointPolicyAllowsCheckpointData(ctx context.Context, repo *git.Repository) error {
policy := localCheckpointPolicyForNewCheckpoint(ctx, repo)
if checkpointpolicy.CanSatisfyPolicy(policy) {
return nil
}
return unsupportedCheckpointPolicyError(policy)
}
func localCheckpointPolicyForNewCheckpoint(ctx context.Context, repo *git.Repository) checkpointpolicy.Policy {
state, err := checkpointpolicy.ReadLocal(ctx, repo)
if err != nil {
version := checkpointpolicy.DefaultCheckpointVersion()
logging.Warn(ctx, "checkpoint policy read failed; using default checkpoint version", logging.Warn(ctx, "checkpoint policy read failed; using default checkpoint policy",
s slog.String("error", err.Error()),
slog.String("using_checkpoint_version", version),
)
return version
return checkpointpolicy.DefaultPolicy()
}
return checkpointpolicy.CheckpointVersion(state.Policy)
return state.Policy
}
func unsupportedCheckpointPolicyError(policy checkpointpolicy.Policy) error {
message := strings.TrimSpace(checkpointpolicy.UnsupportedPolicyMessage(
policy,
versioncheck.UpdateCommandForCurrentBinary(versioninfo.Version),
))
return fmt.Errorf("%w:\n%s", errUnsupportedCheckpointPolicy, message)
}