tidy checkpoint policy telemetry git hook · Entire
tidy checkpoint policy telemetry git hook
fa9c791→main·
pfleidi·2w ago·2 files·+43 added/-24 removed
Extract the duplicated unreadable-policy skip path in the git hook into a shared helper, and cover the agent write-hook label mapping with a table test.
Sessions
c1fa284fd6e7View transcript
[?
Add Checkpoint Policy Blocked TelemetryClaude Code·8 steps](/content/gh/entireio/cli/session/59674bd8-9edc-47fc-adae-9e93955ab9af#timeline-c1fa284fd6e7/index.html)
Changes
2
cmd/entire/cli
Mhook_registry_test.go+23
Mhooks_git_cmd.go+20/-24
277 unmodified lines
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
277 unmodified lines
}
}
func TestAgentWriteHookLabel(t *testing.T) {
t.Parallel()
tests := []struct {
name string
eventType agent.EventType
claudePostTodoCheckpointHook bool
want string
}{
{name: "post todo takes priority", claudePostTodoCheckpointHook: true, want: "post-todo"},
{name: "subagent end", eventType: agent.SubagentEnd, want: "subagent-end"},
{name: "turn end is the default", eventType: agent.TurnEnd, want: "turn-end"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
require.Equal(t, tt.want, agentWriteHookLabel(tt.eventType, tt.claudePostTodoCheckpointHook))
})
}
}
func TestExecuteAgentHookTurnStartDispatchesWhenPolicyUnsupported(t *testing.T) {
setupStopTestRepo(t)
repoRoot := mustGetwd(t)
Mcmd/entire/cli/hook_registry_test.go+23
70 unmodified lines
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
74
75
76
77
78
79
91
92
93
94
95
96
97
98
99
100
101
102
80
81
82
83
21 unmodified lines
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
70 unmodified lines
// disable Entire checkpoint work, not make Git reject the user's operation.
repo, err := gitrepo.OpenCurrent(g.ctx)
if err != nil {
logging.Warn(g.ctx, "checkpoint policy read failed; skipping git hook",
slog.String("error", err.Error()))
if interactive.CanPromptInteractively() {
fmt.Fprintf(os.Stderr, "[entire] Could not read checkpoint policy; skipping Entire checkpoint work: %v\n", err)
}
emitCheckpointPolicyBlocked(g.ctx, telemetry.CheckpointPolicyBlockedEvent{
Hook: g.hookName,
HookType: telemetry.PolicyBlockedHookTypeGit,
Reason: telemetry.PolicyBlockedReasonUnreadable,
Outcome: telemetry.PolicyBlockedOutcomeSkipped,
})
return true
return g.skipUnreadableCheckpointPolicy(err)
}
defer repo.Close()
state, err := checkpointpolicy.ReadLocal(g.ctx, repo)
if err != nil {
logging.Warn(g.ctx, "checkpoint policy read failed; skipping git hook",
slog.String("error", err.Error()))
if interactive.CanPromptInteractively() {
fmt.Fprintf(os.Stderr, "[entire] Could not read checkpoint policy; skipping Entire checkpoint work: %v\n", err)
}
emitCheckpointPolicyBlocked(g.ctx, telemetry.CheckpointPolicyBlockedEvent{
Hook: g.hookName,
HookType: telemetry.PolicyBlockedHookTypeGit,
Reason: telemetry.PolicyBlockedReasonUnreadable,
Outcome: telemetry.PolicyBlockedOutcomeSkipped,
})
return true
return g.skipUnreadableCheckpointPolicy(err)
}
policy := state.Policy
21 unmodified lines
return true
}
// skipUnreadableCheckpointPolicy warns, notifies the user, and reports the
// policy-blocked telemetry event for a hook whose checkpoint policy could not be
// read. It always returns true so callers skip Entire checkpoint work.
func (g *gitHookContext) skipUnreadableCheckpointPolicy(err error) bool {
logging.Warn(g.ctx, "checkpoint policy read failed; skipping git hook",
slog.String("error", err.Error()))
if interactive.CanPromptInteractively() {
fmt.Fprintf(os.Stderr, "[entire] Could not read checkpoint policy; skipping Entire checkpoint work: %v\n", err)
}
emitCheckpointPolicyBlocked(g.ctx, telemetry.CheckpointPolicyBlockedEvent{
Hook: g.hookName,
HookType: telemetry.PolicyBlockedHookTypeGit,
Reason: telemetry.PolicyBlockedReasonUnreadable,
Outcome: telemetry.PolicyBlockedOutcomeSkipped,
})
return true
}
// initHookLogging initializes logging for hooks by finding the most recent session.
// Returns a cleanup function that should be deferred.
// If Entire is not set up or disabled, returns a no-op to avoid creating files.