@tekmidian/pai 0.8.0 → 0.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ARCHITECTURE.md CHANGED
@@ -1,4 +1,4 @@
1
- # PAI Knowledge OS — Architecture
1
+ # PAI Knowledge OS — Architecture (v0.8.0)
2
2
 
3
3
  Technical reference for PAI's architecture, database schema, CLI commands, and development setup.
4
4
 
@@ -151,7 +151,7 @@ If both commands return healthy output, PAI is running. Open a new Claude Code s
151
151
 
152
152
  ## MCP Server
153
153
 
154
- PAI exposes 9 tools, 18 on-demand prompts (skills), and 11 reference resources to Claude Code via a daemon-backed MCP shim. The shim speaks stdio (what Claude Code expects) and proxies each request to the background daemon over NDJSON on a Unix socket.
154
+ PAI exposes 9 tools, 19 on-demand prompts (skills), and 11 reference resources to Claude Code via a daemon-backed MCP shim. The shim speaks stdio (what Claude Code expects) and proxies each request to the background daemon over NDJSON on a Unix socket.
155
155
 
156
156
  ```
157
157
  Claude Code (stdio)
@@ -207,6 +207,7 @@ The MCP server registers 18 prompts that Claude can invoke as on-demand skills.
207
207
  | `name` | Session and project naming conventions |
208
208
  | `observability` | Observation system usage and querying |
209
209
  | `plan` | Forward-looking planning from TODOs and recent activity |
210
+ | `reconstruct` | Retroactively create session notes from JSONL transcripts and git history |
210
211
  | `research` | Structured research methodology |
211
212
  | `review` | Retrospective review of work over a time period |
212
213
  | `route` | Session note routing across projects |
@@ -467,6 +468,8 @@ The PAI daemon is a persistent background service that handles indexing, embeddi
467
468
  - Proxies all MCP tool calls from the shim to PostgreSQL
468
469
  - Re-indexes all active projects on a configurable interval (default: every 5 minutes)
469
470
  - Generates text embeddings asynchronously using Snowflake Arctic Embed (768-dim)
471
+ - Processes the persistent work queue: session summaries, topic detection, note updates
472
+ - Spawns headless Claude CLI processes for AI-powered session summarization
470
473
 
471
474
  ### Configuration
472
475
 
@@ -497,6 +500,62 @@ The daemon runs under the label `com.pai.pai-daemon`. The plist is installed to
497
500
 
498
501
  ---
499
502
 
503
+ ## Work Queue and Session Summary Pipeline
504
+
505
+ The daemon owns a persistent work queue (`~/.config/pai/work-queue.json`) that decouples hook triggers from actual work. Hooks push lightweight work items to the queue and exit immediately. The daemon processes items sequentially from a background worker loop.
506
+
507
+ ### Work Item Types
508
+
509
+ | Type | Who enqueues | Who processes | Description |
510
+ |------|-------------|---------------|-------------|
511
+ | `session-summary` | PreCompact, Stop hooks | `session-summary-worker.ts` | AI-powered summarization of JSONL transcript + git history |
512
+ | `topic-detect` | PreCompact hook | `topic-detect-worker.ts` | BM25-based topic shift detection for note splitting |
513
+ | `session-end` | Stop hook | `work-queue-worker.ts` | General session cleanup coordination |
514
+ | `note-update` | Session summary worker | `work-queue-worker.ts` | Write or update a session note file |
515
+ | `todo-update` | Session summary worker | `work-queue-worker.ts` | Update TODO.md with session state |
516
+
517
+ Work items are retried with exponential backoff (default max 3 attempts). The queue is written atomically (write temp file, then rename) to prevent corruption on daemon restart.
518
+
519
+ ### Session Summary Pipeline
520
+
521
+ ```
522
+ Stop or PreCompact hook fires
523
+
524
+ ├── Hook reads minimal data (session_id, transcript_path, cwd)
525
+ ├── Hook pushes { type: "session-summary", payload: {...} } to work queue
526
+ └── Hook exits (sub-second)
527
+
528
+ ⬇ Daemon worker loop picks up the item
529
+
530
+ session-summary-worker.ts
531
+
532
+ ├── Reads JSONL transcript (500K limit for stop, 200K for compact)
533
+ ├── Reads recent git log (last 20 commits)
534
+ ├── Strips ANTHROPIC_API_KEY from environment
535
+ ├── Spawns headless Claude CLI (Opus for stop, Sonnet for compact)
536
+ ├── Prompt requests: TOPIC: line + Work Done / Key Decisions / Known Issues / Next Steps
537
+ ├── Compares TOPIC: against existing note title (Jaccard similarity < 30% → new note)
538
+ └── Writes or updates session note in project's Notes directory
539
+
540
+ ⬇ If topic-detect was also enqueued
541
+
542
+ topic-detect-worker.ts
543
+
544
+ ├── Extracts recent user messages from JSONL
545
+ ├── Runs BM25 topic shift detector against PAI memory DB
546
+ └── Records topic boundary marker (used by next session-summary run)
547
+ ```
548
+
549
+ ### Cooldown and Force Flags
550
+
551
+ A 30-minute cooldown prevents redundant summary updates during active sessions. The Stop hook sets a `force: true` flag to bypass the cooldown, ensuring the final session state is always written. The PreCompact hook respects the cooldown to avoid O(n) summarizations during rapid compaction cycles.
552
+
553
+ ### Claude Binary Discovery
554
+
555
+ The daemon runs under launchd with a minimal PATH. The `findClaudeBinary()` function checks `~/.local/bin/claude` first, then falls back to standard PATH resolution. This handles the common case where Claude CLI is installed via the npm global prefix, which launchd does not include in its environment PATH.
556
+
557
+ ---
558
+
500
559
  ## Obsidian Bridge
501
560
 
502
561
  PAI can expose your project memory as an Obsidian vault. The vault contains no actual files — only symlinks into each project's `Notes/` directory, so edits in Obsidian are immediately visible to PAI and vice versa.
@@ -583,21 +642,22 @@ Claude Code Event
583
642
  | Hook | Event | Purpose |
584
643
  |------|-------|---------|
585
644
  | `load-core-context.mjs` | SessionStart | Loads PAI skill system and core configuration |
586
- | `load-project-context.mjs` | SessionStart | Detects project, loads notes dir, TODO, session note |
645
+ | `load-project-context.mjs` | SessionStart | Detects project, loads notes dir, TODO, session note; auto-registers new projects from .git, package.json, pubspec.yaml, and other signals |
587
646
  | `initialize-session.mjs` | SessionStart | Creates numbered session note, registers in PAI registry |
588
647
  | `post-compact-inject.mjs` | SessionStart (compact) | Reads saved state and injects into post-compaction context |
589
648
  | `security-validator.mjs` | PreToolUse (Bash) | Validates shell commands against security rules |
590
649
  | `capture-all-events.mjs` | All events | Observability — logs every hook event to session timeline |
591
650
  | `observe.mjs` | PostToolUse | Classifies tool calls into typed observations (decision/bugfix/feature/refactor/discovery/change) |
592
651
  | `inject-observations.mjs` | SessionStart | Injects recent observation context (compact index + timeline) |
593
- | `context-compression-hook.mjs` | PreCompact | Extracts session state, saves checkpoint, writes temp file for relay |
652
+ | `context-compression-hook.mjs` | PreCompact | Extracts session state, saves checkpoint, pushes session-summary work item to daemon |
594
653
  | `capture-tool-output.mjs` | PostToolUse | Records tool inputs/outputs for observability dashboard |
595
654
  | `update-tab-on-action.mjs` | PostToolUse | Updates terminal tab title based on current activity |
596
655
  | `sync-todo-to-md.mjs` | PostToolUse (TodoWrite) | Syncs Claude's internal TODO list to `Notes/TODO.md` |
597
656
  | `cleanup-session-files.mjs` | UserPromptSubmit | Cleans up stale temp files between prompts |
598
657
  | `update-tab-titles.mjs` | UserPromptSubmit | Sets terminal tab title from session context |
599
- | `stop-hook.mjs` | Stop | Writes work items to session note, sends notification |
600
- | `capture-session-summary.mjs` | SessionEnd | Final session summary written to session note |
658
+ | `whisper-rules.mjs` | UserPromptSubmit | Injects critical operating rules on every prompt; rules survive compaction and /clear |
659
+ | `stop-hook.mjs` | Stop | Pushes session-summary work item to daemon queue, sends notification |
660
+ | `capture-session-summary.mjs` | SessionEnd | Pushes session-summary work item to daemon queue |
601
661
  | `subagent-stop-hook.mjs` | SubagentStop | Captures sub-agent completion for observability |
602
662
 
603
663
  ### Context Preservation Relay
@@ -942,8 +1002,14 @@ src/
942
1002
  │ ├── daemon/ # Daemon server internals
943
1003
  │ │ ├── dispatcher.ts # Tool dispatch (zettel, observation, memory)
944
1004
  │ │ ├── handler.ts # NDJSON request handler
945
- │ │ └── server.ts # Socket server
946
- │ ├── indexer/ # Background index scheduler
1005
+ │ │ ├── scheduler.ts # Background index scheduler
1006
+ ├── server.ts # Socket server
1007
+ │ │ ├── state.ts # Shared daemon state
1008
+ │ │ └── types.ts # Shared type definitions
1009
+ │ ├── session-summary-worker.ts # AI-powered session summarization (Opus/Sonnet)
1010
+ │ ├── topic-detect-worker.ts # BM25-based topic shift detection
1011
+ │ ├── work-queue-worker.ts # Generic work item processor
1012
+ │ ├── work-queue.ts # Persistent file-backed work queue
947
1013
  │ ├── config.ts # Runtime configuration
948
1014
  │ └── index.ts # Daemon entry point
949
1015
  ├── daemon-mcp/
@@ -954,12 +1020,14 @@ src/
954
1020
  │ └── index.ts # MCP shim entry point (stdio → socket)
955
1021
  ├── hooks/
956
1022
  │ └── ts/ # TypeScript hook sources by event
957
- │ ├── PreCompact/
958
- │ ├── PreToolUse/
959
- │ ├── PostToolUse/
960
- │ ├── SessionStart/
961
- │ ├── Stop/
962
- └── UserPromptSubmit/
1023
+ │ ├── pre-compact/ # context-compression-hook.ts
1024
+ │ ├── pre-tool-use/ # security-validator
1025
+ │ ├── post-tool-use/ # observe, capture-tool-output, sync-todo-to-md, update-tab-on-action
1026
+ │ ├── session-start/ # load-core-context, load-project-context, initialize-session, inject-observations, post-compact-inject
1027
+ │ ├── session-end/ # capture-session-summary
1028
+ ├── stop/ # stop-hook
1029
+ │ ├── subagent-stop/ # subagent-stop-hook
1030
+ │ └── user-prompt/ # cleanup-session-files, update-tab-titles, whisper-rules
963
1031
  ├── mcp/
964
1032
  │ └── tools/ # Shared tool implementations
965
1033
  │ ├── memory.ts
package/FEATURE.md CHANGED
@@ -28,14 +28,19 @@ different direction: persistent memory, session continuity, and deep Claude Code
28
28
  | **Persistent session memory** | No | Yes — auto-indexed, 449K+ chunks |
29
29
  | **Session registry** | No | Yes — SQLite, tracks 77+ projects |
30
30
  | **Background daemon** | No | Yes — launchd, IPC via Unix socket |
31
- | **MCP server** | No | Yes — 9 tools, 18 prompts, 11 resources exposed to Claude Code |
31
+ | **MCP server** | No | Yes — 9 tools, 19 prompts, 11 resources exposed to Claude Code |
32
32
  | **Keyword search (BM25)** | No | Yes — GIN full-text index, PostgreSQL |
33
33
  | **Semantic search (vector)** | No | Yes — pgvector HNSW, Snowflake Arctic 768-dim |
34
34
  | **Multi-backend storage** | No | Yes — SQLite (simple) or PostgreSQL (full) |
35
35
  | **Obsidian vault bridge** | No | Yes — symlinks + auto-generated topic pages |
36
36
  | **Project lifecycle** | No | Yes — promote, archive, move, detect from cwd |
37
+ | **Auto project registration** | No | Yes — detects .git, package.json, pubspec.yaml, etc. on session start |
37
38
  | **Setup wizard** | No | Yes — idempotent 14-step interactive wizard |
38
- | **Hook system** | No | Yes — pre-compact, session-stop, auto-cleanup |
39
+ | **Hook system** | No | Yes — pre-compact, session-stop, auto-cleanup, whisper rules |
40
+ | **Automatic session notes** | No | Yes — AI-generated via daemon worker (Opus/Sonnet), topic-based splitting |
41
+ | **Topic-based note splitting** | No | Yes — Jaccard similarity detects topic shifts, creates separate notes |
42
+ | **Whisper rules** | No | Yes — injects critical rules on every prompt, survives compaction and /clear |
43
+ | **Session note reconstruction** | No | Yes — /reconstruct skill retroactively creates notes from JSONL + git history |
39
44
  | **Backup / restore** | No | Yes — timestamped pg_dump + registry export |
40
45
  | **Multi-session concurrency** | n/a | Yes — daemon multiplexes Claude sessions |
41
46
  | **Custom statusline** | No | Yes — model, MCPs, context meter, colors |
@@ -6,7 +6,7 @@ Technical reference for PAI's modular plugin system, cross-platform support, use
6
6
 
7
7
  ## Overview
8
8
 
9
- PAI is structured as a modular plugin system with 8 named modules organized into 3 pricing tiers. The architecture supports Claude Code (full integration), Cursor (MCP only), and Gemini CLI (MCP only).
9
+ PAI is structured as a modular plugin system with 8 named modules organized into 3 pricing tiers. The architecture supports Claude Code (full integration), Cursor (MCP only), and Gemini CLI (MCP only). Current version: 0.8.0.
10
10
 
11
11
  ```
