finders

package
v0.12.0 Latest Latest
Warning

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

Go to latest
Published: Jun 25, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Overview

Package finders processes domain query structs into results. Finders encapsulate the actual read logic and hold injected dependencies. Pure reads — no side effects of their own (though injected dependencies may perform IO, e.g. the LLM call behind the pre-flight runner).

Index

Constants

View Source
const DefaultStalledThreshold = 1.0

DefaultStalledThreshold is the score below which a focus target is classified as stalled when actors are assigned. Default 1.0 is "fewer than one fresh ref-equivalent post-14d-decay" — under exp-14d, a single ref two weeks old contributes 0.5, so a target needs more than two weeks of inactivity (or fewer than ~two recent refs) to drop below. Configurable via the `stalled(value)` modifier per d-tac-uww §6.

The default landed during slice 7 implementation as a starting point; the slice 8 closing findings attachment compares this default against alternatives on the live graph.

View Source
const GraphCommitGrepPattern = "^sdd:"

GraphCommitGrepPattern is the commit-message prefix emitted by every SDD handler (handler_new_entry, handler_summarize, handler_wip_start, handler_wip_done, handler_lint_fix, handler_rewrite, handler_init). The sync finder counts commits matching this pattern on either side of the local/upstream divergence to report graph activity.

Variables

This section is empty.

Functions

This section is empty.

Types

type Finder

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

Finder holds dependencies and config shared across query methods. Config is a snapshot taken at construction time — short-lived CLI means a single read at the composition root is sufficient. Nil means no config is available (fresh repo, read-only commands, tests); finder methods degrade gracefully.

func New

func New(opts Options) *Finder

New constructs a Finder with the given options.

func (*Finder) Info added in v0.5.2

func (f *Finder) Info(_ query.InfoQuery) (*query.InfoResult, error)

Info gathers session framing for the `sdd info` command — the session header surface that skill session-start injections read. Pure config inspection — no graph access required.

func (*Finder) Lint

func (f *Finder) Lint(q query.LintQuery) (*query.LintResult, error)

Lint returns every entry in the graph that has at least one warning, alongside the total warning count. Pure read — graph validation runs at graph-construction time, this just collects the results. Also checks summary hash staleness.

func (*Finder) LoadGraph

func (f *Finder) LoadGraph(dir string) (*model.Graph, error)

LoadGraph reads all .md files from dir (hierarchical YYYY/MM/ layout) and builds the graph.

func (*Finder) LoadWIPMarkers

func (f *Finder) LoadWIPMarkers(graphDir string) ([]*model.WIPMarker, error)

LoadWIPMarkers reads all marker files from the wip/ subdirectory of graphDir.

func (*Finder) Preflight

Preflight runs the pre-flight validator against the given query. Runs Go-side mechanical checks first (see mechanicalPreflight), then delegates to the llm package for rubric-based checks, merging the findings so callers see a unified view. Returns an error only for infrastructure failures.

Mechanical checks cover participant coverage (AC 6), actor canonical write-once (AC 5), and role canonical-match + refs-head (AC 7) per plan d-cpt-d34. The former LLM-judged participant-drift check is retired in favor of the mechanical canonical check.

The language-drift check receives the configured graph language from config (see Finder.language). Empty means no language check (English default); a locale code activates the check against description prose.

func (*Finder) SchemaStatus added in v0.2.0

SchemaStatus reads .sdd/meta.json (if present) and evaluates its compatibility fields against the calling binary's version and schema version. Pure read; no side effects.

When meta.json is absent the result reports MetaExists = false and Compatible = true — an uninitialised graph is the init command's responsibility, not the write gate's.

func (*Finder) Show

func (f *Finder) Show(q query.ShowQuery) (*query.ShowResult, error)

Show resolves the entries named in q and returns groups with upstream and downstream chains. The heavy lifting (tree traversal, dedup, depth limiting) is delegated to model.Graph.BuildShowTree.

func (*Finder) SkillStatus added in v0.2.0

SkillStatus loads the embedded skill bundle for the query's target, then walks each entry to compare its embedded content against the file on disk. Classification happens in model.ComputeSkillStatus — the finder only supplies inputs.

func (*Finder) Stats added in v0.9.0

func (f *Finder) Stats(q query.StatsQuery) (*query.StatsResult, error)

Stats reads the local LLM/embedding stats sink, applies the query's range and field filters, and aggregates the result. Pure read — the only side effect is the underlying file read in the reader. SinkEmpty reflects whether the sink held any records at all, before filtering.

func (*Finder) SyncStatus added in v0.3.0

func (f *Finder) SyncStatus(ctx context.Context, q query.SyncStatusQuery) (model.SyncStatus, error)

SyncStatus processes a SyncStatusQuery into a SyncStatus. Cooldown is read from the finder's Config; callers supply SDDDir for the last-fetch marker. The finder touches last-fetch on every successful attempt and on terminal failure states (no remote, no upstream, fetch failure) so transient environment issues don't re-poll on every command.

func (*Finder) View added in v0.5.0

func (f *Finder) View(q query.ViewQuery) (*query.ViewResult, error)

View executes the layout pipeline in q.Layout against q.Graph and returns one SectionResult per section in source order. Per the design, every section must terminate in a render function (e.g. as-list); render is always the pipeline's terminus.

Sourcing dispatches on the first `source(<name>)` call in the section (default `graph` when absent): graph sections walk q.Graph through the filter chain; wip sections call f.LoadWIPMarkers(q.GraphDir) to get a disjoint data set rendered by as-wip-list. The two paths share the section-walking shell but apply distinct primitive vocabularies; cross- path mixing (e.g. kind() over wip markers) errors with a source-aware message.

