An AI coding agent starts every session with no memory of the previous one. Whatever the last session learned - the plan step it finished, the constraint it discovered, the bug it already shipped and fixed once - is gone when the context window closes, and the next session starts from the repository alone. The cost is not just re-reading files: it is re-deciding things that were already decided, without the evidence that decided them.
This page shows that cost concretely. Two real headless Claude Code sessions
were given the identical prompt - continue where we left off - in the
identical repo, against the same model. The only difference is whether Seamless
is installed. Without it, the agent finds a TODO comment, infers the task, and
ships an in-process rate limiter - the exact per-instance bug a recorded memory
warns about, because behind a load balancer each instance only counts its own
slice of traffic. With it, the session opens with an injected briefing: the
plan is 4/6 done, one step is claimable, and the rate-limit-not-in-memory
gotcha is one memory_read away at the moment it matters.
Seamless is a local-first memory and coordination substrate for coding agents: persistent memory, dependency-aware tasks, and shared plans, stored as markdown files you own and indexed by one local daemon. The transcripts below are the recorded sessions, unedited - whole steps are collapsed into fast-forward markers, but no line is reworded. The session id is on each pane.
promptcontinue where we left off
without Seamless
headless Claude Code, session 5c514c38-f6b7-4112-a7d4-0c89be07e85f
I don't have persisted memory of the prior session (no memory index exists yet), and the working tree is clean at the initial scaffold commit. So let me go by what the code itself marks as unfinished. There's exactly one explicit pending item — the TODO in auth.go:13:
this endpoint has no rate limit... Add a limiter before the token lookup.
That's the clear "left off" thread. Let me confirm the build is green, then implement it.
Confirmed working end-to-end: the first 5 requests pass the limiter (reaching the token lookup → 401 for the missing cookie), and requests 6–8 are throttled with 429.
Outcome. No memory to stand on. Ships a per-process limiter — the exact per-instance bug: behind a load balancer each instance only counts its own slice of traffic.
with Seamless
headless Claude Code, session 52a41f8a-0bad-4d9e-89aa-3ea7913bb9f4
I'll check where we left off on the auth-refresh plan.
The claimable step is "Rate-limit POST /auth/refresh (per-IP and per-family)". Let me read the plan note for acceptance criteria and check the relevant code.
Let me claim the step, read the plan note, and check the relevant memory + code in parallel.
Now wire the store in main, with a loud warning that the in-memory store is single-instance only:
Done. Step 5 of the auth-refresh plan is complete and committed to the plan's task/note trail. The plan is now 5/6, and the final step is unblocked.
Outcome. The briefing hands it step 5 and the rate-limit-not-in-memory gotcha. Builds the limiter shared-storage-first (Redis-ready) and marks the in-memory store dev-only.
real sessions against a seeded demo instance — transcripts verbatim, only the typing is animated
The memory file that made the difference
The with-side agent did not get lucky. rate-limit-not-in-memory was recorded
by an earlier session, and it is a plain markdown file on disk - the SQLite
index could vanish and this would not:
---
id: 01JZFJ4S6M3T9BWKS60AQNDAA
kind: gotcha
name: rate-limit-not-in-memory
description: In-memory rate limit on the refresh endpoint resets per instance; use shared storage.
project: myapp
created: 2026-07-08T14:21:07Z
updated: 2026-07-08T14:21:07Z
valid_from: 2026-07-08T14:21:07Z
invalid_at: null
superseded_by: null
source_session: cc/1a2b3c4d
---
A rate limiter kept in a process map only sees one instance's traffic. myapp
runs several instances behind the load balancer, so an attacker's requests fan
out across them and each instance sees a fraction of the limit -- the endpoint
is effectively unthrottled. Keep the counter in shared storage (Redis) keyed by
IP and token family, with a short sliding window.
Two things carry the weight here. The description is the only line the
session-start briefing shows, so it is written to be recognized in an index;
the body is what memory_read returns at the moment of action, and it names
the failure mode, the reason, and the fix. And because the file is the source
of truth - not an opaque database - you can read it, edit it, and git diff
it like anything else you own. How memory works
covers the lifecycle; write good memories
covers the craft.
How to reproduce this
The fixture is in the repo. Seed a throwaway instance with exactly this state -
the myapp project, its nine memories, and the auth-refresh plan at 4/6:
git clone https://github.com/0spoon/seamless && cd seamless
go run ./cmd/demoseed -scenes -data /tmp/seamless-demo -repo /path/to/your/test/repo
SEAMLESS_DATA_DIR=/tmp/seamless-demo go run ./cmd/seamlessd serve
The myapp source itself was a small fictional Go auth service (it is not
committed; any repo with an obvious unfinished thread works). Run your agent in
the mapped repo twice with the same prompt: once vanilla, once with the
Claude Code hooks installed, and diff what comes back.
For a real setup, start at the quickstart.