spool-memory 0.2.3

Local-first developer memory system — persistent, structured knowledge for AI coding tools
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
# Session Handoff

## Date

2026-05-16

## Summary

This session landed the wiki-style self-maintaining knowledge loop (7 PRs): auto-compile knowledge pages, wiki INDEX generation, wiki lint, MCP `memory_lint` tool, desktop facade `wiki_lint`/`read_wiki_index`, CLI `memory lint`/`memory sync-index`, selector test split, frontend lint health page, and frontend wakeup INDEX rendering. Subsequent sessions added: MCP sampling reverse-call integration for auto-compile (fire-and-forget via dedicated thread), project-first retrieval scoring (40% cross-project penalty on user/agent/team-scoped candidates when a project is matched), and frontend workbench batch actions.

## Changes This Session

### Wiki-style Knowledge Loop (PR #1)

- Added `src/knowledge/` module: auto-compile knowledge pages from related lifecycle records
- Added `src/wiki_index.rs`: generate and load wiki INDEX.md grouped by scope/project
- Added `src/wiki_lint.rs`: staleness, orphan, and quality lint checks on lifecycle records
- `vault_writer.rs` now routes `memory_type == "knowledge"` to `50-Memory-Ledger/Compiled/`
- `writeback_from_config` chains INDEX refresh + auto-compile after lifecycle writes
- Superseded records excluded from retrieval via `excluded_record_ids_from_scored`

### MCP `memory_lint` Tool (PR #2)

- New MCP tool `memory_lint` exposing wiki lint report as markdown

### Desktop Facade: wiki_lint + read_wiki_index (PR #3)

- `DesktopService::wiki_lint()` — run lint and return markdown report
- `DesktopService::read_wiki_index()` — load INDEX section for a project

### CLI `memory sync-index` (PR #4)

- New CLI command `memory sync-index` to rebuild INDEX.md
- New CLI command `memory lint` to run wiki lint checks

### Selector Test Split (PR #5)

- Refactored `src/engine/selector.rs` tests into `src/engine/selector/tests.rs`
- `src/engine/selector/` is now a directory module (`mod.rs` + `tests.rs`)

### Frontend Lint Health Page (PR #6)

- New frontend page consuming `wiki_lint` DTO from desktop facade

### Frontend Wakeup INDEX Rendering (PR #7)

- Wakeup result page now renders `knowledge_index` section when present

### MCP Sampling Auto-Compile Integration (2026-05-16)

- Fixed auto-compile to fire on a dedicated thread (`std::thread::spawn` + dedicated tokio runtime) so the main MCP dispatch loop is never blocked waiting for the sampling reverse-call round-trip (up to 180 s timeout)
- Added `mcp_lifecycle_write_should_not_block_when_sampling_supported_but_no_cluster` smoke test: single record write, verifies elapsed < 10 s
- Added `mcp_lifecycle_write_should_trigger_sampling_compile_when_cluster_ready` smoke test: writes 3 records with shared entities, proposes+accepts a 4th, harness fulfills sampling reverse-call, verifies a `knowledge` type record appears in pending review

### Project-First Retrieval Scoring (2026-05-16)

- Added `CROSS_PROJECT_PENALTY = 0.6` constant in `src/engine/selector/mod.rs`
- User/agent/team-scoped candidates receive a 40% score reduction when a project is matched, ensuring project-scoped records rank above cross-project ones
- Added two new tests in `src/engine/selector/tests.rs`:
  - `lifecycle_selector_should_apply_cross_project_penalty_when_project_matched`
  - `lifecycle_selector_should_not_apply_cross_project_penalty_without_project`

---

## Previous Session Summary

This session carried `spool` from a read-only lifecycle prototype into a usable local memory review loop, MCP gateway, and first daemon boundary, with a shared lifecycle service, append-only ledger events, latest-state projections, GUI review/history/create actions, broader CLI lifecycle flows, MCP lifecycle/retrieval tools, event-level write provenance metadata, in-process and disk-backed lifecycle projection caching, MCP prompts/resources, GUI metadata-aware create/propose forms, a minimal lifecycle read daemon, and post-integration fixes for daemon-backed reads, MCP resource loading/smoke coverage, plus malformed-JSON hardening on both stdio protocol boundaries.

