papa-hq reads 01 research -> 03 decision -> 02 design. The order is a scar, not a choice: 02-DESIGN existed from its initial commit, and when adr/ was finally promoted on 2026-07-13 it took the next free number rather than its place in the sequence. By then design was too settled to renumber. hal-hq was three commits old, so it is not. adr/ becomes 02-DECISIONS and 02-DESIGN becomes 03-DESIGN, and following the folder numbers now walks the process in the order it happens: research produces a decision, the decision authorises a design. 00-GENESIS becomes 00-META, matching papa's rename from the same restructure. Every path reference rewritten across documents, frontmatter, playbooks and skills. All links resolve; all 58 frontmatter blocks parse and their path fields still point at files that exist.
75 lines
3.7 KiB
Markdown
75 lines
3.7 KiB
Markdown
---
|
|
status: accepted
|
|
date: 2026-07-12
|
|
deciders: jochen
|
|
reconstructed: true
|
|
---
|
|
|
|
# 12. 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.
|
|
|
|
## 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 0015](0015-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).
|