Skip to content

The ACK grammar

 2 min Supervising an agent through prose alone: an item is handled only when the reply echoes its durable key, with rules for separating acknowledgments from examples.
Published

Jun 30, 2026

The Spice harness steers agents without any API on the agent’s side. A steering item carries a durable key—a nine-character base52 stamp—and the item counts as handled only when the assistant’s reply contains an acknowledgment that echoes it:

ACK dMbnngX3j: <what changed or was captured>

The header parser requires ACK as a standalone ALL-CAPS token followed, in order, by one or more key-shaped tokens (optionally carrying a -N collision suffix). NACK is the same grammar with opposite sign, and both polarities are walked in source order. The hot path is a plain "ACK" in text substring check, so ACK-free replies cost one scan.

The grammar’s real work is tolerating markdown reality. Models bold their headers (**ACK k:** ...), decorate them as list items or headings, and pad them with filler (“ACK inbox key dMbnngX3j”). Each tolerance is an explicit consumption rule with stated widths—wrapper characters, key closers, separators, filler words—rather than a regex shrug, so every reader of the grammar parses the same header the same way.

Then two guards keep prose about the protocol from acting as the protocol. The use-versus-mention guard discards a candidate ACK that context shows is being talked about rather than issued: quoted or backticked, preceded by explicit negation, or sitting in a clause window with hypothetical words or narration words:

return (
    textcontext.has_explicit_negation_before(text, ack_pos)
    or bool(_ACK_HYPOTHETICAL_WORDS & set(recent))
    or bool(_ACK_NARRATION_WORDS & set(recent))
)

“I could write ACK here” does not acknowledge anything. Neither does an example, a phrase, or a saying—the wordlists are cheap and the failure class they close is real. A keyless ACK: shaped like a directive is detected too, as its own failure: said ACK, named no key.

The suppression walk is the second guard. One shared iterator decides, per line, whether a control token is displayed rather than issued—inside a code fence (fence character and size matched), a > quote, 4-space indentation, or a rendered path:line: source-context line. Shown control tokens never act. The doctrine is stated at the trim helper, which refuses to strip indentation off a segment’s first content line:

four spaces there is the difference between code being shown and a directive being issued

Every reader must drop exactly the same lines, so the walk exists once.

The prose is the interface. There is no extra tool call on the agent side, but there is still a protocol: token, key shape, header tolerances, mention guards, and suppression rules. The shared parser makes its readers agree. It cannot prove that the work described after an ACK actually happened; that needs its own evidence.