Terminal and platforms5 of 10
The approval card
On this page
When she wants to run something on your machine, the turn stops and a card opens. In the interactive terminal it takes one keypress, with no Enter.
▄▄▄▄▄▄▄▄▄▄▄▄
█ NEEDS YOU I'd like to run something on your machine
█
█ npm install left-pad
█ y go ahead a always allow npm t always allow just this line n no
█ ? what it touches
The rail names the keys that card offers, never a fixed list.
The keys it accepts
| Key | What it does |
|---|---|
y | run it, once, right now, in this turn |
n | refuse. She is told, and says so plainly instead of pretending |
a | remember the command family — every npm from now on |
t | remember this exact line, character for character, and nothing adjacent to it |
? | show what the command reaches, and why it is asking |
esc | the same as n |
ctrl-c | the same as n — at a card it is the card's refusal, never the end of the session |
Upper case works for all four letters. Anything else is discarded with a flash rather than swallowed:
that key isn't one of them — y, a, t, n or ?
That is not tidiness. A card can open under a message you were half-way through typing, and the first
letter of an ordinary word (and, all) is the key that grants a command family forever. Pressing
a or t on a card that did not draw them is junk in exactly the same way, and flashes too.
A card that opens unasked — the long job's, arriving while you sit at the prompt — refuses every key for 0.35 s after it lands. A keystroke that arrived within a third of a second of a gate appearing on its own was aimed at something else.
What ? shows
? adds the reason and the blast radius — real paths, real sizes, real counts, measured by walking
them:
█ rm -rf /tmp/build
█
█ it's a recursive delete, and the sandbox is local — that
█ combination is yours to say yes to
█ /tmp/build 12 B, 2 files
█ y go ahead n no ? what it touches
The walk stops at 20,000 entries or 0.35 seconds, whichever comes first, and says at least when it
did — a number it did not finish counting would be a lie on the one card that must not tell any.
Why a key is sometimes missing
a and t are two grants of different width, and either can be withheld on its own. An absent key
with no explanation reads as a broken product, so the card says why:
| The line | a | t | What the card says |
|---|---|---|---|
npm install left-pad | yes | yes | — |
curl -s https://example.com | no | yes | “curl” only names what runs it, not what runs — saving that would allow anything. |
sh -c 'ls', python -c '…' | no | yes | the same sentence, for the same reason |
npm run build && ./deploy.sh | no | yes | This line chains commands, so a rule for “npm” would never match it again. |
rm -rf build | no | no | It's a recursive delete, so it asks every time — this one can't be saved. |
| any shell line, on a Windows host | no | no | On Windows I can't read a command line the way the shell will, so every one of them asks. |
curl, wget, scp, rsync, nc and their neighbours are refused the family grant on purpose:
their whole job is to move bytes off this machine, and the file to send is an ordinary argument — not
a metacharacter, not even an absolute path. "Always allow curl" cannot be allowed to mean "curl may
read and post anything I can read". The exact line is still grantable.
The card always keeps ?, whatever else it withholds.
What reading costs you
Nothing. read_file, search_files, and an ls, cat, grep, head, wc or find inside her
workdir run without a card — because a gate that asks about everything trains you to approve without
reading.
That exemption has edges, and each of them asks:
- a path argument that leaves the workdir (
cat ~/.ssh/id_rsa,ls /etc) — including one carried inside a flag, sogrep --file=/etc/passwdasks; - any shell metacharacter (
;&|backtick<>${}newline), because the first token stops describing what runs; - a flag that turns a reader into something else:
find -exec/-delete,rg --pre,sort -o,tail -f, including inside a short bundle liketail -qf; - anything the dangerous-pattern set names, which is never auto-safe and never covered by a saved grant of either width.
Under sandbox docker the picture changes: everything she runs is in a container that sees only her
workdir, so only a dangerous command asks. Under sandbox none she runs nothing on this machine at
all. On a Windows host running local, nothing is exempt — see
Platform support.
Outside the interactive terminal
kotoba --once and kotoba setup have no card renderer, so the same question arrives as a line
prompt — printed to stderr, so it never lands glued to her answer on stdout — and this one does
take Enter:
npm install left-pad
allow? [y/N/a/t] — a = always allow npm — t = always allow just this line
The bracket shrinks to [y/N/t] or [y/N] when a key is withheld, and ? is not offered there.
yes, always and this are accepted as long forms. Piping an answer in still works.
If stdin ends before you answer, that is not a yes: no answer is recorded and the command does not
run. And if you start the full terminal with its output piped somewhere — no keyboard to ask with —
the card is not left waiting for three minutes either. It is drawn once and refused:
nothing here can answer that, so I left it alone.
A card that arrives late
The long job runs detached, so its approvals cannot interrupt a turn. They open at the prompt
instead, minutes later, on your Enter or when the idle prompt wakes for them. Two can be outstanding
at once; the older is drawn first, and the newer one is counted:
2 of hers are waiting — this one first, and it's the older.
Each has a 180-second window. The card says so while it is holding one:
█ I asked while you were away, so I've been holding it — I'll
█ give it three minutes and then leave it alone
A window that runs out collapses the card to the same one-line receipt every answer collapses to.
Taking a grant back
/approvals lists every standing grant and what each one buys now; /approvals rm <name-or-number>
removes one. Revoking never asks for confirmation — it only makes her ask more. The same list is in
the web app under Settings → Security.
