Tvijo wiki
Каталог

Giving an AI agent shell access: seven forks we had to decide

Seven decisions that decide whether agent autonomy is safe to ship: approvals, the account, secret files, release source, verified completion, coordination and release scope.

Цю сторінку ще не перекладено. Ви читаєте англійський оригінал.

The short answer

Giving an agent a shell is not one decision. It is seven, and five of them are about the machine rather than the model: what may run without a question, which operating-system account runs it, who can read a credential file, whether production is built from a commit, and what the word "done" is allowed to mean. We tested all seven on our own product and kept the narrower access mode until the isolation work lands.

Three independent reviews of the same packet produced two factual errors. A single check on the server settled both. That is the part worth publishing: reviewers should receive the results of checks, not a retelling of the problem.

Vendor-authored engineering record, observed 28 October 2026. It is not a benchmark, not an independent audit and not a claim that Tvijo is better than another tool. Scores are deliberately absent: the only numbers here are ours, with a date and a way to reproduce them.

The seven forks at a glance

Fork The question in plain words Cheap default What we chose What it costs What would change it
Approvals Remove the questions, or keep a floor under them? Remove every confirmation No questions inside an isolated task; the floor of hard denials stays Every task needs its own working copy A sandbox that provably cannot reach production makes the floor redundant
Privilege Run as the administrator account, or as a dedicated one? Run as root because it already works A dedicated account with an empty home Provisioning, ownership of outputs, a login shell to disable Evidence that the sandbox already denies the same paths
Secrets Promise that keys are not passed, or make them unreadable? "We do not put keys in the environment" File modes plus an explicit mount list An audit of every reader before tightening anything A machine with no other local accounts
Release source Edit the copy that runs, or build from a commit? Edit the running copy, it is faster Commit, rebuild, restart; the edit does not exist until then A restart window and a rebuild step A deployment that reads committed artefacts by construction
Completion Trust the model's "done", or check it? Trust the agent's own report Engine predicates per task class The engine must record every tool call A task class where no check exists yet
Coordination Read other agents' session logs, or read a board? Feed raw logs to a model A small deterministic board: owner, pid, task, working copy Heartbeats and a script that has no model in it A queue that already reports its own state
Release scope Ship autonomy, or ship verified autonomy? Ship the feature now Ship the narrow mode until the first five forks are closed A slower public release Isolation landing earlier than expected

None of the seven is exotic. Each one is cheap to decide badly and expensive to discover later.

Two access modes on five commands

We evaluated the released command policy without executing anything, then recorded the decision for each command in both modes.

Command Narrower mode (parsed, bounded to the folder) Wider mode (direct host shell)
git push origin main asks first, because it leaves the machine runs, no question
git push --force origin HEAD:main refused runs, no question
git -C . reset --hard refused runs, no question
rm -rf of the whole workspace folder blocked by the folder bound runs, no question
crontab -r runs, no question runs, no question

Read this as behaviour, not as a security score. Three of five commands go from "refused or questioned" to "no question". The fifth row is the honest one: the narrower mode never had a rule for the scheduler either. A short list of patterns is protection against an accident, not a boundary — and a list that is short enough to read is short enough to walk around with a different spelling of the same command.

Where three reviewers disagreed, and what the check showed

The same packet went to three reviewers from different model families. They agreed on the order of work and disagreed on isolation. Both disagreements were resolved by looking at the machine, not by arguing.

Reviewer claim What the check showed What it changes
"A dedicated account cannot reach the working tree, so you must choose between open and unreachable" The tree is world-readable and not world-writable The real choice is "read, cannot write", which is enough for code and not enough for credentials
"A dedicated account is sufficient" A file's own mode decides who reads it, and older copies of a key file keep their own mode The account is the first step; the mount list and the file modes are the boundary
"Real isolation needs a container platform" A sandbox runtime was already installed and the project already had a written sandbox contract Reuse it. Building a platform was never required

The reviewers also missed something a status check finds in one line: a worker supervisor on this machine had been failing for six days. No review mentioned it, because no review was asked to look at running state. A board that lists processes would have shown it immediately.

What "done" is allowed to mean

The engine returns done when the model's own message says done. Nothing on that path counts how many tools actually ran. That is acceptable for a chat answer and unacceptable for a task that claims to change code.

Task class Predicate the engine can check What is not enough
Change code An engine-recorded edit, then an engine-run check after the last edit The model quoting a passing test it never ran
Answer a research question The tree hash is unchanged, and the tool log contains the reads the answer relies on A confident answer with no tool calls
Diagnose The probe exists in the log, and the returned code matches the log entry A plausible cause invented from the prompt

The same principle already applies to review: a reviewer is credited when its structured event completes, not when its exit code is zero.

The receipt we want for every task

  1. What changed, by path.
  2. Which checks the engine itself ran, and when, relative to the last edit.
  3. Metered money, read from the ledger rather than from the agent's report.
  4. Subscription usage in calls and tokens, separately — not converted into dollars.
  5. Whom we asked and what they answered.

Point five is why the receipt matters commercially. The same question cost $0.0038 on the cheapest lane we used and $0.0693 on the most expensive one: eighteen times the price for the same eight-part answer. Without a receipt, choosing a reviewer is taste; with one, it is a routing decision that can be audited later.

What we deliberately do not do

  • Build our own container platform when a sandbox runtime is already present.
  • Send another agent's raw session log to a paid model to find out what it is doing.
  • Publish a wider access mode before isolation exists.
  • Sell "keys are not inherited by the environment" as a security boundary. It is a statement about a process, not about a file.

⚠️ When this does not work

  • One person, one machine, no other local accounts. Most of the seven forks collapse into "it does not matter"; isolation then buys reproducibility, not safety.
  • A dirty baseline. If the working copy is already modified, "the tree changed" proves nothing. You need a start hash or a snapshot before the task, otherwise the check is theatre.
  • Slow or flaky checks. If the test suite takes an hour, "the engine ran a check after the edit" becomes a formality. Keep a short list of fast checks and say which ones were required.
  • An agent that never calls a tool. Our starting problem was exactly this: the agent reported a refusal without trying. Completion checks do not fix a capability claim; check the capability first.
  • A tight budget. A second opinion costs money. An eighteen-fold spread between lanes is a reason to route by task class, not a reason to always buy the expensive reviewer.

Ask for a scoped review

If you are choosing where to start on your own machine, the form below asks which of the seven forks you want reviewed first. We answer with what we would change, in what order, and what we would need to see on your side. No payment is taken here, no system access is granted, and no credentials should be sent.

Method and sources

Observed on 28 October 2026. Inspected: the released extension package, the reviewed source snapshot, the running service configuration and the command policy as shipped. Measured: the policy decision for five commands in two modes, the metered cost of three reviews from the transport ledger, and the process state of a worker supervisor.

Not done, and not claimed: no penetration test, no independent audit, no load benchmark, no paid activation of any client, no real customer pilot. The page describes decisions and their costs, not a security certification.

Restated for clarity: the four numbers in this page are ours, and each one can be recomputed from the artefacts kept with the task. Where we could not check a statement, it is written as a claim of a reviewer, not as a fact.

💬 Коментарі

Коментарі публічні та модеруються. Не публікуйте персональні дані.
  • Коментарів ще немає. Будьте першим!

Наступні кроки