## Current Status Audit

Audit date: `2026-04-14`

This document is still the best restart point, but some other planning docs now understate current progress.

Current repository status:

- latest implementation baseline has progressed through `Round 12`
- `cargo test` is green across library, CLI smoke, MCP smoke, daemon smoke, and Tauri smoke coverage
- the repository is beyond a routing-only prototype and now has a usable minimum memory lifecycle core
- `docs/ROADMAP.md` and `docs/PRODUCT.md` still describe some already-finished capabilities as future work and should not be used alone to judge implementation status

## What Is Completed

The following product slices are already implemented and verified in code/tests.

### Retrieval And Wakeup Core

- project routing from `cwd`
- scoped vault scanning and heuristic ranking
- multi-format output (`prompt`, `markdown`, `json`)
- wakeup packet generation
- wakeup policy enforcement for suppression / redaction / policy reporting
- shared retrieval gateway reuse across CLI and MCP surfaces
- superseded record exclusion from retrieval (via scored note frontmatter `record_id`)

### Knowledge Loop And Wiki

- wiki-style auto-compile: related lifecycle records → knowledge synthesis pages in `50-Memory-Ledger/Compiled/`
- wiki INDEX generation grouped by scope/project (`src/wiki_index.rs`)
- wiki lint: staleness, orphan, quality checks (`src/wiki_lint.rs`)
- `writeback_from_config` chains INDEX refresh + auto-compile after lifecycle writes
- CLI `memory lint` and `memory sync-index` commands
- MCP `memory_lint` tool
- desktop facade `wiki_lint` and `read_wiki_index` methods
- frontend lint health page and wakeup INDEX rendering
- MCP sampling reverse-call integration: auto-compile now fires on a dedicated thread (fire-and-forget) so the main dispatch loop is never blocked waiting for the sampling round-trip
- `McpSamplingClient` / `StdSamplingChannel` infrastructure for `sampling/createMessage` reverse-calls

### Retrieval Intelligence

- excerpt section-level precision: retrieval returns best-matching sections rather than full note content
- stale-memory hints surfaced in wakeup packet (`maintenance_hints` section)
- project-first retrieval scoring: 40% cross-project penalty (`CROSS_PROJECT_PENALTY = 0.6`) applied to user/agent/team-scoped candidates when a project is matched, ensuring project-scoped records rank above cross-project ones

### Developer Memory Core

- lifecycle domain model for memory records, sources, scope, and states
- append-only local ledger in `memory-ledger.jsonl`
- lifecycle transitions for manual create, AI propose, accept, promote, and archive
- latest-state projection queries
- in-process projection cache
- disk-backed rebuildable projection snapshot
- event-level write provenance metadata (`actor`, `reason`, `evidence_refs`)

### Client Surfaces

- CLI lifecycle commands:
  - `memory list`
  - `memory show`
  - `memory history`
  - `memory record-manual`
  - `memory propose`
  - `memory accept`
  - `memory promote`
  - `memory archive`
  - `memory lint`
  - `memory sync-index`
- MCP lifecycle tools for read/write actions (including `memory_lint`)
- MCP retrieval tools for search / explain / wakeup
- MCP prompts/resources for guided client flows
- MCP sampling reverse-call support (`sampling/createMessage`)
- experimental GUI review workbench with queue/detail/history/create/propose/action flows
- GUI workbench batch actions (accept/archive multiple records at once)
- optional daemon-backed lifecycle reads for CLI and MCP, with direct fallback preserved
- desktop-facing Rust facade in `src/desktop/` for future desktop hosts

### Validation Status

- unit coverage for lifecycle, daemon, desktop, retrieval, and formatting helpers
- smoke coverage for CLI, MCP, daemon, and Tauri-facing desktop flows
- malformed JSON recovery verified on both MCP stdio and daemon stdio boundaries

## What Is Not Completed

The following items remain incomplete or only partially implemented.

### Desktop Product Surface

