v4.6.1 — Installer hook-wiring repair + harness-context hook + doctor wiring probe (V4 #39)
PATCH. Single-repo release; crickets stays at v2.1.0 (it received a byte-identical lib/install/python/install_state.py sync via ebf92fa but no release tag — lib-parity only). Fixes a v4.5.1/v4.6.0 installer regression: install.sh --scope user dropped hook dirs into ~/.claude/hooks/<name>/ but never merged their settings-fragment-bash.json into ~/.claude/settings.json, so settings.json had no hooks block and none of the 10 installed hooks fired on any device. (Surfaced when the agent missed a vault-resident PLAN.md because no SessionStart hook was wired to surface it.) The semver bump is PATCH — the regression fix is the load-bearing change; the new hook + doctor probe ride along as bundled improvements.
Added
harness-context-session-starthook (db5e6e0) — new user-scope SessionStart hook. Reads the event'scwd, resolves the active project's vaultPLAN.md+progress.mdviaharness_memory.py vault-state-path, and injects a 4-line context block at session boot — only when both files exist (silent no-op otherwise; 500ms budget;set -uo pipefail, never blocks boot). Surfaces "this project's plan lives at<vault path>" automatically in every project, closing the gap that motivated the release. pwsh twin included.
Changed
install.sh --scope usernow merges hook fragments + absolutizes paths (0baf142) — the user-scope install walks the installed<prefix>/hooks/*/dirs and merges eachsettings-fragment-bash.jsoninto<prefix>/settings.json, rewriting the command to the absolute user-scope dir layoutbash <prefix>/hooks/<name>/<name>.sh.scripts/merge-settings-fragment.pygained a--commandoverride for the absolutization (idempotent re-merge by the rewritten command)./doctorhook-wiring check (110fe9d) — replaced the false-clean "absent hooks block is OK —--hooksopt-in" with a 7-row truth table: hook dirs on disk + nohooksblock now reports[FAIL] N hooks installed but not wired — re-run install.sh(the regression), plus broken-command-path / partial-merge / missing-config / missing-fragments cases. Adds a--livesynthetic SessionStart probe. Mirrored in the canonicalharness/skills/doctor.md.
Internal
.agentm-config.jsongains an additivefragments: [{path, sha256}]field (0baf142) — records each merged settings fragment forinstall-state-syncdrift detection. Noschema_versionbump (schema v2 stays valid; field optional).lib/install/python/install_state.pypersistexposed via a new--fragments-fileCLI flag (synced byte-identical to crickets).- +18 unit tests (312 → 330 per OS workflow):
test_merge_settings_fragment.py(8),test_install_state_fragments.py(6),test_harness_context_hook.py(4).
Backward-compat
- Existing
.agentm-config.jsonfiles withoutfragmentskeep working;install.shadds the field on the next (re-)install. - Operators must re-run
bash install.sh --scope userto pick up the fix — the regression leftsettings.jsonwithout ahooksblock, so hooks stay dormant until the installer re-runs (then they fire on the next session restart).
Cross-references
- crickets
ebf92fa— byte-identicalinstall_state.pylib-sync (no crickets release). - agentm v4.6.0 — the release this patches.