cc-os/openspec/changes/archive/2026-06-12-memory-plugin-so.../tasks.md

3.6 KiB

1. Capture current behavior (golden fixtures)

  • 1.1 For each of the 4 bash hooks (session_start.sh, session_context.sh, post_tool_use_write.sh, session_end.sh), write a golden fixture: known stdin JSON → snapshot of side effects (journal append content, rebuild-stamp invalidation, touched-paths temp file contents, parsed config env vars)
  • 1.2 Store fixtures under cc-os/plugins/memory/tests/fixtures/ with one subdirectory per hook
  • 1.3 Confirm each fixture can be run against the current bash hook and produces the expected snapshot output

2. Move plugin source into cc-os (no behavior change)

  • 2.1 Copy ~/.claude/plugins/memory/ verbatim into cc-os/plugins/memory/ under git (bash hooks, config.yaml, skills — exactly as-is)
  • 2.2 Commit to git; confirm git status shows only the new plugins/memory/ tree, no diffs to existing files
  • 2.3 Do NOT yet repoint the marketplace or change any hook behavior — this establishes the seam only

3. Port to Python deep module

  • 3.1 Implement config.py: load_config() -> Config frozen dataclass; handles YAML parse, path expansion, defaults, missing file — replaces all 3 inline parsers
  • 3.2 Implement hook_io.py: read_input() -> HookInput dataclass (session_id, cwd, file_path, reason); replaces all 4 inline stdin parsers and the python3-vs-jq inconsistency
  • 3.3 Implement session_state.py: record_touch(session_id, path) / read_touches(session_id) -> list[str]; encapsulates the /tmp/claude-vault-touched-$SESSION_ID temp-file contract (file still exists by necessity — separate process invocations; the win is an explicit named contract)
  • 3.4 Implement thin hook entry points: hooks/session_start.py, hooks/session_context.py, hooks/post_tool_use_write.py, hooks/session_end.py (vault journal only)
  • 3.5 Implement hooks/memsearch_sync.py as a separate SessionEnd hook entry (split from session-end); preserve exact ADR-015 sync behavior (auto-commit+push to forgejo.swansoncloud.com/jared/memsearch)
  • 3.6 Wrap every main() in try/except: uncaught exceptions log to stderr and exit 0 (fail-open invariant)

4. Verify parity against golden fixtures

  • 4.1 Run each Python hook entry point against the golden fixtures from task 1; assert output is identical to the bash snapshots
  • 4.2 Fix any divergences; do NOT proceed to cleanup or cutover until all fixtures pass
  • 4.3 Only after fixture parity is confirmed: clean up any dead code, simplify, refactor

5. Cut over marketplace to cc-os source (LAST functional task)

  • 5.1 Verify the exact mechanism to repoint the local-plugins marketplace (source-path change vs symlink vs re-registration) — do not assume; confirm against current Claude Code plugin system behavior
  • 5.2 Repoint local-plugins marketplace entry for memory to cc-os/plugins/memory/
  • 5.3 Update ~/.claude/settings.json hook entries to invoke the Python scripts
  • 5.4 Start a new Claude Code session; confirm memory plugin loads from cc-os path and all hooks fire correctly

6. Documentation and ADR

  • 6.1 Add ADR-016 to docs/memory-system/03-architecture-decisions.md recording the three decisions: source location, module shape (deep functions vs OO hierarchy), and memsearch-sync split (relocation not reversal of ADR-015)
  • 6.2 Update CLAUDE.md Implemented Components section: plugin source pointer changed to cc-os/plugins/memory/; update hook language from bash to Python
  • 6.3 Mark this change done in docs/memory-system/04-build-plan.md and update build plan status