Self-hosted remote command runner with an optional personal-assistant layer
ogma docs workflow.md
5.1 kB · 81 lines
Markdown
at main

How Ogma works — the design #

Ogma is built around one core idea: two surfaces, one brain, bridged by tickets.

The two surfaces #

1. The bot (Telegram) — always on, deliberately restricted. Your assistant lives on an always-on machine and you reach it from your phone. Because that machine may hold SSH keys, wallets, and credentials — and because a chat surface is comparatively exposed — the bot runs with a tight toolset: read-only + web, plus exactly one whitelisted shell helper (ogmactl). It can answer, research, recall, and manage itself, but it cannot edit files, write code, or run arbitrary commands. That restriction is the safety model, not a limitation to "fix".

2. The interactive session — full power, on demand. When you sit down at the machine (or SSH in) and run Claude Code or Codex directly, you get the full toolset: edits, code, shell, the works. This is where real changes happen.

   ┌─────────────────────────┐         ┌──────────────────────────────┐
   │  Telegram bot (Ogma)     │         │  Interactive Claude / Codex   │
   │  always on, restricted   │         │  full tools, on demand        │
   │  read-only + web + ogmactl│        │  edit / code / shell          │
   └───────────┬─────────────┘         └───────────────┬──────────────┘
               │ can't do it under restrictions          │ picks it up
               │  → ogmactl ticket "..."                 │  → `tickets` skill
               ▼                                         ▼
        ┌──────────────────────────  tickets/  ──────────────────────────┐
        │  *.md (open)   →   work it   →   ## Resolution + status: done    │
        │                                  →   tickets/done/              │
        └─────────────────────────────────────────────────────────────────┘
                          shared: memory · skills · workspace persona

The bridge: tickets #

This is the key move. When the bot is asked for something it can't safely do, it doesn't fake a result and it doesn't get unsafe new powers — it files a ticket:

ogmactl ticket "Add a /weather command that ..."

That writes a markdown file into tickets/. Later, in a full interactive session, you say "tickets" and the tickets skill lists the queue, you work the item with the selected harness and full tools, append a ## Resolution, mark it done, and move it to tickets/done/. If the fix taught the system something — a new ogmactl subcommand, a relaxed permission — that knowledge stays.

Tickets that turn out obsolete don't need a full session: ogmactl ticket-close <id> [reason] (from the CLI or via the bot) stamps a resolution and moves the file to tickets/done/ — e.g. ogmactl ticket-close 20260101-120000 "wont-do: superseded".

Net effect: the bot stays safe and honest ("I can't do that here, but I filed a ticket"), and nothing falls through the cracks.

The shared brain #

Both surfaces share the same context, so the bot and your interactive sessions feel like one assistant:

  • Persona — workspace/CLAUDE.md defines who Ogma is and how it behaves.
  • Memory — one configured directory holds durable facts about you and your projects. Fresh Codex-only installs use ~/.local/share/ogma/memory; existing Claude memory locations are preserved, including across harness switches. Both harnesses and the bot use the configured path.
  • Skills — reusable procedures installed in ~/.claude/skills/ and ~/.codex/skills/ (tickets, session-search, daily-briefing, and your own). Both surfaces load them on demand. See ../skills/.

Keeping itself sharp #

  • Dream (nightly) — bin/dream runs unattended: it distils the last ~24h into a rolling yesterday.md and tidies long-term memory (merge dupes, drop stale facts), snapshotting first.
  • Persist nudge (per turn) — a Stop hook (hooks/persist-nudge.py) occasionally spawns a detached pass that saves anything durable from the conversation — without delaying your reply.
  • Self-management — ogmactl lets the bot check its own status/logs, restart itself, and report host health, all without arbitrary shell.
  • Scheduled routines — briefing / health-check deliver to Telegram via tg-send; add your own the same way.

The loop, in one line #

Talk to the bot → it does what it safely can, files tickets for the rest → you clear tickets in a full session → memory + skills carry the learning forward → the bot is a little more capable tomorrow.