gorapide

package module
v0.0.0-...-d1ee73a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 5, 2026 License: MIT Imports: 8 Imported by: 0

README

gorapide

A Go implementation of Stanford Rapide 1.0 causal event-driven architecture semantics.

gorapide models software architectures as collections of concurrent components that communicate through partially ordered event sets (posets). Every event carries a causal history, enabling precise reasoning about happens-before relationships, constraint verification, architecture-level observability, and distributed synchronization.

Installation

go get github.com/ShaneDolphin/gorapide

Requires Go 1.22 or later. The core module has zero external dependencies.

Optional sub-modules with their own go.mod:

  • otelexport/ — live OpenTelemetry trace export (requires go.opentelemetry.io/otel)
  • cmd/rapide-studio/ — visual architecture editor (requires golang.org/x/net)

Quick Start

Build a causal event graph with the fluent builder:

package main

import (
    "fmt"
    "github.com/ShaneDolphin/gorapide"
)

func main() {
    p := gorapide.Build().
        Source("scanner").
        Event("ScanStart").
        Event("VulnFound", "severity", "HIGH").CausedBy("ScanStart").
        Source("aggregator").
        Event("Finding").CausedBy("VulnFound").
        MustDone()

    fmt.Println(p)
    fmt.Println(p.DOT())
}

Package Structure

gorapide/              Core: Event, Poset, Builder, VectorClock, JSON/DOT/Mermaid export
  arch/                Architecture runtime: components, connections, behaviors,
                         Map/Binding, Participant, SubArchitecture, hierarchical constraints
  pattern/             Event Pattern Language: match, sequence, join, independent, timing
  constraint/          Pattern and predicate constraints with runtime checker
  export/              Standalone format helpers (Jaeger JSON, DOT labels, Mermaid nodes)
  dsync/               Distributed poset synchronization: Transport, Coordinator
  studio/              Visual editor backend: schema, reconstruct, recorder, replay
  otelexport/          Live OpenTelemetry span export (separate go.mod)
  cmd/rapide-studio/   Visual architecture editor web application (separate go.mod)
  examples/            Runnable examples

Core API

Events and Posets

An Event is an immutable tuple with a unique ID, name, parameters, source component, and a ClockStamp (Lamport timestamp + wall time + optional vector clock). Events live in a Poset that tracks causal edges.

p := gorapide.NewPoset()

e1 := gorapide.NewEvent("ScanStart", "scanner", nil)
p.AddEvent(e1)

e2 := gorapide.NewEvent("VulnFound", "scanner", map[string]any{"cve": "CVE-2026-0001"})
p.AddEventWithCause(e2, e1.ID)

fmt.Println(p.IsCausallyBefore(e1.ID, e2.ID)) // true
fmt.Println(p.TopologicalSort())                // [ScanStart, VulnFound]
Event Patterns

The pattern package implements the Rapide Event Pattern Language:

import "github.com/ShaneDolphin/gorapide/pattern"

// Match by name with guards
p := pattern.MatchEvent("VulnFound").WhereParam("severity", "CRITICAL")

// Causal sequence
p = pattern.Seq(pattern.MatchEvent("ScanStart"), pattern.MatchEvent("VulnFound"))

// Independence (causally unrelated)
p = pattern.Independent(pattern.MatchEvent("ScanA"), pattern.MatchEvent("ScanB"))

// Join (shared common ancestor)
p = pattern.Join(pattern.MatchEvent("FindingA"), pattern.MatchEvent("FindingB"))

// Timing: events within a duration
p = pattern.Within(pattern.Seq(
    pattern.MatchEvent("Start"), pattern.MatchEvent("End"),
), 5*time.Second)

Also supports: ImmSeq, Or, And, Union, ForEach, Guard, Not, During, After, Before, and pattern macros (causal_chain, fan_in, fan_out).

Constraints

Both pattern-based and predicate-based constraints with runtime checking:

import "github.com/ShaneDolphin/gorapide/constraint"

cs := constraint.NewConstraintSet("pipeline-checks")
cs.Add(constraint.EventCount("VulnFound", 1, 100))
cs.Add(constraint.AllComponentsEmit([]string{"scanner", "aggregator"}))
cs.Add(constraint.CausalDepthMax(10))

