os-vault: add SessionStart git pull for multi-machine vault/memsearch freshness

Sync was push-only via SessionEnd (vault_sync.py/memsearch_sync.py); a second
machine's copies could go stale. session_start.py now runs a fast-forward-only,
10s-timeout git pull for both repos before the staleness check — silent on
success, quiet one-line stderr note on failure, never blocking session start.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Mb3V8NNzAuns7vgX9A2jU
This commit is contained in:
jared 2026-07-10 10:06:55 -04:00
parent c629959f37
commit cc450c385b
3 changed files with 39 additions and 6 deletions

View File

@ -1,6 +1,6 @@
# cc-os implementation status & changelog
_Last updated: 2026-07-08. This is the append-only implementation-status record moved out of
_Last updated: 2026-07-10. This is the append-only implementation-status record moved out of
`CLAUDE.md` (2026-07-08, task B1 of
[system-prompt-profiles-tasks.md](plans/system-prompt-profiles-tasks.md)). CLAUDE.md keeps
orientation only; when a build step completes, record it HERE (plus
@ -113,15 +113,23 @@ drift — see "Editing a local plugin (cache refresh)" below. Investigation resu
caches (not manifest-naming issues) were the cause; slash command registration works
correctly once caches are fresh.
**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.
**Multi-machine freshness closed (2026-07-10):** `session_start.py` gained a fast-forward-only
`git pull` (`timeout 10 git pull --ff-only --quiet`) for both `cfg.vault_path` and
`cfg.memsearch_dir`, run before the staleness check — silent on success, quiet one-line stderr
note on failure (offline machine), never blocking session start. Closes the push-only gap noted
below; mirrors the push style of `vault_sync.py`/`memsearch_sync.py` in the opposite direction.
**Remaining optional items:** additional project onboarding (one at a time, per ADR-013); bulk
vault migration. All required build steps complete as of 2026-06-15.
## Implemented components
**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),
- Hooks: `hooks/``session_start.py` (SessionStart; staleness check + detached graph
rebuild, and, as of 2026-07-10, a fast-forward-only `git pull` for `cfg.vault_path` and
`cfg.memsearch_dir` before the staleness check — silent on success, quiet one-line stderr
note on failure, never blocking), `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

View File

@ -238,7 +238,10 @@ pushes the vault to `forgejo.swansoncloud.com/jared/SecondBrain` on every sessio
daily journal note from `session_end.py` is included in the commit. Mirrors the
`memsearch_sync.py` pattern; uses `cfg.vault_path`. Smoke-tested (exit 0) 2026-06-15.
**Remaining (optional):** SessionStart `git pull` for multi-machine freshness — push-only today.
**Multi-machine freshness — DONE (2026-07-10):** `session_start.py` now runs a fast-forward-only
`git pull` (`timeout 10`, `--ff-only --quiet`) against both `cfg.vault_path` and
`cfg.memsearch_dir` before the staleness check. Silent on success; a quiet one-line stderr note
on failure (offline machine, diverged history) that never blocks or delays session start.
**Do not sync** the Graphify `graphify-out/` directories, Milvus caches, or the Ollama
models. Graphs are rebuilt per machine from the vault (the single source of truth).

View File

@ -63,6 +63,25 @@ def _log(line):
pass
def _pull_repo(repo_dir):
"""Fast-forward-only pull for a sync'd repo. Silent on success; at most a
one-line stderr note on failure (offline machine must never block or
error out session start). Mirrors vault_sync.py / memsearch_sync.py push
style but in the opposite direction (Step 5b multi-machine freshness).
"""
if not os.path.isdir(os.path.join(repo_dir, ".git")):
return
try:
r = subprocess.run(
["timeout", "10", "git", "-C", repo_dir, "pull", "--ff-only", "--quiet", "origin", "main"],
stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, text=True,
)
if r.returncode != 0:
print(f"[session-start] pull skipped for {repo_dir} (offline or diverged)", file=sys.stderr)
except Exception:
print(f"[session-start] pull skipped for {repo_dir}", file=sys.stderr)
def _needs_rebuild(stamp, stale_days):
if not os.path.exists(stamp):
return True
@ -80,6 +99,9 @@ def main():
cfg = config_mod.load_config()
_pull_repo(cfg.vault_path)
_pull_repo(cfg.memsearch_dir)
_emit_usage_note()
if os.environ.get("OS_VAULT_SKIP_REBUILD"):