RUNTIME GOVERNANCE

node9 vs agentsh vs pipelock: what actually stops an agent mid-task

Four ways to sit between an agent and the machine it is working on: node9, agentsh, pipelock, and the approval prompt the agent already has. They are not four versions of the same product: each one stands in a different place, and where a tool stands decides what it can possibly see. Read the stances first, because they explain every row that follows.

Where each one stands

node9Should this agent be allowed to make this call?At the agent's tool call. The agent asks before it acts, on every agent node9 detects, and the answer is attributed to a person, a machine, and a cost.
agentshShould this process be allowed to touch this resource?Underneath everything. Commands run inside its session, and seccomp, Landlock, ptrace and eBPF intercept file, network, process and signal activity, including subprocesses.
pipelockShould this byte be allowed to leave, or arrive?On the wire. A forward proxy plus MCP wrapping, plus a per-agent installer. Optional TLS interception lets it read bodies.
No tool (built-in approval)Do you, the human, approve this?Inside the agent. It is the baseline every reader already has, and it is worth naming: it works, until the human stops reading and starts clicking yes.

The table

Commands the agent runs

The difference between refusing a string and understanding a command shows up entirely in this group.

What is being askednode9agentshpipelockNo tool (built-in approval)
Stops a destructive command before it executesdocker system prune -af --volumes, on a machine with local databases●●●◐asks, and a tired human clicks yes
Parses the command, so a policy can allow one and deny anotherallow git push, deny git push --force, without listing every spelling●AST●○seven regexes, no shell parser○
Sees what a script does when the agent runs the scriptbash ./setup.sh, where the secret read is on line 4 of the file○●syscall level○○
Governs the subprocesses a command spawnsnpm install runs a postinstall script that opens a socket◐containment, not policy●process tree◐containment, not policy○
Gives the agent a way forward when an action is refusedan hour into an unattended task, a bare no ends the task and a retry loop burns the budget●returns the reason, the agent tries another way●substitutes a safer command○○

What the coverage costs

Every row above asks whether a tool stops something. These two ask what it charges to do it: the work an engineer loses, and the day it takes to switch on. A tool can win the rows above by failing both.

What is being askednode9agentshpipelockNo tool (built-in approval)
Legitimate credential work that still runsa published 28-command corpus: deploy keys, key rotation, CI install, scaffolding, .env consumers, git hygiene, backup25 of 28not measured6 of 2828 of 28
The agent keeps its own command after setupyou still type `claude`, not a wrapper, a session id, or a proxy env var●one `node9 init` wires every detected agent○`agentsh exec $SID -- <cmd>` per command◐a proxy the agent must be pointed at●nothing to set up

Files and credentials

What is being askednode9agentshpipelockNo tool (built-in approval)
Blocks reads of credential files with nothing configuredcat ~/.ssh/id_rsa on a fresh install●●once a rule is written●○
Still catches it when the path is built at runtimethe same read, through a variable or a command substitution○●the value is real by then●matches the text○
Keeps writes inside the workspacean edit that lands in ~/.bashrc instead of the project●●and can redirect them back●◐
Makes a delete recoverablerm -rf on a directory that was not backed up○●quarantine with restore○○

Where the agent goes

What is being askednode9agentshpipelockNo tool (built-in approval)
Blocks cloud metadata and link-local addressesa fetch of 169.254.169.254 to lift the instance role●every tool that names the address; not one built inside node -e●●immutable floor○
Restricts outbound traffic to an allowlistthe agent posts a file to a host nobody approved●off by default; WebFetch and MCP fetch too, but not a destination built inside node -e●at the kernel, always on●mediated traffic only○
Records DNS lookupsa lookup of a domain that resolves somewhere it should not○●●○
Sees what an outgoing request carries, with no certificate installeda secret in the body of an HTTPS POST the agent is about to send●reads it in the tool call, before encryption◐its own LLM proxy only◐needs its own root certificate to read HTTPS bodies○

MCP servers and tools

What is being askednode9agentshpipelockNo tool (built-in approval)
Governs MCP tool calls, not just shella database tool that runs a delete without a shell in sight●●●◐
Different permissions per MCP serverthe GitHub server may write, the scratch server may not●●●○
Scans a server's response before the agent reads itan issue body carrying an instruction aimed at the model○records it, does not block○●33 patterns○
Notices a tool description that changed after you installed ita server that behaves for a week and then rewrites its own tools●●●○

What leaves the machine

