query

package
v0.13.0 Latest Latest
Warning

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

Go to latest
Published: Jun 28, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package query holds domain query structs — pure read intent, processed by finders. Queries are plain data; no methods with side effects.

Index

Constants

View Source
const (
	DefaultUpDepth   = 2
	DefaultDownDepth = 1
)

Default expansion depths applied by the CLI when the flags are omitted. Upstream goes deeper to capture an entry's grounding; downstream stays shallow because consumers fan out far faster (a hub contract has dozens of immediate referrers).

View Source
const DefaultMaxCitationsPerEntry = 3

DefaultMaxCitationsPerEntry caps the number of citations an entry may contribute to its result row. Three is enough to show "this entry matched on summary, body section X, and attachment section Y" without drowning the output in near-duplicate chunks. Override on a query for terser ("--max-citations 1") or wider scans.

View Source
const DefaultSearchLimit = 10

DefaultSearchLimit is the top-N applied when SearchQuery.Limit is zero.

Variables

This section is empty.

Functions

func ExpandMacros added in v0.5.0

func ExpandMacros(layout model.Layout) (model.Layout, error)

ExpandMacros walks each section's first function and substitutes macro expansions per d-tac-uww §5. Macros recognized as the section's first function expand into a sequence of canonical primitives; subsequent user-supplied functions append to that sequence and resolve via the executor's last-write-wins rules. Functions appearing mid-section are always treated as primitives — `topic(L)` at section start expands to the macro pipeline; the same name later in the same section is the filter primitive.

Macro expansion is a separate query-layer pass distinct from grammar parsing so each can be tested in isolation. The CLI calls ParseLayout then ExpandMacros; tests can target either step.

func MacroNames added in v0.5.0

func MacroNames() []string

MacroNames returns the registered macro names sorted for deterministic help-text rendering. Exposed so the CLI's view help doesn't need to import the registry directly.

func ParseLayout added in v0.5.0

func ParseLayout(s string) (model.Layout, error)

ParseLayout parses a `--layout=<spec>` string into a Layout AST.

Slice 2 grammar (per d-tac-uww §3):

layout    := section ("," section)*
section   := func (":" func)*
func      := name ("(" arg-list? ")")?
arg-list  := arg ("," arg)*
arg       := func | number | identifier | string
name      := [a-zA-Z][a-zA-Z0-9_-]*
number    := -?[0-9]+ ("." [0-9]+)?
identifier:= same shape as name (leading letter required)
string    := "..." | '...'   (no escapes; cannot contain its own delimiter)

Comma at paren depth 0 separates sections; comma at depth > 0 separates args. The parser is permissive on names: any well-formed name parses, and the executor rejects unknown ones at runtime with a clear listed- valid-set error. Errors point to a 0-based byte position.

Types

type Citation added in v0.4.0

type Citation struct {
	Breadcrumb           []string
	Snippet              string
	SourceAttachmentPath string
	IsSummary            bool
	IsAttachment         bool
	Score                float32
}

Citation describes the chunk that motivated the hit — used to render the user-facing snippet so callers understand source. Breadcrumb is the heading-chain (empty for pre-heading body or summary chunks). Snippet is the citation body (~150 chars) with no Entry/Breadcrumb preamble.

Score is the per-chunk score the finder computed (depth/summary adjusted, status-adjusted at entry level). Different citations from the same entry typically carry different scores — the presenter normalizes them to a relative percentage at render time so the reader sees both the strongest hit and how the weaker ones compare.

type Finding

type Finding struct {
	Severity    Severity
	Category    string
	Observation string
}

Finding is a single observation from pre-flight validation.

type InfoQuery added in v0.5.2

type InfoQuery struct{}

InfoQuery captures intent to read session framing — participant identity, search capability, and configured graph language. No fields today; declared as a struct so the surface evolves consistently with the rest of the CQRS layer.

type InfoResult added in v0.5.2

type InfoResult struct {
	LocalParticipant string
	Language         string
	Search           string
}

InfoResult is the structured snapshot of session framing.

LocalParticipant surfaces the canonical participant name from .sdd/config.local.yaml so agents reading the header see ground truth without inferring from entries (which may carry drift). Empty means "not configured".

Language surfaces the configured graph language (locale code) from .sdd/config.yaml so the /sdd skill knows whether to load a translation vocabulary and author entries in the configured language. Empty means English (default) — the line is suppressed at render time.

Search renders as `text` when only text mode is available and `vector,text` when an embedding provider is configured.

