feat: add type: event for operational state changes (bd-ecmd)

Adds support for event beads that capture operational state transitions
as immutable records. Events are a new issue type with fields:
- event_kind: namespaced category (patrol.muted, agent.started)
- actor: entity URI who caused the event
- target: entity URI or bead ID affected
- payload: event-specific JSON data

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>

Executed-By: beads/crew/dave
Rig: beads
Role: crew
This commit is contained in:
Steve Yegge
2025-12-30 15:53:50 -08:00
parent 407e75b363
commit 6d292f6a0f
7 changed files with 106 additions and 7 deletions

View File

@@ -100,6 +100,12 @@ type Issue struct {
// ===== Molecule Type Fields (swarm coordination) =====
MolType MolType `json:"mol_type,omitempty"` // Molecule type: swarm|patrol|work (empty = work)
// ===== Event Fields (operational state changes) =====
EventKind string `json:"event_kind,omitempty"` // Namespaced event type: patrol.muted, agent.started
Actor string `json:"actor,omitempty"` // Entity URI who caused this event
Target string `json:"target,omitempty"` // Entity URI or bead ID affected
Payload string `json:"payload,omitempty"` // Event-specific JSON data
}
// ComputeContentHash creates a deterministic hash of the issue's content.
@@ -162,6 +168,12 @@ func (i *Issue) ComputeContentHash() string {
// Molecule type
w.str(string(i.MolType))
// Event fields
w.str(i.EventKind)
w.str(i.Actor)
w.str(i.Target)
w.str(i.Payload)
return fmt.Sprintf("%x", h.Sum(nil))
}
@@ -395,12 +407,13 @@ const (
TypeAgent IssueType = "agent" // Agent identity bead
TypeRole IssueType = "role" // Agent role definition
TypeConvoy IssueType = "convoy" // Cross-project tracking with reactive completion
TypeEvent IssueType = "event" // Operational state change record
)
// IsValid checks if the issue type value is valid
func (t IssueType) IsValid() bool {
switch t {
case TypeBug, TypeFeature, TypeTask, TypeEpic, TypeChore, TypeMessage, TypeMergeRequest, TypeMolecule, TypeGate, TypeAgent, TypeRole, TypeConvoy:
case TypeBug, TypeFeature, TypeTask, TypeEpic, TypeChore, TypeMessage, TypeMergeRequest, TypeMolecule, TypeGate, TypeAgent, TypeRole, TypeConvoy, TypeEvent:
return true
}
return false