Repository navigation
fix(OMN-19520): the stall alert fires on handler errors that never form a run - #2879
Merged
jonahgabriel merged 5 commits intoSep 25, 2026
Merged
jonahgabriel merged 5 commits into
jonahgabriel merged 5 commits into
Conversation
Disarms the OMN-16344 release-identity gate that publishing v0.4.216 armed against dev. Triggered-by: https://github.com/OmniNode-ai/omnimarket/actions/runs/36050759868
…rm a run A projection that fails every event on a sparse topic left each failing window alone between IDLE windows, so the consecutive-run rule graded it PENDING_CONFIRMATION or NO_ALERT and delivered nothing. On the .201 dev lane the work_events session-started group failed 197 windows between 2026-09-21 and 2026-09-24 while the stall alert posted only when two failures happened to land in adjacent 30 s windows, titled STALLED. A contract-declared handler_error_windows threshold (1) now fires FAIL_HANDLER_ERRORS when that many windows of the trailing read carry a handler error, unless a confirmed stall already covers them. The Slack text names handler errors, the failing-window count and the totals, and the idempotency key is bucketed on the newest failing window so the existing publish ledger keeps it to one post per consumer, topic and bucket.
✅ Architectural Review — PASSEDErrors: 0 What this checks
No architectural violations found. Static architectural lint — no model inference (OMN-14176). |
✅ Hostile Reviewer — PASSEDBlocking findings (critical/error): 0 Gate semantics
Powered by omniintelligence.review_pairing.cli_review — node-based adversarial review via HandlerLlmCliSubprocess (OMN-8524) |
jonahgabriel
marked this pull request as ready for review
September 25, 2026 02:00
onexbot-occ-writer Bot
added a commit
to OmniNode-ai/onex_change_control
that referenced
this pull request
Sep 25, 2026
…nimarket#2879 The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited. Ticket: OMN-16859 (AC3b) Onex-Workflow: OCC Receipt Runner Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/36084520756
…alert-fires-on-isolated-handler-errors # Conflicts: # pyproject.toml # uv.lock
onexbot-occ-writer Bot
added a commit
to OmniNode-ai/onex_change_control
that referenced
this pull request
Sep 25, 2026
…nimarket#2879 The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited. Ticket: OMN-16859 (AC3b) Onex-Workflow: OCC Receipt Runner Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/36119705466
jonahgabriel
pushed a commit
to OmniNode-ai/onex_change_control
that referenced
this pull request
Sep 25, 2026
…imarket#2879 (#11191) * evidence(OMN-19520): author OCC companion for OmniNode-ai/omnimarket#2879 OCC companion by node_pr_lifecycle_fix_effect (OMN-13317 F1 / OMN-13990 / OMN-14285). Product PR head 765ab4e5934a94354c5e1825fa509e5fb4a64d2a. * evidence(OMN-19520): self-bind OCC#11191 + rebind contract_sha256 * evidence(OMN-16859): executed test_passes receipts for OmniNode-ai/omnimarket#2879 The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited. Ticket: OMN-16859 (AC3b) Onex-Workflow: OCC Receipt Runner Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/36084520756 * evidence(OMN-16859): executed test_passes receipts for OmniNode-ai/omnimarket#2879 The declared checks were executed for real in the OmniNode-ai/omnimarket checkout at the PR head by the product-repo OCC receipt runner, and the results written append-only into this companion. Producer-minted PENDING receipts are superseded by a net-new record; no existing receipt was edited. Ticket: OMN-16859 (AC3b) Onex-Workflow: OCC Receipt Runner Onex-Run: https://github.com/OmniNode-ai/omnimarket/actions/runs/36119705466 --------- Co-authored-by: omnimarket-bot <bot@omninode.ai> Co-authored-by: onexbot-occ-writer[bot] <307849072+onexbot-occ-writer[bot]@users.noreply.github.com>
jonahgabriel
deleted the
jonah/omn-19520-stall-alert-fires-on-isolated-handler-errors
branch
September 25, 2026 12:17
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.
Summary
Ticket: OMN-19520 (parent epic OMN-16776, platform observability). Found while working OMN-19513.
The work_events projection on the .201 dev lane failed every session-started event for four days, and nothing named it.
omninode_internal.consumer_flow_windowscounted every failure (handler_errors,messages_dlq). The existing alert effect,node_consumer_flow_stall_alert_effect, reads exactly that table, but it fires only on a run ofconfirm_windows(2) consecutive STALLED windows that carry failure evidence. Session-started is sparse (one event every few minutes, 30 s windows), so each failure sat alone between IDLE windows. The run rule graded itPENDING_CONFIRMATION(not delivered) orNO_ALERT. It posted only when two failures happened to land in adjacent windows, and those posts were titled STALLED, which read as a flow-rate blip.The runtime
/healthdimensionprojection_dlq_saturationalso missed it: it sums per projection across all four hook topics and needs a 100 percent DLQ ratio, so three healthy topics diluted it to zero (curl :8085/healthon the lab readdlq_saturated_projection_count 0, 2026-09-25T01:40Z). This PR does not change that dimension. The alert effect is the surface that reads per-(consumer group, topic) windows and already delivers.Change
It reuses the existing effect, its window read and the
node_slack_publish_effectdelivery. There is no new daemon.alert_policy.handler_error_windows: 1in the contract. It is contract data with no Python default, and the AST scan now covers it.FAIL_HANDLER_ERRORS. It fires when at least that many windows of the trailing read (history_windows, 16) havehandler_errors > 0, whether or not they are consecutive or the newest.Noneis an unobserved counter and never counts.confirm_windowskeepsFAIL_CONFIRMED_STALL, and its recovery still gradesRECOVERING, so the same incident is not announced twice.<bucket>|<group>|<topic>|HANDLER_ERRORS, bucketed on the newest failing window. Each of the 16 re-evaluations that still see one failure hands the publish ledger the same key, so it becomes one post per consumer, topic and 6 h bucket.HANDLER ERRORS, followed by the group, the topic,N of the last M windows failed messages in the handler, the totals (handler_errors, dlq, in, out), the failing-window span and the correlation id.handler_error_windowsandobserved_windows.consecutive_windowsis relaxed toge=0, because a handler-error payload may have no trailing run.Proof
RED first. Twelve new tests, plus a widened windows-source assertion. With origin/dev node source checked out over the committed tree (rule 17 method), the 11 tests selected by
-k handler_errorran 9 failed and 2 passed. The 2 that pass are the negative controls (zero and unobserved counters), which must pass on both sides. On HEAD, 75 of 75 pass across the stall-alert decision, thresholds, windows-source and self-assembly suites, the golden chain, and the OMN-16875 producer/consumer pin.Positive and negative control on lab data. I exported the
consumer_flow_windowsrows oflocal.omnimarket.projection_work_events.consume.1.0.0from the .201 dev lane Postgres for 2026-09-21 to 2026-09-24, 9,793 windows per topic. The replay runs the shippeddecide_stall_alerton the trailing 16 windows at every window, which is what the node sees on each heartbeat.Volume over the last 24 h, lab data. The same replay covered every key with a handler error in the last 24 h (13 keys) plus 8 healthy FLOWING keys. Each erroring key had every failing window covered, 26 posts in total. The healthy keys produced 0. The notifications channel took 1,030 stall posts over the retained log, so this adds about 2.5 percent. It also names four more projections that fail every event and never reached a post of their own kind:
projection_baselines,projection_baselines_roi,projection_baselines_qualityandprojection_dod_verdict.Local gates. ruff format and check are clean,
mypy --strictover the node is clean, and the full pre-commit suite passed at commit.Lab runtime (rule 24). This is not yet exercised on the lab runtime.
201-dev-runtimeis under a ledger HOLD by another lane until 02:31Z, and deploy-agent-dev is down (ledger MSG from runtime-train-83 at 01:36:24Z). The lab proof above is the shipped decision function over the lab's own recorded windows. OMN-19520 AC5 is the post-deploy readback: aFAIL_HANDLER_ERRORSdecision on the evaluation topic, and its delivery onslack-published. Rule 24(d): this touches no tenant, RLS or reader-authorization path, and onex-api is not involved.Sequencing
Like omnimarket#2878, this branch carries the post-release version bump commit from omnimarket#2874 (0.4.216 to 0.4.217, cherry-picked unchanged). The release-identity pre-commit hook refuses any
src/change on dev without it. Land #2874 first. Updating this branch from dev then drops the duplicate.Evidence-Ticket: OMN-19520
Evidence-Source: OCC#11191