Documentation
¶
Overview ¶
Package store owns Ken's embedded SQLite database: schema migrations plus the search/get queries. Writes serialize through a single-writer pool; reads use a separate pool. WAL lets readers run concurrently with the writer.
Index ¶
- Variables
- func LangForeign(contentLang string, curationLangs []string) bool
- func VerifySnapshot(ctx context.Context, path string) (int, error)
- type BrowseFilter
- type BrowseRow
- type CodeData
- type Content
- type DiffResult
- type EmbedTarget
- type FieldDiff
- type HumanCred
- type HumanUser
- type ImportInput
- type LinkInput
- type NewAuthCode
- type OAuthClient
- type OAuthGrantRow
- type OAuthPrincipal
- type Patch
- type PromoteInput
- type ProposalRow
- type ProposeInput
- type ProposeResult
- type RecentEntry
- type RefreshResult
- type ReviewData
- type SaveInput
- type SaveResult
- type SearchOpts
- type Session
- type Store
- func (s *Store) Close() error
- func (s *Store) CountActiveOAuthGrants(ctx context.Context) (int, error)
- func (s *Store) CountActiveTokens(ctx context.Context) (int, error)
- func (s *Store) CountEntries(ctx context.Context) (int, error)
- func (s *Store) CountHumanUsers(ctx context.Context) (int, error)
- func (s *Store) CountProposals(ctx context.Context) (int, error)
- func (s *Store) CountVersions(ctx context.Context) (int, error)
- func (s *Store) CreateFirstAdmin(ctx context.Context, name, pwHash string) (bool, error)
- func (s *Store) CreateHumanUser(ctx context.Context, name, pwHash string) (int64, error)
- func (s *Store) CreateOAuthGrantAndCode(ctx context.Context, in NewAuthCode, codeTTL time.Duration) (string, error)
- func (s *Store) CreateSession(ctx context.Context, actorID int64, ttl time.Duration) (*Session, error)
- func (s *Store) DeleteExpiredSessions(ctx context.Context) (int64, error)
- func (s *Store) DeleteSession(ctx context.Context, id string) error
- func (s *Store) DistinctCategories(ctx context.Context) ([]string, error)
- func (s *Store) EmbeddingStats(ctx context.Context) (embedded, total int, err error)
- func (s *Store) ExchangeOAuthCode(ctx context.Context, code string, grantID int64, ...) (access, refresh string, err error)
- func (s *Store) FindOrCreateActor(ctx context.Context, kind, name string) (int64, error)
- func (s *Store) FlagStale(ctx context.Context, slug, reason string, actorID int64, actorKind string) (string, error)
- func (s *Store) Get(ctx context.Context, slugs []string, detailed bool) (entries []model.Entry, missing []string, err error)
- func (s *Store) GetEntry(ctx context.Context, slug string) (*model.Entry, error)
- func (s *Store) GetSettings(ctx context.Context) (map[string]string, error)
- func (s *Store) History(ctx context.Context, slug string) ([]VersionRow, error)
- func (s *Store) HumanByName(ctx context.Context, name string) (*HumanCred, error)
- func (s *Store) ImportEntry(ctx context.Context, in ImportInput) (created bool, err error)
- func (s *Store) IssueToken(ctx context.Context, actorID int64, scopes []string, label string) (string, error)
- func (s *Store) ListEntries(ctx context.Context, f BrowseFilter) ([]BrowseRow, bool, error)
- func (s *Store) ListHumanUsers(ctx context.Context) ([]HumanUser, error)
- func (s *Store) ListOAuthGrants(ctx context.Context) ([]OAuthGrantRow, error)
- func (s *Store) ListProposals(ctx context.Context) ([]ProposalRow, error)
- func (s *Store) ListTokens(ctx context.Context) ([]TokenRow, error)
- func (s *Store) Migrate() error
- func (s *Store) OAuthClientByID(ctx context.Context, clientID string) (*OAuthClient, error)
- func (s *Store) PeekOAuthCode(ctx context.Context, code string) (*CodeData, error)
- func (s *Store) Promote(ctx context.Context, in PromoteInput) error
- func (s *Store) ProposalReview(ctx context.Context, versionID int64) (*ReviewData, error)
- func (s *Store) ProposeEnhancement(ctx context.Context, in ProposeInput) (ProposeResult, error)
- func (s *Store) ProvisionalReview(ctx context.Context, slug string) (*ReviewData, error)
- func (s *Store) PurgeExpiredOAuth(ctx context.Context) error
- func (s *Store) RecentContext(ctx context.Context, sinceDays, limit int, kind string) ([]RecentEntry, error)
- func (s *Store) RecordOutcome(ctx context.Context, slug, outcome string, actorID int64, ...) (staleness string, err error)
- func (s *Store) RegisterOAuthClient(ctx context.Context, name string, redirectURIs []string) (string, error)
- func (s *Store) Reject(ctx context.Context, slug string, versionID, actorID int64, ...) error
- func (s *Store) Repromote(ctx context.Context, in PromoteInput) error
- func (s *Store) RevokeOAuthGrant(ctx context.Context, id int64) error
- func (s *Store) RevokeToken(ctx context.Context, tokenID string) error
- func (s *Store) RotateOAuthRefresh(ctx context.Context, refresh string, accessTTL, refreshTTL time.Duration) (access, newRefresh string, rr *RefreshResult, err error)
- func (s *Store) Save(ctx context.Context, in SaveInput) (SaveResult, error)
- func (s *Store) Search(ctx context.Context, query string, opt SearchOpts) ([]model.SearchResult, error)
- func (s *Store) SearchPage(ctx context.Context, query string, opt SearchOpts) ([]model.SearchResult, bool, error)
- func (s *Store) SeedDemo(ctx context.Context) (string, error)
- func (s *Store) SessionByID(ctx context.Context, id string) (*Session, error)
- func (s *Store) SetDetector(d lang.Detector)
- func (s *Store) SetSettings(ctx context.Context, upsert map[string]string, remove []string, updater string) error
- func (s *Store) Snapshot(ctx context.Context, dest string) error
- func (s *Store) TouchToken(ctx context.Context, tokenID string)
- func (s *Store) UpsertEmbedding(ctx context.Context, versionID int64, modelID string, vec []float32) error
- func (s *Store) ValidateOAuthAccessToken(ctx context.Context, token string) (*OAuthPrincipal, error)
- func (s *Store) VersionDiff(ctx context.Context, slug string, revA, revB int) (*DiffResult, error)
- func (s *Store) VersionsNeedingEmbedding(ctx context.Context, modelID string, limit int) ([]EmbedTarget, error)
- type TokenRow
- type VersionRow
Constants ¶
This section is empty.
Variables ¶
var ( ErrSlugConflict = errors.New("an entry with that slug already exists") ErrNotFound = errors.New("entry not found") ErrBadVersion = errors.New("version not found or not in a promotable state") // ErrInvalid wraps user-facing validation failures (safe to surface to clients). ErrInvalid = errors.New("invalid input") // ErrForeignLang blocks promoting a version whose detected content language is // not one the curator declared they can read — the "can't promote what you // can't read" comprehension gate. It is enforced in the store (Promote / // Repromote), not just the UI, so no server-side path reaches the head with // unreadable content. ErrForeignLang = errors.New("proposal is not in a curation language") // OAuth authorization-server errors (see internal/store/oauth.go). ErrOAuthNoClient = errors.New("oauth client not found") ErrOAuthBadCode = errors.New("authorization code invalid, expired, or already used") ErrOAuthBadToken = errors.New("oauth token invalid, expired, or revoked") ErrOAuthReuseKill = errors.New("refresh token reuse detected — grant revoked") )
Sentinel errors surfaced to callers (MCP tools, web handlers).
Functions ¶
func LangForeign ¶
LangForeign reports whether a detected content language would be BLOCKED for promotion under the given curation languages — the inverse of the internal gate. The web layer uses it to flag out-of-language proposals on the review queue with the exact same rule the store enforces (no drift between the badge and the gate).
func VerifySnapshot ¶
VerifySnapshot opens a database file and runs the backup's mandatory checks: PRAGMA integrity_check, foreign-key integrity, the FTS5 internal integrity-check on both indexes, a functional MATCH canary, embedding vector-length parity, and returns the entry count (for the caller to reconcile against the source). Opened read-write so the FTS integrity-check can run; a VACUUM-INTO snapshot is in rollback-journal mode, so no -wal/-shm persists.
Types ¶
type BrowseFilter ¶
type BrowseFilter struct {
Category string // exact match; "" = any
Kind string // user|feedback|project|reference; "" = any
Staleness string // fresh|aging|stale|refuted; "" = any
Lifecycle string // draft|active|deprecated; "" = any non-archived
Sort string // updated (default) | title | used | created | kind
Limit int // default 50, max 200
Offset int
}
BrowseFilter parameterizes ListEntries. Every field is optional; the zero value lists all non-archived entries, newest-updated first.
type BrowseRow ¶
type BrowseRow struct {
Slug string
Title string
Summary string
Kind string
Category string
Staleness string
Lifecycle string
CuratedRev int
UseCount int
HasProvisional bool
UpdatedAt string
}
BrowseRow is one entry as shown in the browse listing. Every field is read straight from the denormalized entry row (the curated head's title/summary/ category are kept in sync on promotion), so browsing never joins entry_version.
type CodeData ¶
type CodeData struct {
GrantID int64
ClientID string
RedirectURI string
CodeChallenge string
CodeChallengeMethod string
Scope string
Resource string
}
CodeData is the authorization-code record needed to validate a token exchange.
type Content ¶
type Content struct {
Title, Summary, Problem, Solution, Rationale, Caveats string
Code []model.CodeSnippet
Tags, Triggers, AppliesTo []string
VerifiedAgainst []model.VerifiedRef
}
Content is the writable content of an entry version.
type DiffResult ¶
DiffResult is the field-by-field diff of two revisions of an entry.
type EmbedTarget ¶
EmbedTarget is a version that needs an embedding computed.
type ImportInput ¶
type ImportInput struct {
Slug string
Kind string
Content Content
ChangeNote string
Links []LinkInput
}
ImportInput migrates a flat-memory file into Ken as a curated rev-1 entry.
type LinkInput ¶
type LinkInput struct{ ToSlug, LinkType string }
LinkInput is a [[wikilink]] to create from the new entry.
type NewAuthCode ¶
type NewAuthCode struct {
ClientID string
ConnectorActorID int64
HumanActorID int64
RedirectURI string
CodeChallenge string
CodeChallengeMethod string
Scope string
Resource string
}
NewAuthCode is the input to CreateOAuthGrantAndCode: everything captured at the consent step. ConnectorActorID is the 'ai' actor that will author MCP writes; HumanActorID is the curator who approved.
type OAuthClient ¶
OAuthClient is a registered public client (PKCE; no secret).
type OAuthGrantRow ¶
type OAuthGrantRow struct {
ID int64
ClientName string
ApprovedBy string
Scope string
CreatedAt string
ActiveTokens int
}
OAuthGrantRow is one live connector grant, for the curator UI.
type OAuthPrincipal ¶
OAuthPrincipal is the resolved identity behind a valid OAuth access token.
type Patch ¶
type Patch struct {
Title, Summary, Problem, Solution, Rationale, Caveats *string
Code *[]model.CodeSnippet
Tags, Triggers, AppliesTo *[]string
VerifiedAgainst *[]model.VerifiedRef
}
Patch carries the fields to change in an enhancement; nil fields inherit from the based-on version (so an enhancement need only send what it changes).
type PromoteInput ¶
type PromoteInput struct {
Slug string
VersionID int64
ActorID int64
ActorKind string
Note string
// CurationLangs, when non-empty, enforces the comprehension gate: a version
// whose detected content language is not one of these is refused with
// ErrForeignLang. Empty ⇒ no language restriction (feature off). The web
// handler fills it from the live settings snapshot.
CurationLangs []string
}
PromoteInput promotes a proposed version to the curated head (the curation gate).
type ProposalRow ¶
type ProposalRow struct {
Slug string
Title string
Kind string
NProposals int
LatestRev int
LatestVersionID int64
LatestConfidence float64
LatestChangeNote string
LatestLang string // detected content language of the latest proposal ("" ⇒ undetected/legacy)
// LatestViaComm marks the latest proposal as possibly SECOND-HAND: the token
// that authored it had recently received an inter-session message
// (docs/COMM.md §7). False means "no signal", never "known first-hand" — it is
// a prompt to ask for a citation, not a verdict.
LatestViaComm bool
}
ProposalRow summarizes an entry that has pending proposals (the review queue).
type ProposeInput ¶
type ProposeInput struct {
Slug string
BasedOnRev int // 0 => base on the current curated head
ChangeNote string
Confidence float64
AuthorActorID int64
AuthorKind string
SessionID string
Patch Patch
// ViaComm — see SaveInput.ViaComm.
ViaComm bool
}
ProposeInput appends an enhancement to an existing entry.
type ProposeResult ¶
ProposeResult reports the appended version and any rebase warning.
type RecentEntry ¶
type RecentEntry struct {
Slug, Title, Summary, Kind, LastEvent, LastAt string
}
RecentEntry is one row of the recent-activity briefing.
type RefreshResult ¶
RefreshResult reports the grant a rotated refresh belongs to.
type ReviewData ¶
type ReviewData struct {
Slug string
EntryTitle string
ProposalVID int64
ProposalRev int
ProposalState string
ChangeNote string
// ViaComm marks this proposal as possibly second-hand (docs/COMM.md §7). It
// belongs here, not only on the review-queue listing, because THIS is the view
// that carries the Promote button — a hearsay warning that never reaches the
// moment of promotion is not a mitigation.
ViaComm bool
Proposal Content
HasCurated bool
CuratedRev int
Curated Content
}
ReviewData is the material for a proposal diff view: the proposal content alongside the current curated head content.
type SaveInput ¶
type SaveInput struct {
Slug string // optional; derived from the title if empty
Kind string
Category string
Content Content
Confidence float64
AuthorActorID int64 // 0 => NULL (e.g. the dev token)
AuthorKind string
SessionID string
Links []LinkInput
// ViaComm marks the version as possibly second-hand: the authoring token had
// recently RECEIVED an inter-session message (docs/COMM.md §7). It is a prompt
// for the curator's judgement, not a verdict — false means "no signal", never
// "known first-hand".
ViaComm bool
}
SaveInput creates a new draft entry with its first (proposed) version.
type SaveResult ¶
type SaveResult struct {
Slug string
EntryID int64
VersionID int64
RevNo int
Lifecycle string
State string
}
SaveResult reports the created entry.
type SearchOpts ¶
type SearchOpts struct {
Kind string
Category string
Scope string // curated (default) | proposals | history | all
K int
Offset int
QueryVec []float32 // optional; when set, adds a semantic (vector) arm
EmbedModel string // model id of QueryVec; only vectors from this model are compared
}
SearchOpts filters a kb_search query.
type Store ¶
type Store struct {
W *sql.DB // single-writer pool (MaxOpenConns == 1) — serializes all writes
R *sql.DB // reader pool
// contains filtered or unexported fields
}
Store holds the writer and reader connection pools over one SQLite file.
func (*Store) CountActiveOAuthGrants ¶
CountActiveOAuthGrants counts live connector grants (for the dashboard stat).
func (*Store) CountActiveTokens ¶
CountActiveTokens returns the number of non-revoked agent API tokens.
func (*Store) CountEntries ¶
CountEntries returns the number of knowledge-base entries (curated or draft).
func (*Store) CountHumanUsers ¶
CountHumanUsers returns the number of human (login) actors; 0 drives the first-run setup wizard.
func (*Store) CountProposals ¶ added in v1.2.0
CountProposals returns how many entries have at least one proposed version — the same population ListProposals returns, counted cheaply. It backs the Proposals page's live auto-refresh: a curator who keeps that page open should see a new proposal appear without a manual reload, and polling a bare count is far lighter than re-running the full listing query on a timer.
func (*Store) CountVersions ¶
CountVersions returns the number of entry versions (the append-only history, which only ever grows).
func (*Store) CreateFirstAdmin ¶
CreateFirstAdmin atomically creates the initial human admin ONLY if no human user exists yet (the first-run wizard). Returns created=false (no error) if one already exists — a single INSERT...WHERE NOT EXISTS that closes the check-then- insert TOCTOU a separate SELECT+INSERT would leave open (two concurrent /setup posts can't both create an admin).
func (*Store) CreateHumanUser ¶
CreateHumanUser creates a human actor with an Argon2id password hash.
func (*Store) CreateOAuthGrantAndCode ¶
func (s *Store) CreateOAuthGrantAndCode(ctx context.Context, in NewAuthCode, codeTTL time.Duration) (string, error)
CreateOAuthGrantAndCode records the human's approval as a durable grant and a single-use authorization code (hashed), returning the plaintext code once.
func (*Store) CreateSession ¶
func (s *Store) CreateSession(ctx context.Context, actorID int64, ttl time.Duration) (*Session, error)
CreateSession creates a session for actorID with the given TTL and a fresh CSRF token (rotated per login).
func (*Store) DeleteExpiredSessions ¶
DeleteExpiredSessions purges sessions past their expiry; returns the count.
func (*Store) DeleteSession ¶
DeleteSession removes a session (logout).
func (*Store) DistinctCategories ¶
DistinctCategories returns the non-empty categories present on non-archived entries, alphabetically — the option list for the browse category filter.
func (*Store) EmbeddingStats ¶
EmbeddingStats reports embedded vs total version counts.
func (*Store) ExchangeOAuthCode ¶
func (s *Store) ExchangeOAuthCode(ctx context.Context, code string, grantID int64, accessTTL, refreshTTL time.Duration) (access, refresh string, err error)
ExchangeOAuthCode atomically consumes the code (single-use) and issues a new access + refresh token pair under its grant, returning both plaintexts once. The DELETE row-count is the double-spend guard: if the code was already used (or expired) between Peek and here, RowsAffected is 0 and this returns ErrOAuthBadCode without issuing anything.
func (*Store) FindOrCreateActor ¶
FindOrCreateActor returns the id of an actor with the given kind + display name, creating it if absent.
func (*Store) FlagStale ¶
func (s *Store) FlagStale(ctx context.Context, slug, reason string, actorID int64, actorKind string) (string, error)
FlagStale marks an entry stale (still authoritative, ranks lower) and records the concern. Raising a concern is safe/additive; asserting freshness is not.
func (*Store) Get ¶
func (s *Store) Get(ctx context.Context, slugs []string, detailed bool) (entries []model.Entry, missing []string, err error)
Get returns full entries for the given slugs (curated head, or the provisional version for an uncurated draft). Unknown slugs are returned in missing. Each found entry bumps use_count. detailed adds provenance.
func (*Store) GetEntry ¶
GetEntry returns one entry without bumping use_count (for the human web UI).
func (*Store) GetSettings ¶
GetSettings returns all operator-set setting overrides (key -> value). An empty map means "all defaults".
func (*Store) HumanByName ¶
HumanByName returns the login credential for a human actor (web login).
func (*Store) ImportEntry ¶
ImportEntry inserts an imported entry directly as curated (lifecycle 'active', one 'curated' version rev 1, author_kind 'import') — imported memories are already curated knowledge, so they bypass the proposal queue. Idempotent: returns created=false without changes if the slug already exists.
func (*Store) IssueToken ¶
func (s *Store) IssueToken(ctx context.Context, actorID int64, scopes []string, label string) (string, error)
IssueToken creates an API token for actorID and returns the full token string (ken_<id>_<secret>) exactly once; only SHA-256(secret) is persisted.
func (*Store) ListEntries ¶
ListEntries returns a filtered, sorted, paginated page of entries plus a has-more flag (it over-fetches one row so an exact-limit final page is not reported as "more" — the same technique as SearchPage). Archived entries are always excluded; a blank Lifecycle filter still shows draft/active/deprecated.
func (*Store) ListHumanUsers ¶
ListHumanUsers lists human (login) actors.
func (*Store) ListOAuthGrants ¶
func (s *Store) ListOAuthGrants(ctx context.Context) ([]OAuthGrantRow, error)
ListOAuthGrants returns live (non-revoked) grants, newest first.
func (*Store) ListProposals ¶
func (s *Store) ListProposals(ctx context.Context) ([]ProposalRow, error)
ListProposals returns entries with at least one proposed version, newest first.
func (*Store) ListTokens ¶
ListTokens lists all API tokens, newest first.
func (*Store) Migrate ¶
Migrate applies embedded migrations in lexical order, skipping versions already recorded in schema_migration. It is idempotent. All migrations are plain SQL (no loadable extensions), so all apply unconditionally; the embeddings table is created empty and only populated when a provider is configured.
func (*Store) OAuthClientByID ¶
OAuthClientByID returns the registered client or ErrOAuthNoClient.
func (*Store) PeekOAuthCode ¶
PeekOAuthCode reads (without consuming) a non-expired authorization code so the token endpoint can verify client_id, redirect_uri, and PKCE before committing. ErrOAuthBadCode if missing or expired. Consumption happens in ExchangeOAuthCode.
func (*Store) Promote ¶
func (s *Store) Promote(ctx context.Context, in PromoteInput) error
Promote is the only operation that moves the curated head. In one IMMEDIATE transaction, guarded by the proposal's state='proposed' check (see below), it supersedes the old head, marks the proposal curated, advances the head, resets staleness, and refreshes the denormalized ranking/browse surface. A duplicate or stale promote returns ErrBadVersion from that state check — reconcile, don't clobber. (lock_version is still bumped for auditing but is no longer a guard.)
func (*Store) ProposalReview ¶
ProposalReview loads a version and its entry's curated head for a diff view.
func (*Store) ProposeEnhancement ¶
func (s *Store) ProposeEnhancement(ctx context.Context, in ProposeInput) (ProposeResult, error)
ProposeEnhancement appends an immutable 'proposed' version. It never moves the curated head — knowledge is persisted the instant it is proposed.
func (*Store) ProvisionalReview ¶
ProvisionalReview returns the review material for an entry's pending proposal (its provisional version), or (nil, nil) when the entry has none.
func (*Store) PurgeExpiredOAuth ¶
PurgeExpiredOAuth deletes spent authorization codes and long-expired tokens. Best-effort housekeeping; safe to call periodically.
func (*Store) RecentContext ¶
func (s *Store) RecentContext(ctx context.Context, sinceDays, limit int, kind string) ([]RecentEntry, error)
RecentContext returns entries with curation activity in the last sinceDays, newest first — a compact "what the KB learned recently" briefing.
func (*Store) RecordOutcome ¶
func (s *Store) RecordOutcome(ctx context.Context, slug, outcome string, actorID int64, actorKind, sessionID, note string) (staleness string, err error)
RecordOutcome records an agent's outcome report for an entry. 'was-wrong' also flags the entry stale (for human review). Returns the entry's staleness after.
func (*Store) RegisterOAuthClient ¶
func (s *Store) RegisterOAuthClient(ctx context.Context, name string, redirectURIs []string) (string, error)
RegisterOAuthClient mints a new public client_id for the given name + redirect-URI allowlist and returns it. The caller validates the redirect URIs (https or loopback) before calling.
func (*Store) Reject ¶
func (s *Store) Reject(ctx context.Context, slug string, versionID, actorID int64, actorKind, note string) error
Reject marks a proposed version rejected (retained + searchable as a dead-end).
func (*Store) Repromote ¶
func (s *Store) Repromote(ctx context.Context, in PromoteInput) error
Repromote sets an EXISTING historical version (superseded/rejected/withdrawn — anything but the current head or a still-'proposed' version) back as the curated head. It is the human recovery path when promotions were applied in the wrong order and regressed the head; unlike Promote it does not require state='proposed' (proposed versions go through the normal Promote review). One IMMEDIATE tx.
func (*Store) RevokeOAuthGrant ¶
RevokeOAuthGrant revokes a grant and all of its outstanding tokens in one tx. Idempotent: revoking an already-revoked grant is a no-op success.
func (*Store) RevokeToken ¶
RevokeToken soft-revokes a token by id.
func (*Store) RotateOAuthRefresh ¶
func (s *Store) RotateOAuthRefresh(ctx context.Context, refresh string, accessTTL, refreshTTL time.Duration) (access, newRefresh string, rr *RefreshResult, err error)
RotateOAuthRefresh validates a refresh token and, on success, revokes it and issues a fresh access + refresh pair (rotation). If a refresh token that has ALREADY been rotated (revoked) is presented, that is a theft signal: the whole grant is revoked and ErrOAuthReuseKill is returned. ErrOAuthBadToken for a missing/expired token or a revoked grant.
func (*Store) Search ¶
func (s *Store) Search(ctx context.Context, query string, opt SearchOpts) ([]model.SearchResult, error)
Search runs the hybrid keyword+vector search and returns the clamped page.
func (*Store) SearchPage ¶
func (s *Store) SearchPage(ctx context.Context, query string, opt SearchOpts) ([]model.SearchResult, bool, error)
SearchPage is Search plus an accurate has-more flag. It over-fetches one row (K+1) so an exact-K final page isn't reported as "more" (a false positive).
func (*Store) SeedDemo ¶
SeedDemo inserts (idempotently) one curated demo entry so the skeleton has something to return from kb_search / kb_get. Dev/smoke use only.
func (*Store) SessionByID ¶
SessionByID returns a live (unexpired) session, or ErrNotFound.
func (*Store) SetDetector ¶
SetDetector overrides the content-language detector (used by tests to force a deterministic language without exercising whatlanggo).
func (*Store) SetSettings ¶
func (s *Store) SetSettings(ctx context.Context, upsert map[string]string, remove []string, updater string) error
SetSettings applies setting changes in one transaction: it upserts each key/value in upsert (an empty value is a legitimate override, stored verbatim) and deletes each key in remove (reverting it to the default). Deletion is an explicit list, never inferred from an empty value.
func (*Store) Snapshot ¶
Snapshot writes a consistent copy of the database to dest via VACUUM INTO — safe on a live WAL database (no torn file). dest must not already exist.
func (*Store) TouchToken ¶
TouchToken updates last_used_at, throttled to at most ~once per minute per token, so the read path doesn't amplify into a write on every request.
func (*Store) UpsertEmbedding ¶
func (s *Store) UpsertEmbedding(ctx context.Context, versionID int64, modelID string, vec []float32) error
UpsertEmbedding stores (or replaces) a version's embedding for a given model. The (version_id, model_id) primary key lets multiple models coexist per version; OR REPLACE upserts the row for this exact (version, model) pair only.
func (*Store) ValidateOAuthAccessToken ¶
func (s *Store) ValidateOAuthAccessToken(ctx context.Context, token string) (*OAuthPrincipal, error)
ValidateOAuthAccessToken resolves an opaque access token to its principal, or ErrOAuthBadToken if it is unknown, expired, revoked, or its grant was revoked. Read-only (reader pool) so it never contends for the single writer.
func (*Store) VersionDiff ¶
VersionDiff diffs two revisions of an entry, field by field.
func (*Store) VersionsNeedingEmbedding ¶
func (s *Store) VersionsNeedingEmbedding(ctx context.Context, modelID string, limit int) ([]EmbedTarget, error)
VersionsNeedingEmbedding returns versions lacking an embedding for modelID (limit<=0 means all). Text is what the query vector is compared against.