Skip to content

Latest commit

 

History

History
128 lines (99 loc) · 9.27 KB

File metadata and controls

128 lines (99 loc) · 9.27 KB

Architecture — The 4-Layer Model

claude-codestart is built on a deliberate separation of concerns. Understanding the four layers tells you exactly where each piece of your context lives, why, and when it gets loaded.

The layers

┌──────────────────────────────────────────────────────────────┐
│  LAYER 1 — STATIC CORE                                        │
│  File: ~/.claude/CLAUDE.md                                    │
│  Size: ~5–15 KB (~1–4k tokens)                                │
│  Loaded: automatically on every session (Claude Code built-in)│
│  Contains: identity, locked rules, stable project paths       │
│  Changes: rarely (edited by hand when rules evolve)           │
└──────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────┐
│  LAYER 2 — DYNAMIC PULSE      ◄── this is what claude-       │
│  File: ~/.claude-codestart/PULSE.md                           │     codestart provides
│  Size: ~20–100 KB (~5–25k tokens)                             │
│  Loaded: via SessionStart hook (claude-codestart's scope)     │
│  Contains: today's state, recent journal, open loops, live   │
│            git/build/PR state — anything time-sensitive       │
│  Changes: on every session start (rebuilt by build-pulse.sh) │
└──────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────┐
│  LAYER 3 — MANIFEST                                           │
│  Location: a dedicated section in ~/.claude/CLAUDE.md         │
│  Size: ~2–3 KB                                                │
│  Loaded: along with Layer 1                                   │
│  Contains: file tree with one-line summaries of everything   │
│            in your knowledge system                            │
│  Purpose: teaches the LLM WHERE to look when it needs detail │
│  Changes: monthly or when the filesystem layout evolves      │
└──────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────┐
│  LAYER 4 — ON-DEMAND                                          │
│  Tools: Read, Grep, Glob, MCP filesystem, (optional) Mem0    │
│  Loaded: only when the LLM explicitly reaches for detail     │
│  Contains: everything else — the full knowledge base,        │
│            codebase, historical notes, archived data         │
│  Purpose: pay-per-read access to detail the pulse didn't    │
│           fit                                                   │
└──────────────────────────────────────────────────────────────┘

Why four layers?

Because different kinds of information have different update frequencies and different value densities.

  • Identity doesn't change daily → put it in Layer 1 (cheap, stable, auto-loaded).
  • Today's state changes constantly → put it in Layer 2 (rebuilt per session).
  • Filesystem layout teaches the LLM where to look → put it in Layer 3 (cheap, rarely changes).
  • Everything else is too big to preload → put it in Layer 4 (read on demand).

Putting the wrong thing in the wrong layer is the main failure mode:

  • Layer 1 with today's state → stale within hours, expensive to edit.
  • Layer 2 with your whole knowledge base → blows the context budget.
  • Layer 4 with today's state → Claude can't find what it didn't know to ask for.

claude-codestart is specifically the tooling for Layer 2. Layers 1 and 3 you build by hand in your CLAUDE.md. Layer 4 is already built into Claude Code (Read, Grep, etc.).

Token budget

A Claude Sonnet 4.5 session has ~200k tokens of usable context. Here's the rough allocation we recommend:

Layer Budget Rationale
Layer 1 (Static Core) ~5–15k tokens Small and stable. Don't over-stuff it.
Layer 2 (Dynamic Pulse) ~15–25k tokens Big enough for today, small enough to leave room for work.
Layer 3 (Manifest) ~2–3k tokens Tiny pointer list, huge leverage.
Layer 4 (On-demand) N/A Loaded as tool calls; counts against remaining budget.
Working context for actual conversation ~160k tokens What's left after the above.

Hard rule: the Layer 2 pulse should never exceed 25% of your token budget. If it does, you're stuffing things into the pulse that belong in Layer 4 (on-demand). Trim.

The included build-pulse.sh template has a soft cap via CODESTART_MAX_BYTES (default 100 KB ≈ 25k tokens). It will warn in the output if you exceed it but will not refuse to build.

Refresh cadence

Layer When it rebuilds How
Layer 1 When you edit CLAUDE.md Manual
Layer 2 Every session start SessionStart hook runs your build-pulse.sh
Layer 2 (optional) Every 30 min in the background Add a cron job that runs build-pulse.sh
Layer 2 (optional) On filesystem change fswatch on your journal/status dirs
Layer 3 When you add or rearrange major knowledge files Manual
Layer 4 Never — it's always on disk Always current

claude-codestart v0.0.1 ships with SessionStart-only refresh. That's sufficient for the common case because each new session gets a fresh pulse. Cron and fswatch are opt-in add-ons for users who want PULSE.md to stay fresh on disk for inspection or non-Claude consumers.

Important caveat: background rebuilds (cron/fswatch) do NOT update a currently-running session's context. A session's context is captured at startup. To get new data into a running session you must /compact, /clear, or start a new session.

Why not a vector database?

We chose markdown-first for five concrete reasons:

  1. Traceability. Every claim in the pulse is a direct quote from a file. You can grep for it. Vector similarity is opaque — you can't audit what the model "remembered."
  2. Edit-ability. You can edit your pulse sources with any editor, on any machine, with any tool. Vector DBs require a re-indexing step after every change.
  3. Determinism. The same state files always produce the same pulse. Vector retrieval has inherent nondeterminism from approximate nearest neighbor search.
  4. Zero dependencies. Bash + jq. That's it. No daemons, no databases, no cloud services, no API keys to leak.
  5. The LLM is already a markdown reader. Claude is literally trained on markdown. Feeding it well-structured markdown is the minimum-friction interface. Adding a vector DB adds a translation step that you then have to debug.

Vector databases and memory frameworks (Mem0, Letta, Zep) are excellent for passive fact extraction from conversation history — a different use case that claude-codestart does not attempt to solve. If you want both, run them side by side: claude-codestart handles "here is today's state," a memory framework handles "what did Rudy mention three weeks ago that I should remember." They compose cleanly.

Multi-user / SaaS mental model

claude-codestart v0.0.1 is single-user by design. Each installation points at one user's state files.

For multi-tenant systems (a SaaS where every user gets their own warm-start experience), the architecture transfers cleanly:

  • Each user has their own build-pulse.sh script + source files (sandboxed per user)
  • The SessionStart hook becomes a server-side middleware that injects the user's pulse into their chat session
  • PULSE.md becomes a per-user document stored in your user storage layer

The generator logic and the 4-layer model are identical. Only the runtime is different. We may ship a claude-codestart-saas reference implementation in a future release — if that's interesting to you, open an issue.

Further reading