You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Agent decisions written with memory.write class decision end up in memory/local instead of decisions/inbox #2314
While digging into how governed memory works, I noticed that decisions agents record the way the coordinator template tells them to never make it into decisions.md.
The template (templates/squad.agent.md.template:549, and the coordinator-response-mode skill at line 91) says to use memory.write with class decision, in lowercase. The enum is uppercase and nothing normalizes the value, so:
the call succeeds and the agent gets back "Stored decision memory ..."
the file goes to .squad/memory/local/ instead of .squad/decisions/inbox/
index.json records class: "decision" with no load guidance (the front matter literally says loadGuidance: [undefined])
Scribe only merges the inbox, so the decision never reaches decisions.md
Repro
With a local-backend .squad, call memory.write through squad_state with:
{ "content": "We decided to use Vitest.", "title": "Use Vitest", "author": "dallas", "class": "decision" }
decisions/inbox stays empty and the file shows up in memory/local. Same result with "Decision", " decision " and even "decisions".
Why it happens
squad_state uses the low-level MCP Server, which doesn't validate arguments against inputSchema, so the enum in the tool schema (packages/squad-sdk/src/tools/index.ts:1000) isn't enforced. The handler passes args.class straight through, and LocalMemoryStore.classify uses it as is (packages/squad-sdk/src/memory/index.ts:608). The class gates are exact matches (FORBIDDEN at :623, TRANSIENT at :631, COPILOT_MEMORY at :682), and the routing only knows DECISION and POLICY (:1331-1337).
The CLI already upper-cases and validates the class (packages/squad-cli/src/cli/commands/memory.ts:59-66). The MCP path just never got the same treatment.
Also: lowercase forbidden, transient and copilot_memory get stored as well, while their uppercase versions are rejected.
Suggested fix
Normalize (trim and upper-case) and validate the class once in LocalMemoryStore.classify, return a proper failure from the memory.* tools for unknown names, and fix the spelling in the template copies. Entries that were already misfiled can be moved with memory.promote <id> DECISION.
changed the title [-]memory.write with class `decision` (lowercase, as the coordinator template instructs) misfiles agent decisions in memory/local[/-][+]Agent decisions written with memory.write class `decision` end up in memory/local instead of decisions/inbox[/+]on Oct 25, 2026
Activity
fix(sdk): treat governed memory class names case-insensitively
[-]memory.write with class `decision` (lowercase, as the coordinator template instructs) misfiles agent decisions in memory/local[/-][+]Agent decisions written with memory.write class `decision` end up in memory/local instead of decisions/inbox[/+]fix(sdk): treat governed memory class names case-insensitively
fix(sdk): treat governed memory class names case-insensitively (#2315)