store

package
v0.6.0 Latest Latest
Warning

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

Go to latest
Published: Sep 13, 2026 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package store owns the on-disk index: a single SQLite file holding the structure, history, effects, and policy tables (RFC-001 §5.1).

The file carries two classes of state with different lifecycles: derived tables (symbols, edges, co-change, decisions, effects) that Rebuild wipes and recomputes from the workspace, and durable tables (proposal, distilled, lesson, finding, rule) holding reviewed decisions and paid inference that no rebuild can regenerate. The database is therefore NOT disposable; deleting it destroys decisions. Rebuilds preserve the durable tables and the schema is versioned (migrate.go). state.go makes the decision subset — proposals and distillation marks — portable; lessons, findings and rules are re-mined rather than exported.

The store is deliberately dumb: it validates nothing about the graph and contains no language knowledge. Writers (the indexer, the history miner) batch rows inside Rebuild; readers get focused query helpers tuned for the CLI/LSP/MCP surfaces.

Index

Constants

View Source
const (
	MetaFixesMinedAt   = "fixes_mined_at"
	MetaReviewsMinedAt = "reviews_mined_at"
)

Meta keys recording when each finding channel was last mined (unix seconds, written with the corresponding finding refresh). All readers and writers must use these constants: a misspelled key does not error, it silently reads as "never mined".

View Source
const DefaultDBName = "index.db"

DefaultDBName is the index filename inside DefaultDir.

View Source
const DefaultDir = ".seamark"

DefaultDir is the workspace-relative directory holding seamark state.

View Source
const StateVersion = 2

StateVersion is the version of the portable state format. Bump only with a reader that still accepts every older version.

Variables

This section is empty.

Functions

func DefaultPath

func DefaultPath(root string) string

DefaultPath returns the conventional index location for a workspace root.

func Integrity

func Integrity(path string) (string, error)

Integrity runs SQLite's integrity check read-only and returns its verdict lines ("ok" when healthy).

func ProbeVersion

func ProbeVersion(path string) (int, error)

ProbeVersion reports an existing database's stamped schema version without touching it. 0 means unstamped (a pre-versioning database); an unopenable or unreadable file is an error.

func SupportedSchema

func SupportedSchema() int

SupportedSchema is the schema version this binary reads and writes.

Types

type CacheEntry

type CacheEntry struct {
	Hash string
	Data []byte
}

CacheEntry is one file's cached parse output.

type CallEdge

type CallEdge struct {
	model.Symbol
	Origin string
}

CallEdge is a call-graph neighbor together with the edge's declared derivation (model.Origin*), so surfaces can show confidence instead of presenting every edge as equally trustworthy.

type CalledSymbol

type CalledSymbol struct {
	model.Symbol
	Callers int
}

CalledSymbol is a symbol with its caller count.

type ClusterCited added in v0.2.0

type ClusterCited struct {
	Cited, Total int
}

ClusterCited counts one mined cluster's findings: how many are among a given citation set, and how many exist in total.

type CoChangePartner

type CoChangePartner struct {
	File     string
	Together int
	Total    int
	Lift     float64
}

CoChangePartner is a co-change row oriented around a queried file.

type DistilledMark

type DistilledMark struct {
	Signature string `json:"signature"`
	Region    string `json:"region,omitempty"`
	At        int64  `json:"at"`
}

DistilledMark is one row of distillation memory: evidence sets already paid for, never re-sent to an agent.

type Effect

type Effect struct {
	Tag    string
	Origin string // direct | propagated
	Depth  int    // 0 for direct
}

Effect is one tag carried by a symbol.

type FileChurn

type FileChurn struct {
	File    string
	Commits int
}

FileChurn is how much of the repo's history a file has absorbed: the number of decisions (commits, PRs, reverts) recorded against it.

type HistoryWindow

type HistoryWindow struct {
	Decisions int
	OldestTS  int64
	NewestTS  int64
	MedianTS  int64
}

HistoryWindow describes the mined decision evidence: how much and how old — an answer backed by three commits from 2019 must not read like one backed by three hundred from last month.

type HotFile

type HotFile struct {
	File     string
	Partners int
	MaxLift  float64
}

HotFile is a co-change hub: a file whose changes rarely travel alone.

type ImportStats

type ImportStats struct {
	ProposalsAdded   int
	ProposalsUpdated int // pending rows that adopted an imported decision
	ProposalsSkipped int
	// TriggersFilled counts kept-local rows whose unanswered trigger
	// question adopted an imported answer — paid once, on one machine.
	TriggersFilled   int
	DistilledAdded   int
	DistilledSkipped int
}

