openlore

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Aug 8, 2026 License: MIT Imports: 64 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultJobTimeout = 10 * time.Minute

DefaultJobTimeout caps a single job's command + write-back wall-clock time.

View Source
const ScopeFull = "full"

ScopeFull is the sentinel scope granting an identity its full authority (no narrowing). SSH key/cert logins resolve to this today; future WIF tokens will instead carry narrowing scopes. Missing/empty/unrecognized scopes are fail-closed (never full) — see docs/mcp-bearer-auth.md §5.4.

View Source
const ScopeRead = "read"

ScopeRead narrows a token to read-only authority. WIF rules use narrowing scopes like this to grant less than an identity's full authority.

Variables

View Source
var (
	WithConfigFile      = config.WithConfigFile
	WithEmbeddedConfig  = config.WithEmbeddedConfig
	WithPort            = config.WithPort
	WithMetricsPort     = config.WithMetricsPort
	WithHostKeyPath     = config.WithHostKeyPath
	WithAllowKeyless    = config.WithAllowKeyless
	WithDefaultCwd      = config.WithDefaultCwd
	WithMOTD            = config.WithMOTD
	WithMOTDFile        = config.WithMOTDFile
	WithAuthFile        = config.WithAuthFile
	WithAllowedPatterns = config.WithAllowedPatterns
	WithIgnorePatterns  = config.WithIgnorePatterns
	WithLogger          = config.WithLogger
	WithSkillsDir       = config.WithSkillsDir
	WithWritableDir     = config.WithWritableDir
	WithHTTPPort        = config.WithHTTPPort
	WithMCPPath         = config.WithMCPPath
	WithMCPEnabled      = config.WithMCPEnabled
	WithTLS             = config.WithTLS
	WithCAKeysFile      = config.WithCAKeysFile
	WithHostCertFile    = config.WithHostCertFile
	WithPasskeys        = config.WithPasskeys
	WithReadonly        = config.WithReadonly
	LoadAuthConfig      = config.LoadAuthConfig
	ValidateAuthConfig  = config.ValidateAuthConfig
)

Configuration options re-exported for external consumers.

View Source
var ErrInvalidScope = errors.New("invalid scope")

ErrInvalidScope signals that a matched WIF rule carries a scope OpenLore does not recognize (or none) — the exchange is denied (fail-closed, never full).

View Source
var ErrLogClosed = errors.New("openlore: write log closed")

ErrLogClosed is returned by writeLog.Submit once the log is shutting down.

View Source
var ErrRefreshInvalid = errors.New("invalid refresh token")

ErrRefreshInvalid signals an unknown or expired refresh token.

View Source
var ErrRefreshReuse = errors.New("refresh token reuse detected")

ErrRefreshReuse signals that an already-used refresh token was presented — a theft indicator. The store revokes the whole chain when this happens.

View Source
var ErrUnknownIdentity = errors.New("unknown identity")

ErrUnknownIdentity signals that a token's claims matched no identity and the posture is `unknown_identity: deny` — the caller must be rejected (403).

View Source
var ErrWIFDisabled = errors.New("workload identity federation is not enabled")

ErrWIFDisabled signals a jwt-bearer exchange arrived but no OIDC issuers are configured, so WIF is not enabled on this instance.

Functions

func EncodeEvent added in v0.2.0

func EncodeEvent(e Event) ([]byte, error)

EncodeEvent serialises an Event to the canonical JSON wire format shared by every transport (SSE, SSH tail, file notifier).

func MatchAll added in v0.2.0

func MatchAll(Event) bool

MatchAll delivers every event.

func NewMCPServer

func NewMCPServer(fs vfs.FileSystem, opts ...MCPOption) *mcp.Server

NewMCPServer creates an MCP server backed by the given filesystem. The returned server exposes two tools — `shell` and `list_commands` — that let agents browse and operate on the filesystem via a restricted shell.

Types

type Actor added in v0.2.0

type Actor struct {
	ID    string
	Extra map[string]string
	// contains filtered or unexported fields
}

Actor is non-durable context about the principal that triggered an operation. It flows into middleware for decisions, gating, and audit. It is deliberately NOT part of vfs.ChangeSet: proposer/approver identity is the consumer's record and decision input, never part of the content-addressed change.

type AuthConfig

type AuthConfig = config.AuthConfig

AuthConfig is loaded from auth.json.

type AuthIdentity

type AuthIdentity = config.AuthIdentity

AuthIdentity defines a user identity with access to a lore spec.

type AuthenticatedPrincipal added in v0.3.0

type AuthenticatedPrincipal struct {
	Subject      string
	IdentityName string
	Source       string
	Claims       map[string]any
	Scope        string
}

AuthenticatedPrincipal is the stable, transport-neutral authentication result passed to authorization. Subject is the original authenticated subject; IdentityName is the claim-resolved local identity.

type AuthorizationPolicy added in v0.3.0

type AuthorizationPolicy struct {
	IdentityName string
	Roles        []string
	HomeDocset   string
}

AuthorizationPolicy is current role membership and home ownership for a fully authenticated principal. Policy semantics remain in Server.

type AuthorizationStore added in v0.3.0

type AuthorizationStore interface {
	ResolveAuthorization(context.Context, AuthenticatedPrincipal) (AuthorizationPolicy, error)
}

AuthorizationStore separates authentication from current authorization.

type Claims added in v0.2.0

type Claims struct {
	Subject  string
	Scope    string
	Issuer   string
	Audience string
	Expiry   time.Time
	// Raw is the full claim set, used by the rule engine (WIF matches on
	// arbitrary claims). Standard claims are also present here.
	Raw map[string]any
}

Claims are the identity-bearing fields extracted from a verified access token. Nothing about authority is frozen in — resolution to an Identity happens live per request via the IdentityStore (see docs/mcp-bearer-auth.md §5.1).

type ClientStore added in v0.2.0

type ClientStore interface {
	// Save stores a newly registered client.
	Save(ctx context.Context, client OAuthClient) error
	// Lookup returns the client if present.
	Lookup(ctx context.Context, clientID string) (OAuthClient, bool, error)
}

ClientStore persists dynamically registered OAuth clients. The flat-file default lives in DataDir; knowledge-backend supplies a SQLite implementation so every instance validates the same registered clients (docs/mcp-bearer-auth.md §9).

type CommitInfo added in v0.2.0

type CommitInfo struct {
	ChangeSet vfs.ChangeSet
	Hash      string
	Actor     Actor
}

CommitInfo describes a committed change.

type ContentTransform added in v0.4.0

type ContentTransform func(path string, content []byte) []byte

ContentTransform changes bytes presented to a caller without changing stored bytes. Transforms run outside read tracking so CAS always records storage.

type ContentTransformProvider added in v0.4.0

type ContentTransformProvider interface{ ContentTransforms() []ContentTransform }

type DirFS

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

DirFS serves files from a real directory on disk. It is the reference vfs.WritableFS implementation.

Write capability is a stateful flag (the substrate-wide readonly lock). A freshly constructed DirFS is read-only; call SetWriteable to enable writes. WriteFileAtomic commits whole objects via temp-file + fsync + rename(2) (POSIX atomic swap). Post-commit reactions run through the server's post-commit middleware chain, not a fan-out bus.

func NewDirFS

func NewDirFS(root string, files config.FilesConfig) *DirFS

NewDirFS creates a new (read-only) DirFS rooted at the given directory.

func (*DirFS) GetXattr added in v0.4.0

func (d *DirFS) GetXattr(p, name string) ([]byte, error)

func (*DirFS) ListXattrs added in v0.4.0

func (d *DirFS) ListXattrs(p string) ([]string, error)

func (*DirFS) MigrateXattrs added in v0.4.0

func (d *DirFS) MigrateXattrs(p string, m vfs.XattrMigration) error

func (*DirFS) Mkdir added in v0.2.0

func (d *DirFS) Mkdir(p string) error

Mkdir creates a folder at p using plain mkdir semantics (the parent must exist). It errors if p is not strictly below a docset root.

func (*DirFS) MkdirAll added in v0.2.0

func (d *DirFS) MkdirAll(p string) error

MkdirAll creates p and any missing ancestors (mkdir -p). The enclosing docset root must already exist — MkdirAll will not create a docset root — and every folder it creates sits strictly below that root. An existing directory is a no-op success.

func (*DirFS) PreflightChange added in v0.4.0

func (d *DirFS) PreflightChange(change vfs.Change) error

PreflightChange checks deterministic write policy without inspecting mutable file/directory shape. Shape may intentionally change earlier in the batch.

func (*DirFS) PreserveAndRecreateXattrs added in v0.4.0

func (d *DirFS) PreserveAndRecreateXattrs(p string, attrs map[string][]byte) error

func (*DirFS) ReadDir

func (d *DirFS) ReadDir(p string) ([]vfs.FileInfo, error)

func (*DirFS) ReadFile

func (d *DirFS) ReadFile(p string) ([]byte, error)

func (*DirFS) Remove added in v0.2.0

func (d *DirFS) Remove(p string) error

Remove deletes a single file or empty directory at p. It refuses a docset root (or anything at/above one) and a non-empty directory.

func (*DirFS) RemoveAll added in v0.2.0

func (d *DirFS) RemoveAll(p string, opts vfs.RemoveOpts) error

RemoveAll deletes p and everything under it atomically. It snapshots the raw physical subtree (refusing the delete if it holds any file/dir hidden by file policy), enforces opts.Expected as an exact compare-and-swap, then renames the subtree into the hidden staging root (atomic visibility) and destroys the staged copy synchronously.

func (*DirFS) RemoveXattr added in v0.4.0

func (d *DirFS) RemoveXattr(p, name string) error

func (*DirFS) SetReadonly added in v0.2.0

func (d *DirFS) SetReadonly() error

SetReadonly transitions the substrate back to read-only, draining in-flight writes first (the exclusive lock blocks until current writers release). Idempotent.

func (*DirFS) SetWriteable added in v0.2.0

func (d *DirFS) SetWriteable() error

SetWriteable transitions the substrate to writable. Idempotent. It also sweeps any staging tree left behind by a delete interrupted by a crash.

func (*DirFS) SetXattr added in v0.4.0

func (d *DirFS) SetXattr(p, name string, value []byte, flags vfs.XattrFlags) error

func (*DirFS) Stat

func (d *DirFS) Stat(p string) (*vfs.FileInfo, error)

func (*DirFS) WithDocsetRoots added in v0.2.0

func (d *DirFS) WithDocsetRoots(roots []string) *DirFS

WithDocsetRoots sets the Mkdir boundary to the given logical docset roots — a folder may only be created strictly below one of them — and returns the receiver for chaining. Configure before the DirFS is shared across goroutines.

func (*DirFS) WithMaxWriteBytes added in v0.4.0

func (d *DirFS) WithMaxWriteBytes(max int64) *DirFS

WithMaxWriteBytes sets the substrate cap for one atomic write. A zero value retains the 8 MiB default. Configure before sharing the DirFS.

func (*DirFS) WriteFileAtomic added in v0.2.0

func (d *DirFS) WriteFileAtomic(p string, content []byte, opts vfs.WriteOpts) (string, error)

WriteFileAtomic commits content to p as a single atomic object. The precondition (opts) is checked under the same lock that guards the commit, so the read-current → check → swap sequence is atomic. Returns the hex SHA-256 of the committed bytes.

type DocsetSpec

type DocsetSpec = config.DocsetSpec

DocsetSpec defines a named set of path mappings for a docset.

type EmbedFS

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

EmbedFS serves files from an embed.FS.

func NewEmbedFS

func NewEmbedFS(efs embed.FS, root string, files config.FilesConfig) *EmbedFS

NewEmbedFS creates a new EmbedFS.

func (*EmbedFS) ReadDir

func (e *EmbedFS) ReadDir(p string) ([]vfs.FileInfo, error)

func (*EmbedFS) ReadFile

func (e *EmbedFS) ReadFile(p string) ([]byte, error)

func (*EmbedFS) Stat

func (e *EmbedFS) Stat(p string) (*vfs.FileInfo, error)

type Emit added in v0.2.0

type Emit interface {
	// Emit appends the event to the stream. Implementations default At when
	// zero. Errors are limited to stream lifecycle / encoding problems; a
	// slow or absent reader is never an error.
	Emit(ctx context.Context, e Event) error
}

Emit is the append-only sink for storage events. It is deliberately NOT a subscriber bus: it fans events into an in-memory tailable stream (ring + live readers) only. All routing, queueing, notification, and coordination policy lives in the host application (e.g. the knowledge backend), which calls Emit from its own write and domain code.

type EmitFunc added in v0.2.0

type EmitFunc func(ctx context.Context, e Event) error

EmitFunc adapts a function to the Emit interface.

func (EmitFunc) Emit added in v0.2.0

func (f EmitFunc) Emit(ctx context.Context, e Event) error

Emit implements Emit.

type Event added in v0.2.0

