molecule-core/docs/architecture/event-log.md
Hongming Wang 24fec62d7f initial commit — Molecule AI platform
Forked clean from public hackathon repo (Starfire-AgentTeam, BSL 1.1)
with full rebrand to Molecule AI under github.com/Molecule-AI/molecule-monorepo.

Brand: Starfire → Molecule AI.
Slug: starfire / agent-molecule → molecule.
Env vars: STARFIRE_* → MOLECULE_*.
Go module: github.com/agent-molecule/platform → github.com/Molecule-AI/molecule-monorepo/platform.
Python packages: starfire_plugin → molecule_plugin, starfire_agent → molecule_agent.
DB: agentmolecule → molecule.

History truncated; see public repo for prior commits and contributor
attribution. Verified green: go test -race ./... (platform), pytest
(workspace-template 1129 + sdk 132), vitest (canvas 352), build (mcp).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 11:55:37 -07:00

4.3 KiB

Event Log

Every structural change appends an immutable row to structure_events. The table is append-only — rows are never updated or deleted. This is the event sourcing pattern.

How It Works

The workspaces table is a projection of these events — it represents current state. If you replay all events from the beginning, you get the same workspaces table.

Event Types

The rule: structural changes are persisted, presentational changes are ephemeral.

The test: "If I replayed all structure_events from scratch, would I reconstruct a fully working system?" If yes, the event log is complete. Canvas positions don't affect system behavior — they belong in canvas_layouts, not structure_events.

Persisted to structure_events (AND broadcast via WebSocket)

WORKSPACE_PROVISIONING       workspace being created
WORKSPACE_PROVISION_FAILED   launch error — needs audit trail
WORKSPACE_ONLINE             availability change
WORKSPACE_OFFLINE            availability change
WORKSPACE_DEGRADED           health change
WORKSPACE_REMOVED            permanent change
WORKSPACE_MOVED              hierarchy change (different parent, NOT canvas drag)
WORKSPACE_EXPANDED           hierarchy change
WORKSPACE_COLLAPSED          hierarchy change
AGENT_ASSIGNED               agent change
AGENT_REMOVED                agent change
AGENT_REPLACED               agent change
AGENT_MOVED                  agent moved between workspaces
AGENT_CARD_UPDATED           capabilities changed

WebSocket only, NOT persisted to structure_events

TASK_UPDATED                 current task changed — saved to workspaces.current_task
ACTIVITY_LOGGED              activity log created — saved to activity_logs table
Canvas node dragged          presentational — saved to canvas_layouts
Canvas viewport changed      presentational — saved to canvas_viewport
Node collapsed/expanded      presentational UI toggle — saved to canvas_layouts
  (different from WORKSPACE_EXPANDED which is a structural team expansion)

TASK_UPDATED and ACTIVITY_LOGGED use BroadcastOnly() — they are sent over WebSocket but not recorded in structure_events. They have their own storage: workspaces.current_task column and activity_logs table respectively. This separation keeps structure_events focused on structural changes that define the org chart, while operational activity (A2A communications, task updates, agent logs) lives in activity_logs with its own retention policy.

WORKSPACE_MOVED is the nuanced case: a workspace moved to a different parent (hierarchy change) is structural and persisted. A node dragged to a new canvas position is presentational and saved to canvas_layouts only.

See WebSocket Events for the full JSON payload of each event type.

Why This Matters

  1. Complete audit trail — you always know exactly what happened and when
  2. Meaningful responses for removed workspaces — other workspaces can get context when querying a workspace that no longer exists
  3. Canvas timeline — the canvas can show a timeline of changes for any workspace
  4. Easier debugging — debugging distributed agent systems becomes much easier with a full history
  5. Future: time travel — replay to any point in time ("what did our org chart look like last Tuesday?")

Schema

CREATE TABLE structure_events (
  id            UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  event_type    TEXT NOT NULL,
  workspace_id  UUID,
  agent_id      UUID,
  target_id     UUID,
  payload       JSONB,
  created_at    TIMESTAMPTZ DEFAULT now()
);

The payload JSONB field contains event-specific data (e.g. the old and new URL for a workspace move, the reason for a deletion).

Rules

  • Never UPDATE or DELETE rows in structure_events. It is append-only.
  • The workspaces table is the mutable projection — update that instead.
  • Every state change must produce an event before updating the projection.