Personal AI operations assistant

BRO

A desktop assistant that drives an AI coding agent CLI as a local runtime. It is read-only by default, and any write needs a human approval that is bound to the exact change by a hash.

Status
Running as a local production baseline since October 2026. Private.
Source
Source: private

The problem

AI agents are useful for operations work, but an agent that can run commands, fetch URLs and edit files on its own is a risk on a machine that holds real credentials.

The goal was an assistant that is genuinely helpful for reading, summarising and proposing changes, while keeping every consequential step visible, bounded and reversible.

The approach

A local dashboard talks to a local backend with a task queue. Each task runs a worker: the agent CLI, started as a local runtime in a fresh, empty per-task workspace.

Workers can only read inside their own workspace. They cannot run commands, fetch URLs or use connectors, and they never see API keys or OAuth variables because the environment is passed through an allowlist.

When a worker wants to write, the attempt is denied and turned into a single approval request. The request shows the full content and is bound by a hash over the task, the tool and the normalised input, including the resolved path.

After a human approves, a guard hook allows exactly that one write, and the apply step verifies the content hash before anything changes.

Architecture

BRO approval and execution flowA local dashboard sends tasks to a backend. A worker (the agent CLI) runs read-only in an empty workspace. A proposed write becomes a hash-bound approval. After human approval, a guard hook allows one write, which is applied and verified.Local dashboardtasks, approvalsSchedulerfixed read-only templatesBackend and task storequeue, state, recoveryWorker: agent CLIread-only, empty workspaceNo shell, no networkno connectors, scrubbed envHash-bound approvalsingle use, expiresGuarded applyguard hook + content hash
Solid outline: component. Amber fill: control or guard. Dashed outline: external input or output. Dotted outline: deliberately blocked.
Text alternative: the flow in words
  1. A task arrives from the dashboard or from a fixed scheduled template.
  2. The backend queues it and starts a worker in a fresh, empty workspace with read-only tools.
  3. If the worker proposes a write, it is denied and converted into one approval request bound to a hash of the exact change.
  4. A human reviews the full content and approves, within a short window.
  5. A guard hook allows exactly that one write, and the apply step verifies the content hash.

Interactive demo

Demo with fictional data

Step through one task from request to guarded apply, then tamper with the change after approval and watch it get refused. The hash here is a toy; nothing real runs.

Request

A person (or a fixed scheduled template) creates a task. The backend queues it. Nothing has run yet.

The worker can

  • Create a task

The worker cannot

  • Run commands
  • Use the network
  • Use connectors
  • See secrets

approval card (fictional)

task
task-0042
proposed write to
notes/draft.txt
content
(none yet)
bound hash (toy)
--------
status
no request

Key technical decisions

  • Read-only by default, fail closed

    Anything the guard cannot verify is refused. Initialisation checks that the worker has exactly the expected tool set and no connectors, otherwise the task does not start.

  • Hash-bound, single-use, expiring approvals

    Approvals are sealed with a keyed hash, expire after a short window, can be used once, and are re-checked right before the apply step. They do not survive a restart.

  • Honest recovery instead of silent resume

    On restart, running tasks are marked interrupted, pending approvals expire, and nothing is resumed behind the user’s back. A Windows Job Object kills the whole worker process tree if the backend dies.

  • Scheduled tasks as code, with a kill switch

    Scheduled jobs are fixed read-only templates, not free text, with a global kill switch and a daily budget. Duplicate prevention and safe re-run rules are part of the design.

  • Read-only activity panel

    A VS Code extension shows live agent sessions and their subagents. It never sends messages to or controls a session, and its web view has no network access.

Safety and security notes

  • Residual risks are written down rather than hidden. For example, the worker still runs as the local user, so the in-process policy is the boundary, not the operating system. That is why the worker tool set is so small.
  • Prompt injection through task text or approved files is a documented risk, which is why approval cards show the full content of the proposed write.
  • External actions use separate executors, each with its own hash-bound approval.
  • No company, client, host or credential detail appears on this page. Sanitised architecture only.

Limits and honest caveats

  • Planned, not claimed: supervision beyond the scheduled-task restart policy, and idempotency keys for scheduled work, are roadmap items.
  • An approval proves a request was created by the backend and approved through its API. Stronger proof that a human clicked is a listed follow-up.