fix(heartbeat): bind every runner to a live-verified Slack destination - #749
Merged
Conversation
added 3 commits
September 12, 2026 00:37
Before any main, employee, or script work, a threaded Slack job now proves that conversations.replies returns the configured parent in the configured channel. Missing, stale, mismatched, rate-limited, unauthenticated, and transport-failed lookups hold the tick without retry or cached success. Live hold reasons remain visible through GET/UI until recovery and invalidate when the destination changes. Every Slack runner reserves enforceDestination authority for its lifetime. Print children present the grant and are pinned to it. Native/pool, employee, and script paths cannot receive a fresh per-turn header, so their headerless Slack sends are refused during the reservation and the server owns final delivery. Interactive Auto grants keep their existing instance-wide contract outside that scheduled window. Planner retries receive fresh grants; channel-root and non-Slack jobs require no Slack read; mention-watch keeps the hit thread it just discovered. Refs #742 #745
A process-global safeguard fixed native heartbeat escape by blocking unrelated Slack sends for the full runner lifetime, which could be ten minutes. It also expired at 15 minutes while a native collector may legitimately wait 20. Destination enforcement is now per process. Grant activation happens before any runtime branch. Print and employee children inherit the header; Cursor and Grok use a request-lifetime native process; Codex App, Claude, and Pi get fresh grant-bearing acquisitions; Pi now launches from its captured env; script children receive the same header explicitly. The enforced grant lives 25 minutes, beyond every runner ceiling, then follows normal revoke cleanup. Unrelated Auto/interactive Slack sends remain available while scheduled work runs. Actual native Grok verifies the grant reached its environment, and source contract tests cover all runtime branches plus the TTL relation. Refs #745
Replace the process-global Slack lock with per-runtime grant injection. Grant activation now precedes every spawn branch. Cursor/Grok run request-lifetime, Codex App/Claude/Pi acquire fresh grant-bearing processes, employee metadata carries the same request and target, and scripts receive the grant in their child environment. Employee Pi now passes the captured spawn env to spawnPiRpc as well as the main pool path. Enforced grants live 25 minutes, longer than the 20-minute collector ceiling, without blocking unrelated Auto or interactive Slack sends. Refs #745
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Depends on the run-identity layer below.
Problem: a heartbeat destination could be syntactically complete while pairing a Slack channel with a stale or unrelated parent ts. The runner spent model/script work before discovering it had nowhere safe to send, live failures were visible only in logs, and Auto runtimes could call Slack outside the scheduled destination.
This layer hard-binds every runner:
conversations.replies(channel, ts, limit=1); the first row must be the configured parent;GET /api/heartbeat/UI until recovery and invalidate when the destination changes;enforceDestinationgrant (collector ceiling: 20 minutes);slack_destination_mismatch;Operational migration already applied on the 3457 home: the five channel-only jobs now explicitly use
scope:"channel_root"; the three threaded jobs were read-only verified live with exact parent ts.Validation: heartbeat/API/security suite 158/158; final runtime/Pi/Grok batch 114/114; audit-fix batch 284/284;
npm run gate:all23/23; private boundary pass. Independent grok-4.6 review: PASS, no merge blocker.Closes #744.
Closes #745.