type LintQuery

type LintQuery struct {
	Graph *model.Graph
}

LintQuery captures intent to surface graph integrity issues.

type LintResult

type LintResult struct {
	Entries     []*model.Entry
	TotalIssues int

	// IndexConfigured is true when an embedding provider is configured.
	// When false, the rest of the index-side fields are zero values and
	// presenters skip rendering the index section.
	IndexConfigured bool
	// IndexEntryCount is the number of entries the manifest knows about.
	IndexEntryCount int
	// IndexDriftCount is the number of manifest entries whose recorded
	// fingerprint differs from the configured embedder. Run
	// `sdd index --force` (or just `sdd search` to lazy-fill) to
	// converge.
	IndexDriftCount int
	// IndexFingerprint is the current embedder fingerprint, included in
	// the lint output so the user can see what the index is being
	// compared against.
	IndexFingerprint string
}

LintResult is the structured output of a LintQuery: every entry that has at least one warning, plus the total warning count for convenience.

Index-side fields (IndexConfigured, IndexEntryCount, IndexDriftCount, IndexFingerprint) are populated by the CLI lint action when an embedding provider is configured — the finder itself stays pure-graph. They surface the search index's health alongside graph health so a single `sdd lint` run reports both.

type PreflightQuery

type PreflightQuery struct {
	Entry   *model.Entry
	Graph   *model.Graph
	Model   string        // LLM model identifier (e.g. "claude-sonnet-4-6")
	Timeout time.Duration // hard timeout for the validator call
}

PreflightQuery captures intent to validate an entry against the graph using the pre-flight LLM validator. Pure read — no side effects of its own; the runner dependency injected into the finder handles the LLM call.

type PreflightResult

type PreflightResult struct {
	Findings []Finding
}

PreflightResult holds all findings from a pre-flight validator run. An empty Findings slice means the validator reported no findings.

func (*PreflightResult) HasBlocking

func (r *PreflightResult) HasBlocking() bool

HasBlocking reports whether any finding blocks entry creation. Currently only SeverityHigh blocks; this is the single source of truth for the blocking threshold (handler_new_entry uses it; templates do not).

type SchemaStatusQuery added in v0.2.0

type SchemaStatusQuery struct {
	// SDDDir is the absolute path to the .sdd/ directory. The query resolves
	// meta.json relative to this path.
	SDDDir string

	// BinaryVersion is the running sdd binary's version string (semver for
	// releases, "dev" or similar for local builds). Dev builds bypass both
	// compatibility gates.
	BinaryVersion string

	// BinarySchemaVersion is the schema version the binary understands. The
	// call site passes model.CurrentGraphSchemaVersion.
	BinarySchemaVersion int
}

SchemaStatusQuery captures intent to evaluate the current binary against the graph's .sdd/meta.json compatibility fields.

The dispatcher-level write-gate runs this query before any command that mutates the graph; read commands bypass the query entirely.

type SchemaStatusResult added in v0.2.0

type SchemaStatusResult struct {
	// MetaExists is false when .sdd/meta.json is not present on disk. In
	// that case Meta is nil and Compatibility is considered compatible (an
	// uninitialized graph will be set up on the next init).
	MetaExists bool

	// Meta is the parsed contents of .sdd/meta.json when MetaExists is true.
	Meta *model.SchemaMeta

	// Compatibility is the result of checking Meta against the binary's
	// version and schema version. Always populated (with Compatible = true)
	// when MetaExists is false.
	Compatibility model.CompatibilityResult
}

SchemaStatusResult reports whether the binary is permitted to proceed and, when !Compatibility.Compatible, why.

type SearchEntry added in v0.4.0

type SearchEntry struct {
	Entry     *model.Entry
	Score     float32
	Citations []Citation
}

SearchEntry pairs a graph entry with its score and one-or-more citations. The citation slice is ordered best-first; for entries with multiple strongly-matching chunks (e.g. a long plan whose summary, approach section, and attachment all match a query) the slice carries each one so the agent reading the result sees the breadth of why the entry matched, not just its single strongest chunk.

func (SearchEntry) Citation added in v0.4.0

func (e SearchEntry) Citation() Citation

Citation returns the entry's primary citation — the best-scoring chunk. Used by callers that don't iterate the full Citations slice. Returns the zero value when Citations is empty (rare; only when no chunk hit could be associated with the entry).

type SearchMode added in v0.4.0

type SearchMode string