// Pattern-based: VulnFound must produce a DocSection
cs.Add(constraint.NewConstraint("completeness").
    Must("vuln_produces_doc",
        pattern.Seq(pattern.MatchEvent("VulnFound"), pattern.MatchEvent("DocSection")),
        "every VulnFound must produce a DocSection").
    Build())

violations, report := cs.CheckAndReport(poset)

Runtime checking modes: CheckAfter (on stop), CheckPeriodic (interval), CheckOnEvent (every N events).

Architecture Runtime

The arch package models running systems with components, connections, and behaviors:

import "github.com/ShaneDolphin/gorapide/arch"

pipeline := arch.NewArchitecture("security-pipeline")

// Define and add components
scannerIface := arch.Interface("Scanner").
    OutAction("VulnFound", arch.P("cve", "string"), arch.P("severity", "string")).
    Build()
scanner := arch.NewComponent("scanner", scannerIface, nil)
pipeline.AddComponent(scanner)

// Register behaviors
scanner.OnEvent("Trigger", func(ctx arch.BehaviorContext) {
    ctx.Emit("VulnFound", map[string]any{"cve": "CVE-2026-0001", "severity": "HIGH"})
})

// Wire connections (Basic, Pipe, or Agent semantics)
conn := arch.Connect("scanner", "aggregator").
    On(pattern.MatchEvent("VulnFound")).
    Pipe().Send("ProcessFinding").
    Build()
pipeline.AddConnection(conn)

// Run
pipeline.Start(context.Background())
pipeline.Inject("Trigger", nil)
time.Sleep(100 * time.Millisecond)
pipeline.Stop()
pipeline.Wait()
Map and Binding Constructs

Maps define cross-architecture event translation rules. Bindings create dynamic runtime wiring.

// Map: translate events between interface vocabularies
m := arch.NewMap("scan_to_agg").
    From(scannerIface).
    To(aggregatorIface).
    TranslateWith("VulnFound", "Finding", func(e *gorapide.Event) map[string]any {
        return map[string]any{"cve": e.ParamString("cve"), "mapped": true}
    }).
    Build()

// Dynamic binding with a Map
pipeline.BindWith("scanner", "aggregator", arch.WithBindingMap(m))

// Simple binding (identity translation, PipeConnection)
pipeline.Bind("scanner", "consumer")

// Remove bindings
pipeline.Unbind("scanner")
Hierarchical Composition

Architectures can nest — a sub-architecture participates as a component in a parent architecture with events flowing across boundaries via export/import rules:

// Inner architecture with its own components
inner := arch.NewArchitecture("inner-pipeline")
worker := arch.NewComponent("worker", workerIface, nil)
inner.AddComponent(worker)

// Wrap as sub-architecture with boundary rules
sub := arch.WrapArchitecture("processing-unit", inner).
    WithInterface(subIface).
    Import("Request", "worker", "Task").                    // parent -> inner
    Export("worker", "Done", "Result").                      // inner -> parent
    ExportWith("worker", "Raw", "Processed", transformFn).   // with param transform
    Build()

parent := arch.NewArchitecture("parent")
parent.AddSubArchitecture(sub)
parent.Start(ctx)

// Hierarchical constraint checking
report := arch.CheckHierarchy(parent)
fmt.Println(report.TotalViolations())

Each architecture level has its own poset — events crossing boundaries create new events in the destination poset, preserving encapsulation.

Distributed Poset Synchronization

Multiple GoRapide instances can synchronize their posets across nodes. The poset is a grow-only CRDT with idempotent merge.

import "github.com/ShaneDolphin/gorapide/dsync"

// Vector clocks for distributed causality
e := gorapide.NewEvent("Scan", "node1", nil)
e.Clock.Vector = gorapide.VectorClock{"node1": 1}

// Create snapshots for exchange
snap := poset.CreateSnapshot("node1")
incrementalSnap := poset.CreateIncrementalSnapshot("node1", lastHighWater)

// Merge remote snapshots (idempotent, deduplicates, buffers pending edges)
result, _ := poset.MergeSnapshot(remoteSnap)
poset.DrainPendingEdges() // resolve edges whose endpoints arrived late

