Skip to content

Memory

SASE memory is durable context that survives individual agent chats. It has two file tiers plus an audited operation ledger:

  • Short-term memory under memory/short/ is instruction context. The files are loaded only when AGENTS.md reaches them through @memory/... references; sase memory init creates that wiring for the generated defaults and synchronizes AMD-managed AGENTS.md memory blocks when the project opts in with amd_h1_title.
  • Long-term memory under memory/long/ is reference context. Files can carry description frontmatter; AMD-managed AGENTS.md files use those descriptions for the long-memory list.
  • Audited memory operations live under the project state directory and record agent reads plus proposed writes and human review decisions.

Use initialization to create or refresh the files. Use sase amd list to inspect AGENTS.md and provider shim status. Day to day, the usual order is: inspect loaded context with sase memory list, have agents use sase memory read for audited long-term reads, have agents use sase memory write only to create proposals, then have a human approve or reject those proposals with sase memory review.

Inspect Context

sase memory and sase memory list render the memory files visible from the current directory:

sase memory
sase memory list

The dashboard separates:

  • loaded files reached by transitive @... references from AGENTS.md in the project or home context. Provider shims normally point at AGENTS.md; they are reported as instruction roots but are not separate traversal roots for this dashboard.
  • referenced files mentioned by plain memory/... text, or by memory-relative long/... paths in audited sase memory read instructions, but not loaded.
  • available files present under project or home memory/short/ and memory/long/ but unreachable from the current launch context.
  • missing referenced files that do not exist.

Approximate token counts are included so large instruction surfaces are visible before an agent launch.

Audited Reads

Agents should read long-term memory through sase memory read so the access is attributable:

sase memory read long/generated_skills.md --reason "Need generated skill context"
sase memory log
sase memory log --include proposals
sase memory log --path long/generated_skills.md
sase memory log --agent agent-a
sase memory log --id <read-id>

The read path is relative to memory/ and currently accepts Markdown files under memory/long/. memory/short is excluded because short-term memory is intended to arrive through instruction loading rather than ad hoc reads. The command strips one leading YAML frontmatter block from stdout, while the audit event records metadata such as path, agent name, timestamp, cwd, byte count, and reason.

Every read requires a non-empty reason via -r or --reason and agent attribution from SASE_AGENT_NAME, SASE_AGENT, or SASE_ARTIFACTS_DIR/agent_meta.json (name, workflow_name, or agent_name). Unattributed reads fail instead of writing the log. In a normal human shell, use regular file reads instead of this audited command unless you are intentionally simulating an agent identity.

Pass --include proposals to include memory proposal and review ledger events in the same audit dashboard. Path and agent filters also apply to proposal target paths and proposal/review actors.

Propose Memory

