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.