Skip to content

State and memory

Alfred is built on the premise that the host filesystem is a fine operational state store for a single-person fleet. Every firing reads its inputs from scratch, writes operational JSON or JSONL under $ALFRED_HOME/state/, and keeps review and reliability rows in $ALFRED_HOME/fleet-brain.db. Recalled lessons live in the local Redis Agent Memory Server by default. If you delete local state, Alfred rebuilds whatever it still can from GitHub and local config.

This page is the map of that directory and the contract each file carries. Full doc at docs/STATE_AND_MEMORY.md.

$ALFRED_HOME/state/
├── global-blocked-until.json fleet-wide rate-limit block
├── paused-repos.json repos you manually paused
├── code-map.json cross-repo files, symbols, imports, routes
├── slack-webhook.cache 30-day cache of the resolved webhook URL
├── _paused/ per-agent pause markers
├── fleet/
│ └── enabled.txt runner-gate list of enabled codenames
├── engines/
│ └── <codename> claude | codex | hybrid override
├── <codename>/
│ ├── spend-YYYY-MM-DD.json per-agent per-day spend ledger
│ ├── spend-dryrun-YYYY-MM-DD.json
│ └── events/ per-firing event log
├── claims/ agent-claim audit trail (when present)
├── transcripts/<codename>/<YYYY-MM>/<firing-id>.jsonl
├── codex/<codename>/<YYYY-MM>/<firing-id>.{last.md,stdout.txt,stderr.txt}
├── worktrees/ throwaway git worktrees per firing
└── memory-outbox/<codename>.jsonl reflect / firing_log / note_repo records

$ALFRED_HOME defaults to ~/.alfred. Forks can override it. Worktrees technically sit under $ALFRED_HOME/worktrees/ (a sibling of state/), but every other artifact is a child of state/.

global-blocked-until.json is the fleet-wide rate-limit block. When a Claude-backed agent returns error_rate_limit or error_budget, the runner calls set_global_block(hours=1, reason=...) which writes this file. Every other agent’s is_globally_blocked() check at the top of main() reads it, prints [<AGENT>-GLOBAL-BLOCKED], and exits 0 until the timestamp passes. See Architecture for the rationale.

paused-repos.json is the manual repo pause list. alfred status reads it, set_repo_paused() writes it. Every consumer’s pick_* helper skips paused repos. Missing or malformed file is treated as “no repos paused” (fail-open).

code-map.json is the cross-repo map that code-map-refresh writes every six hours. Drake, Batman, and code-map-aware review prompts read it for repo HEAD SHAs, source files, public-ish symbols, imports, API calls, server routes, and contract drift. It is advisory and local. Safe to delete; the next code-map-refresh firing rebuilds it.

slack-webhook.cache stores the resolved Slack incoming-webhook URL with a 30-day TTL. Lets agents avoid an AWS Secrets Manager round-trip every firing.

_paused/<codename> is a marker file the alfred pause <codename> command writes. The pause survives a deploy.sh re-render, and alfred resume <codename> removes it.

fleet/enabled.txt is the runner-level fleet gate. Listed codenames are enabled; missing codenames fall back to each runner’s default. alfred enable/alfred disable mutates this file.

engines/<codename> is the persisted engine override (claude, codex, or hybrid). alfred engine set writes it. See Engine routing.

<codename>/spend-YYYY-MM-DD.json is the per-agent per-day ledger. Tracks turns_today, cost_usd, consecutive_failures, success counts. Auto-resets at midnight via the filename. The agent’s runner enforces its ceiling and self-pauses if exceeded. Dry-run firings write to a separate spend-dryrun-YYYY-MM-DD.json sibling so they never poison real spend.

<codename>/events/ is a per-firing event log. Each firing writes a structured trail of what it tried, what it claimed, what the engine returned, and how it exited. Used by alfred status and the recap agents.

claims/<repo>-<issue>.json is the local mirror of an in-flight claim when the runner needs to reconcile against the GitHub-side audit comments. The source of truth for the state machine is the structured HTML comment on the issue itself; this file is the local cache.

transcripts/<codename>/<YYYY-MM>/<firing-id>.jsonl is the planned home for full Claude transcripts. The convention is written and the path helpers exist, but the current runner does not write transcripts by default. Codex transcripts under codex/ are written today.

