fix: complete unified event contract#5
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
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.
What
This focused follow-up carries the final event-contract work that completed after #4 was squash-merged.
It:
process_archivedonly after SQL proves that its fenced transition todeadcommittedprocess_recoveredas one identity-free count fact per row changed by bulk recoveryStatsCollector.Pausedas a zero-or-one gaugeplan.mdtodocs/plan.mdand updates historical documentation linksdeadupdate commitsdocs/plan.mdThe SQL archive boundary is now explicit in code:
if settlementErr != nil { d.handleSettlementFailure(ctx, job, settlementErr) return } settlement.Commit() +if err != nil { + d.observeConfirmedProcessArchive(ctx, job, err) +}flowchart LR OBS["queue.Observer"] --> LAYER{"Event.Layer"} LAYER --> QUEUE["queue facts"] LAYER --> WORKER["worker facts"] LAYER --> WORKFLOW["workflow facts"] WORKER --> FAILURE["terminal SQL handler failure"] FAILURE --> FENCE{"fenced dead update committed?"} FENCE -->|Yes| ARCHIVE["process_archived"] FENCE -->|No| SETTLEMENT["settlement_failed"] BROKERS["SQS, RabbitMQ, Redis, NATS, local"] --> OMIT["omit process_archived"]There is no source/API, configuration, persisted-data, wire-format, or minimum-Go-version change. Runtime observation changes are intentional: terminal SQL failures add one confirmed archive fact, and collected pause state is now a gauge.
Why
PR #4 unified the queue and workflow observer models, but the human event catalog remained incomplete and one reserved event had no reliable built-in producer. That left consumers unable to tell which facts were guaranteed, which fields were available, and where driver settlement stopped short of irreversible archival.
This follow-up makes the documentation and implementation one enforceable contract. Future event additions, internal workflow additions, or adapter fields cannot silently bypass the public reference, and drivers only publish the strongest fact they can actually prove.