Skip to content

Architecture

FleetTelegram phase 1 is one local Windows gateway for Claude Code. Core owns policy and domain logic. Gateway owns Telegram, screenshot capture, and process wiring.

Command Pipeline

flowchart LR
    A[Telegram update] --> B[Andrew allowlist]
    B --> C[Caveman compressor]
    C --> D[Governor gate]
    D --> E[Command router]
    E --> F[Claude session]
    B --> G[Audit JSONL]
    D --> G
    E --> G

Inbound sender ID must match %USERPROFILE%\.claude\fleet-telegram.json. Nonmatching updates are dropped without a Telegram reply and written to audit JSONL. Commands are parsed as leading /cmd or free text. Dangerous words (delete, rm, push, reboot, format) return a confirmation token; callback data confirm:<token> runs the stored command.

Governor tier is read from %USERPROFILE%\.claude\usage-governor\state.json, with FLEET_TELEGRAM_GOVERNOR_STATE override. Missing or unreadable state fails open.

Digest Pipeline

sequenceDiagram
    participant Adapter as ClaudeCodeSessionAdapter
    participant Buffer as DigestBuffer
    participant Gate as Governor tier
    participant Topics as TopicManager
    participant Tg as Telegram

    Adapter->>Buffer: normalized SessionEvent
    Gate->>Buffer: cadence GREEN 120s / YELLOW 300s / RED 900s
    Buffer->>Topics: flush session batch
    Topics->>Tg: create forum topic on first event
    Topics->>Tg: send digest text
    Buffer->>Topics: immediate event flushes context first

Immediate flush kinds: session-died, needs-input, confirm-request, error-blocked, task-complete, command-result.

Seams

classDiagram
    class ISessionAdapter {
      +ListSessions()
      +TailObservations(sessionId)
    }
    class IAgentCommander {
      +Run(prompt,cwd,timeout)
    }
    class ITransport {
      +Send(sessionId,payload)
    }
    class IRecorder {
      +Start(sessionId)
      +Stop(sessionId)
    }
    class IScreenshotter {
      +CapturePng()
    }
    class ITelegramClient {
      +SendMessage(topicId,text,parseMode)
      +SendConfirmation(topicId,text,callbackData)
      +CreateForumTopic(name)
      +EditMessage(topicId,message,text)
      +GetUpdates(offset,timeout)
      +SendPhoto(topicId,path,caption)
    }

Thin real adapters are excluded from coverage: Telegram API, GDI screenshot capture, Claude CLI exec, and Claude transcript file scanning.

Notification Boundary

Gateway owns severity notify: info goes to digest, warn pushes, critical pushes and waits for ack. If critical remains unacked for the configured night window, Gateway will call the existing Pavlok paging skill CLI. That paging call is intentionally left as a TODO stub; this project does not modify claude-session-watchdog.