pub enum HookOutcome {
Allow,
Deny(String),
Modify {
input: Value,
reason: Option<String>,
},
Replace {
output: Value,
is_error: bool,
reason: Option<String>,
},
}Expand description
What the chain decided about a call.
basis’s own type, shaped like mentra’s HookDecision so the adapter bridging
them is a match and nothing more — but carrying the replacement input as
parsed JSON rather than a string, because an in-process host reading this
should not have to parse a document back out of it.
Also what a single Interceptor answers with. Two
bindings, one vocabulary: an interceptor’s Deny and a hook’s deny are
the same refusal, told to the model the same way.
One enum for both events rather than two, because three of the four answers
mean the same thing at either — and the one that does not, Modify,
is refused by name after the call rather than reinterpreted into something
nobody asked for.
Variants§
Allow
No participant objected. Not the same as “nobody was asked”.
After the call this is keep: the result reaches the model as the tool produced it.
Deny(String)
Blocked, with a reason meant to be read — by the model, which sees it as the tool’s error, and by whoever has to work out what happened.
After the call nothing can be blocked, so a refusal is the strongest thing still available: the model is shown this reason instead of the output, marked as an error. What ran, ran — the event stream already carries what it returned.
Modify
Run the tool with this input instead.
input is what the chain left behind after every modification, and
reason names each participant that changed something — “the input is
not what the model wrote” is exactly what an audit trail is for.
Before the call only.
Replace
Show the model this result instead of the one the tool returned.
is_error is carried beside the output because the two are one
statement: a replacement that redacts a secret out of a successful
result is still a success, and one that turns an output into a refusal
is not. reason names every participant that changed something, as
Modify’s does, and reaches the audit trail rather
than the model — the model is not being told “no”, it is simply being
shown a different result.
After the call only.