Skip to content

fix(review): accept frozen correction-plan binding after applied fix - #2240

Closed
Jalmar01 wants to merge 8 commits into
Gentleman-Programming:mainfrom
Jalmar01:fix/2132-review-status-post-correction
Closed

fix(review): accept frozen correction-plan binding after applied fix#2240
Jalmar01 wants to merge 8 commits into
Gentleman-Programming:mainfrom
Jalmar01:fix/2132-review-status-post-correction

Conversation

@Jalmar01

@Jalmar01 Jalmar01 commented Aug 2, 2026

Copy link
Copy Markdown

🎯 Scope

In scope (this PR):

  • Fix the correction-plan binding check in ReviewTargetStatusResult.Validate (line 375) to compare against the frozen authority identity via reviewAuthorityTargetIdentity, restoring correction_plan_required after a bounded correction with an uncommitted workspace.
  • Regression test TestCorrectionPlanStatusAcceptsFrozenBindingAfterAppliedFix (2 subtests, platform-agnostic) covering both branches of the fallback rule.

Out of scope (deliberate decisions):

  • Approach 2 rejected: re-binding CorrectionPlanRequest.TargetIdentity to the live workspace identity — larger blast radius, would weaken the plan's binding to the reviewed candidate.
  • Approach 3 deferred: the catch-all classifier at review_operation_contract.go:869-877 still emits retry_safe: true / next_action: retry for deterministic contract-internal validation failures. Known limitation, documented, not fixed here. If a deterministic failure occurs, the consumer still gets misleading retry advice; a follow-up change is required.
  • No schema change: gentle-ai.review-integration/v2 contract is unchanged.

🔗 Linked Issue

Closes #2132


🏷️ PR Type

  • type:bug — Bug fix (non-breaking change that fixes an issue)

📝 Summary

After a bounded correction in an active negotiated review, the read-only review status operation failed deterministically in the pre_native phase with operation_failed / retry_safe: true / next_action: retry. Root cause: ReviewTargetStatusResult.Validate compared the correction-plan request's TargetIdentity (bound to the frozen reviewed candidate) against the live workspace identity, which diverges the moment the bounded fix lands uncommitted. The fix compares against the frozen authority identity via the existing reviewAuthorityTargetIdentity helper (falling back to TargetIdentity when absent), restoring correction_plan_required after a bounded correction. No schema change, no new helper.


📂 Changes

File Change
internal/cli/review_status_contract.go One-line fix at line 375: compare correction-plan request binding against reviewAuthorityTargetIdentity(result) instead of result.TargetIdentity
internal/cli/review_status_contract_test.go +90 lines: TestCorrectionPlanStatusAcceptsFrozenBindingAfterAppliedFix — 2 platform-agnostic subtests (no forecast + changed workspace → correction_plan_required; forecast + request-build error → corrected_candidate_unavailable)

🧪 Test Plan

  • go build ./internal/cli/... — clean
  • go test ./internal/cli -run TestCorrectionPlanStatusAcceptsFrozenBindingAfterAppliedFix -count=1 -v — PASS 2/2 (fresh)
  • go test ./internal/cli — ok (233.7s)
  • go test ./internal/reviewtransaction — ok (176.3s)
  • go run ./internal/gofmtcheck — exit 0
  • go vet ./... — clean

Known pre-existing failures (not introduced by this PR): root go test ./... has pre-existing failures in internal/components/communitytool/pi_codegraph and internal/tui/sync clusters, present on main; verified via git stash baseline methodology per the repo collab skill. This PR only ran the focused suites above.


✅ Contributor Checklist

  • PR is linked to an issue with status:approved
  • PR stays within 400 changed lines (92 changed lines)
  • type:bug label applied — pending maintainer (contributor cannot add labels)
  • Unit tests pass (focused suites above)
  • Go format passes
  • E2E tests — not run (Docker E2E not executed for this candidate)
  • Benchmark validation — not applicable to this CLI fix
  • My commits follow Conventional Commits format
  • My commits do not include Co-Authored-By trailers

Pending maintainer actions

  • Apply type:bug label to this PR (contributor cannot apply labels — GraphQL 403 is policy)
  • Review / merge decision

💬 Notes for Reviewers

The correction-plan request binds to the frozen reviewed candidate (correction_plan_request.go:71). The contract result exposes AuthorityTargetIdentity only when it differs from the live TargetIdentity (review_status_contract.go:195-198), so the fallback keeps unchanged-workspace fixtures green. A diverged-identity + request-build-error path is unreachable through the facade (it routes to correction_repository_verification_required without a CorrectionRequest), so the test covers the reachable corrected_candidate_unavailable shape with an unchanged candidate.

Summary by CodeRabbit

  • Bug Fixes
    • Improved correction-request validation for authority-specific targets.
    • Fixed correction-plan status handling after bounded fixes, including changed workspaces and request-preparation errors.
    • Preserved accurate validation of revisions, lineage, and target relationships.
    • Improved recovery status selection when approved scope changes or committed deliveries are the only valid options.
    • Ensured status checks remain read-only and accurately distinguish reviewed candidates from the current workspace state.

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Correction status now uses the authority-specific target identity. Target status promotes eligible approved scope-changed recovery candidates. Regression coverage validates frozen bindings and read-only status behavior after bounded corrections.