12
12
  PAI Knowledge OS
@@ -54,24 +54,24 @@ Each module has a `plugins/<module>/plugin.json` that declares:
54
54
 
55
55
  | Module | Tier | Hooks | Skills | Description |
56
56
  |--------|------|-------|--------|-------------|
57
- | `core` | free | 6 | 3 | Memory engine, sessions, projects, security |
58
- | `productivity` | free | 2 | 6 | Plan, Review, Journal, Research, Share, Createskill |
59
- | `ui` | free | 2 | 0 | Tab titles, statusline, tab coloring |
57
+ | `core` | free | 6 | 3 | Memory engine, sessions, projects, security, auto-registration |
58
+ | `productivity` | free | 2 | 7 | Plan, Review, Journal, Research, Share, Createskill, Reconstruct |
59
+ | `ui` | free | 3 | 0 | Tab titles, statusline, tab coloring, whisper rules |
60
60
  | `context-preservation` | free | 3 | 0 | Context compression and relay |
61
61
  | `semantic-search` | pro | 0 | 0 | pgvector, reranking, hybrid search |
62
- | `observability` | pro | 13 | 2 | Event capture, classification, summaries |
62
+ | `observability` | pro | 13 | 2 | Event capture, classification, AI-powered session summaries, topic detection |
63
63
  | `zettelkasten` | enterprise | 0 | 5 | Graph operations, vault intelligence |
