Persist validated_only shadow plans without executing, gate elevated tiers behind INTENT_PLAN_PROJECT_ALLOWLIST, and keep legacy chat routing for shadow.
137 lines
3.9 KiB
Go
137 lines
3.9 KiB
Go
package intentflow
|
||
|
||
import (
|
||
"testing"
|
||
)
|
||
|
||
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)
|
||
}
|
||
}
|