# Capability status — verified source of truth

One table, one rule: **a capability is only `WORKING` if there is code, a test, and a
command that reaches it.** If you cannot point to all three, it is not a feature of this
product.

Status vocabulary:

| Status | Meaning |
|---|---|
| `WORKING` | Implemented, reachable from the CLI, exercised by tests. |
| `PARTIAL` | Reachable, but materially incomplete or with a documented dead end. |
| `LIBRARY-ONLY` | Exists and works in the library, but no CLI path reaches it. |
| `ABSENT` | Not implemented. Nothing advertises it. |

Evidence is `path:line` in this repository. Re-verify before trusting it: the working tree
changes. Verified on 2026-10-02.

## Commands

| Capability | Status | Evidence | How to try it |
|---|---|---|---|
| `cyberbrain version` | WORKING | `cli.py:365` | `cyberbrain version` |
| `cyberbrain plan` | PARTIAL | `cli.py:371`; placeholder planner `agents/orchestrator.py:151-157` | `cyberbrain plan --goal "x"` — output is a hardcoded 3-step plan, not reasoning |
| `cyberbrain run` | PARTIAL | `cli.py:446-556` | `cyberbrain run --id <id> --scopes python` — needs a hand-written roadmap, see quickstart §6 |
| `cyberbrain approvals pending` | WORKING | `product/approvals.py:238` | `cyberbrain approvals pending` |
| `cyberbrain approvals show` | WORKING | `product/approvals.py:287` | `cyberbrain approvals show <id>` |
| `cyberbrain approvals approve` | WORKING | `product/approvals.py:438` | two-terminal flow, quickstart §7 |
| `cyberbrain approvals deny` | WORKING | `product/approvals.py:462` | `cyberbrain approvals deny <id>` |
| `cyberbrain approvals history` | WORKING | `product/approvals.py:478` | `cyberbrain approvals history` |
| `cyberbrain doctor check` | WORKING | `product/doctor.py:976` | `cyberbrain doctor check [--json] [--strict]` |
| `cyberbrain doctor main` | WORKING | `product/doctor.py:997` (alias) | `cyberbrain doctor main` |
| `cyberbrain knowledge ingest /path/to/docs` | PARTIAL | `cli.py:615-672` | `cyberbrain knowledge ingest /path/to/docs` — walks directory, chunks, embeds via Ollama `qwen3-embedding:0.6b` (dim=1024), stores in LanceDB; audit via AuditLog |
| `cyberbrain knowledge search "dotaz"` | PARTIAL | `cli.py:674-709` | `cyberbrain knowledge search "dotaz"` — semantic/vector search přes `MemoryService` nad LanceDB (cli.py:674-709, volání `memory_service.semantic_search`/`hybrid_search`); vrácení ranked výsledků se source metadata |
| Any other command | ABSENT | cli.py:76-77 (app.add_typer approvals/doctor), cli.py:615-616 (@app.command knowledge), cli.py:379-380 version, cli.py:385-386 plan, cli.py:472-473 run | — |

Console script: `cyberbrain = cyberbrain26.cli:main` (`pyproject.toml:46`).

## Security chain on the `run` path

| Capability | Status | Evidence | How to try it |
|---|---|---|---|
| Identity / trust gate | WORKING | `security_plane/permission/__init__.py:129-145`; `policy/__init__.py:284-292` | run a step with an `UNTRUSTED` identity — denied |
| Permission scope gate | WORKING | `permission/__init__.py:82-95,147-165`; `--scopes` `cli.py:456,469` | omit `--scopes`; a code step is denied |
| Policy engine, default deny, SAFE mode | WORKING | `policy/__init__.py:181-245,263-316` | `SENSITIVE_ACTIONS` always route to approval |
| Human approval gate | WORKING | `execution_plane/secure_gateway.py:142-222`; `extension_layer/registry_impl.py:141-241` | quickstart §7 |
| Fail-closed dispatch (`run`) | WORKING | `extension_layer/registry_impl.py:243-251`; `cli.py:496-526` | a step without `action` is refused |
| Sandbox (Bubblewrap) | PARTIAL | `execution_plane/bubblewrap_provider.py:97-258` | quickstart §6-7 |
| No unsandboxed fallback | WORKING | `bubblewrap_provider.py:129-134` raises `RuntimeError` | remove `bwrap`, run: every step refused |
| Audit trail | PARTIAL | `security_plane/audit/__init__.py:122`; 24 event types `:24-50` | events land in SQLite `audit_events` |
| Audit **query** from CLI | ABSENT | `AuditLog.query` exists at `audit/__init__.py:215`, no CLI caller | read the SQLite file directly |
| `plan` -> `run` | ABSENT | `cli.py:405-413` (no `action` emitted) vs `cli.py:498-507` (refused) | run a planned roadmap; all steps refused |

