Files
claudetools/.claude/commands/save.md
Mike Swanson a18fa5f93a ClaudeTools cleanup: drop dead context-recall layer, unify /save + /sync
Deletions (~1,500 lines of dead docs):
- .claude/hooks/ — docs-only directory, no executables. Referenced scripts
  setup-context-recall.sh / test-context-recall.sh did not exist. Hooks
  would have POSTed to localhost:8000; the API actually ran at
  172.16.3.30:8001 and is no longer in use.
- .claude/AUTO_CONTEXT_SYSTEM.md — 347-line duplicate spec of CLAUDE.md's
  Automatic Context Loading section, referencing unimplemented hooks.
- .claude/URGENT-vault-path-bug.md — 217-line urgency note for a fix that
  already shipped weeks ago.
- .claude/context-recall-config.env.example — config template for the same
  dead system.

Refactors (~500 lines net removed):
- /save and /sync now wrap bash .claude/scripts/sync.sh as the single
  source of truth for git ops. /save adds a session-log-writing step in
  front; /sync invokes the script directly.
- Dropped /sync's manual git phases that contradicted sync.sh.
- Dropped the cp -r ~/ClaudeTools/.claude/commands/* ~/.claude/commands/
  step (clobbered per-user customization in the multi-user model).
- Dropped auto-invoke of /refresh-directives (command does not exist).
- Dropped references to directives.md (file does not exist).
- /save now documents the rm -f save_narrative_prompt.txt step, fixing
  the stale-prompt bug Howard documented in feedback_tmp_path_windows.md.

Fixes:
- CLAUDE.md SESSION_STATE.md reference replaced with the canonical
  PROJECT_STATE.md (per-project, with protocol at
  .claude/PROJECT_STATE_PROTOCOL.md). 16 client folders already use
  PROJECT_STATE.md; SESSION_STATE.md was only a stale reference.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 18:33:46 -07:00

5.3 KiB

Save a comprehensive session log to the appropriate session-logs/ directory, then sync the repo.

/save and /sync share bash .claude/scripts/sync.sh as the canonical driver for git operations. The only difference: /save writes a session log first, then calls sync. /sync calls sync directly (no log).


Phase 1 — Generate the narrative

Ollama drafts the prose sections (qwen3:14b at localhost:11434 or Tailscale 100.92.127.64:11434). Claude owns the factual sections — never delegate facts to Ollama.

Author Sections
Ollama Session Summary, Key Decisions, Problems Encountered
Claude (verbatim) User block, Configuration Changes, Credentials, Infrastructure, Commands & Outputs, Pending Tasks, References

Resolve Ollama endpoint

if curl -s -m 2 http://localhost:11434/api/tags >/dev/null 2>&1; then
  OLLAMA="http://localhost:11434"
elif curl -s -m 3 http://100.92.127.64:11434/api/tags >/dev/null 2>&1; then
  OLLAMA="http://100.92.127.64:11434"
else
  OLLAMA=""  # Claude drafts narrative directly
fi

Draft via Ollama

Always delete the prompt file first — prior /save runs leave a stale save_narrative_prompt.txt in %LOCALAPPDATA%/Temp, and the Write tool refuses to overwrite without a Read. The silent fallback is py reading the leftover file and Ollama producing a perfectly-coherent narrative about the previous session's work. Documented in .claude/memory/feedback_tmp_path_windows.md.

PROMPT_FILE="$LOCALAPPDATA/Temp/save_narrative_prompt.txt"
rm -f "$PROMPT_FILE"  # critical — see above
# ... then Write the prompt with this session's WORK DONE bullets ...

Prompt template:

You are a technical session log writer for an MSP (Arizona Computer Guru). Write three sections in markdown. Be concise, factual, technical. No filler phrases. Use past tense. No emojis.

WORK DONE THIS SESSION:
<paste bullet list of what happened>

Write these three sections only:

## Session Summary
<3-5 paragraph narrative: what was accomplished, in what order, why>

## Key Decisions
<bullet list of non-obvious decisions and their rationale>

## Problems Encountered
<bullet list of problems hit and how each was resolved; omit if none>

Run via Python (PyJWT-free path):

py -c "
import urllib.request, json
prompt = open('$PROMPT_FILE', encoding='utf-8').read()
body = json.dumps({'model':'qwen3:14b','messages':[{'role':'user','content':prompt}],'stream':False,'think':False}).encode()
res = json.loads(urllib.request.urlopen(urllib.request.Request('$OLLAMA/api/chat', body), timeout=300).read())
print(res['message']['content'])
"

Claude reviews the output before assembling. Common Ollama issues to fix on review: invented compliance/risk language, hallucinated reasoning, off-task content if the prompt file was stale.


Phase 2 — Write to disk

Location

Work scope Path
Single project projects/<project>/session-logs/YYYY-MM-DD-session.md
Client clients/<slug>/session-logs/YYYY-MM-DD-session.md
Multi-project / general session-logs/YYYY-MM-DD-session.md

Filename + append behavior

  • Filename: YYYY-MM-DD-session.md (today's local date)
  • If file exists, append a ## Update: HH:MM PT — <topic> section. Do not overwrite.
  • If two users worked on the same date, namespace: YYYY-MM-DD-<user>-<topic>.md (e.g. 2026-05-01-howard-syncro-billing-batch.md)

Required sections (in order)

  1. User block — name, machine, role, session span. Pull from .claude/identity.json + git config.
  2. Session Summary (Ollama)
  3. Key Decisions (Ollama)
  4. Problems Encountered (Ollama)
  5. Configuration Changes — files modified / created / deleted (with paths)
  6. Credentials & Secrets — UNREDACTED if newly discovered or created. Vault paths if vaulted. Never half-redact a value future-Claude might need.
  7. Infrastructure & Servers — IPs, hostnames, ports, tenant IDs, container names, DNS, certs
  8. Commands & Outputs — important one-liners, key outputs, error messages with resolution
  9. Pending / Incomplete Tasks — what's left, blockers, next steps
  10. Reference Information — URLs, endpoints, commit SHAs, ticket IDs, routine IDs, file paths

When in doubt, include MORE detail — future sessions search these logs to recover context.


Phase 3 — Sync

bash .claude/scripts/sync.sh

sync.sh handles: stage tracked changes by name (never git add -A), auto-commit, fetch + rebase, push, then the same flow for the vault repo, then surface cross-user ## Note for <user> blocks.

After sync, emit a Post-commit Summary:

## Post-commit Summary
Commit:  <sha>  <subject>
Author:  <name> <<email>>
Push:    <old>..<new>  main -> main  (origin)
File:    <session log path>  (+N lines, appended/created)

Cross-user note handling (CRITICAL)

If sync.sh surfaces a ## Note for <user> or ## Message for <user> block from an incoming session log, display it prominently at the top of the response, before the sync summary:

============================================================
MESSAGE FROM <author> (<date>)
============================================================
<full note content>
============================================================

Explicitly address each action item or question before moving on.