Files
weichenandCursor aefb1e45a6 feat(events): register intent.plan contracts and table owners
Freeze the three fact events, intentflow allowlist, and plan table ownership so later units cannot invent producers or write paths outside app/intentflow.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-15 16:20:19 +00:00

135 lines
3.3 KiB
Go

package events
import (
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"chat-agent-system/internal/archtest"
)
func TestAssertLiveConsumersRejectsFAV(t *testing.T) {
if err := AssertLiveConsumers(EventVersionCommitted, []string{ConsumerFAV}); err == nil {
t.Fatal("fav consumer must fail")
}
if err := NewRegistry().Register(ConsumerFAV); err == nil {
t.Fatal("dynamic fav register must fail")
}
}
func TestAssertLiveConsumersRejectsUnknown(t *testing.T) {
if err := AssertLiveConsumers("document.unknown", []string{ConsumerNotify}); err == nil {
t.Fatal("unknown event must fail")
}
if err := NewRegistry().Register("not-a-consumer"); err == nil {
t.Fatal("unknown consumer must fail")
}
}
func TestLiveConsumersOmitsFAV(t *testing.T) {
for _, c := range LiveConsumers(EventVersionCommitted) {
if c == ConsumerFAV {
t.Fatal("fav leaked into live consumers")
}
}
if err := NewRegistry().Register(ConsumerNotify); err != nil {
t.Fatal(err)
}
}
func TestManifestJSONIncludesDisabledFAV(t *testing.T) {
b, err := ManifestJSON()
if err != nil {
t.Fatal(err)
}
if !strings.Contains(string(b), EventFAVArtifactStaged) || !strings.Contains(string(b), `"enabled":false`) {
t.Fatalf("%s", b)
}
}
func TestIntentPlanContractsOmitSensitivePayload(t *testing.T) {
forbidden := []string{"prompt", "slots", "permissions", "result", "input"}
for _, c := range StaticContracts() {
if !strings.HasPrefix(c.EventName, "intent.plan.") {
continue
}
if !c.Enabled {
t.Fatalf("%s must be enabled for U4 append", c.EventName)
}
if !containsName(c.Producers, "app/intentflow") || !containsName(c.Producers, "events") {
t.Fatalf("%s producers = %v", c.EventName, c.Producers)
}
if !containsName(c.Consumers, ConsumerProjection) || !containsName(c.Consumers, ConsumerNotify) {
t.Fatalf("%s consumers = %v", c.EventName, c.Consumers)
}
for _, field := range c.PayloadFields {
for _, bad := range forbidden {
if field == bad {
t.Fatalf("%s payload contains %s", c.EventName, field)
}
}
}
}
}
func TestRegistryParityWithYAML(t *testing.T) {
root := moduleRoot(t)
b, err := archtest.LoadBoundaries(archtest.DefaultBoundariesPath(root))
if err != nil {
t.Fatal(err)
}
got := map[string]Contract{}
for _, c := range StaticContracts() {
got[c.EventName] = c
}
for name, producers := range b.EventProducers {
if name == "outbox.notify" {
continue
}
c, ok := got[name]
if !ok {
t.Fatalf("yaml producer %s missing from StaticContracts", name)
}
for _, p := range producers {
if !containsName(c.Producers, p) {
t.Fatalf("yaml producer %s/%s not in Go contract", name, p)
}
}
}
for name, consumers := range b.EventConsumers {
if name == "outbox.notify" {
continue
}
c, ok := got[name]
if !ok {
t.Fatalf("yaml consumer %s missing from StaticContracts", name)
}
for _, cons := range consumers {
if !containsName(c.Consumers, cons) {
t.Fatalf("yaml consumer %s/%s not in Go contract", name, cons)
}
}
}
}
func moduleRoot(t *testing.T) string {
t.Helper()
_, file, _, ok := runtime.Caller(0)
if !ok {
t.Fatal("caller")
}
dir := filepath.Dir(file)
for {
if _, err := os.Stat(filepath.Join(dir, "go.mod")); err == nil {
return dir
}
parent := filepath.Dir(dir)
if parent == dir {
t.Fatal("go.mod not found")
}
dir = parent
}
}