feat(ingest): advance a suppressed subscriber's delivery cursor when caught up (RIG-3326) - #1185
Merged
trunk-io[bot] merged 2 commits intoSep 12, 2026
Conversation
…caught up (RIG-3326) A suppressed notification is never acked, so delivered_revision stays behind the cursor revision and the reconcile sweep re-delivers the self-notification as a synthetic UPDATE on every sweep. The suppress path therefore advances the cursor itself - a narrow amendment to the rule that the router never advances delivered_revision, since a suppressed dispatch has no agent to ack it. The advance is conditional on the subscriber being caught up. Advancing unconditionally would erase the gap left by a real event that was dispatched but never delivered, and the agent would never learn of it - losing work-relevant signal, which is strictly worse than a redundant wake. Caught-up means delivered_revision equals the cursor revision as it stood BEFORE this event's upsert, with an empty string for a coordinate never observed, matching a fresh subscriber's default. A separate compare-and-set in SQL guards the write, so a concurrent route cannot erase a gap it did not observe. A lost CAS or a store fault is logged and swallowed: the sweep then synthesizes one UPDATE, which degrades open, never closed. Container-scope subscribers never advance. Their cursor lives on the number=0 row and the sweep compares it against the container cursor's revision, so writing an artifact revision there would poison the row and synthesize an UPDATE every sweep forever. The ack arm's existing unguarded query is untouched: an ack must land regardless of the stored value, so the CAS is a sibling query. Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
added this pull request to stack #1186
September 12, 2026 22:20
rigel-mintaka
marked this pull request as ready for review
September 12, 2026 22:20
|
Compass engineering docs preview: https://compass-forge-rig-3326-t2-cu.compass-eng-docs.pages.dev Deployed from |
Both suppress-advance warn logs carried only the subscription and account, so a failure could not be tied to the artifact it happened on without cross-referencing the subscription row. The sibling dispatch-failed log already carries repo and number; match it. Co-authored-by: Matt Wilkinson <matt@rigel.build>
mattwilkinsonn
approved these changes
Sep 12, 2026
|
😎 Stack merged successfully - details. |
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.
This PR is part of a stack containing 2 PRs:
mainA suppressed notification is never acked, so delivered_revision stays
behind the cursor revision and the reconcile sweep re-delivers the
self-notification as a synthetic UPDATE on every sweep. The suppress
path therefore advances the cursor itself - a narrow amendment to the
rule that the router never advances delivered_revision, since a
suppressed dispatch has no agent to ack it.
The advance is conditional on the subscriber being caught up. Advancing
unconditionally would erase the gap left by a real event that was
dispatched but never delivered, and the agent would never learn of it -
losing work-relevant signal, which is strictly worse than a redundant
wake. Caught-up means delivered_revision equals the cursor revision as
it stood BEFORE this event's upsert, with an empty string for a
coordinate never observed, matching a fresh subscriber's default.
A separate compare-and-set in SQL guards the write, so a concurrent
route cannot erase a gap it did not observe. A lost CAS or a store
fault is logged and swallowed: the sweep then synthesizes one UPDATE,
which degrades open, never closed.
Container-scope subscribers never advance. Their cursor lives on the
number=0 row and the sweep compares it against the container cursor's
revision, so writing an artifact revision there would poison the row
and synthesize an UPDATE every sweep forever.
The ack arm's existing unguarded query is untouched: an ack must land
regardless of the stored value, so the CAS is a sibling query.
Co-authored-by: Matt Wilkinson matt@rigel.build