# Gate checkpoint reads by support, not family recognition

`b69b255`→[main](/content/gh/entireio/cli/commits/main/index.html)·

pfleidi·3w ago·2 files·+5 added/-12 removed

ParseFormat previously hard-failed on any unrecognized family, so a checkpoint written by a newer client surfaced as a malformed-format error and IsUnsupportedVersion returned false, suppressing the upgrade prompt.

Validate only the family-vN structure and let CanRead be the sole read gate. Unknown but well-formed families now parse and resolve to an unsupported-version error, so the upgrade path fires as intended.

## Sessions

1a62a9e93329View transcript

[?\
Fix Checkpoint Version Error HandlingClaude Code·Opus 4.8[1m]·1 step](/content/gh/entireio/cli/session/f595aa27-e7ce-4f83-9fe1-16ed999f57e4#timeline-1a62a9e93329/index.html)

## Changes

2

- cmd/entire/cli/checkpointpolicy

- Mformat.go+1/-11

- Mformat_test.go+4/-1

```
23 unmodified lines

24
25
26
27
28
29
30
31
27
28
29
30
31
37
32
33
34
35
7 unmodified lines

43
44
45
51
52
53
54
55
46
47
48

23 unmodified lines

return CheckpointFormat{}, fmt.Errorf("invalid checkpoint format %q", raw)
	}

family := CheckpointFamily(familyRaw)
	if _, ok := knownFamilies[family]; !ok {
		return CheckpointFormat{}, fmt.Errorf("unknown checkpoint family %q", familyRaw)
	}

major, err := strconv.Atoi(majorRaw)
	if err != nil || major <= 0 {
		return CheckpointFormat{}, fmt.Errorf("invalid checkpoint major %q", majorRaw)
	}

return CheckpointFormat{Family: family, Major: major}, nil
	return CheckpointFormat{Family: CheckpointFamily(familyRaw), Major: major}, nil
}

func (f CheckpointFormat) String() string {
7 unmodified lines

return readFormats[format]
}

var knownFamilies = map[CheckpointFamily]bool{
	CheckpointFamilyBranch: true,
	CheckpointFamilyRefs:   true,
}

var branchV1Format = CheckpointFormat{Family: CheckpointFamilyBranch, Major: 1}

var readFormats = map[CheckpointFormat]bool{
```

Mcmd/entire/cli/checkpointpolicy/format.go+1/-11

```
17 unmodified lines

18
19
20
21
21
22
23
24
20 unmodified lines

45
46
47
48
49
50
51
52
53
54

17 unmodified lines

}{
		{name: "branch v1", input: "branch-v1", want: checkpointpolicy.CheckpointFormat{Family: checkpointpolicy.CheckpointFamilyBranch, Major: 1}},
		{name: "refs v2", input: "refs-v2", want: checkpointpolicy.CheckpointFormat{Family: checkpointpolicy.CheckpointFamilyRefs, Major: 2}},
		{name: "unknown family", input: "unknown-v1", wantErr: "unknown checkpoint family"},
		{name: "unknown family parses", input: "unknown-v1", want: checkpointpolicy.CheckpointFormat{Family: "unknown", Major: 1}},
		{name: "missing v", input: "branch-1", wantErr: "invalid checkpoint format"},
		{name: "zero major", input: "branch-v0", wantErr: "invalid checkpoint major"},
		{name: "non numeric major", input: "branch-vx", wantErr: "invalid checkpoint major"},
20 unmodified lines

require.NoError(t, err)
	refsV1, err := checkpointpolicy.ParseFormat("refs-v1")
	require.NoError(t, err)
	unknownV1, err := checkpointpolicy.ParseFormat("unknown-v1")
	require.NoError(t, err)

require.True(t, checkpointpolicy.CanRead(branchV1))
	require.False(t, checkpointpolicy.CanRead(refsV1))
	require.False(t, checkpointpolicy.CanRead(unknownV1))
}
```

Mcmd/entire/cli/checkpointpolicy/format_test.go+4/-1
