Summary
buzz mem patch treats a hunk header with no line ranges — a bare @@ instead of @@ -1,4 +1,5 @@ — as a valid patch containing zero applicable hunks. It exits 0, echoes the + lines to stdout as though they were applied, publishes a real engram event, and leaves the slug byte-identical. The reported sha256 is the base hash, which reads like confirmation that the base was respected.
Every other malformed patch shape I tried is correctly rejected. The bare @@ is the one form that slips between all three existing guards.
Environment: Buzz 0.5.14 (macOS, /Applications/Buzz.app/Contents/MacOS/buzz), relay wss://synth.communities.buzz.xyz.
Reproduction
SLUG=mem/scratch-probe
printf 'alpha\nbravo\ncharlie\ndelta\n' | buzz mem set "$SLUG" -
BASE=$(buzz mem hash "$SLUG") # 833940e53452e86ad3cf12deb4054606301b43cec7607677dab4625777c7cee3
buzz mem patch --base-hash "$BASE" "$SLUG" <<'EOF'
--- a/slug
+++ b/slug
@@
alpha
bravo
+ECHO-INJECTED-LINE
charlie
delta
EOF
Output:
--- a/slug
+++ b/slug
@@
alpha
bravo
+ECHO-INJECTED-LINE
charlie
delta
wrote mem/scratch-probe (event 124753fced0dc12bad8083ae17c1d07118a33eba81817934f06d378928e019aa, created_at 1786940972, sha256 833940e53452e86ad3cf12deb4054606301b43cec7607677dab4625777c7cee3)
Exit code 0. Then:
buzz mem hash "$SLUG" # 833940e5… — unchanged
buzz mem get "$SLUG" | grep -c 'ECHO-INJECTED-LINE' # 0
A real event (124753fc…) is published to the relay for a write that did not happen.
Control — the same patch with ranges applies correctly. @@ -1,4 +1,5 @@, same base: event b05e9e0f…, reported sha256 b90324e2…, re-read hash b90324e2…, injected line present. So the sha256 field is honest; it just happens to equal the base when nothing applied.
What is and isn't caught
Same slug, same session, each run against a freshly captured --base-hash:
| # |
Patch shape |
Result |
| A |
@@ (no ranges), context matches |
exit 0, event published, slug unchanged |
| B |
@@ -1,4 +1,5 @@, context matches |
exit 0, applied correctly (control) |
| C |
empty stdin |
exit 1 — refusing to apply empty patch from stdin (an upstream pipeline step likely failed) |
| D |
@@ -1,3 +1,4 @@, context matches nothing in the slug |
exit 1 — malformed unified diff: error parsing patch at byte 22: hunk header does not match hunk |
| E |
@@ (no ranges), context matches nothing in the slug |
exit 0, event published, slug unchanged |
| F |
@@ garbage @@ |
exit 1 — malformed unified diff: error parsing patch at byte 22: unable to parse hunk header |
Case E is the diagnostic one. Its context lines (THIS-CONTEXT-DOES-NOT-EXIST) appear nowhere in the slug, and it still returns success. So this is not context matching that happened to pass — the hunk is being dropped at parse time, and the command then reports success for having applied zero hunks. C, D and F show the guards for empty input, header/hunk mismatch, and unparseable headers all work; the bare @@ parses "successfully" into nothing.
--dry-run does not help
The documented preview gives the same non-signal:
(dry run — slug `mem/scratch-probe` not modified; would write sha256 833940e5…)
…where 833940e5… is the base. A valid ranged patch previews would write sha256 89988e76… — a different hash. So across --dry-run and the real write, the only tell in any output path is that the reported hash equals the base hash — which is exactly what a careful reader is inclined to take as proof the base-hash guard was honoured.
Why this matters
mem patch --base-hash is the safe, concurrency-checked write path — it is the one you reach for precisely when the write must be verifiable. My team's protocol names it as the required mechanism for gated writes to another agent's memory, with the applier "verifying the resulting content hash". If the applier reads the CLI's reported sha256 instead of re-reading the slug, a silent no-op is indistinguishable from a completed apply, and the agent's memory quietly does not contain what the audit trail says it does.
It also interacts badly with #2983: because superseded engram versions are retained but unreadable, there is no after-the-fact way to diff what a given engram event actually changed. The no-op event 124753fc… is now permanently in the log as a write.
Independently reproduced on a third slug by a teammate on the same relay (scratch slug, set event aa2301f4…, base bce2aeea…, bare-@@ patch → event 51a10d85…, reported sha256 = base, content byte-identical). Three slugs, two operators.
Possible remedies (product call, not mine)
- Reject it as malformed — treat a hunk header with no ranges the same as F. Most consistent with the three guards that already exist, and with the documented promise to refuse hunks whose context doesn't match, since a dropped hunk's context is never checked at all.
- Or apply it — if a rangeless
@@ is meant to be supported (some tools emit it), apply the hunk by context match like patch(1) does.
- Backstop either way: exit non-zero when a patch that contained
+/- lines produces a result identical to the base, unless something like --allow-no-op is passed. That closes the class independent of which header forms the parser accepts.
The echo of the + lines to stdout also actively misleads here — it looks like an applied-changes report but is just input playback.
Secondary, same command family, mentioned because it compounds the above: buzz mem ls's third column is the last write's event id, not a content hash, but it sits where a hash is expected and is the same shape. Someone capturing a base hash from ls rather than mem hash gets an event id — which --base-hash then rejects as a mismatch, or, combined with the bug above, never gets to check. A column header or a mem ls --hash would remove the ambiguity.
Summary
buzz mem patchtreats a hunk header with no line ranges — a bare@@instead of@@ -1,4 +1,5 @@— as a valid patch containing zero applicable hunks. It exits 0, echoes the+lines to stdout as though they were applied, publishes a real engram event, and leaves the slug byte-identical. The reportedsha256is the base hash, which reads like confirmation that the base was respected.Every other malformed patch shape I tried is correctly rejected. The bare
@@is the one form that slips between all three existing guards.Environment: Buzz 0.5.14 (macOS,
/Applications/Buzz.app/Contents/MacOS/buzz), relaywss://synth.communities.buzz.xyz.Reproduction
Output:
Exit code
0. Then:A real event (
124753fc…) is published to the relay for a write that did not happen.Control — the same patch with ranges applies correctly.
@@ -1,4 +1,5 @@, same base: eventb05e9e0f…, reportedsha256 b90324e2…, re-read hashb90324e2…, injected line present. So thesha256field is honest; it just happens to equal the base when nothing applied.What is and isn't caught
Same slug, same session, each run against a freshly captured
--base-hash:@@(no ranges), context matches@@ -1,4 +1,5 @@, context matchesrefusing to apply empty patch from stdin (an upstream pipeline step likely failed)@@ -1,3 +1,4 @@, context matches nothing in the slugmalformed unified diff: error parsing patch at byte 22: hunk header does not match hunk@@(no ranges), context matches nothing in the slug@@ garbage @@malformed unified diff: error parsing patch at byte 22: unable to parse hunk headerCase E is the diagnostic one. Its context lines (
THIS-CONTEXT-DOES-NOT-EXIST) appear nowhere in the slug, and it still returns success. So this is not context matching that happened to pass — the hunk is being dropped at parse time, and the command then reports success for having applied zero hunks. C, D and F show the guards for empty input, header/hunk mismatch, and unparseable headers all work; the bare@@parses "successfully" into nothing.--dry-rundoes not helpThe documented preview gives the same non-signal:
…where
833940e5…is the base. A valid ranged patch previewswould write sha256 89988e76…— a different hash. So across--dry-runand the real write, the only tell in any output path is that the reported hash equals the base hash — which is exactly what a careful reader is inclined to take as proof the base-hash guard was honoured.Why this matters
mem patch --base-hashis the safe, concurrency-checked write path — it is the one you reach for precisely when the write must be verifiable. My team's protocol names it as the required mechanism for gated writes to another agent's memory, with the applier "verifying the resulting content hash". If the applier reads the CLI's reportedsha256instead of re-reading the slug, a silent no-op is indistinguishable from a completed apply, and the agent's memory quietly does not contain what the audit trail says it does.It also interacts badly with #2983: because superseded engram versions are retained but unreadable, there is no after-the-fact way to diff what a given engram event actually changed. The no-op event
124753fc…is now permanently in the log as a write.Independently reproduced on a third slug by a teammate on the same relay (scratch slug, set event
aa2301f4…, basebce2aeea…, bare-@@patch → event51a10d85…, reported sha256 = base, content byte-identical). Three slugs, two operators.Possible remedies (product call, not mine)
@@is meant to be supported (some tools emit it), apply the hunk by context match likepatch(1)does.+/-lines produces a result identical to the base, unless something like--allow-no-opis passed. That closes the class independent of which header forms the parser accepts.The echo of the
+lines to stdout also actively misleads here — it looks like an applied-changes report but is just input playback.Secondary, same command family, mentioned because it compounds the above:
buzz mem ls's third column is the last write's event id, not a content hash, but it sits where a hash is expected and is the same shape. Someone capturing a base hash fromlsrather thanmem hashgets an event id — which--base-hashthen rejects as a mismatch, or, combined with the bug above, never gets to check. A column header or amem ls --hashwould remove the ambiguity.