Documentation
¶
Overview ¶
Package sqlite provides SQLite persistence for Cortex.
Package sqlite implements the SQLite memory store for Cortex.
It provides CRUD operations for observations with deduplication by normalized_hash, topic key upsert, and soft/hard delete support. The store implements the domain.ObservationRepository interface.
Package sqlite implements the SQLite memory store for Cortex.
This file provides the transactional outbox store (ADR-04, W4, REQ-EMB-002). The outbox commits embed+upsert intents in the SAME transaction as the observation write; the embedding worker leases and processes them asynchronously with retry, capped backoff, and dead-letter for terminal failures.
Package sqlite provides concrete implementations of repository interfaces for SQLite-based persistence in Cortex.
This package contains the actual database implementations that bridge the domain models with SQLite storage, implementing all the repository interfaces defined in the domain package.
Package sqlite: shared embedding-dimension constants.
These constants are shared between the stub (default, zero-CGO) and the cortex_vectors-enabled BLOB scan builds. Declaring them in a build-tag- agnostic file lets the sqlite_blob adapter (W8.1, ADR-05) reference them under BOTH builds without duplicating or guarding them.
Moving them here from vector_store_enabled.go is a pure refactor: the enabled build referenced them via package scope and continues to do so; the stub build gains visibility (it does not use them at runtime but the adapter declares them in its Capabilities).
Package sqlite implements the SQLite memory store for Cortex.
This file provides a stub implementation of the VectorStore when the cortex_vectors build tag is not enabled. All methods return ErrVectorSearchDisabled.
Index ¶
- Constants
- type CodeStore
- func (s *CodeStore) CountSymbols(ctx context.Context, filter code.SymbolFilter) (int, error)
- func (s *CodeStore) DeleteRelationsByFile(ctx context.Context, project, filePath string) error
- func (s *CodeStore) DeleteRelationsByProject(ctx context.Context, project string) error
- func (s *CodeStore) DeleteSymbolsByFile(ctx context.Context, project, filePath string) error
- func (s *CodeStore) DeleteSymbolsByProject(ctx context.Context, project string) error
- func (s *CodeStore) GetGraph(ctx context.Context, project string) (*code.CodeGraph, error)
- func (s *CodeStore) GetSymbolByID(ctx context.Context, id string) (*code.Symbol, error)
- func (s *CodeStore) ListRelationsBySymbol(ctx context.Context, symbolID string) ([]code.Relation, error)
- func (s *CodeStore) ListSymbols(ctx context.Context, filter code.SymbolFilter) ([]code.Symbol, error)
- func (s *CodeStore) SaveRelations(ctx context.Context, relations []code.Relation) error
- func (s *CodeStore) SaveSymbols(ctx context.Context, symbols []code.Symbol) error
- type ConsolidationGroup
- type ExportData
- type MergeResult
- type MetricsRepository
- func (r *MetricsRepository) CreateMetric(ctx context.Context, metric *domain.Metrics) error
- func (r *MetricsRepository) GetAggregatedMetrics(ctx context.Context, from, to time.Time) (*domain.AggregatedMetrics, error)
- func (r *MetricsRepository) GetByOperationType(ctx context.Context, operationType string, from, to time.Time) ([]*domain.Metrics, error)
- func (r *MetricsRepository) GetTemporalMetrics(ctx context.Context, sessionID string, from, to time.Time) ([]*domain.Metrics, error)
- type OutboxIntent
- type OutboxStore
- func (s *OutboxStore) DeadLetter(ctx context.Context, id int64, cause error) error
- func (s *OutboxStore) EnqueueInTx(ctx context.Context, observationID int64, intent, modelInfo string) error
- func (s *OutboxStore) Lease(ctx context.Context, limit int) ([]OutboxIntent, error)
- func (s *OutboxStore) MarkComplete(ctx context.Context, id int64) error
- func (s *OutboxStore) MarkFailed(ctx context.Context, id int64, cause error, nextRetryAt time.Time) error
- func (s *OutboxStore) PendingCount(ctx context.Context) (int, error)
- func (s *OutboxStore) RecoverPending(ctx context.Context) error
- func (s *OutboxStore) UpdateIndexState(ctx context.Context, namespace string, coverage float64, parity int) error
- func (s *OutboxStore) WithinTx(ctx context.Context, handle any, fn func(context.Context) error) error
- type QualityMetricsRepository
- func (r *QualityMetricsRepository) CreateQualityMetric(ctx context.Context, quality *domain.QualityMetrics) error
- func (r *QualityMetricsRepository) GetBySession(ctx context.Context, sessionID string, limit int) ([]*domain.QualityMetrics, error)
- func (r *QualityMetricsRepository) GetByType(ctx context.Context, evaluationType string, from, to time.Time) ([]*domain.QualityMetrics, error)
- func (r *QualityMetricsRepository) GetLatest(ctx context.Context, limit int) ([]*domain.QualityMetrics, error)
- type Stats
- type Store
- func (s *Store) CountAll(ctx context.Context) (int, error)
- func (s *Store) CountByRoot(ctx context.Context, rootObsID int64) (int, error)
- func (s *Store) DB() *sql.DB
- func (s *Store) Delete(ctx context.Context, id int64) error
- func (s *Store) ExportAll(ctx context.Context) (*ExportData, error)
- func (s *Store) FindConsolidationCandidates(ctx context.Context, project string, minCount int) ([]ConsolidationGroup, error)
- func (s *Store) GetByID(ctx context.Context, id int64) (*domain.Observation, error)
- func (s *Store) GetByIDs(ctx context.Context, ids []int64) (map[int64]*domain.Observation, error)
- func (s *Store) GetBySource(ctx context.Context, source string, limit int) ([]*domain.Observation, error)
- func (s *Store) GetByTopicKey(ctx context.Context, project, topicKey string) (*domain.Observation, error)
- func (s *Store) GetByType(ctx context.Context, obsType string, limit int) ([]*domain.Observation, error)
- func (s *Store) GetSearchFeedbackStats(ctx context.Context) (totalEntries int, uniqueQueries int, err error)
- func (s *Store) GetSyncedChunks(ctx context.Context) (map[string]bool, error)
- func (s *Store) HardDelete(ctx context.Context, id int64) error
- func (s *Store) ImportData(ctx context.Context, data *ExportData) (*SyncImportResult, error)
- func (s *Store) List(ctx context.Context, filter domain.ObservationFilter) ([]*domain.Observation, error)
- func (s *Store) ListArchivable(ctx context.Context, cutoff time.Time, minScore float64, limit int) ([]*domain.Observation, error)
- func (s *Store) ListByTopicKey(ctx context.Context, project, topicKey string) ([]*domain.Observation, error)
- func (s *Store) MergeProjects(ctx context.Context, sources []string, canonical string) (*MergeResult, error)
- func (s *Store) OrphanObservations(ctx context.Context, project string, limit int) ([]*domain.Observation, error)
- func (s *Store) RecordSearchFeedback(ctx context.Context, query string, observationID int64, rankPosition int) error
- func (s *Store) RecordSyncedChunk(ctx context.Context, chunkID string) error
- func (s *Store) Restore(ctx context.Context, id int64) error
- func (s *Store) Save(ctx context.Context, obs *domain.Observation) error
- func (s *Store) SaveHandoffWithEffect(ctx context.Context, obs *domain.Observation) (domain.SaveEffect, error)
- func (s *Store) SaveInTx(ctx context.Context, obs *domain.Observation) error
- func (s *Store) SaveWithEffect(ctx context.Context, obs *domain.Observation) (domain.SaveEffect, error)
- func (s *Store) SoftDelete(ctx context.Context, id int64) error
- func (s *Store) StaleObservations(ctx context.Context, project string, minScore float64, daysSinceAccess int) ([]*domain.Observation, error)
- func (s *Store) Stats(ctx context.Context) (*Stats, error)
- func (s *Store) Unarchive(ctx context.Context, id int64) error
- func (s *Store) Update(ctx context.Context, obs *domain.Observation) error
- func (s *Store) WithinTx(ctx context.Context, handle any, fn func(context.Context) error) error
- type SyncImportResult
- type TemporalSnapshotRepository
- func (r *TemporalSnapshotRepository) CreateSnapshot(ctx context.Context, snapshot *domain.TemporalSnapshot) error
- func (r *TemporalSnapshotRepository) GetByID(ctx context.Context, id int64) (*domain.TemporalSnapshot, error)
- func (r *TemporalSnapshotRepository) GetByRootObservation(ctx context.Context, rootObsID int64) ([]*domain.TemporalSnapshot, error)
- func (r *TemporalSnapshotRepository) GetBySnapshotKey(ctx context.Context, snapshotKey string) ([]*domain.TemporalSnapshot, error)
- func (r *TemporalSnapshotRepository) GetSnapshotsInRange(ctx context.Context, from, to time.Time) ([]*domain.TemporalSnapshot, error)
- type VectorStore
- func (s *VectorStore) DeleteEmbedding(ctx context.Context, observationID int64) error
- func (s *VectorStore) GetEmbedding(ctx context.Context, observationID int64) ([]float32, string, error)
- func (s *VectorStore) IsAvailable() bool
- func (s *VectorStore) SearchByVector(ctx context.Context, opts domain.VectorSearchOptions) ([]*domain.VectorSearchResult, error)
- func (s *VectorStore) StoreEmbedding(ctx context.Context, observationID int64, embedding []float32, model string) error
Constants ¶
const ( OutboxStatusPending = "pending" OutboxStatusLeased = "leased" OutboxStatusComplete = "complete" OutboxStatusDeadLetter = "dead_letter" )
Outbox status constants. Stored in index_outbox.status.
const ( // DefaultEmbeddingDimension is the default dimension for embeddings. DefaultEmbeddingDimension = 768 // MinEmbeddingDimension and MaxEmbeddingDimension set valid bounds. MinEmbeddingDimension = 64 MaxEmbeddingDimension = 4096 )
Embedding dimension bounds. Common dimensions: 384 (MiniLM), 768 (nomic-embed-text), 1536 (OpenAI text-embedding-3-small).
const OutboxDefaultMaxAttempts = 5
OutboxDefaultMaxAttempts is the default retry cap for embed intents.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CodeStore ¶ added in v2.3.0
type CodeStore struct {
// contains filtered or unexported fields
}
CodeStore implements code.Store over SQLite.
func NewCodeStore ¶ added in v2.3.0
NewCodeStore creates and initializes a CodeStore, ensuring tables exist.
func (*CodeStore) CountSymbols ¶ added in v2.3.0
CountSymbols counts symbols matching filter parameters.
func (*CodeStore) DeleteRelationsByFile ¶ added in v2.3.0
DeleteRelationsByFile removes relationships whose source or target symbol matches the file path.
func (*CodeStore) DeleteRelationsByProject ¶ added in v2.3.0
DeleteRelationsByProject removes all relationships for a project.
func (*CodeStore) DeleteSymbolsByFile ¶ added in v2.3.0
DeleteSymbolsByFile removes indexed symbols for a specific file.
func (*CodeStore) DeleteSymbolsByProject ¶ added in v2.3.0
DeleteSymbolsByProject removes all indexed symbols for a project.
func (*CodeStore) GetSymbolByID ¶ added in v2.3.0
GetSymbolByID retrieves a single symbol by its ID.
func (*CodeStore) ListRelationsBySymbol ¶ added in v2.3.0
func (s *CodeStore) ListRelationsBySymbol(ctx context.Context, symbolID string) ([]code.Relation, error)
ListRelationsBySymbol retrieves all outbound and inbound relationships for a symbol.
func (*CodeStore) ListSymbols ¶ added in v2.3.0
func (s *CodeStore) ListSymbols(ctx context.Context, filter code.SymbolFilter) ([]code.Symbol, error)
ListSymbols queries symbols matching filter parameters.
func (*CodeStore) SaveRelations ¶ added in v2.3.0
SaveRelations writes code relationships in an atomic transaction.
type ConsolidationGroup ¶
ConsolidationGroup represents a topic key with multiple observations.
type ExportData ¶
type ExportData struct {
Version string `json:"version"`
ExportedAt string `json:"exported_at"`
Sessions []*domain.Session `json:"sessions"`
Observations []*domain.Observation `json:"observations"`
Prompts []*domain.Prompt `json:"prompts"`
}
ExportData holds all data for sync export.
type MergeResult ¶
type MergeResult struct {
Canonical string `json:"canonical"`
SourcesMerged []string `json:"sources_merged"`
ObservationsUpdated int64 `json:"observations_updated"`
SessionsUpdated int64 `json:"sessions_updated"`
}
MergeResult holds the outcome of a project merge operation.
type MetricsRepository ¶
type MetricsRepository struct {
// contains filtered or unexported fields
}
MetricsRepository implements the MetricsRepository interface using SQLite.
func NewMetricsRepository ¶
func NewMetricsRepository(db *sql.DB) *MetricsRepository
NewMetricsRepository creates a new metrics repository with the given database connection.
func (*MetricsRepository) CreateMetric ¶
CreateMetric records a performance metric.
func (*MetricsRepository) GetAggregatedMetrics ¶
func (r *MetricsRepository) GetAggregatedMetrics(ctx context.Context, from, to time.Time) (*domain.AggregatedMetrics, error)
GetAggregatedMetrics gets aggregated metrics for a time range.
type OutboxIntent ¶
type OutboxIntent struct {
ID int64
ObservationID int64
Intent string
ModelInfo string
Status string
Attempts int
MaxAttempts int
NextRetryAt sql.NullString
LeasedAt sql.NullString
CompletedAt sql.NullString
Error sql.NullString
CreatedAt string
}
OutboxIntent is a single durable embed+upsert intent in the outbox.
type OutboxStore ¶
type OutboxStore struct {
// contains filtered or unexported fields
}
OutboxStore reads and writes the index_outbox table. It implements domain.TxParticipant so the enqueue can be enlisted in the shared UnitOfWork transaction alongside the observation write (REQ-EMB-002 atomicity).
func NewOutboxStore ¶
func NewOutboxStore(db *sql.DB) *OutboxStore
NewOutboxStore creates an outbox store backed by the given database. The database must have the index_outbox table (created by migrations/v2/001_init.sql).
func (*OutboxStore) DeadLetter ¶
DeadLetter explicitly transitions an intent to 'dead_letter' (terminal). Used for non-retryable failures (e.g. model not found, dimension mismatch).
func (*OutboxStore) EnqueueInTx ¶
func (s *OutboxStore) EnqueueInTx(ctx context.Context, observationID int64, intent, modelInfo string) error
EnqueueInTx inserts a pending embed+upsert intent into index_outbox using the shared transaction previously stashed in the context by WithinTx. It MUST be called from within a WithinTx closure (or any context that carries a txKey). The intent is committed atomically with the observation write (REQ-EMB-002).
func (*OutboxStore) Lease ¶
func (s *OutboxStore) Lease(ctx context.Context, limit int) ([]OutboxIntent, error)
Lease atomically claims up to limit pending intents whose retry delay has elapsed. Claimed intents transition to 'leased', have leased_at set to now, and attempts incremented (each lease counts as one processing attempt). Returns the claimed intents in id order.
func (*OutboxStore) MarkComplete ¶
func (s *OutboxStore) MarkComplete(ctx context.Context, id int64) error
MarkComplete transitions an intent to 'complete' with completed_at set.
func (*OutboxStore) MarkFailed ¶
func (s *OutboxStore) MarkFailed(ctx context.Context, id int64, cause error, nextRetryAt time.Time) error
MarkFailed records a processing failure. If the intent's current attempts count has reached its max_attempts, the intent is dead-lettered (terminal); otherwise it transitions back to 'pending' with next_retry_at set for capped backoff and the failure cause stored in the error column.
func (*OutboxStore) PendingCount ¶
func (s *OutboxStore) PendingCount(ctx context.Context) (int, error)
PendingCount returns the number of non-terminal intents (pending + leased). Used for saturation/overload detection in the save path (REQ-EMB-001).
func (*OutboxStore) RecoverPending ¶
func (s *OutboxStore) RecoverPending(ctx context.Context) error
RecoverPending resets all 'leased' intents back to 'pending'. Called on startup to recover intents claimed by a worker that died before completing (crash recovery, REQ-EMB-001).
func (*OutboxStore) UpdateIndexState ¶
func (s *OutboxStore) UpdateIndexState(ctx context.Context, namespace string, coverage float64, parity int) error
UpdateIndexState upserts a row into index_state for the given namespace, recording vector coverage and parity (namespace tracking, ADR-04 §F).
func (*OutboxStore) WithinTx ¶
func (s *OutboxStore) WithinTx(ctx context.Context, handle any, fn func(context.Context) error) error
WithinTx implements domain.TxParticipant. It type-asserts the handle to *sql.Tx, stashes it into the context under the same txKey used by Store, and invokes fn within that context. The fn closure can then call EnqueueInTx, which reads the shared tx via txFromContext.
WithinTx does NOT begin, commit, or roll back the transaction — the UnitOfWork that owns the shared tx is responsible for its lifecycle.
type QualityMetricsRepository ¶
type QualityMetricsRepository struct {
// contains filtered or unexported fields
}
QualityMetricsRepository implements the QualityMetricsRepository interface.
func NewQualityMetricsRepository ¶
func NewQualityMetricsRepository(db *sql.DB) *QualityMetricsRepository
NewQualityMetricsRepository creates a new quality metrics repository.
func (*QualityMetricsRepository) CreateQualityMetric ¶
func (r *QualityMetricsRepository) CreateQualityMetric(ctx context.Context, quality *domain.QualityMetrics) error
CreateQualityMetric records a quality evaluation result.
func (*QualityMetricsRepository) GetBySession ¶
func (r *QualityMetricsRepository) GetBySession(ctx context.Context, sessionID string, limit int) ([]*domain.QualityMetrics, error)
GetBySession retrieves quality metrics for a session.
func (*QualityMetricsRepository) GetByType ¶
func (r *QualityMetricsRepository) GetByType(ctx context.Context, evaluationType string, from, to time.Time) ([]*domain.QualityMetrics, error)
GetByType retrieves quality metrics filtered by evaluation type.
func (*QualityMetricsRepository) GetLatest ¶
func (r *QualityMetricsRepository) GetLatest(ctx context.Context, limit int) ([]*domain.QualityMetrics, error)
GetLatest gets the most recent quality metrics.
type Stats ¶
type Stats struct {
TotalObservations int `json:"total_observations"`
Projects []string `json:"projects"`
ByType map[string]int `json:"by_type"`
}
Stats holds aggregated statistics about observations.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store implements the SQLite observation store. It provides CRUD operations with deduplication, topic key upsert, and soft/hard delete support.
func (*Store) CountByRoot ¶
CountByRoot counts distinct observations reachable from a root observation.
func (*Store) DB ¶
DB returns the underlying *sql.DB shared by all SQLite stores. The UnitOfWork (W2.1) uses this to open ONE transaction that threads through every TxParticipant (ADR-02, REQ-TX-001).
func (*Store) Delete ¶
Delete removes an observation by ID (soft delete by default). Returns ErrNotFound if the observation doesn't exist or is already deleted.
func (*Store) ExportAll ¶
func (s *Store) ExportAll(ctx context.Context) (*ExportData, error)
ExportAll exports all sessions, observations, and prompts for sync.
func (*Store) FindConsolidationCandidates ¶
func (s *Store) FindConsolidationCandidates(ctx context.Context, project string, minCount int) ([]ConsolidationGroup, error)
FindConsolidationCandidates finds topic keys with multiple observations in a project.
func (*Store) GetByID ¶
GetByID retrieves an observation by its ID. Returns ErrNotFound if the observation doesn't exist or is soft-deleted.
func (*Store) GetByIDs ¶
GetByIDs retrieves live (non-soft-deleted) observations for a batch of IDs in as few statements as possible (VEC-01 batch hydration).
Semantics mirror GetByID exactly: the same canonical column set, the same deleted_at IS NULL visibility rule, and field-for-field identical row values, so hydrated rows are indistinguishable from per-ID lookups.
- Empty/nil ids returns an empty map and issues NO SQL.
- Soft-deleted and missing IDs are simply absent from the map.
- Duplicate IDs in the request are harmless (idempotent map inserts).
- Request lists longer than maxGetByIDsParameters are transparently chunked; each chunk runs its prepared statement once.
The hydration statements are prepared once per placeholder count and cached on the Store (see getByIDsStmts), eliminating the per-call SQL parse the one-shot path pays. This changes NO observable semantics: same statement text, same rows, same errors.
Errors propagate to the caller — the retrieval layer owns the legacy per-ID fallback when this optional batch path fails.
func (*Store) GetBySource ¶
func (s *Store) GetBySource(ctx context.Context, source string, limit int) ([]*domain.Observation, error)
GetBySource retrieves observations filtered by source type.
func (*Store) GetByTopicKey ¶
func (s *Store) GetByTopicKey(ctx context.Context, project, topicKey string) (*domain.Observation, error)
GetByTopicKey retrieves an observation by its topic key within a project. Returns ErrNotFound if no matching observation exists or is soft-deleted.
func (*Store) GetByType ¶
func (s *Store) GetByType(ctx context.Context, obsType string, limit int) ([]*domain.Observation, error)
GetByType retrieves observations filtered by type.
func (*Store) GetSearchFeedbackStats ¶
func (s *Store) GetSearchFeedbackStats(ctx context.Context) (totalEntries int, uniqueQueries int, err error)
GetSearchFeedbackStats returns basic stats about search feedback data.
func (*Store) GetSyncedChunks ¶
GetSyncedChunks returns a set of chunk IDs that have been imported/exported.
func (*Store) HardDelete ¶
HardDelete permanently removes an observation from the database. Returns ErrNotFound if the observation doesn't exist.
func (*Store) ImportData ¶
func (s *Store) ImportData(ctx context.Context, data *ExportData) (*SyncImportResult, error)
ImportData imports sessions, observations and prompts from an export. Sessions are skipped if they already exist (by ID). Observations and prompts get new auto-increment IDs.
func (*Store) List ¶
func (s *Store) List(ctx context.Context, filter domain.ObservationFilter) ([]*domain.Observation, error)
List retrieves observations based on filter criteria. An empty filter returns all observations up to the default limit (20).
func (*Store) ListArchivable ¶
func (s *Store) ListArchivable(ctx context.Context, cutoff time.Time, minScore float64, limit int) ([]*domain.Observation, error)
ListArchivable retrieves observations older than cutoff with score below minScore. Uses a JOIN with importance_scores to avoid N+1 queries during archival.
func (*Store) ListByTopicKey ¶
func (s *Store) ListByTopicKey(ctx context.Context, project, topicKey string) ([]*domain.Observation, error)
ListByTopicKey retrieves all observations for a project with the given topic key.
func (*Store) MergeProjects ¶
func (s *Store) MergeProjects(ctx context.Context, sources []string, canonical string) (*MergeResult, error)
MergeProjects moves all observations and sessions from source projects into a canonical project name. Sources that normalize to the canonical name are silently skipped.
func (*Store) OrphanObservations ¶
func (s *Store) OrphanObservations(ctx context.Context, project string, limit int) ([]*domain.Observation, error)
OrphanObservations returns observations with no graph edges.
func (*Store) RecordSearchFeedback ¶
func (s *Store) RecordSearchFeedback(ctx context.Context, query string, observationID int64, rankPosition int) error
RecordSearchFeedback logs an implicit signal: the user accessed an observation after performing a search. This data enables Learning-to-Rank model training.
func (*Store) RecordSyncedChunk ¶
RecordSyncedChunk marks a chunk as imported/exported (idempotent).
func (*Store) Save ¶
Save creates a new observation or updates an existing one if topic_key matches. It implements deduplication by normalized_hash within a configurable window.
Business Rules:
- If topic_key is provided and an observation with the same topic_key exists in the same project, update it instead of creating a new one.
- If normalized_hash matches an existing observation within the deduplication window, increment duplicate_count instead of creating a new one.
- Sets created_at and updated_at timestamps.
- Normalizes scope to "project" or "personal".
Dedup classification (REQ-FOUND-003, REQ-MCPH-002): when a TypeManual save hits the normalized_hash dedup path, Save returns a domain.NewDedupSkipped error (IsClass(err, ClassDedupSkipped) == true). Callers can use errors.As / domain.IsClass to distinguish an intentional dedup skip from a real persistence failure.
This method opens and commits its OWN transaction (local-mode path). For cross-store atomic saves, use SaveInTx within a UnitOfWork (W2.1, REQ-TX-001).
REM-SAVE-001/RD2: Save delegates to SaveWithEffect and preserves the exact legacy envelope and error surface — the interactive 64 KiB content limit and the ClassDedupSkipped dedup classification are unchanged.
func (*Store) SaveHandoffWithEffect ¶
func (s *Store) SaveHandoffWithEffect(ctx context.Context, obs *domain.Observation) (domain.SaveEffect, error)
SaveHandoffWithEffect is the specialized handoff save primitive: identical semantics to SaveWithEffect, but the content envelope is the domain handoff payload bound (1 MiB) because the canonical handoff payload was already validated and size-bounded at the domain layer (domain.CanonicalizeHandoff). It exists so the public Save/SaveWithEffect surface keeps exactly one unambiguous interactive limit.
func (*Store) SaveInTx ¶
SaveInTx saves an observation using a shared transaction previously stashed in the context by WithinTx. It MUST be called from within a WithinTx closure (or any context that carries a txKey). It does NOT begin/commit its own transaction — the UnitOfWork owns the lifecycle.
Dedup classification (REQ-MCPH-002): when saveInTx signals a dedup skip via the errDedupSkipped sentinel, SaveInTx converts it to domain.NewDedupSkipped so callers (e.g. SaveWithEmbedIntent) can classify the outcome via errors.As. The shared transaction's commit/rollback is owned by the UnitOfWork — SaveInTx only signals, it does not commit.
This is the atomic-path counterpart to Save() (REQ-TX-001).
func (*Store) SaveWithEffect ¶
func (s *Store) SaveWithEffect(ctx context.Context, obs *domain.Observation) (domain.SaveEffect, error)
SaveWithEffect is the transactional save primitive (REM-SAVE-001, RD2): it saves obs and reports the durable effect — created, replayed (dedup), or updated (topic_key upsert) — decided inside the transaction itself, never inferred from a read-back after the fact.
The content envelope is IDENTICAL to legacy Save (interactive 64 KiB); the handoff path must use SaveHandoffWithEffect. No ambiguous dual ceiling is exposed on this method.
Transaction ownership mirrors Save:
- With no shared transaction in ctx, it opens, commits, or rolls back its own transaction. On the dedup path the transaction COMMITS (persisting the duplicate_count increment) and the returned error carries ClassDedupSkipped alongside the populated replayed effect.
- When a shared UnitOfWork transaction is active in ctx (enlisted via WithinTx), it runs entirely on that transaction and never commits or rolls back; the UnitOfWork owns the lifecycle. The dedup classification is still returned as an error for the enlisting coordinator to handle.
On failure the effect is the zero value (Observation == nil) and nothing committed by this call persists.
func (*Store) SoftDelete ¶
SoftDelete marks an observation as deleted without removing it from the database. Returns ErrNotFound if the observation doesn't exist or is already deleted.
func (*Store) StaleObservations ¶
func (s *Store) StaleObservations(ctx context.Context, project string, minScore float64, daysSinceAccess int) ([]*domain.Observation, error)
StaleObservations returns observations with high importance score but no recent access.
func (*Store) Unarchive ¶
Unarchive restores a soft-deleted observation by clearing its deleted_at field. Returns ErrNotFound if the observation doesn't exist or is not archived.
func (*Store) Update ¶
Update modifies an existing observation. Returns ErrNotFound if the observation doesn't exist or is soft-deleted.
func (*Store) WithinTx ¶
WithinTx implements domain.TxParticipant. It type-asserts the handle to *sql.Tx, stashes it into the context, and invokes fn within that context. The fn closure can then call tx-aware Store methods (e.g. SaveInTx) that read the shared tx via txFromContext.
WithinTx does NOT begin, commit, or roll back the transaction — the UnitOfWork that owns the shared tx is responsible for its lifecycle.
type SyncImportResult ¶
type SyncImportResult struct {
SessionsImported int `json:"sessions_imported"`
ObservationsImported int `json:"observations_imported"`
PromptsImported int `json:"prompts_imported"`
}
SyncImportResult holds the outcome of a sync import.
type TemporalSnapshotRepository ¶
type TemporalSnapshotRepository struct {
// contains filtered or unexported fields
}
TemporalSnapshotRepository implements the TemporalSnapshotRepository interface.
func NewTemporalSnapshotRepository ¶
func NewTemporalSnapshotRepository(db *sql.DB) *TemporalSnapshotRepository
NewTemporalSnapshotRepository creates a new temporal snapshot repository.
func (*TemporalSnapshotRepository) CreateSnapshot ¶
func (r *TemporalSnapshotRepository) CreateSnapshot(ctx context.Context, snapshot *domain.TemporalSnapshot) error
CreateSnapshot creates a point-in-time snapshot of the knowledge graph.
func (*TemporalSnapshotRepository) GetByID ¶
func (r *TemporalSnapshotRepository) GetByID(ctx context.Context, id int64) (*domain.TemporalSnapshot, error)
GetByID retrieves a snapshot by its ID.
func (*TemporalSnapshotRepository) GetByRootObservation ¶
func (r *TemporalSnapshotRepository) GetByRootObservation(ctx context.Context, rootObsID int64) ([]*domain.TemporalSnapshot, error)
GetByRootObservation retrieves snapshots for a root observation.
func (*TemporalSnapshotRepository) GetBySnapshotKey ¶
func (r *TemporalSnapshotRepository) GetBySnapshotKey(ctx context.Context, snapshotKey string) ([]*domain.TemporalSnapshot, error)
GetBySnapshotKey retrieves snapshots by their key.
func (*TemporalSnapshotRepository) GetSnapshotsInRange ¶
func (r *TemporalSnapshotRepository) GetSnapshotsInRange(ctx context.Context, from, to time.Time) ([]*domain.TemporalSnapshot, error)
GetSnapshotsInRange retrieves snapshots within a time range.
type VectorStore ¶
type VectorStore struct{}
VectorStore implements the vector similarity search store. This is the stub implementation used when cortex_vectors build tag is disabled.
func NewVectorStore ¶
func NewVectorStore(_ *sql.DB) *VectorStore
NewVectorStore creates a new vector store stub. When cortex_vectors is not enabled, this returns a stub that always returns ErrVectorSearchDisabled.
func (*VectorStore) DeleteEmbedding ¶
func (s *VectorStore) DeleteEmbedding(ctx context.Context, observationID int64) error
DeleteEmbedding is disabled in stub mode.
func (*VectorStore) GetEmbedding ¶
func (s *VectorStore) GetEmbedding(ctx context.Context, observationID int64) ([]float32, string, error)
GetEmbedding is disabled in stub mode.
func (*VectorStore) IsAvailable ¶
func (s *VectorStore) IsAvailable() bool
IsAvailable returns false in stub mode.
func (*VectorStore) SearchByVector ¶
func (s *VectorStore) SearchByVector(ctx context.Context, opts domain.VectorSearchOptions) ([]*domain.VectorSearchResult, error)
SearchByVector is disabled in stub mode.
func (*VectorStore) StoreEmbedding ¶
func (s *VectorStore) StoreEmbedding(ctx context.Context, observationID int64, embedding []float32, model string) error
StoreEmbedding is disabled in stub mode.