// Automatic sync via Coordinator
net := dsync.NewMemNetwork() // or implement dsync.Transport for gRPC/NATS/HTTP
c := dsync.NewCoordinator("node1", poset, net.Transport("node1"),
    dsync.WithInterval(5*time.Second))
c.AddPeer("node2")
c.Start(ctx)
defer c.Stop()
Live OpenTelemetry Export

Stream poset events as OTLP spans to a collector during execution (separate sub-module):

import "github.com/ShaneDolphin/gorapide/otelexport"

exporter, _ := otelexport.NewLiveExporter(otelexport.Config{
    Endpoint:    "localhost:4317",
    Protocol:    otelexport.GRPC,
    ServiceName: "my-pipeline",
    Insecure:    true,
})
defer exporter.Shutdown(ctx)

pipeline := arch.NewArchitecture("pipeline",
    arch.WithObserver(exporter.OnEvent), // zero-config integration
)

Events become zero-duration OTLP spans. Causal parents map to parent span IDs. Additional causal parents become span links. Batching and backpressure are built in.

Export and Visualization
// JSON round-trip (includes vector clocks when present)
data, _ := json.Marshal(poset)
json.Unmarshal(data, newPoset)

// DOT (Graphviz)
dot := poset.DOTWithOptions(gorapide.DOTOptions{
    ColorBySource:   true,
    ClusterBySource: true,
    ShowTimestamps:  true,
    HighlightPath:   []gorapide.EventID{e1.ID, e2.ID},
})

// Mermaid for markdown
mermaid := poset.Mermaid()

// OpenTelemetry-compatible trace spans
spans := poset.ToTraceSpans()

Visual Architecture Editor

Rapide Studio is a web-based visual tool for designing architectures, running live simulations, and watching events flow in real-time.

cd cmd/rapide-studio
go run . -addr :8400
# Open http://localhost:8400

Features:

  • Drag-and-drop canvas — design architectures visually with Cytoscape.js
  • Component inspector — view and edit component interfaces and connections
  • Live simulation — start/stop simulations, inject events, watch real-time event flow
  • Event feed — scrolling list of all events with names, sources, and parameters
  • WebSocket streaming — events broadcast over WebSocket as they occur

The editor uses an ArchitectureSchema JSON format that can be reconstructed into a live arch.Architecture via studio.Reconstruct().

Running the Example

go run ./examples/ato_scanner/

Five-component ATO security scanning pipeline demonstrating interface definitions, component behaviors, pipe connections, constraint checking, and export formats.

Running Tests

# Core module (8 packages, 462+ tests)
go test -race ./...

# OTel export sub-module
cd otelexport && go test -race ./...

# Visual editor
cd cmd/rapide-studio && go build ./...

Heritage

gorapide implements the semantics described in the Stanford Rapide 1.0 language reference manuals:

  • Poset semantics — partially ordered event sets with causal preorder relation
  • Event patterns — the Event Pattern Language for matching causal structures
  • Architecture composition — components, connections (basic/pipe/agent), behaviors, hierarchical sub-architectures
  • Maps and bindings — cross-architecture event translation and dynamic runtime wiring
  • Constraints — pattern-based and predicate-based constraint checking with runtime modes
  • Distributed synchronization — vector clocks, CRDT-based poset merge, transport abstraction

The original Rapide language was developed at Stanford University by David Luckham's research group for architecture-level modeling and simulation of concurrent systems.

License

MIT

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrEventExists   = errors.New("event already exists in poset")
	ErrEventNotFound = errors.New("event not found in poset")
	ErrCyclicCausal  = errors.New("adding this edge would create a causal cycle")
	ErrNoPath        = errors.New("no causal path exists between events")
	ErrSelfCausal    = errors.New("an event cannot causally precede itself")
)

Functions

This section is empty.

Types

type BindingTarget

type BindingTarget interface {
	Bind(from, to string) error
	Unbind(from string) error
}

BindingTarget is a placeholder interface for future Rapide Binding support. In the Rapide language, Bindings allow different component interfaces to be connected dynamically at runtime. A binding maps event names from one interface to another, enabling modular composition of architectures.

This interface is reserved and will be implemented in a future version.

type CausalStore

