Documentation
¶
Overview ¶
Package memory loads optional context files that are auto-injected into the system prompt at session start.
Layout:
~/.yottacode/USER.md — global preferences (curated, human-only)
<cwd>/.yottacode/YOTTACODE.md — per-repo context (curated, agent-writable)
~/.yottacode/memory/user/<name>.md — user-scope agent-managed memories
~/.yottacode/memory/projects/<project_slug>/<name>.md — project-scope agent-managed memories
~/.yottacode/memory/projects/<project_slug>/subagents/ — that project's subagent run transcripts
(owned by internal/subagents; subdirs are
invisible to scanMemoryDir)
USER.md and YOTTACODE.md are the trust anchor: they always inject in full. The agent-managed memory dirs are managed via the memory_save / memory_forget tools — the agent decides in-band when something is worth remembering. MEMORY.md inside each memory dir is an auto-generated index that always renders too; the per-file bodies are filtered per turn by the retrieval orchestrator (see retrieve.go).
The project_slug is derived by ProjectSlug(cwd) — see path.go.
Package memory — retrieval orchestrator.
Agent-managed memory grows over time. By v0.4 a heavy user can accumulate dozens of typed memory files; concatenating every body into the system prompt on every turn taxes both the context window and the model's attention.
This file scores each MemoryEntry against the current user prompt and returns a ranked, length-bounded subset. It deliberately does NOT touch USER.md / YOTTACODE.md — those are the trust anchor: short, curated, and always injected in full. USER.md is human-only; YOTTACODE.md is human-seeded and the agent keeps it fresh as the project evolves (parity with how Claude Code maintains CLAUDE.md).
MEMORY.md (the per-scope index) is also unfiltered — it's the table of contents, and the model needs to know what files exist even when their bodies aren't injected. Only per-entry bodies pass through Select.
Index ¶
- Constants
- func ArchivePrior(memPath, stamp string) (string, error)
- func AtomicWrite(path string, data []byte, perm os.FileMode) error
- func CosineSimilarity(a, b []float32) float64
- func DeleteVec(mdPath string)
- func EnsureProjectMemoryDir(cwd string) (string, error)
- func EnsureUserMemoryDir() (string, error)
- func Expand(stemmed string) []string
- func ExplicitSearchMatch(_ MemoryEntry, _ string, score float64) bool
- func FormatArchiveTime(t time.Time) string
- func FormatAuditAge(ageDays int) string
- func FormatAuditCreated(created time.Time) string
- func MemoryDirForScope(scope, cwd string) (string, error)
- func MemoryFilePath(scope, name, cwd string) (string, error)
- func MemoryRoot() (string, error)
- func NeedsReembed(path, currentModel string) bool
- func ProjectMemoryDir(cwd string) (string, error)
- func ProjectSlug(cwd string) string
- func ReadVec(path string) ([]float32, error)
- func RecordCurationHistory(scope, name, cwd string, rec CurationHistoryRecord) error
- func RegenerateMemoryIndex(scope, cwd string) error
- func RenderFrontmatter(name, memType, description string, created time.Time) string
- func RenderFrontmatterWithSource(name, memType, description string, created time.Time, source Source) string
- func RenderMemoryIndex(scope string, entries []MemoryEntry) string
- func Score(entry MemoryEntry, query string) float64
- func Stem(word string) string
- func StemExpandTokenize(s string) []string
- func SystemPrompt(base string, l Loaded) string
- func SystemPromptFor(base string, l Loaded, query string, cfg config.RetrievalConfig) string
- func SystemPromptForSemantic(ctx context.Context, base string, l Loaded, query string, ...) string
- func UserMemoryDir() (string, error)
- func VecPath(mdPath string) string
- func WriteVec(path string, vec []float32) error
- func WriteVecWithModel(path string, vec []float32, model string) error
- type ArchiveEntry
- type ArchivePruneOptions
- type ArchivePruneResult
- type ArchiveSummary
- type AuditHealth
- type AuditIssue
- type AuditReport
- type Corpus
- type CurationBatch
- type CurationHistoryRecord
- type CurationPlan
- type CurationProposal
- type EmbedClient
- type Frontmatter
- type Loaded
- type MemoryEntry
- func EffectiveEntries(user, project []MemoryEntry) []MemoryEntry
- func Select(entries []MemoryEntry, query string, cfg config.RetrievalConfig) []MemoryEntry
- func SelectWithEmbeddings(ctx context.Context, entries []MemoryEntry, query string, ...) []MemoryEntry
- func ShadowUserByProject(user, project []MemoryEntry) []MemoryEntry
- type ProposalSource
- type ProposedMemory
- type Scored
- type Source
- type Summary
- type VecMeta
Constants ¶
const ArchiveDirName = ".archive"
ArchiveDirName is the subdirectory inside a memory directory where prior versions of overwritten memories are kept. It is a directory, so scanMemoryDir skips it — archived versions never appear in the index, retrieval, or `memory list`; they exist only for recovery.
const ExplicitSearchMinScore = 0.05
ExplicitSearchMinScore is the default relevance floor for the agent-facing memory_search tool. Prompt injection keeps using retrieval.min_score; explicit tool searches need a small floor so tiny stem/synonym tail scores do not show unrelated memories as matches.
const HistoryDirName = ".history"
HistoryDirName stores append-only curation history beside live memories.
const InteractiveEmbedTimeout = 2 * time.Second
InteractiveEmbedTimeout bounds a single embedding call made on the synchronous, user-facing path: per-turn retrieval (rebuilding the system prompt before a turn fires) and memory_save. The default client Timeout (30s) is correct for batch `memory reindex`, but on the interactive path a mid-session Ollama hang (model unloaded, swapped, or busy) would otherwise freeze the TUI for up to 30s every turn. Interactive callers set Timeout to this short bound; on timeout the retriever falls back to BM25 and memory_save just skips the .vec.
const SubagentsDirName = "subagents"
SubagentsDirName is the directory inside each project memory dir that holds that project's subagent run transcripts. Exported (like ArchiveDirName) because internal/subagents joins it in TranscriptDirFor and the save-proactivity eval skips it when counting memories — one const keeps every site in agreement.
Variables ¶
This section is empty.
Functions ¶
func ArchivePrior ¶ added in v0.3.0
ArchivePrior copies the current contents of memPath (if the file exists) into <dir>/.archive/<name>.<stamp>.md so an overwrite can never silently destroy a different memory that happened to share the name. stamp must be unique per call (the caller passes a timestamp). Returns the archive path written, or "" when there was nothing to archive (the file did not exist). Durable like every other memory write (staged + fsync'd via AtomicWrite).
func AtomicWrite ¶ added in v0.3.0
AtomicWrite writes data to path durably and atomically.
It stages to a UNIQUE temp file in the same directory (via os.CreateTemp), fsyncs the data, renames onto the destination, then fsyncs the directory so the rename survives a crash. The temp file is removed on every error path; a successful rename consumes it, making the deferred Remove a no-op.
This replaces the older "<path>.tmp" + os.WriteFile + os.Rename pattern, which had two latent defects the memory layer relied on:
- A DETERMINISTIC temp name ("<path>.tmp"): two writers targeting the same destination (two yottacode processes in one repo, or a parent loop and a detached background subagent sharing the same tool) staged through the same file, so their bytes interleaved into one descriptor or one rename fired mid-write — corrupting the destination. A unique temp name makes concurrent writes last-writer-wins on a valid file instead.
- No fsync before rename: on a crash/power-loss just after the call returned "saved", the file could come back zero-length or stale.
Using os.CreateTemp also closes a staging-file symlink-follow gap: it refuses to open through a pre-planted symlink at the temp path.
func CosineSimilarity ¶ added in v0.3.0
CosineSimilarity returns the cosine similarity between two vectors. Returns 0 if either vector is zero-length or the vectors have different dimensions.
func DeleteVec ¶ added in v0.3.0
func DeleteVec(mdPath string)
DeleteVec removes a sidecar vector file if it exists.
func EnsureProjectMemoryDir ¶
EnsureProjectMemoryDir creates the project-scope memory directory.
func EnsureUserMemoryDir ¶
EnsureUserMemoryDir creates the user-scope memory directory if missing.
func Expand ¶ added in v0.3.0
Expand returns the stemmed input token plus any known synonyms. The first element is always the input itself. Tokens not in any synonym group return a single-element slice. All entries are pre-stemmed so callers must stem before calling.
func ExplicitSearchMatch ¶ added in v0.4.0
func ExplicitSearchMatch(_ MemoryEntry, _ string, score float64) bool
ExplicitSearchMatch reports whether a scored memory should be shown by the agent-facing memory_search tool. The agent can inspect ranked candidates and refine its query, so keep this conservative: drop only obvious low-score noise instead of applying brittle UI-style query heuristics.
func FormatArchiveTime ¶ added in v0.4.0
FormatArchiveTime renders archive timestamps for CLI/tool output.
func FormatAuditAge ¶ added in v0.4.0
func FormatAuditCreated ¶ added in v0.4.0
func MemoryDirForScope ¶ added in v0.4.0
MemoryDirForScope resolves the directory for the given memory scope. Project scope always derives from cwd via ProjectMemoryDir.
func MemoryFilePath ¶
MemoryFilePath validates a memory name and returns the absolute file path under the chosen scope. Scope must be "user" or "project".
func MemoryRoot ¶ added in v0.3.0
MemoryRoot returns the root of the agent-managed memory tree: $YOTTACODE_HOME/memory when the override is set — the shared ychome.Dir resolution skills, plans, and agent definitions also use, so all global state follows the same root — or ~/.yottacode/memory otherwise.
func NeedsReembed ¶ added in v0.3.0
NeedsReembed reports whether a .vec file should be re-embedded, either because it uses the legacy format (no model recorded) or because it was embedded with a different model.
func ProjectMemoryDir ¶
ProjectMemoryDir returns ~/.yottacode/memory/projects/<slug>/ — the per-project, per-user agent-managed memory directory. The project's subagent transcripts nest under <dir>/subagents (see internal/subagents.TranscriptDirFor); scanMemoryDir ignores subdirectories, so the two cohabit without the loader seeing transcript files.
func ProjectSlug ¶
ProjectSlug returns a stable, slug-safe identifier for the project rooted at cwd. Strategy (highest-priority first):
- Git remote URL of `origin`. Survives renames of cwd, and is the same string across machines and clones — project memory follows the project, not the directory it happens to live in. Parsed from formats like `https://github.com/user/repo.git`, `git@github.com:user/repo.git`, `ssh://git@host/path/repo`.
- `filepath.Base(cwd)` slugified. Used when no git remote is configured (uncommitted scratch dir, vendored copy without git, brand-new project pre-init).
Returns "default" when both lookups fail (empty cwd, root-only path, exotic edge cases). The returned string is guaranteed to match projectSlugPattern, so callers can use it directly as a path component without further sanitization.
Two unrelated repos with the same basename and no git remote will collide. The collision is documented; users who care can either initialize a git repo (which gets them a unique remote-derived slug) or live with the merge.
func ReadVec ¶ added in v0.3.0
ReadVec reads a float32 vector from a .vec file. Handles both the new header format and legacy raw float32 files. Returns nil, nil if the file does not exist.
func RecordCurationHistory ¶ added in v0.4.0
func RecordCurationHistory(scope, name, cwd string, rec CurationHistoryRecord) error
RecordCurationHistory appends one curation event under the requested scope.
func RegenerateMemoryIndex ¶
RegenerateMemoryIndex re-scans the chosen scope's memory dir and rewrites MEMORY.md atomically. Used by memory_save and memory_forget after every mutation. If the dir is empty or missing after the mutation, MEMORY.md is removed instead of being written as an empty stub.
func RenderFrontmatter ¶
RenderFrontmatter writes the base header. Description is expected to already be one line (caller strips newlines before passing); the writer doesn't re-validate. Created is rendered as RFC3339 in UTC.
func RenderFrontmatterWithSource ¶ added in v0.4.0
func RenderFrontmatterWithSource(name, memType, description string, created time.Time, source Source) string
RenderFrontmatterWithSource writes the memory header and includes source provenance fields when they are available.
func RenderMemoryIndex ¶
func RenderMemoryIndex(scope string, entries []MemoryEntry) string
RenderMemoryIndex builds the MEMORY.md text for one scope: a header, a stable preamble warning humans not to edit it, and a per-type section listing each entry as a markdown link with its description. Empty entries produce a minimal index (just the preamble) so the scanner still recognizes the file as ours.
func Score ¶
func Score(entry MemoryEntry, query string) float64
Score returns a relevance score in [0.0, 1.0] for the given entry against the query using the legacy keyword strategy. Pure and deterministic. Kept for backward compatibility with strategy="keyword".
func Stem ¶ added in v0.3.0
Stem returns the Porter-stemmed form of a single lowercase English token. Implements the Porter 1980 suffix-stripping algorithm (5 steps). Pure, deterministic, zero allocations beyond the result.
func StemExpandTokenize ¶ added in v0.3.0
StemExpandTokenize tokenizes, stems, and expands synonyms for the query side. Synonym expansion runs on queries only (not documents) to increase recall without inflating document frequencies.
func SystemPrompt ¶
SystemPrompt composes the base prompt with every loaded memory section. Each section is framed as background reference — not as a topic to describe.
func SystemPromptFor ¶
SystemPromptFor is the per-turn variant of SystemPrompt: USER.md and YOTTACODE.md inject in full as before, both MEMORY.md indexes inject in full (they're the table of contents), and per-entry bodies pass through Select(query, cfg) first.
func SystemPromptForSemantic ¶ added in v0.3.0
func SystemPromptForSemantic(ctx context.Context, base string, l Loaded, query string, cfg config.RetrievalConfig, embedClient *EmbedClient) string
SystemPromptForSemantic is like SystemPromptFor but accepts an optional EmbedClient for semantic retrieval. Pass nil to use keyword/bm25 scoring only. ctx bounds the embed call — callers on an interactive path should pass a cancelable context (the TUI uses the turn context) so retrieval never outlives the work it serves.
func UserMemoryDir ¶
UserMemoryDir returns ~/.yottacode/memory/user/ — the cross-project agent-managed memory directory. Memories saved here apply to every session for this user.
func WriteVec ¶ added in v0.3.0
WriteVec writes a float32 vector to disk with a header that records the embedding model name and dimension count.
func WriteVecWithModel ¶ added in v0.3.0
WriteVecWithModel writes a vector with an explicit model name header.
Staging uses a UNIQUE temp file (os.CreateTemp) and fsyncs before rename, for the same reasons as memory.AtomicWrite: a fixed "<path>.tmp" name let a concurrent writer's deferred cleanup delete this writer's in-flight temp (silently dropping the .vec), and the missing fsync left a crash window. The streaming header+binary layout can't go through AtomicWrite's single-buffer API, so the same guarantees are applied inline here.
Types ¶
type ArchiveEntry ¶ added in v0.4.0
ArchiveEntry describes one archived prior memory version.
type ArchivePruneOptions ¶ added in v0.4.0
ArchivePruneOptions controls explicit archive pruning. Zero values mean no age cutoff and no per-memory keep floor.
type ArchivePruneResult ¶ added in v0.4.0
type ArchivePruneResult struct {
Matched int
Deleted int
Bytes int64
Entries []ArchiveEntry
}
ArchivePruneResult reports what an archive prune selected and optionally deleted.
func PruneArchives ¶ added in v0.4.0
func PruneArchives(cwd string, opts ArchivePruneOptions) (ArchivePruneResult, error)
PruneArchives deletes selected archive files only when DryRun is false.
type ArchiveSummary ¶ added in v0.4.0
type ArchiveSummary struct {
Scope string
Memory string
Count int
Oldest time.Time
Newest time.Time
Bytes int64
Archives []ArchiveEntry
}
ArchiveSummary groups archive inventory by memory name.
func ListArchiveSummaries ¶ added in v0.4.0
func ListArchiveSummaries(scope, cwd string) ([]ArchiveSummary, error)
ListArchiveSummaries inventories .archive files for the requested scope.
type AuditHealth ¶ added in v0.4.0
type AuditHealth struct {
TotalMemories int
TotalIssues int
QuickNotes int
OldQuickNotes int
DuplicateDescriptions int
VagueBodies int
EmptyBodies int
PortableScopeMistakes int
}
AuditHealth is a compact read-only summary of memory-store quality. It is intentionally aggregate-only so status surfaces can show memory health without dumping every curation issue into context.
func SummarizeAuditHealth ¶ added in v0.4.0
func SummarizeAuditHealth(report AuditReport) AuditHealth
SummarizeAuditHealth derives aggregate issue counts for compact status views.
type AuditIssue ¶ added in v0.4.0
type AuditIssue struct {
Scope string
Name string
Type string
Created time.Time
AgeDays int
SourceSession string
SourceTurn string
Problem string
Detail string
Action string
}
AuditIssue is one memory-curation finding. The audit is intentionally read-only: it gives humans and future curator agents a queue of memories to merge, promote, or delete without changing long-term context silently.
type AuditReport ¶ added in v0.4.0
type AuditReport struct {
Total int
QuickNotes int
Issues []AuditIssue
Health AuditHealth
}
AuditReport summarizes memory-store quality. QuickNotes are type=note captures: useful raw material, but not the curated facts that should dominate long-lived memory.
func Audit ¶ added in v0.4.0
func Audit(l Loaded) AuditReport
Audit scans loaded memories for the first curation problems that make an agent less human-like over time: raw note buildup, duplicate index lines, vague bodies, and portable preferences filed under project scope.
type Corpus ¶ added in v0.3.0
Corpus holds precomputed statistics for BM25 scoring. Built once per retrieval pass from the current memory set via BuildCorpus.
func BuildCorpus ¶ added in v0.3.0
func BuildCorpus(entries []MemoryEntry) *Corpus
BuildCorpus tokenizes and stems all entries, computing document frequencies and average document length. O(n * avg_tokens).
func (*Corpus) BM25 ¶ added in v0.3.0
BM25 scores equal-weighted query stems against document at docIdx. Retained for the public/legacy path; the agent's retrieval uses the weighted variant (bm25Weighted) so synonyms count for less than exact terms.
func (*Corpus) Rank ¶ added in v0.3.0
Rank scores all documents against equal-weighted query stems and returns them sorted by descending score with alphabetical tie-breaking by entry name. The agent's retrieval path uses rankWeighted so synonym terms are down-weighted; Rank stays equal-weighted for the public/CLI surfaces.
type CurationBatch ¶ added in v0.4.0
type CurationBatch struct {
Title string
Action string
Issues []AuditIssue
}
CurationBatch is one read-only group of related audit issues. It gives the agent a safe checklist for a later explicit curation turn without mutating memory automatically.
type CurationHistoryRecord ¶ added in v0.4.0
type CurationHistoryRecord struct {
Time time.Time `json:"time"`
Action string `json:"action"`
Scope string `json:"scope,omitempty"`
Name string `json:"name,omitempty"`
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
Reason string `json:"reason,omitempty"`
}
CurationHistoryRecord is one JSONL event explaining a memory maintenance action. It is stored outside the live memory frontmatter so history can grow without bloating prompt-injected memory bodies.
type CurationPlan ¶ added in v0.4.0
type CurationPlan struct {
TotalIssues int
Batches []CurationBatch
}
CurationPlan groups audit issues into work batches ordered by the safest curation sequence: fix duplicates/weak bodies, promote notes, then clean up scope and empty entries.
func PlanCuration ¶ added in v0.4.0
func PlanCuration(report AuditReport) CurationPlan
PlanCuration groups a report's issues into read-only batches. The plan is intentionally high-level: it tells a curator what to work on together, while preserving the requirement that every actual memory change happens through explicit memory_get / memory_save / memory_forget calls.
type CurationProposal ¶ added in v0.4.0
type CurationProposal struct {
Problem string
Action string
Rationale string
Uncertainty string
Sources []ProposalSource
ProposedMemory *ProposedMemory
Forget []ProposalSource
}
CurationProposal is a read-only suggestion for subjective memory curation. It never applies changes; callers must route accepted proposals through memory_get, memory_save, memory_forget, or memory_curate_apply explicitly.
func ProposeCuration ¶ added in v0.4.0
func ProposeCuration(l Loaded, report AuditReport) []CurationProposal
ProposeCuration builds conservative, read-only proposals for subjective audit issues. Mechanical fixes remain handled by memory_curate_apply; this function covers the cases that require judgment and should be reviewed first.
type EmbedClient ¶ added in v0.3.0
EmbedClient talks to a local Ollama embedding endpoint.
func NewEmbedClient ¶ added in v0.3.0
func NewEmbedClient(baseURL, model string) *EmbedClient
NewEmbedClient returns a client configured for local Ollama embeddings. BaseURL defaults to http://localhost:11434 (or $OLLAMA_HOST). Model defaults to "nomic-embed-text".
func (*EmbedClient) Available ¶ added in v0.3.0
func (c *EmbedClient) Available(ctx context.Context) bool
Available reports whether the configured embedding model is installed on the Ollama server. Uses a short probe timeout.
func (*EmbedClient) Embed ¶ added in v0.3.0
Embed returns the embedding vector for a single text input. Calls POST /api/embeddings on the configured Ollama server.
func (*EmbedClient) Status ¶ added in v0.3.0
func (c *EmbedClient) Status(ctx context.Context) (reachable, installed bool)
Status probes the Ollama server and reports separately whether the server is reachable and whether the configured model is installed. Distinguishes "Ollama isn't running" (reachable=false) from "Ollama is running but the model was removed" (reachable=true, installed=false) so callers can surface a targeted warning.
type Frontmatter ¶
type Frontmatter struct {
Name string
Type string
Description string
Created string
SourceSession string
SourceTurn string
}
Frontmatter is the YAML-ish header on every agent-managed memory file. Real YAML is overkill for four flat fields — a tolerant key:value scanner keeps the writer one-line-per-field and the reader tiny.
func ParseFrontmatter ¶
func ParseFrontmatter(data []byte) (fm Frontmatter, body string, ok bool)
ParseFrontmatter splits frontmatter from body. Returns ok=false when the frontmatter block is missing or malformed; in that case fm is zero and body equals the input. Tolerant of files written by hand (no frontmatter at all is fine — caller defaults Type to "reference" and Name to the basename).
type Loaded ¶
type Loaded struct {
UserPath string
UserText string
ProjectPath string // YOTTACODE.md
ProjectText string
// User-scope agent-managed memories.
UserMemoryDir string
UserMemoryIndex string // raw MEMORY.md text (rendered if missing on disk)
UserMemories []MemoryEntry
// Project-scope agent-managed memories (per ProjectSlug(cwd)).
ProjectMemoryDir string
ProjectMemoryIndex string
ProjectMemories []MemoryEntry
}
Loaded carries the raw contents (and resolved paths) of every memory source read at session start. The two trust anchors (USER.md and YOTTACODE.md) sit alongside the user-scope and project-scope agent-managed memory directories. ProjectPath / ProjectText refer to YOTTACODE.md (the field name is historical from the YOTTACODE.md era).
type MemoryEntry ¶
type MemoryEntry struct {
Path string
Scope string // "user" | "project"
Name string // basename without .md
Type string // user | feedback | project | reference
Description string
Created time.Time // zero when frontmatter omitted or held an invalid timestamp
SourceSession string
SourceTurn string
Body string
}
MemoryEntry is one parsed memory file: enough to render the prompt and the MEMORY.md index. Body is raw markdown (frontmatter stripped).
func EffectiveEntries ¶ added in v0.4.0
func EffectiveEntries(user, project []MemoryEntry) []MemoryEntry
EffectiveEntries returns the all-scope memory set after applying the same project-over-user precedence used by prompt injection.
func Select ¶
func Select(entries []MemoryEntry, query string, cfg config.RetrievalConfig) []MemoryEntry
Select ranks entries against the query and returns at most cfg.TopK with score >= cfg.MinScore, further capped so the combined entry bodies stay within cfg.MaxBytes (0 = unlimited). Strategy selects the scoring algorithm: "keyword" uses the legacy exact-token scorer, "bm25" (default) uses BM25 with stemming and synonyms.
func SelectWithEmbeddings ¶ added in v0.3.0
func SelectWithEmbeddings(ctx context.Context, entries []MemoryEntry, query string, cfg config.RetrievalConfig, embedClient *EmbedClient) []MemoryEntry
SelectWithEmbeddings is like Select but accepts an optional EmbedClient for semantic scoring. When embedClient is non-nil and strategy is "semantic", BM25 scores are combined with cosine similarity from vector embeddings. ctx bounds the embed call: the TUI passes the turn context so Esc cancels an in-flight embed instead of waiting out its timeout.
func ShadowUserByProject ¶ added in v0.4.0
func ShadowUserByProject(user, project []MemoryEntry) []MemoryEntry
ShadowUserByProject drops user-scope memories whose name also exists in project scope. In a given repo the project-scope memory of a name is authoritative, so the user-scope twin's body is not injected — it would otherwise duplicate or, worse, contradict the project version. This mirrors the project-shadows-user precedence slash commands and config layering already use. The user file stays on disk and still applies in every other repo (where no project twin exists). Shadowing keys on the full project set, so it applies whether or not the project twin ranked this turn — a name's owner doesn't flip based on relevance.
type ProposalSource ¶ added in v0.4.0
type ProposalSource struct {
Scope string
Name string
Type string
Description string
SourceSession string
SourceTurn string
Excerpt string
}
ProposalSource identifies existing memory text that justifies a proposal. Proposal rendering should quote these snippets so a curator can verify the suggestion without trusting invented context.
type ProposedMemory ¶ added in v0.4.0
type ProposedMemory struct {
Scope string
Name string
Type string
Description string
Content string
}
ProposedMemory is a candidate memory_save payload. It is intentionally only a draft: proposal generation never writes it to disk.
type Scored ¶
type Scored struct {
Entry MemoryEntry
Score float64
}
Scored pairs a memory entry with the relevance score the orchestrator assigned it for a particular query. Score is in [0.0, 1.0]; deterministic across runs.
func SelectWithEmbeddingsScored ¶ added in v0.3.0
func SelectWithEmbeddingsScored(ctx context.Context, entries []MemoryEntry, query string, cfg config.RetrievalConfig, embedClient *EmbedClient) []Scored
SelectWithEmbeddingsScored is like SelectWithEmbeddings but returns Scored entries with their relevance scores preserved. Used by memory_search so the agent can see how well each memory matched.
type Source ¶ added in v0.4.0
Source records optional provenance for a memory save. It is intentionally lightweight frontmatter metadata, not an embedded transcript: session recall remains the path for full source context.
type Summary ¶
Summary is the short tag used by the TUI status bar — a human-friendly one-liner describing which memory sources are active.