64
64
  | `creative` | enterprise | 0 | 2 | Art direction, story, voice/prosody |
65
65
 
66
66
  ### Hook Distribution
67
67
 
68
- Total: 26 hook registrations across 6 modules.
68
+ Total: 27 hook registrations across 6 modules.
69
69
 
70
- **Core (6):** load-core-context, load-project-context, initialize-session, security-validator, stop-hook, pai-session-stop.sh
70
+ **Core (6):** load-core-context, load-project-context (with auto-registration), initialize-session, security-validator, stop-hook, pai-session-stop.sh
71
71
 
72
72
  **Productivity (2):** sync-todo-to-md, cleanup-session-files
73
73
 
74
- **UI (2):** update-tab-titles, update-tab-on-action
74
+ **UI (3):** update-tab-titles, update-tab-on-action, whisper-rules
75
75
 
76
76
  **Context Preservation (3):** context-compression-hook, pai-pre-compact.sh, post-compact-inject
77
77
 
@@ -79,11 +79,11 @@ Total: 26 hook registrations across 6 modules.
79
79
 
80
80
  ### Skill Distribution
81
81
 
82
- Total: 18 skills across 5 modules.
82
+ Total: 19 skills across 5 modules.
83
83
 
84
84
  **Core (3):** Sessions, Route, Name
