[Design] Risk triage for tool calls: what does it classify, and where does it sit in the permission engine?
I maintainer di solito rispondono entro 3 giorni
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 20/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Da chiarire
- Stato di attività
- Ferma
- Stack tecnologico
- python
- Ambito
- ai-infra-agents, backend-api-design
Direzione di ricerca
Read core/harness/permissions.py and the permission flow in core/agent_runtime/runner.py, starting with the precedence and fail-closed behavior described in the issue. Decide whether risk means content triage, action triage, or neither, and settle the integration point and failure behavior with the maintainers. The issue’s linked open pull request #257 indicates work is already underway.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
For context: #189 (feat(classifier): harness risk classifier (split from #181)) was closed with "Auto-mode-style risk triage is a real product question, but it needs a design discussion first (framing of the classifier prompt, where it sits in the permission engine, integration tests). Happy to have that conversation in an issue before any code." This is that issue — no code attached on purpose.
1. Why the prototype answered none of those three questions
#189 added core/harness/classifier.py: a rule-based (keyword + boundary heuristic) scorer with classify(text) -> RiskDecision, gated behind DEEPCODE_RISK_CLASSIFIER, ~427 lines, and no caller. So "where does it sit in the permission engine" was not answerable from the diff — it was a library with no integration point. That is the first thing to fix in the design, before any refactor.
2. The ambiguity worth settling first: two things are called "risk"
(a) Untrusted-content triage. Input is text (tool output, MCP payload, injected input); the question is "should this content be trusted as instructions?" It is consumed before the model acts on it. This is not a permission decision — the permission engine never sees content, only a tool call. Its natural home is a note/reminder channel or a pre-model transform.
(b) Action triage / auto-mode gating. Input is a tool call (name + canonicalized arguments); the question is "may this run without asking?" This is exactly what core/harness/permissions.py already decides (allow / ask / deny).
#189 built (a). The review read it as (b). Both are defensible products, but they have different seams, different inputs, and different tests, so the first decision is which one is wanted — and (b) is the one that has a natural home in the engine.
3. If (b): where it sits, and what it must never break
Current precedence in core/harness/permissions.py (first decisive wins):
- sensitive-path protection → DENY
- canonical Read-only upper bound → DENY
- explicit rule match (last-match-wins) → its action
- mode default for read-only vs mutating tools
Three placements, with the invariant each one buys:
- Option A (my preference): a strictness-raising evaluator after step 4. It may turn
allow→ask. It may never turndeny→allow, and never reinterpret steps 1–2. Invariant: a classifier can only make the engine more careful, never less — so a user's explicit rule and the sensitive-path boundary stay untouched, andfull_auto("rules only, no implicit ask") becomes "rules, plus a soft ask when the classifier objects" rather than losing its promise. - Option B: a rule family inside step 3, participating in last-match-wins. More expressive, but then a classifier decision can silently outrank a user's explicit
allow, which I'd argue against. - Option C: not in the permission engine at all — advisory only, along the
repeat_guard/ no-progress-reminder channel (acontext_note, no gate). Cheapest, adds zero new failure modes, and protects nothing infull_auto; it just tells the model.
Whatever is chosen has to preserve two existing behaviors: the runner's fail-closed path (permission_checker raising ⇒ "permission check errored (fail-closed)", core/agent_runtime/runner.py:1501), and headless ask ⇒ deny ("autonomy never silently escalates", runner.py:1497).
4. If a model is involved: prompt framing
- Input: tool name + canonicalized arguments. Deliberately not tool output — that would add a second-order injection surface and an unbounded input to the permission path (this is the one place where (a) and (b) genuinely interact).
- Output: strict schema (
{"risk": "low"|"high", "reason": "<one short line>"}), no free-form prose, no tool access, no ability to emit a permission decision directly — it returns an opinion, the engine decides. - Failure mode: timeout / unparsable / provider error. Default-off feature ⇒ I'd fail-closed (
ask) only when explicitly enabled, and keep the existing "error ⇒ deny" path for genuinely raised exceptions. Worth agreeing explicitly. - Cost/latency: a model call inside the permission path is per-tool-call latency. It needs caching by call signature and a strict timeout, otherwise it is a UX regression in exactly the mode it targets.
- Rules vs model: rule-based scoring (what #189 did) is deterministic and free but has a high false-negative rate on anything but the patterns it was written for. "Rules only", "model only", or "rules first, model only on the residue" are three different products here — if it is rules-only, most of this section disappears.
5. Integration tests I would write
- The classifier cannot loosen anything: sensitive-path DENY and
plan-mode DENY survive anallowopinion (this is the regression test for Option A's invariant). - The intended path:
full_auto+ enabled + high risk ⇒ask; with no approval callback (headless) ⇒ denied with a reason. - Classifier failure is contained: raising, timing out, or returning garbage ⇒ fail-closed, never a crash, never an allow.
- No waste: no classifier call when steps 1–3 already decided; at most one call per call signature (cache hit asserted).
- Evasion fixtures (encoded/obfuscated arguments, benign wrappers) — plus an explicit statement that this is advisory, not a security boundary.
6. What I need from you
- (a) content triage, (b) action triage, or neither?
- If (b): A, B, or C — and default-off?
- If model-based: is a second LLM call per tool call acceptable in
full_auto, or must it stay rules-only? - Anything about upstream's roadmap that already covers this (searching for
keyring/repeat_guard/auto-mode/riskfound no open PR or issue on it — #181 is closed).
#189's prototype can be rebased onto whatever shape comes out of this discussion; I am not opening a code PR before that.
- Lingua principale
- Python
- Stelle
- 16.7k
- Fork
- 2.2k
- Merge medio
- 2g 20h
- PR unite (30g)
- 15
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di HKUDS/DeepCode
-
dependencies
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
HKUDS/DeepCode#252 · 2 commenti ·
I maintainer di solito rispondono entro 3 giorni
-
[Question]:Privacy PolicyApertaquestion
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 25/100
HKUDS/DeepCode#262 · 1 commento ·
I maintainer di solito rispondono entro 3 giorni
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 25/100
HKUDS/DeepCode#209 · 1 commento ·
I maintainer di solito rispondono entro 3 giorni
-
[Question]:什么时候更新的?UI这么现代了Apertaquestion
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 25/100
HKUDS/DeepCode#196 · 1 commento ·
I maintainer di solito rispondono entro 3 giorni
-
[Question]: How does DeepCode's memory system work and how does it compare with other memory systemsApertaquestion
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 25/100
HKUDS/DeepCode#150 · 1 commento ·
I maintainer di solito rispondono entro 3 giorni
Tutte le issue di HKUDS/DeepCode
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
AstrBotDevs/AstrBot#10720 ·
I maintainer di solito rispondono entro 1 giorno
-
fix(xiaomi): curated picker list still offers six ids that return 400 (plan-limited vs retired)Apertacause/upstream comp/cli P2 provider/other tool/file type/bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
NousResearch/hermes-agent#143900 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 1-3 ore Idoneità per principianti 85/100
WLAN-Pi/wlanpi-profiler#341 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
I maintainer di solito rispondono entro 1 giorno