usecase

package
v0.32.0 Latest Latest
Warning

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

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

Documentation

Overview

Package usecase — bundle usecase implements the v0.9 portability primitive introduced for #572: a local-first, encrypted, content-verifiable archive that operators can move between their machines through any file-transport they already have (AirDrop, scp, Syncthing, etc.). Traceary never ships its own transport.

Portability covers events, sessions, command_audits, memories, memory_edges, and usage_observations — see docs/operations/cross-machine-handoff for the operator guide.

Package usecase — bundle usecase implements the v0.9 portability primitive introduced for #572: a local-first, encrypted, content-verifiable archive that operators can move between their machines through any file-transport they already have (AirDrop, scp, Syncthing, etc.). Traceary never ships its own transport.

Portability covers events, sessions, command_audits, memories, memory_edges, and usage_observations — see docs/operations/cross-machine-handoff for the operator guide.

Package usecase — bundle usecase implements the v0.9 portability primitive introduced for #572: a local-first, encrypted, content-verifiable archive that operators can move between their machines through any file-transport they already have (AirDrop, scp, Syncthing, etc.). Traceary never ships its own transport.

Portability covers events, sessions, command_audits, memories, memory_edges, and usage_observations — see docs/operations/cross-machine-handoff for the operator guide.

Package usecase — bundle usecase implements the v0.9 portability primitive introduced for #572: a local-first, encrypted, content-verifiable archive that operators can move between their machines through any file-transport they already have (AirDrop, scp, Syncthing, etc.). Traceary never ships its own transport.

Portability covers events, sessions, command_audits, memories, memory_edges, and usage_observations — see docs/operations/cross-machine-handoff for the operator guide.

Package usecase contains Traceary's write-side orchestration interfaces and implementations.

Use cases coordinate domain objects, repositories, and query lookups for operator-facing workflows such as session lifecycle management, manual memory updates, and handoff/context assembly.

Index

Constants

View Source
const (
	MemoryBridgeMarkerBegin    = "<!-- traceary-memories:begin:v1 -->"
	MemoryBridgeMarkerEnd      = "<!-- traceary-memories:end -->"
	MemoryBridgeCurrentVersion = 1
)

MemoryBridgeMarkerBegin / End wrap every block Traceary manages inside a host instruction file. The exporter always writes the current version (MemoryBridgeCurrentVersion) so consumers see a stable stamp; the importer accepts any `:v<N>` suffix through MatchMemoryBridgeBeginLine so a future `:v2` build never reimports an older exporter's block as free-form candidates.

Variables

This section is empty.

Functions

func MatchMemoryBridgeBeginLine added in v0.7.1

func MatchMemoryBridgeBeginLine(line string) (version int, ok bool)

MatchMemoryBridgeBeginLine reports whether the trimmed line is a Traceary begin marker. The returned version is the encoded `v<N>` so the caller can warn when it exceeds MemoryBridgeCurrentVersion.

func SummarizeCandidateHygiene added in v0.21.0

func SummarizeCandidateHygiene(candidates []apptypes.MemorySummary, now time.Time, staleThreshold time.Duration) apptypes.CandidateHygieneCounts

SummarizeCandidateHygiene classifies the candidate memories in the supplied summaries into the hygiene dimensions surfaced by the snapshot (#1169). Only rows with status candidate are considered; accepted/other rows are ignored so callers can pass a mixed slice (e.g. the reliability scan loads accepted + candidate together).

The four flag dimensions are independent and may overlap; LikelyActionable is the complement (flagged by none). Duplicate detection is exact only, keyed by the same scope + memory type + fact identity the extraction dedupe uses (memoryCandidateKey), so identical text in different workspaces or memory types is not falsely merged — the reliability scan is global by default. Similarity duplicates stay in the hygiene scan. The classification reuses classifyExtractionNoise so it stays consistent with the extraction-time gate and the cleanup classifier.

Types

type AntigravityUsageCaptureResult added in v0.32.0

type AntigravityUsageCaptureResult struct {
	Applied        int
	AlreadyApplied int
	Unavailable    int
}

AntigravityUsageCaptureResult exposes idempotent write outcomes.

type AntigravityUsageCaptureUsecase added in v0.32.0

type AntigravityUsageCaptureUsecase interface {
	CaptureStatus(context.Context, io.Reader) (AntigravityUsageCaptureResult, error)
	CaptureStopUnavailable(context.Context, AntigravityUsageStopInput) (AntigravityUsageCaptureResult, error)
}

AntigravityUsageCaptureUsecase records idle cumulative snapshots and explicit unavailable Stop boundaries.

func NewAntigravityUsageCaptureUsecase added in v0.32.0

func NewAntigravityUsageCaptureUsecase(
	source application.AntigravityUsageSource,
	repository application.AntigravityUsageRepository,
) AntigravityUsageCaptureUsecase

NewAntigravityUsageCaptureUsecase creates the Antigravity adapter boundary.

type AntigravityUsageStopInput added in v0.32.0

type AntigravityUsageStopInput struct {
	SessionID  types.SessionID
	BoundaryID string
}

AntigravityUsageStopInput identifies one observable Stop boundary whose provider usage is not correlatable.

type BundleConflictPolicy added in v0.10.0

type BundleConflictPolicy string

BundleConflictPolicy controls how bundle import handles a row whose durable identity already exists in the destination store.

const (
	// BundleConflictSkip keeps the destination row and counts a skip.
	BundleConflictSkip BundleConflictPolicy = "skip"
	// BundleConflictReplace overwrites the destination row with the bundle row.
	BundleConflictReplace BundleConflictPolicy = "replace"
	// BundleConflictError fails the import on the first conflict.
	BundleConflictError BundleConflictPolicy = "error"
)

type BundleEventRepository added in v0.9.0

type BundleEventRepository interface {
	// SchemaVersion is the current schema_migrations max version.
	SchemaVersion(ctx context.Context) (int, error)
	ListBundleSessions(ctx context.Context) ([]*model.Session, error)
	ListBundleCommandAudits(ctx context.Context) ([]*model.CommandAudit, error)
	// ListBundleMemories returns all durable memories and their refs for bundle export.
	ListBundleMemories(ctx context.Context) ([]apptypes.MemoryDetails, error)
	// ListBundleMemoryEdges returns all memory graph edges for bundle export.
	ListBundleMemoryEdges(ctx context.Context) ([]*model.MemoryEdge, error)
	// ListBundleUsageObservations returns all provider-neutral usage evidence.
	ListBundleUsageObservations(ctx context.Context) ([]*model.UsageObservation, error)
	// ListBundleRunLineages returns every immutable run lineage fact.
	ListBundleRunLineages(ctx context.Context) ([]*model.RunLineage, error)
	// BeginBundleImport starts the single transaction used by all table
	// importers in registry order.
	BeginBundleImport(ctx context.Context) (BundleImportTransaction, error)
}

BundleEventRepository is the set of write operations the usecase needs to run Import. Export only reads through queryservice.EventQueryService, which already exists.

type BundleExportOptions added in v0.9.0

type BundleExportOptions struct {
	// OutPath is the filesystem path where the encrypted archive
	// lands.
	OutPath string
	// Passphrase derives the archive's symmetric key via
	// Argon2id. Must be non-empty — Traceary does not produce
	// unencrypted bundles because the same artifact may later be
	// carried over an untrusted channel (email, Dropbox, etc.).
	Passphrase []byte
	// Since / Until narrow the event range. Zero value disables
	// the side of the range.
	Since time.Time
	Until time.Time
	// Workspace, when non-empty, restricts exported events to a
	// single workspace.
	Workspace types.Workspace
}

BundleExportOptions controls what a single Export call writes.

type BundleImportOptions added in v0.9.0

type BundleImportOptions struct {
	// InPath is the filesystem path of the archive to read.
	InPath string
	// Passphrase decrypts the archive. Must match what Export used.
	Passphrase []byte
	// OnConflict controls UNIQUE collisions. Empty defaults to skip for
	// v0.9-compatible idempotent re-imports.
	OnConflict BundleConflictPolicy
	// MissingParent controls how the sessions importer handles an imported session whose parent session is absent. Empty defaults to reject.
	MissingParent BundleMissingParentPolicy
	// OrphanEdges controls memory_edges rows whose endpoints are missing after
	// memories import. Empty defaults to skip-with-warning.
	OrphanEdges BundleOrphanEdgesPolicy
}

BundleImportOptions controls a single Import call.

type BundleImportResult added in v0.9.0

type BundleImportResult struct {
	// EventsImported / EventsSkipped count events that were newly
	// written vs dropped because of a pre-existing (event_id)
	// collision.
	EventsImported        int
	EventsSkipped         int
	SessionsImported      int
	SessionsSkipped       int
	CommandAuditsImported int
	CommandAuditsSkipped  int
	// MemoriesImported / MemoriesSkipped count durable memories that were newly
	// written vs dropped because of a pre-existing memory id collision.
	MemoriesImported int
	MemoriesSkipped  int
	// MemoryEdgesImported / MemoryEdgesSkipped count memory graph edges that were
	// newly written vs skipped due to idempotency or orphan-edge tolerance.
	MemoryEdgesImported int
	MemoryEdgesSkipped  int
	// UsageObservationsImported / UsageObservationsSkipped count durable usage
	// observations restored vs retained as exact or policy-selected duplicates.
	UsageObservationsImported int
	UsageObservationsSkipped  int
	RunLineagesImported       int
	RunLineagesSkipped        int
	// BundleSchemaVersion is the schema_migrations version the
	// archive carried at Export time.
	BundleSchemaVersion int
}

BundleImportResult summarises what changed during Import.

type BundleImportTransaction added in v0.10.0

type BundleImportTransaction interface {
	ImportSession(ctx context.Context, session *model.Session, policy BundleConflictPolicy, missingParent BundleMissingParentPolicy) (bool, error)
	ImportEvent(ctx context.Context, event *model.Event, policy BundleConflictPolicy) (bool, error)
	ImportCommandAudit(ctx context.Context, audit *model.CommandAudit, policy BundleConflictPolicy) (bool, error)
	ImportMemory(ctx context.Context, memory *model.Memory, policy BundleConflictPolicy) (bool, error)
	MemoryExists(ctx context.Context, memoryID types.MemoryID) (bool, error)
	MemoryEdgeExists(ctx context.Context, edgeID types.MemoryEdgeID) (bool, error)
	ImportMemoryEdge(ctx context.Context, edge *model.MemoryEdge, policy BundleConflictPolicy) (bool, error)
	ImportUsageObservation(ctx context.Context, observation *model.UsageObservation, policy BundleConflictPolicy) (bool, error)
	ImportRunLineage(ctx context.Context, lineage *model.RunLineage) (bool, error)
	Commit(ctx context.Context) error
	Rollback(ctx context.Context) error
}

BundleImportTransaction is the write-side transaction shared by all bundle table importers.

type BundleMissingParentPolicy added in v0.10.0

type BundleMissingParentPolicy string

BundleMissingParentPolicy controls multi-table bundle imports where a child row (e.g. an imported session) can reference a parent that is absent from both the bundle and the destination store.

const (
	// BundleMissingParentReject fails imports that reference missing parents.
	BundleMissingParentReject BundleMissingParentPolicy = "reject"
	// BundleMissingParentSkip skips rows that reference missing parents.
	BundleMissingParentSkip BundleMissingParentPolicy = "skip"
	// BundleMissingParentBackfill creates placeholder parents when supported.
	BundleMissingParentBackfill BundleMissingParentPolicy = "backfill"
)

type BundleOrphanEdgesPolicy added in v0.10.0

type BundleOrphanEdgesPolicy string

BundleOrphanEdgesPolicy controls how bundle import handles memory edges whose endpoints are absent from the destination store after memories import.

const (
	// BundleOrphanEdgesSkip skips orphan edges and emits a structured warning.
	BundleOrphanEdgesSkip BundleOrphanEdgesPolicy = "skip"
	// BundleOrphanEdgesReject fails the import on the first orphan edge.
	BundleOrphanEdgesReject BundleOrphanEdgesPolicy = "reject"
)

type BundleUsecase added in v0.9.0

type BundleUsecase interface {
	Export(ctx context.Context, opts BundleExportOptions) error
	Import(ctx context.Context, opts BundleImportOptions) (BundleImportResult, error)
}

BundleUsecase exports / imports a local-first portability bundle.

func NewBundleUsecase added in v0.9.0

func NewBundleUsecase(
	events queryservice.EventQueryService,
	repository BundleEventRepository,
	nowFunc func() time.Time,
) BundleUsecase

NewBundleUsecase constructs a BundleUsecase.

type ClaudeUsageCaptureInput added in v0.32.0

type ClaudeUsageCaptureInput struct {
	SessionID          types.SessionID
	DeliveryID         string
	FallbackSourceName string
	FallbackTerminal   types.UsageTerminalCode
}

ClaudeUsageCaptureInput is one body-free Claude terminal boundary.

type ClaudeUsageCaptureResult added in v0.32.0

type ClaudeUsageCaptureResult struct {
	Applied        int
	AlreadyApplied int
	Unavailable    int
}

ClaudeUsageCaptureResult exposes idempotent write outcomes for diagnostics.

type ClaudeUsageCaptureUsecase added in v0.32.0

ClaudeUsageCaptureUsecase records transcript calls or a mutually exclusive one-shot terminal summary in the provider-neutral usage ledger.

func NewClaudeUsageCaptureUsecase added in v0.32.0

func NewClaudeUsageCaptureUsecase(
	source application.ClaudeUsageSource,
	repository application.ClaudeUsageRepository,
) ClaudeUsageCaptureUsecase

NewClaudeUsageCaptureUsecase creates the Claude adapter boundary.

type CodexCaptureDiagnosticUsecase added in v0.32.0

type CodexCaptureDiagnosticUsecase interface {
	Load(
		context.Context,
		apptypes.CodexCaptureDiagnosticCriteria,
	) (apptypes.CodexCaptureDiagnosticEvidence, error)
}

CodexCaptureDiagnosticUsecase exposes the body-free evidence required by doctor without leaking storage or session identity details.

func NewCodexCaptureDiagnosticUsecase added in v0.32.0

func NewCodexCaptureDiagnosticUsecase(
	query queryservice.CodexCaptureDiagnosticQueryService,
) CodexCaptureDiagnosticUsecase

NewCodexCaptureDiagnosticUsecase creates the read-only diagnostic boundary.

type CodexUsageCaptureInput added in v0.32.0

type CodexUsageCaptureInput struct {
	SessionID          types.SessionID
	DeliveryID         string
	FallbackSourceName string
	FallbackTerminal   types.UsageTerminalCode
}

CodexUsageCaptureInput is one body-free Codex terminal boundary.

type CodexUsageCaptureResult added in v0.32.0

type CodexUsageCaptureResult struct {
	Applied        int
	AlreadyApplied int
	Unavailable    int
}

CodexUsageCaptureResult exposes idempotent write outcomes for diagnostics.

type CodexUsageCaptureUsecase added in v0.32.0

CodexUsageCaptureUsecase records mutually exclusive rollout or headless terminal observations in the provider-neutral usage ledger.

func NewCodexUsageCaptureUsecase added in v0.32.0

func NewCodexUsageCaptureUsecase(
	source application.CodexUsageSource,
	repository application.CodexUsageRepository,
) CodexUsageCaptureUsecase

NewCodexUsageCaptureUsecase creates the Codex adapter boundary.

type ContextUsecase added in v0.5.0

type ContextUsecase interface {
	// Handoff builds a structured ContextPack. Returns an empty Optional when no
	// matching session exists.
	Handoff(ctx context.Context, criteria apptypes.ContextPackCriteria) (types.Optional[apptypes.ContextPack], error)
}

ContextUsecase assembles structured working-memory packs for handoff and context resumption.

This is the preferred read/write orchestration surface behind operator-facing `traceary handoff` output and MCP tools such as `session_handoff` and `memory_pack`.

func NewContextUsecase added in v0.5.0

func NewContextUsecase(
	sessionQuery queryservice.SessionQueryService,
	eventQuery queryservice.EventQueryService,
	memoryQuery queryservice.MemoryQueryService,
) ContextUsecase

NewContextUsecase creates a ContextUsecase.

type EventCoverageInput added in v0.21.0

type EventCoverageInput struct {
	SessionID string
	Kind      types.EventKind
}

EventCoverageInput is one observation fed to SummarizeSessionEventCoverage. It carries just enough state for the classifier to attribute the event to a session and decide whether it enriches that session beyond pure boundary metadata.

type EventMetadataUsecase added in v0.31.0

type EventMetadataUsecase interface {
	List(ctx context.Context, criteria apptypes.EventListCriteria) ([]apptypes.EventMetadata, error)
	Search(ctx context.Context, criteria apptypes.EventSearchCriteria) ([]apptypes.EventMetadata, error)
	Context(ctx context.Context, criteria apptypes.EventContextCriteria) ([]apptypes.EventMetadata, error)
}

EventMetadataUsecase exposes body-free event reads to presentation adapters.

func NewEventMetadataUsecase added in v0.31.0

func NewEventMetadataUsecase(query queryservice.EventMetadataQueryService) EventMetadataUsecase

NewEventMetadataUsecase creates the body-free event read usecase.

type EventUsecase added in v0.3.0

type EventUsecase interface {
	// Log records a log event. Zero-value kind defaults to note.
	// logCfg carries redaction settings; its zero value is a
	// pass-through for non-transcript kinds. For EventKindTranscript
	// the implementation applies built-in redactors + the caller's
	// extra patterns before persisting so no log-ingest surface has
	// to re-implement that policy in the presentation layer.
	Log(ctx context.Context, message string, kind types.EventKind, client types.Client, agent types.Agent, sessionID types.SessionID, workspace types.Workspace, logCfg apptypes.LogRedaction) (*model.Event, error)

	// Audit records a command execution audit event. The AuditInput value
	// object carries the command, attribution, exit code, and structural
	// failure flag; auditCfg carries the redaction policy.
	Audit(ctx context.Context, in apptypes.AuditInput, auditCfg apptypes.AuditRedaction) (*model.Event, *model.CommandAudit, error)

	// Search performs full-text search across events.
	Search(ctx context.Context, criteria apptypes.EventSearchCriteria) ([]*model.Event, error)

	// List returns events in descending time order.
	List(ctx context.Context, criteria apptypes.EventListCriteria) ([]*model.Event, error)

	// ListWindow returns every event matching the criteria whose created_at
	// falls in [From, To) under a single read snapshot, so concurrent writers
	// cannot cause the paged scan to drop events. criteria.Limit() controls
	// the per-page size for the internal scan; criteria.Offset() is ignored.
	ListWindow(ctx context.Context, criteria apptypes.EventListCriteria) ([]*model.Event, error)

	// Show returns the details for a single event.
	Show(ctx context.Context, eventID types.EventID) (apptypes.EventDetails, error)

	// Context returns recent events for the given context.
	Context(ctx context.Context, criteria apptypes.EventContextCriteria) ([]*model.Event, error)

	// Timeline returns work blocks separated by idle gaps.
	Timeline(ctx context.Context, criteria apptypes.TimelineCriteria) ([]apptypes.TimelineBlock, error)
}

EventUsecase consolidates event recording and query operations.

func NewEventUsecase added in v0.4.0

func NewEventUsecase(
	eventRepo model.EventRepository,
	eventQuery queryservice.EventQueryService,
) EventUsecase

NewEventUsecase creates an EventUsecase.

type FileRetentionCapacityInspector added in v0.31.0

type FileRetentionCapacityInspector interface {
	InspectCapacity(ctx context.Context, request apptypes.FileRetentionCapacityRequest) ([]apptypes.FileRetentionCapacityStatus, error)
}

FileRetentionCapacityInspector provides read-only operational capacity evidence.

type FileRetentionUsecase added in v0.31.0

type FileRetentionUsecase interface {
	FileRetentionCapacityInspector
	CreatePlan(ctx context.Context, request apptypes.FileRetentionPlanRequest, now time.Time) ([]byte, error)
	Apply(ctx context.Context, encodedPlan []byte, confirmedPlanID string, now time.Time) (apptypes.FileRetentionApplyResult, error)
}

FileRetentionUsecase plans and explicitly applies local archive/backup limits.

func NewFileRetentionUsecase added in v0.31.0

NewFileRetentionUsecase creates the file-capacity workflow.

type GeminiUsageCaptureInput added in v0.32.0

type GeminiUsageCaptureInput struct {
	SessionID        types.SessionID
	DeliveryID       string
	FallbackTerminal types.UsageTerminalCode
}

GeminiUsageCaptureInput identifies one body-free Gemini boundary.

type GeminiUsageCaptureResult added in v0.32.0

type GeminiUsageCaptureResult struct {
	Applied        int
	AlreadyApplied int
	Unavailable    int
}

GeminiUsageCaptureResult exposes idempotent write outcomes.

type GeminiUsageCaptureUsecase added in v0.32.0

type GeminiUsageCaptureUsecase interface {
	CaptureHeadless(context.Context, GeminiUsageCaptureInput, application.GeminiUsageLoadResult) (GeminiUsageCaptureResult, error)
	CaptureInteractiveUnavailable(context.Context, GeminiUsageCaptureInput) (GeminiUsageCaptureResult, error)
}

GeminiUsageCaptureUsecase records terminal one-shot results and explicit unavailable interactive boundaries.

func NewGeminiUsageCaptureUsecase added in v0.32.0

func NewGeminiUsageCaptureUsecase(
	repository application.GeminiUsageRepository,
) GeminiUsageCaptureUsecase

NewGeminiUsageCaptureUsecase creates the Gemini adapter boundary.

type GrokUsageCaptureInput added in v0.32.0

type GrokUsageCaptureInput struct {
	SessionID        types.SessionID
	DeliveryID       string
	FallbackTerminal types.UsageTerminalCode
}

GrokUsageCaptureInput identifies one body-free Grok boundary.

type GrokUsageCaptureResult added in v0.32.0

type GrokUsageCaptureResult struct {
	Applied        int
	AlreadyApplied int
	Unavailable    int
}

GrokUsageCaptureResult exposes idempotent write outcomes.

type GrokUsageCaptureUsecase added in v0.32.0

type GrokUsageCaptureUsecase interface {
	CaptureHeadless(context.Context, GrokUsageCaptureInput, application.GrokUsageLoadResult) (GrokUsageCaptureResult, error)
	CaptureHookUnavailable(context.Context, GrokUsageCaptureInput) (GrokUsageCaptureResult, error)
}

GrokUsageCaptureUsecase records terminal headless results and explicit unavailable native Stop boundaries.

func NewGrokUsageCaptureUsecase added in v0.32.0

func NewGrokUsageCaptureUsecase(repository application.GrokUsageRepository) GrokUsageCaptureUsecase

NewGrokUsageCaptureUsecase creates the Grok adapter boundary.

type KimiUsageBoundary added in v0.32.0

type KimiUsageBoundary string

KimiUsageBoundary identifies a lifecycle completion that has no proven one-to-one relationship with a Kimi wire usage record.

const (
	// KimiUsageBoundaryStop identifies a Kimi Stop hook.
	KimiUsageBoundaryStop KimiUsageBoundary = "stop"
	// KimiUsageBoundarySessionEnd identifies a Kimi SessionEnd hook.
	KimiUsageBoundarySessionEnd KimiUsageBoundary = "session_end"
)

type KimiUsageCaptureInput added in v0.32.0

type KimiUsageCaptureInput struct {
	SessionID         types.SessionID
	ProviderSessionID string
	Boundary          KimiUsageBoundary
}

KimiUsageCaptureInput identifies one body-free Kimi lifecycle boundary.

type KimiUsageCaptureResult added in v0.32.0

type KimiUsageCaptureResult struct {
	Applied        int
	AlreadyApplied int
	Unavailable    int
}

KimiUsageCaptureResult exposes idempotent source and availability writes.

type KimiUsageCaptureUsecase added in v0.32.0

type KimiUsageCaptureUsecase interface {
	Capture(context.Context, KimiUsageCaptureInput) (KimiUsageCaptureResult, error)
}

KimiUsageCaptureUsecase records partial wire evidence and explicit unavailable lifecycle completions.

func NewKimiUsageCaptureUsecase added in v0.32.0

func NewKimiUsageCaptureUsecase(
	source application.KimiUsageSource,
	repository application.KimiUsageRepository,
) KimiUsageCaptureUsecase

NewKimiUsageCaptureUsecase creates the Kimi usage adapter boundary.

type MemoryEdgeUsecase added in v0.9.0

type MemoryEdgeUsecase interface {
	// Add persists a typed relationship between two memories. See
	// model.NewMemoryEdge for validation rules.
	Add(
		ctx context.Context,
		fromMemoryID types.MemoryID,
		toMemoryID types.MemoryID,
		relation types.MemoryEdgeRelation,
		validFrom types.Optional[time.Time],
		validTo types.Optional[time.Time],
	) (*model.MemoryEdge, error)

	// List returns edges matching the filter. The filter's zero
	// value returns every edge up to the limit.
	List(ctx context.Context, filter model.MemoryEdgeListFilter) ([]*model.MemoryEdge, error)
}

MemoryEdgeUsecase exposes write + read operations on the memory graph overlay introduced for #573.

func NewMemoryEdgeUsecase added in v0.9.0

func NewMemoryEdgeUsecase(
	repository model.MemoryEdgeRepository,
	queryService model.MemoryEdgeQueryService,
	nowFunc func() time.Time,
) MemoryEdgeUsecase

NewMemoryEdgeUsecase constructs a MemoryEdgeUsecase bound to the given write + read dependencies. nowFunc is injected so tests can pin validFrom's default without touching real clocks.

type MemoryToolUsecase added in v0.10.0

type MemoryToolUsecase interface {
	View(ctx context.Context, path string, viewRange []int) (string, error)
	Create(ctx context.Context, path string, fileText string) (string, error)
	StrReplace(ctx context.Context, path string, oldStr string, newStr string) (string, error)
	Insert(ctx context.Context, path string, insertLine int, insertText string) (string, error)
	Delete(ctx context.Context, path string) (string, error)
	Rename(ctx context.Context, oldPath string, newPath string) (string, error)
}

MemoryToolUsecase implements Anthropic's native memory-tool commands.

func NewMemoryToolUsecase added in v0.10.0

func NewMemoryToolUsecase(repository model.MemoryToolFileRepository, clock types.Clock) MemoryToolUsecase

NewMemoryToolUsecase creates a usecase for Anthropic memory-tool commands.

type MemoryUsecase added in v0.5.0

type MemoryUsecase interface {
	// Lifecycle
	// Remember records an accepted memory directly.
	Remember(
		ctx context.Context,
		memoryType domtypes.MemoryType,
		scope domtypes.MemoryScope,
		fact string,
		confidence domtypes.Optional[domtypes.Confidence],
		source domtypes.MemorySource,
		evidenceRefs []domtypes.EvidenceRef,
		artifactRefs []domtypes.ArtifactRef,
	) (apptypes.MemoryDetails, error)

	// Propose records a candidate memory that still requires review.
	Propose(
		ctx context.Context,
		memoryType domtypes.MemoryType,
		scope domtypes.MemoryScope,
		fact string,
		source domtypes.MemorySource,
		evidenceRefs []domtypes.EvidenceRef,
		artifactRefs []domtypes.ArtifactRef,
	) (apptypes.MemoryDetails, error)

	// Accept accepts an existing candidate memory.
	Accept(ctx context.Context, memoryID domtypes.MemoryID, confidence domtypes.Optional[domtypes.Confidence]) (apptypes.MemoryDetails, error)

	// Distill turns one or more candidate memories into a new accepted
	// operator-provided memory while preserving source refs.
	Distill(ctx context.Context, criteria apptypes.MemoryDistillCriteria) (apptypes.MemoryDistillResult, error)

	// Reject rejects an existing candidate memory.
	Reject(ctx context.Context, memoryID domtypes.MemoryID) (apptypes.MemoryDetails, error)

	// AttachCandidateRefs attaches supporting refs to an existing candidate
	// memory without changing its lifecycle status. New evidence is required
	// unless the candidate already has evidence; artifact-only attachments are
	// allowed only for already substantiated candidates.
	AttachCandidateRefs(
		ctx context.Context,
		memoryID domtypes.MemoryID,
		evidenceRefs []domtypes.EvidenceRef,
		artifactRefs []domtypes.ArtifactRef,
	) (apptypes.MemoryDetails, error)

	// Supersede replaces an accepted memory with a new accepted memory.
	// validFrom / validTo control the replacement's temporal validity
	// window. Both default to the legacy behaviour (validFrom=now,
	// validTo=open-ended) when None, which keeps manual supersede
	// compatible with pre-v0.8.1 callers. Callers that need to carry
	// a bounded window over to the replacement (e.g. the hygiene
	// `validity_overlap_supersede` apply) must pass the explicit
	// window through — without this, applying the suggestion would
	// discard the very window that caused the pair to be flagged.
	Supersede(
		ctx context.Context,
		memoryID domtypes.MemoryID,
		memoryType domtypes.MemoryType,
		scope domtypes.MemoryScope,
		fact string,
		confidence domtypes.Optional[domtypes.Confidence],
		source domtypes.MemorySource,
		evidenceRefs []domtypes.EvidenceRef,
		artifactRefs []domtypes.ArtifactRef,
		validFrom domtypes.Optional[time.Time],
		validTo domtypes.Optional[time.Time],
	) (apptypes.MemoryDetails, error)

	// Expire expires an active memory at the given time. Empty expiry means now.
	Expire(ctx context.Context, memoryID domtypes.MemoryID, expiresAt domtypes.Optional[time.Time]) (apptypes.MemoryDetails, error)

	// SetValidity sets the content-validity window (valid_from / valid_to)
	// on an existing memory. Either bound may be omitted to leave the
	// current value unchanged. Set clearValidTo=true to explicitly
	// remove an existing validTo (return the memory to open-ended
	// validity). clearValidTo=true with a non-empty validTo argument
	// is invalid.
	SetValidity(
		ctx context.Context,
		memoryID domtypes.MemoryID,
		validFrom domtypes.Optional[time.Time],
		validTo domtypes.Optional[time.Time],
		clearValidTo bool,
	) (apptypes.MemoryDetails, error)

	// List returns memory summaries matching the criteria.
	List(ctx context.Context, criteria apptypes.MemoryListCriteria) ([]apptypes.MemorySummary, error)

	// ListStale returns stale durable-memory rows and the total count before
	// paging. It is a read-side helper for the top dashboard's stale-memory
	// pane.
	ListStale(ctx context.Context, criteria apptypes.StaleMemoryListCriteria) (apptypes.StaleMemoryListResult, error)

	// Search searches durable memories.
	Search(ctx context.Context, criteria apptypes.MemorySearchCriteria) ([]apptypes.MemorySummary, error)

	// Show returns the details for a single durable memory.
	Show(ctx context.Context, memoryID domtypes.MemoryID) (apptypes.MemoryDetails, error)

	// Extract proposes candidate memories from existing session/history signals.
	Extract(ctx context.Context, criteria apptypes.MemoryExtractionCriteria) ([]apptypes.MemoryDetails, error)

	// ExplainExtraction returns segment-level extraction diagnostics without proposing candidates.
	ExplainExtraction(ctx context.Context, criteria apptypes.MemoryExtractionCriteria) (apptypes.MemoryExtractionDebugReport, error)

	// ImportCodex proposes candidate memories from host-native Codex memory sources.
	ImportCodex(ctx context.Context, criteria apptypes.CodexImportCriteria) (apptypes.MemoryImportResult, error)

	// ImportInstructions proposes candidate memories from host instruction files.
	ImportInstructions(ctx context.Context, criteria apptypes.MemoryBridgeImportCriteria) (apptypes.MemoryBridgeImportResult, error)

	// Decay expires eligible auto-extracted candidates (dry-run by default)
	// and optionally collapses exact duplicate candidates. Never auto-accepts.
	Decay(ctx context.Context, criteria apptypes.MemoryDecayCriteria) (apptypes.MemoryDecayResult, error)

	// Restore returns an expired memory to candidate status for re-review.
	Restore(ctx context.Context, memoryID domtypes.MemoryID) (apptypes.MemoryDetails, error)

	// Scan surfaces suggestions for accepted durable memories that need attention.
	Scan(ctx context.Context, criteria apptypes.MemoryHygieneScanCriteria) (apptypes.MemoryHygieneScanResult, error)

	// Apply commits lifecycle transitions for matching hygiene suggestions.
	Apply(ctx context.Context, criteria apptypes.MemoryHygieneApplyCriteria) (apptypes.MemoryHygieneApplyResult, error)

	// Export serializes accepted durable memories into host instruction markdown.
	Export(ctx context.Context, criteria apptypes.MemoryExportCriteria) (apptypes.MemoryExportResult, error)

	// ActivatePlan resolves a host-native activation target and renders the dry-run content.
	ActivatePlan(ctx context.Context, criteria apptypes.MemoryActivationCriteria) (apptypes.MemoryActivationPlan, error)

	// Activate writes accepted durable memories into a host-native activation target.
	Activate(ctx context.Context, criteria apptypes.MemoryActivationCriteria) (apptypes.MemoryActivationApplyResult, error)

	// ActivationStatus compares the host-native activation target with the current accepted memories.
	ActivationStatus(ctx context.Context, criteria apptypes.MemoryActivationCriteria) (apptypes.MemoryActivationStatusResult, error)
}

MemoryUsecase consolidates durable-memory lifecycle, query, capture, hygiene, and export operations.

func NewMemoryUsecase added in v0.5.0

func NewMemoryUsecase(
	memoryRepo model.MemoryRepository,
	memoryQuery queryservice.MemoryQueryService,
	extraRedactPatterns []string,
	optionalDeps ...MemoryUsecaseDependencies,
) MemoryUsecase

NewMemoryUsecase creates a consolidated MemoryUsecase facade.

type MemoryUsecaseDependencies added in v0.10.0

type MemoryUsecaseDependencies struct {
	SessionQuery queryservice.SessionQueryService
	EventQuery   queryservice.EventQueryService
	CodexSource  application.CodexMemorySource
}

MemoryUsecaseDependencies carries the optional dependency set needed by capture, hygiene, and export methods on the consolidated MemoryUsecase.

The parameter remains optional during the adapter-shim transition so legacy lifecycle/query-only call sites keep compiling until DI is collapsed.

type OneShotRepairUsecase added in v0.31.0

type OneShotRepairUsecase interface {
	Preview(ctx context.Context, params apptypes.OneShotRepairParams) (apptypes.OneShotRepairResult, error)
	Apply(ctx context.Context, params apptypes.OneShotRepairApplyParams) (apptypes.OneShotRepairResult, error)
}

OneShotRepairUsecase validates authoritative repair evidence and delegates one consistent dry-run or atomic apply operation.

func NewOneShotRepairUsecase added in v0.31.0

NewOneShotRepairUsecase creates the evidence-backed repair use case.

type RawBodyRetentionUsecase added in v0.31.0

type RawBodyRetentionUsecase interface {
	CreatePlan(ctx context.Context, before time.Time, recoveryPath string, now time.Time) ([]byte, error)
	Apply(ctx context.Context, planData []byte, recoveryPath, confirmedPlanID string, now time.Time) (apptypes.RawBodyApplyResult, error)
	Restore(ctx context.Context, planData []byte, recoveryPath, confirmedPlanID string, now time.Time) (apptypes.RawBodyRestoreResult, error)
}

RawBodyRetentionUsecase creates and executes reviewed raw-body plans.

func NewRawBodyRetentionUsecase added in v0.31.0

NewRawBodyRetentionUsecase creates the explicit plan/apply/restore workflow.

type ReplayUsecase added in v0.8.0

type ReplayUsecase interface {
	// Bundle returns a ReplayBundle that captures recent sessions (each
	// with its per-session event slice) plus the memory panel scoped to
	// those sessions' workspaces.
	Bundle(ctx context.Context, criteria apptypes.ReplayCriteria) (apptypes.ReplayBundle, error)
}

ReplayUsecase assembles a cross-aggregate bundle for the replay HTML export. It hides the session / event / memory query orchestration behind a single call so the CLI layer only renders.

func NewReplayUsecase added in v0.8.0

func NewReplayUsecase(
	sessionQuery queryservice.SessionQueryService,
	eventQuery queryservice.EventQueryService,
	memoryQuery queryservice.MemoryQueryService,
) ReplayUsecase

NewReplayUsecase creates a ReplayUsecase backed by the read-side query services. memoryQuery may be nil — the bundle will simply omit the memory panel in that case.

Using query services directly (instead of write-side usecases) keeps the replay path on the read-only surface, consistent with ContextUsecase and the other cross-aggregate assemblers in this package.

type ReportCommandUsecase added in v0.31.0

type ReportCommandUsecase interface {
	Summarize(ctx context.Context, criteria apptypes.EventListCriteria) (apptypes.ReportCommandSummary, error)
}

ReportCommandUsecase aggregates structured command outcomes for reports.

func NewReportCommandUsecase added in v0.31.0

func NewReportCommandUsecase(query queryservice.CommandAuditQueryService) ReportCommandUsecase

NewReportCommandUsecase creates the structured command report use case.

type ReportUsecase added in v0.31.0

type ReportUsecase interface {
	Generate(ctx context.Context, criteria apptypes.ReportCriteria) (apptypes.ReportSnapshot, error)
}

ReportUsecase generates the shared CLI/MCP report snapshot.

func NewReportUsecase added in v0.31.0

func NewReportUsecase(query queryservice.ReportQueryService) ReportUsecase

NewReportUsecase creates the shared CLI/MCP aggregate generator.

type RunLineageUsecase added in v0.32.0

type RunLineageUsecase interface {
	Record(ctx context.Context, lineage *model.RunLineage) (model.RunLineageTransition, error)
}

RunLineageUsecase is the write boundary consumed by host adapters.

func NewRunLineageUsecase added in v0.32.0

func NewRunLineageUsecase(repository model.RunLineageRepository) RunLineageUsecase

NewRunLineageUsecase creates a provider-neutral lineage write usecase.

type SessionEventCoverage added in v0.21.0

type SessionEventCoverage struct {
	// Sessions counts only sessions whose session_started event was
	// observed in the scanned window. List queries return newest-first, so
	// observing the start means every subsequent event of that session is
	// also in the window — this avoids misclassifying a truncated session
	// (start out of window) as prompt/transcript-missing.
	Sessions                int
	BoundaryOnly            int
	Enriched                int
	Complete                int
	PromptTranscriptMissing int
	WithPrompt              int
	WithTranscript          int
	WithCommand             int
}

SessionEventCoverage reports how many recent sessions captured prompt and transcript events versus sessions that are missing either conversation surface. Command audits are counted separately, but they do not make a session healthy for this diagnostic: a stale install that wires only session boundaries plus AfterTool still misses the core prompt/transcript capture.

func SummarizeSessionEventCoverage added in v0.21.0

func SummarizeSessionEventCoverage(events []EventCoverageInput) SessionEventCoverage

SummarizeSessionEventCoverage classifies the given event observations into per-session coverage counts. Prompt and transcript are the conversation enrichment kinds. Command audits are useful evidence and are counted in WithCommand, but command-only, prompt-only, and transcript-only sessions are still reported as prompt/transcript-missing for the strict coverage ratio because they lack part of the data this diagnostic is meant to protect. Everything else (session boundaries, compact summaries, notes, …) is neutral. The function is pure and client-agnostic so the same classifier can back the gemini and claude coverage diagnostics.

func (SessionEventCoverage) BoundaryOnlyRatio added in v0.21.0

func (s SessionEventCoverage) BoundaryOnlyRatio() float64

BoundaryOnlyRatio returns BoundaryOnly / Sessions, or 0 when no sessions were counted (so callers can compare against a threshold without guarding against division by zero).

func (SessionEventCoverage) PromptTranscriptMissingRatio added in v0.21.0

func (s SessionEventCoverage) PromptTranscriptMissingRatio() float64

PromptTranscriptMissingRatio returns the fraction of observed complete sessions that are missing either the prompt or transcript event. This is the stricter health signal used by doctor: a prompt-only or transcript-only session still indicates a hook coverage gap even though it is not boundary only.

type SessionUsecase added in v0.3.0

type SessionUsecase interface {
	// Start begins a new session. If sessionID is zero, a new ID is generated.
	// Zero-value parentSessionID means no parent (top-level session).
	Start(ctx context.Context, client types.Client, agent types.Agent, sessionID types.SessionID, workspace types.Workspace, parentSessionID types.SessionID) (*model.Event, error)

	// StartWithRuntimeMode begins a session under an explicit non-zero runtime
	// lifecycle contract. Zero-value parentSessionID means no parent.
	StartWithRuntimeMode(ctx context.Context, client types.Client, agent types.Agent, sessionID types.SessionID, workspace types.Workspace, parentSessionID types.SessionID, runtimeMode types.RuntimeMode) (*model.Event, error)

	// StartChild begins a child session spawned from an existing parent.
	StartChild(ctx context.Context, parent types.SessionID, childID types.SessionID, agent types.Agent, workspace types.Workspace, spawnEventID types.EventID, kind string, startedAt time.Time) (*model.Event, error)

	// End closes an existing session. Zero-value client/agent/workspace
	// falls back to values from the corresponding session_started event.
	End(ctx context.Context, client types.Client, agent types.Agent, sessionID types.SessionID, workspace types.Workspace, summary string) (*model.Event, error)

	// FinalizeOneShot applies one authoritative terminal reason to an explicit
	// one-shot session. Same-reason retries return already_applied without
	// writing another boundary event; other runtime modes and conflicts fail closed.
	FinalizeOneShot(ctx context.Context, client types.Client, agent types.Agent, sessionID types.SessionID, workspace types.Workspace, reason types.TerminalReason, summary string) (model.SessionTerminalTransition, *model.Event, error)

	// Label updates the label on an existing session.
	Label(ctx context.Context, sessionID types.SessionID, label string) error

	// List returns session summaries matching the criteria.
	List(ctx context.Context, criteria apptypes.SessionListCriteria) ([]apptypes.SessionSummary, error)

	// FindEndedSessionIDs returns the subset of sessionIDs that have a persisted end boundary.
	FindEndedSessionIDs(ctx context.Context, sessionIDs []types.SessionID) (map[types.SessionID]struct{}, error)

	// Tree returns session summaries as a hierarchy for the given workspace.
	// Zero-value workspace returns sessions across all workspaces. When rootSessionID
	// is set, the requested root is included regardless of the limit window.
	Tree(ctx context.Context, workspace types.Workspace, rootSessionID types.SessionID, limit int) ([]apptypes.SessionSummary, error)

	// Lineage returns the full hierarchy rooted at the topmost ancestor of sessionID.
	Lineage(ctx context.Context, sessionID types.SessionID) ([]apptypes.SessionSummary, error)

	// Active returns the session_started event for the active session matching the criteria.
	// Returns an empty Optional when no active session exists.
	Active(ctx context.Context, criteria apptypes.SessionLookupCriteria) (types.Optional[*model.Event], error)

	// Latest returns the session_started event for the latest session matching the criteria.
	// Returns an empty Optional when no matching session exists.
	Latest(ctx context.Context, criteria apptypes.SessionLookupCriteria) (types.Optional[*model.Event], error)

	// SetSummaryIfEmpty stores summary into sessions.summary when the existing
	// value is NULL or empty. Manually authored summaries are preserved.
	// Returns true when a row was actually updated.
	SetSummaryIfEmpty(ctx context.Context, sessionID types.SessionID, summary string) (bool, error)

	// SetModelIfEmpty stores a host-reported model identifier when the session
	// row still has an empty model. Empty input is a no-op. Never fabricates
	// a model value.
	SetModelIfEmpty(ctx context.Context, sessionID types.SessionID, model string) (bool, error)

	// Handoff returns the legacy session handoff summary shape used by older CLI
	// and MCP callers.
	//
	// New callers that want the structured working-memory pack should prefer
	// ContextUsecase.Handoff instead. Zero-value workspace means no workspace
	// filter. Returns an empty Optional when no matching session exists.
	Handoff(ctx context.Context, sessionID types.SessionID, workspace types.Workspace, recent int) (types.Optional[apptypes.HandoffSummary], error)
}

SessionUsecase consolidates session lifecycle operations plus the legacy session-level query surfaces that remain for compatibility.

func NewSessionUsecase added in v0.4.0

func NewSessionUsecase(
	eventRepo model.EventRepository,
	sessionRepo model.SessionRepository,
	sessionQuery queryservice.SessionQueryService,
	eventQuery queryservice.EventQueryService,
) SessionUsecase

NewSessionUsecase creates a SessionUsecase.

type StoreManagementUsecase added in v0.4.0

type StoreManagementUsecase interface {
	// Initialize creates the store and applies migrations.
	Initialize(ctx context.Context) error

	// CreateBackup creates a backup of the store.
	CreateBackup(ctx context.Context, outputPath string, overwrite bool) error

	// RestoreBackup restores a backup into the store.
	RestoreBackup(ctx context.Context, inputPath string, overwrite bool) error

	// CollectGarbage removes events older than the given time.
	CollectGarbage(ctx context.Context, before time.Time, target apptypes.GarbageCollectionTarget, dryRun bool) (apptypes.CollectGarbageResult, error)

	// CloseStaleSessions closes sessions that started before the threshold and
	// have no activity inside it, excluding the protected active sessions.
	CloseStaleSessions(ctx context.Context, staleAfter time.Duration, dryRun bool, protectedSessionIDs []types.SessionID) (apptypes.CloseStaleSessionsResult, error)

	// DedupeContentEvents reports (dry-run) or quarantines (apply) historical
	// hook-originated prompt/transcript duplicate rows.
	DedupeContentEvents(ctx context.Context, params apptypes.ContentEventDedupeParams) (apptypes.ContentEventDedupeResult, error)

	// RestoreContentEventDedupeRun reverses a quarantine run, moving its rows
	// back into events.
	RestoreContentEventDedupeRun(ctx context.Context, runID string) (apptypes.ContentEventDedupeRestoreResult, error)

	// CreateStoreArchive exports GC-eligible rows to a versioned archive package.
	// When DeleteAfterVerify is set, verifies the package then deletes exact IDs.
	CreateStoreArchive(ctx context.Context, params apptypes.StoreArchiveCreateParams) (apptypes.StoreArchiveResult, error)
	// VerifyStoreArchive checks package integrity (and decryptability when sealed).
	VerifyStoreArchive(ctx context.Context, path string, passphrase []byte) error
	// RestoreStoreArchive imports archived rows idempotently by primary key.
	RestoreStoreArchive(ctx context.Context, path string, passphrase []byte, dryRun bool) (apptypes.StoreArchiveRestoreResult, error)
}

StoreManagementUsecase consolidates store lifecycle operations.

func NewStoreManagementUsecase added in v0.4.0

func NewStoreManagementUsecase(storeManager application.StoreManager) StoreManagementUsecase

NewStoreManagementUsecase creates a StoreManagementUsecase.

type UsageObservationUsecase added in v0.32.0

type UsageObservationUsecase interface {
	Record(ctx context.Context, observation *model.UsageObservation) (model.UsageObservationTransition, error)
}

UsageObservationUsecase is the write boundary consumed by host usage adapters. Domain and repository layers own validity and idempotency.

func NewUsageObservationUsecase added in v0.32.0

func NewUsageObservationUsecase(repository model.UsageObservationRepository) UsageObservationUsecase

NewUsageObservationUsecase creates the provider-neutral usage write usecase.

type WorkspaceIdentityUsecase added in v0.31.0

type WorkspaceIdentityUsecase interface {
	Report(ctx context.Context, conflictSampleLimit int) (apptypes.WorkspaceIdentityReport, error)
	AddAlias(ctx context.Context, sessionID types.SessionID, workspace types.Workspace, reviewedBy, note string) error
	RemoveAlias(ctx context.Context, sessionID types.SessionID, workspace types.Workspace) error
}

WorkspaceIdentityUsecase exposes body-free reports and reviewed alias changes.

func NewWorkspaceIdentityUsecase added in v0.31.0

NewWorkspaceIdentityUsecase constructs workspace identity reporting and alias orchestration.

Jump to

Keyboard shortcuts

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