- a minimal runnable Tauri host is now possible on top of the existing desktop facade and Tauri adapter layer
- a minimal static frontend shell now exists for lifecycle/retrieval flows
- desktop work is still not a finished desktop client and should be treated as an early host/workbench slice

### GUI Lifecycle Scope

- no edit-in-place for memory records
- metadata inputs exist only on create/propose forms, not on lifecycle action buttons

### Retrieval Intelligence

- ranking is still heuristic rather than semantic
- no contradiction detection
- no confidence scoring layer
- no graph-style wikilink traversal
- no large-vault benchmark coverage
- scoring breakdowns are not yet exposed richly enough for all debugging needs

### Memory Ingestion And Distillation

- no transcript importer
- no git importer
- no terminal metadata importer
- no durable extraction pipeline for incident/decision candidates from raw events

### Daemon Scope

- daemon boundary is intentionally narrow and read-only
- write operations still bypass the daemon
- daemon payload shape is still narrower than the richer shared lifecycle summary contract used by CLI/MCP

## Recommended Next Development

Current development should branch from the fact that the memory core exists, while product completion is still uneven.

### High Priority

1. choose whether the next product-facing milestone is:
   - finishing a real desktop host on top of the existing `src/desktop/` boundary, or
   - moving directly into retrieval intelligence work (semantic ranking, contradiction detection)
2. if daemon-backed read surfaces keep growing, align daemon payloads with `src/lifecycle_summary.rs` rather than creating a second response contract

### Recommended Default Path

If the immediate goal is a more usable product, finish the desktop host layer next:

1. convert the existing Tauri-shaped adapter layer into a real runnable host
2. wire a minimal desktop frontend shell to the existing context / wakeup / lifecycle read-write flows
3. keep GUI/Tauri behavior reusing the same lifecycle formatter and summary helpers

If the immediate goal is stronger core quality, move into retrieval intelligence next:

1. improve excerpt selection from best-matching sections
2. expose clearer score breakdowns in machine-readable output
3. add a heavier retrieval index for large vaults only after measuring current bottlenecks
4. evaluate semantic retrieval, contradiction detection, and confidence scoring after index/debuggability work is in place

### Medium Priority

- decide whether lifecycle action buttons should also capture provenance metadata
- design importer boundaries for transcript / git / terminal ingestion without polluting curated Obsidian notes
- keep all new lifecycle presentation logic flowing through `src/lifecycle_format.rs` and `src/lifecycle_summary.rs`

## Restart Guidance

When resuming development, use this status order instead of the older roadmap wording:

1. memory lifecycle core: implemented
2. cross-AI gateway: implemented in minimum viable form
3. optional daemon boundary: implemented for read-side flows
4. desktop client: minimum host/bootstrap slice exists, product surface not finished
5. retrieval intelligence and ingestion pipeline: not yet built

## Product Direction Confirmed

`spool` should evolve into:

- a local-first developer memory operating system
- Obsidian as curated knowledge-of-record
- a separate local ledger for captured session memory
- one retrieval gateway for multiple AI tools
- security and provenance before aggressive compression
- a growth path where manual memory and AI-proposed memory can be reviewed, promoted, archived, and later consumed by multiple clients

Reference docs:

- [PRODUCT.md](/Users/long/Work/spool/docs/PRODUCT.md)
- [ARCHITECTURE.md](/Users/long/Work/spool/docs/ARCHITECTURE.md)
- [OBSIDIAN_SCHEMA.md](/Users/long/Work/spool/docs/OBSIDIAN_SCHEMA.md)
- [ROADMAP.md](/Users/long/Work/spool/docs/ROADMAP.md)
- [PLANNING_ALIGNMENT.md](/Users/long/Work/spool/docs/PLANNING_ALIGNMENT.md)
- [adr/0001-local-developer-memory-os.md](/Users/long/Work/spool/docs/adr/0001-local-developer-memory-os.md)
- [adr/0002-wakeup-packet-v1.md](/Users/long/Work/spool/docs/adr/0002-wakeup-packet-v1.md)

## Code Work Completed

### Wake-up Contract Stabilization

