A book accepts ledger entries, and nothing else

The router sorted directives into files by kind and never asked whether a kind was allowed at all, so a plugin, option, include or custom line composed by a model out of a customer's prose travelled the same path as a transaction.

Every file the router writes is included from main.beancount. So a directive that configures beancount itself, composed by a language model from a sentence a customer typed, went in through the same door as a transaction.

An allow-list, not a plugin denylist. Measured on beancount 3.2.3 with a negative control: plugin in transactions.beancount leaves bean-check exiting 1, and the same line in main.beancount exits 0. Beancount does not honour plugin from an included file, so the directive the issue leads with is contained today by an accident of the library — while include, which is honoured from an included file, would have taken the same else branch.

Dated-versus-undated is not the separating property either: custom is dated, and it is how Fava is configured. So the rule is dated ledger entries by name and nothing else. The gate runs before the write lock and before anything touches disk, so a refusal leaves the book unchanged by construction rather than by rollback.