Skip to content

feat: add Telegram process-event channel (adopted from upstream #2966) - #1

Merged
bingb0t5 merged 33 commits into
mainfrom
fm/fm-telegram-local-fork
Aug 25, 2026
Merged

feat: add Telegram process-event channel (adopted from upstream #2966)#1
bingb0t5 merged 33 commits into
mainfrom
fm/fm-telegram-local-fork

Conversation

@bingb0t5

@bingb0t5 bingb0t5 commented Aug 24, 2026

Copy link
Copy Markdown
Owner

CEO overview

  • What is changing: This fork gains the corrected, validated Telegram process-event channel from upstream PR #2966, together with the current fork main changes.
  • Why it matters: The captain-owned fork can use the Telegram channel locally while upstream PR #2966 remains open.
  • Customer or business impact: The fork receives the validated channel behavior without changing its Telegram implementation, validation, tests, skill contract, or verification evidence.
  • Risk and rollout: The fork main changes are integrated by merge commit; the validated Telegram files remain byte-identical to upstream head e7dd9178b7920dc50982f8915fcf7e8a48fae337. Merge only after all required fork checks pass.

What changed technically

This branch merges current fork main at 54681894c5ab839fe6d5c2f0170a1d94aa427361 with validated upstream head e7dd9178b7920dc50982f8915fcf7e8a48fae337 in merge commit d59128d7ff98ba81d9def82cb149395448cdd83a. When the fork is behind, this also brings the fork up to the upstream base carried by the original upstream PR #2933.

Validation

  • Checks passed: Upstream PR #2966 passed its no-mistakes review, test, documentation, lint, push, and GitHub checks. Local ancestry, whitespace, and byte-identity proofs passed for all five validated Telegram files.
  • Checks not run: No separate tests were run before the pipeline; the no-mistakes pipeline is running the fork validation now.
  • Evidence and limitations: If the legacy check is killed mid-write during the documented handoff, a truncated inbox claim can leave the channel permanently and silently wedged. This is fixed by the transactional state engine on branch fm/telegram-state-redesign, not by this PR. The update_id ceiling rationale in the validated validation module is also an inaccurate documentation rationale carried forward deliberately. This PR does not claim at-least-once, no-loss, or lossless behavior for the handoff path.

Module-boundary decision

Current module retained: This delivery does not redesign or alter the Telegram adapter storage core.

Decision needed

No decision required for the code adoption. Do not merge until the fork’s required checks pass.

bingb0t5 and others added 30 commits August 24, 2026 12:55
Registers the captain's Telegram channel with the generic process-to-event
runner so a captain message wakes firstmate within seconds instead of
waiting up to five minutes for a check sweep. The adapter is deliberately
thin: it owns Telegram's getUpdates long poll, the write-before-offset
invariant that keeps a captain message from being lost, and token
handling; ownership, durable capture, publication, and restart recovery
stay with bin/fm-procevent.sh. The channel is never terminal on its own -
only an explicit retire stops it.
The prior handoff-safety fixes checked whether an update id's inbox file
already existed and then wrote it, which cannot be safe against
state/telegram-watch.check.sh: that home-local script writes in place with
no temp file and no rename, so its output can be observed mid-write, and a
check-then-write gap can still race it.

Replace that with an atomic claim: this adapter always writes its own
complete, fsynced payload to a private temp file first, then hardlinks that
finished file onto the shared <update_id>.json name. A successful hardlink
is an exclusive, race-free claim. A failed one (name already taken) is
resolved by parsing whatever is already there - a complete, well-formed
payload for that update means another claimant (the legacy script or an
earlier invocation of this adapter) already delivered it, so this poll
no-ops without a second captain-visible wake; anything else means a
claimant, most likely the legacy script, is still mid-write, and that
update blocks the whole batch's offset advance exactly like a failed write,
so an unadvanced retry gives the write time to finish. handled/ is checked
first so an archived update is never recreated in the live inbox.

This does not make true simultaneous overlap (both producers inside
getUpdates for the same not-yet-advanced offset) free - the legacy script
has no knowledge of this adapter and can still fire its own independent
wake through the check sweep, which nothing here can suppress. Only
ensuring no legacy invocation is genuinely in flight before arming (not
merely deregistering it) closes that window; the header documents this
plainly rather than claiming a guarantee the design cannot make.

Also keeps the two accumulated fixes this branch already carries: a durable
pending-delivery record so an offset-write failure never strands an already-
written message, checked and reported before any credential validation.

Adds a regression test that reproduces the legacy script's exact non-atomic
write shape mid-write, overlapping a batch that also contains a genuinely
new update, and proves the batch blocks without corruption or duplication
and resolves correctly once the legacy write finishes.
Carry the accepted Telegram adapter and regression coverage onto a fresh validation branch, including permanent API failure signaling and receipt recovery protections.

Co-authored-by: Cursor <cursoragent@cursor.com>
Registers the captain's Telegram channel with the generic process-to-event
runner so a captain message wakes firstmate within seconds instead of
waiting up to five minutes for a check sweep. The adapter is deliberately
thin: it owns Telegram's getUpdates long poll, the write-before-offset
invariant that keeps a captain message from being lost, and token
handling; ownership, durable capture, publication, and restart recovery
stay with bin/fm-procevent.sh. The channel is never terminal on its own -
only an explicit retire stops it.
The prior handoff-safety fixes checked whether an update id's inbox file
already existed and then wrote it, which cannot be safe against
state/telegram-watch.check.sh: that home-local script writes in place with
no temp file and no rename, so its output can be observed mid-write, and a
check-then-write gap can still race it.

Replace that with an atomic claim: this adapter always writes its own
complete, fsynced payload to a private temp file first, then hardlinks that
finished file onto the shared <update_id>.json name. A successful hardlink
is an exclusive, race-free claim. A failed one (name already taken) is
resolved by parsing whatever is already there - a complete, well-formed
payload for that update means another claimant (the legacy script or an
earlier invocation of this adapter) already delivered it, so this poll
no-ops without a second captain-visible wake; anything else means a
claimant, most likely the legacy script, is still mid-write, and that
update blocks the whole batch's offset advance exactly like a failed write,
so an unadvanced retry gives the write time to finish. handled/ is checked
first so an archived update is never recreated in the live inbox.

This does not make true simultaneous overlap (both producers inside
getUpdates for the same not-yet-advanced offset) free - the legacy script
has no knowledge of this adapter and can still fire its own independent
wake through the check sweep, which nothing here can suppress. Only
ensuring no legacy invocation is genuinely in flight before arming (not
merely deregistering it) closes that window; the header documents this
plainly rather than claiming a guarantee the design cannot make.

Also keeps the two accumulated fixes this branch already carries: a durable
pending-delivery record so an offset-write failure never strands an already-
written message, checked and reported before any credential validation.

Adds a regression test that reproduces the legacy script's exact non-atomic
write shape mid-write, overlapping a batch that also contains a genuinely
new update, and proves the batch blocks without corruption or duplication
and resolves correctly once the legacy write finishes.
Carry the accepted Telegram adapter and regression coverage onto a fresh validation branch, including permanent API failure signaling and receipt recovery protections.

Co-authored-by: Cursor <cursoragent@cursor.com>
Preserve the local implementation history while merging the pipeline's rebased base and accepted Telegram safety fixes for the next validation run.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…-telegram-local-fork

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	.agents/skills/process-event-sources/SKILL.md
#	bin/fm-procevent-telegram.sh
#	tests/fm-procevent-telegram.test.sh
@bingb0t5 bingb0t5 changed the title feat: add Telegram process-event channel (adopted from upstream #2933) feat: add Telegram process-event channel (adopted from upstream #2966) Aug 25, 2026
@bingb0t5

Copy link
Copy Markdown
Owner Author

Superseded: hand-created PR cannot receive no-mistakes pipeline attestation. Reopening via pipeline-created fork PR on the same branch head f18b369.

@bingb0t5 bingb0t5 closed this Aug 25, 2026
@bingb0t5 bingb0t5 reopened this Aug 25, 2026
@bingb0t5
bingb0t5 merged commit af21941 into main Aug 25, 2026
27 of 29 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant