fix(BUG-023): rewrite claude-mem hook probe to materialize+break (cross-OS)#89
Merged
Merged
Conversation
…ss-OS) BUG-022 fixed the BUG-015 probe by appending `head -n1` after the while loop, but the form still raced under `set -euo pipefail` when 2+ candidates matched in `~/.claude/plugins/cache/thedotmack/claude-mem/`: the consumer closed after the first line, leftover printfs in the while loop got EPIPE, pipefail propagated 141 to the $() and `set -e` killed healthcheck.sh mid-section 4/12. setup-linux.sh logged the resulting exit as a false-positive `WARNING: healthcheck reported one or more FAIL items`. Race-free pattern: materialize all candidates into a variable first (no pipe), then iterate in pure bash with `break` -- no consumer-close, no EPIPE, no pipefail propagation. Supersedes BUG-022. Cross-OS parity: the PS1 bash sub-invocation never observed the symptom (its `bash -c` context doesn't set pipefail), but the race-free form keeps both probes structurally identical. Applies the recently-captured lesson "the detection probe MUST use the race-free pattern, not faithfully reproduce broken upstream behaviour". Empirical: this user has 6 versions in cache (12.7.4 -> 13.3.0), so the race fires deterministically on every setup run. Post-fix healthcheck completes all 12/12 sections; probe resolves to 13.3.0. Tests: 2 new bats parity asserts in tests/setup-linux.bats lock both the new materialize+break pattern (positive grep) and the absence of the pipe-to-head form (negative grep) in BOTH healthcheck.sh and healthcheck.ps1, so a future "simplification" can't regress us back. 765/765 bats pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
BUG-022 (PR #87) appended
head -n1after the while-loop in the BUG-015 hook-resolution probe, but the form still raced underset -euo pipefailwhen 2+ candidates matched in~/.claude/plugins/cache/thedotmack/claude-mem/: the consumer closed after the first line, leftoverprintfs in the while loop got EPIPE, pipefail propagated 141 to the$(...)andset -ekilledhealthcheck.shmid-section 4/12.setup-linux.shthen logged a false-positiveWARNING: healthcheck reported one or more FAIL items.Race-free pattern: materialize candidates into a variable first (no pipe), then iterate in pure bash with
break— no consumer-close, no EPIPE, no pipefail propagation. Supersedes BUG-022.Cross-OS parity:
healthcheck.ps1's bash sub-invocation never observed the symptom (itsbash -ccontext doesn't set pipefail), but the race-free form keeps both probes structurally identical. Applies the recently-captured lesson "the detection probe MUST use the race-free pattern, not faithfully reproduce broken upstream behaviour".Empirical evidence
This user has 6 versions of claude-mem in cache (
12.7.4→13.3.0), so the race fires deterministically on every setup run. Post-fixhealthcheck.shcompletes all 12/12 sections; probe resolves to13.3.0.SDD skip rationale
Atomic fix to an existing safety-net probe; production diff ~42 LOC (under the 50 LOC spec-gate threshold). Same shape + precedent as PR #87 (BUG-022) and PR #79 (WIN-001b). No public-contract surface touched (probe is an internal helper inside
healthcheck.{sh,ps1}). Lesson capture goes to vault post-merge.Test plan
shellcheck scripts/healthcheck.shcleanbash -n scripts/healthcheck.shcleanbats tests/setup-linux.bats --filter "BUG-023|BUG-015"→ 3/3 PASSbats tests/→ 765/765 PASS, 0 fail (no regressions)healthcheck.shrun completes all 12/12 sections, exit no longer 14113.3.0, latest cache version).shand.ps1Cross-OS validation
bash -csub-context), so this is parity-only. Empirical Windows validation tracked inWIN-002-windows-smoke-sweepspec (full clean-VM sweep).