reuse pre-push repo for policy checks · Entire

reuse pre-push repo for policy checks

450426a→main·

pfleidi·2w ago·5 files·+21 added/-25 removed

Open the repository once during pre-push and pass it through checkpoint policy sync and gating.

Document why policy failures skip checkpoint work instead of failing Git or agent session startup hooks.

Sessions

d632fcef7305View transcript

Changes

5

213 unmodified lines

214
215
216
217
218
219
220
221
3 unmodified lines

225
226
227
228
229
230
231
232

213 unmodified lines

logging.Warn(ctx, "checkpoint policy read failed for agent hook",
        slog.String("error", err.Error()))
        if eventType == agent.SessionStart {
            // Let the agent start; the warning explains that checkpoint capture is
            // disabled until the policy can be read.
            return true, writeUnsupportedPolicySessionStartWarning(errW, ag, sessionStartPolicyReadErrorWarning(err))
        }
        fmt.Fprint(errW, agentCheckpointCaptureDisabledReadErrorMessage(err))
3 unmodified lines

return false, nil
    }
    if eventType == agent.SessionStart {
        // Let the agent start; the warning explains that checkpoint capture is
        // disabled until the CLI is upgraded.
        return true, writeUnsupportedPolicySessionStartWarning(errW, ag, sessionStartPolicyWarning(policy))
    }
    fmt.Fprint(errW, agentCheckpointCaptureDisabledMessage(policy))

Mcmd/entire/cli/hook_registry.go+4

65 unmodified lines

66
67
68
69
70
71
72
73

65 unmodified lines

}

func (g *gitHookContext) skipUnsupportedCheckpointPolicy() bool {
    // Callers return success when this is true because policy failures should
    // 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 skipped for git hook",

Mcmd/entire/cli/hooks_git_cmd.go+2

24 unmodified lines

25
26
27
28
29
30
31
32
33
34
35
36
28
29
30
31
6 unmodified lines

38
39
40
49
50
51
52
53
54
55
56
57
58
41
42
43
44

24 unmodified lines

return state.Policy, nil
}

func checkpointPolicyAllowsGitHook(ctx context.Context) bool {
    repo, err := OpenRepository(ctx)
    if err != nil {
        logging.Warn(ctx, "checkpoint policy read skipped for git hook",
        slog.String("error", err.Error()))
        return true
    }
    defer repo.Close()

func checkpointPolicyAllowsGitHook(ctx context.Context, repo *git.Repository) bool {
    policy, err := readLocalCheckpointPolicy(ctx, repo)
    if err != nil {
        warnOrLogCheckpointPolicyReadFailure(ctx, err)
6 unmodified lines

return false
}

func syncCheckpointPolicyForPrePush(ctx context.Context, ps pushSettings) {
    repo, err := OpenRepository(ctx)
    if err != nil {
        logging.Warn(ctx, "checkpoint policy pre-push: failed to open repository; allowing checkpoint push",
        slog.String("error", err.Error()),
        )
        return
    }
    defer repo.Close()

func syncCheckpointPolicyForPrePush(ctx context.Context, repo *git.Repository, ps pushSettings) {
    dir, err := paths.WorktreeRoot(ctx)
    if err != nil {
        logging.Warn(ctx, "checkpoint policy pre-push: failed to resolve worktree root; allowing checkpoint push",

Mcmd/entire/cli/strategy/checkpoint_policy.go+2/-19

264 unmodified lines

265
266
267
268
268
269
270
271

264 unmodified lines

t.Chdir(workDir)
    paths.ClearWorktreeRootCache()

syncCheckpointPolicyForPrePush(context.Background(), pushSettings{
syncCheckpointPolicyForPrePush(context.Background(), repo, pushSettings{
        remote:        "origin",
        checkpointURL: pushTargetDir,
    })

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

43 unmodified lines

44
45
46
47
48
49
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
23 unmodified lines

85
86
87
79
88
89
90
2 unmodified lines

93
94
95
88
96
97
98

43 unmodified lines

}

refs := checkpoint.ResolveRefs(ctx)
syncCheckpointPolicyForPrePush(ctx, ps)
if !checkpointPolicyAllowsGitHook(ctx) {
    return nil
    repo, repoErr := OpenRepository(ctx)
    if repoErr != nil {
        logging.Warn(ctx, "checkpoint policy pre-push: failed to open repository; allowing checkpoint push",
            slog.String("error", repoErr.Error()),
        )
    } else {
        defer repo.Close()
        syncCheckpointPolicyForPrePush(ctx, repo, ps)
        if !checkpointPolicyAllowsGitHook(ctx, repo) {
            // Policy failures should skip checkpoint pushes, not abort the user's push.
            return nil
        }
    }

// OPF pre-push rewrite: if OPF is configured, resolve the user's
23 unmodified lines

logging.Info(ctx, "OPF skipped for this push (user choice or settings)")
    case OPFRun:
        _, opfSpan := perf.Start(ctx, "opf_pre_push_rewrite")
        repo, repoErr := OpenRepository(ctx)
        if repoErr != nil {
            opfSpan.RecordError(repoErr)
            opfSpan.End()
2 unmodified lines

)
            return repoErr
        }
        defer repo.Close()
        if _, rewriteErr := RewriteUnpushedV1WithOPF(ctx, repo, ps.pushTarget()); rewriteErr != nil {
            opfSpan.RecordError(rewriteErr)
            opfSpan.End()