type CausalStore interface {
	AddEdge(from, to EventID) error
	DirectPredecessors(id EventID) []EventID
	DirectSuccessors(id EventID) []EventID
	HasPath(from, to EventID) bool // transitive reachability
}

CausalStore defines the interface for storing and querying causal edges.

type ClockStamp

type ClockStamp struct {
	Lamport  uint64      // Logical Lamport timestamp for causal ordering
	WallTime time.Time   // Wall clock time for temporal ordering
	Vector   VectorClock // Optional vector clock for distributed mode (nil = single-node)
}

ClockStamp holds both logical and physical time for an event.

func (ClockStamp) Before

func (c ClockStamp) Before(other ClockStamp) bool

Before reports whether this ClockStamp is causally before other, using Lamport ordering.

type DOTOptions

type DOTOptions struct {
	ColorBySource   bool      // different colors per component
	ShowParams      bool      // include param values in labels
	ShowTimestamps  bool      // include Lamport timestamps
	HighlightPath   []EventID // highlight a specific causal path
	ClusterBySource bool      // group nodes by source component in subgraphs
}

DOTOptions configures the DOT export.

type Event

type Event struct {
	ID        EventID
	Name      string
	Params    map[string]any
	Clock     ClockStamp
	Source    string
	Immutable bool
}

Event is the atomic unit of the gorapide system. An Event is an immutable, uniquely identifiable tuple of values that exists within causal and temporal ordering relations.

func NewEvent

func NewEvent(name string, source string, params map[string]any) *Event

NewEvent creates a new Event with an auto-generated ID and WallTime set to now. Lamport starts at 0.

func (*Event) Freeze

func (e *Event) Freeze()

Freeze marks the event as immutable. Once frozen, the Params map should not be modified. Freeze replaces the internal Params map with a defensive copy to discourage further mutation.

func (*Event) Param

func (e *Event) Param(key string) (any, bool)

Param retrieves a parameter value by key. Returns the value and whether the key was present.

func (*Event) ParamInt

func (e *Event) ParamInt(key string) int

ParamInt returns the int value of a parameter, or 0 if the key is missing or not an int.

func (*Event) ParamString

func (e *Event) ParamString(key string) string

ParamString returns the string value of a parameter, or "" if the key is missing or not a string.

func (*Event) String

func (e *Event) String() string

String returns a human-readable representation of the event. Format: "EventName(key=val, ...) @source [id:short]"

type EventExport

type EventExport struct {
	ID          string            `json:"id"`
	Name        string            `json:"name"`
	Params      map[string]any    `json:"params"`
	Source      string            `json:"source"`
	Lamport     uint64            `json:"lamport"`
	WallTime    string            `json:"wall_time"`
	VectorClock map[string]uint64 `json:"vector_clock,omitempty"`
}

EventExport is the JSON-serializable representation of an Event.

type EventID

type EventID string

EventID is a unique identifier for an event, represented as a UUID string.

func NewEventID

func NewEventID() EventID

NewEventID generates a new random UUID-based EventID using crypto/rand.

func (EventID) Short

func (id EventID) Short() string

Short returns a truncated form of the EventID for display purposes.

type EventSet

type EventSet []*Event

EventSet is an ordered collection of events with helper methods.

func (EventSet) Contains

func (es EventSet) Contains(id EventID) bool

Contains reports whether the set contains an event with the given ID.

func (EventSet) Filter

func (es EventSet) Filter(fn func(*Event) bool) EventSet

Filter returns a new EventSet containing only events for which fn returns true.

func (EventSet) IDs

func (es EventSet) IDs() []EventID

IDs returns the EventIDs of all events in the set.

func (EventSet) Names

func (es EventSet) Names() []string

Names returns the names of all events in the set.

type EventStore

type EventStore interface {
	Add(e *Event) error
	Get(id EventID) (*Event, bool)
	All() EventSet
	ByName(name string) EventSet
	Len() int
}

EventStore defines the interface for storing and retrieving events.

type MapTarget

type MapTarget interface {
	MapEvent(source *Event) ([]*Event, error)
}

MapTarget is a placeholder interface for future Rapide Map support. In the Rapide language, Maps define relationships between architectures, translating events from one architecture's vocabulary into another's. A MapTarget transforms a source event into zero or more target events, enabling cross-architecture event translation and composition.

