docs(adr): record the feature-branch refresh hazard in ADR-0019
The session-start refresh resolves against main, so on a branch it redeploys content the branch removed and rewrites the lock to main's commit. Documented as a consequence rather than skipped in code, since a skip would only freeze the session on an older main. Also records the re-measured refresh time (~24-26 s). Simplification audit finding 34. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -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/<pkg>/`. The sidecar and the script directory are gitignored install output; the
|
||||
|
||||
Reference in New Issue
Block a user