ImportStats reports what an import actually did.

type ProposalState

type ProposalState struct {
	Signature string   `json:"signature"`
	Rule      string   `json:"rule"`
	Region    string   `json:"region,omitempty"`
	Regions   []string `json:"regions,omitempty"`
	// TriggerPaths travel with the proposal: they feed region
	// recomputation, and losing them on import would let a retarget
	// silently narrow the imported delivery. The checked stamp rides
	// along so an import does not re-purchase answered questions.
	TriggerPaths         []string `json:"trigger_paths,omitempty"`
	TriggerChecked       int64    `json:"trigger_checked_at,omitempty"`
	TriggerPromptVersion int      `json:"trigger_prompt_version,omitempty"`
	Note                 string   `json:"note"`
	Members              []int64  `json:"members,omitempty"`
	Agent                string   `json:"agent,omitempty"`
	Status               string   `json:"status"`
	CreatedAt            int64    `json:"created_at"`
}

ProposalState is one proposal on the wire. It carries no database id: ids are local to a database, while the signature travels — it hashes stable finding ids, so the same evidence produces the same signature on any machine.

type State

type State struct {
	Version int `json:"seamark_state_version"`
	// Repo identifies the repository the bundle came from (the root
	// commit id — stable across clones, unlike paths or remotes). Filled
	// and checked by the CLI; empty when unknown (not a git repository).
	Repo      string          `json:"repo,omitempty"`
	Proposals []ProposalState `json:"proposals,omitempty"`
	Distilled []DistilledMark `json:"distilled,omitempty"`
}

State is the portable durable-state bundle: the proposal decisions and paid distillation memory that a rebuild cannot regenerate. Everything else in the database is derived and travels by re-indexing.

type Stats

type Stats struct {
	Symbols   int
	Edges     int
	CoChanges int
	Decisions int
	// Tagged counts symbols carrying at least one effect tag.
	Tagged int
	// Lessons counts clustered review-feedback patterns (M6).
	Lessons int
}

Stats summarizes index contents for `seamark index` output.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store wraps the SQLite index database.

func Open

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

Open opens (creating if necessary) the index database at path and applies the schema. The schema is idempotent; opening an existing index is cheap.

func OpenReadOnly added in v0.2.0

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

OpenReadOnly opens an EXISTING database for querying only: no schema application, no migrations, no writes — the opener for diagnostics that must leave the target byte-identical. The database must already carry this binary's schema version: an older one would fail queries on missing columns, a newer one must not be guessed at — both are refused with the same advice, run a current `seamark index` against it first.

func (*Store) AllFindings

func (s *Store) AllFindings() ([]model.Finding, error)

AllFindings returns every stored finding — the distiller's input.

func (*Store) AllLessons

func (s *Store) AllLessons(limit int) ([]model.Lesson, error)

AllLessons returns every mined lesson repo-wide, strongest first — including the one-offs that TopLessons filters out. It is the ledger `seamark lessons --list` shows so a user can decide what to mute or pin. limit <= 0 means no cap.

func (*Store) Callees

func (s *Store) Callees(id int64) ([]CallEdge, error)

Callees returns symbols id has a CALLS edge to, with edge origins.

func (*Store) CallerCounts

func (s *Store) CallerCounts(file string) (map[int64]int, error)

CallerCounts returns the CALLS in-degree of every symbol defined in file, for surfaces that annotate whole files at once (code lenses).

func (*Store) Callers

func (s *Store) Callers(id int64) ([]CallEdge, error)

Callers returns symbols with a CALLS edge into id, with edge origins.

func (*Store) Close

func (s *Store) Close() error

Close releases the underlying database handle.

func (*Store) ClusterCitation added in v0.2.0

func (s *Store) ClusterCitation(ids []int64) (map[string]ClusterCited, error)

ClusterCitation reports, for every mined-lesson cluster the given finding ids touch, how much of the cluster those ids cover. The caller decides what coverage means — this method only counts. Duplicate ids are deduplicated first, so overlapping citation sets cannot inflate a count past the cluster's size.

func (*Store) CoChangePartners

func (s *Store) CoChangePartners(file string, minLift float64, limit int) ([]CoChangePartner, error)

CoChangePartners returns files that historically change together with file, strongest coupling first. minLift filters chance-level pairs; 1.0 is the neutral threshold.

func (*Store) CountCommitsTouching added in v0.3.0

func (s *Store) CountCommitsTouching(regions []string, since, until int64) (int, error)

CountCommitsTouching counts the distinct commits and reverts whose files fall inside any of the given regions within [since, until). The outcome loop uses this as its activity denominator: a region with no commits since exposure cannot prove a pin works.

A region matches as an exact file or as a directory prefix. Empty regions means repo-wide. Times are unix seconds like decision.ts; until <= 0 means no upper bound. Only commits and reverts count: pr/adr rows carry no file activity of their own, and counting them would double-count commits once a PR provider exists.

func (*Store) DecisionsForFile

func (s *Store) DecisionsForFile(file string, limit int) ([]model.Decision, error)

DecisionsForFile returns the most recent decisions touching a file. Bodies are included; callers decide how much to show.

func (*Store) DistilledSignatures

func (s *Store) DistilledSignatures() (map[string]bool, error)

DistilledSignatures returns the evidence sets already processed.

func (*Store) EdgeOriginCounts

func (s *Store) EdgeOriginCounts() (map[string]int, error)

EdgeOriginCounts returns CALL edge counts by resolution origin (qualified, same-package, unique-name, …) — the confidence distribution a consumer needs to weigh the graph's answers. Only call edges: defines/imports edges are structural facts with no resolution uncertainty, and mixing them in understates the call percentages.

func (*Store) EdgesFrom

func (s *Store) EdgesFrom(id int64, kind model.EdgeKind) ([]model.Symbol, error)

EdgesFrom returns symbols id has an outgoing edge of the given kind to.

func (*Store) EdgesTo

func (s *Store) EdgesTo(id int64, kind model.EdgeKind) ([]model.Symbol, error)

EdgesTo returns symbols with an edge of the given kind into id.

func (*Store) EffectOriginCounts

func (s *Store) EffectOriginCounts() (direct, propagated int, err error)

EffectOriginCounts returns how many distinct symbols carry direct sink tags versus propagated ones. Matching is case-insensitive: the indexer writes lowercase origins while the schema comment long claimed uppercase — tolerate both in databases that already exist.

func (*Store) EffectsForSymbol

func (s *Store) EffectsForSymbol(id int64) ([]Effect, error)

EffectsForSymbol returns a symbol's tags, direct first, then by depth.

func (*Store) EvidenceHorizon added in v0.3.0

func (s *Store) EvidenceHorizon() int64

EvidenceHorizon returns the timestamp the finding corpus is known current through: the older of the two mining stamps, because a recurrence can arrive through either channel. Zero when either stamp is missing — a store that cannot prove it looked cannot claim nothing was found, so verdicts stay untested until `seamark index --reviews` runs once.

func (*Store) ExportState

func (s *Store) ExportState() (*State, error)

ExportState collects the durable subset of the database. Both tables are read inside one transaction: SaveDistilledGroup commits proposals and their signature mark together, and an export must never split that pair — a mark without its proposals would suppress re-distillation while losing the paid result.

func (*Store) FileChurn

func (s *Store) FileChurn(limit int) ([]FileChurn, error)

FileChurn returns the most-touched files, busiest first. Where HotFiles ranks by coupling ("this rarely changes alone"), this ranks by sheer activity — the area metric behind the report's hotspot map, and the candidate set a fix-density pass then colours. A non-positive limit returns every file, as AllLessons does.

func (*Store) FileSymbolCounts

func (s *Store) FileSymbolCounts() (map[string]int, error)

FileSymbolCounts returns per-file symbol counts, for module summaries.

func (*Store) FindSymbols

func (s *Store) FindSymbols(query string, limit int) ([]model.Symbol, error)

FindSymbols resolves a user query to symbols, best matches first. It tries exact FQN, exact name, FQN suffix, then FTS prefix search, deduplicating across stages.

func (*Store) FindingCounts

func (s *Store) FindingCounts() (map[string]int, error)

FindingCounts returns mined findings by source (review, fix:…, revert).

func (*Store) FindingsForLesson

func (s *Store) FindingsForLesson(clusterKey string) ([]model.Finding, error)

FindingsForLesson returns the raw comments behind one lesson, oldest first — the evidence trail a distiller or a provenance view reads.

func (*Store) FindingsMetaByIDs added in v0.2.0

func (s *Store) FindingsMetaByIDs(ids []int64) (map[int64]model.Finding, error)

FindingsMetaByIDs returns the cited findings' metadata — everything confidence assessment needs (path, pr, source, timestamps) WITHOUT the bodies, so ambient surfaces can assess pins on every edit without hauling the corpus into memory. Duplicate ids are fine.

