govern

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package govern wraps a recall store in a fail-closed retrieval interface.

recall's own Search is permissive by design: filters live in SearchOptions, a caller may pass none, and search spans every namespace in the store. That is right for a retrieval library. It is wrong for a system where a retrieval is an access decision — there, a caller who says nothing should be refused, not served everything.

This package supplies the missing default. It refuses a request that has not decided its scope, has not declared a classification, or cannot be recorded, and it refuses before touching the store: an interface that only refuses after opening a connection has already revealed that the caller asked.

What it does not decide

Classification is an opaque, required string. This package does not know what values exist, which dominate which, or who may see what — only that a caller must state one. Source names are likewise opaque. The policy belongs to the system embedding this; what belongs here is that no policy can be skipped by omission.

The refusals are ported from a store that enforced them in production, and each one is there because its absence was a real hazard rather than a theoretical one. Their reasoning is recorded per-refusal below.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoQuery: a retrieval with no question is not a retrieval, and
	// refusing early keeps the audit record meaningful.
	ErrNoQuery = errors.New("govern: query is required")

	// ErrNoClassification: classification is the access decision. Without one
	// the interface cannot know what the caller may see, and any default would
	// be a policy nobody wrote.
	ErrNoClassification = errors.New("govern: classification is required")

	// ErrNoScope: the central refusal. A caller must choose between naming
	// sources and deliberately spanning all of them. Silence would default to
	// reading everything, which is the behaviour this package exists to
	// prevent.
	ErrNoScope = errors.New("govern: source scope is required")

	// ErrAmbiguousScope: naming sources *and* asking for all of them is
	// ambiguous rather than resolvable. Picking either reading would silently
	// widen or narrow what the caller sees.
	ErrAmbiguousScope = errors.New("govern: source scope is ambiguous")

	// ErrBlankSource: a blank entry is a scope nobody chose. Treating it as a
	// wildcard or dropping it would both be guesses.
	ErrBlankSource = errors.New("govern: source filter entries must be non-empty")

	// ErrNoRecorder: retrieval is recorded, so a request that cannot be
	// recorded is refused rather than served unrecorded.
	ErrNoRecorder = errors.New("govern: an audit recorder is required")

	// ErrNoEmbedderIdentity: a recorded retrieval must say what produced the
	// vectors it searched, or it cannot be reproduced later. The store this
	// was ported from refused a search with no embedding provider for the same
	// reason; recall injects its embedder at construction, so the identity is
	// required there instead.
	ErrNoEmbedderIdentity = errors.New("govern: embedder identity is required")
)

The refusals, as sentinel errors so a caller can distinguish a governance refusal from a retrieval failure.

Functions

This section is empty.

Types

type Entry

type Entry struct {
	Query          string
	Classification string
	SourceFilters  []string
	AllSources     bool
	Agent          string
	TaskID         string
	ResultCount    int
	Embedder       string
	Model          string
}

Entry is what a completed retrieval records.

Embedder and Model are here because a retrieval is only reproducible against the model that produced its vectors. The store this was ported from refused a search with no embedding provider for exactly that reason -- not because it could not have defaulted one, but because a silent default would make retrievals unattributable. recall injects its embedder at construction rather than per-request, so the same guarantee is met by requiring the identity once, when the governed view is built.

type Recorder

type Recorder interface {
	RecordRetrieval(ctx context.Context, entry Entry) error
}

Recorder receives one entry per completed retrieval.

Required rather than optional. A retrieval nobody can account for afterwards is the thing an audited store exists to make impossible, and an optional recorder is one a caller forgets.

type Request

type Request struct {
	Query          string
	Classification string
	SourceFilters  []string
	AllSources     bool
	Agent          string
	TaskID         string
	TopK           int
}

Request is a governed retrieval. Every field that must be decided is a field a caller has to set; none of them default.

type Searcher

type Searcher interface {
	Search(ctx context.Context, query string, opts index.SearchOptions) ([]index.SearchResult, error)
}

Searcher is the part of a recall store this package needs.

type Store

type Store struct {
	// ClassificationKey and SourceKey name the chunk metadata fields carrying
	// each value. They are configurable because the vocabulary belongs to the
	// embedding system, not to this package.
	ClassificationKey string
	SourceKey         string
	// contains filtered or unexported fields
}

Store is a fail-closed view over a recall store.

func New

func New(search Searcher, recorder Recorder, embedder, model string) (*Store, error)

New returns a governed view.

It refuses a nil recorder here rather than at the first search, so a system wired without auditing fails at construction rather than serving unrecorded retrievals until someone notices. The same reasoning applies to the embedder identity: an unattributable retrieval is refused at wiring time, when it is cheap to fix.

func (*Store) Search

func (s *Store) Search(ctx context.Context, req Request) ([]index.SearchResult, error)

Search performs a governed retrieval, or refuses.

func (*Store) Validate

func (s *Store) Validate(req Request) error

Validate applies every refusal without performing a retrieval.

Exported so a caller can check a request before building one, and so the refusals can be tested without a store — which is also how they are proven to happen before anything is touched.

Jump to

Keyboard shortcuts

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