diff --git a/docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md b/docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md index 9a9ca61..34e44d1 100644 --- a/docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md +++ b/docs/adr/0019-session-start-hook-keeps-the-apm-install-current.md @@ -115,8 +115,9 @@ A test pins the reference. > emptied it. `tests/test-apm-current-hook.sh` still pins the literal string. **Session startup gets slower when the install is stale.** Measured: ~0.7 s for the `apm outdated` -check when everything is current, ~10.4 s when six packages are behind and the refresh runs. The -hook declares `timeout: 380` to cover a cold multi-package fetch. That number is not free-standing: +check when everything is current, ~10.4 s when six packages are behind and the refresh runs +(re-measured 2026-09-16: ~24–26 s for the same six-behind refresh, warm, on a LAN remote — still +well inside the budget below). The hook declares `timeout: 380` to cover a cold multi-package fetch. That number is not free-standing: the script imposes its own `timeout 60` on `apm outdated` and `timeout 300` on `apm update`, so the host-side timeout has to exceed their sum or the host kills the hook mid-update and leaves `.claude/skills/` half-deployed with no notice emitted. An earlier revision declared `320`, which @@ -145,6 +146,21 @@ to plural-only fails it. deploy until this change is merged and `apm update` has run once against the new default branch. Until then the repo has the mechanism in source and not in effect. +**On a feature branch, the refresh installs `main`, not the branch.** Added 2026-09-16, after it +happened. The dependencies resolve against the remote default branch, so a session opened on a +branch that changes `plugins/` loads `main`'s content, refreshed or not — the branch's own edits +are never live until merged. Two visible effects follow. Content the branch *removes* comes back in +the deployed install: on `docs/simplification-audit` a refresh redeployed `main`'s `skill-audit` +and `agent-audit` over the branch's merged `factory-audit`, and re-materialised `main`'s +`plugins/bin/.mcp.json` into `apm_modules/`, so the gitignored root `.mcp.json` regained the +`obsidian` server the branch deleted — invisible to `git status`. And the rewritten +`apm.lock.yaml` records `main`'s commit, so on a branch it should be discarded +(`git checkout -- apm.lock.yaml`, then `apm install` to bring the deployed tree back in line with +the lock, or `apm pack --check-clean` refuses to run), not committed. Skipping the refresh off the +default branch was considered and rejected: it would not make the branch live, only freeze the +session on an older `main` — the silent staleness this ADR exists to prevent. Both effects end when +the branch merges; apm removes a server that is no longer declared on its next update. + **`.claude/settings.json` stops being `{"hooks": {}}`.** apm merges the hook into it and tracks ownership in a `.claude/apm-hooks.json` sidecar, with the script copied to `.claude/hooks//`. The sidecar and the script directory are gitignored install output; the