store

package
v1.4.1 Latest Latest
Warning

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

Go to latest
Published: Jul 28, 2026 License: AGPL-3.0 Imports: 23 Imported by: 0

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

Constants

This section is empty.

Variables

View Source
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

func LangForeign(contentLang string, curationLangs []string) bool

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

func VerifySnapshot(ctx context.Context, path string) (int, error)

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

type DiffResult struct {
	Slug           string
	RevA, RevB     int
	StateA, StateB string
	Fields         []FieldDiff
}

DiffResult is the field-by-field diff of two revisions of an entry.

type EmbedTarget

type EmbedTarget struct {
	VersionID int64
	Text      string // title + summary + problem + solution
}

EmbedTarget is a version that needs an embedding computed.

type FieldDiff

type FieldDiff struct {
	Field   string
	Changed bool
	A, B    string
}

FieldDiff is one field's before/after in a version diff.

type HumanCred

type HumanCred struct {
	ActorID int64
	Name    string
	PwHash  string
}

HumanCred carries a human actor's login credential.

type HumanUser

type HumanUser struct {
	ActorID   int64
	Name      string
	CreatedAt string
}

HumanUser is a row for `ken user list`.

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

type OAuthClient struct {
	ClientID     string
	Name         string
	RedirectURIs []string
}

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

type OAuthPrincipal struct {
	ActorID  int64
	GrantID  int64
	Scope    string
	Resource string
}

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

type ProposeResult struct {
	Slug      string
	VersionID int64
	RevNo     int
	State     string
	Warning   string
}

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

type RefreshResult struct {
	GrantID  int64
	Scope    string
	Resource string
}

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 Session

type Session struct {
	ID        string
	ActorID   int64
	ActorName string
	CSRF      string
	ExpiresAt string
}

Session is a human web-login session (server-side).

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 Open

func Open(path string) (*Store, error)

Open opens (creating if needed) the SQLite database at path.

func (*Store) Close

func (s *Store) Close() error

Close closes both connection pools.

func (*Store) CountActiveOAuthGrants

func (s *Store) CountActiveOAuthGrants(ctx context.Context) (int, error)

CountActiveOAuthGrants counts live connector grants (for the dashboard stat).

func (*Store) CountActiveTokens

func (s *Store) CountActiveTokens(ctx context.Context) (int, error)

CountActiveTokens returns the number of non-revoked agent API tokens.

func (*Store) CountEntries

func (s *Store) CountEntries(ctx context.Context) (int, error)

CountEntries returns the number of knowledge-base entries (curated or draft).

func (*Store) CountHumanUsers

func (s *Store) CountHumanUsers(ctx context.Context) (int, error)

CountHumanUsers returns the number of human (login) actors; 0 drives the first-run setup wizard.

func (*Store) CountProposals added in v1.2.0

func (s *Store) CountProposals(ctx context.Context) (int, error)

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

func (s *Store) CountVersions(ctx context.Context) (int, error)

CountVersions returns the number of entry versions (the append-only history, which only ever grows).

func (*Store) CreateFirstAdmin

func (s *Store) CreateFirstAdmin(ctx context.Context, name, pwHash string) (bool, error)

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

func (s *Store) CreateHumanUser(ctx context.Context, name, pwHash string) (int64, error)

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

func (s *Store) DeleteExpiredSessions(ctx context.Context) (int64, error)

DeleteExpiredSessions purges sessions past their expiry; returns the count.

func (*Store) DeleteSession

func (s *Store) DeleteSession(ctx context.Context, id string) error

DeleteSession removes a session (logout). Takes the RAW cookie value.

func (*Store) DistinctCategories

func (s *Store) DistinctCategories(ctx context.Context) ([]string, error)

DistinctCategories returns the non-empty categories present on non-archived entries, alphabetically — the option list for the browse category filter.

func (*Store) EmbeddingStats

func (s *Store) EmbeddingStats(ctx context.Context) (embedded, total int, err error)

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

func (s *Store) FindOrCreateActor(ctx context.Context, kind, name string) (int64, error)

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