SearchMode is derived from the SearchQuery's input shape: text-only, vector-only, or hybrid (when both --term and --query are supplied). Stored as a string so presenters and skill guidance can render it without importing the query package.

const (
	SearchModeText   SearchMode = "text"
	SearchModeVector SearchMode = "vector"
	SearchModeHybrid SearchMode = "hybrid"
)

type SearchQuery added in v0.4.0

type SearchQuery struct {
	// Graph is the loaded graph used for filtering and entry resolution.
	// Required.
	Graph *model.Graph

	// Terms are the --term values: regex strings combined with AND. Each
	// must match somewhere in the entry's searchable text. Empty disables
	// text mode.
	Terms []string

	// Phrase is the --query value: a free-form phrase used for vector
	// search. Empty disables vector mode.
	Phrase string

	// Filter is the type/layer/kind filter (model.GraphFilter), the same
	// filter shape the view pipeline composes.
	Filter model.GraphFilter

	// IncludeSuperseded includes entries whose derived status is
	// superseded-by-something. Default false — superseded entries are
	// excluded so search seeds reflect the current shape of the graph.
	IncludeSuperseded bool

	// Limit caps the number of returned entries. Zero means
	// DefaultSearchLimit.
	Limit int

	// MaxCitationsPerEntry is the literal cap on citations a single entry
	// may contribute. The value is taken as-is: 0 suppresses citations
	// entirely (entry headers only — the mechanical "which entries match,
	// and what topics do they carry" lookup), 1 renders one line per entry,
	// higher surfaces more of the matching surface. Unlike EffectiveLimit's
	// zero-means-default rule, zero here means zero — the default is applied
	// at the CLI boundary via cmd.IsSet, so the struct field carries literal
	// intent and programmatic callers must set the cap they want.
	MaxCitationsPerEntry int
}

SearchQuery carries the parsed input for the sdd search command. The finder derives the mode from which fields are populated.

func (SearchQuery) EffectiveLimit added in v0.4.0

func (q SearchQuery) EffectiveLimit() int

EffectiveLimit returns Limit or DefaultSearchLimit when zero.

func (SearchQuery) EffectiveMaxCitations added in v0.4.0

func (q SearchQuery) EffectiveMaxCitations() int

EffectiveMaxCitations returns the citation cap, clamping negatives to zero. Unlike EffectiveLimit, zero is NOT treated as "use the default": the field carries literal intent (0 means zero citations), and the default is resolved at the CLI boundary via cmd.IsSet.

func (SearchQuery) Mode added in v0.4.0

func (q SearchQuery) Mode() SearchMode

Mode resolves the SearchQuery's input shape to a SearchMode.

type SearchResult added in v0.4.0

type SearchResult struct {
	Mode    SearchMode
	Entries []SearchEntry
}

SearchResult carries the top-N entries with citations for rendering.

type SectionResult added in v0.5.0

type SectionResult struct {
	Render string            // render function name (e.g. "as-list")
	Name   string            // section header set by `name(string)`; empty = no header
	Data   model.SectionData // shape-tagged data variant produced by the finder
}

SectionResult is one section's render-ready data plus dispatch metadata. Render names the presenter that should consume Data; Data carries the shape-tagged result. The presenter validates that Data.Shape() matches what Render expects before rendering.

Name carries the section header set by `name(string)`. Empty Name means the section renders without a `## <title>` header (the slice 5/6 default for as-list and as-grouped).

type Severity

type Severity string

Severity classifies a pre-flight finding. The tooling layer decides what to block on (currently: only SeverityHigh blocks); templates describe severity in purely semantic terms and never name a threshold.

const (
	SeverityHigh   Severity = "high"
	SeverityMedium Severity = "medium"
	SeverityLow    Severity = "low"
)

type ShowGroup

type ShowGroup struct {
	Primary              *model.Entry
	PrimaryStatus        model.Status
	PrimarySupersedePath []string
	PrimaryTopics        []model.TopicPath
	Upstream             []model.ShowTreeItem
	Downstream           []model.ShowTreeItem
}

ShowGroup is one primary's full tree: the primary entry, its upstream chain, and its downstream chain. Primary-derived attributes (status, supersede trail, effective topics) are carried alongside so presenters render without touching the graph. Multiple groups are joined with separators.

type ShowQuery

type ShowQuery struct {
	Graph     *model.Graph
	IDs       []string
	UpDepth   int // upstream expansion depth (grounding chain); 0 = no upstream
	DownDepth int // downstream expansion depth (consumers); 0 = no downstream
}