This interface is reserved and will be implemented in a future version.

type MergeResult

type MergeResult struct {
	EventsAdded   int
	EventsSkipped int
	EdgesAdded    int
	EdgesSkipped  int
	EdgesPending  int
}

MergeResult summarizes the outcome of merging a Snapshot into a Poset.

type NodeID

type NodeID string

NodeID identifies a node in a distributed GoRapide cluster.

type PendingEdge

type PendingEdge struct {
	From EventID
	To   EventID
}

PendingEdge represents a causal edge whose endpoints may not yet be present in the local poset.

type Poset

type Poset struct {
	// contains filtered or unexported fields
}

Poset is a Partially Ordered Event Set that stores events and their causal and temporal ordering relationships. It is safe for concurrent use.

func NewPoset

func NewPoset() *Poset

NewPoset creates an empty Poset.

func (*Poset) Add

func (p *Poset) Add(e *Event) error

Add implements EventStore. It delegates to AddEvent.

func (*Poset) AddCausal

func (p *Poset) AddCausal(from, to EventID) error

AddCausal establishes that event 'from' causally precedes event 'to'. It validates both events exist, rejects self-edges and cycles, and updates the 'to' event's Lamport timestamp to max(to.Lamport, from.Lamport+1).

func (*Poset) AddEdge

func (p *Poset) AddEdge(from, to EventID) error

AddEdge implements CausalStore. It delegates to AddCausal.

func (*Poset) AddEvent

func (p *Poset) AddEvent(e *Event) error

AddEvent adds an event to the poset, freezes it, and assigns a Lamport timestamp. Returns an error if an event with the same ID already exists.

func (*Poset) AddEventWithCause

func (p *Poset) AddEventWithCause(e *Event, causes ...EventID) error

AddEventWithCause adds an event and establishes causal edges from all specified causes to the new event. This is the primary way events are added during execution.

func (*Poset) All

func (p *Poset) All() EventSet

All implements EventStore. It delegates to Events.

func (*Poset) ByName

func (p *Poset) ByName(name string) EventSet

ByName implements EventStore. It delegates to EventsByName.

func (*Poset) CausalAncestors

func (p *Poset) CausalAncestors(id EventID) EventSet

CausalAncestors returns all transitive causal predecessors of the event.

func (*Poset) CausalChain

func (p *Poset) CausalChain(from, to EventID) (EventSet, error)

CausalChain returns all events on any causal path from 'from' to 'to', including 'from' and 'to' themselves. Returns an error if no causal path exists.

func (*Poset) CausalDescendants

func (p *Poset) CausalDescendants(id EventID) EventSet

CausalDescendants returns all transitive causal successors of the event.

func (*Poset) CreateIncrementalSnapshot

func (p *Poset) CreateIncrementalSnapshot(nodeID NodeID, sinceHighWater uint64) *Snapshot

CreateIncrementalSnapshot builds a Snapshot containing only events with Lamport timestamps >= sinceHighWater, along with edges between those events.

func (*Poset) CreateSnapshot

func (p *Poset) CreateSnapshot(nodeID NodeID) *Snapshot

CreateSnapshot builds a full Snapshot of the current Poset state containing all events and edges.

func (*Poset) DOT

func (p *Poset) DOT() string

DOT exports the poset as a Graphviz DOT format string.

func (*Poset) DOTWithOptions

func (p *Poset) DOTWithOptions(opts DOTOptions) string

DOTWithOptions exports the poset as Graphviz DOT with configurable options.

func (*Poset) DirectCauses

func (p *Poset) DirectCauses(id EventID) EventSet

DirectCauses returns the immediate causal predecessors of the event (one hop back).

func (*Poset) DirectEffects

func (p *Poset) DirectEffects(id EventID) EventSet

DirectEffects returns the immediate causal successors of the event (one hop forward).

func (*Poset) DirectPredecessors

func (p *Poset) DirectPredecessors(id EventID) []EventID

DirectPredecessors implements CausalStore. Returns the EventIDs of immediate causal predecessors.

func (*Poset) DirectSuccessors

func (p *Poset) DirectSuccessors(id EventID) []EventID

DirectSuccessors implements CausalStore. Returns the EventIDs of immediate causal successors.

