Files
Agent-System/internal/coordinator/engine_clarification_test.go
T
WeiCHENandCursor 868238137c fix(intent): Phase 0+1 P0 safety gates for recognition and coordination
Add golden-v1 hard-negative suite, shadow observability fields, query/command
negation gates for high-risk writes, AllowAffirmative enforcement, candidate
conflict clarification, and coordinator clarify-before-ambiguous ordering.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:50:21 +00:00

94 lines
3.1 KiB
Go

package coordinator_test
import (
"context"
"strings"
"testing"
"chat-agent-system/internal/bizdev"
"chat-agent-system/internal/coordinator"
"chat-agent-system/internal/intent"
)
// TestEngine_ClarificationBeforeAmbiguousConsult 缺驳回理由必须返回定向澄清,不得进入参谋模糊咨询
func TestEngine_ClarificationBeforeAmbiguousConsult(t *testing.T) {
rec := intent.NewRecognizer()
engine := coordinator.NewCoordinatorEngine(nil)
ctx := &intent.ContextSnapshot{
SnapshotID: "ctx_engine_clarify",
CurrentStage: string(bizdev.StageV05_Feasibility),
ActiveDocID: "doc-002",
DocLifecycleState: "reviewing",
UserDocRole: "reviewer",
}
recRes, err := rec.Recognize(context.Background(), "把调研报告审核驳回", ctx)
if err != nil {
t.Fatalf("recognize failed: %v", err)
}
if !recRes.RequiresClarifying {
t.Fatal("expected RequiresClarifying from recognizer")
}
if recRes.Branch == intent.BranchAmbiguousFallback {
t.Fatalf("missing reject_reason should not be AMBIGUOUS_FALLBACK before engine, got %s", recRes.Branch)
}
userCtx := &coordinator.UserProjectContext{
User: coordinator.UserInfo{ID: "user_102", Name: "李审核", Role: "reviewer", ProjectRole: "reviewer"},
Project: coordinator.ProjectInfo{
Name: "智能内窥镜项目",
CurrentStage: bizdev.StageV05_Feasibility,
},
BlackboardFacts: map[string]string{},
}
res, err := engine.ProcessIntent(context.Background(), recRes, userCtx)
if err != nil {
t.Fatalf("ProcessIntent failed: %v", err)
}
if res.Status != coordinator.StatusClarificationRequired {
t.Fatalf("expected CLARIFICATION_REQUIRED, got %s", res.Status)
}
if !strings.Contains(res.ClarificationPrompt, "驳回理由") {
t.Fatalf("expected clarification about reject reason, got: %s", res.ClarificationPrompt)
}
}
// TestEngine_ClaimQueryMustNotExecuteWrite 查询认领不得进入写 handler
func TestEngine_ClaimQueryMustNotExecuteWrite(t *testing.T) {
rec := intent.NewRecognizer()
engine := coordinator.NewCoordinatorEngine(nil)
ctx := &intent.ContextSnapshot{
UserDocRole: "viewer",
DocLifecycleState: "draft",
ActiveDocID: "doc-001",
}
recRes, err := rec.Recognize(context.Background(), "这份报告谁认领了?", ctx)
if err != nil {
t.Fatalf("recognize failed: %v", err)
}
if recRes.TopIntent.Intent == intent.IntentDocGovClaim {
t.Fatal("claim query must not be classified as DOCGOV_CLAIM")
}
userCtx := &coordinator.UserProjectContext{
User: coordinator.UserInfo{ID: "user_101", Name: "张工", Role: "engineer", ProjectRole: "composer"},
Project: coordinator.ProjectInfo{Name: "测试项目"},
BlackboardFacts: map[string]string{},
}
res, err := engine.ProcessIntent(context.Background(), recRes, userCtx)
if err != nil {
t.Fatalf("ProcessIntent failed: %v", err)
}
if res.Status == coordinator.StatusAccepted && recRes.TopIntent.Intent == intent.IntentDocGovClaim {
t.Fatal("claim query must not execute write handler")
}
if res.Status != coordinator.StatusClarificationRequired {
t.Fatalf("expected clarification for claim status query, got %s", res.Status)
}
}