func (*Store) GetMeta

func (s *Store) GetMeta(key string) (string, error)

GetMeta returns the stored value or "" when absent.

func (*Store) History

func (s *Store) History() (HistoryWindow, error)

History returns the decision evidence window; zero values when no history was mined.

func (*Store) HotFiles

func (s *Store) HotFiles(limit int) ([]HotFile, error)

HotFiles returns the files most coupled to the rest of the repo by history. Pairs are stored once per (a, b), so both columns count.

func (*Store) ImportState

func (s *Store) ImportState(st *State) (ImportStats, error)

ImportState merges a bundle into the database, atomically. Identity is (signature, rule). Local rows win one exception: a local row still 'proposed' adopts an imported decided status — a decision beats no decision, but an existing local decision is never overwritten.

func (*Store) InsertProposal

func (s *Store) InsertProposal(p *model.Proposal) error

InsertProposal stores one distilled proposal and returns its id.

func (*Store) LessonsForFile

func (s *Store) LessonsForFile(file string, minOccur, limit int) ([]model.Lesson, error)

LessonsForFile returns recurring review feedback whose region is the file itself or the directory it lives in, strongest first. minOccur filters one-off comments — a lesson is a pattern, not a single note.

func (*Store) LoadParseCache

func (s *Store) LoadParseCache() (map[string]CacheEntry, error)

LoadParseCache returns the whole per-file parse cache. Callers version- check separately (via meta) and tolerate a decode failure per entry, so this simply hands back the stored blobs.

func (*Store) MarkDistilled

func (s *Store) MarkDistilled(signature, region string, at int64) error

MarkDistilled records that a candidate group's evidence set has been read by the distiller, so the same signature is never paid for again.

func (*Store) Proposals

func (s *Store) Proposals(status string) ([]model.Proposal, error)

Proposals returns proposals in one lifecycle state, newest first.

func (*Store) ProposalsByIDs

func (s *Store) ProposalsByIDs(ids []int64) ([]model.Proposal, error)

ProposalsByIDs returns the pending proposals with the given ids, in id order. Only 'proposed' rows qualify: applied and dismissed ones already carry a decision.

func (*Store) PruneStaleProposals

func (s *Store) PruneStaleProposals(liveSignatures map[string]bool) (int, error)

PruneStaleProposals deletes pending proposals whose evidence group no longer exists in the current grouping (its membership changed, so a fresh distill of the new signature supersedes them). Applied and dismissed rows are never touched — they are the decision memory.

func (*Store) Rebuild

func (s *Store) Rebuild(fn func(tx *Tx) error) error

Rebuild atomically replaces the derived tables (structure + history + effects). Policy and learning tables (rule, lesson) and meta survive, as they are user/agent state rather than derivations of the current tree. The FTS index is rebuilt after the callback succeeds.

func (*Store) RecentDecisions

func (s *Store) RecentDecisions(limit int) ([]model.Decision, error)

RecentDecisions returns the latest repo-wide decisions, newest first.

func (*Store) ReplaceFixFindings

func (s *Store) ReplaceFixFindings(findings []model.Finding) error

ReplaceFixFindings atomically swaps the fix-derived findings — their own lifecycle, independent of the review set.

func (*Store) ReplaceLessons

func (s *Store) ReplaceLessons(lessons []model.Lesson, findings []model.Finding) error

ReplaceLessons atomically swaps the lesson set — and the raw findings behind it — for a freshly mined one. Lessons are refreshed on the review-mining cadence, not the structural-reindex cadence, so this is their own transaction rather than part of Rebuild. Wiping both tables together keeps a finding's lesson_key from ever dangling.

func (*Store) SaveDistilledGroup

func (s *Store) SaveDistilledGroup(signature, region string, at int64, proposals []model.Proposal) ([]model.Proposal, error)

SaveDistilledGroup persists one distilled group atomically: its surviving proposals and its signature memory in a single transaction. The two must never diverge — proposals without the mark would be duplicated by the retry the unmarked signature invites; a mark without the proposals would silently discard the patterns a paid agent call found.

func (*Store) SetMeta

func (s *Store) SetMeta(key, value string) error

SetMeta stores an index bookkeeping value (schema version, repo root, …).

func (*Store) SetProposalStatus

func (s *Store) SetProposalStatus(ids []int64, to string) (int, error)

