ledger

package
v0.0.0-...-98f5679 Latest Latest
Warning

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

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package ledger is the durable, agentcore-free record of everything an agent does. It is jess's detective control: over a remote channel the operator loses the ability to watch output, so the ledger stands in. Tool requests are recorded even when the gate denies them, so blocked (possibly rogue) attempts stay visible instead of vanishing.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewEventID

func NewEventID() ulid.ULID

NewEventID mints a fresh, monotonically increasing time-ordered id.

Types

type Action

type Action struct {
	Intent   Event
	Result   Event
	Evidence []Ref
}

Action is one effectful invocation: its committed intent (target + verdict + embedded why), its result, and the evidence it rested on. Intent and Result pair by CallID.

type Chain

type Chain struct {
	Request   Event
	Available []Ref
	Actions   []Action
}

Chain is one run reconstructed as the triad. Read backward it answers "why".

func AssembleChain

func AssembleChain(events []Event) Chain

AssembleChain reconstructs the triad from a single run's events. Intent (KindAction) and Result (KindToolResult with the same CallID) pair into one Action; KindToolResult events with no matching action are safe-tool reads and land in Available; KindRetrieved refs also land in Available.

type DiscardSink

type DiscardSink struct{}

DiscardSink drops every Event. Turning recording off is explicit (pass this to jess.WithLedger), never silent.

func (DiscardSink) Record

func (DiscardSink) Record(Event) error

Record satisfies Sink.

type DurableSink

type DurableSink interface {
	Sink
	CommitAction(Event) error
}

DurableSink is a Sink that can durably commit an action record. CommitAction returns nil only when the event is persisted (e.g. written to SQLite). The gate/middleware require a DurableSink before allowing a non-safe tool: no durable record, no action. Plain Sinks (DiscardSink, JSONLSink) are observation-only.

type Event

type Event struct {
	EventID    ulid.ULID       `json:"event_id"`
	RunID      string          `json:"run_id,omitempty"`
	CallID     string          `json:"call_id,omitempty"`
	Refs       []Ref           `json:"refs,omitempty"`
	Time       time.Time       `json:"time"`
	AgentPath  string          `json:"agent_path,omitempty"`
	Kind       Kind            `json:"kind"`
	Tool       string          `json:"tool,omitempty"`
	Label      string          `json:"label,omitempty"`
	Preview    string          `json:"preview,omitempty"`
	Args       json.RawMessage `json:"args,omitempty"`
	Verdict    Verdict         `json:"verdict,omitempty"`
	Reason     string          `json:"reason,omitempty"`
	Result     json.RawMessage `json:"result,omitempty"`
	Err        string          `json:"err,omitempty"`
	DurationMS int64           `json:"duration_ms,omitempty"`
}

Event is one recorded action. Fields are populated per Kind; zero values are fine for fields that do not apply.

type EventID

type EventID = ulid.ULID

EventID is a ULID: time-ordered, globally unique, the ledger primary key.

type JSONLSink

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

JSONLSink appends each Event as one JSON line to a file. Durable and crash-evident: a partial last line is the only possible corruption.

func NewJSONLSink

func NewJSONLSink(path string) (*JSONLSink, error)

NewJSONLSink opens (creating, append mode) the file at path.

func (*JSONLSink) Close

func (s *JSONLSink) Close() error

Close flushes and closes the underlying file.

func (*JSONLSink) Record

func (s *JSONLSink) Record(ev Event) error

Record appends ev and flushes so the line is durable before returning.

type Kind

type Kind string

Kind classifies an audit Event.

const (
	KindPrompt        Kind = "prompt"
	KindModelResponse Kind = "model_response"
	KindToolRequest   Kind = "tool_request"
	KindGateDecision  Kind = "gate_decision"
	KindToolResult    Kind = "tool_result"
	KindAbort         Kind = "abort"
	KindRunEnd        Kind = "run_end"
	KindRequest       Kind = "request"   // chain head: the run input
	KindRetrieved     Kind = "retrieved" // memory recall, by ref
	KindAction        Kind = "action"    // atomic intent + gate verdict, committed before execution
)