Changes

Correction and recovery status

Layer / File(s) Summary
Authority binding and regression coverage
internal/cli/review_status_contract.go, internal/cli/review_status_contract_test.go
Correction requests use reviewAuthorityTargetIdentity(result). Regression coverage validates frozen lineage, revision, target identity, transition reasons, changed workspaces, forecast request-build errors, and read-only status behavior.
Scope-changed candidate promotion
internal/reviewtransaction/target_status.go
Target status promotes a sole approved scope-changed recovery or canonical approved scope-changed delivery when correction recoveries do not govern. Final-verification retries and escalated recoveries are excluded.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers: alan-thegentleman

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the correction-plan binding fix after an applied correction.
Linked Issues check ✅ Passed The changes address frozen authority binding and add regression coverage for post-correction status transitions required by issue #2132.
Out of Scope Changes check ✅ Passed All production and test changes support correction status handling and the requirements of issue #2132.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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/cli/review_status_contract_test.go`:
- Around line 1147-1150: Update the transition validation in the review status
test to assign status.NextTransition to transition and validate that transition
and its ReasonCode before accessing transition.CorrectionRequest. Only read
CorrectionRequest after confirming transition is non-nil, while preserving the
existing failure diagnostic output.
🪄 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: 8e4027d7-dca2-40ab-a5e9-d5a0a82493ef

📥 Commits

Reviewing files that changed from the base of the PR and between 545485d and 5402622.

📒 Files selected for processing (2)
  • internal/cli/review_status_contract.go
  • internal/cli/review_status_contract_test.go

Comment thread internal/cli/review_status_contract_test.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 303-330: In the scope-change promotion block, replace the
re-sliced `scopeChangedCandidates[:1]` assignment with a fresh one-element slice
containing `sc`, so updating `promoted[0].correctionRecovery` and
`promoted[0].recoveryDisposition` cannot mutate `scopeChangedCandidates[0]`.
Keep the existing promotion conditions and candidate replacement behavior
unchanged.
- Around line 281-302: Refactor the duplicate “sole governing authority” logic
in the surrounding target-status selection flow into a shared helper, and use it
from both this block and Block B. Add an explicit len(candidates) > 0 guard here
to match Block B, then remove the unreachable issue `#1826` fallback that checks
len(candidates) == 0 with len(approvedScopeRecovery) == 1.
🪄 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: 5f30b1b4-8211-413b-8be9-6ee263048e78

📥 Commits

Reviewing files that changed from the base of the PR and between 6eb6568 and 8d7aae8.

📒 Files selected for processing (1)
  • internal/reviewtransaction/target_status.go

Comment thread internal/reviewtransaction/target_status.go
Comment thread internal/reviewtransaction/target_status.go Outdated
Jalmar01 pushed a commit to Jalmar01/gentle-ai that referenced this pull request Aug 3, 2026
…x slice aliasing

- Extract isSoleCorrectionRecoveryGoverning helper used by both
  approvedScopeRecovery and scopeChangedCandidates promotion blocks
- Add explicit len(candidates) > 0 guard to approvedScopeRecovery block
- Fix scope-changed promotion: use fresh slice []targetStatusCandidate{sc}
  instead of scopeChangedCandidates[:1] to avoid mutating original
