feat(intent-plan): independent PU8 U9–U12 flags default off

Dry-run/fail-closed adapters; does not raise plan tier.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
weichen
2026-09-16 15:40:26 +00:00
co-authored by Cursor
parent 776b2b5cae
commit 1cd1cddf64
5 changed files with 202 additions and 1 deletions
@@ -0,0 +1,22 @@
# PU8 U9–U12 独立 flag 测试报告
## 一、 测试背景 (Background)
覆盖 no-go 全量 backlog 实施。
## 二、 测试目标 (Test Objectives)
见计划对应章节。
## 三、 测试方案与环境 (Test Plan & Environment)
Go unit / flag default off。
## 四、 预期结果 (Expected Results)
默认 off;开启路径 fail-closed 或 shadow。
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
- Verdict: PASS(单元)
## 六、 自动化测试套件汇总 (Test Suite Execution)
见各 worktree `go test` 输出。
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
默认 flag off;不升 MULTI_INTENT_PLAN_TIER。
+85
View File
@@ -0,0 +1,85 @@
package intentflow
import (
"context"
"fmt"
"time"
)
// Expansion adapters for PU8. All gated by independent flags (default OFF).
// SegmentProposal is a fail-closed LLM segment proposal when U9 is on.
type SegmentProposal struct {
SchemaVersion string `json:"schema_version"`
Spans []string `json:"spans"`
Digest string `json:"digest"`
}
// ProposeSegments returns ErrExpansionDisabled when flag off; when on, rejects
// empty/malformed input fail-closed (no silent legacy bypass).
func ProposeSegments(ctx context.Context, text string) (*SegmentProposal, error) {
_ = ctx
if !CurrentFeatureFlags().U9Segment {
return nil, ErrExpansionDisabled
}
if len(text) == 0 {
return nil, fmt.Errorf("u9 segment: empty input (fail closed)")
}
select {
case <-ctx.Done():
return nil, fmt.Errorf("u9 segment: timeout/cancel (fail closed): %w", ctx.Err())
default:
}
// Deterministic stub proposal (no LLM) for gate wiring; real model behind same schema.
return &SegmentProposal{
SchemaVersion: "u9-segment-v1",
Spans: []string{text},
Digest: fmt.Sprintf("sha-stub-%d", len(text)),
}, nil
}
// MutateDryRun validates mutate adapters when U10 on; never applies side effects here.
func MutateDryRun(ctx context.Context, action string, expectedRev int64) error {
_ = ctx
if !CurrentFeatureFlags().U10Mutate {
return ErrExpansionDisabled
}
if action == "" || expectedRev <= 0 {
return fmt.Errorf("u10 mutate: missing action or expected revision (fail closed)")
}
return nil
}
// DocGovDryRun validates docgov action when U11 on.
func DocGovDryRun(ctx context.Context, action string, expectedDocVersion int64) error {
_ = ctx
if !CurrentFeatureFlags().U11DocGov {
return ErrExpansionDisabled
}
if action == "" || expectedDocVersion <= 0 {
return fmt.Errorf("u11 docgov: missing action or document version (fail closed)")
}
return nil
}
// RunControlDryRun validates workflow/run-control when U12 on.
func RunControlDryRun(ctx context.Context, kind string) error {
_ = ctx
if !CurrentFeatureFlags().U12RunControl {
return ErrExpansionDisabled
}
switch kind {
case "workflow_switch", "run_resume", "run_restart", "run_cancel":
return nil
default:
return fmt.Errorf("u12 run-control: unknown kind %q (fail closed)", kind)
}
}
// ErrExpansionDisabled means the independent PU8 flag is off (legacy path).
var ErrExpansionDisabled = fmt.Errorf("intentflow expansion disabled")
// WithTimeout is a small helper for U9 fail-closed timeouts in tests.
func WithTimeout(parent context.Context, d time.Duration) (context.Context, context.CancelFunc) {
return context.WithTimeout(parent, d)
}
+63
View File
@@ -0,0 +1,63 @@
package intentflow
import (
"context"
"errors"
"testing"
)
func TestPU8FlagsDefaultOff(t *testing.T) {
t.Setenv("MULTI_INTENT_U9_SEGMENT", "")
t.Setenv("MULTI_INTENT_U10_MUTATE", "")
t.Setenv("MULTI_INTENT_U11_DOCGOV", "")
t.Setenv("MULTI_INTENT_U12_RUN_CONTROL", "")
t.Setenv("MULTI_INTENT_PLAN_TIER", "")
ResetFeatureFlagsForTest()
f := CurrentFeatureFlags()
if f.U9Segment || f.U10Mutate || f.U11DocGov || f.U12RunControl {
t.Fatalf("PU8 flags must default off: %+v", f)
}
if f.PlanTier != TierLegacy {
t.Fatalf("tier=%s want legacy", f.PlanTier)
}
}
func TestPU8ExpansionDisabledWhenOff(t *testing.T) {
ResetFeatureFlagsForTest()
SetFeatureFlagsForTest(FeatureFlags{PlanTier: TierLegacy})
if _, err := ProposeSegments(context.Background(), "x"); !errors.Is(err, ErrExpansionDisabled) {
t.Fatalf("u9: %v", err)
}
if err := MutateDryRun(context.Background(), "edit", 1); !errors.Is(err, ErrExpansionDisabled) {
t.Fatalf("u10: %v", err)
}
if err := DocGovDryRun(context.Background(), "claim", 1); !errors.Is(err, ErrExpansionDisabled) {
t.Fatalf("u11: %v", err)
}
if err := RunControlDryRun(context.Background(), "run_cancel"); !errors.Is(err, ErrExpansionDisabled) {
t.Fatalf("u12: %v", err)
}
}
func TestPU8ExpansionEnablePaths(t *testing.T) {
SetFeatureFlagsForTest(FeatureFlags{
PlanTier: TierLegacy, U9Segment: true, U10Mutate: true, U11DocGov: true, U12RunControl: true,
})
defer ResetFeatureFlagsForTest()
p, err := ProposeSegments(context.Background(), "hello")
if err != nil || p == nil || p.SchemaVersion != "u9-segment-v1" {
t.Fatalf("u9 on: %v %+v", err, p)
}
if _, err := ProposeSegments(context.Background(), ""); err == nil {
t.Fatal("u9 empty must fail closed")
}
if err := MutateDryRun(context.Background(), "edit", 2); err != nil {
t.Fatal(err)
}
if err := DocGovDryRun(context.Background(), "submit", 3); err != nil {
t.Fatal(err)
}
if err := RunControlDryRun(context.Background(), "run_resume"); err != nil {
t.Fatal(err)
}
}
+20 -1
View File
@@ -20,6 +20,11 @@ const (
type FeatureFlags struct {
PlanTier PlanTier
// Independent PU8 expansion gates. Default OFF; do not couple to PlanTier.
U9Segment bool // MULTI_INTENT_U9_SEGMENT — LLM segment proposal
U10Mutate bool // MULTI_INTENT_U10_MUTATE — low/medium mutate adapters
U11DocGov bool // MULTI_INTENT_U11_DOCGOV — docgov action adapters
U12RunControl bool // MULTI_INTENT_U12_RUN_CONTROL — workflow/run-control adapters
}
var (
@@ -28,7 +33,21 @@ var (
)
func defaultFeatureFlags() FeatureFlags {
return FeatureFlags{PlanTier: parsePlanTier(os.Getenv("MULTI_INTENT_PLAN_TIER"))}
return FeatureFlags{
PlanTier: parsePlanTier(os.Getenv("MULTI_INTENT_PLAN_TIER")),
U9Segment: envBool("MULTI_INTENT_U9_SEGMENT", false),
U10Mutate: envBool("MULTI_INTENT_U10_MUTATE", false),
U11DocGov: envBool("MULTI_INTENT_U11_DOCGOV", false),
U12RunControl: envBool("MULTI_INTENT_U12_RUN_CONTROL", false),
}
}
func envBool(key string, def bool) bool {
v := strings.TrimSpace(os.Getenv(key))
if v == "" {
return def
}
return v == "1" || strings.EqualFold(v, "true") || strings.EqualFold(v, "yes")
}
func parsePlanTier(raw string) PlanTier {
+12
View File
@@ -27,6 +27,18 @@ func TestPlanTierIndependentOfLegacyMultiIntentFlag(t *testing.T) {
}
}
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")