SetProposalStatus moves pending proposals to a decided state and reports how many actually moved. Only 'proposed' rows transition: a decision, once made, is not silently overwritten.

func (*Store) Stats

func (s *Store) Stats() (Stats, error)

Stats returns row counts of the derived tables.

func (*Store) SupersedeProposals

func (s *Store) SupersedeProposals(ids []int64) (int, error)

SupersedeProposals retires applied proposals whose pin was pruned as a restatement of another. Only 'applied' rows move: superseding something never applied would be meaningless.

func (*Store) SymbolAt

func (s *Store) SymbolAt(file string, line uint32) (*model.Symbol, error)

SymbolAt returns the innermost symbol whose span covers a 1-based line of file, or nil when the line is outside every declaration.

func (*Store) SymbolsByName

func (s *Store) SymbolsByName(name string) ([]model.Symbol, error)

SymbolsByName returns every symbol with exactly this name.

func (*Store) SymbolsInFile

func (s *Store) SymbolsInFile(file string) ([]model.Symbol, error)

SymbolsInFile returns all symbols defined in a repo-relative file, in source order.

func (*Store) TopCalled

func (s *Store) TopCalled(limit int) ([]CalledSymbol, error)

TopCalled returns the most-called symbols: the load-bearing API surface a newcomer should read first.

func (*Store) TopLessons

func (s *Store) TopLessons(minOccur, limit int) ([]model.Lesson, error)

TopLessons returns the strongest recurring review patterns repo-wide.

func (*Store) UpdateProposalRegionsBatch added in v0.2.0

func (s *Store) UpdateProposalRegionsBatch(ps []model.Proposal) error

UpdateProposalRegionsBatch rewrites the region sets of the given proposals in ONE transaction — the ledger half of retarget is all-or-nothing, so a mid-batch failure can never leave some pins retargeted in the database and others not while the file already carries every new identity.

func (*Store) UpdateProposalRegionsIfPending added in v0.4.0

func (s *Store) UpdateProposalRegionsIfPending(p model.Proposal) (bool, error)

UpdateProposalRegionsIfPending rewrites one proposal's regions only while it is still 'proposed', atomically. Extraction re-checks the status at write time: a proposal applied by a concurrent command during the agent call must keep the identity its yaml pin was installed with, or liveness, pruning, and outcomes all reason from a split identity.

func (*Store) UpdateProposalTriggers added in v0.4.0

func (s *Store) UpdateProposalTriggers(id int64, paths []string, checkedAt int64, promptVersion int) error

UpdateProposalTriggers stores one proposal's validated trigger paths and stamps when the question was answered — an empty answer is an answer, and must not be re-purchased. Regions are written separately: pending rows retarget in the same extraction run, applied pins only through the explicit --retarget — an installed pin's delivery never changes without the user.

type Tx

type Tx struct {
	// contains filtered or unexported fields
}

Tx is the write handle passed to a Rebuild callback.

func (*Tx) InsertCoChange

func (t *Tx) InsertCoChange(c model.CoChange) error

InsertCoChange stores one co-change pair (canonical file order expected).

func (*Tx) InsertDecision

func (t *Tx) InsertDecision(d *model.Decision) error

InsertDecision stores d (with its file links) and sets d.ID.

func (*Tx) InsertEdge

func (t *Tx) InsertEdge(e model.Edge) error

InsertEdge stores a structural edge; duplicate (src,dst,kind) rows are ignored so callers need not dedupe.

func (*Tx) InsertEffect

func (t *Tx) InsertEffect(symbolID int64, tag, origin string, depth int) error

InsertEffect stores one effect tag on a symbol. origin is "direct" for catalogue hits, "propagated" for tags inherited along CALLS edges.

func (*Tx) InsertLesson

func (t *Tx) InsertLesson(l *model.Lesson) error

InsertLesson stores one clustered review lesson. The cluster_key is unique; a repeated key accumulates occurrences and keeps the most recent example, so callers may insert per-cluster without pre-merging.

func (*Tx) InsertSymbol

func (t *Tx) InsertSymbol(sym *model.Symbol) error

InsertSymbol stores sym and sets sym.ID.

func (*Tx) PruneParseCache

func (t *Tx) PruneParseCache(keep map[string]bool) error

PruneParseCache drops cache rows for files no longer in the workspace, so a deleted file's stale parse output cannot linger.

func (*Tx) UpsertParseCache

func (t *Tx) UpsertParseCache(file, hash string, data []byte) error

UpsertParseCache stores one file's parse output.

Jump to

Keyboard shortcuts

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