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>
This commit is contained in:
@@ -65,6 +65,7 @@ imports:
|
||||
- app/docflow
|
||||
- app/docnotify
|
||||
- app/docproject
|
||||
- app/intentflow
|
||||
- app/stageflow
|
||||
- app/uow
|
||||
- artifactvault
|
||||
@@ -113,6 +114,10 @@ imports:
|
||||
- docquery
|
||||
- docrevision
|
||||
- events
|
||||
app/intentflow:
|
||||
- app/uow
|
||||
- events
|
||||
- intent
|
||||
app/uow: []
|
||||
app/stageflow:
|
||||
- bizdev
|
||||
@@ -304,6 +309,12 @@ table_owners:
|
||||
- dataset
|
||||
dataset_destroy_requests:
|
||||
- dataset
|
||||
intent_plans:
|
||||
- app/intentflow
|
||||
intent_plan_steps:
|
||||
- app/intentflow
|
||||
intent_plan_decisions:
|
||||
- app/intentflow
|
||||
|
||||
path_owners:
|
||||
output.md:
|
||||
@@ -348,6 +359,15 @@ event_producers:
|
||||
- taskrun
|
||||
fav.artifact_staged:
|
||||
- app/docflow
|
||||
intent.plan.awaiting_input:
|
||||
- app/intentflow
|
||||
- events
|
||||
intent.plan.step_changed:
|
||||
- app/intentflow
|
||||
- events
|
||||
intent.plan.completed:
|
||||
- app/intentflow
|
||||
- events
|
||||
|
||||
event_consumers:
|
||||
outbox.notify:
|
||||
@@ -371,6 +391,15 @@ event_consumers:
|
||||
- notify
|
||||
fav.artifact_staged:
|
||||
- fav
|
||||
intent.plan.awaiting_input:
|
||||
- projection
|
||||
- notify
|
||||
intent.plan.step_changed:
|
||||
- projection
|
||||
- notify
|
||||
intent.plan.completed:
|
||||
- projection
|
||||
- notify
|
||||
|
||||
unwrap_owners:
|
||||
- docgov
|
||||
@@ -380,6 +409,7 @@ unwrap_owners:
|
||||
- events
|
||||
- artifactvault
|
||||
- ctxmgr
|
||||
- app/intentflow
|
||||
|
||||
exceptions:
|
||||
- kind: sql_write
|
||||
|
||||
@@ -14,8 +14,8 @@ import (
|
||||
const internalPrefix = "chat-agent-system/internal/"
|
||||
|
||||
var (
|
||||
sqlWriteRe = regexp.MustCompile(`(?is)\b(INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+([a-zA-Z_][a-zA-Z0-9_]*)`)
|
||||
eventNameRe = regexp.MustCompile(`document\.[a-z0-9_.]+`)
|
||||
sqlWriteRe = regexp.MustCompile(`(?is)\b(INSERT\s+INTO|UPDATE|DELETE\s+FROM)\s+([a-zA-Z_][a-zA-Z0-9_]*)`)
|
||||
eventNameRe = regexp.MustCompile(`(?:document|intent\.plan)\.[a-z0-9_.]+`)
|
||||
)
|
||||
|
||||
type fileClass int
|
||||
|
||||
@@ -12,14 +12,17 @@ const (
|
||||
ConsumerWorkflowAdvance = "workflow_advance"
|
||||
ConsumerFAV = "fav"
|
||||
|
||||
EventCandidateReady = "document.agent_candidate_ready"
|
||||
EventVersionCommitted = "document.agent_version_committed"
|
||||
EventDownstreamImpact = "document.downstream_impact_detected"
|
||||
EventChangeReportDegraded = "document.change_report_degraded"
|
||||
EventApproved = "document.approved"
|
||||
EventTaskRunCompleted = "taskrun.completed"
|
||||
EventTaskRunCancelled = "taskrun.cancelled"
|
||||
EventFAVArtifactStaged = "fav.artifact_staged"
|
||||
EventCandidateReady = "document.agent_candidate_ready"
|
||||
EventVersionCommitted = "document.agent_version_committed"
|
||||
EventDownstreamImpact = "document.downstream_impact_detected"
|
||||
EventChangeReportDegraded = "document.change_report_degraded"
|
||||
EventApproved = "document.approved"
|
||||
EventTaskRunCompleted = "taskrun.completed"
|
||||
EventTaskRunCancelled = "taskrun.cancelled"
|
||||
EventFAVArtifactStaged = "fav.artifact_staged"
|
||||
EventIntentPlanAwaiting = "intent.plan.awaiting_input"
|
||||
EventIntentPlanStepChanged = "intent.plan.step_changed"
|
||||
EventIntentPlanCompleted = "intent.plan.completed"
|
||||
)
|
||||
|
||||
// Contract is the static allowlist row for one event name.
|
||||
@@ -44,6 +47,9 @@ func StaticContracts() []Contract {
|
||||
{EventName: EventTaskRunCompleted, SchemaVersion: 1, Enabled: true, Producers: []string{"taskrun"}, Consumers: []string{ConsumerNotify}, PayloadFields: []string{"run_id"}},
|
||||
{EventName: EventTaskRunCancelled, SchemaVersion: 1, Enabled: true, Producers: []string{"taskrun"}, Consumers: []string{ConsumerNotify}, PayloadFields: []string{"run_id"}},
|
||||
{EventName: EventFAVArtifactStaged, SchemaVersion: 1, Enabled: false, Producers: []string{"app/docflow"}, Consumers: []string{ConsumerFAV}, PayloadFields: []string{"doc_id", "snapshot_id"}},
|
||||
{EventName: EventIntentPlanAwaiting, SchemaVersion: 1, Enabled: true, Producers: []string{"app/intentflow", "events"}, Consumers: []string{ConsumerProjection, ConsumerNotify}, PayloadFields: []string{"plan_id", "revision", "status", "environment", "project_id", "user_id", "session_id", "summary_ref"}},
|
||||
{EventName: EventIntentPlanStepChanged, SchemaVersion: 1, Enabled: true, Producers: []string{"app/intentflow", "events"}, Consumers: []string{ConsumerProjection, ConsumerNotify}, PayloadFields: []string{"plan_id", "revision", "step_id", "status", "environment", "project_id", "user_id", "session_id", "summary_ref"}},
|
||||
{EventName: EventIntentPlanCompleted, SchemaVersion: 1, Enabled: true, Producers: []string{"app/intentflow", "events"}, Consumers: []string{ConsumerProjection, ConsumerNotify}, PayloadFields: []string{"plan_id", "revision", "status", "environment", "project_id", "user_id", "session_id", "summary_ref"}},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,31 @@ func TestManifestJSONIncludesDisabledFAV(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
|
||||
Reference in New Issue
Block a user