Documentation
¶
Overview ¶
Package db provides Warden's central persistence layer backed by SQLite.
It stores three kinds of data:
- **Projects**: container configuration (name, image, mounts, env vars, etc.)
- **Settings**: key-value pairs (runtime, auditLogMode, disconnectKey)
- **Events**: centralized audit log from agent hooks, backend, frontend, containers
The database lives at ~/.config/warden/warden.db (platform-dependent). All methods on Store are safe for concurrent use.
Index ¶
- Constants
- type AccessItemRow
- type AuditMode
- type AuditSummaryRow
- type AuditWriter
- type Entry
- type Level
- type OffsetStoreAdapter
- func (a *OffsetStoreAdapter) DeleteOffset(projectID, agentType, filePath string) error
- func (a *OffsetStoreAdapter) DeleteOffsets(projectID, agentType string) error
- func (a *OffsetStoreAdapter) LoadOffset(projectID, agentType, filePath string) (int64, error)
- func (a *OffsetStoreAdapter) SaveOffset(projectID, agentType, filePath string, offset int64) error
- type ProjectAgentKey
- type ProjectCostRow
- type ProjectRow
- type QueryFilters
- type SessionCostRow
- type SlogHandler
- type Source
- type Store
- func (l *Store) Clear() error
- func (l *Store) Close() error
- func (l *Store) Delete(filters QueryFilters) (int64, error)
- func (l *Store) DeleteAccessItem(id string) error
- func (l *Store) DeleteProject(projectID, agentType string) error
- func (l *Store) DeleteProjectCosts(projectID, agentType string) error
- func (l *Store) DeleteSessionCosts(projectID string, since, until time.Time) error
- func (l *Store) DeleteTailerOffset(projectID, agentType, filePath string) error
- func (l *Store) DeleteTailerOffsets(projectID, agentType string) error
- func (l *Store) DistinctProjectIDs() ([]string, error)
- func (l *Store) GetAccessItem(id string) (*AccessItemRow, error)
- func (l *Store) GetAccessItemsByIDs(ids []string) ([]AccessItemRow, error)
- func (l *Store) GetAllProjectTotalCosts() (map[ProjectAgentKey]ProjectCostRow, error)
- func (l *Store) GetCostInTimeRange(projectID string, since, until time.Time) (ProjectCostRow, error)
- func (l *Store) GetProject(projectID, agentType string) (*ProjectRow, error)
- func (l *Store) GetProjectByContainerName(containerName string) (*ProjectRow, error)
- func (l *Store) GetProjectTotalCost(projectID, agentType string) (ProjectCostRow, error)
- func (l *Store) GetProjectsByPath(hostPath string) ([]*ProjectRow, error)
- func (l *Store) GetSetting(key, defaultValue string) string
- func (l *Store) HasProject(projectID, agentType string) (bool, error)
- func (l *Store) InsertAccessItem(item AccessItemRow) error
- func (l *Store) InsertProject(p ProjectRow) error
- func (l *Store) ListAccessItems() ([]AccessItemRow, error)
- func (l *Store) ListAllProjects() ([]*ProjectRow, error)
- func (l *Store) ListProjectKeys() ([]ProjectAgentKey, error)
- func (l *Store) ListSessionCosts(projectID, agentType string) ([]SessionCostRow, error)
- func (l *Store) LoadTailerOffset(projectID, agentType, filePath string) (int64, error)
- func (l *Store) Query(filters QueryFilters) ([]Entry, error)
- func (l *Store) QueryAuditSummary(filters QueryFilters) (*AuditSummaryRow, error)
- func (l *Store) QueryTopTools(filters QueryFilters, limit int) ([]ToolCountRow, error)
- func (l *Store) Read() ([]Entry, error)
- func (l *Store) SaveTailerOffset(projectID, agentType, filePath string, offset int64) error
- func (l *Store) SetSetting(key, value string) error
- func (l *Store) UpdateAccessItem(item AccessItemRow) error
- func (l *Store) UpdateProjectContainer(projectID, agentType, containerID, containerName string) error
- func (l *Store) UpdateProjectSettings(projectID, agentType, name, containerName string, skipPermissions bool, ...) error
- func (l *Store) UpsertSessionCost(projectID, agentType, sessionID string, cost float64, isEstimated bool) error
- func (l *Store) Write(entry Entry) error
- type ToolCountRow
Constants ¶
const ( SourceAgent = api.AuditSourceAgent SourceBackend = api.AuditSourceBackend SourceFrontend = api.AuditSourceFrontend SourceContainer = api.AuditSourceContainer SourceExternal = api.AuditSourceExternal LevelInfo = api.AuditLevelInfo LevelWarn = api.AuditLevelWarn LevelError = api.AuditLevelError )
Re-export constants so existing db.SourceAgent, db.LevelInfo, etc. still work.
const DefaultQueryLimit = 10_000
DefaultQueryLimit is applied when QueryFilters.Limit is zero.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AccessItemRow ¶ added in v0.4.0
type AccessItemRow struct {
// ID is the unique identifier (UUID for user items).
ID string
// Label is the human-readable display name.
Label string
// Description explains what this access item provides.
Description string
// Method is the delivery strategy (only "transport" for now).
Method string
// Credentials is JSON-encoded []access.Credential.
Credentials json.RawMessage
}
AccessItemRow represents a user-created access item stored in the database. Built-in items (Git, SSH) are not stored — they come from the access package.
type AuditMode ¶
type AuditMode string
AuditMode controls which events are persisted to the audit log.
const ( // AuditOff disables all audit logging. Nothing is written. AuditOff AuditMode = "off" // AuditStandard logs core operational events: session lifecycle, // terminal lifecycle, worktree lifecycle, budget, and system events. AuditStandard AuditMode = "standard" // AuditDetailed logs everything in standard plus agent tool use, // permissions, subagents, config changes, user prompts, and debug // events (auto-captured backend warnings/errors via slog tee). AuditDetailed AuditMode = "detailed" )
type AuditSummaryRow ¶
type AuditSummaryRow struct {
TotalSessions int
TotalToolUses int
TotalPrompts int
UniqueProjects int
UniqueWorktrees int
Earliest string
Latest string
}
AuditSummaryRow holds aggregate audit data from a summary query.
type AuditWriter ¶
type AuditWriter struct {
// contains filtered or unexported fields
}
AuditWriter gates audit log writes based on the current audit mode. All audit writes across the codebase go through this single entry point. Thread-safe for concurrent reads (mode) and writes.
func NewAuditWriter ¶
func NewAuditWriter(store *Store, mode AuditMode, standardEvents map[string]bool) *AuditWriter
NewAuditWriter creates a writer that persists entries to the given store, filtered by the initial audit mode. The standardEvents set defines which events are logged in standard mode — events not in this set are only logged in detailed mode. Pass AuditOff as mode to start silent.
func (*AuditWriter) Mode ¶
func (w *AuditWriter) Mode() AuditMode
Mode returns the current audit mode.
func (*AuditWriter) SetMode ¶
func (w *AuditWriter) SetMode(mode AuditMode)
SetMode updates the audit mode at runtime. Takes effect immediately for subsequent Write calls.
func (*AuditWriter) Write ¶
func (w *AuditWriter) Write(entry Entry)
Write persists an audit entry if the current mode allows it. Drops silently when mode is off or the event is not in the current mode's allowlist. Logs a warning on DB write failure so callers don't need error handling.
type Entry ¶
type Entry = api.AuditEntry
Type aliases for backward compatibility. Canonical definitions live in the api package; these aliases let existing db.Entry / db.Source / db.Level references compile without changes throughout the codebase.
type Level ¶
type Level = api.AuditLevel
Type aliases for backward compatibility. Canonical definitions live in the api package; these aliases let existing db.Entry / db.Source / db.Level references compile without changes throughout the codebase.
type OffsetStoreAdapter ¶ added in v1.5.0
type OffsetStoreAdapter struct {
Store *Store
}
OffsetStoreAdapter wraps a Store to implement watcher.OffsetStore. Lives in the db package to avoid the watcher package importing db.
func (*OffsetStoreAdapter) DeleteOffset ¶ added in v1.5.0
func (a *OffsetStoreAdapter) DeleteOffset(projectID, agentType, filePath string) error
DeleteOffset implements watcher.OffsetStore.
func (*OffsetStoreAdapter) DeleteOffsets ¶ added in v1.5.0
func (a *OffsetStoreAdapter) DeleteOffsets(projectID, agentType string) error
DeleteOffsets implements watcher.OffsetStore.
func (*OffsetStoreAdapter) LoadOffset ¶ added in v1.5.0
func (a *OffsetStoreAdapter) LoadOffset(projectID, agentType, filePath string) (int64, error)
LoadOffset implements watcher.OffsetStore.
func (*OffsetStoreAdapter) SaveOffset ¶ added in v1.5.0
func (a *OffsetStoreAdapter) SaveOffset(projectID, agentType, filePath string, offset int64) error
SaveOffset implements watcher.OffsetStore.
type ProjectAgentKey ¶ added in v0.5.0
ProjectAgentKey uniquely identifies a project+agent pair. Used as a map key where the compound (project_id, agent_type) identity is needed.
type ProjectCostRow ¶
ProjectCostRow holds aggregated cost data for a project from the DB.
type ProjectRow ¶
type ProjectRow struct {
// ProjectID is the deterministic identifier (sha256 of host path, 12 hex chars).
ProjectID string
// Name is the user-chosen display label / Docker container name.
Name string
// HostPath is the absolute host directory mounted into the container.
HostPath string
// AddedAt is when the project was added to Warden.
AddedAt time.Time
// Image is the container image name.
Image string
// EnvVars is JSON-encoded map[string]string of user-provided env vars.
EnvVars json.RawMessage
// Mounts is JSON-encoded []Mount of additional bind mounts.
Mounts json.RawMessage
// OriginalMounts is JSON-encoded []Mount of pre-symlink-resolution mounts.
OriginalMounts json.RawMessage
// SkipPermissions controls whether terminals skip permission prompts.
SkipPermissions bool
// NetworkMode is the container's network isolation level (full/restricted/none).
NetworkMode string
// AllowedDomains is comma-separated domains for restricted mode.
AllowedDomains string
// CostBudget is the per-project cost limit in USD (0 = use global default).
CostBudget float64
// EnabledAccessItems is a comma-separated list of enabled access item IDs (e.g. "git,ssh").
EnabledAccessItems string
// EnabledRuntimes is a comma-separated list of enabled runtime IDs (e.g. "node,python,go").
EnabledRuntimes string
// ForwardedPorts is a comma-separated list of forwarded port numbers (e.g. "5173,3000").
ForwardedPorts string
// AgentType identifies the CLI agent running in this project (e.g. "claude-code", "codex").
AgentType string
// ContainerID is the Docker-assigned container ID (empty when no container exists).
ContainerID string
// ContainerName is the Docker container name (may differ from Name if renamed).
ContainerName string
}
ProjectRow represents a project stored in the database.
Complex fields (EnvVars, Mounts, OriginalMounts) are stored as opaque JSON. The service layer handles marshaling to/from engine types.
type QueryFilters ¶
type QueryFilters struct {
// Source restricts results to a single source layer.
Source Source
// Level restricts results to a single severity level.
Level Level
// ProjectID restricts results to a single project by its deterministic ID.
ProjectID string
// Worktree restricts results to a single worktree ID.
Worktree string
// Event restricts results to a single event type identifier.
Event string
// Events restricts results to any of the listed event types (OR).
Events []string
// ExcludeEvents excludes entries whose event type is in this list (NOT IN).
// Mutually exclusive with Events; if both are set, Events takes precedence.
ExcludeEvents []string
// Since returns only entries with a timestamp at or after this time.
Since time.Time
// Until returns only entries with a timestamp strictly before this time.
Until time.Time
// Limit caps the number of returned entries. Defaults to DefaultQueryLimit if zero.
Limit int
// Offset skips this many entries before returning results.
Offset int
}
QueryFilters controls which entries are returned by Store.Query.
Zero-value fields are ignored (no filtering). Limit defaults to DefaultQueryLimit when zero.
type SessionCostRow ¶ added in v1.8.0
type SessionCostRow struct {
SessionID string
Cost float64
IsEstimated bool
CreatedAt string
UpdatedAt string
}
SessionCostRow holds cost data for a single session.
type SlogHandler ¶
type SlogHandler struct {
// contains filtered or unexported fields
}
SlogHandler is a slog.Handler that writes backend log records to the audit log. It wraps a delegate handler so logs still go to their original destination (stderr).
func NewSlogHandler ¶
func NewSlogHandler(delegate slog.Handler, writer *AuditWriter) *SlogHandler
NewSlogHandler creates a handler that writes to both the delegate and the audit log. If writer is nil, only the delegate receives records.
func (*SlogHandler) Enabled ¶
Enabled reports whether the handler handles records at the given level.
func (*SlogHandler) Handle ¶
Handle writes the record to the delegate and, if the writer is non-nil, also writes a backend entry to the audit log. Only warnings and errors are written — INFO-level traffic is too noisy. These events have auto-generated snake_case names and are classified as debug category (detailed mode only) by the AuditWriter's standardEvents allowlist.
type Source ¶
type Source = api.AuditSource
Type aliases for backward compatibility. Canonical definitions live in the api package; these aliases let existing db.Entry / db.Source / db.Level references compile without changes throughout the codebase.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store writes structured audit log entries to a SQLite database.
All methods are safe for concurrent use. A nil Store is a valid no-op: all methods return immediately without error.
func New ¶
New creates a Store backed by a SQLite database at dir/warden.db. The directory is created if it does not exist. Pass the config directory root (e.g. ~/.config/warden/) — the database file is created inside it.
func (*Store) Delete ¶
func (l *Store) Delete(filters QueryFilters) (int64, error)
Delete removes events matching the given filters. With no filters set, this is equivalent to [Clear]. Supports scoping by project, worktree, and time range (since/until).
func (*Store) DeleteAccessItem ¶ added in v0.4.0
DeleteAccessItem removes a user-created access item by ID.
func (*Store) DeleteProject ¶
DeleteProject removes a project from the projects table. Audit events and cost data are intentionally retained so the audit page can show historical data.
func (*Store) DeleteProjectCosts ¶
DeleteProjectCosts removes all cost entries for a project+agent pair.
func (*Store) DeleteSessionCosts ¶ added in v1.5.0
DeleteSessionCosts removes session cost entries matching the given filters. Supports scoping by project ID and time range. With no filters, clears all session costs.
func (*Store) DeleteTailerOffset ¶ added in v1.5.0
DeleteTailerOffset removes the stored offset for a single file.
func (*Store) DeleteTailerOffsets ¶ added in v1.5.0
DeleteTailerOffsets removes all stored offsets for a project+agent pair.
func (*Store) DistinctProjectIDs ¶
DistinctProjectIDs returns sorted, unique project IDs that have at least one event logged. Empty project IDs are excluded.
func (*Store) GetAccessItem ¶ added in v0.4.0
func (l *Store) GetAccessItem(id string) (*AccessItemRow, error)
GetAccessItem returns a user-created access item by ID, or nil if not found.
func (*Store) GetAccessItemsByIDs ¶ added in v0.4.0
func (l *Store) GetAccessItemsByIDs(ids []string) ([]AccessItemRow, error)
GetAccessItemsByIDs returns user-created access items matching the given IDs. IDs not found are silently skipped.
func (*Store) GetAllProjectTotalCosts ¶
func (l *Store) GetAllProjectTotalCosts() (map[ProjectAgentKey]ProjectCostRow, error)
GetAllProjectTotalCosts returns cumulative costs for all project+agent pairs by summing across all sessions.
func (*Store) GetCostInTimeRange ¶
func (l *Store) GetCostInTimeRange(projectID string, since, until time.Time) (ProjectCostRow, error)
GetCostInTimeRange returns the total cost for sessions that overlap with the given time range. A session overlaps if it was created before the range ends and last updated after the range starts. Pass zero-value times to leave either bound open.
func (*Store) GetProject ¶
func (l *Store) GetProject(projectID, agentType string) (*ProjectRow, error)
GetProject returns a project by its compound key, or nil if not found.
func (*Store) GetProjectByContainerName ¶
func (l *Store) GetProjectByContainerName(containerName string) (*ProjectRow, error)
GetProjectByContainerName returns a project by its Docker container name, or nil if not found.
func (*Store) GetProjectTotalCost ¶
func (l *Store) GetProjectTotalCost(projectID, agentType string) (ProjectCostRow, error)
GetProjectTotalCost returns the cumulative cost for a single project+agent pair.
func (*Store) GetProjectsByPath ¶ added in v0.5.0
func (l *Store) GetProjectsByPath(hostPath string) ([]*ProjectRow, error)
GetProjectsByPath returns all projects at a host path (one per agent type).
func (*Store) GetSetting ¶
GetSetting returns the value for a settings key, or the provided default if the key does not exist.
func (*Store) HasProject ¶
HasProject reports whether a project with the given compound key exists.
func (*Store) InsertAccessItem ¶ added in v0.4.0
func (l *Store) InsertAccessItem(item AccessItemRow) error
InsertAccessItem adds a user-created access item to the database.
func (*Store) InsertProject ¶
func (l *Store) InsertProject(p ProjectRow) error
InsertProject adds a project to the database. If a project with the same project ID already exists, it is replaced (upsert).
func (*Store) ListAccessItems ¶ added in v0.4.0
func (l *Store) ListAccessItems() ([]AccessItemRow, error)
ListAccessItems returns all user-created access items.
func (*Store) ListAllProjects ¶
func (l *Store) ListAllProjects() ([]*ProjectRow, error)
ListAllProjects returns all projects as a flat slice ordered by insertion time.
func (*Store) ListProjectKeys ¶ added in v0.5.0
func (l *Store) ListProjectKeys() ([]ProjectAgentKey, error)
ListProjectKeys returns all project+agent pairs in insertion order.
func (*Store) ListSessionCosts ¶ added in v1.8.0
func (l *Store) ListSessionCosts(projectID, agentType string) ([]SessionCostRow, error)
ListSessionCosts returns per-session cost data for a project+agent pair.
func (*Store) LoadTailerOffset ¶ added in v1.5.0
LoadTailerOffset returns the stored byte offset for a tailed file. Returns 0 if no offset is stored.
func (*Store) Query ¶
func (l *Store) Query(filters QueryFilters) ([]Entry, error)
Query returns entries matching the given filters, sorted by timestamp (newest first). Zero-value filter fields are ignored.
func (*Store) QueryAuditSummary ¶
func (l *Store) QueryAuditSummary(filters QueryFilters) (*AuditSummaryRow, error)
QueryAuditSummary returns aggregate audit statistics matching the given filters. Only ProjectID, Worktree, Since, and Until fields are used for filtering.
func (*Store) QueryTopTools ¶
func (l *Store) QueryTopTools(filters QueryFilters, limit int) ([]ToolCountRow, error)
QueryTopTools returns the most frequently used tools from tool_use events. Only ProjectID, Worktree, Since, and Until fields are used for filtering.
func (*Store) Read ¶
Read returns all entries sorted by timestamp (newest first). This is a convenience wrapper around [Query] with empty filters.
func (*Store) SaveTailerOffset ¶ added in v1.5.0
SaveTailerOffset persists the byte offset for a tailed file (upsert).
func (*Store) SetSetting ¶
SetSetting writes a key-value pair to the settings table (upsert).
func (*Store) UpdateAccessItem ¶ added in v0.4.0
func (l *Store) UpdateAccessItem(item AccessItemRow) error
UpdateAccessItem updates a user-created access item.
func (*Store) UpdateProjectContainer ¶
func (l *Store) UpdateProjectContainer(projectID, agentType, containerID, containerName string) error
UpdateProjectContainer updates the container ID and name for a project. Used after container creation, rebuild, or deletion.
func (*Store) UpdateProjectSettings ¶ added in v0.5.0
func (l *Store) UpdateProjectSettings(projectID, agentType, name, containerName string, skipPermissions bool, costBudget float64, allowedDomains, forwardedPorts string) error
UpdateProjectSettings updates lightweight project settings that do not require container recreation (name, skip_permissions, cost_budget, container_name, allowed_domains, forwarded_ports). All other fields remain unchanged.
func (*Store) UpsertSessionCost ¶
func (l *Store) UpsertSessionCost(projectID, agentType, sessionID string, cost float64, isEstimated bool) error
UpsertSessionCost persists cost for a specific agent session. Cost for a given session ID is monotonically non-decreasing, so upserting is always safe — we simply take the max of old and new values. Project total cost is computed as SUM(cost) across all sessions for a project.
type ToolCountRow ¶
ToolCountRow pairs a tool name with its invocation count.