# CyberBrain Agent Guard — MVP gap analysis

**Status:** code-reading snapshot on 2026-10-01; use with fresh customer discovery before committing the product scope.  
**Update 2026-10-02:** two items below are no longer open in the decision sense — supported OS and the guarded `run` path. Both are **decided and implemented** (D2 fail-closed run, D3 model-free CLI); see [DECISIONS_LOG_V5.md](DECISIONS_LOG_V5.md) (D1, D2). Nothing in this snapshot was deleted.  
**Question:** what is already usable in the proposed V5 user workflow, and what is still missing?

## Current path versus proposed product

| Product capability | Current repository evidence | MVP state |
|---|---|---|
| Deterministic identity, policy and permission boundary | `PtahBridge.execute_step()` routes a registered agent through `TaskDispatcher`; `AuthorizedExecutionService` checks permission before execution. | **Core exists** for the Ptah path. Need to ensure every selected external agent/tool path goes through it. |
| Human approval | `ApprovalManager` can be in-memory or SQLite-backed; the execution gateway can wait for approval. | **Backend and CLI surface exist; cryptographic binding still missing.** **Updated 2026-10-02:** the user-facing approval surface now exists and is registered — `cyberbrain approvals pending\|show\|approve\|deny\|history` is reachable from the `cyberbrain` entry point via `app.add_typer(approvals_app, name="approvals")` (`src/cyberbrain26/cli.py:20-26`), covered by `tests/test_product_cli.py`, and already recorded as done in [SECURITY_ONE_PAGER.md](../SECURITY_ONE_PAGER.md). What it still does **not** guarantee: an approval is **not cryptographically bound** to the code that runs — the record carries `action`, `resource` and `context`, but no hash or signature of the execution payload (`security_plane/approval/__init__.py:98-147`, acknowledged in `product/approvals.py:23-28`), so code can change between approval and `provider.execute`; `--no-persist` is a read-only mode that writes nothing to disk. The default execution wait is still short relative to approval workflows. |
| Bubblewrap execution | `BubblewrapExecutionProvider` runs Python/shell without network and fails closed if Bubblewrap is missing. | **Linux prototype exists.** Not approved for arbitrary hostile code; process-count, aggregate-memory, and workspace disk/inode limits need a supported deployment solution or explicit product restrictions. |
| Persistent task, approval, and audit data | SQLite storage, `SQLiteTaskQueue`, Ptah persistence injection, durable approvals, and `AuditLog(database=...)` exist. | **Optional backend exists.** Current CLI constructs `PtahBridge()` with no database, so normal CLI use does not opt into it. Installation/configuration, migrations, operational backup, and recovery UX remain. |
| Customer-facing task creation and execution | `cyberbrain plan` invokes the prototype planner. `cyberbrain run` calls the model gateway on each roadmap-step description and saves text output. | **Not the proposed guarded coding workflow.** The current `run` command does not send the generated model result through `CoderAgent` or `AuthorizedExecutionService`; a coding-agent tool loop is not available through the normal CLI. **Decided 2026-10-02 (D2):** `run` becomes fail-closed through `AuthorizedExecutionService` + SQLite-backed `PtahBridge`, no `--insecure-legacy` bypass — **approved and implemented** (fail-closed active; existing `run` stops silent pass for sensitive actions without approval). |
| Task workspace and change review | Execution provider accepts a workspace path; Bubblewrap mounts that path writable. | **Partial.** There is no per-task Git worktree lifecycle, diff review, or safe handoff of accepted changes in the CLI. A shared working directory is too broad for the proposed review workflow. |
| Local/cloud model disclosure | `ModelGateway` exists as a library with `default_provider="litellm"` and Ollama/llama.cpp fallbacks, but no CLI command uses it (D3 — `cyberbrain run`/`plan` are model-free; `--model`/`--lang` removed). `PrivacyGateway` redacts local project-memory writes. | **Partially resolved by D3.** CLI-level prompt egress is eliminated; library-level `ModelGatewayConfig` remains a latent risk for non-CLI channels. Memory redaction does not govern prompt egress. Model/provider selection, fallback, data sent, and privacy warnings need an explicit user-visible policy. |
| Local history / audit explanation | Audit records and the `AuditLog.query(...)` API exist (`security_plane/audit/__init__.py:215`). | **Backend exists; complete user query path still missing.** **Updated 2026-10-02:** a partial user path now exists — `cyberbrain approvals history` lists recorded approval decisions (request id, agent, action, resource, decision, reviewer, timestamp, reason) and `cyberbrain approvals show <id>` returns per-request detail (`product/approvals.py:287,478`). Those records are keyed by `request_id` and agent id, **not by task id**, and carry neither the policy decision nor the execution result, so there is still **no** command that returns one task's decision chain and result in one place; `AuditLog.query(...)` is not exposed through the CLI at all, and `AIFirewall` is wired into neither the execution path nor prompt egress ([SECURITY_ONE_PAGER.md](../SECURITY_ONE_PAGER.md)), so prompt egress and content-level threats are not visible there either. |
| Installation and supported environment | Python package and Typer CLI exist; CI installs Bubblewrap on Ubuntu. | **Prototype packaging exists.** Choose a single tested distribution/version — **decided 2026-10-02: Ubuntu 24.04 LTS (D1), decided ahead of customer discovery and still to be confirmed by interviews; not implemented.** Document prerequisites, secrets, backup, and recovery, then test clean installation by a person other than the author. |

