Skip to main content

Telegram Operator Channel Reference

The Telegram bot in /home/telegram is the operator-facing channel for the ORC control plane. It lets an authorized user submit work, approve workflows, inspect phase output, review backlog items, and trigger the next action without opening the ORC codebase directly.

This page documents the working pattern so teams can reproduce the operator experience, not just the backend engine.

What the Telegram Channel Does

The bot is intentionally narrow and operational:

  • receives operator commands and natural-language requests
  • maps Telegram identity to ORC user and roles
  • sends approval prompts with inline buttons
  • triggers auto-run after the final approval when appropriate
  • reports workflow status, audit trail, phase output, and next steps
  • exposes extracted backlog items so the operator can continue into design or implementation

The important architectural choice is that Telegram is a thin channel over ORC, not a second orchestration engine.

Tech Stack

The live Telegram channel uses:

  • Python 3
  • Telegram Bot HTTP API
  • a small local SQLite provenance database
  • ORC client calls into /home/ORC
  • PM2 for service supervision
  • Anthropic Haiku for natural-language intent parsing in the channel flow

Why Telegram Exists in the Architecture

A governed orchestration stack still needs a fast operator surface. Telegram solves three practical problems:

  • approvals can happen from a mobile device
  • workflow inspection does not require shell access
  • the control plane can present the next action immediately after a workflow completes

In other words, ORC owns workflow state; Telegram reduces the friction of operating that state.

Service Layout

The working repository is organized as:

  • telegram_channel/service.py for command handling, callbacks, and message rendering
  • telegram_channel/orc_client.py for ORC integration
  • telegram_channel/nlu.py for natural-language parsing
  • config.example.json for channel and user configuration
  • tests/test_service.py for channel behavior coverage

Authentication and Lockdown Model

The first control is identity enforcement. The service only accepts configured users and optionally only configured chat IDs.

def _authorize(self, chat_id: int, from_user: dict[str, Any], notify: bool = True) -> UserConfig | None:
telegram_user_id = int(from_user.get("id", 0))
actor = self.config.users.get(telegram_user_id)
chat_allowed = not self.config.channel.allowed_chat_ids or chat_id in self.config.channel.allowed_chat_ids
if actor is None or not chat_allowed:
if notify and chat_id:
self.telegram.send_message(chat_id, "Telegram identity is not authorized for this ORC channel.")
return None
return actor

Source: /home/telegram/telegram_channel/service.py

This is the minimum baseline to copy: allowlist by Telegram user ID and by chat ID, then map the actor to ORC roles.

Example Configuration

The example config shows the essential shape:

{
"bot_token_env": "TELEGRAM_BOT_TOKEN",
"orc": {
"root": "/home/ORC",
"db": "/tmp/orc.db",
"worker_auth_mode": "subscription"
},
"channel": {
"poll_interval_seconds": 2,
"allowed_chat_ids": []
},
"provenance": {
"db_path": "/home/telegram/data/channel.db",
"retention_years": 3
}
}

For a private operator bot, set allowed_chat_ids to the exact private chat you want to allow and define a single authorized user mapping.

Command Surface

The implemented command surface is already enough to run the full lifecycle:

/implement <project> <engine> <task...>
/implement <project> <engine> --no-verify <task...>
/plan <project> <action> <family> <command...>
/status <workflow_id>
/audit <workflow_id>
/phases <workflow_id>
/backlog <project> [type] [status]
/run <workflow_id> <plan_hash> <idempotency_key>

The bot also supports plain-language requests that are converted into those ORC actions.

Approval Flow

The Telegram bot is responsible for making the ORC approval step usable. It creates callback actions tied to approval tokens, then routes button presses into ORC approval calls.

The intended operator flow is:

  1. submit /implement flowry codex Add a health endpoint
  2. receive an approval message with inline buttons
  3. approve in Telegram
  4. bot auto-runs once the last required approval is complete
  5. receive terminal summary plus buttons for details, next steps, and backlog

This keeps approval latency low while preserving ORC as the authority.

Auto-Run Behavior

The bot only auto-runs after it confirms all approvals are already approved:

def _maybe_auto_run(self, chat_id: int, workflow_id: str) -> None:
try:
status = self.orc.status(workflow_id)
if any(item["status"] != "approved" for item in status["approval_requests"]):
return
except Exception as exc:
self.telegram.send_message(chat_id, f"Auto-run blocked: {html.escape(str(exc))}")
return