codex/<codename>/<YYYY-MM>/<firing-id>.{last.md,stdout.txt,stderr.txt} is the per-firing Codex artifact bundle. last.md is the final message, stdout.txt and stderr.txt are the captured streams. See Codex provider.

worktrees/eng-<codename>-<repo>-<issue>-<ts>/ is a throwaway git worktree, created by make_worktree and removed at the end of the firing. Surviving worktrees are pruned at the start of the next firing or by agent-cleanup.

memory-outbox/<codename>.jsonl is the append-only outbox the fleet-brain ingest drainer reads. Built-in engine-aware runners now write directly to the configured memory provider, but the outbox remains available for downstream fleets, imports, and tools that want an asynchronous drain path.

What Alfred remembers vs forgets between firings

Section titled “What Alfred remembers vs forgets between firings”
KindSurvives a firingSurvives a rebootSurvives deploy.sh
Per-day spend ledgeryesyesyes
Global rate-limit blockyes (until expiry)yesyes
Repo pause listyesyesyes
Per-codename pause markeryesyesyes
Engine overrideyesyesyes
code-map.jsonyes (until next refresh)yesyes
Transcripts and Codex artifactsyesyesyes
In-flight worktreeno (removed on exit)n/an/a
Process state, in-memory cachesnonon/a
Engine session id from claude -pwritten to the result; not resumedn/an/a
Recalled lessons in Redis Agent Memoryyesyesyes
FleetBrain review and reliability ledgeryesyesyes

The contract is intentionally narrow: operational state is JSON or JSONL on disk, recalled lessons live in Redis Agent Memory, and FleetBrain keeps the local review and reliability ledger. Anything else is reconstructed from GitHub, the repo checkout, or your ~/.alfredrc.

The state files above are operational memory. They tell Alfred what is blocked, what is paused, what spend is left, and which worktree to clean up. They are not where the fleet remembers lessons (repo conventions, recurring bugs, preferred PR style).

That role starts with Redis Agent Memory Server. Engine-aware runners that know their target repo recall a small set of relevant lessons before invoking the engine. If the engine returns a machine-readable memory reflection block, Alfred strips it from the user-facing result and queues those entries as candidates in FleetBrain by default. When ALFRED_AUTO_PROMOTE is armed, an LLM judge saves the safe candidates autonomously instead of waiting on a human queue; otherwise they wait for review. Set ALFRED_MEMORY_REFLECTION_MODE=direct only when direct lesson writes are intentional.

FleetBrain stores recent file touches when an agent or outbox import knows which repo-relative paths changed. Use alfred brain files <repo> to inspect that local history. It also stores reviewable memory candidates and normalized failure events so repeated runtime problems are searchable instead of living only in Slack.

Repeated failures can be grouped with alfred brain failure-patterns and summarized with alfred brain governor. The governor classifies local setup problems, provider limits, auth failures, timeouts, and agent-quality loops, then returns a read-only action list for you and the dashboard.

The default provider chain is redis,fleet: Redis Agent Memory Server handles recalled lessons, and FleetBrain keeps the local review and reliability ledger. Set ALFRED_MEMORY_PROVIDERS=null to disable runtime recall and reflection, or ALFRED_MEMORY_PROVIDERS=redis,fleet,gbrain to add a read-only personal knowledge base behind the default stack. See docs/MEMORY_PROVIDERS.md for the provider chain.

The memory-harvest.py scheduled wrapper runs the same safe loop as memory harvest now: repeated failure patterns become reviewable candidates, not trusted lessons. Slack remains the review surface for memory and the approve/reject actions.

Use alfred brain doctor for a read-only health check, alfred brain governor for the current action queue, and alfred mcp serve when a local MCP client needs read-only memory access.

FleetBrain is dependency-inverted on a Store Protocol, so operational storage can change without touching agent runners. Runtime lesson recall goes through the memory provider chain, with Redis Agent Memory first by default.

Everything in this tree is local to your machine. Nothing in Alfred transmits state files, transcripts, lessons, or spend ledgers off-host. The only outbound channels are:

  • The configured engine (claude -p or codex exec), which sends the prompt you compose to Anthropic or OpenAI on your existing CLI auth.
  • The GitHub CLI (gh), which talks to GitHub on your existing gh auth login token.
  • The Slack incoming webhook, when configured.

If you delete $ALFRED_HOME/, you delete every byte Alfred remembers about your fleet. Treat the directory the way you treat your shell history: it is your data, not fleet data, and never leaves the host unless you put it somewhere yourself.