- extracted wakeup policy from the builder
- isolated redaction / suppression / policy summary logic
- kept wakeup rendering stable across json / markdown / prompt modes

Relevant files:

- [src/wakeup_policy.rs](/Users/long/Work/spool/src/wakeup_policy.rs)
- [src/wakeup.rs](/Users/long/Work/spool/src/wakeup.rs)
- [src/output/wakeup.rs](/Users/long/Work/spool/src/output/wakeup.rs)

### Memory Gateway Core

- introduced a minimal shared gateway layer
- continued converging `get`, `explain`, and `wakeup` toward common domain-level orchestration
- kept rendering responsibility outside the core service boundary

Relevant files:

- [src/memory_gateway.rs](/Users/long/Work/spool/src/memory_gateway.rs)
- [src/cli/commands.rs](/Users/long/Work/spool/src/cli/commands.rs)

### Memory Lifecycle Core

- added lifecycle domain primitives:
  - `MemoryScope`
  - `MemorySourceKind`
  - `MemoryLifecycleState`
  - `MemoryPromotionAction`
  - `MemoryLedgerAction`
  - `MemoryRecord`
- added review-aware semantics:
  - manual memory starts as `Accepted`
  - AI proposals start as `Candidate`
  - only `Accepted` / `Canonical` records are wakeup-eligible

Relevant files:

- [src/domain/memory_lifecycle.rs](/Users/long/Work/spool/src/domain/memory_lifecycle.rs)

### Lifecycle Ledger Store

- implemented append-only local ledger storage in jsonl
- file name: `memory-ledger.jsonl`
- supports:
  - `record_manual_memory(...)`
  - `propose_ai_memory(...)`
  - `accept_memory(...)`
  - `promote_memory_to_canonical(...)`
  - `archive_memory(...)`
- transition events reuse the original `record_id`
- invalid lifecycle transitions now fail and do not append dirty audit entries

Relevant files:

- [src/lifecycle_store.rs](/Users/long/Work/spool/src/lifecycle_store.rs)

### Latest-State Projection Layer

Query optimization currently follows the chosen direction: **in-memory projection first**, not persistent indexing.

Added projection-backed reads for:

- latest state by `record_id`
- latest state by `scope` / `scope_key`
- latest state by `state`
- pending review queue
- wakeup-ready queue

This keeps the ledger append-only while reducing repeated query logic.

Relevant files:

- [src/lifecycle_store.rs](/Users/long/Work/spool/src/lifecycle_store.rs)

### GUI Review Workbench Surface

GUI has continued moving from a pure context shell toward a minimal memory workbench.

It now shows:

- `Context`
- `Explain`
- `Pending review`
- `Wakeup-ready`

The review workbench now supports minimum single-record lifecycle actions and refreshes projection-backed views after each successful write.

Relevant files:

- [src/gui/app_shell.rs](/Users/long/Work/spool/src/gui/app_shell.rs)

### Shared Lifecycle Service

- added a shared lifecycle service above `LifecycleStore`
- unified lifecycle reads for:
  - pending review
  - wakeup-ready
  - record lookup by `record_id`
- unified lifecycle actions for:
  - `Accept`
  - `PromoteToCanonical`
  - `Archive`
- GUI and CLI now reuse the same action path instead of each touching the store directly

Relevant files:

- [src/lifecycle_service.rs](/Users/long/Work/spool/src/lifecycle_service.rs)

### GUI Minimum Action Flow

- replaced read-only lifecycle text panes with selectable `Pending review` / `Wakeup-ready` lists
- added a detail pane for the selected memory record
- added minimal single-record actions in GUI:
  - `Accept`
  - `Promote`
  - `Archive`
- after each successful action, GUI refreshes both lifecycle panels and preserves selection when possible

Relevant files:

- [src/gui/app_shell.rs](/Users/long/Work/spool/src/gui/app_shell.rs)

### CLI Lifecycle Surface

- added `spool memory list`
- added `spool memory show`
- added `spool memory history`
- added `spool memory record-manual`
- added `spool memory propose`
- added `spool memory accept`
- added `spool memory promote`
- added `spool memory archive`
- CLI output now covers:
  - create result summary
  - action result summary
  - single-record detail
  - event history

