Context and Problem Statement
Letta Code (letta) is a memory-first coding agent supporting headless automation via letta -p, --output-format json, and --output-format stream-json. The design spike (#1054) raised two questions:
- Should Letta be skill-only, slash-command-template-based (
.letta/commands/), orchestrator-enabled, or a combination? - How should Letta's persistent memory and long-lived agent/conversation model be handled in repeatable WP cycles — stateless (
--newflag each run) or sticky (reusing the same agent across WPs)?
The persistent-memory and session-model question is the distinguishing challenge for Letta compared to stateless agents like codex and pi. The wrong choice here could produce either stale cross-mission memory contamination (sticky) or loss of in-session context (stateless-per-WP).
Decision Drivers
- Letta natively discovers
.agents/skills/as its preferred skill root; skills are available without additional configuration. - Letta's persistent memory model introduces state-management complexity (session identity, memory isolation across missions) that is out of scope for this CLI-layer integration.
- A
LettaInvokerwith a validated session model belongs in the externalspec-kitty-orchestratorpackage. - Generating
.letta/commands/slash-command templates would require a new migration; the incremental value over skills is unclear given that Letta users can invoke skills directly. - Shipping a half-validated session model risks cross-mission memory contamination, which is a correctness risk for WP automation.
Considered Options
- Option A: Skill-only —
.agents/skills/spec-kitty.*/SKILL.mdonly; no.letta/commands/templates. - Option B: Skills + slash commands —
.agents/skills/plus.letta/commands/spec-kitty.<command>.mdgenerated by a new migration. - Option C: Full support — skills + slash commands +
LettaInvokerwith a defined session model (stateless vs. sticky), enablingspec-kitty next --agent letta.
Decision Outcome
Chosen option: "Option A — skill-only", because Letta's persistent memory/conversation model (stateless --new vs. sticky agent) introduces complexity that has not been prototyped or validated. Committing to a session model without that validation risks cross-mission memory contamination.
LettaInvoker and the session-model design are deferred to the external spec-kitty-orchestrator package scope. AGENT_COMMAND_CONFIG intentionally does not include letta.
Consequences
Positive
- No new migration for slash-command templates; Letta users get skills immediately via
spec-kitty init --ai letta. AGENT_SKILL_CONFIGincludesletta, so skill packages are installed and kept in sync..letta/gitignore entry prevents runtime state, authentication tokens, and memory stores from polluting the repository.spec-kitty agent config add lettais fully supported.
Negative
spec-kitty next --agent lettais not supported withoutspec-kitty-orchestrator..letta/commands/is intentionally absent; Letta users cannot use slash-command-style invocation via spec-kitty.
Neutral
AGENT_COMMAND_CONFIGdoes not includeletta— this is by design, not an oversight.- The session-model question (stateless vs. sticky) is deferred; a follow-up ADR should be written in
spec-kitty-orchestratorwhen a prototype is available.
Confirmation
This decision is correct if Letta users can successfully run Spec Kitty work packages using .agents/skills/ discovery without errors related to missing slash-command templates. The absence of letta from AGENT_COMMAND_CONFIG is confirmed by test_twelve_agent_parity.py:204. Cross-mission memory contamination is avoided because no session model is activated at this layer.
Pros and Cons of the Options
Option A — Skill-only
Skills only; Letta reads .agents/skills/spec-kitty.*/SKILL.md natively.
Pros:
- Zero new migrations needed.
- Immediate value: skills install on
spec-kitty init --ai letta. - No risk of cross-mission memory contamination from an unvalidated session model.
- Consistent pattern with codex and pi integration.
Cons:
- No slash-command surface for Letta users who prefer that interaction style.
spec-kitty next --agent lettaremains unsupported untilspec-kitty-orchestratoraddsLettaInvoker.
Option B — Skills + slash commands
Skills plus .letta/commands/ generated via a new migration.
Pros:
- Users who prefer slash-command invocation can use that surface.
Cons:
- Requires a new migration for a surface whose value is unproven.
- Does not address the session-model question; persistent memory still requires a separate design decision.
Option C — Full support
Skills + slash commands + LettaInvoker with session model.
Pros:
- Complete first-class integration;
spec-kitty next --agent lettaworks.
Cons:
LettaInvokerbelongs inspec-kitty-orchestrator, not in this CLI package.- Session model (stateless vs. sticky) is unvalidated; incorrect choice risks cross-mission memory contamination.
- Largest scope; highest risk.
More Information
- Implementation evidence:
src/specify_cli/upgrade/config.py:85showslettainAGENT_SKILL_CONFIG;tests/specify_cli/test_twelve_agent_parity.py:204confirmslettaabsent fromAGENT_COMMAND_CONFIG. - Related ADR: 2026-06-02-1-pi-agent-skill-only-support.md — same pattern applied to Pi.
- Tests:
tests/specify_cli/cli/commands/test_init_pi_letta.py,tests/specify_cli/cli/commands/test_agent_config_pi_letta.py. - Deferred design question tracked in GitHub #1054 until resolved.