mirror of
https://github.com/nearai/ironclaw.git
synced 2026-09-03 08:06:01 +08:00
`qa_7d_slack_bug_message_trigger` has failed every scheduled canary run since 2026-08-28 03:09Z — 33 consecutive runs — always by burning its full 180s wait and raising "Slack event was not accepted into a Reborn run before timeout". The event was always accepted. The harness could not see it. PR #7941 moved the ingress dedup key off Slack's envelope `event_id`, because Slack sends twins (`app_mention` + `message`) with distinct envelope ids for a single post and keying on them admits two runs for one mention. Ingress now builds `external_event_id` from the message itself, `slack-{installation}-msg-{team}-{channel}-{ts}` (`build_message_event_id`, crates/extensions/packages/slack/src/payload.rs). `_slack_event_run_id_for_event` still searched the persisted idempotency records for the envelope id, a string that is no longer written anywhere, so it returned `None` on every poll. The lookup is renamed to `_slack_event_run_id_for_message` and keyed on `(channel, ts)` — the trailing, installation- and team-independent part of the id the harness can reconstruct without resolving an installation id it never sees. `_post_signed_slack_dm_event` mints that `ts`, so it now hoists it out of the payload literal and returns it with the derived `message_key`. Hoisting also removes a latent defect: `ts` was built from two separate `time.time()` calls that could straddle a second boundary and post a timestamp off by one second. Ingress itself was never broken, and this is why the break stayed invisible: `qa_5d_slack_strategy_doc_answer` injects the same signed DM event through the same path and has passed 60/60 runs, because it asserts on the answer landing back in Slack rather than on the lookup. The same lookup backs `_approve_slack_event_gates`, which has therefore been silently no-opping for every Slack-triggered run — returning no run id instead of approving gates for qa_5d and qa_7e. That path is currently masked by `AGENT_AUTO_APPROVE_TOOLS=true` in the canary workflow, so it was untested rather than failing; it is now exercised again. The existing `test_slack_event_run_id_reads_idempotency_record` fixture pinned the pre-#7941 id shape, which is why no test caught this. Its fixtures move to the shape production writes, verified against a real canary database (run 33507434003). Claude-Session: https://claude.ai/code/session_01VALcHTcTeaar6JRGuPnobL Co-authored-by: Claude Opus 5 <noreply@anthropic.com>