Agents do not write canonical memory/long/*.md files directly. They create proposals:

sase memory write \
  --title "Generated skills" \
  --slug generated_skills \
  --keyword "commit skill" \
  --evidence sdd/research/skills.md \
  --body "Durable memory body" \
  --notify

cat draft.md | sase memory write \
  --title "Generated skills" \
  --target long/generated_skills.md \
  --from-chat abc123 \
  --keyword "commit skill"

sase memory write is the agent-side authoring path. It writes proposal state only under ~/.sase/projects/<project>/; it never modifies canonical memory/long files. A proposal needs:

  • --title
  • exactly one of --slug <slug> or --target long/<slug>.md
  • at least one non-note evidence item
  • body content from --body, --file <path>, --file -, or piped stdin when neither --body nor --file is supplied

Use --file - when a wrapper needs the explicit --file form but should still pass the body on stdin.

Targets must be one-level long-memory paths such as long/generated_skills.md; slugs must match [a-z0-9][a-z0-9_-]*. Evidence can be a path, chat:<id>, --from-chat <id>, url:<url>, a bare HTTP(S) URL, or a supplemental note:<text>. Note-only evidence is rejected.

Proposal bodies must be non-empty UTF-8 and at most 256 KiB. Bodies above 16 KiB produce a warning unless --allow-large is passed. Prompt-injection-like text is also recorded as a warning for the reviewer.

Proposal authors are attributed from the same agent identity sources as audited reads. --manual-author exists for tests and demos; normal agent writes should rely on the SASE-provided identity.

Use --notify to best-effort append a memory.proposed notification after proposal creation. The notification carries the memory tag, attaches any evidence paths that resolved to local files, and opens the interactive memory review TUI at that proposal when selected in ACE. The notification is only a prompt to review; it does not approve, reject, or edit the proposal by itself. Notification delivery is reported in the human output and as notification_id in JSON output.

Use --json for deterministic machine-readable output.

Review Proposals

Humans review proposals with sase memory review:

sase memory review                         # interactive TUI on a TTY
sase memory review --list
sase memory review --list --all --json
sase memory review <proposal-id> --show
sase memory review <proposal-id> --approve
sase memory review <proposal-id> --edit
sase memory review <proposal-id> --approve --edited-file edited.md
sase memory review <proposal-id> --reject --reason "Too speculative"

A bare sase memory review opens the Textual review app when stdin/stdout are TTYs. In non-interactive shells it prints the pending list instead. --list and --show are inspection commands; --approve, --edit, and --reject are the human promotion decisions. Proposal ids can be abbreviated when the prefix is unambiguous.

Agents cannot approve, edit-approve, or reject proposals: those actions fail when agent identity is present in SASE_AGENT_NAME, SASE_AGENT, or SASE_ARTIFACTS_DIR/agent_meta.json. Human review events record the local user and hostname. --edit opens $VISUAL or $EDITOR, then approves the edited body.

Approval writes the canonical file under the current repo's memory/long/ path and prepends frontmatter:

---
keywords:
  - "commit skill"
source_candidate: mem-20260523-142233-a1b2c3d4
---

Approval refuses to overwrite an existing target. Use --target long/<slug>.md to approve into a different unused one-level target, --edit to open $VISUAL/$EDITOR before approving, or --edited-file for non-interactive edited approval.

If approved memory should be loaded every time, add an explicit @memory/long/... reference from the appropriate instruction file.

Review TUI

The interactive review app shows pending proposals, evidence, target status, diffs against existing files, warnings, and audit events. Keybindings:

Key Action
j / k Move through pending proposals
Down/Up Move through pending proposals
g / G Jump to first / last proposal
/ Filter by id, title, author, target, keyword, status
Enter/d Toggle detail view
Esc Return from detail view
a Approve as-is
e Edit in $VISUAL/$EDITOR, then approve
r Reject with a required reason
t Override the approval target
y Copy the proposal id
q Quit

The proposal ledger is append-only JSONL with a lock companion. Malformed rows are skipped when reading, and every review action appends a new event rather than mutating previous events.

Episodes

sase memory episodes builds deterministic, source-linked evidence records for prior agent work. Episodes are useful when raw chats are too fragmented but the lesson is not ready to become approved long-term memory. They connect prompts, chats, plans, diffs, feedback, questions, retries, beads, ChangeSpecs, audited memory reads, and outcomes into canonical episode.json evidence records.

Start from a completed agent. build stores the episode by default; recall searches only stored episodes:

sase memory episodes build -n <agent-name>
sase memory episodes auto -p <project> -l 50
sase memory episodes status -p <project>
sase memory episodes list -g day
sase memory episodes show <episode-id>
sase memory episodes verify <episode-id>
sase memory episodes doctor -p <project>
sase memory episodes recall -q "retry feedback"
sase memory episodes export -s 2026-05-01 -u 2026-05-26 -b high -j

Other selectors are available when the agent name is not the best handle:

sase memory episodes build -a ~/.sase/projects/<project>/artifacts/.../<timestamp>
sase memory episodes build -c <changespec-name>
sase memory episodes build -C ~/.sase/chats/202605/<chat>.md
sase memory episodes build -s 2026-05-01 -u 2026-05-26 --split
sase memory episodes list -s 2026-05-01 -u 2026-05-26 -b high -j

Episodes are stored under ~/.sase/projects/<project>/episodes/. New split v2 episodes write episode.json and sources.jsonl; legacy aggregate episodes also write lesson.md. Use --format overview, --format timeline, --format graph, --format sources, --format agent, or --format json to inspect provenance. recall returns v2 evidence cards and still supports legacy lesson cards. export emits bounded read-only event-readiness summaries and does not write sdd/events/ or proposals. verify recomputes source existence, size, and hashes without changing the episode. Missing or changed sources mean the evidence drifted; they do not delete the episode or automatically block recall.

For scheduled maintenance, sase memory episodes auto runs one checkpointed builder cycle over new completed-agent markers. It does not keep running after that pass; schedule it externally or configure the installed memory_episodes axe chop for repeated maintenance. status shows the automatic builder checkpoint, lock, index, and latest metrics, while doctor inspects that state and can apply safe repairs with --repair.

Human-mode build prints phase progress to stderr and the final summary to stdout. Pass --quiet to suppress progress while keeping the final summary, or --json for a deterministic machine-readable payload with episode, build_request, and build_report objects. With --split --json, the payload contains a components list and a build_reports list with one entry per connected component. Date-bounded split project scans use the date window for seed records only; strong retry/fork/parent/chat/workflow lineage may pull connected evidence outside the window, while weak ChangeSpec, bead, family, touched-path, or date proximity refs do not merge unrelated work. list date filters use stored episode event spans rather than build time.

Episodes do not modify memory/short or memory/long. Promote a durable rule from an episode only through the reviewed proposal path:

sase memory write \
  --title "Retry feedback rule" \
  --slug retry_feedback_rule \
  --evidence ~/.sase/projects/<project>/episodes/<episode-id>/episode.json \
  --body "..."
sase memory review --list

See Episodes for selector guidance, storage details, and trust checks.