## Sandbox specifics and limits

| Control | Status | Evidence |
|---|---|---|
| `--unshare-all`, `--die-with-parent`, `--new-session` | WORKING | `bubblewrap_provider.py:152-158` |
| Read-only `/usr`, fresh `/dev`, `/proc`, tmpfs `/tmp` | WORKING | `bubblewrap_provider.py:157-166` |
| Exactly one workspace bind mount | WORKING | `bubblewrap_provider.py:167-168` |
| Workspace confined to `<data dir>/workspaces` | WORKING | `bubblewrap_provider.py:120-127`; `product/local_store.py:274-301` |
| Cleared environment, fixed `PATH`/`HOME` | WORKING | `bubblewrap_provider.py:169-171` |
| Output capped at 1 000 000 bytes per stream | WORKING | `bubblewrap_provider.py:246-258` |
| `RLIMIT_CPU` / `RLIMIT_AS` / `RLIMIT_FSIZE` | PARTIAL | `bubblewrap_provider.py:220-244` — cooperative child limits, not enforcement |
| Wall-clock timeout + kill | WORKING | `bubblewrap_provider.py:195-199` |
| seccomp filter | ABSENT | no seccomp argument in the argv list |
| Landlock / LSM | ABSENT | no LSM code in `src/` |
| cgroup, PID, memory, disk, inode quotas | ABSENT | stated in `product/doctor.py:104-111` |
| uid/gid pinning, capability dropping | ABSENT | not in the argv list |
| Full host `/usr` incl. site-packages visible/executable | PRESENT (a limit) | `bubblewrap_provider.py:157` |

Disposition, quoted from `EXECUTION_SECURITY_REVIEW.md`: *"suitable for a constrained local
prototype; NOT approved as a general-purpose hostile-code sandbox."*

## Persistence

| Capability | Status | Evidence | Notes |
|---|---|---|---|
| Local SQLite store, 7 tables | WORKING | `data_plane/sqlite_store.py:14-127` | `tasks`, `approval_requests`, `approval_records`, `audit_events`, `project_memories`, `provenance_records`, `schema_migrations` |
| Schema version 1 | WORKING | `sqlite_store.py:129` | migration refuses a newer store |
| WAL + `synchronous = FULL` | WORKING | `sqlite_store.py:233-234` | |
| Data dir `0700` | WORKING | `product/local_store.py:92-110` | |
| DB file `0600` | PARTIAL | `sqlite_store.py:262` | best-effort: `chmod` failure is swallowed |
| Approval persistence across processes | WORKING | `security_plane/approval/__init__.py`; `product/approvals.py:109-147` | the two-terminal flow depends on it |
| Retention window configured (default 90 days) | WORKING | `product/local_store.py:140-169` | fail-closed on a malformed value |
| Retention pruning scheduled | ABSENT | no CLI caller of `prune_expired`; callers are `audit/__init__.py:271`, `approval/__init__.py:290` | the 90-day window is a setting, not a behaviour |
| Secure erasure | ABSENT | `sqlite_store.py:195-229` | logical delete only |
| Encryption at rest | ABSENT | no encryption code in `src/` | |

## Configuration

| Capability | Status | Evidence |
|---|---|---|
| `CYBERBRAIN_DATA_DIR` | WORKING | `product/local_store.py:53,86` |
| `CYBERBRAIN_DB_PATH` | WORKING | `product/local_store.py:54,134` |
| `CYBERBRAIN_RETENTION_DAYS` | WORKING | `product/local_store.py:55,157` |
| `CYBERBRAIN_WORKSPACES_ROOT` | WORKING | `product/local_store.py:56`; read at `bubblewrap_provider.py:92` |
| A configuration file | ABSENT | no config loader in `src/` |
| `.env` files read by the app | ABSENT | zero `load_dotenv` calls in `src/`; `python-dotenv` is a declared dependency that nothing uses |
| `.env.example` correctness | was WRONG, now fixed | old file documented `CB26_*` vars that no code reads |

## Library-only and dead code

Do not present any of these as product capabilities.

