kcode-tg-kennedy-bot 0.1.2

A host-integrated Telegram transport, durable queue, and fail-closed group-security library
Documentation
# kcode-tg-kennedy-bot

`kcode-tg-kennedy-bot` is a host-integrated Telegram transport library. It
long-polls Telegram, stores durable private and group transport work in SQLite,
enforces fail-closed group security, and serves a loopback HTTP queue for a
Kennedy frontend. It deliberately does not own Kennedy users, whitelist
entries, application capabilities, secrets, prompts, model execution, or Kmap
roots.

The crate is a standalone Rust 2024 package. Its public Rust crate name is
`kcode_tg_kennedy_bot`.

## Host integration

The host supplies an optional Telegram bot token and an implementation of
`IdentitySink`:

- `observe_identity` receives each Telegram identity observed by the relay.
- `whitelist` returns the authorized numeric Telegram user IDs at that moment.
- `request_add_user` authorizes and performs the private `/adduser @handle`
  workflow outside the relay.
- `observe_group` receives each stable opaque group ID so the host can attach
  application-owned state independently.

```rust,no_run
use std::{path::PathBuf, sync::Arc};

use kcode_tg_kennedy_bot::{BotToken, Config, IdentitySink};

async fn run(
    identity_sink: Arc<dyn IdentitySink>,
    token: String,
) -> anyhow::Result<()> {
    kcode_tg_kennedy_bot::serve(Config {
        bind: "127.0.0.1:4324".into(),
        database: PathBuf::from("telegram.sqlite3"),
        allowed_origins: vec!["http://127.0.0.1:4321".into()],
        bot_token: Some(BotToken::new(token)?),
        identity_sink,
        max_voice_bytes: 20 * 1024 * 1024,
    })
    .await
}
```

Passing `None` as `bot_token` keeps the loopback API available and reports
Telegram as disabled. A configured token is rejected when empty, validated
with Telegram during startup, redacted from `Debug`, never serialized, and
zeroized on drop.

Call `migrate_storage(path)` to apply the idempotent SQLite migrations without
starting the HTTP service or Telegram polling.

## Identity and group-security contract

The host is authoritative for identity observations, the whitelist, handle
pinning, `/adduser` authorization, and application-owned roots. The relay uses
numeric Telegram user IDs for authorization decisions and never stores the bot
token or application authorization tables in its database.

Groups have random stable opaque IDs that survive Telegram basic-group to
supergroup migrations. The relay permanently retains every human identity it
has observed in a group's membership ledger, including departed and kicked
members.

A group is allowed only while all of these conditions hold:

1. Telegram confirms that the bot is currently an administrator or owner.
2. Telegram's member count matches the observed active-human ledger plus the
   bot.
3. Every human ever recorded for the group is in the host's current whitelist.

Any failed condition quarantines the group. While quarantined, the relay
handles only sender and membership metadata needed to improve the ledger; it
does not inspect invocation text, download media, archive message content, or
expose the content to Kennedy. Eligibility is recomputed on later updates, so
quarantine is reversible after the roster becomes complete and every
historical identity is authorized.

Telegram cannot enumerate all ordinary members of an existing group. Reliable
strict onboarding therefore starts with a new group: add the bot, promote it to
administrator, and then add human members so their joins are observed.

## Durable transport behavior

Authorized private text, voice notes, supported documents, and `/reset`
updates are queued in per-user order. Binding an event records the durable
start of its response deadline. Conversation rebinding uses compare-and-swap
semantics, and reply, reset, timeout, transcription, and abort transitions are
designed to be durable and idempotent.

Allowed group messages invoke Kennedy when they mention the bot, reply to a bot
message, or contain a scoped `/reset`. Group conversation pointers are keyed by
stable group ID and numeric Telegram user ID, separate from private and other
group sessions. The database also retains allowed group context, media,
background-ingress batches, reset ranges, and transport cursors.

The loopback API exposes transport health and queue transitions under
`/api/v1`. Detailed endpoint and persistence behavior is specified in
`Specification.md`.

## Managed-library maintenance

The literal `[package].version` in `Cargo.toml` is the canonical managed-library
version. `Version.txt` is neither required nor used. Update the manifest version
for a release, and keep every file in this directory as ordinary UTF-8 text;
generated build output and binary artifacts must remain outside the
managed-library directory.

The standard kcode check runs dependency fetch, formatting, build, Clippy with
warnings denied, unit and integration tests, and documentation tests. The
SQLite migrations under `migrations/` are compiled into the library and must
remain present.