ShowQuery captures intent to render a set of entries with their reference chains. Upstream and downstream each expand to their own depth; a depth of 0 skips that direction (downstream off, or upstream off, or both → primary only).

type ShowResult

type ShowResult struct {
	Graph  *model.Graph // needed to render derived attributes like status
	Groups []ShowGroup
}

ShowResult is the structured output for a ShowQuery — one group per primary.

type SkillStatusEntry added in v0.2.0

type SkillStatusEntry struct {
	Skill    string
	RelPath  string
	AbsPath  string
	Status   model.SkillInstallStatus
	Embedded model.SkillBundleEntry
	// Installed is the parsed on-disk copy. Nil when Status = Missing.
	Installed *model.SkillFile
}

SkillStatusEntry carries the inputs a handler needs to decide whether (and how) to write the file: the embedded source, the parsed on-disk copy (nil if missing), and the computed status classification.

type SkillStatusQuery added in v0.2.0

type SkillStatusQuery struct {
	Target   model.AgentTarget
	Scope    model.Scope
	RepoRoot string // required for ScopeProject
	UserHome string // required for ScopeUser
}

SkillStatusQuery captures intent to read the install state of the embedded skill bundle against a target agent's skill directory.

type SkillStatusResult added in v0.2.0

type SkillStatusResult struct {
	// InstallDir is the resolved absolute directory where skills install
	// for this target + scope combination.
	InstallDir string

	// Entries is one row per embedded skill file.
	Entries []SkillStatusEntry
}

SkillStatusResult is a per-entry snapshot of the bundle compared to disk.

type StatsQuery added in v0.9.0

type StatsQuery struct {
	StatsDir string
	Since    *time.Time
	Until    time.Time
	Op       string
	Provider string
	Model    string
}

StatsQuery captures intent to read and aggregate the local LLM/embedding stats sink. A nil Since means all-time; empty Op/Provider/Model strings mean no constraint on that field. Until is the reference "now" used for the range's upper bound in rendering.

type StatsResult added in v0.9.0

type StatsResult struct {
	Report    model.StatsReport
	Source    string
	Since     *time.Time
	Until     time.Time
	SinkEmpty bool
}

StatsResult is the aggregated output of a StatsQuery. SinkEmpty distinguishes "no sink on disk yet" from "sink had records but the filter excluded them all", so the renderer can phrase the empty case correctly.

type SyncStatusQuery added in v0.3.0

type SyncStatusQuery struct {
	// SDDDir is the .sdd/ directory where the last-fetch marker lives.
	SDDDir string
	// RespectCooldown, when true, short-circuits the query with a Skipped
	// state if the last fetch is within the configured cooldown window.
	// When false the fetch runs regardless — useful for callers invoked
	// by an explicit user action rather than incidental to a command.
	RespectCooldown bool
}

SyncStatusQuery captures intent to check whether the local graph is in sync with the upstream branch. Processing involves a (potentially rate-limited) git fetch and several read-only git plumbing calls; the side effect of touching the last-fetch marker is considered internal bookkeeping rather than a domain mutation, matching the PreflightQuery precedent where an LLM call is embedded in a read-intent query.

type ViewQuery added in v0.5.0

type ViewQuery struct {
	Graph    *model.Graph
	Layout   model.Layout
	GraphDir string
}

ViewQuery captures intent to execute a layout pipeline against the graph. The Layout AST is produced upstream by ParseLayout — the finder consumes the parsed shape rather than the raw `--layout` string.

GraphDir lets the finder source from disk when a section uses `source(wip)` — the executor calls LoadWIPMarkers against this directory rather than receiving pre-resolved markers in the query slot. Mirrors the shape used by WIPListQuery; can be left empty when no section needs it (the executor errors at section-evaluation time if source(wip) appears without a configured GraphDir). The broader CQRS leak across read queries is captured separately in s-tac-m09 — slice 8 follows the existing peer shape rather than diverging.

type ViewResult added in v0.5.0

type ViewResult struct {
	Graph    *model.Graph // needed by presenters for derived attributes (status, topics)
	Sections []SectionResult
}

ViewResult is the structured output of a ViewQuery: one SectionResult per section in the source layout, in the order they appeared.

type WIPListQuery

type WIPListQuery struct {
	GraphDir string
}

WIPListQuery captures intent to list active WIP markers.

type WIPListResult

type WIPListResult struct {
	Markers []*model.WIPMarker
}

WIPListResult is the structured output of a WIPListQuery.

Jump to

Keyboard shortcuts

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