type Event struct {
	// Kind names the event type.
	Kind EventKind
	// Path is the virtual filesystem path the event refers to. Empty for
	// startup / non-FS events.
	Path string
	// Agent is the publishing principal's agent ID. Empty for system events.
	Agent string
	// Partition is the partition slug the event scopes to. Empty if not
	// partition-scoped.
	Partition string
	// ContentHash is a content-addressed identifier for the bytes written.
	ContentHash string
	// Bytes is the byte count being written. Set for post_write events.
	Bytes int
	// At is the event timestamp. Defaults to time.Now() if zero.
	At time.Time
	// Extra is an optional bag of consumer-specific metadata.
	Extra map[string]string
}

Event is the canonical storage event. It carries the same payload regardless of transport (in-process Go, SSE, SSH tail).

type EventFilter added in v0.2.0

type EventFilter func(Event) bool

EventFilter reports whether an event should be delivered to a reader.

func MatchPartition added in v0.2.0

func MatchPartition(partition string) EventFilter

MatchPartition delivers only events for the given partition slug. An empty slug matches all events.

type EventKind added in v0.2.0

type EventKind string

EventKind names a storage event. New kinds may be added; consumers should ignore unknown kinds rather than error out.

const (
	// KindOnStartup fires once when the server boots, before accepting traffic.
	KindOnStartup EventKind = "on_startup"
	// KindPreRead fires before a virtual file is read.
	KindPreRead EventKind = "pre_read"
	// KindPostWrite fires after a write has succeeded.
	KindPostWrite EventKind = "post_write"
	// KindPostDelete fires after a delete (rm / rm -r) has succeeded.
	KindPostDelete EventKind = "post_delete"
	// KindTopicRefreshed fires when a processing run finishes for a
	// content_hash. Emitted for observability on the feed.
	KindTopicRefreshed EventKind = "topic_refreshed"
)

type FSAdapter

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

FSAdapter adapts a standard fs.FS to the vfs.FileSystem interface.

func NewFSAdapter

func NewFSAdapter(fsys fs.FS) *FSAdapter

NewFSAdapter creates a new FSAdapter.

func (*FSAdapter) ReadDir

func (a *FSAdapter) ReadDir(p string) ([]vfs.FileInfo, error)

func (*FSAdapter) ReadFile

func (a *FSAdapter) ReadFile(p string) ([]byte, error)

func (*FSAdapter) Stat

func (a *FSAdapter) Stat(p string) (*vfs.FileInfo, error)

type FileSystem

type FileSystem = vfs.FileSystem

FileSystem is the read-only filesystem interface used by OpenLore.

type FilesConfig

type FilesConfig = config.FilesConfig

FilesConfig controls which files are served.

type GrantType added in v0.2.0

type GrantType interface {
	// Name is the grant identifier used in lore.json (e.g. "ro", "rw").
	Name() string
	// CanRead reports whether the grant permits reading display path p within
	// docset ds. p is a cleaned VFS display path already known to sit within the
	// docset.
	CanRead(ds config.DocsetSpec, p string) bool
	// AllowsWrite reports whether the grant ever permits writes at all. It drives
	// coarse shell action gating (whether write verbs are offered); per-op
	// authorization still runs through CanWrite.
	AllowsWrite() bool
	// CanWrite reports whether the grant permits mutation action on display path
	// p within docset ds.
	CanWrite(ds config.DocsetSpec, action vfs.ChangeAction, p string) bool
}