func (*Poset) DrainPendingEdges

func (p *Poset) DrainPendingEdges() (int, []error)

DrainPendingEdges attempts to resolve all buffered pending edges whose endpoints are now present in the poset. Returns the count of resolved edges and any errors encountered during resolution.

func (*Poset) Event

func (p *Poset) Event(id EventID) (*Event, bool)

Event looks up an event by ID.

func (*Poset) Events

func (p *Poset) Events() EventSet

Events returns a snapshot of all events in the poset.

func (*Poset) EventsByName

func (p *Poset) EventsByName(name string) EventSet

EventsByName returns all events with the given name.

func (*Poset) Get

func (p *Poset) Get(id EventID) (*Event, bool)

Get implements EventStore. It delegates to Event.

func (*Poset) HasPath

func (p *Poset) HasPath(from, to EventID) bool

HasPath implements CausalStore. Reports whether there is a transitive causal path from 'from' to 'to'.

func (*Poset) IsCausallyBefore

func (p *Poset) IsCausallyBefore(a, b EventID) bool

IsCausallyBefore reports whether event a causally precedes event b (transitive).

func (*Poset) IsCausallyIndependent

func (p *Poset) IsCausallyIndependent(a, b EventID) bool

IsCausallyIndependent reports whether neither a <c b nor b <c a.

func (*Poset) Leaves

func (p *Poset) Leaves() EventSet

Leaves returns events with no causal successors.

func (*Poset) Len

func (p *Poset) Len() int

Len returns the number of events in the poset.

func (*Poset) MarshalJSON

func (p *Poset) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler for Poset.

func (*Poset) MergeSnapshot

func (p *Poset) MergeSnapshot(snap *Snapshot) (*MergeResult, error)

MergeSnapshot integrates a remote Snapshot into the local Poset. Events are sorted by Lamport before insertion so that causal ordering is preserved. Duplicate events are skipped. Edges whose endpoints are missing are buffered as pending edges for later resolution.

func (*Poset) Mermaid

func (p *Poset) Mermaid() string

Mermaid exports the poset as a Mermaid flowchart for embedding in markdown.

func (*Poset) PendingEdgeCount

func (p *Poset) PendingEdgeCount() int

PendingEdgeCount returns the number of buffered pending edges.

func (*Poset) Roots

func (p *Poset) Roots() EventSet

Roots returns events with no causal predecessors.

func (*Poset) Stats

func (p *Poset) Stats() PosetStats

Stats returns aggregate statistics about the poset.

func (*Poset) String

func (p *Poset) String() string

String returns a human-readable multi-line summary of the poset.

func (*Poset) ToTraceSpans

func (p *Poset) ToTraceSpans() []TraceSpan

ToTraceSpans converts poset events to OpenTelemetry-compatible trace spans. All spans share the same TraceID. SpanID maps to EventID. ParentID maps to the first direct causal predecessor (lowest Lamport).

func (*Poset) TopologicalSort

func (p *Poset) TopologicalSort() []*Event

TopologicalSort returns events in a valid causal order where every event appears after all of its causal predecessors. Uses Kahn's algorithm.

func (*Poset) UnmarshalJSON

func (p *Poset) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler for Poset.

func (*Poset) Validate

func (p *Poset) Validate() []error

Validate checks internal consistency of the poset and returns any errors found.

type PosetBuilder

type PosetBuilder struct {
	// contains filtered or unexported fields
}

PosetBuilder provides a fluent API for constructing posets concisely.

func Build

func Build() *PosetBuilder

Build creates a new PosetBuilder.

func (*PosetBuilder) CausedBy

func (b *PosetBuilder) CausedBy(names ...string) *PosetBuilder

CausedBy declares that the last added event was caused by the named events. Names refer to previously added events. If multiple events share a name, the most recently added one with that name is used.

func (*PosetBuilder) Done

func (b *PosetBuilder) Done() (*Poset, error)

Done finalizes the builder and returns the constructed Poset.

func (*PosetBuilder) Event

func (b *PosetBuilder) Event(name string, params ...any) *PosetBuilder

Event adds an event with the given name and optional key-value parameter pairs.

func (*PosetBuilder) MustDone

func (b *PosetBuilder) MustDone() *Poset

