Skip to content

Movechekcpointtestpackage#557

Closed
evisdren wants to merge 2 commits intomainfrom
movechekcpointtestpackage
Closed

Movechekcpointtestpackage#557
evisdren wants to merge 2 commits intomainfrom
movechekcpointtestpackage

Conversation

@evisdren
Copy link
Contributor

No description provided.

evisdren and others added 2 commits February 27, 2026 19:17
Move growth_model_test.go and push_perf_test.go from package
checkpoint_test to package checkpoint, and remove self-import
in push_perf_test.go.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Entire-Checkpoint: 16571a9186d3
Copilot AI review requested due to automatic review settings February 28, 2026 03:18
@evisdren evisdren requested a review from a team as a code owner February 28, 2026 03:18
@cursor
Copy link

cursor bot commented Feb 28, 2026

PR Summary

Medium Risk
Build-tagged tests add GitHub-pushing and repo-deleting performance harnesses; while not in default test runs, they can be destructive and require elevated gh permissions if executed.

Overview
Adds three new build-tagged test suites for capacity/performance analysis.

growth_model_test.go logs projected per-repo/platform storage growth, push-time estimates, and size-threshold timelines based on configurable checkpoint size/rate assumptions.

push_perf_test.go seeds repos with real transcripts, creates/deletes a temporary GitHub repo via gh, and measures first vs incremental push times plus Trace2 phase breakdowns.

commit_hook_profile_test.go adds a deep PostCommit profiler that times key sub-steps (overlap checks, PrepareCondensation components, batch write/finalize) across many seeded sessions.

Written by Cursor Bugbot for commit 1a38675. Configure here.

@evisdren evisdren closed this Feb 28, 2026
@evisdren evisdren deleted the movechekcpointtestpackage branch February 28, 2026 03:20
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds opt-in (build-tagged) performance/profiling tests to measure commit-hook behavior, Git push timings, and projected checkpoint growth.

Changes:

  • Introduces a deep PostCommit profiling test (hookperf) with per-session timing breakdowns.
  • Adds push performance + trace2 profiling tests (pushperf) that seed repos with real transcript blobs and measure push phases.
  • Adds a growth projection “model” test (growthmodel) for estimating storage and push-time scaling.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 12 comments.

File Description
cmd/entire/cli/strategy/commit_hook_profile_test.go Adds hookperf profiling test that decomposes PostCommit into timed sub-steps.
cmd/entire/cli/checkpoint/push_perf_test.go Adds pushperf push timing + trace2 profiling tests and helpers to seed repos using real transcripts.
cmd/entire/cli/checkpoint/growth_model_test.go Adds growthmodel projection test printing tables for storage/push-time growth assumptions.
.claude/worktrees/cached-spinning-nebula Updates referenced subproject commit.

// Log progress for large scenarios.
logInterval := progressInterval(count, transcriptSize)

