Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cba35eb7d4 | ||
|
|
5045faefad | ||
|
|
d44581539b |
No files matched your search
+78
-4
@@ -21,6 +21,7 @@ overnight and expects to be treated well in return.
|
||||
| Dev Agent | `nisse-dev` | Designs and builds software projects (Part D) |
|
||||
| Review Agent | `nisse-review` | Reviews pull requests (Part R) |
|
||||
| Sysadmin Agent | `nisse-ops` | Operates infrastructure (Part O) |
|
||||
| Status page | `nisse-ui` | Shows the operator what the agents are doing and how (X6); not an agent |
|
||||
|
||||
More agents are planned (3D design work, video-file management), each another
|
||||
application over `nisse-core`. One string names all of an agent's artifacts
|
||||
@@ -220,6 +221,10 @@ again after a restart), permissions (L3), and work in progress as intents (L8).
|
||||
next tool boundary, unmounts elevated credentials, and asks what next.
|
||||
- **`abandon` ends a work item** from any waiting point, closing its record and
|
||||
any open PRs with a note and aborting its unresolved intents.
|
||||
- **A run going in circles ends** rather than running to its turn cap: turns that
|
||||
repeat near-identically, or one correction (such as "reply with a tool call")
|
||||
given again and again, end it in code, escalated with what it was doing. A loop
|
||||
the model can't leave is the harness's to fix, not the model's to push through.
|
||||
- **Every action passes through the three layers** (P4).
|
||||
|
||||
### L3. Authority: scope and approvals
|
||||
@@ -278,7 +283,8 @@ executes nothing, so it runs on the agent host.
|
||||
|
||||
**Matrix is the conversation channel:** a self-hosted homeserver, one identity and
|
||||
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 for conversation and commands; a
|
||||
read-only page shows each agent's work, and how it went, in detail (X6).
|
||||
|
||||
**A thread per work item.** Each item's conversation is a Matrix thread, and the
|
||||
thread is how the agent knows which item a message is about.
|
||||
@@ -332,7 +338,8 @@ logs the outage; interrupted outbound effects are covered by intents (L8).
|
||||
### L6. Context and memory
|
||||
|
||||
**1. The working context of one model call** is rendered from the log at call time
|
||||
for one role, fitted to that model's window, and never stored.
|
||||
for one role, fitted to that model's window, and never stored as state. A copy
|
||||
goes into the call record (L7) for the operator to study; nothing reads it back.
|
||||
- **A long run is compacted:** well before the window fills, the model's own
|
||||
notes replace the middle of its run in one step (a `compaction` event, L7),
|
||||
keeping word for word what started the work and its last few turns. Rare,
|
||||
@@ -411,6 +418,30 @@ call time.
|
||||
delegation that produced it.
|
||||
- **The log is never edited;** corrections and compactions are new events.
|
||||
|
||||
**The call record** is a second store beside the log, for study only: `nisse-core`
|
||||
writes it for every model call of every agent, into its own file on the agent's
|
||||
volume.
|
||||
- **What each call was:** the request exactly as sent (system prompt, tools,
|
||||
messages, `tool_choice`, output limit; never headers, so no credential), the raw
|
||||
response with its reasoning, the model asked and the one that answered, time,
|
||||
tokens, the server's own count of prompt reuse, and what fitting cut. A failed
|
||||
call is recorded with its error.
|
||||
- **Where it came from:** its work item, role and run (a driver run, a consult, a
|
||||
compaction, a classification), and for each message, the log events it was
|
||||
rendered from and what rendering did to them (unchanged, labelled, narrated,
|
||||
compacted, shortened and by how much), with what was dropped. So a request reads
|
||||
against the log it was made from (L6).
|
||||
- **Content is stored once,** by hash: a long, growing conversation costs about one
|
||||
copy of itself.
|
||||
- **It is never load-bearing:** nothing in the agent reads it, a failed write is
|
||||
logged and the call goes ahead, and it is deleted when the agent starts. Its
|
||||
layout never migrates; it carries its version for the page (X6).
|
||||
- **Agents are told:** while it records, each system prompt says in one sentence
|
||||
that the agent's calls are recorded for the operator's study.
|
||||
- **On by default, off per agent** in its configuration: an agent that handles
|
||||
other people's lives (a household's presence, conversations, cameras) records
|
||||
nothing unless they know.
|
||||
|
||||
### L8. Durability and recovery
|
||||
|
||||
**The state store** (SQLite) holds each work item's position, permissions, pending
|
||||
@@ -1078,8 +1109,9 @@ template with a trigger, rate limit and expiry, for a routine fix).
|
||||
|
||||
**One agent host,** stable and long-lived. Each agent is a container on it with its
|
||||
own volume (state, transcripts), secrets (L12) and network; no agent can reach
|
||||
another's. Its MCP servers run beside it (X3). The vault lives here (L10). **It never
|
||||
runs a command a model chose** (L13), which is what makes sharing it safe.
|
||||
another's, and only the status page reads their volumes, read-only (X6). Its MCP
|
||||
servers run beside it (X3). The vault lives here (L10). **It never runs a command
|
||||
a model chose** (L13), which is what makes sharing it safe.
|
||||
|
||||
**Tool VMs** are where model-chosen commands run, reached only over SSH from the
|
||||
agent host, each built from a template plus recorded installs and disposable:
|
||||
@@ -1135,10 +1167,52 @@ Vaultwarden, Samba AD with Authelia, and SilverBullet for the operator's view of
|
||||
the vault. Each agent has its own account, token and room in each; nothing is
|
||||
shared between agents.
|
||||
|
||||
### X6. The status page
|
||||
|
||||
**`nisse-ui`** is the operator's view of the agents: what each is doing, and how it
|
||||
did it in full detail. It is for understanding the system (how context, compaction
|
||||
and memory work in practice), more than for daily use.
|
||||
- **What it shows:** per agent, the active item, what's queued, parked and blocked
|
||||
and why, recent closed items, with links to issue, PR and thread; and per item, a
|
||||
walkthrough: its steps (runs, and the orchestrator's facts and gates between
|
||||
them), each run's turns, and each turn's request and response from the call
|
||||
record (L7), readable: where each message came from and what was done to it,
|
||||
what changed since the previous turn and where prompt reuse stopped, the
|
||||
reasoning, and the raw JSON. Memory appears as the log records it: the index
|
||||
when it was shown, each note read or written. Work from before the agent's last
|
||||
start has its steps but no requests.
|
||||
- **Loops are flagged:** near-identical turns, repeated apologies, one correction
|
||||
given again and again, so they're seen and fixed (L2).
|
||||
- **It reads, never writes:** each agent's state store and call record through a
|
||||
read-only mount, opened read-only in short transactions, and the agent's memory
|
||||
folder read-only, as SilverBullet does (L10). Each agent stays the only writer
|
||||
of its state (L8), and agent code doesn't change for the page. It runs no
|
||||
model, holds no credentials and reaches nothing but the mounts and Caddy.
|
||||
- **Versions:** it is released with the agents, from the same tag. It reads the
|
||||
state store's schema versions it knows and says so for any other, rather than
|
||||
guessing; it reads item data tolerantly (defaults for missing fields, raw names
|
||||
for unknown states), for the gap while one container updates before another.
|
||||
CI tests it against stores written by the agents' own code, so a change that
|
||||
would break it fails in the same PR.
|
||||
- **Any recorded run opens,** not only a live agent's: bring-up, end-to-end and
|
||||
benchmark runs leave the same two files.
|
||||
- **Everything it shows is untrusted text** (L11): it is escaped, and the page
|
||||
allows no script it didn't ship.
|
||||
- **Access** is through Caddy behind Authelia, the operator's group only: it shows
|
||||
everything the models saw, including what other people wrote (peers, issue
|
||||
authors, whatever an agent handles). Nothing is exported from it.
|
||||
- **Commands come later** (Part Q), never by writing an agent's files: as another
|
||||
`Transport` (L5), so a button sends what Matrix would, with the same rules and
|
||||
record.
|
||||
|
||||
---
|
||||
|
||||
## Part Q — Open questions
|
||||
|
||||
- **Commands from the status page** (X6): how they reach each agent and show who
|
||||
sent them (a per-agent inbox only the page writes, or signed requests). The
|
||||
first are `stop`, priority ("do #N next"), and a **hold**: a task, or a whole
|
||||
agent, does nothing until released. A hold is a new command, in Matrix too.
|
||||
- **The classifier's model,** and how its verdicts are calibrated against overrides.
|
||||
- **Recognising questions:** an explicit marker or classification; a misread asks.
|
||||
- **How far the local driver goes,** measured on real work (P7).
|
||||
|
||||
@@ -578,6 +578,23 @@ Samba AD principal (L12).
|
||||
|
||||
**M6.5 The browser tool.** *Pre-approved.* On the internal test network (D7).
|
||||
|
||||
**M6.6 The status page.** *Pre-approved (design agreed 2026-10-24, #109).*
|
||||
`nisse-ui` (X6), for studying how the agents work: context, compaction, memory.
|
||||
Slices a–c are built on this box before the agent host is ready, against
|
||||
bring-up, end-to-end and benchmark runs; only d waits for M6.1.
|
||||
- **a. The call record** (L7) in `nisse-core`: written by the shared model client
|
||||
and `Driver.run`, with each message's provenance from the per-role view and
|
||||
fitting; wired in each agent's build; deleted at start. Each system prompt
|
||||
says the calls are recorded, while they are.
|
||||
- **b. The walkthrough:** an item's steps, each run's turns, and each request read
|
||||
against the log it was made from; runs going in circles flagged.
|
||||
- **c. The overview:** each agent's active, queued, parked and blocked items.
|
||||
- **d. Deployment:** its image, the read-only mounts and a Caddy route behind
|
||||
Authelia (with #166).
|
||||
|
||||
Commands wait (Part Q). The shared database #109 first proposed is dropped: each
|
||||
agent keeps its own store.
|
||||
|
||||
### Phase 7 — `nisse-core` and `nisse-review`
|
||||
|
||||
`nisse-review` (Part R) comes before `nisse-ops`: it writes only comments, so it
|
||||
@@ -780,6 +797,13 @@ publishes `gitea.dongar.net/dev/nisse-review` beside `nisse-dev`, and
|
||||
**M7.7 Deployment.** *Waits for the agent host (Phase 6).* Its container on the
|
||||
agent host, Gitea account and secrets (R5).
|
||||
|
||||
**M7.8 Runs that go in circles end** (L2). *Pre-approved.* In `Driver.run`, for
|
||||
every agent. Seen 2026-10-24 on Flash-Next: invented tool names met with the
|
||||
prose reminder turn after turn, and a no-thinking run posting the same apology
|
||||
comment about 20 times until the turn cap. Repeated near-identical turns, or the
|
||||
same correction given too often, end the run as escalated, with what it was
|
||||
doing; the limits are tuning.
|
||||
|
||||
### Phase 8 — `nisse-ops`
|
||||
|
||||
**M8.1 MCP servers** (#37). Settled so far: redaction scrubs each instance's own
|
||||
@@ -796,6 +820,7 @@ the Terraform the operator is writing now. **M8.4 The ops tool VM and deployment
|
||||
From the architecture's open questions and older issues: filing issues from
|
||||
conversation; stacked PRs; releases; `nisse-ops` issuing credentials; a server
|
||||
database; recovering the agent host (an ops issue); more than one active work item;
|
||||
commands from the status page, with a hold on a task or agent (X6);
|
||||
vision; one local model for every agent; several forges (#26); a room per project
|
||||
(#28).
|
||||
|
||||
@@ -816,6 +841,7 @@ vision; one local model for every agent; several forges (#26); a room per projec
|
||||
| #69 inline review comments | M2.1 |
|
||||
| #70 watch stall | M2.1 |
|
||||
| #77 conversational agent | M2.3 (questions), M2.7 |
|
||||
| #109 a UI for every agent's status (no shared database) | M6.6 |
|
||||
| #137 block on an unreachable build VM | M4.4 |
|
||||
| #144 redact secrets an MCP server returns | After M8.1 |
|
||||
|
||||
|
||||
Reference in new issue
Block a user