From 9f9732624cc8b0197f3db86d36d2cd1f7a5adc55 Mon Sep 17 00:00:00 2001 From: Maciek Ostaszewski Date: Tue, 28 Jul 2026 07:45:29 +0200 Subject: [PATCH 1/3] docs: define telegram adapter migration --- docs/telegram-adapter-functional-analysis.md | 186 +++++++++++++++++++ 1 file changed, 186 insertions(+) create mode 100644 docs/telegram-adapter-functional-analysis.md diff --git a/docs/telegram-adapter-functional-analysis.md b/docs/telegram-adapter-functional-analysis.md new file mode 100644 index 0000000..9c5ff84 --- /dev/null +++ b/docs/telegram-adapter-functional-analysis.md @@ -0,0 +1,186 @@ +# Telegram adapter: functional analysis and migration acceptance criteria + +- Status: proposed +- Module ID: M7 Telegram compatibility adapter +- System contract authority: [HyperDev unified channels contracts](https://github.com/gohyperdev/hyperdev-platform/blob/main/docs/architecture/unified-channels-contracts-and-delivery-plan.md) +- Runtime dependency: `hyperdev-channels` host runtime and Claude Code bridge + +## 1. Purpose and non-goals + +`hdcd-telegram` is the compatibility reference implementation for the Telegram +channel while HyperDev moves routing and configuration onto the platform. Its +current 0.2 router mode already provides a valuable migration primitive: one +Telegram poll owner, many Claude Code sessions and filesystem mailboxes. + +The target state is different: + +- the platform `channels-edge` owns the Telegram token reference, update offset, + provider authentication, access policy, conversation route and outbound API + delivery; +- the platform-managed host worker owns agent registration, mailbox receive and + session lease; +- Claude Code sees one generic `channels` MCP bridge, not a separate Telegram + MCP server; +- only agents with an explicit Telegram ChannelInstance are exposed through a + bot. The initial scope is Agda and Calluna. + +This repository does not become the source of tenant routing, agent discovery, +Teams support or provider-independent MCP lifecycle. + +## 2. Current capability inventory + +| Capability | Current `hdcd-telegram` | Target owner | +| --- | --- | --- | +| Bot API polling and single poller | standalone and `hdcd-router` | channels edge | +| Multi-session assignment | router topics + mailbox files | host worker session lease | +| Pairing and allowlist | local state | platform policy with migration import | +| Text, Markdown and chunked reply | local tool | Telegram adapter | +| Threads/forum topics | local tool/router | Telegram adapter + conversation route | +| Attachments/download | local tool | adapter/media policy | +| Reactions and edits | local tools | adapter capability operations | +| Permission relay | local inline keyboard | bridge/adapter extension path | +| Voice transcription | local Whisper path | explicit design decision: worker or media service | + +The existing direct binary remains a rollback path during migration. It must +not run concurrently with a platform poller for the same production token: +Telegram permits one `getUpdates` owner, otherwise updates conflict. + +## 3. Adapter contract binding + +The Telegram adapter implements provider contract C6. It consumes a verified +ChannelInstance and produces a source-neutral `CommunicationEnvelope`. + +### Inbound mapping + +```ts +type TelegramInboundMapping = { + provider: 'telegram'; + channelInstanceId: string; + providerUpdateId: string; + providerConversationRef: string; + senderRef: string; + text: string; + replyRef?: string; + attachmentRefs?: string[]; +}; +``` + +The adapter verifies bot/update provenance, deduplicates by update/message +identity, applies the configured access policy and asks the platform to bind +the verified channel instance to a tenant and target agent. Provider payload +cannot select an arbitrary tenant or agent. + +### Outbound mapping + +```ts +type TelegramDeliveryCommand = { + routeRef: string; // opaque platform conversation/contact route + operation: 'reply' | 'send' | 'react' | 'edit' | 'download'; + idempotencyKey: string; + payload: unknown; +}; +``` + +The adapter accepts only an M4-issued route reference. A model, local worker or +Telegram user cannot supply a raw `chat_id` as an authoritative delivery target. + +## 4. Functional analysis + +### FA-TG-01: single-poller safety + +**Actor:** Telegram adapter deployment. + +**Behaviour:** acquire the configured bot token lease before polling; persist +the update offset; reject a second owner; release/expire the lease during +controlled cutover. + +**Acceptance:** the same production bot cannot be polled by legacy and platform +implementations at once. Shadow testing uses a distinct test bot. + +### FA-TG-02: inbound acceptance and pairing policy + +**Actor:** Telegram sender and channels edge. + +**Behaviour:** evaluate migrated pairing/allowlist policy before creating a +platform conversation/envelope; return the agreed pairing response where +required; store provider references tenant-scoped. + +**Acceptance:** unpaired sender cannot inject an envelope; a paired sender +cannot reach another tenant/agent; legacy access-state import is auditable and +reversible. + +### FA-TG-03: conversational reply and initiated send + +**Actor:** Claude Code agent. + +**Behaviour:** `reply` uses an opaque context; initiated `send` resolves only +an authorised contact/conversation alias. Telegram constraints remain visible: +the bot can start a message only where it already has an allowed chat route. + +**Acceptance:** threading follows the original message when appropriate; +unknown/raw chat targets are rejected; duplicate tool retries do not duplicate +an outbound Telegram message. + +### FA-TG-04: media and rich operations + +**Actor:** adapter and bridge. + +**Behaviour:** advertise operations only when the route/capability permits +them; process attachments through a tenant-scoped media policy; retain reaction, +edit and permission-relay semantics that are approved for the pilot. + +**Acceptance:** the feature-parity matrix below is tested for Agda and Calluna. +Voice transcription has an explicit owner before migration, rather than an +implicit loss of functionality. + +## 5. Definition of Ready + +- C4-C6 platform contracts are merged and fixture-backed. +- Telegram ChannelInstance schema, secret reference and access-policy ownership + are implemented by the platform module. +- Feature-parity scope for Agda and Calluna is signed off. +- A test bot is available for integration testing; a production cutover owner + and rollback procedure are named. +- Voice transcription disposition is decided: host worker capability or + platform media service. + +## 6. Definition of Done + +- platform adapter passes the approved text, thread, attachment, reaction, + edit, pairing and permission-relay matrix; +- one production token has exactly one poll owner; +- bot secret is absent from Claude Code MCP config, process arguments and logs; +- Agda, then Calluna, use the generic `channels` MCP bridge rather than a + separate Telegram MCP entry; +- agents without an enabled Telegram ChannelInstance have no Telegram route; +- rollback to the direct compatibility binary is documented and tested before + each production-token cutover. + +## 7. PR breakdown and integration plan + +| PR | Scope | Dependency | Acceptance | +| --- | --- | --- | --- | +| T1 | Telegram adapter contract fixtures and parity matrix | C4-C6 | mappings and errors are deterministic, no provider secret in fixture output | +| T2 | Compatibility bridge integration | M5/M6 | one generic bridge can consume Telegram envelopes through test mailbox IPC | +| T3 | Platform adapter ingress/outbound | M4 | token lease, offset, dedupe and route-bound delivery pass integration tests | +| T4 | Agda pilot | T1-T3 | test bot then controlled production cutover with rollback evidence | +| T5 | Calluna pilot | T4 | same criteria on a second agent without cross-agent state leakage | + +Pre-production rollout uses the single platform runtime in controlled sequence: + +1. run fixtures and test-bot integration with T1-T3; +2. enable only Agda's test ChannelInstance; +3. stop legacy poller, enable platform poller and verify Agda production bot; +4. retain a time-bounded rollback window; +5. repeat for Calluna; +6. remove direct Telegram MCP configuration only after both pilots pass. + +## 8. Evidence required at each pilot gate + +- adapter version and configured ChannelInstance ID; +- token-poll owner and offset health, without token disclosure; +- inbound dedupe and outbound idempotency evidence; +- pairing/access positive and negative tests; +- reply, initiated send and attachment operation results; +- platform delivery/lease dashboard state; +- exact rollback command and named operator. From 286307eb2922a1b560faee5ef6873c55d9b6fd9f Mon Sep 17 00:00:00 2001 From: Maciek Ostaszewski Date: Tue, 28 Jul 2026 07:55:16 +0200 Subject: [PATCH 2/3] docs: align telegram workstream identifier --- docs/telegram-adapter-functional-analysis.md | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/docs/telegram-adapter-functional-analysis.md b/docs/telegram-adapter-functional-analysis.md index 9c5ff84..fcf42f4 100644 --- a/docs/telegram-adapter-functional-analysis.md +++ b/docs/telegram-adapter-functional-analysis.md @@ -1,7 +1,14 @@ # Telegram adapter: functional analysis and migration acceptance criteria - Status: proposed -- Module ID: M7 Telegram compatibility adapter +- Technical workstream: CH-TG (Telegram compatibility adapter) +- Functional owner: Agis (Agent communications and platform agents) +- Operational delivery: Agda; contract ratification: Calluna and Agoga + +`CH-TG` is a technical-workstream identifier, not a platform module number. +Canonical `M1`–`M9` identifiers remain reserved by +`hyperdev-infra/docs/TEAM-RULES.md`; agent communications have no separate +canonical `M` identifier. - System contract authority: [HyperDev unified channels contracts](https://github.com/gohyperdev/hyperdev-platform/blob/main/docs/architecture/unified-channels-contracts-and-delivery-plan.md) - Runtime dependency: `hyperdev-channels` host runtime and Claude Code bridge @@ -81,7 +88,7 @@ type TelegramDeliveryCommand = { }; ``` -The adapter accepts only an M4-issued route reference. A model, local worker or +The adapter accepts only a CH-EDGE-issued route reference. A model, local worker or Telegram user cannot supply a raw `chat_id` as an authoritative delivery target. ## 4. Functional analysis @@ -137,7 +144,7 @@ implicit loss of functionality. - C4-C6 platform contracts are merged and fixture-backed. - Telegram ChannelInstance schema, secret reference and access-policy ownership - are implemented by the platform module. + are implemented by the platform workstream. - Feature-parity scope for Agda and Calluna is signed off. - A test bot is available for integration testing; a production cutover owner and rollback procedure are named. @@ -161,8 +168,8 @@ implicit loss of functionality. | PR | Scope | Dependency | Acceptance | | --- | --- | --- | --- | | T1 | Telegram adapter contract fixtures and parity matrix | C4-C6 | mappings and errors are deterministic, no provider secret in fixture output | -| T2 | Compatibility bridge integration | M5/M6 | one generic bridge can consume Telegram envelopes through test mailbox IPC | -| T3 | Platform adapter ingress/outbound | M4 | token lease, offset, dedupe and route-bound delivery pass integration tests | +| T2 | Compatibility bridge integration | CH-HOST/CH-MCP | one generic bridge can consume Telegram envelopes through test mailbox IPC | +| T3 | Platform adapter ingress/outbound | CH-EDGE | token lease, offset, dedupe and route-bound delivery pass integration tests | | T4 | Agda pilot | T1-T3 | test bot then controlled production cutover with rollback evidence | | T5 | Calluna pilot | T4 | same criteria on a second agent without cross-agent state leakage | From 1dec9ddcee809c00df20c3272016e71ff898ff08 Mon Sep 17 00:00:00 2001 From: Maciek Ostaszewski Date: Tue, 28 Jul 2026 08:00:56 +0200 Subject: [PATCH 3/3] docs: link telegram decision record --- docs/telegram-adapter-functional-analysis.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/telegram-adapter-functional-analysis.md b/docs/telegram-adapter-functional-analysis.md index fcf42f4..6117640 100644 --- a/docs/telegram-adapter-functional-analysis.md +++ b/docs/telegram-adapter-functional-analysis.md @@ -10,6 +10,7 @@ Canonical `M1`–`M9` identifiers remain reserved by `hyperdev-infra/docs/TEAM-RULES.md`; agent communications have no separate canonical `M` identifier. - System contract authority: [HyperDev unified channels contracts](https://github.com/gohyperdev/hyperdev-platform/blob/main/docs/architecture/unified-channels-contracts-and-delivery-plan.md) +- Decision record: [ADR-076](https://github.com/gohyperdev/hyperdev-platform/blob/main/docs/adr/ADR-076-unified-channels-edge.md) - Runtime dependency: `hyperdev-channels` host runtime and Claude Code bridge ## 1. Purpose and non-goals