85
85
 
86
- **Productivity (6):** Plan, Review, Journal, Research, Share, Createskill
86
+ **Productivity (7):** Plan, Review, Journal, Research, Share, Createskill, Reconstruct
87
87
 
88
88
  **Observability (2):** Observability, SearchHistory
89
89
 
@@ -162,9 +162,9 @@ Claude Code gets the complete PAI experience:
162
162
  |------------|---------|
163
163
  | MCP Tools (9) | Full |
164
164
  | MCP Resources (11) | Full |
165
- | MCP Prompts (18) | Full |
166
- | Hooks (26 registrations) | Full |
167
- | Skills (18 SKILL.md stubs) | Full |
165
+ | MCP Prompts (19) | Full |
166
+ | Hooks (27 registrations) | Full |
167
+ | Skills (19 SKILL.md stubs) | Full |
168
168
  | Statusline | Full |
169
169
  | Tab management | Full |
170
170
 
@@ -342,16 +342,31 @@ No migration needed. The plugin architecture is purely additive:
342
342
 
343
343
  ## Future Roadmap
344
344
 
345
- ### Phase 1 (v0.7.0 — Current)
345
+ ### Phase 1 (v0.7.0 — Implemented)
346
346
  - Module manifest system
347
347
  - Cross-platform manifests
