Add type: event for state transitions (bd-ecmd)

Adds TypeEvent issue type for recording operational state changes as
immutable beads. Events capture:
- event_category: namespaced category (e.g., patrol.muted, agent.started)
- event_actor: entity URI who caused the event
- event_target: entity URI or bead ID affected
- event_payload: event-specific JSON data

Changes:
- Add TypeEvent constant and IsValid() support in types.go
- Add event fields to Issue struct with ComputeContentHash support
- Add --event-category/actor/target/payload flags to bd create
- Add event fields to RPC CreateArgs and UpdateArgs
- Add migration 033_event_fields to add columns to issues table
- Update insertIssue and queries to include event fields
- Fix migrations_test.go for new column requirements

This enables:
- bd activity --follow showing events
- bd list --type=event --target=agent:deacon
- Full audit trail for operational state
- HOP-compatible transaction records

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-30 16:13:39 -08:00
parent aa2c66c4f7
commit 21a0ff6d0d
5 changed files with 109 additions and 65 deletions

View File

@@ -102,6 +102,11 @@ type CreateArgs struct {
// Agent identity fields (only valid when IssueType == "agent")
RoleType string `json:"role_type,omitempty"` // polecat|crew|witness|refinery|mayor|deacon
Rig string `json:"rig,omitempty"` // Rig name (empty for town-level agents)
// Event fields (only valid when IssueType == "event")
EventCategory string `json:"event_category,omitempty"` // Namespaced category (e.g., patrol.muted, agent.started)
EventActor string `json:"event_actor,omitempty"` // Entity URI who caused this event
EventTarget string `json:"event_target,omitempty"` // Entity URI or bead ID affected
EventPayload string `json:"event_payload,omitempty"` // Event-specific JSON data
}
// UpdateArgs represents arguments for the update operation
@@ -142,6 +147,11 @@ type UpdateArgs struct {
// Agent identity fields
RoleType *string `json:"role_type,omitempty"` // polecat|crew|witness|refinery|mayor|deacon
Rig *string `json:"rig,omitempty"` // Rig name (empty for town-level agents)
// Event fields (only valid when IssueType == "event")
EventCategory *string `json:"event_category,omitempty"` // Namespaced category (e.g., patrol.muted, agent.started)
EventActor *string `json:"event_actor,omitempty"` // Entity URI who caused this event
EventTarget *string `json:"event_target,omitempty"` // Entity URI or bead ID affected
EventPayload *string `json:"event_payload,omitempty"` // Event-specific JSON data
}
// CloseArgs represents arguments for the close operation

View File

@@ -122,6 +122,19 @@ func updatesFromArgs(a UpdateArgs) map[string]interface{} {
if a.Rig != nil {
u["rig"] = *a.Rig
}
// Event fields
if a.EventCategory != nil {
u["event_category"] = *a.EventCategory
}
if a.EventActor != nil {
u["event_actor"] = *a.EventActor
}
if a.EventTarget != nil {
u["event_target"] = *a.EventTarget
}
if a.EventPayload != nil {
u["event_payload"] = *a.EventPayload
}
return u
}
@@ -208,6 +221,11 @@ func (s *Server) handleCreate(req *Request) Response {
// Agent identity fields
RoleType: createArgs.RoleType,
Rig: createArgs.Rig,
// Event fields (map protocol names to internal names)
EventKind: createArgs.EventCategory,
Actor: createArgs.EventActor,
Target: createArgs.EventTarget,
Payload: createArgs.EventPayload,
}
// Check if any dependencies are discovered-from type