launch = self._launch_run(workflow_id, status["plan_hash"])
if launch is not None:
self.telegram.send_message(...)

This is the right control-plane pattern: channels may launch runs, but only after rechecking engine state.

Status and Terminal Notifications

One of the main improvements in the working bot is that terminal completion messages are no longer dead ends. The bot now renders a phase summary and includes follow-up actions.

Current terminal actions:

  • Full Details
  • Phase Outputs
  • Next Steps
  • Open Backlog
  • Audit Trail
  • Check Status

That is the correct UX pattern for orchestration channels: every completed run should lead naturally into the next governed action.

Full Details and Phase Output Rendering

The bot now renders stored phase outputs directly from ORC:

phase_runs = self.orc.phase_status(status["workflow_id"])
for phase_run in phase_runs:
self._send_chunked_message(chat_id, self._render_phase_detail(phase_run))
self._send_next_steps(chat_id, status)

And the next-step helper turns workflow output into concrete operator choices:

def _send_next_steps(self, chat_id: int, status: dict[str, Any]) -> None:
...
backlog_items = self.orc.backlog(project_id, status="open")[:3] if project_id else []
...
lines.append(
f"3. Start a focused design/review pass: "
f"<code>/implement {html.escape(project_id)} codex --pipeline=read_only &lt;task&gt;</code>"
)
lines.append(
f"4. Start implementation directly: "
f"<code>/implement {html.escape(project_id)} codex &lt;task&gt;</code>"
)

This is the part most teams miss. A workflow channel should not just report status; it should present the next safe action.

Example Operator Experience

A complete operator loop now looks like this:

  1. ask for review or implementation from Telegram
  2. approve the workflow from Telegram
  3. receive a terminal summary when ORC completes
  4. open Full Details to inspect per-phase output
  5. use Next Steps or Open Backlog
  6. start a follow-on planning, design, or implementation workflow

That creates a continuous operational loop around the same control-plane state.

How To Implement the Same Pattern

If you want to reproduce this channel architecture, use this sequence.

1. Keep Telegram stateless with respect to workflow truth

The bot can cache message state and callback actions, but ORC should remain the source of workflow, phase, backlog, and audit truth.

2. Lock access down early

Require an allowlisted Telegram user ID, an allowlisted chat ID, and a role mapping before any command reaches ORC.

3. Map every button to an engine capability

Status, phase details, audit, backlog, and next-step actions should call explicit ORC interfaces rather than inspect raw logs.

4. Render structured outputs, not transcript fragments

The channel should display phase output objects, gate failures, and execution summaries pulled from ORC storage.

5. Offer a continuation path on completion

Always provide the operator with at least:

  • inspect output
  • review backlog
  • start a design pass
  • start implementation

6. Preserve provenance locally

Keep a separate channel database for message tracking, callback actions, and retention policy. That keeps channel operations auditable without polluting engine storage concerns.

7. Run the service under a supervisor

Use PM2 or an equivalent process manager so polling and callback handling recover automatically.

PM2 Deployment

The working deployment pattern is:

cd /home/telegram
cp config.example.json config.json
pm2 start /home/telegram/ecosystem.config.cjs --only orc-telegram
pm2 save

This keeps the bot process independent from ORC itself while still colocated for low-latency local calls.

Security Notes

The Telegram channel should stay conservative:

  • store the bot token in environment, not in Git
  • restrict to private chat IDs
  • keep the user allowlist small
  • do not grant direct shell access from Telegram
  • route all execution through ORC policy and registry controls
  • preserve provenance for approvals and terminal messages

What To Copy First

If you are implementing an operator bot from scratch, copy these design elements first:

  1. _authorize() allowlist enforcement
  2. callback-driven approval flow
  3. status, phase_status, audit, and backlog integration
  4. terminal notification buttons
  5. next-step rendering from backlog and workflow output

Working Project File Map

Key files in the live Telegram implementation:

  • /home/telegram/telegram_channel/service.py
  • /home/telegram/telegram_channel/orc_client.py
  • /home/telegram/telegram_channel/nlu.py
  • /home/telegram/config.example.json
  • /home/telegram/tests/test_service.py