GrantType decides what a named grant permits within a single docset. Core registers the "ro" and "rw" grants; plugins contribute others (e.g. the inbox plugin's "publish") via GrantTypeProvider.

A grant only ever narrows. The authorizer consults it for reads and for each write action; its decision is then further capped by the token scope and the global / per-docset readonly locks (enforced by the server, not here). A grant name referenced by lore.json but not registered as a GrantType makes the server refuse to boot — fail-closed.

type GrantTypeProvider added in v0.2.0

type GrantTypeProvider interface {
	GrantTypes() []GrantType
}

GrantTypeProvider is implemented by a plugin that contributes named grant types. The server registers them at plugin registration so lore.json may reference the grant names.

type HTTPRouteProvider added in v0.4.0

type HTTPRouteProvider interface {
	PrepareHTTPRoutes(*Server) (HTTPRouteRegistrar, error)
}

type HTTPRouteRegistrar added in v0.4.0

type HTTPRouteRegistrar func(*http.ServeMux)

type Identity

type Identity struct {
	RemoteAddr   string
	User         string
	PublicKey    ssh.PublicKey
	SessionID    string
	ConnectedAt  time.Time
	IdentityName string // matched identity name from auth config
	Principal    AuthenticatedPrincipal

	HomeDir    string   // display path of the identity's home docset ($HOME); empty = none
	HomeDocset string   // name of the identity's home docset; empty = none
	Scopes     []string // token scopes narrowing authority; {ScopeFull} = full authority
	// contains filtered or unexported fields
}

Identity represents a connected caller (SSH session or MCP/HTTP request).

type IdentityStore added in v0.2.0

type IdentityStore interface {
	Resolve(ctx context.Context, claims Claims) (Identity, error)
}

IdentityStore resolves verified token claims to an Identity. It is the single seam that makes "permissions change live" work against either backend: the go-openlore default reads lore.json + rules; knowledge-backend supplies a SQLite-backed Resolve (docs/mcp-bearer-auth.md §7, §9).

type InboxPlugin added in v0.2.0

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

InboxPlugin contributes the "publish" grant: an identity holding it may read the whole docset, may never delete anything, and may only create or edit files within the docset's configured inbox folder. It is registered like any other plugin (Server.RegisterPlugin) and exposes its grant via GrantTypeProvider.

The inbox model lets an outside collaborator drop material into a docset (an "inbox") without granting them write access to the rest of the docset and without any ability to delete.

func NewInboxPlugin added in v0.2.0

func NewInboxPlugin() *InboxPlugin

NewInboxPlugin returns the inbox plugin.

func (*InboxPlugin) GrantTypes added in v0.2.0

func (*InboxPlugin) GrantTypes() []GrantType

GrantTypes implements GrantTypeProvider.

func (*InboxPlugin) Info added in v0.3.0

func (*InboxPlugin) Info() PluginInfo

Info implements PluginInfoProvider.

func (*InboxPlugin) PrepareHTTPRoutes added in v0.4.0

func (p *InboxPlugin) PrepareHTTPRoutes(s *Server) (HTTPRouteRegistrar, error)

type InboxToken added in v0.4.0

type InboxToken struct {
	ID        string     `json:"id"`
	Secret    string     `json:"secret,omitempty"`
	Identity  string     `json:"identity"`
	Label     string     `json:"label,omitempty"`
	CreatedAt time.Time  `json:"created_at"`
	ExpiresAt *time.Time `json:"expires_at,omitempty"`
}

InboxToken is a revocable credential for the inbox upload endpoint. Secret is deliberately persisted in plaintext because it is the HMAC key.

func (InboxToken) Credential added in v0.4.0

func (t InboxToken) Credential() string

type InboxTokenStore added in v0.4.0

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

func NewInboxTokenStore added in v0.4.0

func NewInboxTokenStore(dataDir string) (*InboxTokenStore, error)

func (*InboxTokenStore) Create added in v0.4.0

func (s *InboxTokenStore) Create(identity, label string, expires *time.Time) (InboxToken, error)

func (*InboxTokenStore) Delete added in v0.4.0

func (s *InboxTokenStore) Delete(id string) (bool, error)

func (*InboxTokenStore) Get added in v0.4.0

func (s *InboxTokenStore) Get(id string) (InboxToken, bool, error)

func (*InboxTokenStore) List added in v0.4.0

func (s *InboxTokenStore) List() ([]InboxToken, error)

type Issuer added in v0.2.0

type Issuer interface {
	// Mint signs a short-lived access token for the subject with the given
	// scope and TTL, returning the token and its expiry.
	Mint(sub, scope string, ttl time.Duration) (token string, exp time.Time, err error)
	// Verify parses and validates a token (signature, iss, aud, exp) and
	// returns its claims. A verification failure unwraps to auth.ErrInvalidToken.
	Verify(token string) (Claims, error)
	// JWKS returns the public JSON Web Key Set for this issuer.
	JWKS() ([]byte, error)
}

Issuer signs and verifies OpenLore access tokens and publishes its public keys as JWKS. The default implementation is ES256 with a keypair persisted in DataDir; knowledge-backend injects a DB-backed keypair for multi-instance deployments (docs/mcp-bearer-auth.md §5.3, §9).

func NewIssuerFromConfig added in v0.2.0

func NewIssuerFromConfig(cfg config.Config) (Issuer, error)

NewIssuerFromConfig builds the default ES256 Issuer from the server config's token settings, using the ES256 keypair under DataDir (generated on first use). It returns an error if tokens are not configured. Token config is server infrastructure and lives in openlore.yml, so this reads Config, not the lore.json AuthConfig. Used by the CLI `token` command and embedders.

type Job added in v0.2.0

type Job struct {
	ID        string
	Command   string
	Target    string
	Identity  string
	State     JobState
	Note      string // terminal detail: bytes written, pending request id, or error
	StartedAt time.Time
	EndedAt   time.Time
}

Job is the in-memory record of one async job (Part D). It is intentionally not persisted — a server restart loses in-flight jobs, which is acceptable for ad-hoc operational write-back.

type JobManager added in v0.2.0

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

JobManager runs JobSpecs on a bounded worker pool and keeps an in-memory registry surfaced read-only at /jobs. It implements cmds.JobBackend.

func NewJobManager added in v0.2.0

func NewJobManager(maxConcurrent int, runner Runner, logger *slog.Logger) *JobManager

NewJobManager creates a manager with at most maxConcurrent jobs running at once. runner defaults to a real `sh -c` runner.

func (*JobManager) Drain added in v0.2.0

func (m *JobManager) Drain(timeout time.Duration) bool

Drain waits for in-flight jobs to finish, up to timeout. Returns false if the timeout elapsed with jobs still running.

func (*JobManager) Submit added in v0.2.0

func (m *JobManager) Submit(spec cmds.JobSpec) (string, error)

Submit registers a job and starts it in the background, returning its id immediately (cmds.JobBackend).

type JobState added in v0.2.0

type JobState string

JobState is the lifecycle state of an async job.

const (
	// JobRunning: queued or executing.
	JobRunning JobState = "running"
	// JobDone: the command ran and its output committed (or was parked for
	// approval).
	JobDone JobState = "done"
	// JobFailed: the command failed, or its write-back could not commit.
	JobFailed JobState = "failed"
)

type JobsFS added in v0.2.0

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

JobsFS is the read-only computed filesystem mounted at /jobs. Each job renders as a file named by its id; the directory lists all jobs. It is not a vfs.WritableFS, so writes to /jobs are denied by MergeFS.

func NewJobsFS added in v0.2.0

func NewJobsFS(mgr *JobManager) *JobsFS

NewJobsFS wraps a manager as a read-only computed FS.

func (*JobsFS) ReadDir added in v0.2.0

func (f *JobsFS) ReadDir(p string) ([]vfs.FileInfo, error)

func (*JobsFS) ReadFile added in v0.2.0

func (f *JobsFS) ReadFile(p string) ([]byte, error)

func (*JobsFS) Stat added in v0.2.0

func (f *JobsFS) Stat(p string) (*vfs.FileInfo, error)

type MCPHTTPAPI added in v0.2.0

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

MCPHTTPAPI is a plain JSON HTTP API in front of an MCP server. Unlike the Streamable HTTP transport (which speaks the MCP wire protocol), this exposes simple REST-style endpoints that any HTTP client can call, while still routing every request through the MCP server's tools.

Each request runs on its own short-lived in-process MCP session. The session is connected with the request's context, so the server-side tool handler sees the caller's identity (via auth.TokenInfoFromContext) exactly as the Streamable transport does — identity always flows through the connection context, never through client-supplied tool arguments.

It mirrors the MCP server's two tools:

POST {prefix}/shell     -> body {"command": "..."} runs the `shell` tool
GET  {prefix}/commands  -> runs the `list_commands` tool

func NewMCPHTTPAPI added in v0.2.0

func NewMCPHTTPAPI(server *mcp.Server) *MCPHTTPAPI

NewMCPHTTPAPI returns an API that forwards HTTP requests to the given MCP server's tools, one in-process session per request.

func (*MCPHTTPAPI) Handler added in v0.2.0

func (a *MCPHTTPAPI) Handler(prefix string) http.Handler

Handler returns an http.Handler serving the API under the given path prefix (e.g. "/api"). Register it on a mux at prefix+"/".

type MCPOption

type MCPOption func(*mcpConfig)

MCPOption configures the MCP server constructed by NewMCPServer.

func WithMCPEnvVars

func WithMCPEnvVars(vars map[string]string) MCPOption

WithMCPEnvVars sets environment variables on the shell for every command execution.

func WithMCPInstructions

func WithMCPInstructions(instructions string) MCPOption

WithMCPInstructions sets server instructions that are automatically injected into the client's context when it connects.

func WithMCPServerName

func WithMCPServerName(name string) MCPOption

WithMCPServerName overrides the MCP server name reported in the initialize response. Clients see this in their connector list.

func WithMCPShellDescription

func WithMCPShellDescription(desc string) MCPOption

WithMCPShellDescription overrides the shell tool's description.

type MergeFS

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

MergeFS merges multiple filesystems under named mount points. An optional root filesystem serves content directly at "/".

func NewMergeFS

func NewMergeFS() *MergeFS

NewMergeFS creates an empty MergeFS.

func (*MergeFS) GetXattr added in v0.4.0

func (m *MergeFS) GetXattr(p, name string) ([]byte, error)

func (*MergeFS) ListXattrs added in v0.4.0

func (m *MergeFS) ListXattrs(p string) ([]string, error)

func (*MergeFS) MigrateXattrs added in v0.4.0

func (m *MergeFS) MigrateXattrs(p string, migration vfs.XattrMigration) error

func (*MergeFS) Mkdir added in v0.2.0

func (m *MergeFS) Mkdir(p string) error

Mkdir routes the folder creation to the resolved mount. Creating a docset (the merge root, or a mount root) is not allowed.

func (*MergeFS) MkdirAll added in v0.2.0

func (m *MergeFS) MkdirAll(p string) error

MkdirAll routes recursive folder creation to the resolved mount. Creating a docset (the merge root, or a mount root) is not allowed.

func (*MergeFS) Mount

func (m *MergeFS) Mount(name string, fs vfs.FileSystem)

Mount adds a filesystem under the given name.

func (*MergeFS) MountSystem added in v0.2.0

func (m *MergeFS) MountSystem(name string, fs vfs.FileSystem)

MountSystem adds a control-plane mount that is preserved across FilteredView for every session (it is not a lore docset). Used for /requests.

func (*MergeFS) PreflightChange added in v0.4.0

func (m *MergeFS) PreflightChange(change vfs.Change) error

func (*MergeFS) PreserveAndRecreateXattrs added in v0.4.0

func (m *MergeFS) PreserveAndRecreateXattrs(p string, attrs map[string][]byte) error

func (*MergeFS) ReadDir

func (m *MergeFS) ReadDir(p string) ([]vfs.FileInfo, error)

func (*MergeFS) ReadFile

func (m *MergeFS) ReadFile(p string) ([]byte, error)

func (*MergeFS) Remove added in v0.2.0

func (m *MergeFS) Remove(p string) error

Remove routes a single-file/empty-dir delete to the resolved mount. Deleting the merge root or a mount root is not allowed.

func (*MergeFS) RemoveAll added in v0.2.0

func (m *MergeFS) RemoveAll(p string, opts vfs.RemoveOpts) error

RemoveAll routes a whole-tree delete to the resolved mount. A changeset spans exactly one writable backend; deleting the merge root or a mount root is not allowed. The Expected snapshot is passed through unchanged (its RelPaths are relative to the target, so they are mount-agnostic).

func (*MergeFS) RemoveXattr added in v0.4.0

func (m *MergeFS) RemoveXattr(p, name string) error

func (*MergeFS) SetReadonly added in v0.2.0

func (m *MergeFS) SetReadonly() error

SetReadonly fans out to every writable-capable backend, draining in-flight writes on each.

func (*MergeFS) SetRoot

func (m *MergeFS) SetRoot(fs vfs.FileSystem)

SetRoot sets the root filesystem that serves content at "/".

func (*MergeFS) SetWriteable added in v0.2.0

func (m *MergeFS) SetWriteable() error

SetWriteable fans out to every writable-capable backend (root + mounts). Read-only backends (EmbedFS, FSAdapter) are skipped. It fails fast if no backend can be made writable at all (e.g. a fully embedded, read-only distribution), so a misconfigured readonly=false is rejected at startup.

func (*MergeFS) SetXattr added in v0.4.0

func (m *MergeFS) SetXattr(p, name string, value []byte, flags vfs.XattrFlags) error

func (*MergeFS) Stat

func (m *MergeFS) Stat(p string) (*vfs.FileInfo, error)

func (*MergeFS) SystemMountPaths added in v0.2.0

func (m *MergeFS) SystemMountPaths() []string

SystemMountPaths returns the display paths ("/name") of every control-plane (system) mount. These are always readable regardless of an identity's roles, so the read-scoping layer includes them.

func (*MergeFS) WriteFileAtomic added in v0.2.0

func (m *MergeFS) WriteFileAtomic(p string, content []byte, opts vfs.WriteOpts) (string, error)

WriteFileAtomic routes the write to the resolved mount (or root). It errors if the path resolves to the merge root itself or to a read-only backend.

type MetaExtenderProvider added in v0.3.0

type MetaExtenderProvider interface {
	MetaExtenders() []meta.Extender
}

MetaExtenderProvider is implemented by a plugin that enriches `lore meta` records. registerPlugin detects it and collects each extender onto the server, which installs them per session (buildSessionShell). This is how the okf plugin annotates documents with OKF conformance in `lore meta` output where OKF applies, so read-side discovery agrees with write-side enforcement — without coupling the generic `lore meta` reader (pkg/meta) to the OKF spec.

type MetaFilterProvider added in v0.3.0

type MetaFilterProvider interface{ MetaFilters() []meta.Filter }

type OAuthClient added in v0.2.0

type OAuthClient struct {
	ClientID                string    `json:"client_id"`
	ClientName              string    `json:"client_name,omitempty"`
	RedirectURIs            []string  `json:"redirect_uris"`
	TokenEndpointAuthMethod string    `json:"token_endpoint_auth_method"`
	GrantTypes              []string  `json:"grant_types"`
	ResponseTypes           []string  `json:"response_types"`
	Scope                   string    `json:"scope,omitempty"`
	ClientIDIssuedAt        time.Time `json:"client_id_issued_at"`
}

OAuthClient is a client registered via Dynamic Client Registration (RFC 7591). OpenLore only supports public PKCE clients, so no client_secret is ever issued; the client_id is not a credential, it merely selects the registered redirect_uris that /authorize will accept (docs/mcp-bearer-auth.md §11 Phase 3).

func (OAuthClient) AllowsRedirect added in v0.2.0

func (c OAuthClient) AllowsRedirect(uri string) bool

AllowsRedirect reports whether uri exactly matches one of the client's registered redirect URIs. Registered clients get exact-match only (no normalization) to prevent redirect smuggling.

type OIDCVerifier added in v0.2.0

type OIDCVerifier interface {
	// Verify validates the assertion's signature (against the issuer's JWKS),
	// issuer, audience, and expiry, returning its claims. Failure unwraps to
	// auth.ErrInvalidToken.
	Verify(ctx context.Context, assertion string) (Claims, error)
}

OIDCVerifier verifies an external IdP assertion (a platform-issued JWT) for workload identity federation. It is the seam that turns a platform OIDC token (GitHub Actions, Kubernetes/SPIFFE, Okta, …) into OpenLore Claims the WIF rule engine can match. The default implementation (newOIDCVerifier) pins each trusted issuer to its own JWKS and requires OUR audience, so a token minted for one service cannot be replayed to another. Injectable so knowledge-backend can supply its own verifier. See workload-identity-federation.md.

type OnConnectFunc

type OnConnectFunc func(Identity)

OnConnectFunc is called when a new SSH session is established.

type OnDisconnectFunc

type OnDisconnectFunc func(Identity)

OnDisconnectFunc is called when an SSH session ends.

type Option

type Option = config.Option

Option is a functional option for configuring the server.

type OverlayFS added in v0.3.0

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

OverlayFS exposes a writable directory over a read-only filesystem at one virtual root. Upper entries shadow lower entries; directories are merged. Deletes of lower-backed paths are rejected because the overlay deliberately has no persistent whiteout format.

func NewOverlayFS added in v0.3.0

func NewOverlayFS(upper *DirFS, lower vfs.FileSystem) *OverlayFS

NewOverlayFS creates a filesystem with upper as its writable layer and lower as its read-only fallback.

func (*OverlayFS) GetXattr added in v0.4.0

func (o *OverlayFS) GetXattr(p, name string) ([]byte, error)

func (*OverlayFS) ListXattrs added in v0.4.0

func (o *OverlayFS) ListXattrs(p string) ([]string, error)

func (*OverlayFS) MigrateXattrs added in v0.4.0

func (o *OverlayFS) MigrateXattrs(p string, m vfs.XattrMigration) error

func (*OverlayFS) Mkdir added in v0.3.0

func (o *OverlayFS) Mkdir(p string) error

func (*OverlayFS) MkdirAll added in v0.3.0

func (o *OverlayFS) MkdirAll(p string) error

func (*OverlayFS) PreflightChange added in v0.4.0

func (o *OverlayFS) PreflightChange(change vfs.Change) error

func (*OverlayFS) PreserveAndRecreateXattrs added in v0.4.0

func (o *OverlayFS) PreserveAndRecreateXattrs(p string, attrs map[string][]byte) error

func (*OverlayFS) ReadDir added in v0.3.0

func (o *OverlayFS) ReadDir(p string) ([]vfs.FileInfo, error)

func (*OverlayFS) ReadFile added in v0.3.0

func (o *OverlayFS) ReadFile(p string) ([]byte, error)

func (*OverlayFS) Remove added in v0.3.0

func (o *OverlayFS) Remove(p string) error

func (*OverlayFS) RemoveAll added in v0.3.0

func (o *OverlayFS) RemoveAll(p string, opts vfs.RemoveOpts) error

func (*OverlayFS) RemoveXattr added in v0.4.0

func (o *OverlayFS) RemoveXattr(p, name string) error

func (*OverlayFS) SetReadonly added in v0.3.0

func (o *OverlayFS) SetReadonly() error

func (*OverlayFS) SetWriteable added in v0.3.0

func (o *OverlayFS) SetWriteable() error

func (*OverlayFS) SetXattr added in v0.4.0

func (o *OverlayFS) SetXattr(p, name string, value []byte, flags vfs.XattrFlags) error

func (*OverlayFS) Stat added in v0.3.0

func (o *OverlayFS) Stat(p string) (*vfs.FileInfo, error)

func (*OverlayFS) WriteFileAtomic added in v0.3.0

func (o *OverlayFS) WriteFileAtomic(p string, content []byte, opts vfs.WriteOpts) (string, error)

type PasskeysConfig

type PasskeysConfig = config.PasskeysConfig

PasskeysConfig holds WebAuthn passkey configuration.

type PathMapping

type PathMapping = config.PathMapping

PathMapping represents a path entry.

type PluginInfo added in v0.3.0

type PluginInfo struct {
	// Name is the plugin's stable identifier (e.g. "okf", "shellexec").
	Name string
	// Version is the plugin's semantic version (e.g. "0.1.0").
	Version string
}

PluginInfo identifies a registered plugin: a stable name and a semantic version. Every built-in plugin reports one via PluginInfoProvider so the active plugin set (and its versions) is recorded in the server's boot logs.

type PluginInfoProvider added in v0.3.0

type PluginInfoProvider interface {
	Info() PluginInfo
}

PluginInfoProvider is implemented by a plugin that reports its identity and version. registerPlugin logs it at registration, so the boot logs record exactly which plugins — and which versions — are active.

type PostCommitHandler added in v0.2.0

type PostCommitHandler func(ctx context.Context, info CommitInfo) error

PostCommitHandler processes a committed change.

type PostCommitMiddleware added in v0.2.0

type PostCommitMiddleware func(next PostCommitHandler) PostCommitHandler

PostCommitMiddleware wraps a PostCommitHandler.

type PostCommitProvider added in v0.2.0

type PostCommitProvider interface {
	PostCommitMiddleware() []PostCommitMiddleware
}

PostCommitProvider is implemented by a plugin that contributes post-commit middleware.

type ReadHandler added in v0.2.0

type ReadHandler func(ctx context.Context, op ReadOp) error

ReadHandler runs the before-read step. A non-nil error aborts the read.

type ReadKind added in v0.2.0

type ReadKind string

ReadKind names the read operation a ReadOp refers to.

const (
	ReadKindStat ReadKind = "stat"
	ReadKindDir  ReadKind = "readdir"
	ReadKindFile ReadKind = "readfile"
)

type ReadMiddleware added in v0.2.0

type ReadMiddleware func(next ReadHandler) ReadHandler

ReadMiddleware wraps a ReadHandler.

type ReadMiddlewareProvider added in v0.2.0

type ReadMiddlewareProvider interface {
	ReadMiddleware() []ReadMiddleware
}

ReadMiddlewareProvider is implemented by a plugin that contributes read middleware.

type ReadOp added in v0.2.0

type ReadOp struct {
	Path  string
	Kind  ReadKind
	Actor Actor
}

ReadOp is the input to the read chain.

type RefreshToken added in v0.2.0

type RefreshToken struct {
	Token     string    `json:"token"`
	Subject   string    `json:"subject"`
	Scope     string    `json:"scope"`
	ChainID   string    `json:"chain_id"`
	ExpiresAt time.Time `json:"expires_at"`
	Used      bool      `json:"used"`
}

RefreshToken is a stateful, revocable credential. Tokens in the same ChainID descend from one login; rotation issues a new token in the chain and marks the old one used, so re-presenting a used token reveals theft.

type RefreshTokenStore added in v0.2.0

type RefreshTokenStore interface {
	// Save stores a newly issued refresh token.
	Save(rt RefreshToken) error
	// Lookup returns the token if present.
	Lookup(token string) (RefreshToken, bool, error)
	// Rotate consumes oldToken and stores newToken (same chain) atomically. If
	// oldToken was already used it revokes the whole chain and returns
	// ErrRefreshReuse; if unknown/expired it returns ErrRefreshInvalid.
	Rotate(oldToken string, newToken RefreshToken) error
	// RevokeChain deletes every token descending from one login.
	RevokeChain(chainID string) error
}

RefreshTokenStore persists refresh tokens with rotation and reuse detection. The flat-file default lives in DataDir; knowledge-backend supplies a SQLite implementation (docs/mcp-bearer-auth.md §9).

type Runner added in v0.2.0

type Runner interface {
	// Run executes cmd with the given env. Returns the command's combined
	// output (stdout+stderr) and any execution error. Honour ctx for
	// cancellation/timeout.
	Run(ctx context.Context, cmd string, env []string) ([]byte, error)
}

Runner executes a shell command line. Production uses ShellRunner; tests substitute a fake. It backs the built-in shellexec plugin and the async job manager (spawn).

type SFTPHandler

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

SFTPHandler implements the SFTP server interfaces using a vfs.FileSystem.

func NewSFTPHandler

func NewSFTPHandler(fs vfs.FileSystem) *SFTPHandler

NewSFTPHandler creates a new SFTP handler backed by the given filesystem.

func (*SFTPHandler) Filecmd

func (h *SFTPHandler) Filecmd(r *sftp.Request) error

Filecmd rejects all file commands (read-only filesystem).

func (*SFTPHandler) Filelist

func (h *SFTPHandler) Filelist(r *sftp.Request) (sftp.ListerAt, error)

Filelist handles SFTP directory listing and stat requests.

func (*SFTPHandler) Fileread

func (h *SFTPHandler) Fileread(r *sftp.Request) (io.ReaderAt, error)

Fileread handles SFTP file read requests.

func (*SFTPHandler) Filewrite

func (h *SFTPHandler) Filewrite(r *sftp.Request) (io.WriterAt, error)

Filewrite rejects all write requests (read-only filesystem).

type Server

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

Server is the main OpenLore SSH server.

func NewServer

func NewServer(rootDir string, opts ...config.Option) (*Server, error)

NewServer creates a new OpenLore SSH server. rootDir is the primary directory to serve (can be empty if using Mount). Options are applied using the functional options pattern via config.Option.

func NewServerWithLowerFS added in v0.3.0

func NewServerWithLowerFS(lower fs.FS, opts ...config.Option) (*Server, error)

NewServerWithLowerFS creates a server with a read-only lower filesystem. When writable_dir is configured, its disk tree is layered over lower at the same virtual root and receives all writes.

func NewServerWithRootFS added in v0.2.0

func NewServerWithRootFS(root vfs.FileSystem, opts ...config.Option) (*Server, error)

NewServerWithRootFS creates a server whose root filesystem is a caller-supplied vfs.FileSystem, set BEFORE the writable substrate and the ordered write log are established. Use this (instead of NewServer + SetRootBashFS) when the root is a custom writable backend and writes should flow through the ordered log: a late SetRootBashFS runs after SetWriteable()/newWriteLog and would leave the log with no writable backend at construction time.

func (*Server) AdmitChangeSet added in v0.4.0

func (s *Server) AdmitChangeSet(ctx context.Context, id Identity, cs vfs.ChangeSet) (WriteResult, error)

func (*Server) CommitChangeSet added in v0.2.0

func (s *Server) CommitChangeSet(ctx context.Context, actor Actor, cs vfs.ChangeSet) (WriteResult, error)

CommitChangeSet appends an already-authorized ChangeSet directly to the ordered log, skipping the admission chain but still running the serialized applier (compare-and-swap against current state) and the post-commit chain. It is how a consumer commits a previously-deferred change after human approval: the change already passed admission when it was first parked, so re-running admission would let the approval middleware defer it again in an infinite loop.

It returns the committed hash (empty for non-write actions) or a CAS/commit error (*vfs.PreconditionError / *vfs.TreeStaleError on drift). If the substrate is read-only (no write log), it returns vfs.ErrReadOnly.

func (*Server) CompleteAuthorize added in v0.2.0

func (s *Server) CompleteAuthorize(requestID, sub string) (string, bool)

CompleteAuthorize is called by the passkey login-finish hook once a caller has authenticated as sub. It mints a PKCE-bound authorization code for the pending authorize request and returns the redirect URL (redirect_uri?code=&state=) the browser should navigate to. ok is false when the request id is unknown/expired or token auth is disabled.

func (*Server) Config

func (s *Server) Config() config.Config

Config returns the resolved configuration.

func (*Server) ExchangeAssertion added in v0.2.0

func (s *Server) ExchangeAssertion(ctx context.Context, assertion string) (sub, scope string, ttl time.Duration, err error)

ExchangeAssertion implements the jwt-bearer (WIF) exchange: it verifies an external IdP assertion, matches its claims to a WIF rule, and returns the subject/scope/TTL for the OpenLore token to mint. The verifier already pinned the assertion to a trusted issuer and OUR audience, so cross-service and cross-issuer replay are ruled out before any rule is consulted.

func (*Server) FileSystem

func (s *Server) FileSystem() vfs.FileSystem

FileSystem returns the server's filesystem.

func (*Server) IdentityExists added in v0.2.0

func (s *Server) IdentityExists(name string) bool

IdentityExists reports whether name is a registered identity in the auth table. It backs passkeys.TokenIssuer so `passkey register --identity` can validate its target.

func (*Server) IssueAuthCode added in v0.2.0

func (s *Server) IssueAuthCode(sub, scope string) (string, bool)

IssueAuthCode mints a single-use authorization code for the identity (`sub`), to be exchanged for tokens at /oauth/token. Returns false if token auth is disabled. The passkey login-success hook (Phase 2) calls this; tests use it to drive the authorization_code grant.

func (*Server) ListenAndServe

func (s *Server) ListenAndServe() error

ListenAndServe starts the SSH server (blocks).

func (*Server) Mount

func (s *Server) Mount(name string, fs vfs.FileSystem)

Mount adds a named filesystem mount point using a vfs.FileSystem.

func (*Server) MountFS

func (s *Server) MountFS(name string, fsys fs.FS)

MountFS adds a named filesystem mount point using a standard fs.FS.

func (*Server) OnConnect

func (s *Server) OnConnect(fn OnConnectFunc)

OnConnect registers a callback for new connections.

func (*Server) OnDisconnect

func (s *Server) OnDisconnect(fn OnDisconnectFunc)

OnDisconnect registers a callback for disconnections.

func (*Server) RegisterPlugin added in v0.2.0

func (s *Server) RegisterPlugin(p any) error

RegisterPlugin wires a plugin's middleware into the admission, read, and post-commit chains, in registration order. It is the exported seam for consumers (e.g. the knowledge-backend approvals plugin) to contribute middleware after NewServer returns.

Admission (write) and read middleware take effect for every session created afterward, because those chains are composed per-session in buildSessionShell. Post-commit middleware is refreshed onto the running write log here, so a post-commit provider registered after construction still fires on commits.

Call it before serving; it is not safe to call concurrently with live traffic.

func (*Server) SetRootBashFS

func (s *Server) SetRootBashFS(fsys vfs.FileSystem)

SetRootBashFS sets the root filesystem using a vfs.FileSystem. Paths that don't match any mount fall through to this filesystem.

func (*Server) SetRootFS

func (s *Server) SetRootFS(fsys fs.FS)

SetRootFS sets the root filesystem using a standard fs.FS.

func (*Server) SetSessionFSFn

func (s *Server) SetSessionFSFn(fn SessionFSFn)

SetSessionFSFn registers a per-session filesystem decorator. When set, the server calls fn(identity, baseFS) for each new SSH session and uses the returned filesystem for that session's shell.

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown gracefully shuts down the server.

type SessionFSFn

type SessionFSFn func(id Identity, base vfs.FileSystem) vfs.FileSystem

SessionFSFn returns the filesystem to use for a given SSH session identity. The default implementation returns the base FS unchanged.

type ShellRunner added in v0.2.0

type ShellRunner struct{}

ShellRunner runs commands via `sh -c`.

func (ShellRunner) Run added in v0.2.0

func (ShellRunner) Run(ctx context.Context, cmdLine string, env []string) ([]byte, error)

type Stream added in v0.2.0

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

Stream is an in-memory, tailable event stream: the mechanism half of the storage-event system. It implements Emit (append side) and offers three read transports over the same payload — a recent-events ring snapshot, a live Go channel subscription, and an io.ReadCloser for `tail -f`-style consumers — plus an SSE HTTP handler.

A Stream is intentionally ephemeral and lossy for slow readers: it is not a durable log, a queue, or a synchronization primitive. Host applications that need durable processing, queueing, or wait-coordination must implement those directly, not by subscribing to a Stream.

func NewStream added in v0.2.0

func NewStream(opts ...StreamOption) *Stream

NewStream constructs an empty Stream.

func (*Stream) ClientCount added in v0.2.0

func (s *Stream) ClientCount() int

ClientCount returns the number of currently-connected live readers.

func (*Stream) Emit added in v0.2.0

func (s *Stream) Emit(_ context.Context, e Event) error

Emit appends the event to the ring and non-blockingly delivers it to every matching live reader. It implements Emit. Slow readers drop the event.

func (*Stream) HTTPHandler added in v0.2.0

func (s *Stream) HTTPHandler(filterFromRequest func(*http.Request) EventFilter) http.Handler

HTTPHandler returns an SSE handler. filterFromRequest derives the per-request filter (e.g. from a `partition` query param); nil yields MatchAll.

func (*Stream) OpenReader added in v0.2.0

func (s *Stream) OpenReader(ctx context.Context, filter EventFilter) io.ReadCloser

OpenReader returns a tail-style io.ReadCloser that streams matching events, one JSON object per line (terminated by '\n', encoded by EncodeEvent). Read blocks until the next event or ctx cancellation; it returns io.EOF when the context is cancelled or the stream reader closes. Close is mandatory.

func (*Stream) Recent added in v0.2.0

func (s *Stream) Recent(filter EventFilter, n int) []Event

Recent returns up to n most-recent matching events (newest last). n <= 0 returns all matching events in the ring.

func (*Stream) Subscribe added in v0.2.0

func (s *Stream) Subscribe(filter EventFilter) (<-chan Event, func())

Subscribe registers a live reader filtered by filter (nil = all). It returns a channel of events and a cancel function the caller MUST invoke to release the subscription.

type StreamOption added in v0.2.0

type StreamOption func(*Stream)

StreamOption configures a Stream.

func WithClientBuffer added in v0.2.0

func WithClientBuffer(n int) StreamOption

WithClientBuffer sets the per-reader channel buffer (default 64).

func WithRingSize added in v0.2.0

func WithRingSize(n int) StreamOption

WithRingSize sets the recent-events ring buffer capacity (default 256).

type ValidatorProvider added in v0.3.0

type ValidatorProvider interface{ Validators() []validation.Validator }

ValidatorProvider is implemented by a plugin that contributes checks to the core `lore validate` command. registerPlugin collects validators onto the server, which installs them per session in buildSessionShell.

type WriteHandler added in v0.2.0

type WriteHandler func(ctx context.Context, op WriteOp) (WriteResult, error)

WriteHandler commits or hands off a WriteOp. The terminal handler submits to the write log; middleware wrap it.

type WriteMiddleware added in v0.2.0

type WriteMiddleware func(next WriteHandler) WriteHandler

WriteMiddleware wraps a WriteHandler.

type WriteMiddlewareProvider added in v0.2.0

type WriteMiddlewareProvider interface {
	WriteMiddleware() []WriteMiddleware
}

WriteMiddlewareProvider is implemented by a plugin that contributes admission middleware. The server composes providers' middleware in registration order, after the fixed scope layer.

type WriteOp added in v0.2.0

type WriteOp struct {
	Actor Actor
	// contains filtered or unexported fields
}

WriteOp is the input to the admission chain.

func NewWriteOp added in v0.4.0

func NewWriteOp(actor Actor, cs vfs.ChangeSet) WriteOp

NewWriteOp constructs an immutable admission operation. The changeset is intentionally not exposed: policy middleware must inspect every leaf.

func (WriteOp) Leaves added in v0.4.0

func (op WriteOp) Leaves() []vfs.Change

Leaves returns every proposed mutation in execution order.

func (WriteOp) Pending added in v0.4.0

func (op WriteOp) Pending(ref string) *vfs.PendingChangeError

Pending captures the complete operation for durable deferred processing.

type WriteResult added in v0.2.0

type WriteResult struct {
	// Hash is the committed content hash (empty for a delete, or when the
	// mutation was deferred/rejected).
	Hash string
}

WriteResult is the outcome of a committed mutation.

Directories

Path Synopsis
Package meta holds the business logic behind `lore meta`: walking a document tree, extracting each document's YAML frontmatter, and letting plugins enrich the result.
Package meta holds the business logic behind `lore meta`: walking a document tree, extracting each document's YAML frontmatter, and letting plugins enrich the result.
Package plugin defines the seven primary hook interfaces that pluggable openlore implementations satisfy (P1-07).
Package plugin defines the seven primary hook interfaces that pluggable openlore implementations satisfy (P1-07).
Package validation holds the generic bundle-linting mechanism behind `lore validate`.
Package validation holds the generic bundle-linting mechanism behind `lore validate`.

Jump to

Keyboard shortcuts

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