348
348
  - User extension points
349
349
  - Tier annotations (no enforcement)
350
350
 
351
- ### Phase 2 (v0.8.0)
351
+ ### Phase 2 (v0.8.0 — Implemented)
352
+ - AI-powered session notes via daemon work queue
353
+ - Topic-based note splitting (Jaccard similarity)
354
+ - Whisper rules hook (persistent rule injection)
355
+ - Reconstruct skill (retroactive session note creation)
356
+ - API key stripping for cost-safe headless Claude spawning
357
+
358
+ ### Phase 3 (v0.9.0)
352
359
  - `pai plugins list` — show installed modules and tiers
353
360
  - `pai plugins enable/disable <module>` — selective module activation
354
- - Build system reads `pai-plugin.json` to generate platform manifests
361
+ - License validation system
362
+ - `pai license activate <key>` command
363
+ - Graceful tier gating with upgrade prompts
364
+
365
+ ### Phase 4 (v1.0.0)
366
+ - Plugin marketplace integration
367
+ - Third-party plugin support
368
+ - Plugin dependency resolution
369
+ - Community plugin repository
355
370
 
356
371
  ### Phase 3 (v0.9.0)
357
372
  - License validation system
package/README.md CHANGED
@@ -1,8 +1,27 @@
1
- # PAI Knowledge OS
1
+ # PAI Knowledge OS — v0.8.0
2
2
 
