Skip to content

feat(gate): execute repair and retry-posts paths#49

Merged
rianjs merged 3 commits into
mainfrom
feat/cr-14c-gate-repair-retry-posts
Jun 1, 2026
Merged

feat(gate): execute repair and retry-posts paths#49
rianjs merged 3 commits into
mainfrom
feat/cr-14c-gate-repair-retry-posts

Conversation

@rianjs
Copy link
Copy Markdown
Contributor

@rianjs rianjs commented Jun 1, 2026

Summary

  • execute pruned-ledger partial repair by allocating recovery runs, planning the missing submit_review, and posting through outbox
  • execute --retry-posts by proving desired outcome, resetting required terminal failures, and reposting through outbox
  • preserve no-local-row-only repair semantics, aborted audit-only behavior, base prechecks, and limiter scoping

Verification

  • rtk go test ./internal/gateio
  • rtk go test ./internal/gateio ./internal/outbox ./internal/gate ./internal/ledger
  • rtk go test ./...
  • rtk go test -race ./internal/gateio
  • rtk make check

Closes #23

@rianjs
Copy link
Copy Markdown
Contributor Author

rianjs commented Jun 1, 2026

Findings

Major: requireOutboxLimiter runs before the base-moved precheck in both repair and retry paths (internal/gateio/gateio.go:449, internal/gateio/gateio.go:492). That means a moved-base repair/retry with a nil limiter returns outbox limiter is required instead of StatusBaseMovedAbort, even though no outbox posting should happen. This drifts from the pinned limiter scope and base-precheck intent. Move the limiter check after baseMovedDecision, before local mutation/posting, and add moved-base + nil-limiter coverage for repair and retry.

Major: Repair/retry mutate local ledger state before calling outbox.Post, but there is no coverage for outbox errors after those mutations start (internal/gateio/gateio.go:468, internal/gateio/gateio.go:472, internal/gateio/gateio.go:513, internal/gateio/gateio.go:516). outbox.Post can still return a Go error on host-state reads or validation before recording a post attempt, leaving a recovery run/action inserted or failed-terminal actions reset with no returned OutboxResult. Please define and test the intended durable state for those failures, especially ListInlineThreads/host-read failure after repair allocation and after retry reset.

Nit: StatusRepairUnsupported / StatusRetryPostsUnsupported remain defined but are no longer returned by CR-14c (internal/gateio/gateio.go:31). Removing the obsolete statuses would avoid stale CLI/status mapping assumptions.

@rianjs
Copy link
Copy Markdown
Contributor Author

rianjs commented Jun 1, 2026

No findings on the targeted re-review.

The prior issues are addressed: repair/retry now perform the base-moved precheck before limiter validation, outbox errors after mutation return a stable execution Result with durable-state coverage, and the obsolete unsupported statuses are gone.

Copy link
Copy Markdown

@monit-reviewer monit-reviewer left a comment

Choose a reason for hiding this comment

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

Automated PR Review

Reviewed commit: f1a54b7

Summary

Reviewer Findings
harness-engineering:harness-architecture-reviewer 1
harness-engineering:harness-self-documenting-code-reviewer 1
harness-engineering:harness-architecture-reviewer (1 findings)

⚠️ Should Fix - internal/gateio/gateio.go:477

In executeRepair, if allocateRepair succeeds but insertRepairSubmitReview subsequently fails, an orphaned run is written to the ledger with no planned actions. The guard at the top of executeRepair checks GetRun and returns 'repair run already exists' on all future attempts, permanently blocking automatic repair for this PR until the ledger row is manually removed. Either wrap allocateRepair+insertRepairSubmitReview in a single transaction, or delete the allocated run on insertRepairSubmitReview failure before returning the error.

harness-engineering:harness-self-documenting-code-reviewer (1 findings)

💡 Suggestion - internal/gateio/gateio.go:601

resetRequiredFailedTerminalActions clears Error, FailureClass, PostedAt, and UpstreamID but deliberately preserves Attempts and AttemptedAt. The name 'reset' implies a full state reset; the selective preservation is only discoverable via the test. A name like resetRequiredFailedTerminalActionsForRetry, or a brief inline comment naming the invariant, would make the behavior explicit at the call site.

3 info-level observations excluded. Run with --verbose to include.

2 PR discussion threads considered.


