feat(13-12): G-B1/G-B2 cloud-egress secret scan and turn-minimality screen
assistant/egress.rs: screen_outbound(body, ctx) -> EgressVerdict runs on every request body about to leave this node for a cloud backend. G-B1 scan_secret_shapes checks for macaroon-shaped hex runs, BIP39-length word runs, ecash/Nostr-key-shaped strings, and the literal contents of files under data_dir/secrets — a hit fails closed (BlockFallBackLocal), logging only the match's kind, never the value. G-B2 assert_turn_minimal checks the outbound body against a mechanical allowlist of this turn's own fields (the user's turn, this turn's granted tool names, this turn's own tool results); an unrelated earlier tool result or content wrapped for a different turn is truncated out rather than eyeballed. An unparsable/ambiguous body also fails closed. MAX_OUTBOUND_CONTEXT_CHARS caps body size independent of minimality. Wired into backends/claude.rs's send() before the outbound HTTP request (on a block, send() errors before anything is sent — Rule 3, outside this task's originally-declared file list but structurally required to give screen_outbound a real caller); never wired into ollama.rs — nothing leaves the node on that leg, so paying the scan cost would be pointless. mod.rs: AssistantCounters/OwnerNotice — grant refusals, validation failures, turns-per-request, untrusted-content-present, cloud-escalation-while-local-up, blocked-egress and MAX_TURNS-reached counters, each raising an owner_notice() at its own AI-SPEC §7b threshold. Local and owner-facing only: no exporter, no /metrics, no OTLP anywhere in assistant/ or rate_limit.rs. backends/mod.rs's select_backend raises a cloud-escalation-while-local-up notice when Ollama is reachable but its configured model isn't tool-capable (Rule 3, same file-scope reasoning). 9/9 assistant::egress:: tests pass in this task's own isolated state (Task 1's 56 plus these 9 — ToolExecCtx's counters field and its loop_.rs call sites are Task 3's own commit, since nothing in this task's behavior needs them yet). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
265ba5ab19
commit
fde7b1572d
@@ -137,6 +137,12 @@ pub async fn select_backend(data_dir: &Path) -> (Box<dyn Backend>, BackendId) {
|
||||
model,
|
||||
"D-04: Ollama detected but the configured model is not tool-capable — falling through to Claude"
|
||||
);
|
||||
// G-B3/T-13-83: Ollama IS up (reachable) — this is exactly the
|
||||
// "cloud used even though local is up" case the owner must see,
|
||||
// even though the reason this time is capability, not health.
|
||||
crate::assistant::global_counters().note_cloud_escalation_while_local_up(&format!(
|
||||
"Ollama is reachable but its configured model ({model}) is not tool-capable"
|
||||
));
|
||||
}
|
||||
(
|
||||
Box::new(claude::ClaudeBackend::new(data_dir.to_path_buf())),
|
||||
|
||||
Reference in New Issue
Block a user