Documentation
¶
Overview ¶
Package instruction loads project + user "agent memory" files (typically AGENTS.md) into the system prompt.
Loader v2 (docs/instruction-loader-v2-design.md) supports two composition primitives on top of the v1 single-file shape:
- @include <relative-path> directive: a line that matches the pattern is replaced in-place by the referenced file's content. Outside fenced code blocks only. Cycle + depth capped.
- .agents/AGENTS.d/*.md directory: every top-level .md file is loaded in lexical filename order, appended after the scope's primary file.
Both primitives work at user-global and project scope. A per-Load canonical-path visited set deduplicates: the same file reached via any path is read once and the first encounter wins.
The project scope's primary entry is resolved via the first-match- wins fallback chain AGENTS.md → CLAUDE.md → GEMINI.md (legacy compatibility). The user-global scope reads only AGENTS.md.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrInvalidCallerIdentity = errors.New("instruction: caller identity contains path-traversal characters")
ErrInvalidCallerIdentity is returned by LoadForSession when the callerIdentity argument contains characters that could traverse out of usersDir (path separators or ".."). Operators see this as a validation error at agent construction time rather than a silent load from an unexpected directory.
Functions ¶
This section is empty.
Types ¶
type Loaded ¶
Loaded is the result of a Load call. Instruction is the assembled text suitable for prepending to the agent's system prompt; Sources describes what got included (one entry per loaded file); Searched lists the primary-file paths that were probed during resolution (regardless of whether a file existed at that path). Callers can use Searched to produce actionable "no AGENTS.md found — checked [...]" diagnostics when Sources is empty; without this the operator has no visible signal that the load found nothing (the daemon happily runs with an empty system prompt).
func Load ¶
Load resolves the project + user memory files and returns the concatenated instruction text. Missing files at primary slots are not errors — memory is optional. A missing @include target IS an error so operator typos surface immediately.
projectRoot may be empty; in that case only user memory is loaded. userRoot may be empty in tests.
func LoadForSession ¶
func LoadForSession(projectRoot, userRoot, callerIdentity, usersDir string, opts ...Option) (Loaded, error)
LoadForSession extends Load with an optional per-caller overlay scope used by the multi-session attach layer. It walks (in order):
- userRoot/.agents/ + userRoot/ — the daemon-wide user-scope memory (same as Load).
- projectRoot/.agents/ + projectRoot/ — the project-scope memory (same as Load).
- <usersDir>/<callerIdentity>/.agents/ — the per-caller overlay (NEW; multi-session only).
Per-caller overlay rules:
- usersDir == "" OR callerIdentity == "" → no overlay applied; behaves identically to Load. This is the single-user / pre- multi-session path.
- callerIdentity containing path separators or ".." → returns ErrInvalidCallerIdentity. Defense against a malicious identity (e.g. "../../etc") traversing out of usersDir.
- <usersDir>/<callerIdentity>/ doesn't exist → silently skip. Operators may provision overlays for some callers and not others; a missing directory is a legitimate "no overlay" signal.
The visited-set propagates across all three scopes — a file referenced by both the project layer and the caller overlay loads exactly once, preserving the dedup semantics of Load.
type Option ¶
type Option func(*loadOptions)
Option configures a Load / LoadForSession call. All options are optional; the zero-options call matches the pre-#322 loader behavior exactly.
func WithInterpolator ¶
WithInterpolator supplies a string transform applied to every loaded file body — used to substitute ${env:VAR} references declared in .agents/env.yaml (see pkg/agentenv). Passing nil is legal and equals "no interpolation."
type Source ¶
type Source struct {
Scope string // "user" | "project"
Path string // canonical absolute path
Bytes int // bytes after truncation
Truncated bool // true if the on-disk file exceeded maxFileBytes
}
Source records where one piece of loaded memory came from. Used by callers (e.g. a /memory slash command) to show provenance. Every file loaded — primary, transitively included, or AGENTS.d/ scanned — produces one Source entry.