cc-os/docs/memory-system/10-sb-findability-plan.md

116 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# SecondBrain Findability Plan
_Last updated: 2026-06-27_
_Status: Planning_
## Problem
Plan A (`09-sb-content-plan.md`) populates the vault with typed, templated notes. But notes that exist and cannot be found are no better than notes that do not exist. The vault needs three complementary findability layers: a queryable index so the AI can discover notes by tag without reading every file; session-start injection so the AI knows the vault exists and how to query it from the first prompt; and an end-of-session agent that closes the knowledge loop — creating notes that should have been written, detecting drift between documented and actual procedures, and preventing duplicate notes before they are created. Without these layers, the vault is a write-only system. This plan builds the read and update path.
## Design Principles
- **Vault as library, not navigation:** Don't pre-compute "when to read X." Make querying cheap and let the AI decide at the point of need. Query results surface paths + summaries; AI reads summaries and decides which notes to fetch.
- **Minimal injection overhead:** SessionStart targets ~200 tokens total for all vault context. No embedded links or pre-computed indexes in project repos.
- **Projects contain product; SecondBrain contains knowledge:** Project repos contain no SB infrastructure — project notes live in SB, not in repos.
- **Experience-driven updates:** When a session executes a documented procedure and finds a discrepancy, update the note. Not date-based.
## Scope
This plan covers four phases, strictly sequenced — each phase depends on the previous:
1. Hub/index type + vault-index.json
2. `/memory-find` skill + SessionStart injection
3. SessionEnd agent (create + detect + dedup)
4. Feedback loop hardening
## Out of Scope
- **Atomic note splitting:** Large notes from Plan A that exceed focus — deferred to Plan C and beyond.
- **SQLite/FTS upgrade:** When vault-index.json query latency becomes measurable (>200 notes or >15 matches per query consistently).
- **Auto-update without human confirmation:** Deferred until flag-then-confirm is stable and trusted.
- **SessionStart vault pull:** Multi-machine sync; push-only is the current locked design.
- **Meeting, task, QoL opportunity note types:** Require findability layer to be useful; define after Plan B is operational.
- **memsearch ↔ SB integration:** memsearch (episodic) and SB (semantic) remain separate by design (ADR-006, ADR-010).
## Surfaces Touched
- **Plugin code:** `cc-os/plugins/memory/hooks/session_start.py` (extend), `cc-os/plugins/memory/hooks/vault_index_rebuild.py` (new), `cc-os/plugins/memory/hooks/session_end.py` (extend for Phase 3 Parts A/B/C)
- **Skills:** `cc-os/plugins/memory/skills/memory-find.md` (new)
- **Vault content:** `~/Documents/SecondBrain/vault-index.json` (new), `~/Documents/SecondBrain/project/` directory (new), hub notes as density warrants
- **Settings:** `~/.claude/settings.json` — add `vault_index_rebuild.py` as fourth SessionEnd hook (separate hook, mirrors `memsearch_sync.py` / `vault_sync.py` pattern)
## Risks
| Risk | Mitigation |
|------|-----------|
| **Index staleness** | Rebuild at SessionEnd only (batched). Stale index is acceptable within a session; regenerated within one session boundary. Stale results are surfaced as a known gap, not a silent failure. |
| **SessionEnd agent latency** | Agent runs at session close. Target: under 30 seconds, same constraint as `memsearch_sync.py` and `vault_sync.py`. Cap at 5 candidate notes per run; deeper audits are on-demand via `/memory-audit`. |
| **Duplicate notes** | Phase 3 Part C (pre-action deduplication) adds a tag-intersection check before any note creation. Dedup runs before create — not after. |
| **False positives in discrepancy detection** | Phase 3 Part B flags, does not auto-update. Human confirms before any note change. Auto-update deferred until flag-then-confirm workflow is stable and trusted. |
| **Hub note timing** | Hub notes should not be created before cluster density exists (3+ related notes). Phase 1 defers hub creation to emergence — noted as a natural byproduct, not a scheduled deliverable. |
| **Injection token budget** | SessionStart injection targets ~200 tokens total. If project note + global rules exceed budget, truncate global rules, not the project note. Project-specific context is higher signal at the point of use. |
## Build Order
### Phase 1: Hub/index type + vault-index.json (Size: M)
Two deliverables ship together:
**Hub/index note type**
Hub notes are deferred from Plan A because their value is relational — they only earn their place once notes are dense enough to navigate between. A hub note is a map, not content: title + one-sentence purpose + bulleted links to member notes with one-line descriptions. Do not create hub notes on a schedule; create them as a natural byproduct when a cluster of 3+ related notes exists. Planned first hubs (after content density warrants): agent-orchestration hub, rails-conventions hub.
**vault-index.json**
Location: `~/Documents/SecondBrain/vault-index.json`. Structure: `{tag: [{path, title, summary}]}`. Built by scanning vault notes: frontmatter tags + first 12 sentences as summary. Rebuilt at SessionEnd — batched, not real-time, not per-note-write. Tracked in git so it is pushed with every vault sync.
**Rebuild hook**
Add `vault_index_rebuild.py` as a fourth SessionEnd hook. Hook order at SessionEnd: `session_end.py``memsearch_sync.py``vault_index_rebuild.py``vault_sync.py`. Rebuild runs after vault notes are written but before `vault_sync.py` pushes to Forgejo, so the pushed index is current.
Decision: separate hook (not extending `session_end.py`) — mirrors `memsearch_sync.py` / `vault_sync.py` pattern, cleaner separation of concerns.
### Phase 2: /memory-find skill + SessionStart injection (Size: S)
Prerequisite: Phase 1 complete (vault-index.json exists).
**/memory-find skill**
Location: `cc-os/plugins/memory/skills/memory-find.md`. Accepts a tag argument. Loads vault-index.json. Filters for matching tags. Returns bulleted list: path, title, summary — one line per match. No embedded note fetching — AI reads summaries and decides which notes to open with Read tool calls or `/memory-recall`. No hard result limit in V1; revisit if queries consistently return 15+ matches.
Trigger: on-demand only. The AI is instructed to call it when it encounters something that might be in SB. Automatic triggering before every action is deferred — too noisy until the index has density.
**SessionStart injection**
Extend `session_start.py` to inject two things at session start (~200 tokens total):
1. Global type classification rules (~100 tokens): "SecondBrain is your knowledge layer. Types that always go to SB: convention (rule/pattern), reference (lookup/architecture), howto (procedure). Use `/memory-find [tag]` to query. Use `/memory-recall [path]` to read full notes. DRY: if knowledge already exists in SB, reference it — don't duplicate."
2. Project note (if exists for current project): project name, one-sentence description, tags this project produces. Tells the AI what types to write inline and what to look up. Project note format: `project/[name].md` containing name, one-sentence description, bulleted tag list, and optional `produces:` section for project-specific note types.
### Phase 3: SessionEnd agent (Size: L)
Prerequisite: Phase 1 and Phase 2 complete. Runs after `session_end.py` writes the episodic journal.
**Part A — Create new notes**
Agent audits git diff since last session for knowledge that belongs in SB but wasn't written inline. Uses value gate (longevity + reusability + mutability) to assess candidates. Agent judgment: global type gap → update global classification rules; project-specific type → add to project note in SB. Creates notes using the appropriate template. Does NOT auto-update existing notes — flag only (see Part B). Cap at 5 candidates per run to stay within latency budget.
**Part B — Detect discrepancies with existing notes**
When a session executed a procedure already in SB, agent checks actual vs. documented. Three outcomes:
1. Confirms — process matched the note, nothing to do.
2. Flags for update — process differed; agent reports the discrepancy and proposed change; human confirms before note is updated.
3. Flags ambiguity — process differed but unclear which is correct; human resolves before any change.
Auto-update deferred until flag-then-confirm workflow is stable and trusted.
**Part C — Pre-action deduplication**
Before creating a new note, agent checks vault-index.json for tag collision: do any existing notes carry the same primary tags? If yes, surface the existing note first — create only if the existing note doesn't cover the case. Implementation: tag intersection query on vault-index.json (fast, no embeddings needed). This closes the "we already have a note for that" gap.
### Phase 4: Feedback loop hardening (Size: S)
Prerequisite: Phase 3 stable.
Project-specific type exceptions discovered by the SessionEnd agent are written to the project's SB note (`project/[name].md`) under a `produces:` section. Next SessionStart for that project injects these exceptions alongside global rules. Over time: global rules handle obvious cases → SessionEnd catches less → per-project notes accumulate correct type exceptions → system approaches self-managing.
This phase is complete when the SessionEnd agent's "create" suggestions drop to near zero for a project — meaning global and per-project rules have absorbed the common cases.
## Open Questions
1. **SessionEnd agent token budget:** Target under 30 seconds. If Phase 3 Parts A + B + C together exceed the budget, split: Part C (dedup check) runs inline at note-create time, Parts A + B run as the SessionEnd agent. This preserves deduplication without blocking on the full audit.
2. **When does /memory-find trigger automatically vs. on-demand?** V1: on-demand only. The AI is instructed to call it when it encounters something that might be in SB. Automatic triggering (before every action) is deferred — too noisy until the index has density.
3. **Project note bootstrapping:** Who creates the initial project note for a new project? Options: (a) user creates manually using template, (b) `/memory-audit` suggests it, (c) `memory-project` skill creates it during onboarding. Current design: option (c) — `memory-project` skill writes a `project/[name].md` to the vault as part of onboarding. Confirm this in the memory-project skill spec.