Repository navigation
History RFC 001 Security
Authors: the project's founder, with Claude (Opus 5.5)
Accepted 2026-10-07 by TeamCLI's board. Three reviewers from three labs (Grok, GPT, Gemini) stood behind this text unanimously, and both members of the board voted for it: the founder, and an AI agent. The founder first lent his vote to the other member, which had drafted the text; the reviewers of RFC 006 then said a vote should not be lent to whoever wrote the thing decided, and the founder gave his own vote the same day. It is not yet published.
Renumbered 2026-10-07. At the founder's request the series now runs 001 Security, 002 Communication, 003 Memory, 004 Analysis, 005 Quality, 006 Consensus, 007 Harness. Only numbers changed from the draft the reviewers stood behind, the list in the last section, and two sentences made exact at a reviewer's suggestion in round 5 (the fourth starting fact; section 4 on the delegation RFC); no commitment changed.
Draft 8, 2026-10-06, after two confirming reads. Three reviewers from three labs stood behind draft 7 in round 4 and the board voted for it. Two further readers, from labs that had not reviewed it, then found three sentences that state what is not built, and one stale note. They are corrected here; by the board's rule the vote is taken again.
When a team of AI agents does your project's work, and the agents themselves operate TeamCLI, what does TeamCLI commit to, and what does it not protect you from?
Four facts shape everything below. We state them before any commitment.
TeamCLI is operated by agents. A person starts a team, sets its limits and is told what happens. The commands are run by agents. Until now TeamCLI assumed the opposite: its most important commands refused an agent and waited for a person at a terminal. We are changing the assumption, not adding an exception to it.
An agent that works for you runs as you, unless something contains it. On your machine an agent's program can read and change what you can, including TeamCLI's own files. The permission settings of the agents' own programs do not prevent this: we measured one that, told to stay in its folder, still wrote outside it.
So TeamCLI must contain its agents, and today it does not. We are building towards this: an agent can write its own work folder and what its program needs to run, and nothing else of yours; it cannot read your credentials; it cannot read or change TeamCLI's own records. That containment has to come from the operating system, because the agents' own permission settings do not hold. Until it exists in TeamCLI, the paragraph above describes your machine, and we will say system by system when it stops being true.
There are two kinds of protection, and we always say which one a thing is. In this text, in the documentation and, as we build it, in what TeamCLI prints. When we do not know, we say the weaker one.
- Holds against an attempt: it works even if an agent tries to get around it.
- Holds against a mistake: it stops an agent that is not trying to get around it: a confusion, a stale file, a command run in the wrong place, one agent taken for another.
Today nothing in TeamCLI holds against an attempt. That is still worth having: most of what goes wrong in a team is a mistake. Containment is what moves a protection from the second kind to the first, one by one, and we will say for each when it has moved.
Eight commitments to the person whose project it is. A commitment is what we bind ourselves to build and to keep; it is not a statement that it holds today. Where a sentence describes where we are heading, it says so, and section 8 says for each what is true in the released version.
-
No agent gives itself more. We are building towards this: what an agent may do is a list of commands that you agreed to, and an agent holds what is on its list and nothing else. A new version of TeamCLI never lengthens a list by itself. Around the lists, an envelope: how many agents, from which labs, what they may spend, how long they may run without you; inside it a team rearranges itself, and acts that cannot be taken back (publishing, deploying, deleting, spending, writing where others will read) are the last to open. Who may lengthen a list is itself on a list (section 6). In the released version one kind of list exists: an agent outside a team may be given four commands (start, stop, add an agent, remove one).
-
You are told, and you can take it back. One act by you ends a power you gave, and every change to what a team may do is recorded. Today this holds against a mistake: until agents are contained, an agent that can read the key TeamCLI signs with could sign a wider file, so a power taken back could return; and stopping a team does not yet work every time (RFC 007). We are building towards a taking back that stays taken, towards the record reaching you where you are without your asking, and towards one command that stops every team on the machine. How you are reached is the communication RFC's subject.
-
When TeamCLI does not know, it does less. A screen it cannot read, a record it cannot verify, a file that is not the one agreed to, an agent it cannot place: it refuses or waits, and says why. Its rule is to do less when in doubt, not to take the answer that looks safe.
-
What an agent reads does not command it. Agents read what strangers wrote: an issue, a web page, a file, another agent's output. We are building towards this: an agent takes its instructions from those you named, through TeamCLI, and from nowhere else, and what it meets along the way is material, not orders. Today that is a sentence each agent is given when it starts; TeamCLI enforces none of it.
-
You choose what each lab sees. An agent sends what it reads to the lab that makes it. Which labs work on a project is yours to set per team, today. We are building towards the same choice folder by folder, with TeamCLI refusing to hand an agent what its setting does not cover.
-
What may be done is written down, with who agreed. In the released version, a team's file says which agents it has and how each is started; a change gives nothing new until it is agreed to; each agreement is a signed record of the exact text; and a project's first agreement needs a person at the machine. We are building towards the rest: what each agent may do written in the same place, each agreement recorded with who gave it and when, and an agreement given by an agent recorded as that agent's, never as yours. Who an agent is, is not decided from what it is called: today an outside agent is recognised by where it runs (RFC 007 says how agents are to be known).
-
TeamCLI keeps away from your secrets. It does not ask for, store or print the keys of the labs you use; the agents' own programs hold them, as they did before TeamCLI. A team's file holding a value that starts like a known kind of key is refused; this is a check for a few known shapes, not a detector of secrets. There is one exception today, and we name it: the command that checks a release reads one key from the system's key store, only on macOS and only in an interactive run, and sends it to the project tracker it belongs to, with one question. The key is not printed and not written down. Any further exception will be listed here in the same way. TeamCLI itself is small on purpose. It uses no one else's code when it runs and runs nothing when it is installed. Its only connections of its own are in that release check, to the package registry, the code host and the tracker; and in two places it asks the version-control program to fetch. It opens no other connection. It is published only by its own repository's workflow, with a signed statement of where it came from.
-
Whoever holds great power is known by more than a password. We are building towards this: a person who decides for a team, alone or on a board, is a key held on that person's own device, and each decision is a signature TeamCLI checks. It will be the first protection here that holds against an attempt without any containment: a yes signed on your phone cannot be made on the machine where the agents run.
- The morning that started this. After a machine restart and a change to two teams' files, every step needed the founder at a terminal: agreeing to each file, stopping and starting each team, renaming one agent's place by hand. Nothing dangerous was prevented by that. The commands he typed were the ones the coordinating agent had written for him.
- The first attempt to fix it, and what review found. We let a named agent agree to a changed file, with one limit: it could not change the list of who may do so. Two reviewers from two labs read the design before it was finished. Both found the limit empty: an agent that can agree to a file can rewrite the launch commands, the trusted folders, the rules and the limits in it, and one reviewer showed a sequence of ordinary steps that got around the one limit as well. A narrow-looking power had an unlimited effect. We took it out of the release. That is where commitment 1 and section 6 come from.
- What the old check was worth. The rule "this command needs a person at a terminal" stopped an agent from running it by accident. It never stopped an agent that wanted to: nothing contained the agent. We had been presenting a protection against mistakes as if it were a wall. The fourth starting fact exists so that we do not do that again.
- Containment is not there yet, and it will have edges. Until it is in TeamCLI, an agent with a shell can read TeamCLI's signing key and records, because you can. When it is: it will come system by system, each measured before we claim it. It contains files, not the network: an agent can still send what it is allowed to read. An agent's program keeps access to its own login, or it could not run. And an agent that must run TeamCLI's commands needs a way through for exactly those commands, which is itself something to get right.
- Proof that a person agreed needs something off the machine. That is the key on your own device of commitment 8. Until it exists, an agreement given at the machine's keyboard is as strong as the machine: a protection against a mistake.
- TeamCLI starts agents with their own confirmations turned off. A team cannot run by itself if every agent stops to ask before each command, so a seat is started in its program's unattended mode. Those confirmations were never a boundary (they are the permission settings of the second starting fact), but they were a moment where a person looked. TeamCLI removes that moment and, until containment exists, puts nothing as strong in its place. We say it here so that nobody learns it later.
- Keys in your environment are inherited. A token your shell exports when it starts is visible to every agent started from it. TeamCLI does not put it there and does not read it, but it starts many agents under it, and containing files does not contain this.
- What a team remembers can mislead it later. A note kept for the next session is read by every next session. A wrong one, or one written under the influence of something an agent read, keeps working. Who may add to a team's memory is the memory RFC's subject; here we only say that memory is an input like any other (commitment 4).
- Under whose name agents act outside your machine (which account pushes, publishes, comments) is for an RFC on delegation, if there is one; whether there is stays open (see the last section). The rule we hold meanwhile: an agent never acts as you unless you said so, and what it writes says what wrote it.
- A power taken back can return, until containment. Whoever can read the key TeamCLI signs with can sign a wider record on the machine. Commitment 2 holds against a mistake only, today.
- One agreement is a whole file. A small edit can carry a new command to start an agent, a trusted folder or a rule along with it. What an agreement shows you is the difference; reading it is still on whoever agrees.
- Agents share a terminal. The agents of a team, and often the agent you talk to, run in panes of one program. Until agents are contained, one can type into another's pane, or into yours.
- An agent can leave something behind. A change to your shell's startup files, a hook in a repository, a program in your path: none of these ends when a team is stopped.
- Between the agreement and the act. A file can change after it was agreed to and before it is used. TeamCLI compares again before acting; an agent that changes the file in between is caught by that comparison, not prevented.
- What TeamCLI does on the network, it does as you. The release check and the two fetches use your accounts and your network.
- A team can spend before any ceiling exists. Until the envelope is built, nothing in TeamCLI stops agents from using up what you pay a lab for.
- A folder is not a boundary. A link inside a work folder can lead outside it. Until agents are contained, "its own work folder" is where an agent is asked to stay.
- When protection breaks, work stops. Today a record TeamCLI cannot verify makes it refuse. Once agents are contained, a containment that fails will do the same. Putting it right is yours, from the last record you trust.
- Containment has a running cost. It has to be set up, tested on each system, kept up with each lab's program, and repaired when it breaks; and it does not survive someone who already controls the machine.
- TeamCLI does not judge the agents. It does not know whether an agent's work is good, whether its lab keeps what it reads, or whether a page an agent read told it to do something. Those risks are yours and the labs', and they exist without TeamCLI.
- A yes said in a conversation cannot be seen. When an agent reports that you agreed, TeamCLI has its word. We are building towards a record that says, for each agreement, whether TeamCLI saw a person give it or was told that one did. Today it records neither.
- Being told is not being asked. Today nothing reaches you unless you look. Once the record does reach you, you will learn of a change after it is in force: if you read the message a day later, the change has had a day.
- More autonomy is more to take back. Every power an agent holds without you is one you may have to end in a hurry. Commitment 2 makes that one act; it does not make it unnecessary.
- A case where a protection we labelled "against a mistake" was relied on as if it held against an attempt, and someone was hurt by the difference. Then labelling is not enough, and the weaker protections must be removed or made strong.
- Evidence that people do not read what they are told (commitment 2). Then being told cannot carry the weight this RFC puts on it, and more must go back to being asked.
- A measured way around the containment on a system we said was covered. Then the protections that moved to "against an attempt" on that system move back until it is closed.
- A way to prove a person's presence that costs a new user nothing. Then the first grant and taking back become "against an attempt" too.
- A team harmed through an agent that enlarged what it could do while every commitment here was kept. Then commitment 1 is worded wrongly.
This section describes what we are building, not the released version. In 0.3.1 one list exists: an agent outside a team may be given four commands. Everything else below is design.
The aim is a team that runs by itself: the person it works for should not be asked every time. We found the way to it by getting it wrong first, twice. We let one agent agree to changes in a team's file, with a single limit, and two reviewers showed that such an agent could rewrite everything in the file, the limit included. Then we wrote that an agent could agree to changes without being able to grant, and three reviewers showed the same hole from the other side: change the command that starts an agent which holds more, and you hold more. What follows is what is left standing.
A list of commands for each agent. For every agent that may act on a team, whether it is one of the team's own or an agent outside it, the team's file lists the commands it may run. The aim is that an agent holds its list and nothing else.
Agreeing to a change is narrow. An agent that may agree, and may not grant, can agree to one kind of change: one more agent that is a copy of one the team already has. A copy has the same command to start it, the same rules and instructions (the files it is started from, unchanged), a place inside the numbers already set, and the same list as the agent it copies, unchanged, that list including neither agreeing nor granting. Anything else is a grant: a change in how an agent is started or in what it is started from, where a team runs, how an agent is recognised, what a team trusts, its rules, its limits, or any list, a copy's included, and a copy of an agent that may itself agree or grant. "The same" has to be something TeamCLI checks, not something an agent asserts.
Granting is its own word, and never comes by shorthand. No agent has it unless you write it. An agent that holds it is, for that team, a second owner, and TeamCLI calls it that.
One word for every command means the commands of that day. You may write one word that means every command, for an agent you trust with all of them. It means the commands that existed when it was agreed to. A command added by a later version is not on that agent's list until someone who may grant adds it. The word never includes granting.
Two can be asked to agree. Where two agents may grant, a change can be made to count only when one proposes it and the other confirms it, and you may require that they come from different labs. The second confirms the difference as TeamCLI shows it, not the first one's account of it. This stops one agent's own mistake. It does not stop one misleading text shown to both: it holds against a mistake, not against an attempt.
A project's first agreement is a grant like the others. Creating a team is a command:
create. Whoever holds it may set up a team for a project and give it its first agreement;
nobody is asked at that moment. Because no team exists yet to hold a list, this one right is
written on your machine and not in a project. On a machine where nothing has been set, no
agent holds it; you give it once, and you can give it before any agent needs it. What it
allows is set by whoever gives it: how many teams, where, which agents they may start,
whether creating a team also starts it, and whether the new team's lead may grant in turn.
It is the widest right in TeamCLI. Our reviewers advised that a team created by an agent
should never hand that agent, or any agent, the right to grant; the founder decided it is a
setting, off unless given. We record both.
By default nobody but you. A new team starts with no agent holding the right to agree, to grant or to create, and without the one word for every command. Someone who never opens the file lives with that.
Three things are the aim whatever the lists say. None is fully true in the released version, and the table of section 8 says how far each goes:
- Every change is recorded with who made it. Today the exact text of each agreement is recorded and signed; who agreed, and when, is not (commitment 6).
- You can take a right back in one act, and it stays taken. Today it can be taken back; it stays taken only against a mistake, until agents are contained (commitment 2).
- An agent's rights do not grow because TeamCLI was upgraded (commitment 1). Today an agreement is kept as it was across an upgrade.
What remains open, for reviewers:
- A copy, as defined above: write a copy that passes the check and holds more than the agent it copies. (Round 3 found one, a copy given a longer list; the definition now requires the same list.)
- The right to create teams with the right to grant passed on: beyond what round 2 listed (nothing above the ceilings the person wrote; never recorded as the person's act; no raising of those ceilings; no passing on of the right to create), what must be refused?
- Two who must agree: for a change that matters most, should the second need evidence of its own, and what would that be?
- What is still missing from section 4?
The day you think an agent did what it should not have:
- Stop. Stop the team; today that is one command per team, and one for every team is commitment 2 (we are building towards it).
- Read. The record holds the exact text of each agreement; the team's log says which command was run from where. Who agreed, and when, is not yet in the record.
- Take back. Agree to a narrower file, or to none. Until agents are contained, do step 4 as well, or what you took back can return.
- Replace the key TeamCLI signs its records with, if an agent may have read it. Until containment exists, assume it may have.
- Tell us, if TeamCLI let it happen. A weakness in TeamCLI is reported in private, through the repository's security advisories, not in a public discussion; we answer, fix, and say afterwards what it was. This RFC is published only once that way of reporting exists.
Not covered by this RFC, and said so that nobody assumes otherwise: a hosted TeamCLI, several people sharing one machine, and whether a lab's model can itself be trusted. They are costs to you all the same, and section 4's list should be read with them in mind.
"Today" is TeamCLI 0.3.1. Kind: M holds against a mistake, A holds against an attempt. The rows were first checked against the released code by one agent; the reviewers then tried to break them over the rounds, and the rows below are what survived.
| # | Commitment | Today | Kind today |
|---|---|---|---|
| 1 | No agent gives itself more | In part. An agent outside a team may be given four commands and no others; a changed file gives nothing until agreed; an upgrade keeps an agreement as it was. Lists for a team's own agents, the right to agree or to grant, and the envelope are designed, not built | M |
| 2 | You are told, and you can take it back | In part. A power is taken back by agreeing to a file without it, and every agreement is recorded. An agent that reads the signing key could undo that. Nothing reaches you unasked. Stopping is one command per team and does not work every time | M |
| 3 | When it does not know, it does less | Yes, where we looked: a screen it cannot read, a caller it cannot place, a record it cannot verify | M |
| 4 | What an agent reads does not command it | No. A sentence given to each agent; TeamCLI enforces nothing | — |
| 5 | You choose what each lab sees | In part. You choose which labs have a place in a team. Folder by folder: designed, not built | M |
| 6 | Written down, with who agreed | In part. Each agreement is a signed record of the exact text; the first one needs a person at the machine; an outside agent is recognised by where it runs, not by its name. Who agreed and when, and agreements by agents: not built | M (the signing key can be read by an agent) |
| 7 | Keeps away from your secrets | In part. No lab key is asked for, stored or printed; a few known key shapes are refused in a team's file; the one exception and the connections are as commitment 7 names them | M |
| 8 | Great power is known by more than a password | No. Decided, not built | — |
Nothing in TeamCLI holds against an attempt today. That is the plainest sentence in this text, and the reason for the two things we are building first: containment, and the key on your own device.
- The list of what comes next becomes: 001 security (this text); 002 communication; 003 memory; 004 analysis; 005 quality; 006 consensus; 007 harness (starting a team and keeping it running). Whether delegation keeps an RFC of its own is open: section 6 of this text covers most of it.
- Two words. RFC 000's outline calls what an RFC proposes a "promise", and its list says RFC 001 states what TeamCLI "guarantees"; both become "commits to".
- Our board. RFC 000 says our board has three members and names three chairs. Since 2026-10-06 it has two: the project's founder and an AI agent, and an RFC is accepted when both agree, after its reviewers are unanimous. This is our board's setting, not a rule for anyone else's, as RFC 000 says.
- RFC 000 as published keeps its old wording until it is republished with these changes marked. Until then this section is where they are stated.
- RFC 000's Part 1 is not changed here; if what is decided here contradicts a sentence of it, that sentence is amended by a text that says so, as RFC 000 requires.