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:

  1. Should Letta be skill-only, slash-command-template-based (.letta/commands/), orchestrator-enabled, or a combination?
  2. How should Letta's persistent memory and long-lived agent/conversation model be handled in repeatable WP cycles — stateless (--new flag 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 LettaInvoker with a validated session model belongs in the external spec-kitty-orchestrator package.
  • 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.md only; no .letta/commands/ templates.
  • Option B: Skills + slash commands — .agents/skills/ plus .letta/commands/spec-kitty.<command>.md generated by a new migration.
  • Option C: Full support — skills + slash commands + LettaInvoker with a defined session model (stateless vs. sticky), enabling spec-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_CONFIG includes letta, 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 letta is fully supported.

Negative

  • spec-kitty next --agent letta is not supported without spec-kitty-orchestrator.
  • .letta/commands/ is intentionally absent; Letta users cannot use slash-command-style invocation via spec-kitty.

Neutral

  • AGENT_COMMAND_CONFIG does not include letta — 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-orchestrator when 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 letta remains unsupported until spec-kitty-orchestrator adds LettaInvoker.

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 letta works.

Cons:

  • LettaInvoker belongs in spec-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:85 shows letta in AGENT_SKILL_CONFIG; tests/specify_cli/test_twelve_agent_parity.py:204 confirms letta absent from AGENT_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.