audit

package
v0.1.5 Latest Latest
Warning

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

Go to latest
Published: Aug 19, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

Documentation

Overview

Package audit provides the immutable audit log: Entry, FieldChange, and Log.Write/Query. Every Document Engine and Workflow Engine write shares a single dal.Tx with its audit write — a failed audit write rolls back the data write (TAD §13.1).

See TAD §13 and PRD §29.1 for the full specification. Implemented in Phase 4.

Index

Constants

View Source
const DocType = "audit"

DocType is the pseudo DocType under which the audit table is registered with the DAL. It is not a Registry Document — audit entries are written only by the Document/Workflow Engines and are never exposed as operable documents (TAD §13).

View Source
const TableName = "audit_entries"

TableName is the SQL table backing the DB-backed audit log.

Variables

This section is empty.

Functions

func RequestIDFromContext

func RequestIDFromContext(ctx context.Context) string

RequestIDFromContext extracts the request_id from ctx, or empty string.

func WithAgent

func WithAgent(ctx context.Context, sessionID, prompt string) context.Context

WithAgent marks the context as an agent-initiated request.

func WithRequestID

func WithRequestID(ctx context.Context, requestID string) context.Context

WithRequestID attaches a request_id to the context.

func WriteInTx

func WriteInTx(ctx context.Context, tx dal.Tx, log Log, e Entry) error

WriteInTx writes e inside tx when log implements TxWriter (TAD §13.1), and falls back to the plain Write path for logs that don't participate in the caller's transaction (e.g. InMemoryLog). Engines must call this inside their dal.Tx callback so a failed audit write rolls back the data write.

Types

type DBLog

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

DBLog is the DB-backed audit.Log. It satisfies TAD §13.1 by writing through the caller's dal.Tx (WriteTx), so a failed audit write rolls back the data write; reads and the standalone Write path use the underlying connection.

The backing table is TableName, registered with the DAL under the pseudo DocType (see DocType) at site compile time so tx.Insert resolves it. It is not a Registry Document: audit entries are never exposed as operable documents (TAD §13).

func NewDBLog

func NewDBLog(db *sql.DB, dialect dal.Dialect) *DBLog

NewDBLog creates a DB-backed audit log on the given connection using the active dialect. The table must exist before writes; call EnsureSchema (or let Site.InitAuditLog do it) first.

func (*DBLog) EnsureSchema

func (l *DBLog) EnsureSchema(ctx context.Context) error

EnsureSchema creates the audit table if it does not exist (idempotent).

func (*DBLog) Query

func (l *DBLog) Query(ctx context.Context, f QueryFilter) ([]Entry, error)

Query returns entries matching f, ordered newest first. Since and Limit are applied server-side; the remaining filters are simple equality predicates.

func (*DBLog) Write

func (l *DBLog) Write(ctx context.Context, e Entry) error

Write records e as a standalone (autocommit) write. Engines use WriteTx inside their transaction; this path exists for direct Log callers that do not have a transaction (TAD §13.1 only applies to Engine writes).

func (*DBLog) WriteTx

func (l *DBLog) WriteTx(ctx context.Context, tx dal.Tx, e Entry) error

WriteTx records e inside tx, sharing the transaction with the data write. A failure here returns an error to the caller's transaction callback, which rolls back the whole operation (TAD §13.1).

type Entry

type Entry struct {
	ID           string
	Timestamp    time.Time
	UserID       string
	DocType      string
	DocID        string
	Action       string // "create" | "update" | "delete" | "workflow_transition"
	Changes      []FieldChange
	ViaAgent     bool
	AgentSession string
	AgentPrompt  string
	IPAddress    string
	UserAgent    string
	RequestID    string
}

Entry is an immutable audit record written inside the same dal.Tx as the triggering Document Engine or Workflow Engine operation. See TAD §13.

func BuildEntry

func BuildEntry(ctx context.Context, action, docType, docID string, changes []FieldChange) Entry

BuildEntry constructs an audit Entry from the context and the given fields. Callers supply Action, DocType, DocID, and Changes; this function fills in identity, timestamp, and agent metadata.

type FieldChange

type FieldChange struct {
	Field    string
	OldValue any
	NewValue any
}

FieldChange records the pre/post value of a single field. Unchanged fields are omitted entirely (TAD §13.2).

func DiffMaps

func DiffMaps(oldRow, newRow map[string]any) []FieldChange

DiffMaps computes the per-field changes between oldRow and newRow, returning only fields whose value changed. Uses column names as field keys.

type InMemoryLog

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

func NewInMemoryLog

func NewInMemoryLog() *InMemoryLog

NewInMemoryLog creates a new in-memory audit log.

func (*InMemoryLog) Query

func (l *InMemoryLog) Query(_ context.Context, f QueryFilter) ([]Entry, error)

func (*InMemoryLog) Write

func (l *InMemoryLog) Write(_ context.Context, e Entry) error

type Log

type Log interface {
	Write(ctx context.Context, e Entry) error
	Query(ctx context.Context, f QueryFilter) ([]Entry, error)
}

Log is the audit log interface. Implementations must write inside the caller's dal.Tx (TAD §13.1 write-path guarantee). The in-memory implementation provided here is sufficient for MVP unit tests; the DB-backed DBLog is wired at site compile time.

type QueryFilter

type QueryFilter struct {
	DocType  string
	DocID    string
	UserID   string
	ViaAgent *bool
	Since    time.Time
	Limit    int
}

QueryFilter selects entries from the audit log.

type TxWriter

type TxWriter interface {
	WriteTx(ctx context.Context, tx dal.Tx, e Entry) error
}

TxWriter is implemented by Log implementations that write inside the caller's dal.Tx, giving TAD §13.1 its rollback guarantee: a failed audit write aborts the triggering operation. The in-memory log does not need a transaction handle; the DB-backed log does. Engines dispatch through WriteInTx, which prefers WriteTx when the configured log supports it.

Jump to

Keyboard shortcuts

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