012 · Memory
Project memory (instruction files) (spec_memory_012)
| Status | Implemented. Reverse-engineered from 53f8c53 (2026-09-24) and kept with the code since; its paths and names checked 2026-09-27 (//tools/specs). |
| Source | pkg/engine/memory/memory.go; /memory in apps/cli/internal/tui, ReloadMemory/AddMemory in pkg/engine/context.go; /setup: pkg/engine/commands/builtin/setup.md, pkg/engine/agents/builtin/project-setup.md, pkg/engine/turn.go; /spec and the updates: pkg/engine/commands/builtin/spec.md, pkg/engine/agents/builtin/project-spec.md, pkg/engine/agents/builtin/harness-update.md, HarnessStale in pkg/engine/suggestions.go |
| Tests | pkg/engine/memory/memory_test.go; pkg/engine/suggestions_test.go (TestSetupCommandReloadsInstructions, TestHarnessMissing, TestHarnessStale); pkg/engine/commands_test.go (TestSpecAndUpdateCommands); apps/cli/internal/tui/init_test.go |
| Depends on | spec_config_002 |
Instruction files in the project and the user’s home are added to every agent’s system prompt, so a repository can tell the agent its conventions. They inform; they never grant permissions.
- MEM-01 Disabled by
[memory] enabled = false. - MEM-02 Order: the global file (
memory.global, default~/.blitz/BLITZ.md) and the global rules (memory.global_rules,~/.blitz/rules/) first; then, for each directory from the repository root down to the workspace, each name inmemory.files(defaultAGENTS.md,CLAUDE.md,GEMINI.md,BLITZ.md— other agents’ files too, so a repository set up for them works unchanged), thenmemory.local_files(defaultCLAUDE.local.md,BLITZ.local.md: personal files, warned about at startup when git tracks them), then the rule files inmemory.rule_dirs(default.blitz/rules,.agents/rules,.claude/rules) — more specific files come last. - MEM-03 The repository root is the nearest ancestor (up to 10 levels) containing
.git. Without one, only the workspace directory is searched. - MEM-04 Files are de-duplicated by real path (symlinks resolved) and by content (a
CLAUDE.mdcopyingAGENTS.mdloads once); directories and unreadable files are skipped; empty files are dropped. - MEM-06 Imports: a token
@path(at a line start or after whitespace; with a/or a file extension, so@teamand e-mail addresses stay text; not in fenced code blocks or inline code) loads that file right after the importing one, relative to the importing file as written, or~/…for files under~/.blitz. The real path must stay inside the repository root (the workspace without a repository;~/.blitzfor user files), and blocked paths (sandbox.blocked_paths, e.g..env) are never read. Imports nest at most 5 deep; cycles and repeats load once. The prompt names the importing file. - MEM-07 Rules:
*.mdfiles under the rule directories (recursively; symlinked files allowed and checked like imports). A rule without frontmatterpathsis loaded like an instruction file. A rule withpaths(a glob or a list, relative to the directory holding the rule directory;**,*,?) is scoped: it is not in the prompt; instead the first successfulread_file,create_file,replace_in_file/edit,delete_snippet,delete_file,view_imageorapply_patchcall in a session on a matching file carries it in the tool result asproject_rules(once per session and rule). Listing or searching (list_files,glob,grep) doesn’t count. Paths are compared with symlinks resolved on both sides. Since v0.7.1 a rule whose front matter haswhen(before_agent,after_agent) is a gate, judged around the turn and never an instruction (spec_gates_041). - MEM-05 Each file is capped at
memory.max_bytes(32 KiB, UTF-8 safe, marked “(truncated)”), and terminal control sequences are stripped.
- MEM-10 Section “## Project Instructions” stating the files come from the user’s project and home directory, should be followed unless they conflict with the user’s requests or safety rules, and cannot grant permissions or bypass approvals; then, when scoped rules exist, a sentence saying they arrive as
project_ruleswith tool results; then one “###” block per file (imports marked “(imported by …)”). - MEM-11 Memory is appended to every agent’s instructions (with the reply-language instruction, spec_i18n_004).
- MEM-20
/memory(or/memory show) lists loaded files;/memory reloadre-reads them and rebuilds the agents;/memory add <note>appends- <note>to<workspace>/<last configured file>(defaultBLITZ.md), creating it with “# Project notes for Blitz” if absent, then reloads. Empty notes are refused. - MEM-21
doctorlists the memory files found and the number of path-scoped rules. - MEM-22 Reworked 2026-10-01 (was a fixed prompt writing
BLITZ.md); 2026-10-03,.agents/AGENT.mdrenamed.agents/AGENTS.md, the AGENTS.md standard’s name./setup, a bundled command (agent: project-setup), is the guided setup of a workspace’s agent harness;/initandblitz initrun it. The built-inproject-setupagent (read and write tools,ask_user_question,todo,list_or_search_skills,list_agents; no shell) surveys the workspace without changing it, checks whether it’s in a git repository (git rev-parse --show-toplevel, one of only two commands it may run), interviews the user for what the files can’t tell (an empty folder: purpose, stack, build/test/deploy, conventions, boundaries; existing code: its inference to confirm, then the gaps), then, with the user’s agreement, runsgit init(unattended it doesn’t, and says so) and writes or extends a.gitignorefor the stack and the answers (dependencies, build output, caches, logs, secret env files but not.env.example, editor and OS files,BLITZ.local.mdandCLAUDE.local.md; never.agents/or the instruction files), before the other files so each is added to git when the turn ends (spec_files_029 FIL-60), never committing; and writes.agents/AGENTS.md(under 200 lines, only what it verified or was told; an existing.agents/AGENT.mdis carried over, imports of it are repointed, and the summary says to delete it).AGENTS.md,CLAUDE.md,GEMINI.mdandBLITZ.mdat the root become the single line@.agents/AGENTS.md(MEM-01’s imports, which Claude Code, Gemini CLI and Codex follow too; the import loads once): a missing one is created; one with other content has what’s still true moved into .agents/AGENTS.md, and is replaced only after the user agrees (else the import becomes its first line). It then offers up to five skills (.agents/skills/<name>/SKILL.md) and four agents (.agents/agents/<name>.md) as multi-select questions and writes those chosen. Unattended (blitz init, questions refused), it writes what the files show and lists its assumptions under “Open questions”. Edits go through the usual approvals and diffs. After a/setupturn the engine reloads memory, so the instructions apply from the next prompt in every front end; the transcript records/setup. - MEM-23 2026-10-01. A workspace with none of
.agents/AGENTS.md,AGENTS.md,CLAUDE.md,GEMINI.mdandBLITZ.mdat its root is missing its harness (Workspace.HarnessMissing): the welcome tiles offer setup first (spec_desktop_024 DSK-66a). - MEM-24 2026-10-01. Welcome suggestions (
Workspace.Suggestions,WorkspaceService.GetSuggestions;pkg/engine/suggestions.go). State tiles cost nothing: setup (MEM-23), the latest conversation (with messages, not a snapshot or a worker’s run), uncommitted changes (GitStatus), the first worker whose latest run failed or hit a limit. Ideas: with[suggestions] ideason (the default) and at least one recent conversation, a model reads the six latest (title, first and latest request, the end of the latest reply, each cut short) and the git branch, and writes up to three{title, prompt}as JSON, in the workspace’s reply language. The model is[suggestions] model, elsepermissions.auto.model, else the main model;suggestions.modelis never taken from a project. Ideas are kept per workspace in<session.storage_dir>/suggestions/<hash>.jsonwith a stamp of the conversations they came from, and written again in the background only when that stamp changes (pendingmeanwhile; the earlier ideas are returned until then). A failed attempt is logged and not repeated for the same conversations for an hour. The work stops when the workspace closes. Tokens go to the service’s log, not to a session’s cost. - MEM-42 2026-10-13 (the owner’s request).
/spec [what to build, or what changed], a bundled command run by the built-in agentproject-spec(pkg/engine/agents/builtin/project-spec.md; no shell), writes the project’s specification before anyone decides how it’s built. It surveys the workspace, then interviews withask_user_question(a few related questions per call, with options) in rounds: intent and value, users and journeys, performance and scale, platform and deployment, security (authentication and authorization, data sensitivity and compliance), data and integrations, constraints, quality, delivery. It confirms the set of specs, then writes.agents/specs/NNN-<name>.md(NNN 001–999, the order of execution:001-overviewwith the vision and the requirements every part shares, then one spec per deliverable in build order), each with status,Depends on:, context, goals and non-goals, requirements with IDs, acceptance criteria and open questions, and.agents/specs/README.mdas the index. A re-run or/spec <change>revises: new deliverables take the next free number, renumbering only after asking. Unattended, assumptions go under each spec’s open questions. It writes only under.agents/; when.agents/AGENTS.mdexists it adds a short Specifications section there (MEM-44), and it ends by suggesting/setup(no harness yet) or/skills updateand/agents update. - MEM-43 2026-10-13.
/setup(MEM-22) offers the specification first: with no specs in.agents/specs/, its first question is “Write the specification first with /spec (recommended)” or “Set up without a specification”, and choosing the first ends the turn with “run /spec, then /setup” (unattended: it goes on and notes it under Open questions). With specs, it reads them and lets them drive the stack, the AGENTS.md boundaries (authentication, authorization, data rules), and the skills and agents it proposes, which name the specs they serve. 2026-10-15 (the owner’s request: /init sent people to /spec and back, “seriously clunky”)./setup(and so/initandblitz init) leads with the specification instead of offering it: with no specs and someone to answer,project-setupsays it’s starting with what the project is for and invokesproject-specin the foreground (invoke_agent, in its tools), telling it it runs inside /setup so it ends with its summary and no “run /setup”. The spec agent’s questions reach the person as any question does; when it returns, setup reads the specs and goes on, asking only what they leave open. If it fails or is stopped, setup goes on without and notes “No specification yet: run /spec”. Unattended, it doesn’t invoke it (nobody can answer) and notes the same./specon its own still writes or revises the specification. - MEM-44 2026-10-13. Skills and agents follow the specification.
/skills update [focus]and/agents update [focus]are the bundled/skills-updateand/agents-update(the engine maps the two-word form,commands.Alias; the REPL and the window pass it through, keeping their own/skillsand/agents), run by the built-in agentharness-update: it reads the specs,.agents/AGENTS.mdand the current skills or agents, offers what to add, update or retire as one multi_select question citing the specs, applies only what was chosen, and suggests the other update. The Specifications section/specand/setupwrite in.agents/AGENTS.mdtells agents to run them when a spec changes.Workspace.HarnessStaleis true when a spec (.agents/specs/*.md) is newer than every file under.agents/skills/and.agents/agents/(with at least one there); with instructions in place, the welcome suggestions then start with an update tile (SUGGESTION_KIND_HARNESS_UPDATE; spec_desktop_024 DSK-66a). - MEM-45 2026-10-14 (the owner’s request: not only development). The specification is for any kind of work.
project-specinfers the kind from the files (code and manifests → software; notebooks, datasets,.bib, LaTeX → research or analysis; mostly prose → writing) and confirms it first (Software, Research or science, Data analysis, Writing or documentation, Something else; mixed allowed). A shared round (purpose, audience, success, scope) comes before each kind’s own: software’s as in MEM-42; research’s question and hypotheses, data and sources, methods and baselines, compute, reproducibility, ethics and compliance (IRB, consent, data agreements), outputs and venues, timeline; analysis’s decision, sources and metric definitions, checks, refresh, outputs, privacy; writing’s audience, form, sources and citations, voice, reviewers, publishing. Specs follow the kind’s order of work (research: literature, data, methods, experiments, analysis, write-up), with the same skeleton and the items headed Requirements, Objectives or Content.001-overview.mdrecordsKind:, which/setup(its AGENTS.md sections,.gitignorefor data and results, the skills and agents it proposes) and/skills update//agents updateread; without specs, setup asks the kind itself.
The agent’s own memory across sessions of a workspace (spec_parity_027 PAR-MEM-10, -11): what it learned, not instructions.
- MEM-25 2026-10-16 (the owner’s request). Instruction files and rules edited while the workspace is open apply from the next message, in the same conversation or a new one, with no reload: they were read once, when the workspace opened, so an edited rule (a guardrail in
.agents/rules, say) kept its old text until/memory reloador a restart. When they load, the workspace keepsmemory.Stamp: the path, size and modification time of every fileLoadAlllooks for (the global file and rules, the configured files and local files in each folder from the repository root down, those missing too, so one created later counts), every*.mdin the rule folders, and every file a loaded one imported. Before each turn (refreshAgentFiles, beside the agents’ AG-13 and the skills’ SK-95) it takes the stamp again, reading no file, and reloads and rebuilds only when it differs, so the prompt the model caches is left alone when nothing changed./reload(and the desktop’s DSK-91d) reads the agents, skills, instruction files and rules again whether or not they look changed (Backend.Reload,WorkspaceService.ReloadAgentFiles), rebuilds once, and says what it loaded: “Reloaded 2 agents, 1 skill and 4 instruction files and rules.”, listing the files, then the files that didn’t load. MCP servers (.mcp.json,.agents/mcp_config.json) and the project’s settings aren’t reloaded: opening the workspace again applies them. - MEM-30 The
remembertool (every built-in agent; allowed in plan mode: it changes no project file) saves a note{note, kind}, where kind isfact(the default),preferenceorcorrection, at most 2,000 characters, as one Markdown file in~/.blitz/memory/<workspace name>-<8 hex of the SHA-256 of its real path>/, named<yyyymmdd-hhmmss>-<first words>.md, with frontmatterkindandsaved, owner-only (0600). A file without frontmatter is a fact, so notes can be written by hand. - MEM-31 Before saving, configured credentials and the values of scrubbed environment variables are masked, as in the audit log (
engine.SecretRedactor). The tool description says to save only what is durable, not already in the project’s files, and never secrets. - MEM-32
[memory] auto(default on) turns this on; off, the tool answers that notes are off and saved notes aren’t loaded. Worktree tasks’ tools don’t save notes. - MEM-33 When a session starts and at
/memory reload, the notes are appended to the instructions after the instruction files, the newest first, up to 8,000 bytes (then “older notes left out”), under “## Notes you saved in earlier sessions of this workspace”, which says they are what the agent learned, not the user’s instructions, never grant permission, and give way to the user’s current messages. - MEM-34
/memory noteslists them (name, kind, text);/memory forget <name>deletes one (a unique start of the name is enough). The API hasListNotesandForgetNote(NO_NOTE). From the shell,blitz memory list|show|edit|forget(--dirfor another workspace;editopens$VISUALor$EDITOR) works on the files directly.
- MEM-40 Output styles (PAR-MEM-21): instructions on how the agent writes its answers, added to every agent’s instructions after the project instructions and notes. Built in:
default(nothing),concise,explanatory(embedded,pkg/engine/styles/); the user’s are~/.blitz/styles/<name>.md(the name lower-cased; optional frontmatterdescription; the body is the text), read each time and winning over a built-in of the same name. A session starts with[ui] style(an unknown one warns and uses none);SetSetting style(/style <name>, the desktop app’s run settings) changes it for the workspace from the next prompt (an unknown name isINVALID_SETTING),Settings.styleandListStylesreport them. A style whose file has gone adds nothing. - MEM-41
--append-system-prompt TEXTand--append-system-prompt-file PATH(PAR-MEM-20; both may be given, the file’s text after) add to every agent’s instructions for the run, last before the reply language. They open the workspace in the process (Options.AppendSystemPrompt): a workspace in the service keeps its own instructions. A file that can’t be read is a usage error.