| Component | Status | Evidence |
|---|---|---|
| `ModelGateway`, `ModelRouter` | LIBRARY-ONLY | `control_plane/model_gateway/__init__.py:233` — no CLI caller; `cli.py` has no model import |
| `ModelGatewayConfig` default `default_provider="litellm"` + silent fallback | LIBRARY-ONLY, open risk | `control_plane/model_gateway/__init__.py:43-45,325-349` — contradicts the no-silent-cloud promise |
| LiteLLM / Ollama / llama.cpp clients | LIBRARY-ONLY | `model_layer/` — unreachable from the CLI |
| `AIFirewall` (727 lines) | LIBRARY-ONLY, guards nothing | `security_plane/firewall/__init__.py` — not called by the gateway, policy engine or dispatcher |
| `PrivacyGateway` redaction | LIBRARY-ONLY | `security_plane/privacy_gateway.py` — not called on any egress path |
| `control_plane/api` router skeleton | DEAD CODE | `control_plane/api/__init__.py` — zero registered routes, zero importers |
| `control_plane/registry` | DEAD CODE | `control_plane/registry/__init__.py` — zero importers |
| `AsyncEventBus` | WORKING, in-process | `control_plane/event_bus/__init__.py:85-105` — fans out to every subscriber |
| Bus-task authorization for agents | PARTIAL | `TaskAuthorizer` protocol + `DispatcherAuthorizer` adapter `agents/orchestrator.py:64-140`; refusal on missing/raising authorizer `:229-260` — but `PtahBridge` never assigns an authorizer (`orchestration/ptah_bridge.py` has no `authorizer`), so bus-delivered `*_TASK_REQUEST` events are refused today |
| Zero-byte placeholder packages | ABSENT | `core/`, `governance_plane/`, `experience_layer/`, `personal_ai_layer/`, `integration_layer/`, `data_plane/schemas/`, `execution_plane/tools/` — all 0 bytes, zero importers |
| HTTP server / REST API / web UI / TUI / MCP server | ABSENT | no FastAPI/uvicorn anywhere in `src/` |
| Git worktree, `git diff`, change review, merge | ABSENT | zero occurrences of `worktree` / `git diff` in `src/` |
| Browser / Git / Docker / ChromaDB / Notebook execution backends | ABSENT | `execution_plane/tools/` is a 0-byte file |
| `TelemetryProvider (OpenTelemetry)` extension contract | ABSENT | never existed in `src/`; the old README listed it |
| CI badge | must not be claimed | `.github/workflows/ci.yml` exists but `git remote -v` is empty: the workflow has never run |

## Agents and orchestration

| Capability | Status | Evidence |
|---|---|---|
| Six built-in roles (planner, coder, evaluator, security, research, browser) | PARTIAL | `orchestration/ptah_bridge.py:205-268` |
| Durable step records + `execution_attempted` marker | WORKING | `orchestration/ptah_bridge.py:363-504`; `agents/orchestrator.py:43-56` |
| Real planning | ABSENT | `agents/orchestrator.py:151-157` emits a hardcoded 3-step plan |
| Research / browser / security agents doing real work | ABSENT | inspect `agents/orchestrator.py`; no live research, browsing or scanning backend |
| Model call in `plan` or `run` | ABSENT (deliberate) | `cli.py` imports no model gateway |

## Tests and CI

| Item | Value |
|---|---|
| Recorded figure at the time of writing | `413 passed` (`PYTHONPATH=src python3 -m pytest -q`, 2026-10-02, Bubblewrap 0.9.0 present on this host). The tree is uncommitted and was moving while this table was written — re-run before quoting the number. |
| Canonical action vocabulary (`security_plane/actions.py`) | IN PROGRESS | module exists in the working tree with zero importers: `ACTION_SCOPE_REQUIREMENTS:64`, `SENSITIVE_ACTIONS:81`, `KNOWN_SAFE_ACTIONS:108`, `is_registered_action:118` — the deny-by-default vocabulary is not yet consulted by `PermissionGateway` (`permission/__init__.py:148`) or `PolicyEngine` |
| CI job `quality` | runs pytest + ruff + mypy on `ubuntu-latest` (`.github/workflows/ci.yml`) |
| CI job `no-bubblewrap-fail-closed` | uninstalls `bwrap`, asserts it is unresolvable, runs the suite, asserts execution raises (`.github/workflows/ci.yml`) |
| Has CI ever run? | **No.** `git remote -v` is empty; no tags exist |
| Untracked in the working tree | `src/cyberbrain26/product/`, `tests/test_product_cli.py`, `tests/test_cli_run_authorized.py`, `tests/conftest.py`, `docs/SECURITY_ONE_PAGER.md` — the working tree is ahead of `HEAD` |

## If you add a capability

Update this table in the same commit, with a `file:line`. If you cannot cite the line, the
capability is not done.
