You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
harden(danger): fix code-review findings on the Unknown class
Self-review of the fail-closed change surfaced consumers that enumerate
risk classes but were never taught about the new Unknown class, plus two
classifier correctness bugs. Fixes:
1. Sub-agent risk caps ignored Unknown (cmd/odek/subagent.go). The mirror
riskRank() had no Unknown case (returned 0) and the untrusted + maxRisk
clamp loops didn't list it. Result: max_risk="unknown" denied even Safe,
and a capped/untrusted sub-agent never force-denied Unknown when the
inherited config loosened it. Root cause was the duplicated ranking, so
export danger.Rank as the single source of truth (rank→Rank) and have
subagent.go use it; add danger.Unknown to both clamp loops.
2. Trust-class shortcut allowed Unknown (internal/danger/approver.go,
cmd/odek/wsapprover.go). "Trust class for session" was disabled only for
Destructive/Blocked, so a single grant could blanket-approve every future
unrecognised verb — the exact approval-fatigue attack the exclusion
exists to stop. Exclude Unknown too.
3. dd to a character device misclassified destructive (classifier.go).
isDestructive's of= branch matched any "/dev/" substring, so the common
`dd ... of=/dev/null` / `of=/dev/stdout` idioms were denied. Use the
precise containsBlockDevice matcher (also dedupes the device logic).
4. ANSI-C octal over-read (classifier.go decodeEscape). The loop consumed
up to 4 octal digits; bash takes at most 3. `$'\1551'` now decodes to
"m1" (octal 155 + literal 1), matching the shell, not a single byte.
Regression tests added for each; rank→Rank rename propagated through the
danger package and its tests. Full suite green; go vet clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments