package intentflow import ( "testing" "chat-agent-system/internal/intent" ) func TestDefaultPlanTierIsLegacy(t *testing.T) { t.Setenv("MULTI_INTENT_PLAN_TIER", "") ResetFeatureFlagsForTest() if got := CurrentFeatureFlags().PlanTier; got != TierLegacy { t.Fatalf("default tier = %s, want legacy", got) } } func TestUnknownPlanTierFailsClosedToLegacy(t *testing.T) { if parsePlanTier("definitely-not-a-tier") != TierLegacy { t.Fatal("unknown MULTI_INTENT_PLAN_TIER must fail closed to legacy") } } func TestPlanTierIndependentOfLegacyMultiIntentFlag(t *testing.T) { t.Setenv("MULTI_INTENT_ENABLED", "true") t.Setenv("MULTI_INTENT_PLAN_TIER", "") ResetFeatureFlagsForTest() if CurrentFeatureFlags().PlanTier != TierLegacy { t.Fatal("MULTI_INTENT_ENABLED must not promote plan tier") } } func TestPlanTierIndependentOfExpansionFlags(t *testing.T) { t.Setenv("MULTI_INTENT_PLAN_TIER", "") t.Setenv("MULTI_INTENT_U9_SEGMENT", "true") t.Setenv("MULTI_INTENT_U10_MUTATE", "true") t.Setenv("MULTI_INTENT_U11_DOCGOV", "true") t.Setenv("MULTI_INTENT_U12_RUN_CONTROL", "true") ResetFeatureFlagsForTest() if CurrentFeatureFlags().PlanTier != TierLegacy { t.Fatal("U9–U12 flags must not raise MULTI_INTENT_PLAN_TIER") } } func TestPlanTierEnv(t *testing.T) { if parsePlanTier("shadow") != TierShadow { t.Fatal("shadow") } if parsePlanTier("auto_read") != TierAutoRead { t.Fatal("auto_read") } if parsePlanTier("confirm") != TierConfirm { t.Fatal("confirm") } if parsePlanTier("full") != TierFull { t.Fatal("full") } if !TierConfirm.Allows(TierAutoRead) || TierShadow.Allows(TierConfirm) { t.Fatal("tier rank") } } func TestProjectAllowlistParseAndGate(t *testing.T) { if got := ParseProjectAllowlist(""); len(got) != 0 { t.Fatalf("empty = %+v", got) } if got := ParseProjectAllowlist("*"); len(got) != 1 || got[0] != AllowAllProjects { t.Fatalf("star = %+v", got) } got := ParseProjectAllowlist("42, 100,42,bad") if len(got) != 2 || got[0] != 42 || got[1] != 100 { t.Fatalf("list = %+v", got) } legacy := FeatureFlags{PlanTier: TierLegacy} if !legacy.ProjectAllowed(99) { t.Fatal("legacy must not require allowlist") } denied := FeatureFlags{PlanTier: TierShadow} if denied.ProjectAllowed(42) { t.Fatal("empty allowlist must deny elevated") } ok := FeatureFlags{PlanTier: TierAutoRead, ProjectAllowlist: []int64{42}} if !ok.ProjectAllowed(42) || ok.ProjectAllowed(7) { t.Fatal("id allowlist") } all := FeatureFlags{PlanTier: TierConfirm, ProjectAllowlist: []int64{AllowAllProjects}} if !all.ProjectAllowed(1) { t.Fatal("wildcard") } } func TestDefaultAllowlistEmpty(t *testing.T) { t.Setenv("MULTI_INTENT_PLAN_TIER", "shadow") t.Setenv("INTENT_PLAN_PROJECT_ALLOWLIST", "") ResetFeatureFlagsForTest() f := CurrentFeatureFlags() if f.PlanTier != TierShadow { t.Fatal(f.PlanTier) } if len(f.ProjectAllowlist) != 0 { t.Fatalf("default allowlist must be empty deny, got %+v", f.ProjectAllowlist) } } func TestErrorCodes(t *testing.T) { if ErrorCode(ErrPlanNotFoundOrHidden) != "PLAN_NOT_FOUND_OR_HIDDEN" { t.Fatal(ErrorCode(ErrPlanNotFoundOrHidden)) } if ErrorCode(ErrPlanStaleRevision) != "PLAN_STALE_REVISION" { t.Fatal("stale") } if ErrorCode(ErrPlanExpired) != "PLAN_EXPIRED" { t.Fatal("expired") } if ErrorCode(ErrPlanDecisionConflict) != "PLAN_DECISION_CONFLICT" { t.Fatal("conflict") } if ErrorCode(ErrPlanDependencyInvalid) != "PLAN_DEPENDENCY_INVALID" { t.Fatal("dep") } if ErrorCode(ErrPlanActionForbidden) != "PLAN_ACTION_FORBIDDEN" { t.Fatal("forbidden") } if ErrorCode(ErrPlanActionVersionConflict) != "PLAN_ACTION_VERSION_CONFLICT" { t.Fatal("version") } } func TestRESTPathsFrozen(t *testing.T) { if PathActivePlan != "/api/v1/intent-plans/active" { t.Fatal(PathActivePlan) } if PathPlanByID != "/api/v1/intent-plans/{plan_id}" { t.Fatal(PathPlanByID) } if PathPlanDecisions != "/api/v1/intent-plans/{plan_id}/decisions" { t.Fatal(PathPlanDecisions) } } // TestValidateFlagConsistency FIND-QUAL-01 回归:PlanTier 升档但多意图识别 // 关闭时组合根必须 fail-fast,不允许静默漂移配置。 func TestValidateFlagConsistency(t *testing.T) { base := intent.FeatureFlags{MultiIntentEnabled: true} if err := ValidateFlagConsistency(base, FeatureFlags{PlanTier: TierFull}); err != nil { t.Fatalf("elevated tier with multi-intent on should pass: %v", err) } if err := ValidateFlagConsistency(base, FeatureFlags{PlanTier: TierLegacy}); err != nil { t.Fatalf("legacy tier should always pass: %v", err) } drifted := intent.FeatureFlags{MultiIntentEnabled: false} for _, tier := range []PlanTier{TierShadow, TierAutoRead, TierConfirm, TierFull} { if err := ValidateFlagConsistency(drifted, FeatureFlags{PlanTier: tier}); err == nil { t.Fatalf("tier %s with multi-intent off must fail fast", tier) } } }