Repository navigation
Fail closed Nova model HTTP without a policy and a witness - #41
Conversation
With NOVA_ICK_POLICY and NOVA_ICK_SERVICE unset, Nova does not call the provider client. WICKET_ALLOW_DIRECT_CALLS=1 remains the only local-dev escape and warns on every use. A configured gate still sends through the witness with the derived call_digest. Co-authored-by: Jon Halstead <warheart1984@gmail.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 173172e373
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| return self._from_provider_json(governed_request, data) | ||
|
|
||
| def chat_completion(self, governed_request: dict[str, Any]) -> dict[str, Any]: | ||
| refuse_unconfigured_model_http() |
There was a problem hiding this comment.
Reject streamed requests before starting the response
When stream=true and neither a policy nor the direct-call opt-out is configured, this new refusal is raised only while _stream_provider_completion is iterating, after StreamingResponse has already committed an HTTP 200 response. That generator catches KernelRefusal as ProviderError and emits an assistant-style [ProviderError] SSE chunk instead of the documented HTTP 403 WITNESS_REQUIRED, so streaming clients can interpret a denied request as a successful completion. Preflight the refusal before constructing StreamingResponse, or otherwise preserve the 403 semantics for this case.
Useful? React with 👍 / 👎.
What this is
Nova model HTTP no longer calls the provider when
NOVA_ICK_POLICYandNOVA_ICK_SERVICEare both unset. Nothing is sent unless a policy and a witness are configured. This does not prove observed effect.What a reviewer can check
POST /v1/chatandPOST /v1/chat/completionsreturn HTTP 403WITNESS_REQUIRED, and the provider is not called. The same holds forpost_json, the local-model tool, and the Ollama path innova/api.py. A witness with no policy does not send, and the witness is not asked.WICKET_ALLOW_DIRECT_CALLSsends only when it is exactly1. Other values send nothing and print no warning.1sends and prints the stderr warning once per use. It does not bypass a policy that is already set, and it does not apply to gossip./v1/chatis sent by the witness. Nova'spost_jsonis not called. The allow receipt'scall_digestis the digest derived from the concrete POST (effectwrite). A streamed known-shape call is refused withSTREAM_NOT_BOUND.What this does not prove
state_ref, retries, a heartbeat, and a two-account probe.riskandactionare still the caller's claim. The clock is unproven. A compromised witness can sign a false execution. The authorization header is presence-only.User-Agentis sent and is not hashed. A streamed known-shape call stays refused because the witness binds one body. The opt-out does not derive acall_digest.Limits are stated in
docs/executor-mode.md.