jcp: a ModelIn caveat says which model a grant authorizes, and the frame names the model it runs #285
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/jcp-model-in-caveat"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What was missing
A grant's capability names one
resourceby content address. When that resource is an inference endpoint, the model it runs is chosen inside the payload, and the decision point sees only the payload's hash. So a grant could authorize "this endpoint", but never "this endpoint, running these models".PayloadIscomes close, but it makes the grant single-use. JCP enforced a model's integrity (refuse the wrong bytes) but not authorization over which model runs.What this adds
Frame.model: Option<ContentId>: the content address of the model the action runs. The dispatching runtime fills it in, because it knows what it will load. When absent, it is omitted from the encoding, so frames, and every receipt and vector over them, keep their bytes.Caveat::ModelIn(Vec<ContentId>): the frame must name one of these models.caveat-unsatisfied, so a dispatcher that does not say what it will run cannot exercise the grant.ModelInbeside the inherited one. Both must hold, so the intersection governs.ModelIn.Frameliteral in the repository gainsmodel: None. That is 28 sites across jcp-rs, joule-code-rs, joule-ui-rs, jouleclaw-rs and sandbox-rs.Checked
On the build host:
ModelIn.gen-vectorswrites is byte-identical to the publishedjcp/conformance/v1.cargo check --all-targets. jouleclaw-jcp, joule-code-jcp, sandbox-jcp and joule-ui pass their tests.std::slice::from_ref) are in a jcp-runtime test that predates this change.The first consumer to fill
modelshould be a dispatcher that picks its model before dispatch, such as mesh's routes. That is a follow-up.🤖 Generated with Claude Code