Add durable Workshop delivery authority epochs - #866
Merged
Conversation
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
make install-statusWhy
The future Workshop delivery worker must not overlap ambiguously with the current direct Telegram delivery path. A restart-safe authority boundary is needed before any production cutover can be considered. Process-local flags are insufficient because they cannot distinguish work created under different authority periods or prevent a later worker from draining older work.
This PR establishes that boundary without activating it in production.
Durable contract
Schema version 14 adds:
delivery_authority_epochs, with at most one active epoch for the conversation-finalization lanedelivery_outbox.authority_epoch_id, deliberately leaving historical rows unclassifiedActivation is transactional and idempotent across restarts and concurrent attempts. First activation fails closed if matching historical outbox work is unclassified; it never silently adopts those rows.
Atomic streaming finalization resolves the active epoch inside the same database transaction that records the canonical outbound message and delivery request. Callers cannot choose or inject an epoch.
The streaming-finalization worker now requires a typed epoch at construction and uses that exact epoch for:
An inactive or different epoch cannot drain or complete the work.
Deactivation refuses non-terminal work. If the epoch contains terminal failures, including failures with uncertain-fragment evidence, an operator must explicitly acknowledge them before deactivation. The evidence remains durable after acknowledgement. A later activation creates a new epoch and cannot replay prior-epoch work.
Operator diagnostic
make install-statusnow includes one aggregate authority line reporting:It does not expose epoch IDs, delivery IDs, lease IDs, worker IDs, Telegram identifiers, message content, or provider errors.
Production safety
This remains a production-unused foundation:
The implementation map requires a separate sixth cutover review before any production wiring is authorized.
Tests
make checkmake typecheck.venv/bin/python -m pytest -qResult:
5392 passed, 1 skippedNew contracts cover idempotent restart, concurrent activation, fail-closed inactive enqueue, internal epoch stamping, exact-epoch isolation, non-terminal deactivation refusal, explicit terminal-failure acknowledgement, rollback/reactivation without replay, unclassified historical work, and aggregate non-secret diagnostics.