Completed in 2m 22s | $1.47 | sonnet | daemon 0.2.121 | Glorfindel
Field Value
Model sonnet
Reviewers hybrid-synthesis, harness-engineering:harness-architecture-reviewer, harness-engineering:harness-enforcement-reviewer, harness-engineering:harness-knowledge-reviewer, harness-engineering:harness-self-documenting-code-reviewer, security:security-code-auditor
Engine claude · sonnet
Reviewed by pr-review-daemon · monit-pr-reviewer
Duration 2m 22s wall · 8m 42s compute (Reviewers: 1m 46s · Synthesis: 33s)
Cost $1.47
Tokens 368.7k in / 44.6k out
Turns 11

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost
hybrid-synthesis sonnet 31.7k 1.7k 0 31.7k (1h) $0.15
harness-engineering:harness-architecture-reviewer sonnet 70.5k 14.0k 29.7k 40.8k (1h) $0.39
harness-engineering:harness-enforcement-reviewer sonnet 105.4k 8.7k 67.5k 37.9k (1h) $0.31
harness-engineering:harness-knowledge-reviewer sonnet 65.9k 7.0k 29.7k 36.2k (1h) $0.27
harness-engineering:harness-self-documenting-code-reviewer sonnet 65.1k 6.3k 29.7k 35.4k (1h) $0.26
security:security-code-auditor haiku 30.1k 6.9k 0 30.1k (1h) $0.09

Re-reviews only run when @monit-reviewer is re-requested as a reviewer — push as many commits as you need, then re-request when ready. PRs targeting branches other than main, master are skipped, even when @monit-reviewer is re-requested.

Comment thread internal/gateio/gateio.go
}

desired, event, err := repairOutcomeEvent(decision.Outcome)
if err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Medium (harness-engineering:harness-architecture-reviewer): In executeRepair, if allocateRepair succeeds but insertRepairSubmitReview subsequently fails, an orphaned run is written to the ledger with no planned actions. The guard at the top of executeRepair checks GetRun and returns 'repair run already exists' on all future attempts, permanently blocking automatic repair for this PR until the ledger row is manually removed. Either wrap allocateRepair+insertRepairSubmitReview in a single transaction, or delete the allocated run on insertRepairSubmitReview failure before returning the error.

Reply to this thread when addressed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed - delete recovery run if repair action insert fails.

Comment thread internal/gateio/gateio.go
}
}
return nil
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔵 Low (harness-engineering:harness-self-documenting-code-reviewer): resetRequiredFailedTerminalActions clears Error, FailureClass, PostedAt, and UpstreamID but deliberately preserves Attempts and AttemptedAt. The name 'reset' implies a full state reset; the selective preservation is only discoverable via the test. A name like resetRequiredFailedTerminalActionsForRetry, or a brief inline comment naming the invariant, would make the behavior explicit at the call site.

Reply to this thread when addressed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed - renamed retry reset helper to make attempt preservation explicit.

Copy link
Copy Markdown

@monit-reviewer monit-reviewer left a comment

Choose a reason for hiding this comment

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

Automated PR Review

Reviewed commit: 67cf79b | Previous: f1a54b7 (incremental)

Summary

No issues found.

4 PR discussion threads considered.


Completed in 3m 07s | $0.92 | sonnet | daemon 0.2.121 | Glorfindel
Field Value
Model sonnet
Mode Re-review · Cycle 2 · Session resumed
Reviewers hybrid-synthesis, harness-engineering:harness-architecture-reviewer, harness-engineering:harness-enforcement-reviewer, harness-engineering:harness-knowledge-reviewer, harness-engineering:harness-self-documenting-code-reviewer, security:security-code-auditor
Engine claude · sonnet
Reviewed by pr-review-daemon · monit-pr-reviewer
Duration 3m 07s wall · 4m 31s compute (Reviewers: 2m 44s · Synthesis: 12s)
Cost $0.92
Tokens 356.2k in / 7.2k out
Turns 6

Per-workstream usage

Workstream Model In Out Cache read Cache create Cost
hybrid-synthesis sonnet 36.3k 581 18.6k 17.6k (1h) $0.08
harness-engineering:harness-architecture-reviewer sonnet 64.0k 85 0 64.0k (1h) $0.24
harness-engineering:harness-enforcement-reviewer sonnet 58.7k 80 0 58.7k (1h) $0.22
harness-engineering:harness-knowledge-reviewer sonnet 57.0k 129 0 57.0k (1h) $0.22
harness-engineering:harness-self-documenting-code-reviewer sonnet 56.3k 222 56.3k 0 $0.02
security:security-code-auditor haiku 57.6k 5.9k 57.6k 0 $0.04
discussion-summarizer 26.3k 213 0 26.3k (1h) $0.10

Re-reviews only run when @monit-reviewer is re-requested as a reviewer — push as many commits as you need, then re-request when ready. PRs targeting branches other than main, master are skipped, even when @monit-reviewer is re-requested.

@rianjs rianjs merged commit 30b7f54 into main Jun 1, 2026
8 checks passed
@rianjs rianjs deleted the feat/cr-14c-gate-repair-retry-posts branch June 1, 2026 05:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

CR-14c: gate **repair + retry-posts execution**

2 participants