Skip to content

fix: macOS portability for core locking and test assertions - #142

Open
aymandakirgh wants to merge 1 commit into
AgriciDaniel:mainfrom
aymandakirgh:fix/macos-flock-and-wc-portability
Open

fix: macOS portability for core locking and test assertions#142
aymandakirgh wants to merge 1 commit into
AgriciDaniel:mainfrom
aymandakirgh:fix/macos-flock-and-wc-portability

Conversation

@aymandakirgh

Copy link
Copy Markdown

Summary

Two independent macOS issues surfaced on a clean install (macOS 15, bash 3.2.57, arm64) following docs/install-guide.md. One is a real functional gap in the core concurrency layer, the other is a test-harness portability bug. Neither affects Linux.

Type

  • Bug fix (fix:)
  • Documentation (docs:)

Changes

  • docs/install-guide.md — promoted flock(1) from a line inside the optional DragonScale callout to its own macOS prerequisite note, with the brew install flock remedy.
  • tests/test_allocate_address.sh — wrapped 2 wc -l captures in $(( ... )).
  • tests/test_concurrent_write.sh — wrapped 3 wc -l captures in $(( ... )).
  • tests/test_wiki_lock.sh — wrapped 1 wc -l capture in $(( ... )).
  • CHANGELOG.md — entry under ## [Unreleased].

1. flock(1) is a core prerequisite, not a DragonScale-only one

flock(1) ships with util-linux on Linux and is absent on macOS. It is invoked by two scripts that are core v1.7 surfaces referenced from CLAUDE.md, not DragonScale extras:

  • scripts/wiki-lock.sh:156 — per-file advisory locks
  • scripts/allocate-address.sh:36 — address allocator

On a stock Mac every call returns flock: command not found:

$ bash scripts/wiki-lock.sh list
scripts/wiki-lock.sh: line 156: flock: command not found
ERR: could not acquire meta-lock within 5s 1

The downstream effect is quiet. The PostToolUse hook gates its auto-commit on LOCK_RC, so a failing wiki-lock list makes it exit 0 and defer, on every write, for the life of the vault. It fails safe, which is the right design, but the advertised auto-commit never runs and nothing tells the user why.

install-guide.md:8 mentioned flock only inside the optional DragonScale block ("Extra prerequisites beyond the base"), so a base-install user has no reason to install it.

Worth noting the Python helpers (bm25-index.py, rerank.py, tiling-check.py) use fcntl.flock(2) from the stdlib and are unaffected. Only the two Bash callers of the CLI utility are.

2. BSD wc -l padding failed 6 assertions

With flock installed, 6 assertions still failed. BSD wc -l pads output with leading spaces, GNU wc -l does not:

FAIL 10 concurrent allocs: unique count: expected '10', got '      10'
FAIL no live lockfiles after workers exited: expected '0', got '       0'
FAIL total line count (seed + workers): expected '11', got '      11'

Every value was numerically correct, so this is a harness bug rather than a defect in the locking or allocator code. Arithmetic expansion normalizes on both platforms with no behavior change on Linux.

Six-cut self-review

  • Read every file before changing it
  • New identifiers named for the next reader (no new identifiers introduced)
  • Smallest unit that works (no speculative abstraction; $(( )) over a new helper for 6 call sites)
  • Deletions kept up with additions where applicable
  • New behavior has hermetic test coverage (no new behavior; this restores existing coverage on macOS)
  • New failure modes have explicit handling + undo plan (no new failure modes; git revert is a clean undo)

Testing

make test on macOS 15 / bash 3.2.57 / arm64, with flock 0.4.0 installed via Homebrew:

All tests passed.

Before this change, on the same machine: test_allocate_address.sh, test_concurrent_write.sh and test_wiki_lock.sh all failed. Per-suite after:

test_allocate_address.sh   PASS      test_bm25_index.py        PASS
test_concurrent_write.sh   PASS      test_boundary_score.py    PASS
test_wiki_lock.sh          PASS      test_contextual_prefix.py PASS
                                     test_retrieve.py          PASS
                                     test_tiling_check.py      PASS
                                     test_wiki_mode.py         PASS

Verifier

Not dispatched. The change is 7 modified lines across 3 test files plus a docs note, with no production-code surface, so I applied the six-cut manually rather than spending an agent pass. Happy to run agents/verifier.md if you'd prefer it on record.

CHANGELOG

  • Added an entry under ## [Unreleased] in CHANGELOG.md

Notes for reviewer

The docs half is the part worth a second opinion. I framed flock as a hard macOS prerequisite for the base install. If you'd rather keep the base install dependency-free, the alternative is a shell fallback in wiki-lock.sh (mkdir-based locking is atomic on POSIX and needs no external binary), which would make the vault work on a stock Mac with no Homebrew step. That is a larger change and a design call that is yours, so I went with the documentation fix here.

🤖 Generated with Claude Code

Two independent macOS issues surfaced on a clean install (macOS 15,
bash 3.2.57, arm64) following docs/install-guide.md.

1. flock(1) is absent on macOS but required by the CORE concurrency
   layer, not just the optional DragonScale extension. Both
   scripts/wiki-lock.sh and scripts/allocate-address.sh invoke it, and
   both are referenced from CLAUDE.md as core v1.7 surfaces. On a stock
   Mac every lock call returns "flock: command not found", so the
   PostToolUse hook hits LOCK_RC != 0 and silently defers the wiki
   auto-commit on every write, permanently. It fails safe, but the
   advertised feature is simply off with no user-visible signal.
   install-guide.md mentioned flock only inside the optional DragonScale
   callout. Promoted to its own prerequisite note with the
   `brew install flock` remedy.

2. With flock installed, 6 assertions still failed because BSD wc -l
   pads its output with leading spaces where GNU wc -l does not:
   assert_eq compared "10" against "      10". The counts were
   numerically correct throughout, so this was a harness bug rather
   than a defect in the locking or allocator code. Wrapped each capture
   in arithmetic expansion $(( ... )), which normalizes on both
   platforms without changing behavior on Linux.

make test: 9/9 suites pass on macOS (was 3 suites failing).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant