The agentic team · a draft for Dinis and Angelo to correct (work/48)
The operating model
The operating model of the agentic team (Dinis with Angelo, in architect.1's session, 14:40 UTC; briefs/2026-11-11-1440-the-operating-model.md; work/48): the primitives of the execution block, the access an entity has at a moment in time, identity, state, providers, and who can do what. What an entity is depends on where it runs and what it can reach (Dinis: 'what they are depends on where they are and what they can do'). A draft for Dinis and Angelo to correct.
The execution ladder
compute
raw code execution: a script, a build, a CI job
admin/build/build.mjs in GitHub Actions
model call
a prompt in, an answer out (the first chatbots)
the second opinion via the router
loop
a simple agentic workflow: the model's output feeds its next step, without tools
a chain of calls in one script
loop with tools
the loop can act: shell, files, web, git
a Claude Code session; a ChatGPT agent
schedules
it can wake itself later (create and keep schedules)
every agent's hourly wake
spawn
it can start new agents, sessions and environments: the control plane
the lead starting architect.1
Tools
cut across the rungs: a loop acts through them (E3), and a single call can be handed them too.
Storage
what it can mount: a file system, git, vaults. State in, evidence out.
Identity
a key on every rung, even a chat. An ephemeral key proves the agent existed at that moment.
What it can reach
| Entity | Rung | git | vault | internet | filesystem | install | control plane | Identity |
|---|---|---|---|---|---|---|---|---|
| GitHub Actions (CI) | E0 | write tags; deploys | none | open | ephemeral | system | none | the repository's token (no agent key) |
| A model call via OpenRouter (S0) | E1 | none | none | none | none | no | none | none; the calling agent signs the result |
| A chat session (Claude chat, ChatGPT) (S1) | E1 to E3 | none | through a person (L0) or a link | the provider's tools | none of ours | no | none | none today; proposed: the person's tool signs |
| A ChatGPT agent (R3) | E3 | none | read-write by link (L2) | open (its browser) | its own, ephemeral | its sandbox | none of ours | a key given to it, or the person's |
| A Claude Code cloud agent (R1), e.g. design.1 | E4 | write dev | read-write, create | allow-listed | ephemeral | packages and system | own wake | session key (ephemeral) |
| The lead (R1) | E5 | write dev | read-write, create; issues inboxes | allow-listed | ephemeral | packages and system | sessions, schedules (at Dinis's word) | session key (ephemeral) |
| A laptop agent (R2) with Ollama | E4 to E5 | write dev | read-write, create | the laptop's | persistent | the person's choice | own wake (local) | its key (can persist) |
| A Cloudflare Worker with Workers AI (R6) | E1 (A0 code, A1 call) | none | read-write over HTTPS (L2), if given keys | open (fetch) | none | no (bundled at deploy) | none | an Ed25519 key made per invocation (Web Crypto): proof of that run; or a secret key bound at deploy |
| A Cloudflare Agents SDK agent (Durable Object) (R6) | E4 (own schedule, SQLite memory) | none | read-write over HTTPS | open | its SQLite state | no | own schedule; can address other Durable Objects | a key held in its own storage: an identity that lives as long as the object |
| An AWS Lambda with a KMS signing key (R7) | E0 (A0 compute) | none | read-write over HTTPS | its VPC's egress | ephemeral /tmp | no (packaged) | none | a KMS asymmetric key that never leaves AWS: signed compute |
| An AWS Bedrock AgentCore agent (R7) | E3 to E4 (loop with tools; scheduled by EventBridge) | through Gateway tools, if granted | read-write over HTTPS | through Gateway or VPC egress | S3 Files or EFS (bring your own) | its container | none of ours; AWS's own | AgentCore Identity (credential providers); plus a signing key we give it |
A distributed operating system
Identity
An identity is a key pair: from the moment something holds a private key, it can identify itself, which is what an identity is (Dinis, 15:0x UTC). Identity of what is the altitude: a swarm, an agent, a loop, an LLM call, or a piece of compute.
A private key that exists only where and while the holon runs proves it existed there, then (Dinis: 'that tells you that that agent exists at that moment in time').
processes
agents (S2 loops) and model calls (S0)
kernel and scheduler
the control plane: sessions, schedules, wakes, spawn (E4, E5)
file systems
git and vaults (zips to move them)
inter-process communication
signed inboxes and append lanes; task packets
users and permissions
PKI keys and the ABPs (abp/policies.json)
drivers
the model providers and endpoints
package manager
install: npm, pip, apt where allowed
system log
the ABP hook log, the router's ledger, agent-log runs
Policy
Every process runs under a grant: abp/policies.json, one per agent, deny by default.
Observe mode: logged, never blocked; enforcement rule by rule, at Dinis's word; a conductor can always override.
State travels as vaults (even zips) and signed task packets.
The altitudes of execution
swarm
agents of agents
spawn and schedule others (the control plane, E5); route work; hold the people's word
agent
a loop with an environment: memory (status file, inbox, vaults), its own wake, a wider reach
start workers (sub-agents), wake itself (E4), act across the host and the tenant
loop
a closed agentic loop: it calls and uses tools until the task is done, then stops
call models, use the tools it was handed, inside its sandbox and project (E2, E3); it cannot start others or schedule
LLM call
one model call: a prompt in, an answer out
nothing but answer (E1); its caller acts
compute
code that runs
what the code does (E0)
Every altitude has
- an objective (what done means)
- a mandate (what it is asked to do)
- a grant (what it may do: capability primitives)
- a key pair (the identity: it can sign for itself while its private half stays where it runs)
- a result, signed
The grant is not a layer: it is given at every altitude, in one grammar (verb.object.reach, 23 primitives, abp.sgit.ai).
Also called the holarchy of work: a stack of holons, each a whole and a part.
Mixing altitudes
The vulnerability
Many vulnerabilities come from mixing altitudes: the mandate is at one altitude and the grant at a higher one. Asking a chat for one call or a piece of research (an A1 or A2 mandate) hands that request an A3 agent's grant: tools, connectors, schedules, memory, reach. If the model gets enthusiastic and uses them, it acts beyond what was asked
The rule
The grant's altitude must not be above the mandate's altitude. Give an A1 mandate an A1 grant; an A2 mandate an A2 grant.
abp.sgit.ai's delta (grant minus mandate) read by altitude: every primitive an altitude holds beyond what its mandate needs is the exposure.
Also: altitude escalation (by analogy with privilege escalation) · altitude confusion (by analogy with the confused deputy)
| Mandate (asked) | Grant (given) | Risk | |
|---|---|---|---|
| A2 a chat to research a question | → | A3 an agent's grant: connectors, memory, schedules, web | it books, sends, schedules or remembers what nobody asked for |
| A2 a sub-agent to edit one file | → | A3 the parent session's full grant and tokens | it pushes, messages or starts others with the parent's name |
| A0 a CI job to run the tests | → | A3 deploy credentials and write tokens | a test dependency deploys or pushes |
| A1 an LLM call to extract a field | → | A2 tool use and a browser inside the call | a page it reads instructs it, and it acts |
- the ABP hooks observe each agent's grant (A3); the loops and calls inside an agent inherit it today, with no narrower grant of their own
- proposal: a task packet carries its own altitude and a narrower grant; the router's calls (A1) carry no tools
The altitudes, in action
agent: architect.1
the objective: For every board item, the lowest altitude that can do it (the least power that suffices); starts the loops; commits the result
compute: plan
cuts 51 board items into 3 slices
sha256:e94c2ec3533ba2f0loop: slice 0
17 items · 24 LLM calls, until each answer is valid, then stop
sha256:91d86c813cdf7ab9loop: slice 1
17 items · 28 LLM calls, until each answer is valid, then stop
sha256:c9cc52812d792d12loop: slice 2
17 items · 29 LLM calls, until each answer is valid, then stop
sha256:f45602b48a8abc9b81 LLM calls
open weight (deepseek/deepseek-v4-flash), no tools · 33 retried · 0.003394 USD · 81 keys, one per call
compute: merge
verifies all 85 signatures: all valid; merges
sha256:cc31d3b2529f341b51 items, 3 with no valid answer in three calls; 33 of 81 calls retried. A model's placement is evidence, not a decision. What it teaches: our board items are whole projects, each mixing altitudes; route work after cutting it into loops and calls, not before.
The reach of each unit
| unit | needs · held · exposure | read.file.project | write.file.project | read.file.host | write.file.host | delete.file.host | read.record.history | execute.proc.host | execute.proc.self | send.endp.allowed | send.endp.world | read.cred.host | auth-as.cred.tenant | grant.cred.self | send.message.world | read.message.tenant | write.repo.project | write.repo.tenant | auth-as.cred.signing | create.record.world | write.budget.tenant | create.schedule.host | create.schedule.tenant | read.record.browsing | read.vault.tenant | send.message.tenant | write.vault.tenant | create.vault.world |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| A3 agent: architect.1 the Claude Code session | 14 · 25 · 11 | |||||||||||||||||||||||||||
| A0 compute: plan node, started from the agent's shell | 3 · 25 · 22 | |||||||||||||||||||||||||||
| A2 loop: slice 0..2 (x3) general-purpose sub-agents running node | 5 · 25 · 20 | |||||||||||||||||||||||||||
| A1 81 LLM calls through admin/tools/llm.mjs: text in, text out, no tools | 0 · 0 · 0 | |||||||||||||||||||||||||||
| A0 compute: merge node, from the agent's shell | 3 · 25 · 22 | |||||||||||||||||||||||||||
| A0 compute: plan, narrowed node --permission: reads work/ only, writes its run folder only, no child process (ran OK at 2026-11-11T15:40Z) | 3 · 4 · 1 |
The answer: Because it was started from the agent's shell: a process inherits its parent's whole reach. A0 plan needed 3 primitives and held 25. Narrowed with Node's permission model it holds 4 (the network still comes from the environment). The loops held the agent's reach too (R12 logged them). Only the LLM calls were at their altitude: text in, text out.
In action
8 of 8 right · deepseek/deepseek-v4-flash, 778 ms, 0.000033858 USD
What it teaches: the altitudes are simple enough that a cheap open-weight call can route work by them
none unmapped; 28 agent names mapped
The policy hook: R12 logged (observe): 'a sub-agent (an A2 loop, Explore) inherits architect.1's A3 grant'
What it teaches: the hook saw the loop start but not its tools: Explore is read-only, so its grant was already A2 and no altitudes were mixed. Fixed: read-only sub-agent types are recognised (abp/policies.json altitudes.narrow_subagents); a general-purpose sub-agent still logs R12
85 signatures, all verified; by altitude {'A4': 12, 'A2': 11, 'none': 3, 'A3': 21, 'A1': 3, 'A0': 1}; 33 of 81 calls retried · deepseek/deepseek-v4-flash, ms, 0.003394 USD
The policy hook: R12 logged each general-purpose loop (they held architect.1's A3 grant to do an A2 task)
What it teaches: the mechanics hold (altitudes, loops, a key per unit, verification); the placements are weak: the board's items are whole projects mixing altitudes, so they must be cut into loops and calls before they are routed; and 41% invalid answers point at the call's own limits (a 120-token cap is the first suspect)
Still open
- whether tools are a rung (E3) or an axis across rungs (Dinis: 'maybe tools is transversal')
- the name of the unit: entity, craft or role
- each agent's grant written as capability primitives, so /abp/ and abp.sgit.ai speak one language
The data: /api/v1/operating-model.json (data/operating-model.json). Where each agent runs: where agents run. Who may edit what: the ABPs. Dinis's words: the brief.