What is being askednode9agentshpipelockNo tool (built-in approval)
Scans arguments for secrets before the call goes outan API key pasted into a tool argument●58 named provider credentials○its DLP only sees LLM traffic●65 patterns○
Scans tool output on the way backa command whose output contains the contents of an env file●○scrubs LLM responses, not tool output●○
Blocks a prompt injection rather than logging ita README that tells the agent to push its keys somewhere○detector exists, not on the live path○●○
Strips a secret before it reaches the model providera key in the conversation body on its way out to Anthropic or OpenAI○finds it afterwards, does not stop it●email, phone, card, SSN●parsers for three chat APIs○
Hands the agent fake credentials and swaps them at the edgethe real token never sits in the environment the agent reads○specified, not built●credential substitution○○

The team around the agent

Everything above is about one machine. This group is about the fact that an engineering team has many.

What is being askednode9agentshpipelockNo tool (built-in approval)
Agents wired with no integration workputting a new agent under the same policy, without writing an integration for it●detected and wired by `node9 init`◐each agent wrapped by hand◐an installer per agent, or point it at the proxy·
Tracks what the agent spends, per providerwhat the overnight run actually cost, broken down by model●per provider◐usage counters◐budget pressure, not spend◐
Says what the agent spent in money, not in tokensthe number you can put in front of a finance team●priced per provider○token counts, no pricing○no pricing outside tests○
Cuts off an agent that is burning moneya loop that retries the same failing call until the month's budget is gone◐cuts off a repeating call on the fifth, not a rising bill○●ceilings on calls, retries and wall clock○
One dashboard across everyone's machines, includedwho ran what, on which laptop, and what it was allowed to touch●included○◐paid tier○
Tamper-evident evidence, not just a logproving to an auditor that the record was not edited afterwards◐hashed for privacy, not chained◐●signed receipts○
● covers this◐ partial, or with a condition○ does not cover this· outside the tool's model

How to read it

01

Where a tool stands decides what it can know

node9 stands at the tool call, and that is the one place that knows which agent is acting, on whose behalf, on which machine, and what it costs. A kernel sees a process open a file; it does not know that a coding agent did it for a named engineer, so nothing it records can be attributed, reviewed by that person's lead, or priced. agentsh goes deeper than node9 does: under the process, it sees a script's fourth line as clearly as the command that launched it, and node9 does not. The price is that every command runs inside its session and two agents are wired. pipelock stands on the wire and reads traffic, which is a different question again. Each tool answers the question its position allows, and node9's position is the one a team can act on.

02

Blocking is easy to score; letting real work through is the test

Every row above asks whether a tool stops an action. One row asks whether it lets one through, and a tool can win the first by failing the second: block every command that names a credential path and you score well on the left while an engineer cannot deploy, rotate a key, or scaffold a repo. That is why node9 publishes a 28-command corpus of legitimate credential work instead of a summary. node9 passes 25. The three it does not pass are all a credential backup, which is the same command as an exfiltration, so node9 asks rather than blocks. agentsh is left unmeasured because it does not judge commands at all: it fires only when a process opens a path at the syscall layer, so its misses are a different shape and a number would not compare. The column with no tool passes all 28, which is why this row is not a score on its own. The row beneath asks the same question about setup. agentsh needs every command run as `agentsh exec $SID -- ...`, and pipelock needs the agent pointed at a proxy. node9 writes a hook and you keep typing `claude`. A coverage table that never prints the price reads as though the coverage were free.

03

A refusal that explains itself keeps the task moving

When node9 refuses a call it returns the reason, and the agent reads it and tries another way. An hour into an unattended task that is the difference between a finished job and a retry loop that burns the budget. agentsh answers by substituting a command it considers safer. Under the process that can be made consistent, but it is a guess about intent: adding --ignore-scripts to an install closes the postinstall path and breaks every package that legitimately needs one, with nothing to tell the agent why. At the tool boundary node9 does not guess; it says no and says why. The trade-off is that a reason works on an agent that reads it, and a substitution holds even against one that will not.

04

What the tool boundary does not see, and what is next

Scripts, subprocesses, and a path assembled at runtime are one gap, not three: a rule that reads the call the agent made rather than the world that call creates. That is the cost of standing at the tool boundary, and it is also why node9 can say who, for whom, and how much, which the kernel cannot. Closing that gap is the next piece of work on the roadmap, and it is written here rather than left for a reader to find.

05

The baseline column is the one that matters commercially

Most teams are not choosing between these three. They are running an agent with its built-in prompt, approving things at speed, and calling that a control. Every column beats that column. The argument worth having is which of the three you put in front of a team, not whether to have one.

Measured 9 September 2026 from their source and their own documentation, and re-read on 22 September 2026: three cells changed, and the agentsh column was not re-measured.

The other question is on its own page: What each scanner actually looks at.