Documentation
¶
Overview ¶
Package strategy holds the memory-strategy executors: the algorithmic core that any `memory.MemoryStore` driver delegates to. The strategy is a behaviour mode of the driver, not a separate driver per AGENTS.md §4.4 — every memory driver hosts the same executor surface.
Phase 24 ships three executors:
- `none` (`noneExec`) — Strategy=none preserves the Phase 23 semantics: AddTurn is a no-op, GetLLMContext returns empty, all snapshot bytes round-trip through `state.StateStore`.
- `truncation` (`truncationExec`) — synchronous recent-window buffer with `OverflowDropOldest` enforcement at the configured `BudgetTokens` boundary.
- `rolling_summary` (`rollingSummaryExec`) — recent-window buffer + background-summarised long-term context. Health FSM `healthy → retry → degraded → recovering → healthy` with a bounded recovery backlog (`RecoveryBacklogMax`); failure paths emit `memory.health_changed` and `memory.recovery_dropped` events so degradation is observable, not silent (D-035).
Persistence: every successful mutation lands as a `state.StateStore` record at `Kind = "memory.state"` (D-027 typed wrapper). Phase 25's SQLite + Postgres drivers will inherit the shape unchanged.
Identity-mandatory contract (D-001): every method validates the identity quadruple at the boundary. Drivers OWN the boundary validation + the `memory.identity_rejected` emit; executors trust the driver's pre-validation. The driver passes through validated identities and the executor focuses on the algorithmic core.
Concurrent-reuse contract (D-025): one executor is safe to share across N concurrent goroutines. Per-key state lives in mutex- guarded maps inside the executor; no per-call mutable state on the executor struct itself.
Index ¶
Constants ¶
const DefaultRecoveryBacklogMax = 16
DefaultRecoveryBacklogMax is the default recovery-backlog cap for the rolling-summary strategy when `Deps.RecoveryBacklogMax` is zero. Sized to absorb a short summariser outage (≈4 minutes at `defaultDegradedRetryEvery = 10s` × 16 retries) without unbounded memory growth.
const FullZoneTurns = 4
FullZoneTurns is the recent-window size before turns spill into the rolling-summary `pending` queue. Constant per D-035 (the brief 04 §2 knob is encoded as a constant; an operator who needs to tune it files an RFC PR rather than fighting yaml).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Deps ¶
type Deps struct {
State state.StateStore
Bus events.EventBus
Summarizer memory.Summarizer
BudgetTokens int
RecoveryBacklogMax int
}
Deps carries the runtime dependencies an executor consumes.
`State` is the persistence floor — every executor writes typed records through it (D-027). Mandatory for every strategy including `none` (the wiring is exercised by Phase 23's conformance suite).
`Bus` is the event bus the executor publishes lifecycle events on — `memory.identity_rejected` (driver-side; passed through here so executors can re-emit if needed), `memory.health_changed` (rolling-summary FSM transitions), `memory.recovery_dropped` (bounded-backlog overflow). Mandatory.
`Summarizer` is the injectable LLM-edge callable the rolling-summary strategy consumes. Mandatory for `StrategyRollingSummary`; ignored by other strategies. The LLM-backed implementation lands at Phase 32+; Phase 24 ships a test-grade stub (`EchoSummarizer`).
`BudgetTokens` is the truncation / rolling-summary budget cap (per-key, applied as token estimates). Zero is honoured as "no budget" — appending is unbounded. Positive values enforce the `OverflowDropOldest` policy.
`RecoveryBacklogMax` is the bounded queue size for the rolling-summary recovery loop. Zero defaults to `DefaultRecoveryBacklogMax` (16).
type EchoSummarizer ¶
type EchoSummarizer struct{}
EchoSummarizer is the test-grade `memory.Summarizer` stub Phase 24 ships. It concatenates the previous summary + the joined user/assistant turns into a deterministic string so tests can pin expected outputs without an LLM backend.
The real LLM-backed `Summarizer` lands at Phase 32+ in the `internal/llm` subsystem; tests in Phase 24 reach for `EchoSummarizer` because (a) it is fully deterministic, and (b) it never hits the network so the test suite stays hermetic.
Concurrent-reuse contract (D-025): no mutable state on the struct; safe to share across N goroutines.
func (EchoSummarizer) Summarize ¶
func (EchoSummarizer) Summarize(_ context.Context, _ identity.Quadruple, req memory.SummarizeRequest) (memory.SummarizeResponse, error)
Summarize implements `memory.Summarizer`.
type StrategyExecutor ¶
type StrategyExecutor interface {
AddTurn(ctx context.Context, id identity.Quadruple, turn memory.ConversationTurn) error
GetLLMContext(ctx context.Context, id identity.Quadruple) (memory.LLMContextPatch, error)
EstimateTokens(ctx context.Context, id identity.Quadruple) (int, error)
Flush(ctx context.Context, id identity.Quadruple) error
Health(ctx context.Context, id identity.Quadruple) (memory.Health, error)
Snapshot(ctx context.Context, id identity.Quadruple) (memory.Snapshot, error)
Restore(ctx context.Context, id identity.Quadruple, snap memory.Snapshot) error
Close(ctx context.Context) error
}
func New ¶
func New(s memory.Strategy, deps Deps) (StrategyExecutor, error)
New constructs the strategy executor for the given strategy. Unknown strategies return wrapped `memory.ErrStrategyNotImplemented`.
Phase 24 routes:
StrategyNone → noneExec (no-op surface; preserves Phase 23 semantics) StrategyTruncation → truncationExec StrategyRollingSummary → rollingSummaryExec
A nil `Deps.State` or `Deps.Bus` returns a wrapped construction error. A nil `Deps.Summarizer` is rejected for `StrategyRollingSummary` and ignored for the others.