grpcdriver

package
v0.0.35 Latest Latest
Warning

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

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

Documentation

Overview

Package grpcdriver implements the harness side of the mecatl.driver.v1 store-driver protocol: gRPC client adapters that satisfy the engine's store seams over a remote, operator-run driver process, plus the matching server wrappers a Go driver (or a test fixture) mounts over an in-process store.

  • SessionStore implements port.SessionStore over SessionStoreService.
  • MemoryStore implements tool.MemoryStore over MemoryStoreService.
  • NewSessionStoreServer / NewMemoryStoreServer wrap an in-process store as the generated server interfaces (bufconn conformance fixtures today; promoting them to an importable location for external driver authors is deliberately deferred to a future DRIVERS.md — see docs/design/IMPLEMENTATION-NOTES.md).

Trust model

A driver is OPERATOR-CONFIGURED INFRASTRUCTURE, sitting at the same trust tier as an on-disk store directory (the JSONL file the jsonlstore adapter writes): it holds whatever the harness persists, and a corrupt or hostile payload from it fails the harness-side decode loudly — it never reaches the model silently. Sanitization of model-written memory values stays in the harness's memory tools; a driver is never trusted to sanitize. The server wrappers deliberately install no authentication or TLS: mount them only on a separately protected operator network, or provide those controls in the driver host.

Wire format and versioning

Session snapshots cross the wire as an OPAQUE, format-tagged envelope: the payload is exactly engine/adapter/sessnap's encoding and the format tag is SnapshotFormat ("sessnap-json/1"). The driver stores and returns the envelope verbatim and never decodes it. Snapshot schema evolution lives in sessnap (additive JSON fields); the envelope's format tag changes ONLY if the encoding itself is replaced. Load rejects an unknown format with an infrastructure error — never ErrNotFound.

Resilience posture

Deadline passthrough only: the caller's ctx deadline rides the RPC, there are NO retries, NO default deadline, and NO transient/permanent error classification — store consumers already treat Save/Load errors as unit failures. If drivers ever need retries/breakers the house pattern is a resilience DECORATOR over these clients (the llmresilience precedent), not knobs here. Dial is lazy (grpc.NewClient): the first RPC surfaces a connect error.

Index

Constants

View Source
const EventLogFormat = "eventlog-json/1"

EventLogFormat is the event-log envelope format tag this client writes on Append and accepts on Read: the payload is exactly json.Marshal of a session.Event (one event per message). It is the SAME tag the local jsonlstore writes inside its {"v":...,"ev":...} on-disk record (jsonlstore.eventLogFormat) — the wire and the file version the SAME event encoding, so a log written by one and read by the other agrees. The driver round-trips the tag verbatim; it changes only if the event encoding itself is replaced (session.Event's own schema evolution is additive and needs no bump). Read rejects any other tag as an infrastructure fault — a forward-incompatible log must fail loud, never silently skip.

SIGNPOST — a future format bump MUST be read-set-accept / write-newest: the readers (this client's Read, the server wrapper's Append decode-or-passthrough) must keep ACCEPTING every previously-shipped tag while Append WRITES only the newest. The driver round-trips envelopes verbatim and cannot migrate them.

View Source
const MaxSnapshotBytes = 64 << 20

MaxSnapshotBytes is the protocol's REQUIRED MINIMUM message capacity for a snapshot envelope: 64 MiB. A session snapshot legitimately reaches multiple MiB (inline media parts alone may carry session.MaxPromptMediaBytes = 20 MiB in one prompt, base64-inflated by sessnap's JSON encoding), so gRPC's default 4 MiB receive cap would brick Save/Load mid-session. Dial raises the client's per-call send AND receive limits to this value; a conforming driver MUST accept payloads up to it on its server too (grpc.MaxRecvMsgSize(MaxSnapshotBytes) — see the server-wrapper notes in server.go and the SessionSnapshot doc in session_store.proto). Pinned by the storeconformance "large snapshot" subtest run over bufconn.

View Source
const ScheduleFormat = "schedule-json/1"

