Files
Agent-System/internal/workflowdef/keyspace_test.go
T
weichenandCursor dba8139d56 feat(workflow): namespace task keys without breaking old instances
Published manifests now use bd_/pm_/tm_/sw_ prefixes so workflows cannot share a doc id. Frozen instances keep the old keys; lookup, templates, and duty checks treat the two names as the same task.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-19 10:50:25 +00:00

94 lines
2.7 KiB
Go

package workflowdef
import (
"strings"
"testing"
)
func TestSameTaskKey_LegacyAndCanonical(t *testing.T) {
pairs := [][2]string{
{"intake", "bd_intake"},
{"system_reqs", "pm_system_reqs"},
{"test_manager", "tm_system_verification"},
{"software_charter", "sw_software_charter"},
{"change_brief", "sw_change_brief"},
}
for _, pair := range pairs {
if !SameTaskKey(pair[0], pair[1]) {
t.Fatalf("expected %s == %s", pair[0], pair[1])
}
if CanonicalTaskKey(pair[0]) != pair[1] {
t.Fatalf("canonical %s = %s, want %s", pair[0], CanonicalTaskKey(pair[0]), pair[1])
}
if ImplementationTaskKey(pair[1]) != pair[0] {
t.Fatalf("implementation %s = %s, want %s", pair[1], ImplementationTaskKey(pair[1]), pair[0])
}
}
if SameTaskKey("intake", "research") {
t.Fatal("intake and research must stay distinct")
}
if CanonicalTaskKey("rd_proposal") != "rd_proposal" {
t.Fatal("rd_ keys are already namespaced")
}
}
func TestAlternateDocIDs_RoundTrip(t *testing.T) {
alts := AlternateDocIDs("doc_proj56_intake")
if len(alts) != 1 || alts[0] != "doc_proj56_bd_intake" {
t.Fatalf("old id aliases = %v", alts)
}
back := AlternateDocIDs("doc_proj56_bd_intake")
if len(back) != 1 || back[0] != "doc_proj56_intake" {
t.Fatalf("new id aliases = %v", back)
}
if got := AlternateDocIDs("doc_proj56_rd_proposal"); len(got) != 0 {
t.Fatalf("rd_ doc id should not alias, got %v", got)
}
}
func TestPublishedTaskKeysAreNamespacedAndDisjoint(t *testing.T) {
files := map[string]string{
"main.v2.json": "bd_",
"product_manager.v2.json": "pm_",
"test_manager.v2.json": "tm_",
"rdev.v2.json": "rd_",
"software_bootstrap.v2.json": "sw_",
"software_delivery.v2.json": "sw_",
}
seen := map[string]string{}
for file, prefix := range files {
def, err := LoadManifestDefinition(file)
if err != nil {
t.Fatal(err)
}
for _, stage := range def.Stages {
for _, task := range stage.DocTasks {
key := task.Key
if !strings.HasPrefix(key, prefix) {
t.Fatalf("%s task %s missing prefix %s", file, key, prefix)
}
if prev, ok := seen[key]; ok {
t.Fatalf("task key %s intersects %s and %s", key, prev, file)
}
seen[key] = file
if task.OutputDocType != key {
t.Fatalf("%s output_doc_type %s != key %s", file, task.OutputDocType, key)
}
if prefix == "rd_" {
if ImplementationTaskKey(key) != key {
t.Fatalf("rd_ key %s must not alias", key)
}
continue
}
legacy := ImplementationTaskKey(key)
if legacy == key {
t.Fatalf("%s has no legacy alias", key)
}
if CanonicalTaskKey(legacy) != key {
t.Fatalf("legacy %s does not round-trip to %s", legacy, key)
}
}
}
}
}