Revise the deployment model: an agent host and tool VMs #90

Merged
dev-agent merged 12 commits from deployment-model into main 2026-10-02 19:36:33 +00:00
Showing only changes of commit 2187c24d0d - Show all commits
+44 -24
View File
@@ -66,14 +66,16 @@ injection, and one built to contain a hostile model makes the agent useless.
### P3. Actions by their effects ### P3. Actions by their effects
Every action is **harmless**, **contained** or **dangerous**:
| Class | What it is | Examples | Rule | | Class | What it is | Examples | Rule |
|---|---|---|---| |---|---|---|---|
| **1. No side effects** | Changes nothing outside a disposable sandbox | Reading, querying, searching, running tests in a throwaway environment | Always allowed | | **Harmless** | Changes nothing outside a disposable sandbox | Reading, querying, searching, running tests in a throwaway environment | Always allowed |
| **2. Contained** | Stays within the agent's own area, or has a known undo | Editing the workspace, committing to the agent's branch, opening a PR, writing its own notes; for ops, an approved step with a known undo | Allowed in scope; logged and reported | | **Contained** | Stays within the agent's own area, or has a known undo | Editing the workspace, committing to the agent's branch, opening a PR, writing its own notes; for ops, an approved step with a known undo | Allowed in scope; logged and reported |
| **3. Dangerous** | Irreversible, visible beyond the agent's area, or outside what was agreed | Merging to a default branch, deleting data, changing a firewall, installing on a host the agent doesn't own, contacting third parties, spending beyond a budget | Needs discussion, unless an approved step sequence (O2) or the operator in conversation names the exact action | | **Dangerous** | Irreversible, visible beyond the agent's area, or outside what was agreed | Merging to a default branch, deleting data, changing a firewall, installing on a host the agent doesn't own, contacting third parties, spending beyond a budget | Needs discussion, unless an approved step sequence (O2) or the operator in conversation names the exact action |
**In scope** means within what the operator agreed to (L3). The same action can be **In scope** means within what the operator agreed to (L3). The same action can be
class 2 in one work item and class 3 in another. **Move actions down the classes contained in one work item and dangerous in another. **Make actions less dangerous
wherever it is cheap** (P5). wherever it is cheap** (P5).
### P4. Three layers of control ### P4. Three layers of control
@@ -82,7 +84,7 @@ wherever it is cheap** (P5).
destinations it can't reach (X2), branches it can't push to or merge into, mounts destinations it can't reach (X2), branches it can't push to or merge into, mounts
it doesn't have, budget caps, the kill switch, idempotent external effects (L8). it doesn't have, budget caps, the kill switch, idempotent external effects (L8).
They hold even if every model is fooled. They hold even if every model is fooled.
2. **A deterministic fast path:** class-1 actions, and class-2 actions a static rule 2. **A deterministic fast path:** harmless actions, and contained ones a static rule
recognises as in scope, proceed without asking any model. Most actions go here. recognises as in scope, proceed without asking any model. Most actions go here.
3. **The action classifier** (L4) for everything else. 3. **The action classifier** (L4) for everything else.
@@ -117,9 +119,10 @@ naming a milestone (D4).
review), on the operator's own inference host behind LiteLLM (L9). review), on the operator's own inference host behind LiteLLM (L9).
- **Frontier models are helpers the driver calls:** a quick question - **Frontier models are helpers the driver calls:** a quick question
(`ask_expert`) or a scoped sub-task (delegation), L9. (`ask_expert`) or a scoped sub-task (delegation), L9.
- **Escalation never depends on self-assessment alone.** The driver is prompted to - **Escalation doesn't wait for the model to notice.** The driver is prompted to
ask for help when unsure, and observable triggers (repeated failures, caps) ask for help when unsure, which is its own judgement; observable triggers
escalate too, since small models are poorly calibrated. (repeated failures, caps) escalate as well, even when it doesn't ask, since small
models are poorly calibrated about their own competence.
- **This is an experiment with a cheap exit:** if a local model falls short at some - **This is an experiment with a cheap exit:** if a local model falls short at some
kind of work, a frontier model drives it instead, as a configuration change. kind of work, a frontier model drives it instead, as a configuration change.
@@ -210,7 +213,7 @@ again after a restart), permissions (L3), and work in progress as intents (L8).
- **Dev work:** the assigned issue and what was agreed in its conversation (D1). - **Dev work:** the assigned issue and what was agreed in its conversation (D1).
Documents inform it but don't widen it (D2). The real check is the PR review. Documents inform it but don't widen it (D2). The real check is the PR review.
- **Ops work:** an approved step sequence, exactly (O2). - **Ops work:** an approved step sequence, exactly (O2).
- **Always discussed first:** any class-3 action not named by an approved step - **Always discussed first:** any dangerous action not named by an approved step
sequence or by the operator in conversation. sequence or by the operator in conversation.
- **Labels and words steer, and are never required** (D1): leaving one off is never - **Labels and words steer, and are never required** (D1): leaving one off is never
an error. an error.
@@ -261,12 +264,19 @@ executes nothing, so it runs on the agent host.
room per agent, behind a `Transport` interface so another chat system is one new room per agent, behind a `Transport` interface so another chat system is one new
class. Existing Matrix clients are the UI. class. Existing Matrix clients are the UI.
**A thread per work item.** Each item's conversation is a Matrix thread. **A thread per work item.** Each item's conversation is a Matrix thread, and the
- A reply in a thread goes to that item, even while it is parked. thread is how the agent knows which item a message is about.
- Commands in a thread apply to that item. At top level, `stop` applies to the - **When a thread starts:** with the item. For an assigned issue, the agent's
active item and `status` to the agent; any other top-level message starts a new acknowledgement ("queued myproject#14") is the thread's first message. For a
conversation in its own thread, and the agent offers to continue an existing item conversation, the operator's own top-level message is, and the agent replies in
if it clearly belongs there. a thread under it. The item records its thread, so the mapping survives restarts.
- **Inside a thread,** every message and command (`go`, `stop`, `abandon`, an
answer) applies to that item, even while it is parked.
- **At top level,** `status` is about the agent and `stop` stops the active item. A
command that names its item applies to it ("abandon #14"). Any other command is
ambiguous, so the agent asks which item rather than guessing. Any other message
starts a new conversation, and the agent offers to continue an existing item if
it clearly belongs there.
- **Any conversation about work is a work item from its first message,** however - **Any conversation about work is a work item from its first message,** however
vague ("I'm having trouble with X…"). It may end with a project, an issue, or vague ("I'm having trouble with X…"). It may end with a project, an issue, or
just an answer. just an answer.
@@ -638,10 +648,10 @@ the project needs and installs any gap **before any planning**; toolchain versio
become facts (L6). become facts (L6).
**The build VM is the agent's to change:** installing packages and toolchains there, **The build VM is the agent's to change:** installing packages and toolchains there,
cleaning caches or reinstalling dependencies to fix a broken build are class 2, cleaning caches or reinstalling dependencies to fix a broken build are contained,
reported but not asked about. Every install is recorded (as a fact and in scope reported but not asked about. Every install is recorded (as a fact and in scope
memory) so the VM can be rebuilt; recurring ones go into the template (X4). memory) so the VM can be rebuilt; recurring ones go into the template (X4).
Installing on any other host is class 3. Installing on any other host is dangerous.
### D4. Git, branches and PRs ### D4. Git, branches and PRs
@@ -693,9 +703,9 @@ Installing on any other host is class 3.
| Class | Examples | | Class | Examples |
|---|---| |---|---|
| 1 | Reading the repository, running builds and tests on the build VM, querying Gitea | | Harmless | Reading the repository, running builds and tests on the build VM, querying Gitea |
| 2 (in scope) | Editing the workspace; milestone branches, pushes and PRs; commenting on its issues and PRs; filing agreed issues (D1); changing its build VM (D3) | | Contained (in scope) | Editing the workspace; milestone branches, pushes and PRs; commenting on its issues and PRs; filing agreed issues (D1); changing its build VM (D3) |
| 3 | Merging to the default branch (unless the trust dial allows), deleting remote branches or others' work, changing repository settings, anything outside the item's repository or build VM | | Dangerous | Merging to the default branch (unless the trust dial allows), deleting remote branches or others' work, changing repository settings, anything outside the item's repository or build VM |
### D7. Deployment and isolation ### D7. Deployment and isolation
@@ -754,7 +764,7 @@ stricter controls because live changes have no review step before they take effe
|---|---|---| |---|---|---|
| Undo | discard a branch | often none (`zfs destroy`, a firewall lockout) | | Undo | discard a branch | often none (`zfs destroy`, a firewall lockout) |
| Scope | the assigned issue and its conversation | approved step sequences (O2) | | Scope | the assigned issue and its conversation | approved step sequences (O2) |
| Class 3 | discuss | discuss, and exact-step approval | | Dangerous actions | discuss | discuss, and exact-step approval |
| Work shape | milestones → PRs | short reactive tasks → live changes | | Work shape | milestones → PRs | short reactive tasks → live changes |
| Intake | issues in the project's repository, Matrix | issues in the infrastructure repository, alerts, duties, Matrix | | Intake | issues in the project's repository, Matrix | issues in the infrastructure repository, alerts, duties, Matrix |
| Reach | sealed build VMs | Tailscale, credentials, both sites | | Reach | sealed build VMs | Tailscale, credentials, both sites |
@@ -795,9 +805,9 @@ template with a trigger, rate limit and expiry, for a routine fix).
| Class | Examples | | Class | Examples |
|---|---| |---|---|
| 1 | Metrics, logs, status, read-only MCP calls, issues, the world model | | Harmless | Metrics, logs, status, read-only MCP calls, issues, the world model |
| 2 (in scope) | Approved steps with a known undo; its own world model; commenting on and filing issues in the infrastructure repository | | Contained (in scope) | Approved steps with a known undo; its own world model; commenting on and filing issues in the infrastructure repository |
| 3 | Every other infrastructure write; browser actions on admin UIs (each confirmed); **anything on network gear**, the most conservative case, since a bad change can sever the path to fix it | | Dangerous | Every other infrastructure write; browser actions on admin UIs (each confirmed); **anything on network gear**, the most conservative case, since a bad change can sever the path to fix it |
### O4. Interfaces ### O4. Interfaces
@@ -917,6 +927,16 @@ shared between agents.
- **Browser access to network gear:** standing, or handed off per task. - **Browser access to network gear:** standing, or handed off per task.
- **Relocating a stateful MCP server** off the agent host, if one ever justifies - **Relocating a stateful MCP server** off the agent host, if one ever justifies
losing attribution. losing attribution.
- **The state store's engine.** SQLite, one database per agent, for now. If
scaling or backups call for it, a server database such as PostgreSQL on the agent
host (still one database and role per agent).
- **`nisse-ops` issuing credentials** to other agents: an SSH key for a new VM, Gitea
credentials for a new project. Writing into another agent's secret set crosses
the isolation in L12, so it needs a designed channel and its own approval rule.
- **Releases.** Building and publishing artifacts at each release, usually by tag,
sometimes from release branches: what the agent may do (a release is visible
beyond its own area, so dangerous unless the trust dial says otherwise) and how a
build plan names one.
- **Recovering the agent host.** It is a single point of failure for every agent, - **Recovering the agent host.** It is a single point of failure for every agent,
`nisse-ops` included, so its recovery can't depend on ops running. A recovery `nisse-ops` included, so its recovery can't depend on ops running. A recovery
plan (rebuilding the host, restoring state from snapshots) is ops work still to plan (rebuilding the host, restoring state from snapshots) is ops work still to