WIP markers are loaded once when any section in the layout uses source(wip), then the same slice is handed to every wip section in the layout — disk read amortises across sections. A nil GraphDir with a source(wip) layout errors at section evaluation; non-wip layouts ignore GraphDir entirely.

Unknown function names return an error listing the valid set so users (and future-slice tests) get a clear signal.

func (*Finder) WIPList

func (f *Finder) WIPList(q query.WIPListQuery) (*query.WIPListResult, error)

WIPList loads every active WIP marker from the wip/ subdirectory of q.GraphDir. Returns an empty result (not an error) when no markers exist.

type GitSyncer added in v0.3.0

type GitSyncer interface {
	// InRepo reports whether the process is inside a git working tree.
	InRepo(ctx context.Context) bool
	// HasRemote reports whether the repository has at least one remote configured.
	HasRemote(ctx context.Context) bool
	// UpstreamRef returns the upstream ref name for the current branch
	// (e.g. "origin/main"). Empty string + nil error means the branch has
	// no upstream configured.
	UpstreamRef(ctx context.Context) (string, error)
	// Fetch runs `git fetch` with no args. A non-nil error means the fetch
	// attempt failed (network, auth, etc.).
	Fetch(ctx context.Context) error
	// CountCommits counts commits in rangeSpec whose messages match the
	// given grep pattern (ERE). rangeSpec is a git log range such as
	// "HEAD..@{u}" or "@{u}..HEAD".
	CountCommits(ctx context.Context, rangeSpec, grepPattern string) (int, error)
	// MergeTreePredict simulates a three-way merge in memory and returns
	// the list of paths that would conflict. An empty slice means clean.
	// The merge base is computed by git internally from (ourRef, theirRef)
	// — this keeps the surface compatible with git 2.38 (the explicit
	// --merge-base flag was added in 2.40).
	MergeTreePredict(ctx context.Context, ourRef, theirRef string) ([]string, error)
}

GitSyncer is the git surface consumed by the sync finder. Production shells out via exec.Command; tests inject stubs. Methods return errors only for unexpected failures — missing-repo / missing-remote / missing-upstream are expressed through the dedicated boolean / string predicates (InRepo, HasRemote, UpstreamRef) so the finder can report distinct SyncStates rather than collapsing everything into errors.

type Options added in v0.3.0

type Options struct {
	PreflightRunner llm.Runner
	Config          *model.Config
	GitSyncer       GitSyncer
}

Options configures a new Finder. Zero-valued fields mean "not available" — methods that need a dependency fall back to empty/nil behaviour rather than failing.

type SearchFinder added in v0.4.0

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

SearchFinder is the read-side handler for sdd search. It composes three retrieval modes — text (live grep over .sdd/graph/), vector (chromem-go cosine search over chunks), and hybrid (RRF fusion when both are present) — and returns ranked entries with citation chunks.

Pure read: no side effects. The lazy-fill that precedes a query is the IndexHandler's job; this finder consumes the index as-is.

func NewSearchFinder added in v0.4.0

func NewSearchFinder(opts SearchFinderOptions) *SearchFinder

NewSearchFinder constructs a SearchFinder.

func (*SearchFinder) Search added in v0.4.0

Search dispatches the query to the appropriate mode.

func (*SearchFinder) VectorAvailable added in v0.4.0

func (f *SearchFinder) VectorAvailable() bool

VectorAvailable reports whether the configured dependencies allow vector or hybrid mode. Used by the CLI to render the `Search: text` vs `Search: vector,text` capability line in `sdd info`'s header.

type SearchFinderOptions added in v0.4.0

type SearchFinderOptions struct {
	GraphDir   string
	Embedder   llm.Embedder
	IndexStore *index.Index
}

SearchFinderOptions configures NewSearchFinder. GraphDir is required (used by text mode to resolve attachment paths). Embedder + IndexStore are required for vector and hybrid modes; their absence makes those modes return an error.

type TopicFilter added in v0.5.0

type TopicFilter struct {
	Prefix model.TopicPath
}

TopicFilter selects entries whose effective topic set contains a label matching the given prefix path component-wise (case-insensitive).

"Effective topics" of an entry combine inline `topics:` declared on the entry's own frontmatter with topics declared by `kind: annotation` entries whose refs (or per-topic members sub-selection) include the entry. This merge is what makes annotations a first-class clustering mechanism — an entry is "in topic X" whether it tagged itself or some annotation tagged it.

Owned by Plan 1 (d-tac-gvn) per the augmenting directive d-tac-9q1; Plan 2 (d-tac-uww, sdd view) consumes this primitive for its `topic(L)` filter vocabulary in the pipeline grammar.

func (TopicFilter) ExcludeEntries added in v0.5.1

func (f TopicFilter) ExcludeEntries(g *model.Graph, entries []*model.Entry) []*model.Entry

ExcludeEntries returns the subset of entries whose effective topic set does NOT match the prefix. Mirror of FilterEntries for the not(topic(...)) negation primitive (d-tac-e1s). A zero prefix is treated as "no exclusion" — every entry passes through unchanged.

func (TopicFilter) FilterEntries added in v0.5.0

func (f TopicFilter) FilterEntries(g *model.Graph, entries []*model.Entry) []*model.Entry

FilterEntries returns the subset of entries whose effective topic set matches the prefix. Order is preserved; nil input returns nil.

func (TopicFilter) MatchEntry added in v0.5.0

func (f TopicFilter) MatchEntry(g *model.Graph, e *model.Entry) bool

MatchEntry reports whether the entry has any effective topic with prefix. Pure — uses the graph's reverse index for annotation lookups, no I/O.

Jump to

Keyboard shortcuts

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