package taskloop import ( "bufio" "fmt" "os" "path/filepath" "regexp" "sort" "strings" "testing" ) const goPlanValidatorCommand = "go run ./apps/agent/cmd/agent task-loop validate-plan --workspace " var cutoverStaticOwnershipDocuments = []string{ "agent-ops/skills/common/plan/SKILL.md", "agent-ops/skills/common/code-review/SKILL.md", "agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md", "agent-ops/rules/project/domain/testing/rules.md", "agent-ops/rules/project/rules.md", } var cutoverProductionRoots = []string{ "agent-ops/skills/common", "agent-ops/skills/project", "agent-ops/rules", } func TestCutoverProductionOwnershipHasNoReferenceCallerOrStaticRouteTable(t *testing.T) { root := repoRoot(t) if err := validateCutoverProductionOwnership(root); err != nil { t.Fatal(err) } } func TestCutoverProductionOwnershipRejectsInjectedPythonCaller(t *testing.T) { root := t.TempDir() for _, relativeRoot := range cutoverProductionRoots { if err := os.MkdirAll(filepath.Join(root, relativeRoot), 0700); err != nil { t.Fatal(err) } } for _, relative := range cutoverStaticOwnershipDocuments { contents := "" if relative == "agent-ops/skills/common/plan/SKILL.md" || relative == "agent-ops/skills/common/code-review/SKILL.md" { contents = goPlanValidatorCommand } path := filepath.Join(root, relative) if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { t.Fatal(err) } if err := os.WriteFile(path, []byte(contents), 0600); err != nil { t.Fatal(err) } } relative := "agent-ops/skills/common/other/SKILL.md" path := filepath.Join(root, relative) if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil { t.Fatal(err) } if err := os.WriteFile(path, []byte("python3 dispatch.py --validate-plan candidate\n"), 0600); err != nil { t.Fatal(err) } err := validateCutoverProductionOwnership(root) if err == nil || !strings.Contains(err.Error(), "matches") || !strings.Contains(err.Error(), ":1") { t.Fatalf("validateCutoverProductionOwnership error = %v", err) } } func TestCutoverNodeRemainsSharedRuntimeConsumer(t *testing.T) { root := repoRoot(t) patterns := []*regexp.Regexp{ regexp.MustCompile(`agenttask\.NewManager\(`), regexp.MustCompile(`taskloop\.New\(`), regexp.MustCompile(`NewProvider\(`), } err := filepath.WalkDir(filepath.Join(root, "apps", "node"), func(path string, entry os.DirEntry, walkErr error) error { if walkErr != nil { return walkErr } if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") || strings.HasSuffix(entry.Name(), "_test.go") { return nil } assertNoPatterns(t, path, patterns) return nil }) if err != nil { t.Fatal(err) } } func assertNoPatterns(t *testing.T, path string, patterns []*regexp.Regexp) { t.Helper() file, err := os.Open(path) if err != nil { t.Fatal(err) } defer file.Close() scanner := bufio.NewScanner(file) line := 0 for scanner.Scan() { line++ for _, pattern := range patterns { if pattern.MatchString(scanner.Text()) { t.Fatalf("cutover ownership violation %s:%d matches %q", path, line, pattern.String()) } } } if err := scanner.Err(); err != nil { t.Fatal(err) } } func validateCutoverProductionOwnership(root string) error { callerPatterns := []*regexp.Regexp{ regexp.MustCompile(`dispatch\.py`), regexp.MustCompile(`python3 .*orchestrate-agent-task-loop`), } staticOwnershipPatterns := []*regexp.Regexp{ regexp.MustCompile(`gpt-5\.6`), regexp.MustCompile(`claude-opus`), regexp.MustCompile(`Gemini`), regexp.MustCompile(`ornith`), regexp.MustCompile(`laguna`), } documents, err := discoverCutoverProductionDocuments(root) if err != nil { return err } for _, relative := range documents { path := filepath.Join(root, relative) if err := noPatternViolation(path, callerPatterns); err != nil { return err } } for _, relative := range cutoverStaticOwnershipDocuments { path := filepath.Join(root, relative) if err := noPatternViolation(path, staticOwnershipPatterns); err != nil { return err } if relative == "agent-ops/skills/common/plan/SKILL.md" || relative == "agent-ops/skills/common/code-review/SKILL.md" { contents, err := os.ReadFile(path) if err != nil { return err } if !strings.Contains(string(contents), goPlanValidatorCommand) { return fmt.Errorf("cutover ownership violation %s lacks %q", path, goPlanValidatorCommand) } } } return nil } func discoverCutoverProductionDocuments(root string) ([]string, error) { var documents []string for _, relativeRoot := range cutoverProductionRoots { directory := filepath.Join(root, filepath.FromSlash(relativeRoot)) err := filepath.WalkDir(directory, func(path string, entry os.DirEntry, walkErr error) error { if walkErr != nil { return walkErr } if entry.IsDir() { relative, err := filepath.Rel(root, path) if err != nil { return err } relative = filepath.ToSlash(relative) if entry.Name() == "tests" || strings.HasPrefix(entry.Name(), ".") || relative == "agent-ops/skills/project/orchestrate-agent-task-loop/scripts" { return filepath.SkipDir } return nil } if !entry.Type().IsRegular() { return nil } relative, err := filepath.Rel(root, path) if err != nil { return err } documents = append(documents, filepath.ToSlash(relative)) return nil }) if err != nil { return nil, err } } sort.Strings(documents) return documents, nil } func noPatternViolation(path string, patterns []*regexp.Regexp) error { file, err := os.Open(path) if err != nil { return err } defer file.Close() scanner := bufio.NewScanner(file) line := 0 for scanner.Scan() { line++ for _, pattern := range patterns { if pattern.MatchString(scanner.Text()) { return fmt.Errorf("cutover ownership violation %s:%d matches %q", path, line, pattern.String()) } } } return scanner.Err() }