Skip to content

Telegram Fleet, Pure Phoenix Phase 4.2 + 4.2.5

Doctrine: FORGE-DOCTRINE.md Sections 3, 5, 6, 7. Handoff: pure-phoenix-phase-4-2-bot-redesign-2026-04-28.

The fleet

Bot Role Service Brain persona Tool count
@forge_inbox_capture_bot low-friction capture, voice + text forge-inbox-capture.service capture 16
@forge_lifeos_coordinator_bot deep synthesis, full tool surface forge-lifeos-coordinator.service coordinator 50
@forge_notify_outbound_bot push (notify.sh, heartbeat, morning-brief, nudge-fire) + inbound slash commands (/help, /status, /wellness, /quota) forge-notify-bot.service n/a (no LLM, dispatcher only) n/a
@forge_remote_bridge_bot spawn-by-default phone-to-tmux on-ramp; brain routes plain text to spawn / kill / propose_kill / reply forge-remote-bridge.service bridge (separate, see reference_remote_bridge_bot) 4 (spawn, kill, propose_kill, reply)

All 4 bots use the same UX: 👀 on receive + typing indicator, then 👌 on success or 🤔 on failure. Reply text (when a tool ran) starts with a labeled action prefix like Food Item Logged:, Calendar Event Created:, Task Created:, Session Spawned:, Failed: <tool>. See feedback_telegram_bot_ux_reactions.

Plus forge-inbox-webhook.service on port 7400 for the iOS Shortcut (calls capture persona).

Tokens

~/.forge-secrets/telegram-{inbox-capture,lifeos-coordinator,notify-outbound}.env (chmod 600).

Each env file:

TELEGRAM_BOT_TOKEN=...
TELEGRAM_BOT_USERNAME=...
TELEGRAM_AUTHORIZED_USER_ID=7110798439   (Justin's Telegram user id; doubles as DM chat_id)
TELEGRAM_CHAT_ID=7110798439              (push helper reads this)

Brain layer

forge/scripts/forge_telegram_brain.py is the single brain module. Persona param selects: - system prompt (capture: "low-friction only, route heavy work to coordinator"; coordinator: "synthesis + spawn_worker for big jobs") - tool subset (capture filters TOOLS down to 7 names; coordinator gets all 28) - context log file (data/capture-context.jsonl vs data/coordinator-context.jsonl) - per-call quota record via forge_quota_tracker.record(...)

The 1120-line forge_telegram_inbox_brain.py remains as the implementation backend (tool functions, n8n helper, Notion DB IDs). The new brain module is a persona-aware facade that imports from it.

Capture persona tool surface

save_to_inbox, create_task, save_knowledge, log_habit,
schedule_nudge, wellness_now, create_calendar_event

Heavy tools (Gmail, Notion query/update, calendar update/delete, spawn_worker) are deliberately omitted. Capture is single-shot; capture brain refuses multi-step work and routes it to coordinator via the prompt.

Coordinator persona tool surface

All 29 tools, including spawn_remote_session(name, model, prompt) which shells out to forge/scripts/forge_spawn_session.sh (canonical extraction of the /spawn skill bash) and returns a claude.ai/code URL. Added 2026-04-29.

Required: the forge-lifeos-coordinator.service unit MUST NOT have PrivateTmp=true, or the spawned tmux session lands in an isolated namespace and Justin can't reach it. Removed 2026-04-29; see LESSONS.md.

Notify bot inbound (slash commands, added 2026-04-29)

forge/scripts/forge_telegram_notify_bot.py polls @forge_notify_outbound_bot for inbound messages. Slash-command framework with @cmd(name, description) decorator; adding a new command is a single function. /help auto-lists every registered command. Anything not starting with / gets routed back to coordinator/capture with a hint.

Initial commands: - /help - list available commands - /status - service health snapshot for the bot fleet - /wellness - calls brain_core.tool_wellness_now() - /quota - calls forge_quota_tracker.aggregate()

Service: forge-notify-bot.service, unit at /etc/systemd/system/forge-notify-bot.service. Logs at forge/logs/telegram-notify-bot.log.

Push channel

forge_telegram_push.sh selectors after Phase 4.2: - capture, coordinator, notify are canonical - legacy inbox, ava, manager, updates, chat map to notify for backwards compatibility during cutover

forge_notify.sh send_manager fn reads ~/.forge-secrets/telegram-notify-outbound.env.

forge_telegram_nudge_fire.py, morning-brief.py, heartbeat.py all push via forge_telegram_push.sh notify ....

Quota tracker

forge/scripts/forge_quota_tracker.py: - record(invoker, model, prompt_chars, response_chars, latency_ms, success, extra=None) - append-only JSONL at forge/data/claude-quota/<YYYY-MM>.jsonl - aggregate(month) - per-invoker daily + total summary - merge_with_stats_cache(summary) - pulls ~/.claude/stats-cache.json (Claude Code interactive sessions) into the same view - CLI: forge_quota_tracker.py [--month YYYY-MM] [--write-summary]

Foundation for Phase 4.7 (system-wide quota observability across all 9 forge scripts that call claude -p).

Operational notes

  • Voice transcription via forge_telegram_transcribe.py (faster-whisper base.en CPU int8). Both capture and coordinator bots use it.
  • Each bot enforces single-authorized-user via TELEGRAM_AUTHORIZED_USER_ID.
  • Both long-pollers run under ~/.forge-venvs/inbox/bin/python (whisper venv with requests).

Retired (do not reuse)

Old bot Service Status
@jw_inbox_bot forge-telegram-inbox.service unit retired, file archived to memory/_archive/cron-pre-phoenix-2026-04-28/. Token still active until Justin deletes via @BotFather.
@Ava_JForgeBot forge-telegram-ava.service same
@Manager_JForgeBot n/a push-only, no service. Token superseded by notify-outbound.
@jw_updates_bot n/a push-only, merged into notify-outbound.

Justin's manual final step: delete the four old bots via @BotFather and revoke their tokens.

Pending work

  • Phase 4.7: instrument the other 7 forge scripts that call claude -p (heartbeat, morning-brief, dispatcher, etc.) with forge_quota_tracker.record(...) so the aggregator covers the whole subscription footprint.
  • @BotFather deletion of retired bots (Justin owns this).
  • After 7-day clean operation: tighten naming-taxonomy-services eval check from warning to error severity.

[Claude Code, Pure Phoenix Phase 4.2]