Files
hq/02-DECISIONS/0003-agents-are-persistent-employees.md
T
jschoubben fd7f7557bd The node's own session, and why it is not hired
Answering a question that was asked three times and that I kept not answering:
should the node's session just be an agent per node, since otherwise the
functionality exists at two levels?

Same mechanism, different lifecycle. A persistent session, accumulating memory,
a system prompt, a scoped tool list, addressable by message -- identical, and
building that twice is the duplication the question was worried about. What
must not be shared is the lifecycle, because if a node's own voice were an
ordinary hired agent it could be retired, leaving a node nothing can talk to;
reassigned, moving one machine's mind onto another; hired twice, with no answer
to which one replies; or never hired, leaving a node mute. The exemption in
this record exists to make those four unreachable.

I had this backwards earlier today and said so out loud: I called "a node
itself is an agent of a kind exempt from the hiring lifecycle" a fossil of the
old model and recommended striking it. It is the design. And it does not
conflict with 0001 -- "the two agent rows per node merge" means one per node,
not zero. I read merge as delete and invented a contradiction between two
records that agree.

Engrams are recorded for the first time. They are in use on every node and
appear in no record, which is how a decided thing comes to look accidental.
The engram is the node's system prompt, and it is what makes one node's answers
recognisably its own rather than generic.

Also recorded: there is no authorisation between nodes, because every node is
the operator's own and a prompt from one is a prompt from them. The consequence
is stated once rather than left to be discovered -- the mesh boundary is the
security boundary, which is what puts the whole perimeter on the token and the
overlay.

And how a node passes a question on is the node's choice, not a protocol field.
A node may say who is asking or may simply ask, the way a person relaying a
question decides how to phrase it. That follows from the engram. The cost is
that there is no machine-readable chain of who ultimately asked; each node
still holds what it was asked and by whom.
2026-08-29 14:01:00 +02:00

132 lines
6.8 KiB
Markdown

