fix(heartbeat): bound provider-advertised retry horizons (BLO-23438) - #1225
Conversation
Clamp untrusted capacity reset hints with additive jitter and bound transient retry floors while preserving provider_quota reset semantics. Co-Authored-By: Paperclip <noreply@paperclip.ing>
|
Bugbot is not enabled for your account, so this pull request was not reviewed. Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs. |
|
@ally please review exact head 31ebed4 only. This independent kkroo successor to #1186 bounds untrusted provider capacity hints with a 15-minute cap plus additive jitter, clamps transient retry floors at 24 hours, preserves provider_quota, and deliberately excludes #1187 watchdog or manager-chain authorization changes. |
There was a problem hiding this comment.
Ally — Consolidated PR Review
Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 31ebed4
Critical Issues (0)
Important Issues (0)
Suggestions (0)
Strengths
- The capacity-specific resolver centralizes ceiling, fallback, jitter, and provenance behavior, with deterministic coverage for boundary conditions.
- The persistence-path test verifies that the clamped retry floor, original advertised horizon, and operator-facing clamp metadata all reach the scheduled run.
- The second clamp closes the finalized-run retry-floor path, preventing it from reintroducing the same multi-day park.
Recommended Action
- Merge when the remaining required checks pass.
allyblockcast
left a comment
There was a problem hiding this comment.
Ally — Consolidated PR Review
Lenses: pr-review-toolkit (code, tests, comments, errors, types) + gstack/review + native-codex.
Reviewed head: 31ebed4
Critical Issues (0)
Important Issues (0)
Suggestions (0)
Strengths
- The capacity-specific resolver centralizes ceiling, fallback, jitter, and provenance behavior, with deterministic coverage for boundary conditions.
- The persistence-path test verifies that the clamped retry floor, original advertised horizon, and operator-facing clamp metadata all reach the scheduled run.
- The second clamp closes the finalized-run retry-floor path, preventing it from reintroducing the same multi-day park.
Recommended Action
- Merge when the remaining required checks pass.
…ents observable (BLO-24011) A `ccrotate_capacity` park is re-decided every time the run comes due and the pool is still exhausted, but the promotion-time re-defer updated only `scheduledRetryAttempt`/`scheduledRetryAt`. Every descriptive field stayed behind from the *first* denial, so the incident row read `penstockRetryAfterSeconds: 3834` and `retryNotBefore: 08:00Z` beside a `scheduledRetryAt` four days out — two decisions wearing one row, two orders of magnitude apart, on attempt 1, with nothing explaining why. The horizon clamp itself landed in #1225. This closes the remaining gap: - Route both writers through `applyCcrotateCapacityDecision` so a re-defer clears the previous decision wholesale before writing the current one, and the two writers cannot drift. - Add `GET /api/companies/:companyId/parked-agents` + the `paperclipListParkedAgents` MCP tool, answering "which agents cannot run, and until when?" without invoking a heartbeat on each one to find out. Reuses the same per-agent read filter as the agents list, so an agent caller sees exactly what it is already allowed to see. - `overdueMs` separates "parked a long time" from "due but the sweep is not draining it" — different failures that looked identical before. Regression replays the incident end to end: initial denial advertising 3834s, promotion-time denial advertising ~4.6 days. Asserts attempt 1 never parks past 24h, that the row's retry floor and scheduled instant agree, and that the superseded 3834s figure is gone rather than sitting beside a park it no longer explains. Verified as a negative control: reverting the resultJson write fails the test. Co-Authored-By: Claude <noreply@anthropic.com>
Thinking Path
Linked Issues or Issue Description
Refs BLO-23438 and BLO-18278. This is the independent kkroo-authored successor to app/allyblockcast PR #1186.
Related but intentionally excluded: #1187's watchdog and manager-chain authorization changes, #1142's distinct over-cap parking approach, and #1196's recovery work.
What Changed
Verification
Risks
The change intentionally re-probes earlier when an untrusted capacity hint exceeds the ceiling, so an outage can create bounded extra probe attempts instead of a multi-day freeze. Additive jitter never retries before a respected reset, provider_quota remains unbounded, and the patch has no schema or API migration.
Model Used
OpenAI GPT-5 Codex with tool-assisted review-context inspection, source reconstruction, and local test execution.
Checklist