MustDone finalizes the builder and returns the Poset, panicking on error.

func (*PosetBuilder) Source

func (b *PosetBuilder) Source(component string) *PosetBuilder

Source sets the source component for subsequent events.

type PosetExport

type PosetExport struct {
	Events      []EventExport     `json:"events"`
	CausalEdges [][]string        `json:"causal_edges"`
	Metadata    map[string]string `json:"metadata"`
}

PosetExport is the JSON-serializable representation of a Poset.

type PosetQuerier

type PosetQuerier interface {
	IsCausallyBefore(a, b EventID) bool
	IsCausallyIndependent(a, b EventID) bool
	CausalAncestors(id EventID) EventSet
	CausalDescendants(id EventID) EventSet
	CausalChain(from, to EventID) (EventSet, error)
	Roots() EventSet
	Leaves() EventSet
	TopologicalSort() []*Event
}

PosetQuerier defines read-only causal query operations on a poset.

type PosetReadWriter

type PosetReadWriter interface {
	EventStore
	CausalStore
	PosetQuerier
	AddEventWithCause(e *Event, causes ...EventID) error
	Validate() []error
	Stats() PosetStats
	DOT() string
}

PosetReadWriter combines event storage, causal storage, and query capabilities into a single interface representing a full poset.

type PosetStats

type PosetStats struct {
	EventCount     int
	EdgeCount      int
	RootCount      int
	LeafCount      int
	MaxDepth       int     // longest causal chain
	AvgFanOut      float64 // average number of direct effects per event
	ComponentCount int     // number of distinct Source values
}

PosetStats holds aggregate statistics about a Poset.

type Snapshot

type Snapshot struct {
	NodeID      NodeID        `json:"node_id"`
	Events      []EventExport `json:"events"`
	CausalEdges [][]string    `json:"causal_edges"`
	HighWater   uint64        `json:"high_water"`
}

Snapshot is a serializable representation of a subset of a Poset, used for shipping events between nodes.

type TraceSpan

type TraceSpan struct {
	TraceID    string
	SpanID     string
	ParentID   string
	Name       string
	StartTime  time.Time
	EndTime    time.Time
	Attributes map[string]string
}

TraceSpan represents an OpenTelemetry-compatible trace span derived from a poset event. Causal edges become parent-child span relationships.

type VectorClock

type VectorClock map[NodeID]uint64

VectorClock tracks logical time across multiple nodes. A nil VectorClock indicates single-node mode (backward compatible).

func (VectorClock) Before

func (vc VectorClock) Before(other VectorClock) bool

Before reports whether vc is strictly causally before other. This is true iff for every node k, vc[k] <= other[k], and there exists at least one node k where vc[k] < other[k]. A nil receiver is treated as having all entries equal to 0.

func (VectorClock) Clone

func (vc VectorClock) Clone() VectorClock

Clone returns a deep copy of the VectorClock. A nil receiver returns nil.

func (VectorClock) Concurrent

func (vc VectorClock) Concurrent(other VectorClock) bool

Concurrent reports whether vc and other are causally concurrent, meaning neither is before the other and they are not equal. Two nil/empty vectors are considered equal, not concurrent (returns false).

func (VectorClock) Increment

func (vc VectorClock) Increment(node NodeID) VectorClock

Increment returns a NEW VectorClock with the given node's counter incremented by one. It does not mutate the original.

func (VectorClock) Merge

func (vc VectorClock) Merge(other VectorClock) VectorClock

Merge returns a NEW VectorClock containing the pointwise maximum of vc and other. Neither receiver nor argument is mutated.

Directories

Path Synopsis
Package constraint implements Rapide pattern constraints for verifying acceptable and unacceptable event patterns in a poset.
Package constraint implements Rapide pattern constraints for verifying acceptable and unacceptable event patterns in a poset.
examples
ato_scanner command
Command ato_scanner demonstrates a security scanning pipeline modeled as a Rapide architecture using gorapide.
Command ato_scanner demonstrates a security scanning pipeline modeled as a Rapide architecture using gorapide.
Package export provides format utilities for working with exported poset data.
Package export provides format utilities for working with exported poset data.
Package pattern implements the Rapide Event Pattern Language.
Package pattern implements the Rapide Event Pattern Language.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL