Rename memory plugin to os-vault; fix marketplace registration

The plugin directory, symlink, and settings.json were already renamed to
os-vault, but the local-plugins marketplace manifest still declared the old
memory/./memory entry, so skills/slash-commands silently stopped registering
while hooks (wired by absolute path) kept working. Re-registered the plugin
under its new name via the marketplace manifest + claude plugin install/
uninstall, and documented the fix and standing rename procedure (ADR-018,
CLAUDE.md) so this doesn't recur.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
jared 2026-07-03 09:43:18 -04:00
parent 05437c8d41
commit f138c8d98b
86 changed files with 141 additions and 70 deletions

View File

@ -50,7 +50,7 @@ existing **`~/Documents/SecondBrain` Obsidian vault** as the single source of tr
tree-sitter AST for code). Retrieval is hook-injected + on-demand so project repos stay thin; tree-sitter AST for code). Retrieval is hook-injected + on-demand so project repos stay thin;
freshness is lazy freshness is lazy
(write-time hook + SessionStart reconcile, no daemon/cron); the vault syncs to a VPS while (write-time hook + SessionStart reconcile, no daemon/cron); the vault syncs to a VPS while
indexes stay disposable and rebuildable. Ships as a global Claude Code plugin with skills. indexes stay disposable and rebuildable. Ships as a global Claude Code plugin (`os-vault`) with skills.
**Recent pivot (2026-06-03):** Graphify **replaces** the originally-planned Ruby/SQLite **Recent pivot (2026-06-03):** Graphify **replaces** the originally-planned Ruby/SQLite
tag-index CLI and also covers the deferred QMD semantic layer. `04-build-plan.md` and tag-index CLI and also covers the deferred QMD semantic layer. `04-build-plan.md` and
@ -61,24 +61,24 @@ to those two and fix the stale doc.
**Empirical finding locked (2026-06-05):** Graphify is a structure extractor, not a topic clusterer — no emergent hub nodes appear even at `--mode deep`; hub notes + wikilinks must be author-provided during migration (not deferred). Migration scaffolding is now a first-class deliverable. Open question: do facet tags create graph edges? (ADR-014; findings: `docs/memory-system/07-graph-connectivity-findings.md`). **Empirical finding locked (2026-06-05):** Graphify is a structure extractor, not a topic clusterer — no emergent hub nodes appear even at `--mode deep`; hub notes + wikilinks must be author-provided during migration (not deferred). Migration scaffolding is now a first-class deliverable. Open question: do facet tags create graph edges? (ADR-014; findings: `docs/memory-system/07-graph-connectivity-findings.md`).
**Implementation status (2026-06-09):** The global Claude Code plugin is live (`~/.claude/plugins/memory/`). Steps 1, 2a, 2b, 3, and 6 of the build plan are complete (including the `memory-project` skill, previously TODO under Step 6/Part D). Step 1 completed 2026-06-09: vault-conventions.md exists, all 6 fixture notes seeded, and 14 Graphify handbook + memory-system design notes migrated to the vault as migration scaffolding. Step 4 (memsearch) completed 2026-06-09: plugin installed via marketplace, MEMSEARCH_DIR set global (~/.memsearch), Stop hook verified producing daily memory files, search confirmed working. Step 5a (memsearch episodic git sync) completed 2026-06-09: dedicated private Forgejo repo (`forgejo.swansoncloud.com/jared/memsearch`), whitelist `.gitignore` (memory/*.md only), auto-commit+push via cc-os `session-end.sh` hook (ADR-015; relocated to `memsearch_sync.py` by ADR-016, 2026-06-12). Step 5b (Obsidian vault → VPS sync) remains. See `docs/memory-system/04-build-plan.md` for full step status. **Implementation status (2026-06-09):** The global Claude Code plugin is live (`~/.claude/plugins/os-vault/`). Steps 1, 2a, 2b, 3, and 6 of the build plan are complete (including the `onboard-project` skill, previously TODO under Step 6/Part D). Step 1 completed 2026-06-09: vault-conventions.md exists, all 6 fixture notes seeded, and 14 Graphify handbook + memory-system design notes migrated to the vault as migration scaffolding. Step 4 (memsearch) completed 2026-06-09: plugin installed via marketplace, MEMSEARCH_DIR set global (~/.memsearch), Stop hook verified producing daily memory files, search confirmed working. Step 5a (memsearch episodic git sync) completed 2026-06-09: dedicated private Forgejo repo (`forgejo.swansoncloud.com/jared/memsearch`), whitelist `.gitignore` (memory/*.md only), auto-commit+push via cc-os `session-end.sh` hook (ADR-015; relocated to `memsearch_sync.py` by ADR-016, 2026-06-12). Step 5b (Obsidian vault → VPS sync) remains. See `docs/memory-system/04-build-plan.md` for full step status.
**Decision (2026-06-09):** Single global memsearch store for ALL clients — cross-client commingling is the accepted, intended design (ADR-015 resolved). One private Forgejo repo (`forgejo.swansoncloud.com/jared/memsearch`), not per-client repos. Forward direction: minimize/eliminate dedicated per-client working directories; work projects locally or use a single general `clients/` dir for non-local client work — memory is captured globally regardless of cwd. No `clients/` directory structure designed yet; open item. **Decision (2026-06-09):** Single global memsearch store for ALL clients — cross-client commingling is the accepted, intended design (ADR-015 resolved). One private Forgejo repo (`forgejo.swansoncloud.com/jared/memsearch`), not per-client repos. Forward direction: minimize/eliminate dedicated per-client working directories; work projects locally or use a single general `clients/` dir for non-local client work — memory is captured globally regardless of cwd. No `clients/` directory structure designed yet; open item.
**Implementation status (2026-06-12):** Memory plugin source moved into git at `cc-os/plugins/memory/` and bash hooks ported to Python (deep-module architecture: shared `config.py`, `hook_io.py`, `session_state.py`; thin entry-point scripts). Cutover via symlink `~/.claude/plugins/memory → cc-os/plugins/memory/` and settings.json hook rewrite. memsearch sync split into dedicated `memsearch_sync.py` SessionEnd hook (relocation of ADR-015 behavior, not reversal). Fresh-session test passed 2026-06-12. See ADR-016. **Implementation status (2026-06-12):** os-vault plugin source moved into git at `cc-os/plugins/os-vault/` and bash hooks ported to Python (deep-module architecture: shared `config.py`, `hook_io.py`, `session_state.py`; thin entry-point scripts). Cutover via symlink `~/.claude/plugins/os-vault → cc-os/plugins/os-vault/` and settings.json hook rewrite. memsearch sync split into dedicated `memsearch_sync.py` SessionEnd hook (relocation of ADR-015 behavior, not reversal). Fresh-session test passed 2026-06-12. See ADR-016.
**Implementation status (2026-06-15):** Step 5b done and automated — vault (`~/Documents/SecondBrain`) initialized as git repo, pushed to private Forgejo (`ssh://git@forgejo.swansoncloud.com:2222/jared/SecondBrain.git`); 52 files, git chosen over Syncthing. Auto-commit+push wired via `vault_sync.py` SessionEnd hook (third SessionEnd hook, runs after `session_end.py` so the daily journal note is included; push-only — SessionStart pull is an optional future item for multi-machine). Step 2e pilot done — llf-schema (`/home/jared/dev/llf-schema`, PHP 8.2 WordPress plugin) onboarded via `memory-project` skill: 605 nodes / 930 edges / 52 communities; Ollama doc pass lossy on WordPress docs but AST pass solid. Step 2d closed — live vault `graphify-out/` is the baseline; fixture-only build superseded. **Implementation status (2026-06-15):** Step 5b done and automated — vault (`~/Documents/SecondBrain`) initialized as git repo, pushed to private Forgejo (`ssh://git@forgejo.swansoncloud.com:2222/jared/SecondBrain.git`); 52 files, git chosen over Syncthing. Auto-commit+push wired via `vault_sync.py` SessionEnd hook (third SessionEnd hook, runs after `session_end.py` so the daily journal note is included; push-only — SessionStart pull is an optional future item for multi-machine). Step 2e pilot done — llf-schema (`/home/jared/dev/llf-schema`, PHP 8.2 WordPress plugin) onboarded via `/os-vault:onboard-project` skill: 605 nodes / 930 edges / 52 communities; Ollama doc pass lossy on WordPress docs but AST pass solid. Step 2d closed — live vault `graphify-out/` is the baseline; fixture-only build superseded.
**Implementation status (2026-06-17):** `memory-project` skill now uses assessment-first onboarding: surveys the repo structure, classifies exclude candidates by TYPE (11 categories: fetched deps, build output, caches, VCS internals, editor/AI-tooling dirs, lockfiles, coverage/logs, bulk data, binaries, secrets, graphify-out/ — illustrative names, not fixed templates), generates a per-project `.graphifyignore`, confirms with the user, then extracts the graph using `qwen25-coder-7b-16k` (config.yaml `ollama_model`; 16k-context build of qwen2.5-coder:7b — larger context window cuts chunk count per doc, the main speed lever). Fixes issue where repos with large dependency trees routed non-code files through the Ollama doc pass (see ADR-017). **Implementation status (2026-06-17):** `/os-vault:onboard-project` skill now uses assessment-first onboarding: surveys the repo structure, classifies exclude candidates by TYPE (11 categories: fetched deps, build output, caches, VCS internals, editor/AI-tooling dirs, lockfiles, coverage/logs, bulk data, binaries, secrets, graphify-out/ — illustrative names, not fixed templates), generates a per-project `.graphifyignore`, confirms with the user, then extracts the graph using `qwen25-coder-7b-16k` (config.yaml `ollama_model`; 16k-context build of qwen2.5-coder:7b — larger context window cuts chunk count per doc, the main speed lever). Fixes issue where repos with large dependency trees routed non-code files through the Ollama doc pass (see ADR-017).
**Implementation status (2026-06-30):** Phase 1 of the SecondBrain Content Plan complete (`docs/memory-system/09-sb-content-plan.md`, issues #1#6). `~/Documents/SecondBrain/vault-conventions.md` reconciled to a single authoritative typed frontmatter schema (removed the contradictory block; canonical filenames are slug-only, `source:` is a frontmatter field not a tag, `scope` is a field not a tag). New `memory-template` skill added (`cc-os/plugins/memory/skills/memory-template/SKILL.md`) — routes between template-design (4-step process + injection-economics filter) and new-type creation (9-step lifecycle). Three vault note templates created in `~/Documents/SecondBrain/_templates/` (`howto.md`, `convention.md`, `reference.md`; `reference` carries a four-subtype variant selector — pattern/framework, api-integration, role-definitions, design-rules), each dogfooded against a real note. Four proof-of-concept vault notes patched (cookbook subtype → pattern/framework, glossary de-duped to a wikilink, design-mode scope → project, tags + `last_reviewed` added). Phase 2 (issue #7) remains open as the steady-state migration/onboarding epic (no code). See `docs/memory-system/09-sb-content-plan.md`. **Implementation status (2026-06-30):** Phase 1 of the SecondBrain Content Plan complete (`docs/memory-system/09-sb-content-plan.md`, issues #1#6). `~/Documents/SecondBrain/vault-conventions.md` reconciled to a single authoritative typed frontmatter schema (removed the contradictory block; canonical filenames are slug-only, `source:` is a frontmatter field not a tag, `scope` is a field not a tag). New `/os-vault:design-template` skill added (`cc-os/plugins/os-vault/skills/design-template/SKILL.md`) — routes between template-design (4-step process + injection-economics filter) and new-type creation (9-step lifecycle). Three vault note templates created in `~/Documents/SecondBrain/_templates/` (`howto.md`, `convention.md`, `reference.md`; `reference` carries a four-subtype variant selector — pattern/framework, api-integration, role-definitions, design-rules), each dogfooded against a real note. Four proof-of-concept vault notes patched (cookbook subtype → pattern/framework, glossary de-duped to a wikilink, design-mode scope → project, tags + `last_reviewed` added). Phase 2 (issue #7) remains open as the steady-state migration/onboarding epic (no code). See `docs/memory-system/09-sb-content-plan.md`.
## Implemented Components ## Implemented Components
**Global memory plugin** — `cc-os/plugins/memory/` (git-tracked, 2026-06-12); symlinked into `~/.claude/plugins/memory` **Global os-vault plugin** — `cc-os/plugins/os-vault/` (git-tracked, 2026-06-12); symlinked into `~/.claude/plugins/os-vault`
- Hooks: `hooks/``session_start.py`, `session_context.py` (project graph path only), `post_tool_use_write.py`, `session_end.py` (vault journal), `memsearch_sync.py` (second SessionEnd hook; memsearch auto-commit+push, 30s timeout), `vault_sync.py` (third SessionEnd hook; vault auto-commit+push to forgejo.swansoncloud.com/jared/SecondBrain, 30s timeout; mirrors memsearch_sync.py) - Hooks: `hooks/``session_start.py`, `session_context.py` (project graph path only), `post_tool_use_write.py`, `session_end.py` (vault journal), `memsearch_sync.py` (second SessionEnd hook; memsearch auto-commit+push, 30s timeout), `vault_sync.py` (third SessionEnd hook; vault auto-commit+push to forgejo.swansoncloud.com/jared/SecondBrain, 30s timeout; mirrors memsearch_sync.py)
- Shared modules: `config.py` (load_config → frozen Config dataclass), `hook_io.py` (read_input → HookInput dataclass), `session_state.py` (record_touch/read_touches; encapsulates `/tmp/claude-vault-touched-$SESSION_ID` contract) - Shared modules: `config.py` (load_config → frozen Config dataclass), `hook_io.py` (read_input → HookInput dataclass), `session_state.py` (record_touch/read_touches; encapsulates `/tmp/claude-vault-touched-$SESSION_ID` contract)
- Skills: `skills/`memory-vault, memory-write, memory-reorganize, memory-project (assessment-first onboarding: surveys repo, classifies excludes by type (11 categories), writes per-project `.graphifyignore`, confirms with user, then extracts using `qwen25-coder-7b-16k` — per ADR-017), memory-template (routes template-design ↔ new-type-creation: 4-step template-design process + injection-economics filter, 9-step new-type lifecycle; backs Phase 1 of the SB Content Plan — see `docs/memory-system/09-sb-content-plan.md`) - Skills: `skills/`query, write, reorganize, onboard-project (assessment-first onboarding: surveys repo, classifies excludes by type (11 categories), writes per-project `.graphifyignore`, confirms with user, then extracts using `qwen25-coder-7b-16k` — per ADR-017), design-template (routes template-design ↔ new-type-creation: 4-step template-design process + injection-economics filter, 9-step new-type lifecycle; backs Phase 1 of the SB Content Plan — see `docs/memory-system/09-sb-content-plan.md`)
- Config: `config.yaml` — vault path, Ollama model (qwen25-coder-7b-16k), env vars - Config: `config.yaml` — vault path, Ollama model (qwen25-coder-7b-16k), env vars
- Hook wiring: `~/.claude/settings.json` (hook entries invoke `/usr/bin/python3` with absolute paths into cc-os) - Hook wiring: `~/.claude/settings.json` (hook entries invoke `/usr/bin/python3` with absolute paths into cc-os)
@ -102,6 +102,37 @@ to those two and fix the stale doc.
**Remaining optional items:** SessionStart vault pull (multi-machine sync; push-only is the current design); additional project onboarding (one at a time, per ADR-013); bulk vault migration. All required build steps complete as of 2026-06-15. **Remaining optional items:** SessionStart vault pull (multi-machine sync; push-only is the current design); additional project onboarding (one at a time, per ADR-013); bulk vault migration. All required build steps complete as of 2026-06-15.
**Plugin renamed `memory``os-vault` (2026-07-03):** directory renamed in git, `~/.claude/plugins/os-vault` symlink and `settings.json`'s `enabledPlugins` updated — but the `local-plugins` marketplace manifest (`~/.claude/plugins/.claude-plugin/marketplace.json`) still declared the old `memory`/`./memory` entry, and `installed_plugins.json` still had a cached `memory@local-plugins` install record. Skills (and therefore slash commands) never registered under the new name as a result; hooks kept working because they're wired by absolute path in `settings.json`, independent of plugin resolution. Fixed by editing the marketplace manifest to `"os-vault"`/`"./os-vault"`, then `claude plugin marketplace update local-plugins`, `claude plugin install os-vault@local-plugins`, `claude plugin uninstall memory@local-plugins`. See ADR-018 and the "Renaming or moving a local plugin" procedure below.
### Renaming or moving a local plugin
Renaming a plugin directory under a directory-source marketplace (like `local-plugins`, whose
source is `~/.claude/plugins` itself) requires updating **three** places, not just the directory
and `settings.json`:
1. **Plugin directory / symlink** — the actual files (or symlink target, for plugins that live in
a git repo like `cc-os/plugins/os-vault/`).
2. **Marketplace manifest**`~/.claude/plugins/.claude-plugin/marketplace.json` (for
`local-plugins`) lists each plugin's `name` and `source` path explicitly; this does **not**
auto-discover from the directory listing. Update the entry to match the new name/path.
3. **`settings.json` `enabledPlugins`** — the `<name>@<marketplace>` key must match the manifest
entry from step 2.
Then refresh the plugin manager's state so it re-resolves the marketplace and drops the stale
install record:
```bash
claude plugin marketplace update <marketplace-name> # re-validates the manifest
claude plugin install <new-name>@<marketplace-name> # creates the new install record
claude plugin uninstall <old-name>@<marketplace-name> # drops the stale one
claude plugin list # verify: new name enabled, old name gone
claude plugin details <new-name>@<marketplace-name> # verify skills/agents/hooks resolved
```
Skipping step 2 is the failure mode to watch for: hooks (wired by absolute path in
`settings.json`) keep working, masking the fact that skills/slash-commands silently stopped
registering under the plugin's new name.
## Issue tracking ## Issue tracking
Issues (created via `/to-issues`) live on self-hosted Forgejo (`jared/cc-os`), queried with the `tea` CLI — not GitHub/`gh`. See `docs/issue-workflow.md` for token setup, listing, implementing, and closing issues. Issues (created via `/to-issues`) live on self-hosted Forgejo (`jared/cc-os`), queried with the `tea` CLI — not GitHub/`gh`. See `docs/issue-workflow.md` for token setup, listing, implementing, and closing issues.
@ -130,6 +161,7 @@ project context for OpenSpec artifacts comes from `docs/` and this file.
`03-architecture-decisions.md` with the reasoning. `03-architecture-decisions.md` with the reasoning.
- The package on PyPI is `graphifyy` (double-y) but the command is `graphify`. - The package on PyPI is `graphifyy` (double-y) but the command is `graphify`.
- **Keep this file current:** When a build step completes, (a) mark it done in `docs/memory-system/04-build-plan.md`, (b) add or update a component pointer in the Implemented Components section above, and (c) update the current design paragraph if the design changed. This file is the AI's orientation entry point — accuracy matters more than brevity. - **Keep this file current:** When a build step completes, (a) mark it done in `docs/memory-system/04-build-plan.md`, (b) add or update a component pointer in the Implemented Components section above, and (c) update the current design paragraph if the design changed. This file is the AI's orientation entry point — accuracy matters more than brevity.
- **Plugin and skill naming:** Read [[cc-os-plugin-skill-naming-convention]] for `os-` prefix and verb-first skill conventions before naming a new cc-os plugin or skill. Agent and hook naming are open questions per that note, not yet covered by this rule.
## Session Orchestration ## Session Orchestration

View File

@ -1,6 +1,6 @@
# Architecture Decision Records # Architecture Decision Records
_Last updated: 2026-06-17_ _Last updated: 2026-07-03_
A running log of decisions and *why*. Format per entry: Context · Decision · Rationale · A running log of decisions and *why*. Format per entry: Context · Decision · Rationale ·
Alternatives rejected · Status. Newest decisions extend the log; supersede rather than delete. Alternatives rejected · Status. Newest decisions extend the log; supersede rather than delete.
@ -435,8 +435,8 @@ _Date: 2026-06-09_
_Date: 2026-06-12_ _Date: 2026-06-12_
- **Context**: The global Claude Code memory plugin was developed iteratively in-place at - **Context**: The global Claude Code os-vault plugin was developed iteratively in-place at
`~/.claude/plugins/memory/` — never tracked in version control. Four bash hook scripts `~/.claude/plugins/os-vault/` — never tracked in version control. Four bash hook scripts
(`session-start.sh`, `session-context.sh`, `post_tool_use_write.sh`, `session_end.sh`) each (`session-start.sh`, `session-context.sh`, `post_tool_use_write.sh`, `session_end.sh`) each
independently parsed YAML config, decoded stdin JSON, and referenced shared filesystem independently parsed YAML config, decoded stdin JSON, and referenced shared filesystem
contracts (e.g. a temp file keyed by `$SESSION_ID`) via ad-hoc inline code with no contracts (e.g. a temp file keyed by `$SESSION_ID`) via ad-hoc inline code with no
@ -445,9 +445,9 @@ _Date: 2026-06-12_
and fragile; the bash scripts had no shared modules, no tests, and a jq-vs-python3 and fragile; the bash scripts had no shared modules, no tests, and a jq-vs-python3
inconsistency across hooks. An OpenSpec change (`memory-plugin-source-and-port`) was inconsistency across hooks. An OpenSpec change (`memory-plugin-source-and-port`) was
initiated to move the plugin into git and port the hooks to Python. initiated to move the plugin into git and port the hooks to Python.
- **Decision (1) — Source location**: The canonical source for the global memory plugin is now - **Decision (1) — Source location**: The canonical source for the global os-vault plugin is now
`cc-os/plugins/memory/` (this repo, git-tracked). `~/.claude/plugins/memory/` is a symlink `cc-os/plugins/os-vault/` (this repo, git-tracked). `~/.claude/plugins/os-vault/` is a symlink
pointing to `cc-os/plugins/memory/`; it is no longer an independent directory. pointing to `cc-os/plugins/os-vault/`; it is no longer an independent directory.
- **Decision (2) — Module shape: deep-module Python architecture**: The four bash hooks were - **Decision (2) — Module shape: deep-module Python architecture**: The four bash hooks were
ported to Python as a **deep-module** design — three shared modules providing clean, stable ported to Python as a **deep-module** design — three shared modules providing clean, stable
abstractions, plus thin entry-point scripts: abstractions, plus thin entry-point scripts:
@ -472,18 +472,18 @@ _Date: 2026-06-12_
failures and memsearch sync failures are now independently observable and independently failures and memsearch sync failures are now independently observable and independently
fail-open. fail-open.
- **Decision (4) — Deployment-mechanism deviation (symlink)**: The OpenSpec plan described - **Decision (4) — Deployment-mechanism deviation (symlink)**: The OpenSpec plan described
repointing the `local-plugins` marketplace source path to `cc-os/plugins/memory/`. In repointing the `local-plugins` marketplace source path to `cc-os/plugins/os-vault/`. In
practice, there is no `marketplace.json` registry manifest to repoint — the marketplace's practice, there is no `marketplace.json` registry manifest to repoint — the marketplace's
`known_marketplaces.json` manages marketplace sources, not per-plugin paths, and the hook `known_marketplaces.json` manages marketplace sources, not per-plugin paths, and the hook
scripts are entirely decoupled from the marketplace (they are registered in `settings.json` scripts are entirely decoupled from the marketplace (they are registered in `settings.json`
by hardcoded absolute path). The functional cutover was therefore accomplished via two by hardcoded absolute path). The functional cutover was therefore accomplished via two
actions: (1) `~/.claude/settings.json` hook entries were rewritten to invoke `/usr/bin/python3` actions: (1) `~/.claude/settings.json` hook entries were rewritten to invoke `/usr/bin/python3`
with absolute paths into `cc-os/plugins/memory/hooks/`, which is the real behavioral cutover; with absolute paths into `cc-os/plugins/os-vault/hooks/`, which is the real behavioral cutover;
(2) a symlink `~/.claude/plugins/memory → cc-os/plugins/memory/` was created so that skill (2) a symlink `~/.claude/plugins/os-vault → cc-os/plugins/os-vault/` was created so that skill
resolution (which follows the plugins directory) continues to resolve correctly. Pre-cutover resolution (which follows the plugins directory) continues to resolve correctly. Pre-cutover
backups were taken: `~/.claude/settings.json.bak-precutover-2026-06-12`, backups were taken: `~/.claude/settings.json.bak-precutover-2026-06-12`,
`~/.claude/known_marketplaces.json.bak-precutover-2026-06-12`, and `~/.claude/known_marketplaces.json.bak-precutover-2026-06-12`, and
`~/.claude/plugins/memory.bak-bash-precutover/`. `~/.claude/plugins/os-vault.bak-bash-precutover/`.
- **Rationale**: - **Rationale**:
- **Source in git**: an untracked plugin is invisible to review, diff, and rollback; living in - **Source in git**: an untracked plugin is invisible to review, diff, and rollback; living in
cc-os gives change history, golden fixtures, and CI-comparable testing. cc-os gives change history, golden fixtures, and CI-comparable testing.
@ -510,7 +510,7 @@ _Date: 2026-06-12_
- **Repoint `known_marketplaces.json`**: no per-plugin path override semantics confirmed in - **Repoint `known_marketplaces.json`**: no per-plugin path override semantics confirmed in
the actual marketplace format; would require undocumented hacking with no rollback path. the actual marketplace format; would require undocumented hacking with no rollback path.
- **Consequences / ongoing contracts**: - **Consequences / ongoing contracts**:
- `~/.claude/plugins/memory` is a symlink; do not replace it with a directory (e.g. on plugin - `~/.claude/plugins/os-vault` is a symlink; do not replace it with a directory (e.g. on plugin
reinstall) without checking cc-os source first. reinstall) without checking cc-os source first.
- `~/.claude/settings.json` hook entries now invoke Python 3 via absolute path into cc-os; - `~/.claude/settings.json` hook entries now invoke Python 3 via absolute path into cc-os;
keep these entries current when hook filenames change. keep these entries current when hook filenames change.
@ -527,7 +527,7 @@ _Date: 2026-06-12_
_Date: 2026-06-17_ _Date: 2026-06-17_
- **Context**: The `/memory:memory-project` skill's onboarding flow ran `graphify extract . --backend ollama --model qwen2.5-coder:7b` directly. graphify does NOT honor `.gitignore`; it uses a separate `.graphifyignore` file (same syntax — see `docs/graphify/02-installation-setup.md`). With no `.graphifyignore`, onboarding `viking-warrior-training-log` (135 tracked files) walked `node_modules/` (5,858 files / 161MB) and routed every non-code file there through the Ollama doc pass. The run was killed after ~1 hour with no `graph.json` produced. Cost driver: only non-code files hit the Ollama LLM; code uses the free tree-sitter AST pass. - **Context**: The `/os-vault:onboard-project` skill's onboarding flow ran `graphify extract . --backend ollama --model qwen2.5-coder:7b` directly. graphify does NOT honor `.gitignore`; it uses a separate `.graphifyignore` file (same syntax — see `docs/graphify/02-installation-setup.md`). With no `.graphifyignore`, onboarding `viking-warrior-training-log` (135 tracked files) walked `node_modules/` (5,858 files / 161MB) and routed every non-code file there through the Ollama doc pass. The run was killed after ~1 hour with no `graph.json` produced. Cost driver: only non-code files hit the Ollama LLM; code uses the free tree-sitter AST pass.
- **Decision**: Onboarding is now assessment-first. Before running `graphify extract`, the skill surveys the repo, classifies directories and file types into include/exclude (weighing non-code file count since only non-code files cost LLM time), confirms the proposed ignore list with the user, writes `.graphifyignore` at the repo root, ensures `graphify-out/` is in the project's `.gitignore`, then runs extract. The ignore list is generated per-project — what counts as noise varies by stack — not from a static template. - **Decision**: Onboarding is now assessment-first. Before running `graphify extract`, the skill surveys the repo, classifies directories and file types into include/exclude (weighing non-code file count since only non-code files cost LLM time), confirms the proposed ignore list with the user, writes `.graphifyignore` at the repo root, ensures `graphify-out/` is in the project's `.gitignore`, then runs extract. The ignore list is generated per-project — what counts as noise varies by stack — not from a static template.
- **Rationale**: graphify's `.gitignore` blindness is by design; the correct lever is `.graphifyignore`, not a workaround. Assessment before extraction surfaces borderline dirs (migrations, seeds, fixtures, sample data) that need a human call. Per-project generation avoids the false safety of a shared template that silently mismatches a new stack. - **Rationale**: graphify's `.gitignore` blindness is by design; the correct lever is `.graphifyignore`, not a workaround. Assessment before extraction surfaces borderline dirs (migrations, seeds, fixtures, sample data) that need a human call. Per-project generation avoids the false safety of a shared template that silently mismatches a new stack.
- **Alternatives rejected**: **Static `.graphifyignore` template** — rejected; dependency/build/cache dirs vary by project stack; a template would both over-exclude (suppressing wanted source) and under-exclude (missing stack-specific dirs) for any given project. **Auto-write without user confirmation** — rejected; borderline directories (e.g. migrations, seeds, fixtures) require human judgment; mechanical exclusion would silently drop legitimate content. **AST-only mode (skip doc pass entirely)** — deferred; the `--backend ollama` flag stays; the ignore list is the correct cost lever, not backend switching. - **Alternatives rejected**: **Static `.graphifyignore` template** — rejected; dependency/build/cache dirs vary by project stack; a template would both over-exclude (suppressing wanted source) and under-exclude (missing stack-specific dirs) for any given project. **Auto-write without user confirmation** — rejected; borderline directories (e.g. migrations, seeds, fixtures) require human judgment; mechanical exclusion would silently drop legitimate content. **AST-only mode (skip doc pass entirely)** — deferred; the `--backend ollama` flag stays; the ignore list is the correct cost lever, not backend switching.
@ -537,6 +537,45 @@ _Date: 2026-06-17_
- **Default-exclude taxonomy is type-based, not name-based.** The skill's assessment step organizes exclude candidates into 11 categories by KIND (fetched deps, build/generated output, caches, VCS internals, editor/AI-tooling dirs, lockfiles, coverage/logs, bulk data/databases, binaries, secrets, graphify-out/) with a meta-principle: index what a human authored; exclude anything fetched, generated, cached, tooling config, bulk data/binary, or secret. Example names within each category are illustrative, not exhaustive — the goal is to recognize the kind even in an unfamiliar stack. See SKILL.md for the full table. - **Default-exclude taxonomy is type-based, not name-based.** The skill's assessment step organizes exclude candidates into 11 categories by KIND (fetched deps, build/generated output, caches, VCS internals, editor/AI-tooling dirs, lockfiles, coverage/logs, bulk data/databases, binaries, secrets, graphify-out/) with a meta-principle: index what a human authored; exclude anything fetched, generated, cached, tooling config, bulk data/binary, or secret. Example names within each category are illustrative, not exhaustive — the goal is to recognize the kind even in an unfamiliar stack. See SKILL.md for the full table.
- **Onboarding uses the 16k-context model.** The `graphify extract` command now passes `--model qwen25-coder-7b-16k` (the `ollama_model` from config.yaml), a 16k-context build of qwen2.5-coder:7b. Inference is GPU-bound (~65 tok/s); the main speed lever is chunk-count × generation — fewer chunks per doc via a larger context window. `GRAPHIFY_OLLAMA_NUM_CTX` does not propagate through graphify's OpenAI-compatible endpoint; the larger context must come from the model's Modelfile. - **Onboarding uses the 16k-context model.** The `graphify extract` command now passes `--model qwen25-coder-7b-16k` (the `ollama_model` from config.yaml), a 16k-context build of qwen2.5-coder:7b. Inference is GPU-bound (~65 tok/s); the main speed lever is chunk-count × generation — fewer chunks per doc via a larger context window. `GRAPHIFY_OLLAMA_NUM_CTX` does not propagate through graphify's OpenAI-compatible endpoint; the larger context must come from the model's Modelfile.
## ADR-018 — Plugin renames must update the marketplace manifest, not just the directory and settings.json
_Date: 2026-07-03_
- **Context**: The `memory` plugin directory was renamed to `os-vault` (git rename,
`plugins/memory/``plugins/os-vault/`), the `~/.claude/plugins/os-vault` symlink was
updated, and `settings.json`'s `enabledPlugins` was flipped to `os-vault@local-plugins`.
Despite this, no `os-vault` slash commands (skills) were available in-session. Root cause:
the `local-plugins` marketplace manifest (`~/.claude/plugins/.claude-plugin/marketplace.json`)
— which explicitly lists each plugin's `name`/`source` rather than auto-discovering the
directory — still declared only `memory`/`./memory`, and `installed_plugins.json` still held
a stale install record for `memory@local-plugins`. Hooks kept firing throughout (they're
wired by absolute path directly in `settings.json`, bypassing plugin resolution entirely),
which masked the break — everything looked healthy except the skills/slash-commands.
- **Decision**: A local-plugin rename/move is a three-file operation: (1) the plugin directory
or symlink, (2) the marketplace manifest entry (`name` + `source`), (3) `settings.json`
`enabledPlugins`. After all three, run `claude plugin marketplace update <marketplace>` to
re-validate, `claude plugin install <new>@<marketplace>` to create the new install record,
and `claude plugin uninstall <old>@<marketplace>` to drop the stale one — then verify with
`claude plugin list` and `claude plugin details <new>@<marketplace>` (skills/agents/hooks
inventory). Documented as a standing procedure in `CLAUDE.md` under "Renaming or moving a
local plugin."
- **Rationale**: The marketplace manifest is the actual source of truth for what plugins exist
under a directory-source marketplace — the directory listing itself is not consulted for
plugin identity. Because hooks are independently wired by path, they give a false signal that
the plugin is fully operational; skill/slash-command registration must be checked separately
via `claude plugin details`.
- **Alternatives rejected**: **Rely on directory listing / auto-discovery** — not how
`local-plugins` (a directory-source marketplace) resolves plugins; the manifest is
authoritative. **Skip the install/uninstall refresh, just fix the manifest** — leaves a stale
cached install record in `installed_plugins.json` under the old name, which is confusing and
can mask a future rename of the same kind.
- **Consequences / ongoing contracts**: any future rename of `os-vault` (or a new local plugin)
must touch the marketplace manifest, not just `settings.json`. `claude plugin details
<plugin>@<marketplace>` is the verification step to run after any plugin registration change
— it surfaces the skill/agent/hook inventory that a passing hook test would not.
- **Status**: Accepted 2026-07-03. Fixed and verified same day (`os-vault@local-plugins` shows
enabled with 5 skills resolved; stale `memory@local-plugins` record removed).
## Rejected tools (summary) ## Rejected tools (summary)
| Tool | Why rejected for our use | | Tool | Why rejected for our use |

View File

@ -1,6 +1,6 @@
# Build Plan # Build Plan
_Last updated: 2026-06-15_ _Last updated: 2026-07-02_
How a human builds this system, step by step, and answers to the operational questions: How a human builds this system, step by step, and answers to the operational questions:
which scripts and hooks, how the AI knows when to write and what conventions to follow, how and which scripts and hooks, how the AI knows when to write and what conventions to follow, how and
@ -77,7 +77,7 @@ GRAPHIFY_OLLAMA_NUM_CTX=8192 # 8K is sufficient for vault notes (200-2000 w
To verify context is being used: `ollama ps` shows allocated context after first call. To verify context is being used: `ollama ps` shows allocated context after first call.
**Status:** All env vars set in `~/.claude/plugins/memory/config.yaml`: **Status:** All env vars set in `~/.claude/plugins/os-vault/config.yaml`:
`OLLAMA_FLASH_ATTENTION=1`, `GRAPHIFY_OLLAMA_NUM_CTX=8192`, `GRAPHIFY_OLLAMA_KEEP_ALIVE=5`. `OLLAMA_FLASH_ATTENTION=1`, `GRAPHIFY_OLLAMA_NUM_CTX=8192`, `GRAPHIFY_OLLAMA_KEEP_ALIVE=5`.
Model locked to `qwen25-coder-7b-16k` (per ADR and memory note — this is Graphify's default Model locked to `qwen25-coder-7b-16k` (per ADR and memory note — this is Graphify's default
and the confirmed working extraction model). and the confirmed working extraction model).
@ -171,7 +171,7 @@ but `cc-os` is a docs-only repo, not a pilot project in the ADR-013 sense. A pil
with real code has not yet been onboarded. with real code has not yet been onboarded.
**Status: PILOT DONE (2026-06-15).** The llf-schema project (`/home/jared/dev/llf-schema`, **Status: PILOT DONE (2026-06-15).** The llf-schema project (`/home/jared/dev/llf-schema`,
PHP 8.2 WordPress plugin) was onboarded via the `memory-project` skill: `graphify extract` PHP 8.2 WordPress plugin) was onboarded via the `/os-vault:onboard-project` skill: `graphify extract`
(tree-sitter AST on 90 code files + Ollama doc pass on 9 doc files, ~3.5 min) + `cluster-only` (tree-sitter AST on 90 code files + Ollama doc pass on 9 doc files, ~3.5 min) + `cluster-only`
→ 605 nodes / 930 edges / 52 communities (~524K `graph.json`). `graphify-out/` added to that → 605 nodes / 930 edges / 52 communities (~524K `graph.json`). `graphify-out/` added to that
repo's `.gitignore`. **Finding:** Ollama doc pass was lossy on structured WordPress docs (101 repo's `.gitignore`. **Finding:** Ollama doc pass was lossy on structured WordPress docs (101
@ -246,16 +246,16 @@ models. Graphs are rebuilt per machine from the vault (the single source of trut
### Step 6 — Package as a global plugin (Part D) **DONE (2026-06-08)** ### Step 6 — Package as a global plugin (Part D) **DONE (2026-06-08)**
- Wrap Steps 23 into a Claude Code plugin with skills; install at user level. - Wrap Steps 23 into a Claude Code plugin with skills; install at user level.
**Status:** Global plugin installed at `~/.claude/plugins/memory/` with all hook scripts and **Status:** Global plugin installed at `~/.claude/plugins/os-vault/` with all hook scripts and
4 skills (`memory-vault`, `memory-write`, `memory-reorganize`, `memory-project`). Plugin enabled in 5 skills (`query`, `write`, `reorganize`, `onboard-project`, `design-template`). Plugin enabled in
`~/.claude/settings.json`. `~/.claude/settings.json`.
**Source-in-git + bash→Python port — DONE (2026-06-12):** Plugin source moved into git at **Source-in-git + bash→Python port — DONE (2026-06-12):** Plugin source moved into git at
`cc-os/plugins/memory/` (OpenSpec change `memory-plugin-source-and-port`). Bash hooks ported to `cc-os/plugins/os-vault/` (OpenSpec change `memory-plugin-source-and-port`). Bash hooks ported to
Python using a deep-module architecture (shared `config.py`, `hook_io.py`, `session_state.py`; Python using a deep-module architecture (shared `config.py`, `hook_io.py`, `session_state.py`;
thin entry-point scripts under `hooks/`). memsearch sync split into `memsearch_sync.py` as a thin entry-point scripts under `hooks/`). memsearch sync split into `memsearch_sync.py` as a
dedicated second SessionEnd hook (ADR-015 behavior relocated, not reversed). Cutover done via dedicated second SessionEnd hook (ADR-015 behavior relocated, not reversed). Cutover done via
symlink `~/.claude/plugins/memory → cc-os/plugins/memory/` and settings.json hook rewrite to symlink `~/.claude/plugins/os-vault → cc-os/plugins/os-vault/` and settings.json hook rewrite to
Python absolute paths. Fresh-session test passed 2026-06-12. See ADR-016. Python absolute paths. Fresh-session test passed 2026-06-12. See ADR-016.
### Step 7 — (SKIPPED) QMD semantic layer ### Step 7 — (SKIPPED) QMD semantic layer
@ -348,17 +348,17 @@ Graphify config.
`graphify path`, `graphify explain` directly. No server process. Project-specific graphs `graphify path`, `graphify explain` directly. No server process. Project-specific graphs
are queried with `--graph <path>` pointing at the project's `graphify-out/graph.json`. are queried with `--graph <path>` pointing at the project's `graphify-out/graph.json`.
- **Skills** (these carry the *know-how* to the model): - **Skills** (these carry the *know-how* to the model):
- `memory-write` — when to record evergreen knowledge, the frontmatter contract (summary - `/os-vault:write` — when to record evergreen knowledge, the frontmatter contract (summary
required, scope rule), "vault not repo." required, scope rule), "vault not repo."
- `memory-vault` — how/when to use `graphify query` vs memsearch; god-node discipline; - `/os-vault:query` — how/when to use `graphify query` vs memsearch; god-node discipline;
`--budget`/`--dfs` usage; cross-client lookups via `--graph`; progressive-disclosure `--budget`/`--dfs` usage; cross-client lookups via `--graph`; progressive-disclosure
via summary field. via summary field.
- `memory-reorganize` — the plan-mode consolidation/promotion procedure + guardrails; - `/os-vault:reorganize` — the plan-mode consolidation/promotion procedure + guardrails;
when to trigger `graphify --force` rebuild. when to trigger `graphify --force` rebuild.
- `memory-project` **DONE (2026-06-08)** — full lifecycle skill for per-project Graphify graphs: - `/os-vault:onboard-project` **DONE (2026-06-08)** — full lifecycle skill for per-project Graphify graphs:
- **Onboard**: `graphify extract . --backend ollama --model qwen2.5-coder:7b`, then `graphify cluster-only .`, add `graphify-out/` to `.gitignore` - **Onboard**: `graphify extract . --backend ollama --model qwen2.5-coder:7b`, then `graphify cluster-only .`, add `graphify-out/` to `.gitignore`
- **Onboard flow (updated 2026-06-17, ADR-017)**: Assessment-first — the skill surveys the repo and generates a per-project `.graphifyignore` for user confirmation before running extract, because Graphify does not honor `.gitignore`. - **Onboard flow (updated 2026-06-17, ADR-017)**: Assessment-first — the skill surveys the repo and generates a per-project `.graphifyignore` for user confirmation before running extract, because Graphify does not honor `.gitignore`.
- **Query**: `graphify query ... --graph <path>` for project-context queries (wraps `memory-vault`) - **Query**: `graphify query ... --graph <path>` for project-context queries (wraps `/os-vault:query`)
- **Update**: `graphify update .` for incremental updates (no API cost) or `--force` rebuild after structural changes - **Update**: `graphify update .` for incremental updates (no API cost) or `--force` rebuild after structural changes
- **Remove**: delete `graphify-out/` when no longer needed - **Remove**: delete `graphify-out/` when no longer needed
- **Config**: vault path, Graphify output dir, Ollama model name, `num_ctx`, rebuild-stale - **Config**: vault path, Graphify output dir, Ollama model name, `num_ctx`, rebuild-stale

View File

@ -1,6 +1,6 @@
# Implementation Process # Implementation Process
_Last updated: 2026-06-05_ | _Status: Steps 2a/2b/2d executed — toolchain installed, context fix applied, vault graph built; model selected (qwen2.5-coder:7b); Step 2c (reference set) previously complete. Step 2 fully executed._ _Last updated: 2026-07-02_ | _Status: Steps 2a/2b/2d executed — toolchain installed, context fix applied, vault graph built; model selected (qwen2.5-coder:7b); Step 2c (reference set) previously complete. Step 2 fully executed._
This document distills `04-build-plan.md` into a concrete, staged build process and folds in This document distills `04-build-plan.md` into a concrete, staged build process and folds in
two locked decisions: **ADR-011** (faceted six-namespace taxonomy) and **ADR-012** (reuse the two locked decisions: **ADR-011** (faceted six-namespace taxonomy) and **ADR-012** (reuse the
@ -337,9 +337,9 @@ Graphify config.
via the Bash tool. No server process per graph; project-specific graphs are queried with via the Bash tool. No server process per graph; project-specific graphs are queried with
`--graph <project-root>/graphify-out/graph.json`. `--graph <project-root>/graphify-out/graph.json`.
- **Skills** (carry the know-how to the model): - **Skills** (carry the know-how to the model):
- `memory-write` — when to record evergreen knowledge, frontmatter contract, scope rule, vault not repo. - `/os-vault:write` — when to record evergreen knowledge, frontmatter contract, scope rule, vault not repo.
- `memory-vault` — `graphify query` vs memsearch; god-node discipline; `--budget`/`--dfs`; cross-client lookups; progressive disclosure via `summary`. - `/os-vault:query` — `graphify query` vs memsearch; god-node discipline; `--budget`/`--dfs`; cross-client lookups; progressive disclosure via `summary`.
- `memory-reorganize` — plan-mode consolidation/promotion procedure; when to trigger `--force` rebuild; human-approval guardrails. - `/os-vault:reorganize` — plan-mode consolidation/promotion procedure; when to trigger `--force` rebuild; human-approval guardrails.
- **Env vars** baked in: `OLLAMA_FLASH_ATTENTION=1`, `GRAPHIFY_OLLAMA_KEEP_ALIVE=5`, - **Env vars** baked in: `OLLAMA_FLASH_ATTENTION=1`, `GRAPHIFY_OLLAMA_KEEP_ALIVE=5`,
`OLLAMA_BASE_URL=http://127.0.0.1:11434/v1`, `OLLAMA_API_KEY=<any-non-empty>`. Note: `OLLAMA_BASE_URL=http://127.0.0.1:11434/v1`, `OLLAMA_API_KEY=<any-non-empty>`. Note:
`GRAPHIFY_OLLAMA_NUM_CTX` is NOT effective through graphify's `/v1` path — context must `GRAPHIFY_OLLAMA_NUM_CTX` is NOT effective through graphify's `/v1` path — context must
@ -369,7 +369,7 @@ These are deferred to build time. Most can be defaulted without blocking. **§6
5. **`summary` field discipline** — Graphify extracts entities and edges but does not write 5. **`summary` field discipline** — Graphify extracts entities and edges but does not write
summaries. The human (or AI at note-creation time) must write `summary:` frontmatter. Confirm summaries. The human (or AI at note-creation time) must write `summary:` frontmatter. Confirm
this holds in practice and add a lint/reminder to the memory-write skill if it drifts. this holds in practice and add a lint/reminder to the `/os-vault:write` skill if it drifts.
6. **Step 2c reference set + model selection****RESOLVED (2026-06-04/05):** The reference 6. **Step 2c reference set + model selection****RESOLVED (2026-06-04/05):** The reference
set was generated: 18 fragments (6 fixtures × 3 tiers) in `benchmark/reference-outputs/`. set was generated: 18 fragments (6 fixtures × 3 tiers) in `benchmark/reference-outputs/`.

View File

@ -6,7 +6,7 @@
# SecondBrain Active Use Plan # SecondBrain Active Use Plan
_Last updated: 2026-06-27_ _Last updated: 2026-07-02_
_Status: Planning_ _Status: Planning_
## Problem ## Problem
@ -44,7 +44,7 @@ All pieces are self-contained; they build on each other but do not introduce ext
## Surfaces Touched ## Surfaces Touched
- **Vault content:** `~/Documents/SecondBrain/` (notes, templates, vault-conventions.md updates) - **Vault content:** `~/Documents/SecondBrain/` (notes, templates, vault-conventions.md updates)
- **Plugin code:** `cc-os/plugins/memory/` (hooks: `session_start.py` extended; new build step for index) - **Plugin code:** `cc-os/plugins/os-vault/` (hooks: `session_start.py` extended; new build step for index)
- **Plugin config:** `config.yaml` — no changes required (log index build status if helpful) - **Plugin config:** `config.yaml` — no changes required (log index build status if helpful)
- **Settings:** `~/.claude/settings.json` — only if new hook is needed; likely already covered by SessionStart - **Settings:** `~/.claude/settings.json` — only if new hook is needed; likely already covered by SessionStart
- **Project repos:** No changes to project CLAUDE.md files. Project notes live in SecondBrain, not in repos. - **Project repos:** No changes to project CLAUDE.md files. Project notes live in SecondBrain, not in repos.
@ -76,7 +76,7 @@ Create a JSON file at `~/Documents/SecondBrain/vault-index.json` with structure
### 4. `/memory-find` skill (Size: S) ### 4. `/memory-find` skill (Size: S)
Create a skill in `cc-os/plugins/memory/skills/memory-find.md` that accepts a tag argument, loads vault-index.json, filters for matching tags, and returns results as a bulleted list: path, title, summary. One line per match. No embedded note fetching; AI reads summaries and decides which notes to open with `/memory-recall` or manual Read tool calls. Create a skill in `cc-os/plugins/os-vault/skills/memory-find.md` that accepts a tag argument, loads vault-index.json, filters for matching tags, and returns results as a bulleted list: path, title, summary. One line per match. No embedded note fetching; AI reads summaries and decides which notes to open with `/memory-recall` or manual Read tool calls.
### 5. Project note format + initial project notes (Size: S) ### 5. Project note format + initial project notes (Size: S)

View File

@ -1,6 +1,6 @@
# SecondBrain Content Plan (Plan A) # SecondBrain Content Plan (Plan A)
_Status: Phase 1 complete (2026-06-30); Phase 2 ongoing. Last updated: 2026-06-30._ _Status: Phase 1 complete (2026-06-30); Phase 2 ongoing. Last updated: 2026-07-02._
> Plan A of two. Plan A solves the **content problem** — the vault is dormant because it holds > Plan A of two. Plan A solves the **content problem** — the vault is dormant because it holds
> too little valuable knowledge to be worth querying. Plan B (separate doc) solves the > too little valuable knowledge to be worth querying. Plan B (separate doc) solves the
@ -209,8 +209,8 @@ source: [project name] # project that spawned the note (e.g., llf-schema, desig
### Phase 1 — Harden the Foundation ### Phase 1 — Harden the Foundation
**Status: COMPLETE (2026-06-30).** All of Step 1Step 3 below are done: `vault-conventions.md` **Status: COMPLETE (2026-06-30).** All of Step 1Step 3 below are done: `vault-conventions.md`
reconciled to the single authoritative typed schema (issue #1); the `memory-template` skill reconciled to the single authoritative typed schema (issue #1); the `/os-vault:design-template` skill
written at `cc-os/plugins/memory/skills/memory-template/SKILL.md` (issue #2); the three written at `cc-os/plugins/os-vault/skills/design-template/SKILL.md` (issue #2); the three
templates (`howto.md`, `convention.md`, `reference.md`) created in templates (`howto.md`, `convention.md`, `reference.md`) created in
`~/Documents/SecondBrain/_templates/` and dogfooded (issues #3#5); the four proof-of-concept `~/Documents/SecondBrain/_templates/` and dogfooded (issues #3#5); the four proof-of-concept
notes patched (issue #6). Issue #7 (Phase 2) remains open — see the Phase 2 status note below. notes patched (issue #6). Issue #7 (Phase 2) remains open — see the Phase 2 status note below.
@ -228,9 +228,9 @@ content intact. A contradictory conventions doc undermines every note that refer
Step 1 (reconciling the frontmatter schema) must be complete before this step — templates sit on top of the frontmatter contract. Step 1 (reconciling the frontmatter schema) must be complete before this step — templates sit on top of the frontmatter contract.
**Step 2a — Write the `memory-template` plugin skill** **Step 2a — Write the `/os-vault:design-template` plugin skill**
Location: `cc-os/plugins/memory/skills/memory-template/SKILL.md` — alongside the existing skills (`memory-vault`, `memory-write`, `memory-project`, `memory-reorganize`). It is Graphify-indexed in the cc-os project graph, not the vault graph. Location: `cc-os/plugins/os-vault/skills/design-template/SKILL.md` — alongside the existing skills (`query`, `write`, `onboard-project`, `reorganize`). It is Graphify-indexed in the cc-os project graph, not the vault graph.
The skill handles two related workflows, routing between them based on context: The skill handles two related workflows, routing between them based on context:
- **Template design** — the repeatable 4-step process for designing any note-type template. - **Template design** — the repeatable 4-step process for designing any note-type template.
@ -263,7 +263,7 @@ Key design decisions baked in to the template-design flow:
Location: `~/Documents/SecondBrain/_templates/` Location: `~/Documents/SecondBrain/_templates/`
Apply the Step 2a process (from the `memory-template` skill) to each type in this order: Apply the Step 2a process (from the `/os-vault:design-template` skill) to each type in this order:
1. `howto.md` — first, because the template-design flow dogfoods it 1. `howto.md` — first, because the template-design flow dogfoods it
2. `convention.md` 2. `convention.md`
3. `reference.md` — include the sub-template variant selector in the body 3. `reference.md` — include the sub-template variant selector in the body
@ -290,7 +290,7 @@ population; began once Phase 1 landed (2026-06-30).
signal for a given type. signal for a given type.
- Use the SessionEnd catch-all (once Plan B is live) to discover new candidates between - Use the SessionEnd catch-all (once Plan B is live) to discover new candidates between
sessions. sessions.
- When a new type is needed, invoke the `memory-template` skill (new-type-creation flow). - When a new type is needed, invoke the `/os-vault:design-template` skill (new-type-creation flow).
Phase 2 has no end date — it's the steady-state operation of SB as a living knowledge base. Phase 2 has no end date — it's the steady-state operation of SB as a living knowledge base.

View File

@ -1,6 +1,6 @@
# SecondBrain Findability Plan # SecondBrain Findability Plan
_Last updated: 2026-06-28_ _Last updated: 2026-07-02_
_Status: Planning_ _Status: Planning_
## Problem ## Problem
@ -34,8 +34,8 @@ This plan covers four phases, strictly sequenced — each phase depends on the p
## Surfaces Touched ## Surfaces Touched
- **Plugin code:** `cc-os/plugins/memory/hooks/session_context.py` (extend for Phase 2 injection + Phase 3 queue processing), `cc-os/plugins/memory/hooks/vault_index_rebuild.py` (new), `cc-os/plugins/memory/hooks/session_end.py` (extend for Phase 3 queue writing + git SHA capture) - **Plugin code:** `cc-os/plugins/os-vault/hooks/session_context.py` (extend for Phase 2 injection + Phase 3 queue processing), `cc-os/plugins/os-vault/hooks/vault_index_rebuild.py` (new), `cc-os/plugins/os-vault/hooks/session_end.py` (extend for Phase 3 queue writing + git SHA capture)
- **Skills:** `cc-os/plugins/memory/skills/memory-find.md` (new) - **Skills:** `cc-os/plugins/os-vault/skills/memory-find.md` (new)
- **Vault content:** `~/Documents/SecondBrain/vault-index.json` (new), `~/Documents/SecondBrain/project/` directory (new), hub notes as density warrants - **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) - **Settings:** `~/.claude/settings.json` — add `vault_index_rebuild.py` as fourth SessionEnd hook (separate hook, mirrors `memsearch_sync.py` / `vault_sync.py` pattern)
@ -73,7 +73,7 @@ Decision: separate hook (not extending `session_end.py`) — mirrors `memsearch_
Prerequisite: Phase 1 complete (vault-index.json exists). Prerequisite: Phase 1 complete (vault-index.json exists).
**/memory-find skill** **/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. Location: `cc-os/plugins/os-vault/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. 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.
@ -124,6 +124,6 @@ This phase is complete when the SessionEnd agent's "create" suggestions drop to
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. 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. 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) `/os-vault:onboard-project` skill creates it during onboarding. Current design: option (c) — `/os-vault:onboard-project` skill writes a `project/[name].md` to the vault as part of onboarding. Confirm this in the onboard-project skill spec.
4. **Queue file retention policy:** How long should unprocessed queue files persist? If the next session is in a different project directory, does `session_context.py` still pick up the queue? Simplest answer: always process any queue file regardless of current project — knowledge extraction is global. Retain queue files until processed; delete on successful processing. 4. **Queue file retention policy:** How long should unprocessed queue files persist? If the next session is in a different project directory, does `session_context.py` still pick up the queue? Simplest answer: always process any queue file regardless of current project — knowledge extraction is global. Retain queue files until processed; delete on successful processing.

View File

@ -1,5 +1,5 @@
{ {
"name": "memory", "name": "os-vault",
"description": "Vault and graph memory system for Claude Code — integrates SecondBrain knowledge graph, episodic journal, and convention summaries into every session", "description": "Vault and graph memory system for Claude Code — integrates SecondBrain knowledge graph, episodic journal, and convention summaries into every session",
"version": "0.1.0" "version": "0.1.0"
} }

View File

@ -37,10 +37,10 @@ Shared modules: `hooks/config.py`, `hooks/hook_io.py`, `hooks/session_state.py`.
## Skills ## Skills
- `skills/memory-query.md` — When and how to query the vault graph - `skills/query/SKILL.md` — When and how to query the vault graph
- `skills/memory-write.md` — When and how to write to the vault - `skills/write/SKILL.md` — When and how to write to the vault
- `skills/memory-reorganize.md` — Plan-mode vault consolidation - `skills/reorganize/SKILL.md` — Plan-mode vault consolidation
## Configuration ## Configuration
Edit `cc-os/plugins/memory/config.yaml` (or via the symlink `~/.claude/plugins/memory/config.yaml`) to change vault path, model, or thresholds. Edit `cc-os/plugins/os-vault/config.yaml` (or via the symlink `~/.claude/plugins/os-vault/config.yaml`) to change vault path, model, or thresholds.

View File

@ -14,7 +14,7 @@ try:
except Exception: # pragma: no cover - yaml is provided via graphify except Exception: # pragma: no cover - yaml is provided via graphify
yaml = None yaml = None
CONFIG_PATH = os.path.expanduser("~/.claude/plugins/memory/config.yaml") CONFIG_PATH = os.path.expanduser("~/.claude/plugins/os-vault/config.yaml")
DEFAULT_VAULT_PATH = "~/Documents/SecondBrain" DEFAULT_VAULT_PATH = "~/Documents/SecondBrain"
DEFAULT_GRAPHIFY_OUTPUT_DIR = "~/Documents/SecondBrain/.graphify" DEFAULT_GRAPHIFY_OUTPUT_DIR = "~/Documents/SecondBrain/.graphify"

View File

@ -2,7 +2,7 @@
description: Manage per-project Graphify knowledge graphs — onboard, update, remove, and query codebase structure for the current repo description: Manage per-project Graphify knowledge graphs — onboard, update, remove, and query codebase structure for the current repo
--- ---
**Scope:** project graph at `./graphify-out/graph.json` — codebase structure and module relationships for the current repo only. For cross-project evergreen knowledge, use `memory-vault`. **Scope:** project graph at `./graphify-out/graph.json` — codebase structure and module relationships for the current repo only. For cross-project evergreen knowledge, use `/os-vault:query`.
## Onboard ## Onboard
@ -71,7 +71,7 @@ Delete `graphify-out/` when the project is inactive or the graph is too stale. T
graphify query "<question>" --graph ./graphify-out/graph.json graphify query "<question>" --graph ./graphify-out/graph.json
``` ```
For traversal mechanics (`graphify path`, `graphify explain`, `--budget`, `--dfs`), see `memory-vault` — query mechanics are not duplicated here. For traversal mechanics (`graphify path`, `graphify explain`, `--budget`, `--dfs`), see `/os-vault:query` — query mechanics are not duplicated here.
## Graph path discovery ## Graph path discovery

View File

@ -2,7 +2,7 @@
description: Query the SecondBrain vault knowledge graph for cross-project evergreen knowledge — conventions, tool behavior, client facts, patterns that generalize beyond one repo description: Query the SecondBrain vault knowledge graph for cross-project evergreen knowledge — conventions, tool behavior, client facts, patterns that generalize beyond one repo
--- ---
**Scope:** vault at `~/Documents/SecondBrain` — cross-project evergreen knowledge, not codebase structure. For codebase structure and module relationships in the current repo, use `memory-project`. **Scope:** vault at `~/Documents/SecondBrain` — cross-project evergreen knowledge, not codebase structure. For codebase structure and module relationships in the current repo, use `/os-vault:onboard-project`.
Use this skill when you need to retrieve evergreen knowledge from the SecondBrain vault (conventions, tool/API behavior, client facts, cross-project patterns). For **episodic questions** ("what did we do last week", "when did X happen"), use memsearch instead. Use this skill when you need to retrieve evergreen knowledge from the SecondBrain vault (conventions, tool/API behavior, client facts, cross-project patterns). For **episodic questions** ("what did we do last week", "when did X happen"), use memsearch instead.
@ -38,4 +38,4 @@ For questions about sessions, events, or time-ordered history, use memsearch dir
## Writing to vault ## Writing to vault
Use `memory-write` when knowledge generalizes beyond the current repo. Routing heuristic: "Would this be useful outside this repo, next year?" If yes → vault via `memory-write`. If no → project-graph only (no persistent write needed). See `~/.claude/CLAUDE.md` for the full routing rule. Use `/os-vault:write` when knowledge generalizes beyond the current repo. Routing heuristic: "Would this be useful outside this repo, next year?" If yes → vault via `/os-vault:write`. If no → project-graph only (no persistent write needed). See `~/.claude/CLAUDE.md` for the full routing rule.

View File

@ -22,7 +22,7 @@ description: Consolidate, promote, or restructure vault notes — plan mode only
4. **Execute edits** — make the approved changes 4. **Execute edits** — make the approved changes
5. **Force rebuild:** after any reorganization that removes, renames, or restructures notes, run: 5. **Force rebuild:** after any reorganization that removes, renames, or restructures notes, run:
```bash ```bash
# vault_path and ollama_model from ~/.claude/plugins/memory/config.yaml # vault_path and ollama_model from ~/.claude/plugins/os-vault/config.yaml
graphify extract <vault-path> --backend ollama --model <configured-model> --force graphify extract <vault-path> --backend ollama --model <configured-model> --force
``` ```

View File

@ -25,7 +25,7 @@ to prevent symlink leaks). The harness sets `HOME="$SANDBOX"` so all hook code t
Key sandbox contents created before each hook run: Key sandbox contents created before each hook run:
- `$SANDBOX/.claude/plugins/memory/config.yaml` — points `vault_path` and - `$SANDBOX/.claude/plugins/os-vault/config.yaml` — points `vault_path` and
`graphify_output_dir` at sandbox-local dirs `graphify_output_dir` at sandbox-local dirs
- `$SANDBOX/vault/journal/` — journal target for `session_end.py` - `$SANDBOX/vault/journal/` — journal target for `session_end.py`
- `$SANDBOX/.cache/graphify/` — stamp/lock/log directory for `session_start.py` - `$SANDBOX/.cache/graphify/` — stamp/lock/log directory for `session_start.py`
@ -120,7 +120,7 @@ The bash hooks (`hooks/*.sh`) were removed after parity was verified — they li
history only. The only supported invocation uses the Python hooks via `tests/python-wrappers/`: history only. The only supported invocation uses the Python hooks via `tests/python-wrappers/`:
```bash ```bash
cd /home/jared/dev/cc-os/plugins/memory/tests cd /home/jared/dev/cc-os/plugins/os-vault/tests
HOOKS_DIR="$(pwd)/python-wrappers" bash generate-fixtures.sh HOOKS_DIR="$(pwd)/python-wrappers" bash generate-fixtures.sh
``` ```
@ -141,7 +141,7 @@ fixtures (e.g. after modifying a hook):
2. Run generate-fixtures.sh via python-wrappers with a replay dir: 2. Run generate-fixtures.sh via python-wrappers with a replay dir:
```bash ```bash
HOOKS_DIR=/home/jared/dev/cc-os/plugins/memory/tests/python-wrappers \ HOOKS_DIR=/home/jared/dev/cc-os/plugins/os-vault/tests/python-wrappers \
bash tests/generate-fixtures.sh --replay-dir /tmp/replay-out bash tests/generate-fixtures.sh --replay-dir /tmp/replay-out
``` ```
This writes new fixtures to `/tmp/replay-out` using the Python hooks. This writes new fixtures to `/tmp/replay-out` using the Python hooks.

View File

@ -77,8 +77,8 @@ make_sandbox() {
sb=$(mktemp -d) sb=$(mktemp -d)
sb=$(cd "$sb" && pwd -P) sb=$(cd "$sb" && pwd -P)
mkdir -p "$sb/.claude/plugins/memory" mkdir -p "$sb/.claude/plugins/os-vault"
cat > "$sb/.claude/plugins/memory/config.yaml" <<YAML cat > "$sb/.claude/plugins/os-vault/config.yaml" <<YAML
vault_path: ${sb}/vault vault_path: ${sb}/vault
graphify_output_dir: ${sb}/vault/graphify-out graphify_output_dir: ${sb}/vault/graphify-out
ollama_model: qwen25-coder-7b-16k ollama_model: qwen25-coder-7b-16k

View File

@ -58,8 +58,8 @@ trap cleanup EXIT
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# 2. Populate sandbox structure # 2. Populate sandbox structure
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
mkdir -p "$SANDBOX/.claude/plugins/memory" mkdir -p "$SANDBOX/.claude/plugins/os-vault"
cat > "$SANDBOX/.claude/plugins/memory/config.yaml" <<YAML cat > "$SANDBOX/.claude/plugins/os-vault/config.yaml" <<YAML
vault_path: ${SANDBOX}/vault vault_path: ${SANDBOX}/vault
graphify_output_dir: ${SANDBOX}/vault/graphify-out graphify_output_dir: ${SANDBOX}/vault/graphify-out
ollama_model: qwen25-coder-7b-16k ollama_model: qwen25-coder-7b-16k