## Critical product decision before implementation

The first user entry point cannot be chosen from architecture alone:

1. **Integrate one existing coding agent** and intercept its tool/execution requests. This keeps CyberBrain from having to build another code-generation loop, but depends on a real supported integration and the agent's extension model.
2. **Build a small CyberBrain-native coding loop** around one selected model and the existing authorized execution path. This gives a controlled demo but takes more product work and enters a crowded coding-agent market.
3. **Sell only a local authorized runner** for explicit code/shell payloads. This is smallest technically but may not solve enough of the customer's workflow to command payment.

Ask interviewees to show the agent and action they already use. Select one path based on an actual design partner's willingness to pilot it; do not implement all three.

## MVP implementation slices after discovery

### Slice A — Make the secured path selectable and persistent

- Give CLI one explicit database configuration and stable local data directory.
- Route the chosen task to the `PtahBridge`/dispatcher path, not a parallel direct model call. **This is decision [D2](DECISIONS_LOG_V5.md#d2--cyberbrain-run-bude-fail-closed) (approved, implemented) and [D3](DECISIONS_LOG_V5.md#d3--cyberbrain-runplan-nevolaj%C3%AD-model--odstran%C4%9Bny---model---lang) (approved, implemented).**
- Store task inputs and state with a documented policy for secret and source retention.
- Resume only states with defined idempotency/retry semantics; keep interrupted side effects explicit.

### Slice B — Make approval understandable and actionable

- **Updated 2026-10-02:** *list, inspect, approve, deny* exist — `cyberbrain approvals pending|show|approve|deny` (`product/approvals.py:238,287,438,462`) — and reviewer identity and reason are captured via `--reviewer`/`--reason` and printed back by `show` (`product/approvals.py:321-335`) and by `history`. **Still open: *expire*.** There is no `expire` command: requests leave `PENDING` only through the lazy `manager.check_expired()` invoked inside `pending` (`product/approvals.py:251`), so a stale request cannot be expired on demand and expired requests cannot be listed or inspected from the CLI.
- Show exact action, arguments, workspace, requested scopes, task ID, policy result, and any data egress.
- Bind the decision to the request/action details. Materially changed arguments require a new evaluation and approval. **Still fully open (2026-10-02):** the approval record carries `action`, `resource` and `context` but no hash or signature of the execution payload, so the code can change between approval and `provider.execute` (`security_plane/approval/__init__.py:98-147`, open item in [SECURITY_ONE_PAGER.md](../SECURITY_ONE_PAGER.md)).
- Keep denial, timeout, cancellation, and missing approval UI fail-closed.

### Slice C — Make project changes reviewable

- Execute against a task-specific worktree or copy, not the developer's active checkout.
- Capture status and diff; require explicit user action to apply or commit changes.
- Define cleanup and interrupted-task behavior without deleting user data.

### Slice D — Make the policy and data path transparent

- Choose one supported local model path and one optional cloud path only if discovery needs both.
- Show provider/model and disclose the classes of data sent before the first remote call.
- Prevent silent local-to-cloud fallback. A failed selected provider should stop with a clear error unless the user explicitly approved a fallback.
- Keep `PrivacyGateway` claims narrow: current heuristics redact a few patterns during project-memory writes and are not complete DLP or outbound-prompt controls.

### Slice E — Package and support one pilot

- One clean install path for the chosen host — **Ubuntu 24.04 LTS per [D1](DECISIONS_LOG_V5.md#d1--podporovaný-os-ubuntu-2404-lts) (owner decision made before customer interviews; re-confirm against discovery evidence).**
- `cyberbrain doctor` checks configuration and Bubblewrap prerequisites without exposing secrets. **Updated 2026-10-02:** this is now **done and registered** — `cyberbrain doctor check` (alias `main`) is reachable from the `cyberbrain` entry point via `app.add_typer(doctor_app, name="doctor")` (`src/cyberbrain26/cli.py:21,26`, `product/doctor.py:969,976,997`), is strictly read-only, reports only *presence* flags for credential variables and never their values, and is covered by `tests/test_product_cli.py::test_doctor_never_prints_secret_values` and recorded as done in [SECURITY_ONE_PAGER.md](../SECURITY_ONE_PAGER.md). **Two caveats stand:** it is a **configuration self-report, not a verified guarantee** (`product/doctor.py:19-24` — several gates self-report `pass` without inspecting anything), and `ModelGateway.health_check` is still not called from the CLI, so provider reachability remains unverified by it.
- One versioned sample policy; no default blanket shell/Python grant.
- Document support boundaries, retention, backup and known sandbox limitations.
- Run the exact customer demo from clean install on the partner's approved test repository.

## Evidence needed before calling the MVP complete

- A design partner completes the agreed real task without the author manually operating the product.
- Every execution in the selected flow can be traced to a policy decision and either approval or a documented safe rule.
- Deny, approval timeout, cancellation, missing provider, missing Bubblewrap, restart, and interrupted task behavior are visible and fail safely.
- The user can see the resulting diff and choose what is applied.
- The task/audit data survives restart and follows the documented retention and backup procedure.
- The new user can identify which data stays local and which leaves for the selected provider.
