Repository navigation
Send Nova's known-shape calls through the witness - #39
Conversation
Provider HTTP and the local-model tool go through executor mode when the gate is on, or they are not sent. ickverify recomputes call_digest from a supplied call and joins the witness log by allow receipt id. Co-authored-by: Jon Halstead <warheart1984@gmail.com>
The provider client is not called unless Witness.execute dispatched, and a direct post is refused while the gate is on. 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: 1a0dbde842
ℹ️ 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".
| witness_key=Path(args.witness_key), | ||
| receipt_trusted_keys=Path(args.receipt_keys), | ||
| receipt_anchor=Path(args.receipt_anchor) if args.receipt_anchor else None, | ||
| dispatch=dispatch_known, |
There was a problem hiding this comment.
Preserve provider timeouts in witness dispatch
When the gate is enabled, this newly selected production dispatcher routes every external and Ollama generation through dispatch_https, which constructs its HTTP connections with a hard-coded 10-second timeout (runtime/witness.py:103-107). This ignores the existing provider timeouts—60 seconds for registry providers and 120 seconds for /v1/chat Ollama—so otherwise valid model generations taking more than 10 seconds are consumed and recorded as failed. Pass the configured timeout to the witness or expose an equivalent witness timeout.
Useful? React with 👍 / 👎.
| if bound.kind == "https_request": | ||
| return dispatch_https(bound) |
There was a problem hiding this comment.
Reject unsuccessful HTTP responses in witness dispatch
For witnessed provider calls, dispatch_known sends HTTP through dispatch_https, but that function returns response.read() without checking the status code (runtime/witness.py:123-124). Unlike the previous urllib clients, http.client does not raise for 4xx/5xx responses, so an authentication failure or provider outage is recorded as a completed witness execution and its error JSON may be returned as an empty or malformed completion. Treat non-2xx statuses as dispatch failures before recording completion.
Useful? React with 👍 / 👎.
| raise WitnessError("dispatch", "a local model call needs prompt and model text") | ||
| temperature = arguments.get("temperature", 0.2) | ||
| max_tokens = arguments.get("max_tokens", 2048) | ||
| ollama = os.environ.get("NOVA_NODE_OLLAMA_URL", "http://localhost:11434/api/generate") |
There was a problem hiding this comment.
Retain the vLLM fallback for witnessed local tools
When the gate is enabled, local-model calls now execute here instead of through _direct, but this dispatcher only reads NOVA_NODE_OLLAMA_URL and never attempts the established NOVA_NODE_VLLM_URL fallback. Deployments configured for vLLM, or those relying on vLLM when Ollama is unavailable, therefore fail every governed code, wire, explain, or replay call even though the same configuration works with the gate off.
Useful? React with 👍 / 👎.
What this is
When Nova's gate is on, a known call shape is sent by the witness or not sent at all.
verifier/ickverify.pycan recomputecall_digestfrom a concrete call and join the witness log by allow receipt id. This does not prove observed effect.What a reviewer can check
explain,status,code, andwirego throughWitness.execute. Nova does not hold the witness key.NOVA_ICK_WITNESSis the socket forpython -m runtime.witness_service. If the gate is on and no witness is configured, the call is not sent.post_jsonrefuses a direct send while the gate is on.write.ickverify.py --callrecomputescall_digestwith the standard library only. That digest matchesruntime/call_binding.py. A forged digest and an omitted digest on a bound allow fail verification. The verifier cannot rebuild a call from a digest alone.--witness-logreports mismatch, unauthorized, reused, late, and a bound allow with no execution.--witness-keyschecks signatures. A witness key file that usesthroughis refused.Tests
nova-shell/tests/test_witness_gate.py: a known shape cannot skip the witness.tests/test_execution_binding.pyandtests/test_standalone_verifier.py: forged and omitted digests fail verify, and the witness join reports the five cases above.What this does not prove
completedwitness entry means this process sent the call and received bytes.state_ref, retries, a witness heartbeat, and a two-account probe.python -m runtimeandrun_turnwithout a witness still call the provider after the kernel allows it.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 not hashed.Limits are stated in
docs/executor-mode.md.