- Remove unreachable fallback (issue Gentleman-Programming#1826) — covered by first block

Addresses CodeRabbit findings on PR Gentleman-Programming#2240 (target_status.go).
Jalmar Villarreal added 4 commits August 3, 2026 14:28
Fix CodeRabbit finding: defensive nil check on NextTransition before
accessing CorrectionRequest field in regression test.
…ority in STATUS

Issue Gentleman-Programming#2345: STATUS was selecting a historical correction-required authority
instead of the approved delivery with canonical receipt when a small follow-up
touched the same tracked files. This inflated original_changed_lines (11619 vs
actual small diff) and incorrectly required recovery authorization.

Fix mirrors START command precedence (compact_store.go:1095-1099):
- recoveryCandidates (approved scope-changed deliveries) govern over
  claimants (correction-required authorities)
- Promotes approvedScopeRecovery when it's the sole governing authority
- Also promotes scopeChangedCandidates with canonical receipts when
  only correction-required claimants exist in candidates

All existing TestAssessTargetStatus* tests pass (27 tests).
…x slice aliasing

- Extract isSoleCorrectionRecoveryGoverning helper used by both
  approvedScopeRecovery and scopeChangedCandidates promotion blocks
- Add explicit len(candidates) > 0 guard to approvedScopeRecovery block
- Fix scope-changed promotion: use fresh slice []targetStatusCandidate{sc}
  instead of scopeChangedCandidates[:1] to avoid mutating original
- Remove unreachable fallback (issue Gentleman-Programming#1826) — covered by first block

Addresses CodeRabbit findings on PR Gentleman-Programming#2240 (target_status.go).
@Jalmar01
Jalmar01 force-pushed the fix/2132-review-status-post-correction branch from 79771dc to c9692a0 Compare August 3, 2026 19:29

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

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 567-576: Update isSoleCorrectionRecoveryGoverning to require every
candidate’s state to be StateCorrectionRequired, in addition to the existing
correctionRecovery, retry, and escalation checks. Return false for invalidated,
approved, or other states so only compact StateCorrectionRequired candidates can
be promoted over.
🪄 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: ccbd3cd7-5b40-4697-a97d-10c40444f45f

📥 Commits

Reviewing files that changed from the base of the PR and between 79771dc and c9692a0.

📒 Files selected for processing (3)
  • internal/cli/review_status_contract.go
  • internal/cli/review_status_contract_test.go
  • internal/reviewtransaction/target_status.go

Comment on lines +567 to +576
func isSoleCorrectionRecoveryGoverning(candidates []targetStatusCandidate) bool {
for _, c := range candidates {
if !c.correctionRecovery || c.finalVerificationRetry != nil {
return false
}
if c.recoveryDisposition == RecoveryEscalated {
return false
}
}
return true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Restrict promotion inputs to StateCorrectionRequired candidates.

This predicate accepts invalidated and approved scope recovery candidates because they set correctionRecovery. Lines 285 and 293 can then replace those governing candidates with another approved scope-changed candidate.

Require every promoted-over candidate to be a compact StateCorrectionRequired candidate.

Proposed fix
 func isSoleCorrectionRecoveryGoverning(candidates []targetStatusCandidate) bool {
 	for _, c := range candidates {
-		if !c.correctionRecovery || c.finalVerificationRetry != nil {
+		if c.compact == nil || c.compact.State.State != StateCorrectionRequired ||
+			!c.correctionRecovery || c.finalVerificationRetry != nil {
 			return false
 		}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func isSoleCorrectionRecoveryGoverning(candidates []targetStatusCandidate) bool {
for _, c := range candidates {
if !c.correctionRecovery || c.finalVerificationRetry != nil {
return false
}
if c.recoveryDisposition == RecoveryEscalated {
return false
}
}
return true
func isSoleCorrectionRecoveryGoverning(candidates []targetStatusCandidate) bool {
for _, c := range candidates {
if c.compact == nil || c.compact.State.State != StateCorrectionRequired ||
!c.correctionRecovery || c.finalVerificationRetry != nil {
return false
}
if c.recoveryDisposition == RecoveryEscalated {
return false
}
}
return true
🤖 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 567 - 576, Update
isSoleCorrectionRecoveryGoverning to require every candidate’s state to be
StateCorrectionRequired, in addition to the existing correctionRecovery, retry,
and escalation checks. Return false for invalidated, approved, or other states
so only compact StateCorrectionRequired candidates can be promoted over.

Jalmar Villarreal added 4 commits August 3, 2026 14:38
…ity check

isSoleCorrectionRecoveryGoverning now validates c.compact.State.State ==
StateCorrectionRequired, per CodeRabbit review. Only compact
StateCorrectionRequired candidates can be promoted over by an approved
recovery candidate.

Addresses CodeRabbit finding on PR Gentleman-Programming#2240 (target_status.go:567-576).
…change

Issue Gentleman-Programming#2349: STATUS was advertising escalated recovery for accounting-only
escalations (correction passed but budget exceeded), but RecoverCompactAuthority
rejected it because the target was byte-identical to the predecessor.

Fix: validateCompactRecoveryEdge now skips the target-changed check for
accounting-only escalations (compactAccountingOnlyEscalation returns true),
matching the behavior of STATUS which offers this recovery via the
accounting-only path.

This makes STATUS and Recover consistent for accounting-only escalations.
…n-eligibility

Issue Gentleman-Programming#2340: review finalize rejected --next-transition and --action-eligibility
with contract v2, even though review status accepts v2. The error was also
misclassified as operation_outcome_unknown instead of a clean validation error.

Changes:
- Update error message to allow v1 OR v2 contract
- Require v2 specifically when --next-transition or --action-eligibility is used
- Use reviewPreflightError for proper error classification
- Update test to expect new message format

Now finalize --next-transition --contract v2 works like status --next-transition --contract v2.
Fix potential 63-char SHA-256 issue when first byte is 0x00.
fmt.Sprintf with %x drops leading zero bytes; hex.EncodeToString preserves all bytes.

This addresses the root cause of issue Gentleman-Programming#2252 where negotiated review.start
emitted a target with 63 hex chars instead of 64.
@Alan-TheGentleman

Copy link
Copy Markdown
Contributor

Thanks for the original diagnosis and fix. The valid #2132 work was salvaged and merged through #2599 as b64b7c8f, preserving Jalmar Villarreal's authorship and the original commit provenance with cherry-pick -x.

I am closing this PR because its branch later accumulated six unrelated commits for #2345, #2349, #2340, and #2252. Some of those changes are now stale or unsafe against current main, and retaining them would make the review scope misleading. The focused replacement contains only the frozen correction-binding fix and its v2 regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type:bug Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

review status fails before authority evaluation after bounded correction

3 participants