---
topic: the mesh
status: accepted
date: 2026-07-12
deciders: jochen
reconstructed: true
---
# 3. An agent is a persistent employee, not an instance of a pool
> Reconstructed after the fact from the evidence cited below.
## Context
Agents were originally a **pool**: a named kind of worker, scaled to some number of
interchangeable instances. Work went to whichever instance was free.
That model has no place to put the things that turn out to matter. An agent that accumulates
knowledge of a domain cannot keep it, because the next task lands on a different instance. An
agent cannot own a workspace, because there are several of it. It cannot be held to a policy —
warned for a violation, then dismissed — because there is no continuing subject to warn.
Scaling was also solving a problem the mesh does not have. Instances were being multiplied to
get concurrency, when concurrency is a property of how much work one agent may hold at once.
## Considered options
1. **Keep the pool, attach memory to the pool.** Rejected: shared memory across
interchangeable workers is a knowledge base, not an agent's experience, and the mesh
already has one.
2. **Keep the pool, make instances sticky.** Rejected as a pool pretending to be identities —
identity by scheduling accident, lost on any restart.
3. **One agent is one persistent identity, with concurrency as a property of it.** Chosen.
## Decision
An agent is a **singular, named, persistent identity**: a home node, a workspace on that node,
accumulating memory, and a lifecycle — hired, active, draining, retired. Not a pool member.
Concurrency is a property of the agent, not a count of copies: an agent has a cap on how many
sessions it may hold at once.
Lifecycle is explicit and has verbs. An agent is hired onto a node; it may be reassigned while
idle; it is retired by draining first, and forced only deliberately. Retired agents are not
deleted.
Surge capacity is expressed within the model rather than against it: a template agent is a
blueprint, cloned into a real agent with a lifetime when a queue grows, drained and retired
when it expires. A temporary employee is still an employee.
Some agents are **human**. What differs is modality — how the agent acts — not category. A node
itself is an agent of a kind exempt from the hiring lifecycle.
### The node's own session
*Written 2026-08-29. The sentence above is the whole of this and had been left as one line, which
is why it kept being read as a leftover rather than as the design.*
**Every node holds one session of its own, permanently.** It listens on its own queue, anything in
the mesh may prompt it, and it remembers — what it was asked ten minutes ago and what it was asked
last week, across every caller, the way any conversation is remembered by both sides. Its system
prompt is the node's **engram**: the personality that makes one node's answers recognisably its
own.
Nothing about it is request-response. A caller asks, the node answers, the exchange stays.
**It is the same mechanism as a hired agent, and deliberately not the same lifecycle.** That
distinction is the answer to a question asked repeatedly and worth settling here:
| the same | different |
|---|---|
| a persistent session, accumulating memory, a system prompt, a scoped tool list, addressable by message | how it comes into existence, and whether it can stop |
**One implementation, two ways of existing: hired, or inherent to a node.** Building the mechanism
twice is real duplication and the concern was right; collapsing the lifecycles is the other mistake
and it is worse.
**The exemption is not bureaucracy — it removes four states that make no sense.** If a node's own
voice were an ordinary hired agent it could be **retired**, leaving a node nothing can talk to;
**reassigned**, moving one machine's mind onto another; hired **twice**, with no answer to which
replies when the node is addressed; or hired **not at all**, leaving a node with no voice. The
exemption is what makes those unreachable.
[ADR 0001](0001-mesh-brokers-nodes-host-agents-think.md)'s *the two agent rows per node merge* is
the same fact from the other side: **one per node** — not zero, and not two.
### What is scoped, and what is not
**Its tool list is its own and narrower than a session a person drives.** The same scoping any
agent has; a different list.
**There is no authorisation between nodes.** Every node is the operator's own, and a prompt from
one is a prompt from the operator. Asking a node something is asking a colleague, and colleagues do
not present credentials.
Stated once so it is not discovered later: **the mesh boundary is therefore the security
boundary.** Anything inside can reach whatever any node can reach, which is what makes the token
and the overlay the entire perimeter ([ADR 0004](0004-a-node-and-how-it-joins.md),
[ADR 0007](0007-connectivity.md)).
**How a node passes a question on is the node's own choice, not a field in a message.** Asked
something it must ask a third node about, a node may say who is asking or may simply ask — the way
a person relaying a question decides how to phrase it. That follows from the engram, not from a
protocol. What it costs is a machine-readable chain of who ultimately asked; what each node was
asked, and by whom, remains in that node's own record.
**A node thinks about one thing at a time**, being one session. Callers queue, and a long answer
delays the others.
## Consequences
- Memory, workspace and reputation have a subject to belong to. Policy becomes possible: an
agent that violates a rule can be warned, and warned agents can be dismissed.
- The mesh gained a hiring model, and with it the question of who may hire.
- Scaling by adding instances is gone. If one agent is saturated, either its session cap rises
or another agent is hired — both deliberate acts.
- The transition was not free. Lifecycle columns had to reach every query that selects an
agent, and the ones that were missed failed at the moment of hiring rather than at startup.
- This is the decision [ADR 0001](0001-mesh-brokers-nodes-host-agents-think.md) generalises:
one kind of participant, differing only in modality.
## References
- `docs(adr): agents as persistent employees + MINERVA librarian` (#495), 2026-07-12 — the
original record, in the code repository.
- `feat(B4): one persistent employee, N sessions — rename max_instances → max_sessions` (#547)
and `feat(noxflow): B3 — workspace provisioner for agent employee model` (#549), 2026-07-20.
- `feat(noxflow): warn-then-fire agents who merge to main without review` (#209), 2026-06-01 —
policy that presumes a continuing subject, predating the model that provides one.
- Knowledge base: `agents/employee-lifecycle`, `agents/temp-surge`, `agents/workspace-layout`.
- The migration cost: `troubleshooting`/`noxflow-agent-enriched-select-missing-lifecycle-columns` (#546).