Skip to content

Latest commit

 

History

History
31 lines (27 loc) · 8.02 KB

File metadata and controls

31 lines (27 loc) · 8.02 KB

Architecture Decision Records

Baseline: 65de769ded3eb6e7b59eabb5daf6a8d0b89531ba · Reviewed: 2026-08-17

These records capture repository design decisions and their implementation context. An Accepted status means the repository adopted the stated design; it is not evidence of operational effectiveness, compliance, certification, formal risk acceptance, or continued production use.

ADR Status Decision scope
0001 — Development Mode restart recovery uses replacement attempts Accepted Restart recovery preserves worktree/artifact state and continues through a new attempt rather than resuming an interrupted provider stream.
0002 — Development cloud authorization uses ChatOptions.AdditionalProperties Accepted Version-aware carrier and enforcement seam for Development Mode cloud authorization.
0003 — Six-plan implementation scope and hardware evidence decisions Accepted Operator-supplied scope decisions, unavailable-hardware evidence handling, and embedding width.
0004 — Docker permitted for Development Mode execution only, as a stopgap ahead of MXC Accepted Narrows the runtime-rearchitecture epic's "no Docker anywhere" decision to "no Docker on the inference path" and unblocks its container-execution slices.
0005 — Training runs in a uv-managed Python runtime, holds the node exclusively, and lands in a thin provider project Accepted Training semantics live in Python behind a structured stdio contract; a run holds a training marker plus the runtime-mutation lease (never the GPU load-admission semaphore); a thin Providers.Training project owns only uv/venv/subprocess mechanics.
0006 — Agentic MCP keys capture bounded operator-equivalent execution authority Accepted Explicit inbound authority, durable capture across restart and rotation, agentic-root tool adaptation, and strict audit-before-invocation without granting the Operator role.
0007 — The sandbox execution substrate is capability-declared, and the backend is selected, never named Accepted A consumer declares execution requirements rather than naming a backend; a selector resolves one that can honour them and fails closed when none can. Amends ADR 0004 Decision §1 only; §2–§5 stand.
0008 — External integrations invoke a saved agent through a keyed, loopback-only surface inside /api/local/v1 Accepted An external caller invokes a saved agent through hand-mapped integration-api/… routes inside /api/local/v1 with their own xeint_ keys; admission is one BEGIN IMMEDIATE transaction bounded per node and per principal, runs are unattended and fail closed, and V1 is explicitly loopback-only.
0009 — A 409 uses the global conflict envelope, unless the refusal is an operational block with its own typed body Accepted A thrown typed domain exception answers with the one ConflictProblemDetails envelope; a refusal the service reports as a returned value — a runtime, process, build or prerequisite standing in the way — answers with a per-feature typed *BlockedResponse, built in one place per family.
0010 — User-managed application containers from the XE catalog are a separate consumer class with their own runtime layer Proposed Curated, digest-pinned application containers run on an engine-owned runtime layer beside the sandbox SPI, from an XE-owned manifest whose schema is the allow-list; ADR 0004 §5 is replaced for this class alone, and ADR 0004 §2–§4 and ADR 0007 stand.
0011 — An application container reaches the node's own inference surface through one guarded, non-loopback listener Proposed The engine opens ONE extra Kestrel listener on a LAN-facing address, serving only /llm/v1/* behind a same-host peer guard and a mandatory per-instance token; llama-server keeps binding loopback and /api/local/v1 stays loopback-only.
0012 — Local audio transcription runs on a supervised whisper.cpp daemon, captures in the browser, and never persists audio Accepted whisper.cpp is a third independent supervised runtime; capture is browser-first with Windows per-application capture as a later slice; speakers are attributed by channel (You/Others), never clustered; the Linux CUDA lane is a managed source build; and audio is never written to the database, enforced by an architecture test, a single-owner temp slot and a streaming upload.
0013 — The native desktop is a separate thin shell process that supervises the engine, never a host it links against Accepted A thin Avalonia + NativeWebView shell with no engine project references; engine ownership is attach-or-own, carried by a named-pipe parent lifetime with bounded shutdown on both sides; one shell per data root with activation; first close offers Keep in tray / Quit / Cancel with a remembered preference; Linux runs a restricted GTK document policy with microphone-only consent while Windows relies on WebView2 defaults; browser, headless, MCP-only and CLI modes bypass the window.
0014 — Update channels are app state, and Development builds ship on their own Velopack feed Accepted The selected update channel is node-settings state (Stable / Preview / Development) passed explicitly on every check, never the installed package's sticky channel; Development snapshots of develop publish daily as dev/<version> prereleases on their own win-dev / linux-dev Velopack feeds, which a Stable or Preview feed read skips silently; the app ships a paginating update source because the stock GitHub source reads only the 10 newest releases; versions extend the anchor tag with dots and never a second hyphen; updates stay forward-only.
0016 — Managed Python is one shared uv layer in its own provider project, with one pinned uv and one XE-owned toolchain store Accepted A leaf-like Providers.Python (references only Providers.Abstractions; consumed by Providers.Training and Client.Application) owns uv acquisition, the uv pin, the uv environment allowlist and the scrubbed runner; uv is pinned and digest-verified at run time, never bundled; uv, CPython and the uv cache move to one machine-global store with no automatic pruning while feature environments stay in their roots; each environment carries an explicit identity. Amends ADR 0005 Decision §3 only; lands across slices M1–M4.
0017 — Web access is two operator-enabled built-in tools, and a graph reaches the web only through an allowlisted fetch Proposed web_search (DuckDuckGo HTML default, operator SearXNG URL) and web_fetch are Network tools behind an off-by-default node setting; every fetch hop passes CustomToolSsrfGuard; output is fenced as untrusted and consented to per request and reviewed by the user before it enters context (per-conversation auto mode skips both, behind a one-time notice); graph Agent nodes never get them, and a Tool node may fetch only against a URL-prefix allowlist, the single exception to the ReadLocal-only rule.

For the baseline technical/security narrative and its explicit evidence limitations, see the Technical/Security Architecture Dossier. For what the execution substrate behind ADR 0004 and ADR 0007 actually enforces today, and what it still does not, see the sandbox threat model.