fix(review): retain staged-equivalent receipts in status - #2115
Conversation
📝 WalkthroughWalkthroughThe change preserves approved receipts when staged files exactly match the reviewed intended transition. Target status validates staged candidates through the pre-commit gate. Tests cover mismatched paths, content, modes, lineage selectors, receipt identity, and approval state. ChangesApproved staged receipt retention
Estimated code review effort: 3 (Moderate) | ~20 minutes Possibly related issues
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/reviewtransaction/target_status.go`:
- Around line 247-254: Update the PRE-COMMIT targeting flow around
AssessCompactGateTarget so assessment uses the same live status snapshot
represented by the returned TargetIdentity, rather than rebuilding from the
mutable live index; alternatively reject the candidate unless the assessed
snapshot identity equals live.Identity. Add an interleaving test covering a
staged change between the initial snapshot and gate assessment.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: d21b583d-71c6-4051-b842-27d484ca6bda
📒 Files selected for processing (3)
internal/cli/review_next_transition_test.gointernal/reviewtransaction/target_status.gointernal/reviewtransaction/target_status_test.go
| assessment, assessmentErr := AssessCompactGateTarget(ctx, repo, state, NativeGateRequestInput{ | ||
| Gate: GatePreCommit, LineageID: state.LineageID, | ||
| }) | ||
| if assessmentErr != nil { | ||
| return targetStatusFailure(base, assessmentErr) | ||
| } | ||
| if assessment.Applicability == CompactGateTargetExact { | ||
| candidates = append(candidates, candidate) |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
ast-grep outline internal/reviewtransaction/target_status.go --items all
rg -n -C 16 '^func AssessCompactGateTarget\b|^func targetStatusForCandidate\b|BuildStoredSnapshot|TargetIdentity' internal/reviewtransaction -g '*.go'Repository: Gentleman-Programming/gentle-ai
Length of output: 50388
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the status flow and compact gate API without reading unrelated files.
wc -l internal/reviewtransaction/target_status.go internal/reviewtransaction/compact_native_gate.go internal/reviewtransaction/compact_state.go
sed -n '1,290p' internal/reviewtransaction/target_status.go
printf '\n--- compact_native_gate.go ---\n'
sed -n '1,260p' internal/reviewtransaction/compact_native_gate.go
printf '\n--- compact_state.go relevant --\n'
rg -n -C 10 'type NativeGateRequestInput|func AssessCompactGateTarget|TargetIdentity|InitialSnapshot|BuildStoredSnapshot|AssessTargetStatusWithSnapshot' internal/reviewtransaction/compact_native_gate.go internal/reviewtransaction/compact_state.go internal/reviewtransaction/target_status.goRepository: Gentleman-Programming/gentle-ai
Length of output: 387
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- locate relevant files ---'
git ls-files internal/reviewtransaction | grep -E '(target_status|compact|native|gate|state)\.go$' | sed -n '1,120p'
printf '%s\n' '--- target_status.go top and relevant ranges ---'
sed -n '1,280p' internal/reviewtransaction/target_status.go
printf '%s\n' '--- search for NativeGateRequestInput and AssessCompactGateTarget ---'
rg -n -C 16 'type NativeGateRequestInput|func AssessCompactGateTarget|AssessCompactGateTarget\(' internal/reviewtransaction -g '*.go'
printf '%s\n' '--- search for snapshot builders/stores in target_status.go ---'
rg -n -C 8 'BuildStoredSnapshot|AssessTargetStatusWithSnapshot|targetStatusForCandidate|TargetIdentity|AssessCompactGateTarget' internal/reviewtransaction/target_status.go -g '*.go'Repository: Gentleman-Programming/gentle-ai
Length of output: 50387
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- compact_gate.go ---'
sed -n '1,180p' internal/reviewtransaction/compact_gate.go
printf '%s\n' '--- gate context/build functions ---'
rg -n -C 12 'func buildCompactGateRequest|func buildCompactLifecycleSnapshot|type GateRequest|type Stage|func.*Staged' internal/reviewtransaction -g '*.go'
printf '%s\n' '--- compact.go relevant snapshot types/functions ---'
rg -n -C 10 'type CompactState|type CompactRecord|type Snapshot|func BuildStoredSnapshot|type SnapshotBuilder|TargetIdentity|CandidateTree|PathsDigest|CandidatePathDigest' internal/reviewtransaction/compact.go internal/reviewtransaction/target_status.go -g '*.go'Repository: Gentleman-Programming/gentle-ai
Length of output: 50388
Bind PRE-COMMIT gate targeting to the status snapshot.
assessTargetStatusSnapshot uses live as the returned TargetIdentity, but AssessCompactGateTarget rebuilds the staged target from the live index via NativeGateRequestInput. A staged change between the initial snapshot and this gate can make the exact gate accept one snapshot while STATUS reports a newer status snapshot identity. Derive this assessment from the same live snapshot, or fail closed unless the assessed snapshot identity matches live.Identity, and add an interleaving test for that TOCTOU window.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@internal/reviewtransaction/target_status.go` around lines 247 - 254, Update
the PRE-COMMIT targeting flow around AssessCompactGateTarget so assessment uses
the same live status snapshot represented by the returned TargetIdentity, rather
than rebuilding from the mutable live index; alternatively reject the candidate
unless the assessed snapshot identity equals live.Identity. Add an interleaving
test covering a staged change between the initial snapshot and gate assessment.
🔗 Linked Issue
Closes #1951
🏷️ PR Type
What kind of change does this PR introduce?
type:bug— Bug fix (non-breaking change that fixes an issue)type:feature— New feature (non-breaking change that adds functionality)type:docs— Documentation onlytype:refactor— Code refactoring (no functional changes)type:chore— Build, CI, or tooling changestype:breaking-change— Breaking change (fix or feature that changes existing behavior)📝 Summary
Retains an approved compact receipt for negotiated pre-commit STATUS only when every reviewed intended-untracked path is staged byte- and mode-equivalently with unchanged candidate scope. The exact match routes to
review.validateinstead of a freshreview.start; partial staging, extra paths, content drift, and mode drift remain fail closed. Explicit-lineage and unqualified STATUS return the same authority.📂 Changes
Review size: 198 additions, 0 deletions (198 changed lines).
internal/reviewtransaction/target_status.gointernal/reviewtransaction/target_status_test.gointernal/cli/review_next_transition_test.goreview.validateidentically with or without an explicit lineage.🧪 Test Plan
Focused unit tests
Both commands passed, including five consecutive isolated runs.
Build and static checks
All passed.
Broader package attempts
Each timed out at 10 minutes without assertion failures in unrelated raw-fixture Git commands. The focused tests above passed independently and five consecutive times; this PR does not claim that either full package suite passed.
Go Format
Not run: the supplied verification covers
git diff --check, notgo run ./internal/gofmtcheck.E2E Tests (Docker required)
Not run: this bounded review-status change was validated with focused Go tests and repository build/static checks.
Benchmark Validation
Not run: no
bench/files or benchmark claims change.go test ./...)go run ./internal/gofmtcheck)cd e2e && ./docker-test.sh)🤖 Automated Checks
Closes #1951status:approvedtype:*Labelgo test ./...must passgo run ./internal/gofmtcheckmust passcd e2e && ./docker-test.shmust pass✅ Contributor Checklist
status:approvedsize:exceptionwith rationale documentedtype:*label to this PRgo test ./...)go run ./internal/gofmtcheck)cd e2e && ./docker-test.sh)Co-Authored-Bytrailers💬 Notes for Reviewers
guard:populationcontract changes;.guard-population-baseline.txtis unchanged. Registry/declaration checks are not used as semantic proof.↩️ Rollback Boundary
Revert commit
97176fc3794182a2acc69048b2c174b31260456eto remove only staged-equivalent receipt retention and its focused coverage; unrelated STATUS behavior remains outside this work unit.Pending maintainer actions
type:bugto this PR.Summary by CodeRabbit