Relevant files:

- [src/cli/args.rs](/Users/long/Work/spool/src/cli/args.rs)
- [src/cli/commands.rs](/Users/long/Work/spool/src/cli/commands.rs)
- [tests/cli_smoke.rs](/Users/long/Work/spool/tests/cli_smoke.rs)

### MCP Lifecycle Surface

- added `spool-mcp` as a minimal stdio MCP server
- added lifecycle MCP read tools:
  - `memory_review_queue`
  - `memory_wakeup_ready`
  - `memory_get`
  - `memory_history`
- added lifecycle MCP write tools:
  - `memory_record_manual`
  - `memory_propose`
  - `memory_accept`
  - `memory_promote`
  - `memory_archive`

Relevant files:

- [src/mcp.rs](/Users/long/Work/spool/src/mcp.rs)
- [src/bin/spool_mcp.rs](/Users/long/Work/spool/src/bin/spool_mcp.rs)
- [tests/mcp_smoke.rs](/Users/long/Work/spool/tests/mcp_smoke.rs)

### MCP Retrieval Gateway Surface

- added retrieval MCP tools on the same server:
  - `memory_search`
  - `memory_explain`
  - `memory_wakeup`
- these tools reuse the existing retrieval / wakeup core rather than duplicating route logic
- MCP now exposes both:
  - lifecycle review operations
  - retrieval / wakeup gateway operations
- resource reads now prefer docs adjacent to the active config, with repository-doc fallback for local smoke/integration paths
- MCP smoke coverage now provisions doc resources explicitly so prompt/resource flows are validated end-to-end
- malformed JSON on the MCP stdio boundary now returns JSON-RPC parse errors and the server continues serving subsequent requests
- lifecycle create/action tool responses now derive their summary fields from a shared lifecycle summary helper instead of hand-assembled per-tool payloads

Relevant files:

- [src/mcp.rs](/Users/long/Work/spool/src/mcp.rs)
- [src/memory_gateway.rs](/Users/long/Work/spool/src/memory_gateway.rs)
- [tests/mcp_smoke.rs](/Users/long/Work/spool/tests/mcp_smoke.rs)
- [src/bin/spool_mcp.rs](/Users/long/Work/spool/src/bin/spool_mcp.rs)
- [src/lifecycle_summary.rs](/Users/long/Work/spool/src/lifecycle_summary.rs)

### Write Provenance Metadata

- added optional event-level metadata on lifecycle writes:
  - `actor`
  - `reason`
  - `evidence_refs`
- preserved compatibility with older ledger entries that do not include metadata
- threaded metadata through:
  - `LifecycleStore`
  - `LifecycleService`
  - CLI write commands
  - MCP write tools
- surfaced metadata in:
  - CLI output
  - MCP structured tool responses
  - GUI lifecycle detail pane
- later refactors also converged repeated lifecycle presentation/summary logic into shared helpers:
  - `src/lifecycle_format.rs` for CLI/GUI state/action labels plus list/detail/history rendering
  - `src/lifecycle_summary.rs` for CLI/MCP create/action summary payloads plus queue/record/history shared payload and text helpers

Relevant files:

- [src/lifecycle_store.rs](/Users/long/Work/spool/src/lifecycle_store.rs)
- [src/lifecycle_service.rs](/Users/long/Work/spool/src/lifecycle_service.rs)
- [src/cli/commands.rs](/Users/long/Work/spool/src/cli/commands.rs)
- [src/mcp.rs](/Users/long/Work/spool/src/mcp.rs)
- [src/gui/app_shell.rs](/Users/long/Work/spool/src/gui/app_shell.rs)
- [src/lifecycle_format.rs](/Users/long/Work/spool/src/lifecycle_format.rs)
- [src/lifecycle_summary.rs](/Users/long/Work/spool/src/lifecycle_summary.rs)

### GUI Operator Console

- added a history pane for the selected lifecycle record
- GUI history now shows event-level metadata when present
- added minimal GUI write forms for:
  - manual memory creation
  - AI proposal creation
