From 1bd496d12703bfe0af955e4f5caa5d7cc6864403 Mon Sep 17 00:00:00 2001 From: Aaron Bockelie Date: Mon, 29 Jun 2026 02:14:54 -0500 Subject: [PATCH 1/2] fix(check-setup): probe embedding engine functionally, loud every session MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old session-start check was broken three ways: it looked for way-embed at $XDG_WAY/way-embed (it lives at ~/.claude/bin/way-embed, so healthy installs false-positived "not installed"), it only checked file existence (never that the engine can actually embed), and it suppressed the notice once per day. Replace it with a functional probe: ask the binary to embed a query (`ways match`) and warn only when that fails. This catches corrupt models and load-but-error binaries that existence checks miss, resolves identically across all ADR-140 topologies (in-place / copy-subdir / symlink-subdir) instead of hardcoding paths that become symlinks under projection, and fires EVERY session while broken — a degraded engine drops matching to coarse pattern-only triggers and must not be skimmable. Silent when it works. Records the topology-safety contract in ADR-140 Consequences (closes the embeddings-off observation in #195 by failing loud rather than building degraded-mode precision gating). Refs #195 --- ...-place-repo-and-subdirectory-projection.md | 6 +++ hooks/ways/check-setup.sh | 49 ++++++++++++------- 2 files changed, 36 insertions(+), 19 deletions(-) diff --git a/docs/architecture/system/ADR-140-two-install-topologies-in-place-repo-and-subdirectory-projection.md b/docs/architecture/system/ADR-140-two-install-topologies-in-place-repo-and-subdirectory-projection.md index 14c0d162..622f958e 100644 --- a/docs/architecture/system/ADR-140-two-install-topologies-in-place-repo-and-subdirectory-projection.md +++ b/docs/architecture/system/ADR-140-two-install-topologies-in-place-repo-and-subdirectory-projection.md @@ -167,6 +167,12 @@ the messaging branch are the remaining follow-on work this ADR authorizes. do not eliminate it the way symlink or in-place would. - A new marker file and a new detection branch add moving parts to the update checker, which is security-sensitive (it runs at session start). +- Session-start health checks must resolve through the binary, not hardcoded + `~/.claude/...` paths. Under symlink projection those paths are links into the subdir + repo, so a path-based check is topology-fragile — the embedding-engine notice in + `check-setup.sh` checked the wrong `way-embed` location and went stale once already. + The durable contract: probe the engine *functionally* (`ways match`), which resolves + identically across in-place, copy-subdir, and symlink-subdir installs. ### Neutral diff --git a/hooks/ways/check-setup.sh b/hooks/ways/check-setup.sh index f399a7e8..13496e16 100755 --- a/hooks/ways/check-setup.sh +++ b/hooks/ways/check-setup.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash # SessionStart: Check if ways installation is complete. # Runs as the first startup hook. If setup is incomplete, emits a -# one-time diagnostic and exits cleanly so other hooks don't error. +# diagnostic and exits cleanly so other hooks don't error. # -# Checks: ways binary → embedding model (optional) → corpus +# Checks: ways binary → corpus → embedding engine (functional probe) WAYS_BIN="${HOME}/.claude/bin/ways" XDG_WAY="${XDG_CACHE_HOME:-$HOME/.cache}/claude-ways/user" @@ -43,25 +43,36 @@ MSG exit 0 fi -# Warn loudly if embedding model is missing — ADR-125 made it a hard dependency -MODEL="${XDG_WAY}/minilm-l6-v2.gguf" -EMBED_BIN="${XDG_WAY}/way-embed" -if [[ ! -f "$MODEL" ]] || [[ ! -x "$EMBED_BIN" ]]; then - # Only mention this once per day (rate limit via marker file). - # Resolve a writable temp dir portably: TMPDIR/TEMP/TMP are set on Windows - # (Git Bash) and most CI; /tmp is the Unix fallback. - MARKER="${TMPDIR:-${TEMP:-${TMP:-/tmp}}}/.claude-embed-notice-$(date +%Y%m%d)" - if [[ ! -f "$MARKER" ]]; then - cat <<'MSG' +# Embedding engine — a hard dependency (ADR-125). Probe it *functionally* rather +# than checking file paths. Two reasons: +# 1. Path checks go stale. The old check looked for way-embed at $XDG_WAY/way-embed, +# but it actually lives at ~/.claude/bin/way-embed — so on a healthy install it +# false-positived "not installed" (masked by a once-a-day marker). +# 2. ADR-140 symlink projection makes ~/.claude/{bin,hooks,...} symlinks into a +# subdir repo. Asking the binary to actually embed a query resolves identically +# across all topologies (in-place / copy-subdir / symlink-subdir) and also +# catches a corrupt model or a binary that loads-but-errors — which existence +# checks miss entirely. +# Loud EVERY session while broken (no per-day suppression): a degraded engine means +# only coarse pattern:/commands:/files: triggers fire, and that must not be skimmable. +# Silent when it works. +probe_embed() { + if command -v timeout >/dev/null 2>&1; then + timeout 10 "$WAYS_BIN" match "$1" 2>/dev/null + else + "$WAYS_BIN" match "$1" 2>/dev/null + fi +} +if ! probe_embed "embedding engine health probe" | grep -qE '[0-9]\.[0-9]'; then + cat <<'MSG' -⚠ Embedding engine not installed — semantic way matching is unavailable. - Only explicit pattern:/commands:/files: triggers will fire. +⚠ Embedding engine is NOT functional — semantic way matching is OFF. + Only explicit pattern:/commands:/files: triggers will fire (coarse — expect ways + to over- and under-fire until this is fixed). It is a hard dependency (ADR-125). -To install: - - cd ~/.claude && make setup + Repair: + in-place install: cd ~/.claude && make setup + subdirectory install: cd && make setup && make sync-to-home MSG - touch "$MARKER" 2>/dev/null - fi fi From 45c69b258cbb19407607057379503dc2ea8f4764 Mon Sep 17 00:00:00 2001 From: Aaron Bockelie Date: Mon, 29 Jun 2026 02:14:54 -0500 Subject: [PATCH 2/2] fix(ways): drop bare generic tokens from over-firing patterns MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Five ways had pattern: regexes matching bare high-frequency tokens that collide with unrelated domains — they fired (in pattern-only mode especially) on prompts with nothing to do with the way: - migrations: drop bare `schema` (JSON/GraphQL/config schemas collide); add add.?column / drop.?(table|column) - performance: drop bare `profile` (homonym of perf profiling); add cpu.?profil / flamegraph - release: drop bare `tag`, `version.?bump`, `bump.?version` (collide with data/ schema versioning); add semver / git.?tag / release.?(notes|candidate) - patches: drop bare `patch` and `apply.*change`; lean on the precise files:/ commands: triggers, keep tight `\.patch\b|git.?(apply|am)|patch.?(set|series)` - errors: drop bare `catch` (matches "catch up", ordinary prose) The vocabulary: fields stay domain-specific; only the coarse pattern fallbacks were the problem. Semantic vocabulary-breadth collisions (e.g. "version bump") are a separate concern, as noted in #194. Closes #194 --- hooks/ways/softwaredev/code/errors/errors.md | 2 +- hooks/ways/softwaredev/code/performance/performance.md | 2 +- hooks/ways/softwaredev/delivery/migrations/migrations.md | 2 +- hooks/ways/softwaredev/delivery/patches/patches.md | 2 +- hooks/ways/softwaredev/delivery/release/release.md | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/hooks/ways/softwaredev/code/errors/errors.md b/hooks/ways/softwaredev/code/errors/errors.md index 4299ce77..32bb2fbe 100644 --- a/hooks/ways/softwaredev/code/errors/errors.md +++ b/hooks/ways/softwaredev/code/errors/errors.md @@ -1,7 +1,7 @@ --- description: error handling patterns, exception management, try-catch boundaries, error wrapping and propagation vocabulary: exception handling catch throw boundary wrap rethrow fallback graceful recovery propagate unhandled -pattern: error.?handl|exception|try.?catch|throw|catch +pattern: error.?handl|exception|try.?catch|throw scope: agent, subagent refire: 0.2 --- diff --git a/hooks/ways/softwaredev/code/performance/performance.md b/hooks/ways/softwaredev/code/performance/performance.md index 980ca6e5..e5446959 100644 --- a/hooks/ways/softwaredev/code/performance/performance.md +++ b/hooks/ways/softwaredev/code/performance/performance.md @@ -1,7 +1,7 @@ --- description: performance optimization, profiling, benchmarking, latency vocabulary: optimize profile benchmark latency throughput memory cache bottleneck flamegraph allocation heap speed slow -pattern: slow|optimi|latency|profile|performance|speed.?up|benchmark|bottleneck|throughput|memory.?leak +pattern: slow|optimi|latency|cpu.?profil|flamegraph|performance|speed.?up|benchmark|bottleneck|throughput|memory.?leak scope: agent, subagent refire: 0.2 --- diff --git a/hooks/ways/softwaredev/delivery/migrations/migrations.md b/hooks/ways/softwaredev/delivery/migrations/migrations.md index f0e69dc4..f7e3ae17 100644 --- a/hooks/ways/softwaredev/delivery/migrations/migrations.md +++ b/hooks/ways/softwaredev/delivery/migrations/migrations.md @@ -1,7 +1,7 @@ --- description: database migrations, schema changes, table alterations, rollback procedures vocabulary: migration schema alter table column index rollback seed ddl prisma alembic knex flyway -pattern: migrat|schema|database.?change|alter.?table|alembic|prisma.?migrate|knex.?migrate|flyway|liquibase +pattern: migrat|database.?change|alter.?table|add.?column|drop.?(table|column)|alembic|prisma.?migrate|knex.?migrate|flyway|liquibase scope: agent, subagent refire: 0.15 --- diff --git a/hooks/ways/softwaredev/delivery/patches/patches.md b/hooks/ways/softwaredev/delivery/patches/patches.md index 5ef7d694..b85aa03a 100644 --- a/hooks/ways/softwaredev/delivery/patches/patches.md +++ b/hooks/ways/softwaredev/delivery/patches/patches.md @@ -1,7 +1,7 @@ --- description: creating and applying patch files, git diff generation, patch series management vocabulary: patch diff apply hunk unified series format-patch -pattern: patch|\.diff|apply.*change +pattern: \.patch\b|git.?(apply|am)|patch.?(set|series) files: \.(patch|diff)$ commands: git\ apply|git\ diff.*\> scope: agent, subagent diff --git a/hooks/ways/softwaredev/delivery/release/release.md b/hooks/ways/softwaredev/delivery/release/release.md index 6a300b3d..4c456afe 100644 --- a/hooks/ways/softwaredev/delivery/release/release.md +++ b/hooks/ways/softwaredev/delivery/release/release.md @@ -2,7 +2,7 @@ description: software releases, changelog generation, version bumping, semantic versioning, tagging vocabulary: release changelog version bump semver tag publish ship major minor breaking refire: 0.15 -pattern: release|changelog|tag|version.?bump|bump.?version|npm.?publish|cargo.?publish +pattern: release|changelog|semver|git.?tag|release.?(notes|candidate)|npm.?publish|cargo.?publish scope: agent, subagent ---