You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[bug] wire-company-brain.sh: re-run fails on macOS awk and still reports Updated #598
What broke: bin/wire-company-brain.sh cannot rewrite an existing company-brain block on macOS. The rewrite path passes the multi-line block to awk with -v blk="$block"; BSD awk (macOS default, awk version 20200816) rejects newlines in -v values. The mv after awk never runs, so the files are left untouched, but the script still prints Updated: … rewritten in place and pointer written to N instruction surface(s). A brain that moved, or a changed block text, is never applied on a re-run.
Command / script run (exact invocation):
mkdir -p /tmp/w/p /tmp/w/b && touch /tmp/w/p/CLAUDE.local.md /tmp/w/b/README.md /tmp/w/b/ROUTING.md
bin/wire-company-brain.sh /tmp/w/p /tmp/w/b # first run: appends, fine
bin/wire-company-brain.sh /tmp/w/p /tmp/w/b # second run: fails
Expected vs. actual:
Expected: block rewritten between the markers, idempotent (the header promises this).
Actual (origin/master, macOS 26, bash 3.2, BSD awk):
awk: newline in string <!-- COMPANY-BRAIN:B... at source line 1
awk: newline in string <!-- COMPANY-BRAIN:B... at source line 1
Updated: CLAUDE.local.md — company brain block rewritten in place.
Company brain pointer written to 1 instruction surface(s).
Each surface fails once per line of the block. The "Updated" message is false.
Suggested fix (tested on macOS BSD awk): pass the block through the environment, which allows newlines:
With this, a re-run against a moved brain dir rewrote the block in place and kept the text above and below the markers. Also worth checking the awk exit code before printing "Updated".
Field evidence:
Hit while wiring a company brain into a scratch copy of a field-run project (three surfaces: CLAUDE.md, CLAUDE.local.md, AGENTS.md). The first run worked, the re-run failed as above on all three. Reproduced on a clean origin/master checkout with the empty fixture above.
Triage: FIX track. Category: portability bug. Code path verified; the BSD awk failure is UNVERIFIED here (this container only has mawk, which accepts newlines in -v, so I couldn't reproduce it).
Root cause: bin/wire-company-brain.sh:68. It passes the multi-line block as -v blk="$block", and BSD awk rejects newlines in -v values. The second bug is at :71–72: the "Updated: … rewritten in place" echo runs whether or not awk && mv succeeded, so a failed rewrite still reports success, and written still counts it (:82).
Value: Medium.
Who hits it: every macOS user who re-runs the script, whether because a brain moved or because the block text changed.
What breaks: the rewrite silently does nothing and the script reports success.
Why CI misses it: the existing re-point check (tests/wave2/test-company-brain.sh:63) passes on Linux, where gawk and mawk both accept the newline.
Risk of fixing: Low.
ENVIRON is POSIX and works the same in BSD awk, gawk and mawk. I checked mawk: same output.
The only output change is that a failed rewrite now reports failure instead of "Updated". The exit code stays the same unless we choose to return non-zero when a surface fails.
No gate or verdict reads this script, and baseline words are unchanged.
Rigidity check: no change to the process path, the architecture or performance.
Proposed fix:
- awk -v b="$BEGIN" -v e="$END" -v blk="$block" '- index($0,b)==1 { print blk; skip=1; next }+ if BLK="$block" awk -v b="$BEGIN" -v e="$END" '+ index($0,b)==1 { print ENVIRON["BLK"]; skip=1; next }
index($0,e)==1 { skip=0; next }
- !skip { print }' "$CL" > "$tmp" && mv "$tmp" "$CL"- echo "Updated: ${CL#$PROJECT/} — company brain block rewritten in place."+ !skip { print }' "$CL" > "$tmp" && mv "$tmp" "$CL"; then+ echo "Updated: ${CL#$PROJECT/} — company brain block rewritten in place."+ else+ echo "FAILED: ${CL#$PROJECT/} — block not rewritten (awk/mv failed); file unchanged" >&2+ rm -f "$tmp"; continue+ fi
The continue keeps a failed surface out of written. The append path (:74) should get the same if … then echo guard.
Proof: a new case in tests/wave2/test-company-brain.sh.
Put a stub awk on PATH that exits 2 whenever a -v value contains a newline, mimicking BSD awk.
Re-run the script against a project that is already wired.
Assert there is no Updated: line, the file is byte-identical, and the surface count is 0.
On master, the "no Updated" assertion fails. With the fix, the block goes through ENVIRON, so the stub never sees a newline in -v and the re-point check (:63) passes with the stub on PATH. A field run on macOS BSD awk should still be cited before merge; the report above already contains one.
Effort: S. Recommendation: FIX NOW. It's small, contained, and it hides a silent no-op behind a success message.
Reply go to have a fix PR opened (it still gets an independent review and your merge).
Fix PR: #599. It passes the block through ENVIRON, and a failed rewrite now prints FAILED instead of Updated. The new fixture T2c fails 4 of 5 checks on master and passes 50 of 50 with the fix. It still needs the independent review before merge.
Activity
MendixMau commentedon Oct 30, 2026
Triage: FIX track. Category: portability bug. Code path verified; the BSD awk failure is UNVERIFIED here (this container only has mawk, which accepts newlines in
-v, so I couldn't reproduce it).Root cause:
bin/wire-company-brain.sh:68. It passes the multi-line block as-v blk="$block", and BSD awk rejects newlines in-vvalues. The second bug is at:71–72: the"Updated: … rewritten in place"echo runs whether or notawk && mvsucceeded, so a failed rewrite still reports success, andwrittenstill counts it (:82).Value: Medium.
tests/wave2/test-company-brain.sh:63) passes on Linux, where gawk and mawk both accept the newline.Risk of fixing: Low.
ENVIRONis POSIX and works the same in BSD awk, gawk and mawk. I checked mawk: same output.Rigidity check: no change to the process path, the architecture or performance.
Proposed fix:
The
continuekeeps a failed surface out ofwritten. The append path (:74) should get the sameif … then echoguard.Proof: a new case in
tests/wave2/test-company-brain.sh.awkonPATHthat exits 2 whenever a-vvalue contains a newline, mimicking BSD awk.Updated:line, the file is byte-identical, and the surface count is 0.On master, the "no Updated" assertion fails. With the fix, the block goes through
ENVIRON, so the stub never sees a newline in-vand the re-point check (:63) passes with the stub onPATH. A field run on macOS BSD awk should still be cited before merge; the report above already contains one.Effort: S. Recommendation: FIX NOW. It's small, contained, and it hides a silent no-op behind a success message.
Reply go to have a fix PR opened (it still gets an independent review and your merge).
Generated by Claude Code
MendixMau commentedon Oct 30, 2026
Fix PR: #599. It passes the block through
ENVIRON, and a failed rewrite now printsFAILEDinstead ofUpdated. The new fixture T2c fails 4 of 5 checks on master and passes 50 of 50 with the fix. It still needs the independent review before merge.Generated by Claude Code