3
- Claude Code has a memory problem. Every new session starts cold — no idea what you built yesterday, what decisions you made, or where you left off. You re-explain everything, every time. PAI fixes this.
3
+ Claude Code has a memory problem. Every new session starts cold — no idea what you built yesterday, what decisions you made, or where you left off. PAI fixes this.
4
4
 
5
- Install PAI and Claude remembers. Ask it what you were working on. Ask it to find that conversation about the database schema. Ask it to pick up exactly where the last session ended. It knows.
5
+ ## Automatic Session Notes by Topic
6
+
7
+ PAI's headline feature: **every session is automatically documented.** No manual note-taking, no "pause session" commands, no forgetting to save what you did.
8
+
9
+ When you work, a background daemon watches your session **continuously**. Every time Claude's context compacts — which happens automatically as the conversation grows — the daemon reads the JSONL transcript, combines it with your git history, and spawns a headless Claude process to write a structured session note. Not just at session end. Midway through your work, while you're still coding. The notes build up in real time as you go — what was built, what decisions were made, what problems were hit, what's left to do.
10
+
11
+ **When you change topics mid-session, PAI creates a new note.** If you start the day debugging audio, then pivot to a Flutter rewrite, you get two notes — not one giant file mixing unrelated work:
12
+
13
+ ```
14
+ Notes/2026/03/
15
+ 0001 - 2026-03-23 - Phase 1 Research and Architecture.md
16
+ 0002 - 2026-03-24 - Background Audio and iOS Conflicts.md
17
+ 0003 - 2026-03-24 - Flutter Rewrite with Whisper.md ← auto-split, same day
18
+ ```
19
+
20
+ Topic detection uses Jaccard word similarity between the new summary's topic and the existing note's title. Below 30% overlap = new note.
21
+
22
+ **Model tiering:** Opus for final session summaries (best quality, runs once). Sonnet for mid-session checkpoints (good quality, runs on compaction). All using your Max plan — no API charges.
23
+
24
+ This is not a template or a skeleton. These are real notes with build error chronologies, architectural decisions with rationale, code snippets, and "what was tried and failed" sections. The kind of notes you'd write yourself if you had time.
6
25
 
7
26
  ---
8
27
 
@@ -56,6 +75,7 @@ Install PAI and Claude remembers. Ask it what you were working on. Ask it to fin
56
75
  - "Go" — reads your TODO.md continuation prompt and picks up exactly where the last session stopped
57
76
  - "What was I working on?" — progressive context injection loads recent observations at session start
58
77
  - "Continue the daemon refactor" — session summaries give Claude full context without re-explaining
78
+ - "/reconstruct" — retroactively creates session notes from JSONL transcripts and git history when automatic capture missed a session
59
79
 
60
80
  ### Keeping Things Safe
61
81
 
@@ -114,15 +134,59 @@ PAI runs hooks at every stage of a Claude Code session:
114
134
 
115
135
  | Event | What PAI Does |
116
136
  |-------|--------------|
117
- | **Session Start** | Loads project context, detects which project you're in, creates a session note |
118
- | **User Prompt** | Cleans up temp files, updates terminal tab titles |
119
- | **Pre-Compact** | Saves session state checkpoint, sends notification |
137
+ | **Session Start** | Loads project context, detects which project you're in, auto-registers new projects, creates a session note |
138
+ | **User Prompt** | Cleans up temp files, updates terminal tab titles, injects whisper rules on every prompt |
139
+ | **Pre-Compact** | Saves session state checkpoint, pushes `session-summary` work item to daemon, sends notification |
120
140
  | **Post-Compact** | Injects preserved state back into Claude's context |
