返回 DeepSeek-Reasonix
constraints_test.go
根目录 / internal / runtimepolicy / constraints_test.go
1 package runtimepolicy
2
3 import (
4 "testing"
5
6 "reasonix/internal/evidence"
7 )
8
9 func TestParseConstraintsNeverBansMutationFromProse(t *testing.T) {
10 for _, instruction := range []string{
11 "Do not modify PR #10. Create a branch and implement the repair.",
12 "Write AUDIT.md with the result. Do not change any config.",
13 "Implement login. The schema: do not modify",
14 "Analyze only the payment flow.",
15 "Read-only review of PR #10.",
16 "Do not modify anything.",
17 "No changes.",
18 "按方案实现登录模块,数据库结构不要改。",
19 "帮我新建登录模块的前后端文件,其他不要改",
20 "不要修改当前工作区。",
21 "只分析支付流程。",
22 } {
23 t.Run(instruction, func(t *testing.T) {
24 got := ParseConstraints(StripQuotedConstraints(instruction))
25 if got.ForbidMutation || !got.AllowsMutation() {
26 t.Fatalf("prose set a mutation ban: %+v", got)
27 }
28 decision := (ConstraintGuard{Constraints: got}).BeforeTool(CallContext{
29 Profile: evidence.EffectProfile{Known: true, WorkspaceWrite: true},
30 })
31 if decision.Action == GuardDeny {
32 t.Fatalf("writer decision = %+v, want no constraint denial", decision)
33 }
34 })
35 }
36 }
37
38 func TestPlanModeConstraintDeniesWriters(t *testing.T) {
39 c := Constraints{PlanModeReadOnly: true}
40 decision := (ConstraintGuard{Constraints: c}).BeforeTool(CallContext{
41 Profile: evidence.EffectProfile{Known: true, WorkspaceWrite: true},
42 })
43 if decision.Action != GuardDeny {
44 t.Fatalf("plan-mode writer decision = %+v, want deny", decision)
45 }
46 }
47
48 // TestParseConstraintsRecognizesAnExplicitRebuild keeps the rebuild waiver tied
49 // to the user's own explicit phrasing; nothing else may set it.
50 func TestParseConstraintsRecognizesAnExplicitRebuild(t *testing.T) {
51 cases := []struct {
52 text string
53 want bool
54 }{
55 {"Please rewrite notes.md from scratch.", true},
56 {"把 notes.md 完全重写一遍", true},
57 {"rewrite the whole file", true},
58 {"add a section to notes.md", false},
59 {"read notes.md and fix the typo", false},
60 {"", false},
61 }
62 for _, tc := range cases {
63 if got := ParseConstraints(tc.text).AllowRebuild; got != tc.want {
64 t.Fatalf("ParseConstraints(%q).AllowRebuild = %v, want %v", tc.text, got, tc.want)
65 }
66 }
67 }
68
68 lines GO