- GUI now refreshes:
  - pending review
  - wakeup-ready
  - selected detail
  - selected history
  after create/propose or lifecycle action success
- GUI lifecycle text rendering now shares the same lifecycle formatter module used by CLI for state/action/detail/history labels, while keeping small UI-specific differences (for example summary placement)

Relevant files:

- [src/gui/app_shell.rs](/Users/long/Work/spool/src/gui/app_shell.rs)
- [src/lifecycle_format.rs](/Users/long/Work/spool/src/lifecycle_format.rs)

### Lifecycle Projection Cache

- added in-process projection caching for lifecycle latest-state reads
- cache is keyed by ledger file fingerprint
- cache is invalidated immediately after append
- repeated reads in one process now avoid rebuilding the same projection when the ledger has not changed
- retrieval path remains on the existing vault snapshot cache; no extra retrieval cache was added in this round

Relevant files:

- [src/lifecycle_store.rs](/Users/long/Work/spool/src/lifecycle_store.rs)
- [src/vault/scanner.rs](/Users/long/Work/spool/src/vault/scanner.rs)

### Persistent Projection Snapshot

- added a rebuildable disk-backed lifecycle projection snapshot
- persistent snapshot is only used when its ledger fingerprint matches current source-of-truth state
- corrupted or stale snapshots fall back to direct ledger rebuild
- in-process cache still sits above the persistent snapshot for the cheapest repeated reads

Relevant files:

- [src/lifecycle_store.rs](/Users/long/Work/spool/src/lifecycle_store.rs)

### MCP Prompts And Resources

- added MCP prompts for common flows:
  - lifecycle queue review
  - project wakeup generation
  - project context retrieval
- added MCP read-only resources for:
  - current session handoff
  - current MCP prompts/resources plan
  - restart guide context
- prompts/resources are layered on top of the existing MCP server without changing tool behavior

Relevant files:

- [src/mcp.rs](/Users/long/Work/spool/src/mcp.rs)
- [tests/mcp_smoke.rs](/Users/long/Work/spool/tests/mcp_smoke.rs)

### GUI Metadata Inputs

- added optional GUI inputs for:
  - `actor`
  - `reason`
  - `evidence_refs`
- GUI manual/propose writes now produce the same provenance metadata shape as CLI and MCP
- GUI metadata remains optional and limited to the create/propose form

Relevant files:

- [src/gui/app_shell.rs](/Users/long/Work/spool/src/gui/app_shell.rs)

### Lifecycle Read Daemon

- added `spool-daemon` as a minimal resident-process boundary
- kept the daemon responsibility narrow to read-only lifecycle queries:
  - `ping`
  - `workbench`
  - `record`
  - `history`
- CLI and MCP now have optional daemon-backed read paths with direct fallback; daemon use is not mandatory
- current daemon client behavior now reuses a shared daemon stdio session keyed by `(daemon_bin, config_path)` for repeated reads inside one process
- if that shared session dies, the next request rebuilds it once before falling back, while CLI/MCP still preserve direct fallback if daemon transport remains unavailable
- daemon read helpers and MCP lifecycle read paths now both have explicit tests covering shared-session reuse and rebuild-after-exit behavior
- malformed JSON on the daemon stdio boundary now returns a structured `ok: false` error and the process continues serving subsequent requests

Relevant files:

- [src/daemon.rs](/Users/long/Work/spool/src/daemon.rs)
- [src/bin/spool_daemon.rs](/Users/long/Work/spool/src/bin/spool_daemon.rs)
- [tests/daemon_smoke.rs](/Users/long/Work/spool/tests/daemon_smoke.rs)

### Desktop Facade Boundary

- added `src/desktop.rs` as a pure Rust desktop-facing facade for future Tauri or other desktop shells
- introduced stable desktop DTOs for:
  - context requests/responses
  - wakeup requests/responses
  - workbench / record / history reads
  - manual record / AI propose / lifecycle action writes
  - daemon preference inputs and lifecycle action enums
- added `DesktopErrorEnvelope` so desktop hosts receive classified input/config/routing/scan/runtime failures with hints instead of surface-local ad-hoc strings
- kept desktop orchestration thin by reusing existing shared core layers:
  - `app::run_with_overrides` for context
  - `memory_gateway::execute` for wakeup
  - `read_workbench` / `read_record` / `read_history` for daemon-preferred read flows
  - `LifecycleService` for write flows
- desktop lifecycle responses now prefer the same shared `src/lifecycle_summary.rs` payload helpers already used by CLI/MCP rather than inventing a second desktop-only payload contract
- added focused tests for desktop parsing helpers, validation envelopes, context/wakeup flow, and lifecycle read/write workflow coverage

Relevant files:

- [src/desktop.rs](/Users/long/Work/spool/src/desktop.rs)
- [src/lib.rs](/Users/long/Work/spool/src/lib.rs)
- [CLAUDE.md](/Users/long/Work/spool/CLAUDE.md)

## Key Decisions Made In This Session

1. Do not open too many agents; default to the main agent driving work directly.
2. During the daytime, pause for user input on key architecture or workflow decisions.
3. For lifecycle query optimization, choose **in-memory latest-state projection first**, not persistent indexing.
4. Keep lifecycle actions narrow and append-only:
   - no batch actions
   - no edit-in-place
   - no history rewriting
5. Keep MCP thin and reuse existing app/service layers instead of adding a parallel business core.
6. Defer richer write metadata until all write surfaces are stable enough to carry the same contract.
7. Keep write provenance on ledger events rather than on `MemoryRecord` itself.
8. Keep GUI growth narrow: history + create/propose are acceptable, but batch edit is still out of scope.
9. Prefer the smallest safe cache first: in-process + freshness-checked before disk-backed persistence.
10. Add MCP UX layers after tools, not before them.
11. Keep GUI metadata optional and form-scoped before expanding it to action buttons.
12. Treat persistent caches as rebuildable derivatives, never as new sources of truth.
13. Keep the first daemon boundary read-only and optional.

## Current Working Capabilities

The repository now has a real minimal memory growth loop:

- manual memory write
- AI memory proposal
- append-only lifecycle ledger
- accept / promote / archive transitions
- latest-state projection
- pending review queue
- wakeup-ready queue
- shared lifecycle service for GUI / CLI reuse
- GUI lifecycle review and actions
- CLI lifecycle list / show / history
- CLI lifecycle record-manual / propose
- CLI lifecycle accept / promote / archive
- MCP lifecycle read / write tools
- MCP retrieval / explain / wakeup gateway tools
- event-level provenance metadata across lifecycle writes
- GUI history pane and minimal create/propose flow
- in-process lifecycle projection cache
- disk-backed lifecycle projection snapshot
- MCP prompts/resources for guided client usage
- GUI metadata-aware create/propose inputs
- minimal lifecycle read daemon
- desktop-facing Rust facade for future Tauri/desktop hosts
- desktop workflow DTOs and classified error envelopes
- desktop context / wakeup / lifecycle read-write workflow boundary

This is no longer just a retrieval prototype; it is the beginning of a memory lifecycle core.

## Current Gaps

- daemon-backed reads now reuse a shared stdio daemon session keyed by `(daemon_bin, config_path)` inside one process, with one rebuild attempt before direct fallback
- daemon read-side structured payload shape is still narrower than the richer MCP shared payload contract and can be unified further later
- desktop facade exists as a pure Rust boundary, a Tauri-shaped adapter layer exists, and a minimal runnable host/bootstrap slice now exists, but the desktop product surface is still early
- desktop documentation must continue to describe `src/desktop/` as the implemented backend-facing contract instead of implying a finished Tauri host already exists
- GUI still has no edit-in-place and no metadata on lifecycle action buttons

## Validation Completed In This Session

```bash
cargo test -q memory_lifecycle --lib
cargo test -q lifecycle_store --lib
cargo test -q lifecycle_service --lib
cargo test -q mcp --lib
cargo test -q --features gui --lib
cargo test -q
cargo check -q
cargo check -q --features gui --bin spool-gui
cargo check -q --bin spool-mcp
cargo test -q mcp -- --nocapture
cargo test -q daemon -- --nocapture
cargo test -q desktop --lib
cargo check -q --lib
```

## Next Critical Decision

### Daemon integration or heavier index layer first?

The local, GUI, and MCP workflow surfaces are now present, and the first daemon boundary exists. The next branch point is whether to integrate existing clients with the daemon or continue building heavier index artifacts first.

#### Option A — Daemon integration first
- let CLI and/or MCP optionally use the daemon for read-only operations
- preserve direct fallback paths
- exercise the new boundary under real clients

#### Option B — Heavier index first
- add more disk-backed derived state before daemonization
- optimize more reads first
- keep client/daemon relationship unchanged

### Current recommendation

Prefer **Option A — Daemon integration first**.

Reason:
- the daemon now exists but is not exercised by real clients
- integrating one narrow read path will validate whether the boundary is actually useful
- more index layers should wait until client/daemon interaction is clearer

## Recommended Next Steps

### High Priority

1. keep lifecycle formatter/summary helpers as the only place where presentation and summary field selection evolves
2. if new lifecycle surfaces are added, wire them through `src/lifecycle_format.rs` and `src/lifecycle_summary.rs` first instead of duplicating render logic
3. continue pushing repeated CLI/GUI/MCP contracts downward into shared helpers before widening feature scope
4. if daemon read payloads need to grow, align them with the existing shared lifecycle payload contracts instead of inventing a second shape

Relevant files:

- [src/lifecycle_format.rs](/Users/long/Work/spool/src/lifecycle_format.rs)
- [src/lifecycle_summary.rs](/Users/long/Work/spool/src/lifecycle_summary.rs)
- [src/cli/commands.rs](/Users/long/Work/spool/src/cli/commands.rs)
- [src/gui/app_shell.rs](/Users/long/Work/spool/src/gui/app_shell.rs)
- [src/mcp.rs](/Users/long/Work/spool/src/mcp.rs)
- [src/daemon.rs](/Users/long/Work/spool/src/daemon.rs)

### Medium Priority

1. evaluate whether lifecycle action buttons should also accept metadata in GUI
2. evaluate whether retrieval path eventually needs more than the current vault snapshot cache
3. evaluate whether heavier index artifacts are justified after daemon-backed client reads exist
4. keep extending new lifecycle payload/text behavior through `src/lifecycle_summary.rs` first rather than reintroducing surface-local assembly
5. keep GUI-specific presentation differences intentionally small and parameterized rather than forking formatter logic

Relevant files:

- [src/lifecycle_format.rs](/Users/long/Work/spool/src/lifecycle_format.rs)
- [src/lifecycle_summary.rs](/Users/long/Work/spool/src/lifecycle_summary.rs)
- [docs/SESSION_HANDOFF.md](/Users/long/Work/spool/docs/SESSION_HANDOFF.md)
- [src/gui/app_shell.rs](/Users/long/Work/spool/src/gui/app_shell.rs)

### Lower Priority

1. persistent index / snapshot cache
2. semantic retrieval enrichment for ledger-derived memory
3. revisit whether lifecycle formatter output should also back future API docs or exported markdown reports

## Recommended Restart Entry Point

When continuing later:

1. read [src/lifecycle_service.rs](/Users/long/Work/spool/src/lifecycle_service.rs)
2. read [src/lifecycle_store.rs](/Users/long/Work/spool/src/lifecycle_store.rs)
3. read [src/daemon.rs](/Users/long/Work/spool/src/daemon.rs)
4. read [src/mcp.rs](/Users/long/Work/spool/src/mcp.rs)
5. read [src/lifecycle_summary.rs](/Users/long/Work/spool/src/lifecycle_summary.rs)
6. read [docs/DAEMON_INTEGRATION_ROUND_12_PLAN.md](/Users/long/Work/spool/docs/DAEMON_INTEGRATION_ROUND_12_PLAN.md)
7. if extending lifecycle tooling, preserve these invariants:
   - append-only ledger
   - stable `record_id`
   - invalid transitions do not append
   - GUI / CLI / future MCP all go through the shared lifecycle service
   - every successful write refreshes projection-backed review and wakeup-ready views