121
141
  | **Tool Use** | Classifies tool calls into structured observations (decision/bugfix/feature/refactor/discovery/change) |
122
- | **Session End** | Summarizes work done, finalizes session note |
123
- | **Stop** | Writes work items to session note, sends notification |
142
+ | **Session End** | Pushes `session-summary` work item to daemon for AI-powered note generation |
143
+ | **Stop** | Pushes `session-summary` work item to daemon, sends notification |
144
+
145
+ All hooks are TypeScript compiled to `.mjs` modules. They run as separate processes and communicate via stdin (JSON input from Claude Code) and stdout (context injection back into the conversation). Hooks are thin relays — they capture minimal data and immediately push work items to the daemon queue, which handles all heavy processing asynchronously.
146
+
147
+ ---
148
+
149
+ ## Automatic Session Notes
150
+
151
+ PAI automatically writes structured session notes after every session ends — no manual journaling required. The daemon spawns a headless Claude CLI process (using your Max plan, not the API) to summarize the JSONL conversation transcript combined with recent git history.
152
+
153
+ ### What Gets Generated
154
+
155
+ Each session note contains:
156
+
157
+ - **Work Done** — concrete description of what was accomplished
158
+ - **Key Decisions** — choices made and their rationale
159
+ - **Known Issues** — bugs found, blockers, or open questions
160
+ - **Next Steps** — where to pick up in the next session
161
+
162
+ The summarizer uses tiered model selection based on the trigger:
163
+
164
+ | Trigger | Model | Timeout | JSONL Limit |
165
+ |---------|-------|---------|-------------|
166
+ | Session end (Stop hook) | Opus | 5 minutes | 500K bytes |
167
+ | Auto-compaction (PreCompact hook) | Sonnet | 2 minutes | 200K bytes |
168
+
169
+ ### Topic-Based Note Splitting
124
170
 
125
- All hooks are TypeScript compiled to `.mjs` modules. They run as separate processes, communicate via stdin (JSON input from Claude Code) and stdout (context injection back into the conversation).
171
+ When a session covers multiple distinct topics, PAI creates separate notes rather than one long note for the whole session. The summarizer outputs a `TOPIC:` line describing the subject of the current work. PAI compares this against the existing note title using Jaccard word similarity when similarity falls below 30%, a new note is created automatically.
172
+
173
+ Notes within the same day are numbered sequentially: `0042 - 2026-03-24 - Session Name.md`, `0043 - 2026-03-24 - Different Topic.md`, and so on.
174
+
175
+ ### One Note Per Session
176
+
177
+ Each compaction within a session updates the existing note rather than creating a new one. The 30-minute cooldown between summaries prevents redundant updates. Stop hook triggers bypass the cooldown with a force flag to ensure the final state is always captured.
178
+
179
+ ### Garbage Title Filter
180
+
181
+ Session note titles are validated before creation. Over 20 patterns are rejected, including: task notification strings, `[object Object]`, hex hashes, bare numbers, and other non-descriptive artifacts that can appear in session transcripts. Titles must describe actual work done and are capped at 60 characters.
182
+
183
+ ### Finding the Claude Binary
184
+
185
+ The daemon runs under launchd with a minimal PATH that does not include `~/.local/bin/`. PAI resolves the Claude CLI binary by checking `~/.local/bin/claude` first, then falling back to PATH lookup, before spawning headless summarization processes.
186
+
187
+ ### Stripping the API Key
188
+
189
+ When spawning headless Claude CLI processes for summarization, the daemon strips `ANTHROPIC_API_KEY` from the subprocess environment. This forces the spawned process to authenticate via your Max plan (free) rather than using the API key (billable). Without this, every automatic session note would incur API charges.
126
190
 
127
191
  ---
128
192
 
@@ -187,6 +251,27 @@ When a session ends, PAI generates a structured summary capturing what was reque
187
251
 