ScheduleFormat is the schedule/fire-record envelope format tag this client writes on Save/RecordFire* and accepts on Load/LoadFire/List*: the payload is exactly `encoding/json` of a `port.Schedule` / `port.ScheduleFire` (the same encoding the in-process jsonlstore/redisstore persist). The driver round-trips the tag verbatim; it changes ONLY if the encoding itself is replaced (the Schedule/ScheduleFire structs' own schema evolution is additive and needs no bump). Load/LoadFire reject any other tag with an infrastructure error — never ErrScheduleNotFound.

SIGNPOST — a future format bump MUST be read-set-accept / write-newest: the readers (this client's Load/LoadFire, the server wrapper's Save/RecordFire* decode) must keep ACCEPTING every previously-shipped format tag while Save/RecordFire* WRITE only the newest. The driver round-trips envelopes verbatim and cannot migrate them — a bump that switches the write tag and rejects the old tag in the same step bricks every schedule/fire already stored under the old format.

View Source
const SnapshotFormat = "sessnap-json/1"

SnapshotFormat is the snapshot envelope format tag this client writes on Save and accepts on Load: the payload is exactly sessnap.Marshal output (one JSON line). The driver round-trips the tag verbatim; it changes ONLY if the encoding itself is replaced (sessnap's own schema evolution is additive and needs no bump). Load rejects any other tag with an infrastructure error — never ErrNotFound.

SIGNPOST — a future format bump MUST be read-set-accept / write-newest: the readers (this client's Load, the server wrapper's Save decode) must keep ACCEPTING every previously-shipped format tag while Save WRITES only the newest. A bump that switches the write tag and rejects the old tag in the same step bricks every session already stored under the old format — the driver round-trips envelopes verbatim and cannot migrate them.

Variables

View Source
var ErrDriverCursorUnsupported = errors.New("grpcdriver: remote driver does not support event-log cursors")

ErrDriverCursorUnsupported reports that the remote driver does not implement the cursor RPCs — an older driver process speaking only port.EventLog.

It exists because a type assertion cannot answer this question across a wire: this client satisfies port.CursorEventLog by construction, so composition would otherwise believe every driver supports cursors and discover otherwise only when a watch failed. ADR 0250 requires that a backend without cursor support be reported as UNSUPPORTED rather than silently degraded, and this is the value that makes that reportable.

View Source
var ErrMemoryLifecycleUnsupported = errors.New("remote memory driver does not support lifecycle operations")

ErrMemoryLifecycleUnsupported reports an old/base-only remote driver. Base memory operations remain usable; irreversible lifecycle operations never silently downgrade.

View Source
var ErrNotFound = fmt.Errorf("grpcdriver: session not found: %w", port.ErrSessionNotFound)

ErrNotFound is returned by Load when the driver has no snapshot under the given id. It wraps port.ErrSessionNotFound so a consumer that may not import this adapter can distinguish not-found from an infra failure via errors.Is.

Functions

func Dial

func Dial(target string, opts ...Option) (*grpc.ClientConn, error)

Dial connects to a store driver at target ("host:port") per opts. The connection is LAZY (grpc.NewClient): the first RPC surfaces a connect error. Plaintext is the LOCAL single-user default (loopback hosts and unix sockets); ANY other target requires WithTLS — token or not (see the cleartext refusal in dialOptions).

func NegotiateMemoryStore

func NegotiateMemoryStore(ctx context.Context, conn grpc.ClientConnInterface) (tool.MemoryStore, error)

NegotiateMemoryStore reads the explicit optional-capability signal once and returns either the base client or a distinct lifecycle-capable wrapper. Unimplemented means an older valid driver; every other negotiation failure is returned rather than silently changing the catalog.

func NewAgentSourceServer

func NewAgentSourceServer(src tool.AgentDefSource) driverv1.AgentSourceServiceServer

NewAgentSourceServer wraps src as an AgentSourceService driver server.

func NewAttemptRepositoryServer added in v0.0.24

func NewAttemptRepositoryServer(repository learning.AttemptRepository) driverv1.AttemptRepositoryServiceServer

NewAttemptRepositoryServer wraps a domain repository as a driver service.

func NewAutomaticAdmissionLedgerServer added in v0.0.24

func NewAutomaticAdmissionLedgerServer(ledger learning.AutomaticAdmissionLedger) driverv1.AutomaticAdmissionLedgerServiceServer

NewAutomaticAdmissionLedgerServer wraps a domain ledger as a driver service.

func NewCommandSourceServer

func NewCommandSourceServer(src prompt.CommandSource) driverv1.CommandSourceServiceServer

NewCommandSourceServer wraps src as a CommandSourceService driver server.

func NewEventLogServer

func NewEventLogServer(log port.EventLog) driverv1.EventLogServiceServer

NewEventLogServer wraps log as an EventLogService driver server.

func NewLearningRepositoryCapabilitiesServer added in v0.0.24

func NewLearningRepositoryCapabilitiesServer(capabilities LearningRepositoryCapabilities) driverv1.LearningRepositoryCapabilitiesServiceServer

NewLearningRepositoryCapabilitiesServer advertises one driver's complete repository set. It does not expose connection, identity, or storage details.

func NewMemoryStoreServer

func NewMemoryStoreServer(st tool.MemoryStore) driverv1.MemoryStoreServiceServer

NewMemoryStoreServer wraps st as a MemoryStoreService driver server.

func NewProposalRepositoryServer added in v0.0.24

func NewProposalRepositoryServer(repository learning.ProposalRepository) driverv1.ProposalRepositoryServiceServer

NewProposalRepositoryServer wraps a domain proposal repository as a driver service.

func NewScheduleOneShotReArmerServer

func NewScheduleOneShotReArmerServer(reArmer port.ScheduleOneShotReArmer) driverv1.ScheduleOneShotReArmerServiceServer

NewScheduleOneShotReArmerServer wraps reArmer as a ScheduleOneShotReArmerService driver server.

func NewScheduleStoreServer

func NewScheduleStoreServer(st port.ScheduleStore) driverv1.ScheduleStoreServiceServer

NewScheduleStoreServer wraps st as a ScheduleStoreService driver server.

func NewSessionLeaseServer

func NewSessionLeaseServer(lease port.SessionLease) driverv1.SessionLeaseServiceServer

NewSessionLeaseServer wraps lease as a SessionLeaseService driver server.

func NewSessionStoreServer

func NewSessionStoreServer(st port.SessionStore) driverv1.SessionStoreServiceServer

NewSessionStoreServer wraps st as a SessionStoreService driver server.

func NewSkillRepositoryServer added in v0.0.24

func NewSkillRepositoryServer(repository learning.SkillRepository) driverv1.SkillRepositoryServiceServer

NewSkillRepositoryServer wraps a domain repository as a driver service.

func NewSkillSourceServer

func NewSkillSourceServer(src tool.SkillSource) driverv1.SkillSourceServiceServer

NewSkillSourceServer wraps src as a SkillSourceService driver server.

func NewSoulSourceServer

func NewSoulSourceServer(src prompt.SoulSource) driverv1.SoulSourceServiceServer

NewSoulSourceServer wraps src as a SoulSourceService driver server. The wrapped Go source already upholds the fail-soft contract; the harness CLIENT re-validates the body regardless (it never trusts a driver to sanitize).

Types

type AgentOptions

type AgentOptions struct {
	// Diagnostics is the operational-logging sink for the defensive-drop WARNs
	// (an over-cap def, the def-count ceiling). nil defaults to
	// port.NopDiagnostics.
	Diagnostics port.Diagnostics
}

AgentOptions configures a remote AgentSource client.

type AgentSource

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

AgentSource is a tool.AgentDefSource over a remote AgentSourceService driver. It is translation plus a DEFENSIVE normalization layer (the driver sits at the operator-infrastructure trust tier, but its metadata feeds the always-in-context Subagent roster and per-def system prompts, so the client re-enforces the invariants the port promises rather than trusting the wire): names are TRIMMED before every use (the FS parser trims frontmatter names; the wire client must not be weaker), blank-name defs are dropped, duplicate names de-dup first-wins, the result is name-sorted, descriptions are forced single-line then re-truncated to tool.MaxAgentDescriptionBytes, bodies are re-truncated to tool.MaxAgentBodyBytes, per-def collection sizes are count-capped (see the caps above — an over-cap def is dropped with a WARN), hooks/headers are re-normalized via the SAME exported helpers the parser uses (agents.NormalizeHooks/NormalizeHeaders), and Origin is stamped AgentOriginDriver UNCONDITIONALLY — a driver-served def IS driver tier; a driver must not claim the "project"/"user" admission labels (the wire origin field stays driver-side observability only).

func NewAgentSource

func NewAgentSource(conn grpc.ClientConnInterface, opts AgentOptions) *AgentSource

NewAgentSource wraps an established driver connection (see Dial) as a tool.AgentDefSource.

func (*AgentSource) ListAgentDefs

func (s *AgentSource) ListAgentDefs(ctx context.Context) ([]tool.AgentDef, error)

ListAgentDefs returns the driver's definition snapshot, defensively normalized (see the type doc).

type AttemptRepository added in v0.0.24

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

AttemptRepository adapts the bounded learning attempt lifecycle to a remote driver. All records are revalidated after transport; versions remain opaque.

func NewAttemptRepository added in v0.0.24

func NewAttemptRepository(conn grpc.ClientConnInterface) *AttemptRepository

NewAttemptRepository wraps an established driver connection.

func (*AttemptRepository) Abandon added in v0.0.24

func (*AttemptRepository) AcquireClaim added in v0.0.24

func (*AttemptRepository) Checkpoint added in v0.0.24

func (*AttemptRepository) Create added in v0.0.24

func (*AttemptRepository) Delete added in v0.0.24

func (*AttemptRepository) DeleteTerminalOlderThan added in v0.0.24

func (r *AttemptRepository) DeleteTerminalOlderThan(ctx context.Context, partition learning.AttemptPartition, olderThan time.Duration, limit int) (int, error)

func (*AttemptRepository) DiscoverWork added in v0.0.24

func (*AttemptRepository) Finalize added in v0.0.24

func (*AttemptRepository) Get added in v0.0.24

func (*AttemptRepository) List added in v0.0.24

func (*AttemptRepository) ReleaseClaim added in v0.0.24

func (*AttemptRepository) RenewClaim added in v0.0.24

func (*AttemptRepository) Retry added in v0.0.24

type AutomaticAdmissionLedger added in v0.0.24

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

AutomaticAdmissionLedger adapts distributed automatic accounting to a remote infrastructure driver.

func NewAutomaticAdmissionLedger added in v0.0.24

func NewAutomaticAdmissionLedger(conn grpc.ClientConnInterface) *AutomaticAdmissionLedger

NewAutomaticAdmissionLedger wraps an established driver connection.

func (*AutomaticAdmissionLedger) DiscoverExpired added in v0.0.24

func (*AutomaticAdmissionLedger) Get added in v0.0.24

func (*AutomaticAdmissionLedger) Reassign added in v0.0.24

func (*AutomaticAdmissionLedger) Reserve added in v0.0.24

type CommandOptions

type CommandOptions struct {
	// Diagnostics is the operational-logging sink for the RUNTIME fail-soft
	// branches (a driver fault during a run degrades to "no commands from this
	// source" with a WARN, never an aborted run). nil defaults to
	// port.NopDiagnostics.
	Diagnostics port.Diagnostics
}

CommandOptions configures a remote CommandSource client.

type CommandSource

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

CommandSource is a prompt.CommandSource over a remote CommandSourceService driver. LIVE semantics: every Expand/List consults the driver (no snapshot, matching the file expander's reads-current-files discipline) — and deliberately NO latching: a transient fault must not latch a command "missing", and grammar-invalid names are re-dropped statelessly per List.

Defensive normalization on List (the driver is operator infrastructure, but the metadata feeds the palette): names that violate the invocation grammar are DROPPED (prompt.ValidCommandName — they could never be invoked), duplicates de-dup first-wins, the result is name-sorted, and descriptions are forced single-line then rune-capped to prompt.MaxCommandDescriptionRunes.

Fault posture: a RUNTIME fault fail-softs — ListCommands → (nil, nil) + WARN (prompt.MultiExpander.List aborts the whole palette walk on a child error, so a transient driver blip must not propagate), CommandBody → ("", false, nil) + WARN (the raw input passes through). A caller-cancelled ctx still surfaces (rpcErr rewraps so errors.Is(ctx.Err()) holds), as does the server's INVALID_ARGUMENT pre-validation (a programming error, not a blip). The BUILD-time reachability check is the separate Probe (loud-misconfig posture, fatal in the composition layer).

func NewCommandSource

func NewCommandSource(conn grpc.ClientConnInterface, opts CommandOptions) *CommandSource

NewCommandSource wraps an established driver connection (see Dial) as a prompt.CommandSource.

func (*CommandSource) CommandBody

func (s *CommandSource) CommandBody(ctx context.Context, name string) (string, bool, error)

CommandBody returns the named command's RAW template. A driver NOT_FOUND is the NORMAL unknown-command outcome (found=false, nil error → the input passes through unchanged); a runtime fault degrades the same way with a WARN; a caller-cancelled ctx and a server INVALID_ARGUMENT (blank name — pre-validated server-side) surface as non-nil errors.

func (*CommandSource) ListCommands

func (s *CommandSource) ListCommands(ctx context.Context) ([]prompt.Command, error)

ListCommands returns the driver's CURRENT command metadata, defensively normalized (see the type doc). A runtime driver fault degrades to (nil, nil) with a WARN.

func (*CommandSource) Probe

func (s *CommandSource) Probe(ctx context.Context) error

Probe performs the BUILD-time reachability check: one ListCommands round trip, returning the wrapped RPC error on a fault (the composition layer treats it as FATAL — an explicitly configured driver that cannot answer is a misconfiguration, unlike a runtime blip which the live calls degrade on). The command set itself is NOT judged: an empty set is a legal "no commands".

type EventLog

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

EventLog is a port.EventLog over a remote EventLogService driver. Encode (session.Event → JSON) happens HERE on Append and decode (JSON → session.Event) HERE on Read, harness-side: the driver only ever sees the opaque format-tagged envelope, exactly as the SessionStore driver keeps sessnap harness-side.

func NewEventLog

func NewEventLog(conn grpc.ClientConnInterface) *EventLog

NewEventLog wraps an established driver connection (see Dial) as a port.EventLog.

func (*EventLog) Append

func (l *EventLog) Append(ctx context.Context, id session.SessionID, ev session.Event) error

Append encodes ev to its session.Event JSON and records it under id on the driver, in append order. A marshal failure is a client-side error (no RPC). The relay treats any non-nil error as "not recorded" and WARNs.

func (*EventLog) AppendEvent added in v0.0.22

func (l *EventLog) AppendEvent(ctx context.Context, id session.SessionID, ev session.Event) (port.Cursor, error)

AppendEvent records ev on the driver and returns the cursor it reports.

The returned cursor is the driver's own token, passed through untouched. This client never calls port.EncodeCursor: doing so would wrap a token whose generation basis lives in another process, and the harness has no basis of its own to put in it.

func (*EventLog) AppendGap added in v0.0.22

func (l *EventLog) AppendGap(ctx context.Context, id session.SessionID, reason string) (port.Cursor, error)

AppendGap records a gap marker on the driver and returns its cursor.

func (*EventLog) Read

Read streams the session's recorded events from the driver and decodes each envelope back into a session.Event, yielding them in append order. An empty stream (a session never appended to) yields an EMPTY sequence — absence is data, never an error. A mid-stream fault — an unknown envelope format, a payload that fails to decode, or an RPC/stream error — yields (session.Event{}, err) and then stops, honouring the port.EventLog contract (Read yields no further events after an error).

func (*EventLog) ReadAfter added in v0.0.22

ReadAfter streams the driver's records after the given cursor.

A cursor rejection arrives as a status carrying an ErrorInfo reason and is restored to the exact sentinel, so errors.Is(err, port.ErrCursorExpired) works identically against a remote driver and a local store.

type LearningRepositoryCapabilities added in v0.0.24

type LearningRepositoryCapabilities struct {
	AttemptRepository                 bool
	ProposalRepository                bool
	SkillRepository                   bool
	ValidatedSkillActivation          bool
	AutomaticAdmissionLedger          bool
	OwnershipMode                     LearningRepositoryOwnershipMode
	CallerInfrastructureRPCsSeparated bool
}

LearningRepositoryCapabilities is the closed set required to select one remote distributed-learning backend. It deliberately excludes attempt watch: ADR-0250 watches session events only; advisory notifications need a separate durable attempt-change-feed ADR.

func ProbeLearningRepositoryCapabilities added in v0.0.24

func ProbeLearningRepositoryCapabilities(ctx context.Context, conn grpc.ClientConnInterface) (LearningRepositoryCapabilities, error)

ProbeLearningRepositoryCapabilities negotiates the repository set before any remote learning repository is composed.

type LearningRepositoryOwnershipMode added in v0.0.24

type LearningRepositoryOwnershipMode uint8

LearningRepositoryOwnershipMode declares the driver's explicit ADR-0213 ownership posture. Zero is invalid for configured learning drivers.

const (
	// LearningRepositoryOwnershipTrusted marks a driver as deployment-trusted
	// infrastructure without caller ownership enforcement.
	LearningRepositoryOwnershipTrusted LearningRepositoryOwnershipMode = iota + 1
	// LearningRepositoryOwnershipEnforced is reserved for future negotiation.
	// Current composition treats it only as deployment-trusted because the raw
	// repository RPCs do not yet implement ADR-0213 authenticated ownership.
	LearningRepositoryOwnershipEnforced
)

type MemoryConvergenceStore

type MemoryConvergenceStore struct{ *MemoryLifecycleStore }

MemoryConvergenceStore is the negotiated presence-and-version CAS view.

func (*MemoryConvergenceStore) RememberIfCurrent

func (st *MemoryConvergenceStore) RememberIfCurrent(ctx context.Context, entry tool.MemoryEntry, expected tool.MemoryCurrent) (tool.MemoryRecord, error)

RememberIfCurrent invokes the separately negotiated atomic convergence RPC.

type MemoryLifecycleStore

type MemoryLifecycleStore struct{ *MemoryStore }

MemoryLifecycleStore is the negotiated lifecycle-capable view of MemoryStore. It is returned only after the remote driver successfully answers a lifecycle probe, so base-only drivers never accidentally advertise optional tools.

func (*MemoryLifecycleStore) ForgetVersioned

func (st *MemoryLifecycleStore) ForgetVersioned(ctx context.Context, key string, expected tool.MemoryVersion) (tool.MemoryRecord, error)

ForgetVersioned never downgrades to legacy Forget because doing so would lose compare-version protection and history.

func (*MemoryLifecycleStore) Inspect

Inspect returns lifecycle data from the positively negotiated driver. A missing or failing lifecycle RPC is not reinterpreted as a legacy Recall.

func (*MemoryLifecycleStore) RememberVersioned

func (st *MemoryLifecycleStore) RememberVersioned(ctx context.Context, entry tool.MemoryEntry, expected tool.MemoryVersion) (tool.MemoryRecord, error)

RememberVersioned uses the lifecycle RPC selected by negotiation. Once a driver advertises lifecycle support, any RPC failure is a protocol/operation error; the capable client never downgrades to legacy unconditional writes.

func (*MemoryLifecycleStore) UndoLatest

func (st *MemoryLifecycleStore) UndoLatest(ctx context.Context, key string, expected tool.MemoryVersion) (tool.MemoryRecord, error)

UndoLatest requires lifecycle support and never silently degrades.

type MemoryStore

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

MemoryStore is a tool.MemoryStore over a remote MemoryStoreService driver. It is PURE TRANSLATION: every behavioral guarantee (key validation, sorting, value omission on Index/Search, determinism) is the DRIVER's, and the memconformance suite run over this client is what pins it. Sanitization of model-written values stays harness-side in the memory tools.

func NewMemoryStore

func NewMemoryStore(conn grpc.ClientConnInterface) *MemoryStore

NewMemoryStore wraps an established driver connection (see Dial) as a tool.MemoryStore.

func (*MemoryStore) Forget

func (st *MemoryStore) Forget(ctx context.Context, key string) error

Forget deletes the entry for key on the driver; a missing key is not an error (idempotent).

func (*MemoryStore) Index

func (st *MemoryStore) Index(ctx context.Context) ([]tool.MemoryEntry, error)

Index returns the driver's tier-0 routing table: key-sorted entries with values omitted and descriptions filled.

func (*MemoryStore) List

func (st *MemoryStore) List(ctx context.Context, prefix string) ([]tool.MemoryEntry, error)

List returns all entries whose key has the given prefix (empty = all), key-sorted by the driver, values present.

func (*MemoryStore) Recall

func (st *MemoryStore) Recall(ctx context.Context, key string) (tool.MemoryEntry, bool, error)

Recall returns the entry for the exact key. A driver miss (found=false) is (zero, false, nil) — never an error.

func (*MemoryStore) RememberEntry

func (st *MemoryStore) RememberEntry(ctx context.Context, e tool.MemoryEntry) error

RememberEntry stores e on the driver, overwriting any existing entry under e.Key. The driver stamps UpdatedAt on write (the input value is advisory); a blank/whitespace-only key surfaces the driver's INVALID_ARGUMENT.

func (*MemoryStore) Search

func (st *MemoryStore) Search(ctx context.Context, query string, k int) ([]tool.MemoryEntry, error)

Search returns up to k entries relevant to query, best-first per the driver's (deterministic) ranking, values omitted. k <= 0 selects the driver's default page size; a blank query yields an empty result.

type Option

type Option func(*dialConfig)

Option customises Dial.

func WithBearerToken

func WithBearerToken(token string) Option

WithBearerToken attaches a per-RPC bearer credential ("authorization: Bearer <token>"). For a non-loopback target the credential demands transport security, so the token can never ride a cleartext wire to a remote host.

func WithTLS

func WithTLS(o TLSOptions) Option

WithTLS enables transport TLS per o (a zero o verifies against the system roots with no client certificate).

type ProposalRepository added in v0.0.24

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

ProposalRepository adapts the bounded staged-learning proposal lifecycle to a remote driver. Versions are relayed as opaque CAS tokens.

func NewProposalRepository added in v0.0.24

func NewProposalRepository(conn grpc.ClientConnInterface) *ProposalRepository

NewProposalRepository wraps an established driver connection.

func (*ProposalRepository) ClaimDecision added in v0.0.24

func (*ProposalRepository) ClaimPromotion added in v0.0.24

func (*ProposalRepository) Finalize added in v0.0.24

func (*ProposalRepository) Get added in v0.0.24

func (*ProposalRepository) LinkSkillDraft added in v0.0.24

func (*ProposalRepository) List added in v0.0.24

func (*ProposalRepository) StageBatch added in v0.0.24

func (r *ProposalRepository) StageBatch(ctx context.Context, partition learning.ProposalPartition, digest string, candidates []learning.Candidate, signals []learning.Signal) ([]learning.ProposalRecord, error)

type ScheduleStore

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

ScheduleStore is a port.ScheduleStore (and, unconditionally, a port.ScheduleOneShotReArmer) over a remote ScheduleStoreService / ScheduleOneShotReArmerService driver. Encode/decode happens HERE (encoding/json of port.Schedule / port.ScheduleFire), harness-side: the driver only ever sees the opaque, format-tagged envelope, exactly as the SessionStore driver keeps sessnap harness-side.

The client implements the OPTIONAL ScheduleOneShotReArmer UNCONDITIONALLY — the PrunableStore precedent: a driver that does not serve the re-arm service answers ReArmOneShot with UNIMPLEMENTED, which this client maps to port.ErrScheduleUnsupported (the sticky-disable sentinel, the ErrLeaseUnsupported precedent); composition then logs one INFO and stickily disables the one-shot re-arm path (byte-identical to the pre-Phase-2 at-most-once posture). This is the production degradation path, not an error: a driver serving only ScheduleStoreService still conforms.

func NewScheduleStore

func NewScheduleStore(conn grpc.ClientConnInterface) *ScheduleStore

NewScheduleStore wraps an established driver connection (see Dial) as a port.ScheduleStore. The connection serves BOTH ScheduleStoreService AND ScheduleOneShotReArmerService over the same conn; a driver that omits the re-arm service is tolerated (ReArmOneShot maps its UNIMPLEMENTED to port.ErrScheduleUnsupported).

func (*ScheduleStore) Claim

func (st *ScheduleStore) Claim(ctx context.Context, name string, now, nextFire time.Time) (port.Schedule, error)

Claim is the at-most-once atomic advance over the wire. The driver applies it atomically (the durable NextFireAt advance IS the at-most-once fence — the harness client cannot fence over the wire); a zero nextFire is the "no further fire" sentinel. A driver NOT_FOUND maps to port.ErrScheduleNotFound.

func (*ScheduleStore) ClaimNow

func (st *ScheduleStore) ClaimNow(ctx context.Context, name string, now, nextFire time.Time) (port.Schedule, error)

ClaimNow is the manual-trigger variant of Claim over the wire (no due-check). The driver fences on LastFireAt: a ClaimNow at the SAME now as a prior ClaimNow is rejected (the driver maps that to an error the harness surfaces). A driver NOT_FOUND maps to port.ErrScheduleNotFound.

func (*ScheduleStore) Delete

func (st *ScheduleStore) Delete(ctx context.Context, name string) error

Delete removes the schedule stored under name on the driver. It is idempotent harness-side: a driver NOT_FOUND (a thin driver surfacing its primitive's miss) maps to success, per the port.ScheduleStore contract.

func (*ScheduleStore) Due

func (st *ScheduleStore) Due(ctx context.Context, now time.Time) ([]port.Schedule, error)

Due returns the schedules whose NextFireAt is <= now AND Enabled AND (when MaxFires > 0) FireCount < MaxFires. The driver computes the due set; the records are decoded harness-side.

func (*ScheduleStore) List

func (st *ScheduleStore) List(ctx context.Context) ([]port.Schedule, error)

List returns the driver's full stored-schedule inventory. The records are decoded harness-side; an unknown envelope format or undecodable payload on any record is an infrastructure error.

func (*ScheduleStore) ListFires

func (st *ScheduleStore) ListFires(ctx context.Context, scheduleName string) ([]port.ScheduleFire, error)

ListFires returns the fire records for a schedule. An unknown SCHEDULE maps to port.ErrScheduleNotFound; an empty fire list for an existing schedule is a successful empty slice.

func (*ScheduleStore) Load

func (st *ScheduleStore) Load(ctx context.Context, name string) (port.Schedule, error)

Load fetches the schedule stored under name from the driver and decodes it. A driver NOT_FOUND maps to port.ErrScheduleNotFound (wrapped); an unknown envelope format, a payload that fails to decode, or a decoded schedule whose Spec.Name is NOT the requested one (a mis-keyed driver) is an infrastructure error, never not-found.

func (*ScheduleStore) LoadFire

func (st *ScheduleStore) LoadFire(ctx context.Context, fireID string) (port.ScheduleFire, error)

LoadFire fetches the fire record stored under fireID from the driver and decodes it. A driver NOT_FOUND maps to port.ErrScheduleNotFound (wrapped); an unknown envelope format, a payload that fails to decode, or a decoded fire whose ID is NOT the requested one (a mis-keyed driver) is an infrastructure error, never not-found.

func (*ScheduleStore) ReArmOneShot

func (st *ScheduleStore) ReArmOneShot(ctx context.Context, name string, nextFire time.Time) error

ReArmOneShot re-enables the named one-shot schedule, sets its NextFireAt to nextFire, and increments OneShotRetryCount over the wire. The driver applies it atomically (the at-most-once fence for the re-arm). A driver NOT_FOUND maps to port.ErrScheduleNotFound. A driver that does not serve the re-arm service answers UNIMPLEMENTED → port.ErrScheduleUnsupported (the sticky- disable sentinel; the production degradation path — see the type doc).

func (*ScheduleStore) RecordFire

func (st *ScheduleStore) RecordFire(ctx context.Context, f port.ScheduleFire) error

RecordFire records the terminal outcome of a fire and clears the in-flight state. It is IDEMPOTENT per fire id over the wire (the driver MUST NOT duplicate a repeat record); a driver NOT_FOUND (the schedule was deleted between Claim and RecordFire) maps to port.ErrScheduleNotFound.

func (*ScheduleStore) RecordFireProgress

func (st *ScheduleStore) RecordFireProgress(ctx context.Context, name string, fireID string, at time.Time) error

RecordFireProgress advances the in-flight fire's last-observed-progress instant. It is BEST-EFFORT and IDEMPOTENT over the wire. A driver NOT_FOUND (the schedule was deleted) maps to port.ErrScheduleNotFound.

func (*ScheduleStore) RecordFireStart

func (st *ScheduleStore) RecordFireStart(ctx context.Context, name string, fire port.ScheduleFire) error

RecordFireStart persists the IN-FLIGHT fire over the wire. It is IDEMPOTENT per fire id. A driver NOT_FOUND (the schedule was deleted between Claim and RecordFireStart) maps to port.ErrScheduleNotFound.

func (*ScheduleStore) Save

func (st *ScheduleStore) Save(ctx context.Context, s port.Schedule) error

Save encodes s via encoding/json and persists it under s.Spec.Name on the driver, overwriting any prior record. The schedule is upserted by name.

func (*ScheduleStore) SetEnabled

func (st *ScheduleStore) SetEnabled(ctx context.Context, name string, enabled bool) error

SetEnabled atomically sets the schedule's Enabled flag. A driver NOT_FOUND maps to port.ErrScheduleNotFound.

type SessionLease

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

SessionLease is a port.SessionLease over a remote SessionLeaseService driver. Unlike the SessionStore/EventLog clients, the lease carries no opaque payload: its fields ARE the protocol, so this wrapper just marshals the Lease value to/from proto (expiry via timestamppb) and maps the status codes onto the port sentinels — FAILED_PRECONDITION → ErrLeaseHeld, UNIMPLEMENTED → ErrLeaseUnsupported (the sticky-disable signal).

func NewSessionLease

func NewSessionLease(conn grpc.ClientConnInterface) *SessionLease

NewSessionLease wraps an established driver connection (see Dial) as a port.SessionLease.

func (*SessionLease) Acquire

func (l *SessionLease) Acquire(ctx context.Context, id session.SessionID, owner string) (port.Lease, error)

Acquire requests the lease for id from the driver. FAILED_PRECONDITION → ErrLeaseHeld, UNIMPLEMENTED → ErrLeaseUnsupported; any other non-OK status is an opaque infrastructure failure.

func (*SessionLease) Release

func (l *SessionLease) Release(ctx context.Context, in port.Lease) error

Release relinquishes the held lease; idempotent on the driver side.

func (*SessionLease) Renew

func (l *SessionLease) Renew(ctx context.Context, in port.Lease) (port.Lease, error)

Renew extends the held lease, returning the refreshed value (new expiry, same token). A FAILED_PRECONDITION means the caller lost the lease → ErrLeaseHeld (the loss signal the renewer acts on).

type SessionStore

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

SessionStore is a port.SessionStore over a remote SessionStoreService driver. Encode/decode happens HERE (sessnap), harness-side: the driver only ever sees the opaque envelope.

func NewSessionStore

func NewSessionStore(ctx context.Context, conn grpc.ClientConnInterface) (*SessionStore, error)

NewSessionStore wraps an established driver connection (see Dial), probing optional operations once. UNIMPLEMENTED means an older Save/Load-only driver; any other probe failure fails construction rather than guessing capabilities.

func (*SessionStore) Create added in v0.0.22

func (st *SessionStore) Create(ctx context.Context, s *session.Session) error

Create atomically publishes s when the negotiated driver supports SessionCreator.

func (*SessionStore) Delete

func (st *SessionStore) Delete(ctx context.Context, id session.SessionID) error

Delete removes the snapshot stored under id on the driver. It is idempotent harness-side: a driver NOT_FOUND (a thin driver surfacing its primitive's miss) maps to success, per the port.PrunableStore contract.

func (*SessionStore) List

func (st *SessionStore) List(ctx context.Context) ([]port.StoredSession, error)

List returns the driver's full stored-session inventory (ids + last-modified times). An unset modified_at maps to the zero time — the retention sweep's age pass then treats the entry as arbitrarily old, which fails SAFE only because the sweep also never touches unprefixed ids; a driver SHOULD return real times.

func (*SessionStore) Load

Load fetches the most recent snapshot for id from the driver and restores it through sessnap. A driver NOT_FOUND maps to ErrNotFound (wrapping port.ErrSessionNotFound); an unknown envelope format, a payload that fails to decode, or a decoded session whose id is NOT the requested one (a mis-keyed driver) is an infrastructure error, never not-found.

func (*SessionStore) PageSessionMetadata

func (st *SessionStore) PageSessionMetadata(ctx context.Context, request port.SessionMetadataPageRequest) (port.SessionMetadataPage, error)

PageSessionMetadata asks the remote driver for one bounded owner-filtered metadata page. UNIMPLEMENTED is the optional pager's permanent unsupported posture, not a transient transport failure.

func (*SessionStore) ReadSessionLineage added in v0.0.22

func (st *SessionStore) ReadSessionLineage(ctx context.Context, query port.SessionLineageQuery) (port.SessionLineageResult, error)

ReadSessionLineage asks the trusted driver for bounded content-free direct edges.

func (*SessionStore) Save

func (st *SessionStore) Save(ctx context.Context, s *session.Session) error

Save encodes s via sessnap and persists it under s.ID on the driver, overwriting any prior snapshot. A nil session fails client-side with sessnap.ErrNilSession (no RPC), matching the local stores.

func (*SessionStore) SupportsSessionDelete

func (st *SessionStore) SupportsSessionDelete() bool

SupportsSessionDelete reports the negotiated backend capability. SessionStore keeps implementing PrunableStore unconditionally for compatibility.

type SkillRepository added in v0.0.24

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

SkillRepository adapts the learned-skill lifecycle to a remote driver.

func NewSkillRepository added in v0.0.24

func NewSkillRepository(conn grpc.ClientConnInterface) *SkillRepository

func (*SkillRepository) Activate added in v0.0.24

func (*SkillRepository) Archive added in v0.0.24

func (*SkillRepository) CreateDraft added in v0.0.24

func (*SkillRepository) Generation added in v0.0.24

func (*SkillRepository) Get added in v0.0.24

func (*SkillRepository) List added in v0.0.24

func (*SkillRepository) RecordEvaluation added in v0.0.24

func (r *SkillRepository) RecordEvaluation(ctx context.Context, partition learning.SkillPartition, owner string, id learning.SkillID, version learning.VersionID, revision learning.Revision, evaluation learning.SkillEvaluation) (learning.SkillVersion, error)

func (*SkillRepository) Reject added in v0.0.24

func (*SkillRepository) Rollback added in v0.0.24

func (*SkillRepository) Stage added in v0.0.24

type SkillSource

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

SkillSource is a tool.SkillSource over a remote SkillSourceService driver. It is translation plus a DEFENSIVE normalization layer on ListSkills (the driver sits at the operator-infrastructure trust tier, but its metadata feeds the always-in-context tool description, so the client re-enforces the invariants the port promises rather than trusting the wire): invalid skill names are dropped, duplicate names de-dup first-wins, the result is name-sorted, descriptions are forced single-line (control characters → spaces) then re-truncated to the always-in-context cap (skills.MaxDescriptionBytes), and Origin is stamped SkillOriginDriver UNCONDITIONALLY — a driver-served skill IS driver tier; a driver must not claim the "project"/"user" admission labels (the wire origin field stays driver-side observability only). Bodies/assets pass through; the SkillSource is retained by composition and enforces bounded logical payload reads through the Skill tool.

func NewSkillSource

func NewSkillSource(conn grpc.ClientConnInterface) *SkillSource

NewSkillSource wraps an established driver connection (see Dial) as a tool.SkillSource.

func (*SkillSource) ListSkillAssets

func (s *SkillSource) ListSkillAssets(ctx context.Context, name string) ([]tool.SkillAsset, error)

ListSkillAssets returns the named skill's payload descriptors. A driver NOT_FOUND wraps tool.ErrSkillNotFound.

func (*SkillSource) ListSkills

func (s *SkillSource) ListSkills(ctx context.Context) ([]tool.SkillMeta, error)

ListSkills returns the driver's skill metadata snapshot, defensively normalized (see the type doc).

func (*SkillSource) ReadSkillAsset

func (s *SkillSource) ReadSkillAsset(ctx context.Context, skill, asset string) ([]byte, error)

ReadSkillAsset returns one payload's bytes. A driver NOT_FOUND (unknown skill OR asset) wraps tool.ErrSkillAssetNotFound; an INVALID_ARGUMENT (the server pre-validates logical names via tool.ValidSkillAssetName) surfaces as a non-nil infrastructure error — never content.

func (*SkillSource) SkillBody

func (s *SkillSource) SkillBody(ctx context.Context, name string) (string, error)

SkillBody returns the named skill's full instruction body. A driver NOT_FOUND wraps tool.ErrSkillNotFound with the name in the message.

type SoulOptions

type SoulOptions struct {
	// MaxBytes caps the accepted body; 0 uses soul.DefaultMaxBytes. Over the
	// cap the body is REJECTED (no fragment), not truncated — the same rule as
	// the local file store.
	MaxBytes int
	// Diagnostics is the operational-logging sink for the fail-soft branches
	// (driver fault at runtime → WARN; body rejected by re-validation → Debug).
	// nil defaults to port.NopDiagnostics.
	Diagnostics port.Diagnostics
}

SoulOptions configures a remote SoulSource client.

type SoulSource

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

SoulSource is a prompt.SoulSource over a remote SoulSourceService driver. The driver's body is RE-VALIDATED client-side with the full local soul discipline (soul.ValidateBody: byte cap, injection scan, fence integrity, trim) — a driver is never trusted to sanitize. Load upholds the prompt.SoulSource fail-soft contract: a driver fault at RUNTIME degrades to ("", nil) with a logged WARN, never an error that aborts a run; the BUILD-time reachability check is the separate Probe (loud-misconfig posture, fatal in the composition layer).

func NewSoulSource

func NewSoulSource(conn grpc.ClientConnInterface, opts SoulOptions) *SoulSource

NewSoulSource wraps an established driver connection (see Dial) as a prompt.SoulSource.

func (*SoulSource) Load

func (s *SoulSource) Load(ctx context.Context) (string, error)

Load returns the re-validated soul body, or ("", nil) when there is no usable soul — fail-soft at every branch (driver fault, empty body, validation rejection), exactly like the local store's Load.

func (*SoulSource) Probe

func (s *SoulSource) Probe(ctx context.Context) error

Probe performs the BUILD-time reachability check: one LoadSoul round trip, returning the wrapped RPC error on a fault (the composition layer treats it as FATAL — an explicitly configured driver that cannot answer is a misconfiguration, unlike a runtime blip which Load degrades on). The body itself is NOT judged here: an empty or invalid persona is a legal "no soul", not a misconfig.

type TLSOptions

type TLSOptions struct {
	// CAFile is an optional PEM CA bundle used to verify the driver's server
	// certificate (empty uses the system roots).
	CAFile string
	// ClientCertFile/ClientKeyFile are an optional PEM client certificate and
	// key for mutual TLS; set both or neither.
	ClientCertFile string
	ClientKeyFile  string
}

TLSOptions configures transport TLS for a driver connection: an optional custom CA bundle for server verification and an optional client certificate/key pair for mutual TLS.

type ValidatedSkillRepository added in v0.0.24

type ValidatedSkillRepository struct{ *SkillRepository }

ValidatedSkillRepository adds the optional validated-activation capability.

func NewValidatedSkillRepository added in v0.0.24

func NewValidatedSkillRepository(conn grpc.ClientConnInterface) *ValidatedSkillRepository

func (*ValidatedSkillRepository) ActivateValidated added in v0.0.24

Jump to

Keyboard shortcuts

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