func (s *Store) GetEntry(ctx context.Context, slug string) (*model.Entry, error)

GetEntry returns one entry without bumping use_count (for the human web UI).

func (*Store) GetSettings

func (s *Store) GetSettings(ctx context.Context) (map[string]string, error)

GetSettings returns all operator-set setting overrides (key -> value). An empty map means "all defaults".

func (*Store) History

func (s *Store) History(ctx context.Context, slug string) ([]VersionRow, error)

History returns all versions of an entry, newest rev first.

func (*Store) HumanByName

func (s *Store) HumanByName(ctx context.Context, name string) (*HumanCred, error)

HumanByName returns the login credential for a human actor (web login).

func (*Store) ImportEntry

func (s *Store) ImportEntry(ctx context.Context, in ImportInput) (created bool, err error)

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

func (s *Store) ListEntries(ctx context.Context, f BrowseFilter) ([]BrowseRow, bool, error)

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

func (s *Store) ListHumanUsers(ctx context.Context) ([]HumanUser, error)

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

func (s *Store) ListTokens(ctx context.Context) ([]TokenRow, error)

ListTokens lists all API tokens, newest first.

func (*Store) Migrate

func (s *Store) Migrate() error

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

func (s *Store) OAuthClientByID(ctx context.Context, clientID string) (*OAuthClient, error)

OAuthClientByID returns the registered client or ErrOAuthNoClient.

func (*Store) PeekOAuthCode

func (s *Store) PeekOAuthCode(ctx context.Context, code string) (*CodeData, error)

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

func (s *Store) ProposalReview(ctx context.Context, versionID int64) (*ReviewData, error)

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

func (s *Store) ProvisionalReview(ctx context.Context, slug string) (*ReviewData, error)

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

func (s *Store) PurgeExpiredOAuth(ctx context.Context) error

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

func (s *Store) RevokeOAuthGrant(ctx context.Context, id int64) error

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

func (s *Store) RevokeToken(ctx context.Context, tokenID string) error

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) Save

func (s *Store) Save(ctx context.Context, in SaveInput) (SaveResult, error)

Save creates a new draft entry (lifecycle 'draft', one 'proposed' version).

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

func (s *Store) SeedDemo(ctx context.Context) (string, error)

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

func (s *Store) SessionByID(ctx context.Context, id string) (*Session, error)

SessionByID returns a live (unexpired) session for the RAW cookie value, or ErrNotFound. The lookup is by hash (see sessionKey); the returned Session carries the raw id the caller passed in, so callers are unaffected by the storage change.

func (*Store) SetDetector

func (s *Store) SetDetector(d lang.Detector)

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

func (s *Store) Snapshot(ctx context.Context, dest string) error

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.

The result is chmod'd 0600 HERE, not left to the caller. A snapshot is a byte-complete copy of the knowledge base — every entry, the full curation history, curator accounts and token records — so its mode is part of writing it correctly, not a courtesy the caller may forget. SQLite creates the file at the process umask (0644 under the usual 0022), and callers that only *document* a safe umask leave every hand-run `ken backup snapshot --out …` world-readable: the shell wrappers cannot protect an operator following the runbook by hand.

The umask is also narrowed for the duration of the write (see the CLI), so the file is 0600 from creation rather than only once VACUUM INTO returns; this chmod is the backstop that holds no matter which caller invoked us.

func (*Store) TouchToken

func (s *Store) TouchToken(ctx context.Context, tokenID string)

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

func (s *Store) VersionDiff(ctx context.Context, slug string, revA, revB int) (*DiffResult, error)

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.

type TokenRow

type TokenRow struct {
	TokenID, ActorName, Kind, Scopes, Label, CreatedAt, LastUsedAt, RevokedAt string
}

TokenRow is a row for `ken token list`.

type VersionRow

type VersionRow struct {
	VersionID  int64
	RevNo      int
	State      string
	ChangeNote string
	AuthorKind string
	Confidence float64
	CreatedAt  string
}

VersionRow is a row in an entry's version history.

Jump to

Keyboard shortcuts

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