Explanation
Why a binary and not a prompt#
A model that is asked “may this run?” will sometimes say yes. The gate reads argv. This crate is that process: argv in, a one-line verdict out. The harness hook calls it. A Janet pack can deny more after this verdict.
A model cannot be the mediator. An agent that can talk its way past
the check is the threat, and indirect prompt injection shows that
instructions carried in data change what a model permits (Greshake et
al., doi:10.48550/arXiv.2302.12173). No matching rule in this table is
an allow. This table judges the argv it is given. Saltzer and
Schroeder would deny in that case
(Saltzer and Schroeder, 1975).
This table does not. The fail-closed switch is
POLICYD_REQUIRED=1, and it covers a missing binary. The next layer
may deny more. It cannot allow what this table refused.
First deny wins#
The built-in list is the argv TCB from phronesis (Ali Akber Saifee /
indynull, HaoZeke; MIT): privilege runners, remote-exec, recursive
delete off tmp, force-push, setuid, raw disk. A later pack rule can
deny more. A pack may only deny more. python -c is
allow: this hook sits on a general agent shell, not a uv-only
product seat.
Cap’n is the typed verdict#
Decision / PolicyDecision / checkShell(argv) follow phronesis
schema/policy.capnp. The hook still reads a one-line text verdict.
ljos-policyd capnp -- argv writes the packed message. Seat, model,
and audio planes stay in phronesis.
A missing binary leaves the line open#
A seat without the binary still sits. Doctor names the row. The
hook and ljos policy print the line and any pack rule. Setting
POLICYD_REQUIRED=1 is the fail-closed seat: then a missing binary
is a deny. That switch belongs to the operator.
A check is the argv verdict#
A Janet file, a comment, a stamp, a ticket id written into a policy
pack: those are file writes. This crate prints a verdict. Pack
rules live in packset and are composed by ljos policy after this
verdict.
Remember and Prefer stay in packset#
Remember and Prefer are speech acts in the pack. A deed is a frozen product. A ticket is a heading. A claim is a lease. This crate answers one question: may this command line run? Mixing that answer into a memory store is how a hook starts writing.
Where the seat puts it#
ljos doctor lists a policyd row when the binary answers.
ljos policy -- argv prints the line, then this verdict, then any
pack rule. ljos hook is the same answer on the runner’s
PreToolUse path. The public crate is this one.
https://leidarljos.github.io teaches sitting; this site teaches
the binary.