Kotoba

Where to start

What Kotoba isWho she is and where she runs, in one page
InstallingOne package, two commands
First runA key, a model, her first words
The approval gateHow she asks before she acts
The two voice modesLocal voice, or the agent tunnel
The soul fileChange who she is
RoadmapWhat grows next, and what was cut on purpose

Or a section

↑↓ move openesc close124 pages
All pages

Terminal and platforms5 of 10

The approval card

About 5 minutes to read

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

KeyWhat it does
yrun it, once, right now, in this turn
nrefuse. She is told, and says so plainly instead of pretending
aremember the command family — every npm from now on
tremember this exact line, character for character, and nothing adjacent to it
?show what the command reaches, and why it is asking
escthe same as n
ctrl-cthe 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 lineatWhat the card says
npm install left-padyesyes
curl -s https://example.comnoyes“curl” only names what runs it, not what runs — saving that would allow anything.
sh -c 'ls', python -c '…'noyesthe same sentence, for the same reason
npm run build && ./deploy.shnoyesThis line chains commands, so a rule for “npm” would never match it again.
rm -rf buildnonoIt's a recursive delete, so it asks every time — this one can't be saved.
any shell line, on a Windows hostnonoOn 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, so grep --file=/etc/passwd asks;
  • 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 like tail -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.