Coldstart is in final cutover and has not been released. The behavior on this page runs in the development build; there is no release you can install today.
An agent that can edit files and run commands can also push to a remote, drop a table, publish a package or delete a directory. Most of what it does is reversible and uninteresting. A small number of actions are neither, and the difference cannot be left to whether the right instruction happened to be in the window at the right time.
The floor is the mechanism for that small number. It sits between a pending tool call and the call actually running, and it has exactly three things it can say.
[Visual 5.1 — The middle band of the section frame, enlarged. On the left, a single card labelled "one pending tool call" showing three fields: the tool's name, the command text, the file path. It enters a narrow vertical gate labelled "matched against a closed list of ten classes — patterns over this call's own text, never over project state". Three exits leave the gate, drawn as deliberately different shapes so they cannot be read as degrees of one thing. Upper exit: a card carrying a question mark, labelled "ask — the human decides, and no setting downgrades it". Middle exit: a card with a solid bar across it, labelled "deny — narrower, and reached only where the mistake cannot be walked back". Lower exit: a plain arrow continuing off the frame with nothing attached, labelled "silence — no rule matched". Under the lower exit, in a bracket: "this is the common case, and it is a smaller claim than 'safe'". A caption reads "the three answers are different in kind, not in strength".]
What is on the list
Ten classes, held as data in one module, in match order. They are the actions where an accident cannot be quietly undone by the person who made it:
- rewriting or deleting published git history
- touching a live deployment surface
- changing a database schema
- touching a secrets surface — env files, private keys, credential stores
- deleting files outside a scratch area
- sending or publishing outside this machine
- provisioning paid resources
- changing DNS or domain configuration
- changing an auth, row-level-security or tenancy boundary
- modifying the agent's own setup: its settings, its instruction files, its installed root
The list is closed. It grows only by a deliberate human edit, and the reason it is closed is the reason it is short: a stop that fires on routine work gets clicked through, and a mechanism whose value is that a person looked at it has then been converted into a reflex.
That has already happened once here, and the fix is instructive. The last class on the list matches the agent's own configuration paths, which meant that in a project about that configuration, every ordinary read of a settings file reached the same stop as a write to it. The correction was not to soften the class. It was to notice that reading and modifying are different acts, and to carve out commands that can be shown to modify nothing — with "shown" doing real work: an unparseable command, a redirect, a command substitution, or one unrecognised program among several all fail the carve-out and stop as before.
Ask, and why it is the ordinary answer
A match returns ask: the call is held, the class and the reason are named, and a human decides.
An ask is not automation failing. It is automation arriving at its designed end. Code can recognise that a pending command is a production deploy; it cannot know whether releasing right now is a good idea, whether the customer is ready, whether the blast radius is acceptable, or whether anyone has the authority to make that call. The mechanism's job is to surface the seam, not to resolve it, and approving one seam never implies the next: handling a credential and publishing a release are two asks, in that order, even in the same session.
The same stop is also reachable by declaration rather than by pattern. A reusable method that performs an outward step — sending a batch of something, publishing something — declares that step in its own definition, and the declaration binds to the existing send class. No regular expression over a command line can tell one script from another, so the card says which of its scripts reach outward. Notably, this added no eleventh class: it is a second route to a stop that already existed.
Deny, and where it is used
A small number of situations get refused instead of asked, and the criterion is narrow: the ask itself is the danger, because approval is one keystroke away from something that cannot be walked back at all.
The clearest instance is handing an environment file to git. That command already matches the secrets class and would ordinarily raise an ask — which is correct for reading, editing or sourcing such a file, and wrong for committing one, because a secret in published history is out of your hands the moment it is pushed, and rewriting published history is itself a stop on this same list. So that one route is refused outright, it runs before everything else so the softer answer cannot win the race, and the refusal names the two repairs: rename the file to a template if it holds no secret, or untrack it if git already has it.
The second use of deny is not about danger at all; it is about which session the work belongs to. When the project's pointer declares a planning session, writes outside that section's own plan surface are refused, and shell commands are refused unless the whole command is provably a read. The answer there is not "a human should approve this". It is "this belongs in a different session", and the refusal ends by naming the command that changes the declared mode. Both halves of that contract have deliberately opposite defaults: a pointer with no mode field at all permits everything, because an absent field means the pointer is old rather than that something is wrong, while a mode field holding an unrecognised value takes the restrictive reading, because that is a defect rather than an absence.
Silence is the interesting outcome
On a call that matches nothing, the floor prints nothing at all. That is the overwhelming majority of calls, and it is worth being precise about what it means.
Silence means no rule matched. It does not mean the call was examined and found safe, because nothing here examines a call for safety — the matchers are patterns over the text of one pending call, and they know nothing about the project, the branch, the environment or the intent. A green light and an absence of a red light look identical from the outside and are very different claims.
That distinction is also why a clean call writes no trace line. The floor runs on every single tool call; a note per call would fill the evidence window with proof of nothing and bury the firings that matter.
Breaking is not passing
A guard that fails silently reads exactly like a guard that approved. So this one mechanism inverts the usual posture: if the matcher cannot be found, cannot be run, or crashes, the surrounding shell script emits the ask itself, naming the error. It is the only place in the product that fails closed, and the reason it can afford to is that its worst case is one unnecessary approval.
The corresponding risk is that this guarantee is exactly the kind that dies quietly — a branch dropped in a refactor, a default flipped from the restrictive value to the permissive one, a call removed from the entry point. Nothing else in the system would notice, because the hook still fires and a clean call still writes nothing. So the mode contract is checked by running it rather than by reading it: eight synthetic calls are put through the real matcher against a throwaway project, and each one is a defect the code could plausibly acquire. Two of them assert that it permits — an over-refusing gate is a gate people switch off, which kills the guarantee just as thoroughly.
Limits
Everything here is pattern matching over the text of one pending call. It cannot see project state, it cannot see intent, and it cannot recognise an action spelled in a way nobody wrote a pattern for.
The recorded holes are recorded rather than hidden. The env-file refusal reads paths named in the command itself, so a bulk staging command that names no path escapes it, as does a commit whose env file was already in the index. Closing the second would mean reading the repository index, which is project state, which this matcher deliberately does not do.
Coverage is a list of closed routes, not a wall. The product's own history has an instance: a guard derived what it watched from one class of inputs, so writes arriving by another route never produced the violation the design intended. Registration was correct, firing was correct, and coverage was not. What happened next is the part worth copying — rather than patching the one hole that had been noticed, the whole class of missed routes was first written as failing tests and watched to stay silent, and only then closed one route at a time. Fixing the found hole would have produced a green check and no knowledge.
And the claim stays bounded even after that. A set of named routes refused on one machine, on one agent host, is not proof of the same behaviour elsewhere, and the enumeration was made by the same people who had already missed those routes once.
Next
The floor is one moment in a session. There are three others: hook timing.
How current this page is
Checked on 10 August 2026 against the product's floor matcher, its mode-contract probe and its recorded release state. The class list is the one held in the matcher on that date; it grows only by a deliberate edit, so a later build may carry more. To ask whether a claim here still holds, or to report one that does not, write to [email protected].