for i := range count {
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for i := range count does not compile in Go (you can’t range over an int). Use an indexed loop (e.g., for i := 0; i < count; i++ { ... }).

Suggested change
for i := range count {
for i := 0; i < count; i++ {

Copilot uses AI. Check for mistakes.
headTree: headTree,
shadowTree: shadowTree,
parentTree: parentTree,
hasParentTree: true,
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hasParentTree is always set to true even when parentTree is nil (e.g., initial commit). This can lead to incorrect overlap behavior or nil dereferences inside filesOverlapWithContent. Set hasParentTree based on whether parentTree != nil (and/or early-return when there is no parent).

Suggested change
hasParentTree: true,
hasParentTree: parentTree != nil,

Copilot uses AI. Check for mistakes.
Comment on lines +550 to +557
ref := shadowRef
hasShadowBranch := ref != nil
if !hasShadowBranch {
refName := plumbing.NewBranchReferenceName(shadowBranchName)
var err error
ref, err = repo.Reference(refName, true)
hasShadowBranch = err == nil
}
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ref can still be nil if the shadow branch doesn’t exist and repo.Reference fails, but it’s passed unconditionally to calculateSessionAttributions. Guard the attribution step (and any downstream use) on hasShadowBranch or return early when ref == nil.

Copilot uses AI. Check for mistakes.

// Sub-step 4: Attribution
ts3 := time.Now()
_ = calculateSessionAttributions(ctx, repo, ref, &ExtractedSessionData{FilesTouched: state.FilesTouched}, state, attributionOpts{headTree: headTree, headTreeHashes: headTreeHashes})
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ref can still be nil if the shadow branch doesn’t exist and repo.Reference fails, but it’s passed unconditionally to calculateSessionAttributions. Guard the attribution step (and any downstream use) on hasShadowBranch or return early when ref == nil.

Suggested change
_ = calculateSessionAttributions(ctx, repo, ref, &ExtractedSessionData{FilesTouched: state.FilesTouched}, state, attributionOpts{headTree: headTree, headTreeHashes: headTreeHashes})
if hasShadowBranch && ref != nil {
_ = calculateSessionAttributions(ctx, repo, ref, &ExtractedSessionData{FilesTouched: state.FilesTouched}, state, attributionOpts{headTree: headTree, headTreeHashes: headTreeHashes})
}

Copilot uses AI. Check for mistakes.
shadowBranchesToDelete := make(map[string]struct{})

// Precompute headTree hash index (same as real PostCommit does)
headTreeHashes, _ := BuildTreeHashIndex(ctx, headTree)
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error from BuildTreeHashIndex is ignored. Since this is a test/profiler, failing fast on errors makes results more trustworthy; consider handling the error and t.Fatalf so profiling doesn’t silently proceed with incomplete data.

Suggested change
headTreeHashes, _ := BuildTreeHashIndex(ctx, headTree)
headTreeHashes, err := BuildTreeHashIndex(ctx, headTree)
if err != nil {
t.Fatalf("BuildTreeHashIndex failed: %v", err)
}

Copilot uses AI. Check for mistakes.
Comment on lines +73 to +85
firstPush := []scenario{
// Small sessions
{"10cp_100KB", 10, 100 * 1024},
{"50cp_500KB", 50, 500 * 1024},
// Average-sized sessions (~2.8MB real-world avg)
{"50cp_2500KB", 50, 2500 * 1024},
{"100cp_2500KB", 100, 2500 * 1024},
{"200cp_2500KB", 200, 2500 * 1024},
// Heavy sessions
{"50cp_10MB", 50, 10 * 1024 * 1024},
// Near-max sessions
{"10cp_50MB", 10, 50 * 1024 * 1024},
}
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The firstPush scenario list is duplicated between TestPushPerformance and TestPushProfile. Consider defining shared scenario slices (or a helper that returns them) to keep the two tests in sync and reduce maintenance overhead.

Copilot uses AI. Check for mistakes.
Comment on lines +612 to +620
firstPush := []scenario{
{"10cp_100KB", 10, 100 * 1024},
{"50cp_500KB", 50, 500 * 1024},
{"50cp_2500KB", 50, 2500 * 1024},
{"100cp_2500KB", 100, 2500 * 1024},
{"200cp_2500KB", 200, 2500 * 1024},
{"50cp_10MB", 50, 10 * 1024 * 1024},
{"10cp_50MB", 10, 50 * 1024 * 1024},
}
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The firstPush scenario list is duplicated between TestPushPerformance and TestPushProfile. Consider defining shared scenario slices (or a helper that returns them) to keep the two tests in sync and reduce maintenance overhead.

Copilot uses AI. Check for mistakes.
Comment on lines +533 to +534
// profilePrepareCondensation runs PrepareCondensation step by step with timing.
// This replicates the logic in manual_commit_condensation.go but with instrumentation.
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments claim this replicates PrepareCondensation, but some steps are effectively no-ops (simulate the filtering loop, and the summary timing measures an empty block). Either update the comments to reflect that these are placeholders, or implement the actual logic you intend to measure so the reported breakdown is meaningful.

Suggested change
// profilePrepareCondensation runs PrepareCondensation step by step with timing.
// This replicates the logic in manual_commit_condensation.go but with instrumentation.
// profilePrepareCondensation runs the PrepareCondensation-related steps with timing.
// It is a profiling helper that approximates the logic in manual_commit_condensation.go,
// and some sub-steps may be simplified or implemented as placeholders.

Copilot uses AI. Check for mistakes.
Comment on lines +569 to +578
// Sub-step 3: File filtering
ts2 := time.Now()
if len(committedFiles) > 0 && len(state.FilesTouched) > 0 {
for _, f := range state.FilesTouched {
_ = f // simulate the filtering loop
if _, ok := committedFiles[f]; ok {
_ = ok
}
}
}
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments claim this replicates PrepareCondensation, but some steps are effectively no-ops (simulate the filtering loop, and the summary timing measures an empty block). Either update the comments to reflect that these are placeholders, or implement the actual logic you intend to measure so the reported breakdown is meaningful.

Copilot uses AI. Check for mistakes.
Comment on lines +586 to +590
// Sub-step 5: Summary generation (disabled in test — summarize needs API key)
// Just measure the check
ts4 := time.Now()
// settings.IsSummarizeEnabled() check only
prof.pcSummary = time.Since(ts4)
Copy link

Copilot AI Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comments claim this replicates PrepareCondensation, but some steps are effectively no-ops (simulate the filtering loop, and the summary timing measures an empty block). Either update the comments to reflect that these are placeholders, or implement the actual logic you intend to measure so the reported breakdown is meaningful.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants