diff --git a/docs/superpowers/contracts/extract-session-autopsy-2026-07-26.json b/docs/superpowers/contracts/extract-session-autopsy-2026-07-26.json new file mode 100644 index 00000000..c5934bb9 --- /dev/null +++ b/docs/superpowers/contracts/extract-session-autopsy-2026-07-26.json @@ -0,0 +1,16 @@ +{ + "title": "Extract session_autopsy and the MCP fleet out of the monorepo", + "objective": "testsAndMisc carried 12GB of third-party MCP clones and a self-contained analyzer package that has no monorepo dependencies. Both move to kuhyx/mcp-servers. Success is: the SessionEnd hook still ingests transcripts, every registered MCP server still resolves its binary, and no history is lost.", + "acceptance_criteria": [ + "session_autopsy history preserved via git subtree split, not a copy", + "SessionEnd hook exercised end to end against a real transcript with an empty error log", + "All MCP command paths verified to resolve after the move (12 references across 4 config files)", + "The 12GB of clones is moved and gitignored, never committed; a pinned manifest + setup.sh reconstructs it", + "testsAndMisc pre-commit gate passes with no --no-verify" + ], + "out_of_scope": [ + "Rebuilding any MCP server binary", + "third_party/agent-skills, which is unrelated to MCP and stays" + ], + "verifier": "bash ~/.claude/hooks/session_autopsy_end.sh against a real transcript; a script asserting every mcpServers command path exists; pre-commit run" +} diff --git a/docs/superpowers/evidence/extract-session-autopsy-2026-07-26.json b/docs/superpowers/evidence/extract-session-autopsy-2026-07-26.json new file mode 100644 index 00000000..29bbd6b7 --- /dev/null +++ b/docs/superpowers/evidence/extract-session-autopsy-2026-07-26.json @@ -0,0 +1,38 @@ +{ + "intent": "Remove from the monorepo two things that do not belong in it: a 12GB tree of third-party clones, and a self-contained analyzer package.", + "scope": [ + "python_pkg/session_autopsy/ (26 tracked files) -> kuhyx/mcp-servers/session-autopsy/", + "third_party/mcp/ (12GB, untracked) -> ~/mcp-servers/servers/, gitignored", + "Non-goal: third_party/agent-skills, unrelated to MCP" + ], + "changes": [ + "git subtree split preserved session_autopsy's history; it only ever imported itself, so the extraction needed nothing but python_pkg.session_autopsy -> session_autopsy.", + "The 12GB tree was moved by rename (same filesystem) and gitignored. What is tracked instead is servers.json - upstream URL, branch and exact commit for all 24 - plus an idempotent setup.sh that reconstructs the fleet. 20KB tracked in place of 12GB.", + "12 absolute-path references rewritten across ~/.claude.json and three mcp-optional configs." + ], + "verification": [ + { + "command": "bash ~/.claude/hooks/session_autopsy_end.sh ", + "result": "pass", + "evidence": "exit 0, hook.log empty, store grew to 275 sessions. An earlier run failed with an AttributeError that turned out to be a stale __pycache__ from before the restructure, not a code fault - a clean run ingests 1,026 assistant messages." + }, + { + "command": "python3 -c ''", + "result": "pass", + "evidence": "5 servers now under mcp-servers/ all resolve (reflex, servo-fetch, vestige, toolport, go-docs-mcp); no broken command path in any config." + }, + { + "command": "diff -r old new", + "result": "pass", + "evidence": "Every difference between the extracted and original copies mentions the package name - i.e. imports only." + } + ], + "risks": [ + "MCP servers already running from the old path keep their old cwd until the session restarts; new sessions pick up the rewritten config.", + "servers/ binaries under target/ are build output: a fresh clone needs setup.sh plus a per-server build before the registrations work." + ], + "rollback": [ + "git revert this commit restores the package; the clones can be moved back with a single mv and the config paths rewritten in reverse.", + "Config backups were taken to the session scratchpad before rewriting." + ] +} diff --git a/linux_configuration/tests/test_session_autopsy_hooks.py b/linux_configuration/tests/test_session_autopsy_hooks.py index 2976cee0..cbe30d2d 100644 --- a/linux_configuration/tests/test_session_autopsy_hooks.py +++ b/linux_configuration/tests/test_session_autopsy_hooks.py @@ -144,11 +144,16 @@ class TestSessionEndHookLaunchesIngest: json.dumps({"transcript_path": str(transcript)}), ) argv = _await_launch(record) - assert "python_pkg.session_autopsy" in argv + # session_autopsy was extracted from this monorepo to kuhyx/mcp-servers; + # the hook must launch it from there, not from a python_pkg that no longer + # exists here. This test reads the DEPLOYED hook, which is why it caught the + # move rather than passing against a stale copy. + assert "-m session_autopsy" in argv + assert "python_pkg" not in argv assert "ingest" in argv assert str(transcript) in argv assert "--quiet" in argv - assert f"PYTHONPATH={home}/testsAndMisc" in argv + assert f"PYTHONPATH={home}/mcp-servers/session-autopsy" in argv assert "timeout 120" in argv def test_creates_the_autopsy_home(self, tmp_path: Path) -> None: