mirror of
https://github.com/shareAI-lab/analysis_claude_code.git
synced 2026-09-21 21:03:38 +08:00
feat: consolidate course into 21 lessons
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
[English](README.md) · [中文](README.zh.md) · [日本語](README.ja.md)
|
||||
|
||||
s01 → ... → s07 → s08 → `s09` → [s10](../s10_system_prompt/) → s11 → ... → s20 → s21 → s22
|
||||
s01 → ... → s07 → s08 → `s09` → [s10](../s10_system_prompt/) → s11 → ... → s20 → s21
|
||||
> *"Compression loses details, keep a layer that doesn't"* — File store + index + on-demand loading, across compactions, across sessions.
|
||||
>
|
||||
> **Harness Layer**: Memory — knowledge that survives compaction and sessions.
|
||||
@@ -146,8 +146,6 @@ def consolidate_memories():
|
||||
# Replace all files with consolidated results
|
||||
```
|
||||
|
||||
CC calls this process **Dream**, with four gates in practice: time interval, scan throttle, session count, file lock. The teaching version simplifies to a file-count threshold.
|
||||
|
||||
### What Memory Stores
|
||||
|
||||
Memory stores information that remains useful across sessions: user preferences, recurring feedback, project background, common entry points, and investigation clues. It focuses on "what will be useful later" and brings that information back through an index plus on-demand loading.
|
||||
@@ -192,90 +190,5 @@ Memory, compression, and tools are all in place. But the system prompt is still
|
||||
|
||||
s10 System Prompt → segments + runtime assembly. Different projects, different tools, different prompts.
|
||||
|
||||
<details>
|
||||
<summary>Deep Dive Into CC Source Code</summary>
|
||||
|
||||
> The following is based on analysis of CC source code under `src/` in `memdir/`, `services/`, `utils/`, `query/`. Line numbers verified against source.
|
||||
|
||||
### Source Code Paths
|
||||
|
||||
| File | Lines | Responsibility |
|
||||
|------|-------|---------------|
|
||||
| `memdir/memdir.ts` | 507 | Core: MEMORY.md definition (`34-38`), memory behavior instructions distinguishing memory/plan/tasks (`199-266`), `loadMemoryPrompt()` three paths (`419-490`) |
|
||||
| `memdir/findRelevantMemories.ts` | 141 | Sonnet side-query memory selection (`18-24` system prompt, `97-122` call logic) |
|
||||
| `memdir/memoryTypes.ts` | 271 | Type definitions, frontmatter fields |
|
||||
| `memdir/memoryScan.ts` | — | Scan .md files, exclude MEMORY.md, read frontmatter, max 200 files, sorted by mtime desc (`35-94`) |
|
||||
| `services/extractMemories/extractMemories.ts` | 615 | Forked agent extraction, restricted permissions, `skipTranscript: true`, `maxTurns: 5` (`371-427`) |
|
||||
| `services/autoDream/autoDream.ts` | 324 | Dream consolidation, four-layer gating (`63-66` defaults, `130-190` gating, `224-233` forked agent) |
|
||||
| `services/SessionMemory/sessionMemory.ts` | 495 | Session-level memory management |
|
||||
| `services/compact/sessionMemoryCompact.ts` | — | Session memory lightweight summary, thresholds 10K/5/40K (`56-61`) |
|
||||
| `utils/attachments.ts` | — | Injection budget: 200 lines / 4096 bytes per file, 60KB per session (`269-288`); find relevant memory by query (`2196-2241`) |
|
||||
| `query.ts` | — | Memory prefetch at start of each user turn (`301-304`), non-blocking collection (`1592-1614`) |
|
||||
| `query/stopHooks.ts` | — | Stop hook fire-and-forget triggers extraction and Dream (`141-155`) |
|
||||
|
||||
### Memory Selection: LLM, Not Embedding
|
||||
|
||||
CC uses **Sonnet itself to select** (`findRelevantMemories.ts`), not embedding vector similarity:
|
||||
|
||||
1. `memoryScan.ts` scans all `.md` files in `.memory/` (excluding MEMORY.md), max 200 files, sorted by mtime descending
|
||||
2. Lists all memory files' `name` + `description` as a catalog
|
||||
3. Sends to Sonnet side-query: "Select truly useful memories by name and description (max 5). Skip if unsure."
|
||||
4. Sonnet returns `{ selected_memories: ["file1.md", ...] }`
|
||||
5. Selected files' full contents are read (≤ 200 lines / 4096 bytes per file) and injected. Total session budget: 60KB
|
||||
|
||||
At the start of each user turn, `query.ts:301-304` starts memory prefetch (async); after tool execution, `1592-1614` collects completed results non-blocking.
|
||||
|
||||
### Extraction Timing: Stop Hook, Not After autoCompact
|
||||
|
||||
Trigger location (`stopHooks.ts:141-155`): inside `handleStopHooks()`, fire-and-forget triggers extraction and Dream. The teaching version places extraction in the `stop_reason != "tool_use"` branch, matching the direction.
|
||||
|
||||
CC's extraction runs via forked agent (`extractMemories.ts:371-427`): restricted permissions, `skipTranscript: true`, `maxTurns: 5`. Also has overlap protection: if the main Agent already wrote memory files, extraction is skipped.
|
||||
|
||||
### Memory File Format
|
||||
|
||||
CC uses Markdown + YAML frontmatter, consistent with the teaching version. Four types: `user`, `feedback`, `project`, `reference`.
|
||||
|
||||
`memdir.ts:34-38` defines index constraints: `MEMORY.md` max 200 lines / 25KB. `memdir.ts:199-266` builds memory behavior instructions, explicitly distinguishing memory from plan and tasks. Storage location: `~/.claude/projects/<sanitized-git-root>/memory/`.
|
||||
|
||||
### Dream: Four-Layer Gating
|
||||
|
||||
Not "triggered when idle" or "consolidate when count is enough", but four gates (`autoDream.ts`, defaults `63-66`, gating logic `130-190`):
|
||||
|
||||
1. **Time gate**: ≥ 24 hours since last consolidation
|
||||
2. **Scan throttle**: Avoid frequent filesystem scans
|
||||
3. **Session gate**: ≥ 5 session transcripts modified since last consolidation
|
||||
4. **Lock gate**: No other process currently consolidating (`.consolidate-lock` file)
|
||||
|
||||
The merge itself runs via forked agent (`224-233`): locate → collect recent signals → merge and write files → prune and update index. Lock file mtime serves as lastConsolidatedAt. Crash recovery: lock auto-expires after 1 hour.
|
||||
|
||||
### User Memory vs Session Memory
|
||||
|
||||
| | User Memory | Session Memory |
|
||||
|---|---|---|
|
||||
| Persistence | Cross-session | Single session |
|
||||
| Storage | Multiple .md files in `memory/` | `session-memory/<id>/memory.md` |
|
||||
| Loaded into | system prompt | compact summary |
|
||||
| Purpose | Cross-session knowledge accumulation | Cross-compact context continuity |
|
||||
|
||||
sessionMemoryCompact (mentioned in s08) uses Session Memory: before autoCompact, it reads the session memory file and, if sufficient (≥ 10K tokens, ≥ 5 text messages, ≤ 40K tokens, `sessionMemoryCompact.ts:56-61`), uses it as a summary without calling the LLM.
|
||||
|
||||
### Where the Real Implementation Is More Complex
|
||||
|
||||
- **Feature flags**: Memory features have multiple feature gate layers
|
||||
- **Team memory**: Shared team memories, `loadMemoryPrompt()` has a dedicated path (not covered in teaching version)
|
||||
- **KAIROS**: Timing-aware memory extraction strategy, daily-log mode in `loadMemoryPrompt()`
|
||||
- **Prompt cache**: Memory injection must account for prompt cache TTL, avoiding full system prompt rewrites each turn
|
||||
- **File locks**: Concurrency control for multi-process scenarios
|
||||
- **Memory prefetch**: Async prefetch, non-blocking main flow
|
||||
|
||||
### Teaching Version Simplifications Are Intentional
|
||||
|
||||
- LLM side-query → LLM side-query + keyword fallback: teaching version keeps LLM selection, adds fallback path
|
||||
- Memory JSON → Markdown + frontmatter: teaching version matches CC
|
||||
- Stop hook trigger → `stop_reason != "tool_use"` branch: same direction
|
||||
- Four-layer gating → file-count threshold: teaching version lacks transcript system and multi-session concepts
|
||||
- Forked agent + restricted permissions → direct call: teaching version has no subprocess isolation
|
||||
|
||||
</details>
|
||||
|
||||
<!-- translation-sync: zh@v1, en@v1, ja@v1 -->
|
||||
|
||||
Reference in New Issue
Block a user