type Postgres

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

Postgres is the durable provenance ledger backed by PostgreSQL: DurableSink + Reader over a shared server, for deployments where the ledger must outlive any single host or process. Same write contract as SQLite: plain INSERT, duplicate ids error, actions must be self-explaining before they persist.

func NewPostgres

func NewPostgres(db *sql.DB) (*Postgres, error)

NewPostgres wraps a caller-owned pool (callers sharing the database with e.g. a job queue keep one pool and one transaction domain) and ensures the schema. Close on the returned Postgres closes the pool.

func OpenPostgres

func OpenPostgres(dsn string) (*Postgres, error)

OpenPostgres connects to dsn, verifies the connection and ensures the schema.

func (*Postgres) Chain

func (p *Postgres) Chain(runID string) (Chain, error)

Chain reads one run's events ordered by time then id and assembles the triad. Implements Reader.

func (*Postgres) Close

func (p *Postgres) Close() error

Close releases the underlying pool.

func (*Postgres) CommitAction

func (p *Postgres) CommitAction(e Event) error

CommitAction is the durable write path. It validates that the action is self-explaining before persisting; a record that could only say "an action happened" is rejected, so the caller denies rather than store junk. Implements DurableSink.

func (*Postgres) Get

func (p *Postgres) Get(id EventID) (Event, error)

Get resolves one event by id. Implements Reader.

func (*Postgres) Record

func (p *Postgres) Record(e Event) error

Record is the best-effort write path (observation). Implements Sink.

type Reader

type Reader interface {
	Get(id EventID) (Event, error)
	Chain(runID string) (Chain, error)
}

Reader is the read side of a ledger. Both methods are index-backed, never a scan.

type Ref

type Ref struct {
	Source RefSource `json:"source"`
	ID     string    `json:"id"`
	Hash   string    `json:"hash"`
}

Ref addresses an available item by id plus a content hash captured at decision time, so drift or deletion is detectable. Refs, not copies.

type RefSource

type RefSource string

RefSource names what a Ref points at, so resolution never guesses from id shape.

const (
	RefTool   RefSource = "tool"   // ID is a ledger EventID
	RefMemory RefSource = "memory" // ID is a memory.Entry.ID
)

type Resolver

type Resolver interface {
	CurrentHash(source RefSource, id string) (hash string, ok bool)
}

Resolver resolves the current content hash of a referenced item, for drift detection. ok is false when the id is unknown (deleted) or unresolvable.

type SQLite

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

SQLite is the durable provenance ledger: DurableSink + Reader over a local SQLite file (modernc, pure-Go, no CGO).

func OpenSQLite

func OpenSQLite(path string) (*SQLite, error)

OpenSQLite opens (creating) the ledger at path.

func (*SQLite) Chain

func (s *SQLite) Chain(runID string) (Chain, error)

Chain reads one run's events ordered by time then id and assembles the triad. Implements Reader.

func (*SQLite) Close

func (s *SQLite) Close() error

Close releases the underlying database handle.

func (*SQLite) CommitAction

func (s *SQLite) CommitAction(e Event) error

CommitAction is the durable write path. It validates that the action is self-explaining before persisting; a record that could only say "an action happened" is rejected, so the caller denies rather than store junk. Implements DurableSink.

func (*SQLite) Get

func (s *SQLite) Get(id EventID) (Event, error)

Get resolves one event by id. Implements Reader.

func (*SQLite) Record

func (s *SQLite) Record(e Event) error

Record is the best-effort write path (observation). Implements Sink.

type Sink

type Sink interface {
	Record(Event) error
}

Sink receives audit Events. Implementations must be safe for concurrent use.

type Verdict

type Verdict string

Verdict is the gate outcome recorded on a gate_decision Event.

const (
	VerdictAllowed       Verdict = "allowed"
	VerdictDenied        Verdict = "denied"
	VerdictNeedsApproval Verdict = "needs_approval"
)

Jump to

Keyboard shortcuts

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