188
252
  ---
189
253
 
254
+ ## Whisper Rules
255
+
256
+ PAI provides a hook that injects user-defined rules into every prompt via `UserPromptSubmit`. Rules survive compaction, `/clear`, and session restarts — they fire on every single turn, making them the most reliable way to enforce behavioral constraints.
257
+
258
+ **PAI ships the mechanism. You provide the rules.** The file `~/.claude/whisper-rules.md` does not exist by default. Use the `/whisper` skill to manage your rules:
259
+
260
+ ```
261
+ /whisper — show current rules
262
+ /whisper add "NEVER send emails" — add a rule
263
+ /whisper remove 3 — remove rule #3
264
+ /whisper list — list with line numbers
265
+ ```
266
+
267
+ Or edit `~/.claude/whisper-rules.md` directly — one rule per line, plain text.
268
+
269
+ **Keep rules focused.** Every rule is injected on every prompt. Too many rules dilute effectiveness and waste tokens. Reserve whisper rules for truly critical constraints that keep getting violated despite being in CLAUDE.md.
270
+
271
+ The pattern is inspired by [Letta's claude-subconscious](https://github.com/letta-ai/claude-subconscious) approach to persistent context injection.
272
+
273
+ ---
274
+
190
275
  ## Auto-Compact Context Window
191
276
 
192
277
  Claude Code can automatically compact your context window when it fills up, preventing session interruptions mid-task. PAI's statusline shows you at a glance whether auto-compact is active.
@@ -3793,7 +3793,7 @@ function cmdLogs(opts) {
3793
3793
  }
3794
3794
  function registerDaemonCommands(daemonCmd) {
3795
3795
  daemonCmd.command("serve").description("Start the PAI daemon in the foreground").action(async () => {
3796
- const { serve } = await import("../daemon-B8pkxhSc.mjs").then((n) => n.t);
3796
+ const { serve } = await import("../daemon-Ds9dTptY.mjs").then((n) => n.t);
3797
3797
  const { loadConfig: lc, ensureConfigDir } = await import("../config-BuhHWyOK.mjs").then((n) => n.r);
3798
3798
  ensureConfigDir();
3799
3799
  await serve(lc());
@@ -8,7 +8,7 @@ import "../indexer-D53l5d1U.mjs";
8
8
  import { t as PaiClient } from "../ipc-client-CoyUHPod.mjs";
9
9
  import { i as ensureConfigDir, o as loadConfig } from "../config-BuhHWyOK.mjs";
10
10
  import "../factory-Ygqe_bVZ.mjs";
11
- import { n as serve } from "../daemon-B8pkxhSc.mjs";
11
+ import { n as serve } from "../daemon-Ds9dTptY.mjs";
12
12
  import "../state-C6_vqz7w.mjs";
13
13
  import "../tools-DcaJlYDN.mjs";
14
14
  import "../detector-jGBuYQJM.mjs";
@@ -1899,7 +1899,7 @@ function computeTopicOverlap(topicA, topicB) {
1899
1899
  return union > 0 ? intersection / union : 0;
1900
1900
  }
1901
1901
  /** Threshold: below this overlap ratio, we consider topics different. */
1902
- const TOPIC_OVERLAP_THRESHOLD = .3;
1902
+ const TOPIC_OVERLAP_THRESHOLD = .15;
1903
1903
  /**
1904
1904
  * Write (or update) the session note with the AI-generated summary.
1905
1905
  *
@@ -3043,4 +3043,4 @@ var daemon_exports = /* @__PURE__ */ __exportAll({ serve: () => serve });
3043
3043
 
3044
3044
  //#endregion
3045
3045
  export { serve as n, daemon_exports as t };
3046
- //# sourceMappingURL=daemon-B8pkxhSc.mjs.map
3046
+ //# sourceMappingURL=daemon-Ds9dTptY.mjs.map