events

package
v0.629.4 Latest Latest
Warning

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

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package events provides a durable, append-only log of delegation signals with cursor-based, at-least-once delivery.

Pando's delegation feedback loop (Case A live injection, Case B resurrection) is driven by an in-memory completion bus whose sends are non-blocking: a slow or full subscriber silently drops the event, and a restart loses every signal that had not been consumed yet. This log is the durable counterpart, mirroring Hermes Kanban Swarm's task_events table plus its cursor-advanced notifier:

  • Every terminal task outcome (and the integrity signals around it) is appended to a JSONL file before it is broadcast.
  • A consumer identified by a subscription id reads its Unseen events in order and Acks them once handled, which persists its cursor.
  • An event that was never acked is redelivered — after a crash, a restart, or a dropped in-memory broadcast — so delivery is at-least-once and consumers stay responsible for their own idempotency.

The log deliberately stores only identifiers and a short summary, never the whole task: consumers re-read the task from the store, so a replayed event can never resurrect a stale snapshot of it.

Index

Constants

View Source
const DefaultMaxEntries = 5000

DefaultMaxEntries bounds the retained log. The file is compacted once it grows past twice this many events.

Variables

This section is empty.

Functions

This section is empty.

Types

type Event

type Event struct {
	Seq             int64  `json:"seq"`
	Kind            Kind   `json:"kind"`
	TaskID          string `json:"task_id"`
	ParentSessionID string `json:"parent_session_id,omitempty"`
	CorrelationID   string `json:"correlation_id,omitempty"`
	// Detail is a short human-readable note (conclusion summary, refusal reason,
	// gate dependency id). It exists for logs and UIs, never for control flow.
	Detail    string    `json:"detail,omitempty"`
	CreatedAt time.Time `json:"created_at"`
}

Event is one durable delegation signal. Seq is assigned by the log and is strictly increasing across the log's lifetime; consumers use it as their cursor. The payload is intentionally minimal — enough to route and explain the signal without duplicating task state that may since have changed.

type Kind

type Kind string

Kind classifies a delegation signal.

const (
	// KindCompleted / KindFailed / KindCancelled are the terminal task outcomes.
	// They are the events the delegation supervisor acts on.
	KindCompleted Kind = "completed"
	KindFailed    Kind = "failed"
	KindCancelled Kind = "cancelled"
	// KindGateFailed records a dependent task held pending because a gate
	// dependency completed without passing its conclusion gate.
	KindGateFailed Kind = "gate_failed"
	// KindBreakerTripped records a task that reached the consecutive-failure
	// limit and can no longer be respawned without a fix or an explicit force.
	KindBreakerTripped Kind = "breaker_tripped"
	// KindRespawnRefused records a Relaunch/Retry denied by the respawn guard.
	KindRespawnRefused Kind = "respawn_refused"
	// KindReclaimed records a task whose claim lease expired (or whose worker
	// process died) and that was returned to the dispatchable pool.
	KindReclaimed Kind = "reclaimed"
)

func (Kind) IsTerminal

func (k Kind) IsTerminal() bool

IsTerminal reports whether the kind describes a task reaching a terminal state, i.e. the events a delegation consumer must react to.

type Log

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

Log is a durable append-only event log with per-subscription cursors. A nil *Log is a valid no-op log: every method is nil-safe, so callers can hold a nil pointer when the feature is disabled instead of branching at each call site.

func Open

func Open(path string, maxEntries int) (*Log, error)

Open loads (or creates) the log at path. maxEntries <= 0 uses DefaultMaxEntries. A malformed line is skipped rather than failing the open: an event log must never be the reason the orchestrator cannot start.

func (*Log) Ack

func (l *Log) Ack(subID string, seq int64) error

Ack advances a subscription's cursor to seq (never backwards) and persists it. Acking event N also acks everything before it: events are delivered in order, so a consumer that reaches N has already decided what to do with its predecessors.

func (*Log) Append

func (l *Log) Append(e Event) (Event, error)

Append records an event, assigning it the next sequence number, and returns the stored copy. On a nil log it is a no-op returning the zero Event.

func (*Log) Cursor

func (l *Log) Cursor(subID string) int64

Cursor reports a subscription's acked watermark.

func (*Log) LastSeq

func (l *Log) LastSeq() int64

LastSeq reports the sequence number of the most recently appended event.

func (*Log) Recent

func (l *Log) Recent(limit int) []Event

Recent returns up to limit of the most recent events, newest last. Intended for inspection surfaces (CLI/UI), not for control flow.

func (*Log) Unseen

func (l *Log) Unseen(subID string) []Event

Unseen returns the events a subscription has not acked yet, oldest first. An unknown subscription starts at the beginning of the retained log, so a consumer that lost its cursor file replays what is still on disk rather than silently skipping it.

Jump to

Keyboard shortcuts

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