Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/entire/cli/explain.go
Original file line number Diff line number Diff line change
Expand Up @@ -816,7 +816,7 @@ func computeReachableFromMain(repo *git.Repository) map[plumbing.Hash]bool {
}

// Walk main's first-parent chain to build the set
_ = walkFirstParentCommits(repo, mainBranchHash, 1000, func(c *object.Commit) error { //nolint:errcheck // Best-effort
_ = walkFirstParentCommits(repo, mainBranchHash, strategy.MaxCommitTraversalDepth, func(c *object.Commit) error { //nolint:errcheck // Best-effort
reachableFromMain[c.Hash] = true
return nil
})
Expand Down
5 changes: 3 additions & 2 deletions cmd/entire/cli/hooks_geminicli_handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,10 @@ func handleGeminiBeforeAgent() error {
}
if input.UserPrompt != "" {
// Truncate long prompts for logging
const maxPromptPreviewLen = 100
promptPreview := input.UserPrompt
if len(promptPreview) > 100 {
promptPreview = promptPreview[:100] + "..."
if len(promptPreview) > maxPromptPreviewLen {
promptPreview = promptPreview[:maxPromptPreviewLen] + "..."
}
logArgs = append(logArgs, slog.String("prompt_preview", promptPreview))
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/entire/cli/rewind.go
Original file line number Diff line number Diff line change
Expand Up @@ -1155,7 +1155,7 @@ func countCommitsBetween(repo *git.Repository, ancestor, descendant plumbing.Has
count := 0
current := descendant

for count < 1000 { // Safety limit
for count < strategy.MaxCommitTraversalDepth { // Safety limit
if current == ancestor {
return count, nil
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/entire/cli/strategy/auto_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -1054,8 +1054,8 @@ func (s *AutoCommitStrategy) findReferencedCheckpoints(repo *git.Repository) map
count := 0
_ = iter.ForEach(func(c *object.Commit) error { //nolint:errcheck // Best effort
count++
if count > 1000 {
return errors.New("limit reached")
if count > MaxCommitTraversalDepth {
return errStop
}
if visited[c.Hash] {
return nil
Expand Down
8 changes: 6 additions & 2 deletions cmd/entire/cli/strategy/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ const (
branchMaster = "master"
)

// MaxCommitTraversalDepth is the safety limit for walking git commit history.
// Prevents unbounded traversal in repositories with very long histories.
const MaxCommitTraversalDepth = 1000

// errStop is a sentinel error used to break out of git log iteration.
// Shared across strategies that iterate through git commits.
// NOTE: A similar sentinel exists in checkpoint/temporary.go - this is intentional.
Expand All @@ -49,7 +53,7 @@ func IsEmptyRepository(repo *git.Repository) bool {

// IsAncestorOf checks if commit is an ancestor of (or equal to) target.
// Returns true if target can reach commit by following parent links.
// Limits search to 1000 commits to avoid excessive traversal.
// Limits search to MaxCommitTraversalDepth commits to avoid excessive traversal.
func IsAncestorOf(repo *git.Repository, commit, target plumbing.Hash) bool {
if commit == target {
return true
Expand All @@ -65,7 +69,7 @@ func IsAncestorOf(repo *git.Repository, commit, target plumbing.Hash) bool {
count := 0
_ = iter.ForEach(func(c *object.Commit) error { //nolint:errcheck // Best-effort search, errors are non-fatal
count++
if count > 1000 {
if count > MaxCommitTraversalDepth {
return errStop
}
if c.Hash == commit {
Expand Down
5 changes: 3 additions & 2 deletions cmd/entire/cli/strategy/manual_commit_condensation.go
Original file line number Diff line number Diff line change
Expand Up @@ -532,9 +532,10 @@ func generateContextFromPrompts(prompts []string) []byte {

for i, prompt := range prompts {
// Truncate very long prompts for readability
const maxDisplayPromptLen = 500
displayPrompt := prompt
if len(displayPrompt) > 500 {
displayPrompt = displayPrompt[:500] + "..."
if len(displayPrompt) > maxDisplayPromptLen {
displayPrompt = displayPrompt[:maxDisplayPromptLen] + "..."
}
buf.WriteString(fmt.Sprintf("### Prompt %d\n\n", i+1))
buf.WriteString(displayPrompt)
Expand Down
7 changes: 6 additions & 1 deletion redact/redact.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ var secretPattern = regexp.MustCompile(`[A-Za-z0-9/+_=-]{10,}`)
// and tokens which tend to have entropy well above 5.0.
const entropyThreshold = 4.5


// RedactedPlaceholder is the replacement text used for redacted secrets.
const RedactedPlaceholder = "REDACTED"

// String replaces high-entropy strings matching secretPattern with REDACTED.
var (
gitleaksDetector *detect.Detector
gitleaksDetectorOnce sync.Once
Expand Down Expand Up @@ -98,7 +103,7 @@ func String(s string) string {
prev := 0
for _, r := range merged {
b.WriteString(s[prev:r.start])
b.WriteString("REDACTED")
b.WriteString(RedactedPlaceholder)
prev = r.end
}
b.WriteString(s[prev:])
Expand Down