PR19: automatic client reconnect restores panic-message reporting in sensitive clipboard pilot #20

Closed
opened 2026-10-18 22:20:35 +08:00 by Breadway · 3 comments
Owner

Found during independent exact-head review of PR19 at a55d015f0c. Confidence: confirmed by isolated runtime reproduction, no live clipboard or daemon accessed.

At breadclipd/src/main.rs:417 strict options disable panic messages and log forwarding, but :425 calls BreadClient::connect again. In bread-utils v0.8.1 (c6442cabb6c02acd1380dcd0d17189c4e22def03), enable_bug_reporting takes LIVE and returns the custom guard without putting it back; the next connect sees LIVE empty and starts automatic defaults (panic_message=true, forward_logs=true), overwriting the process-wide panic configuration and losing app_version. Other connect call sites at :229, :254-289 also matter, including capture-once subprocesses.

Reproduction: scratch probe using the pinned library and exact-head dependency versions, synthetic text only, private HOME/XDG_RUNTIME_DIR and Unix socket. Strict options then induced panic: message=(message omitted by the app), app_version=0.3.0, synthetic text absent. Identical sequence plus the second connect from :425: message=CLIP19_SYNTHETIC_PRIVATE_TEXT_7f42, app_version=null, synthetic text present on bug.marker wire payload. Both exit 101. Evidence: /tmp/opencode/clip19-review/probe.py and privacy-probe/src/main.rs.

Repair on existing PR19: use the explicit nonautomatic connection path consistently for sensitive daemon/capture/command clients, retain intentional strict reporting, and add regression coverage for a panic after later client construction. Verify no synthetic clipboard bytes anywhere in emitted payloads, version preserved, no automatic log reporter, and intended heartbeat/no-breadd behavior. Do not merge PR19 until repaired and independently re-reviewed.

Found during independent exact-head review of PR19 at a55d015f0cdf1b6e1736a4432de628f516d8fac2. Confidence: confirmed by isolated runtime reproduction, no live clipboard or daemon accessed. At breadclipd/src/main.rs:417 strict options disable panic messages and log forwarding, but :425 calls BreadClient::connect again. In bread-utils v0.8.1 (c6442cabb6c02acd1380dcd0d17189c4e22def03), enable_bug_reporting takes LIVE and returns the custom guard without putting it back; the next connect sees LIVE empty and starts automatic defaults (panic_message=true, forward_logs=true), overwriting the process-wide panic configuration and losing app_version. Other connect call sites at :229, :254-289 also matter, including capture-once subprocesses. Reproduction: scratch probe using the pinned library and exact-head dependency versions, synthetic text only, private HOME/XDG_RUNTIME_DIR and Unix socket. Strict options then induced panic: message=(message omitted by the app), app_version=0.3.0, synthetic text absent. Identical sequence plus the second connect from :425: message=CLIP19_SYNTHETIC_PRIVATE_TEXT_7f42, app_version=null, synthetic text present on bug.marker wire payload. Both exit 101. Evidence: /tmp/opencode/clip19-review/probe.py and privacy-probe/src/main.rs. Repair on existing PR19: use the explicit nonautomatic connection path consistently for sensitive daemon/capture/command clients, retain intentional strict reporting, and add regression coverage for a panic after later client construction. Verify no synthetic clipboard bytes anywhere in emitted payloads, version preserved, no automatic log reporter, and intended heartbeat/no-breadd behavior. Do not merge PR19 until repaired and independently re-reviewed.
Author
Owner

Re-review finding at breadclip PR19 head6a7e2c3: implementation privacy repair passes release wire probe, but durable regression coverage remains incomplete. Confirmed high-confidence reproduction: copy breadclipd/tests/privacy_regression.rs unchanged from6a7e2c3 into isolated vulnerable a55d015 checkout, then cargo test --locked -p breadclipd --test privacy_regression passes1/1. Test lines13-29 hard-code repaired constructors independent of production main.rs and never exercise actual command/capture code. Fix by sharing/exercising production setup and clients; require same assertions to fail on old production behavior. Existing issue reused rather than creating duplicate. Evidence /tmp/opencode/clip19-finalreview/old-head-regression.log; full verdict PR19 comment5423.

Re-review finding at breadclip PR19 head6a7e2c3: implementation privacy repair passes release wire probe, but durable regression coverage remains incomplete. Confirmed high-confidence reproduction: copy breadclipd/tests/privacy_regression.rs unchanged from6a7e2c3 into isolated vulnerable a55d015 checkout, then cargo test --locked -p breadclipd --test privacy_regression passes1/1. Test lines13-29 hard-code repaired constructors independent of production main.rs and never exercise actual command/capture code. Fix by sharing/exercising production setup and clients; require same assertions to fail on old production behavior. Existing issue reused rather than creating duplicate. Evidence /tmp/opencode/clip19-finalreview/old-head-regression.log; full verdict PR19 comment5423.
Author
Owner

Already repaired on feature/breadbug-pilot at ec4e1b1, and re-verified today.

Every daemon client now goes through privacy_clients::client(), which calls BreadClient::connect_without_bug_reporting, so a later connect cannot replace the strict configuration. enable_reporting() sets panic_message=false and forward_logs=false. breadclipd/tests/privacy_regression.rs spawns a child that installs that configuration, constructs the second client, then panics with a synthetic string. Re-ran cargo test -p breadclipd --test privacy_regression at ec4e1b1: 2 passed. The marker message is "(message omitted by the app)", app_version is 0.3.0, and the synthetic string is absent from the wire payload.

The fix is on the pilot branch, not main, because PR19 itself has not merged. Nothing further to commit for this card.

Already repaired on feature/breadbug-pilot at ec4e1b1, and re-verified today. Every daemon client now goes through privacy_clients::client(), which calls BreadClient::connect_without_bug_reporting, so a later connect cannot replace the strict configuration. enable_reporting() sets panic_message=false and forward_logs=false. breadclipd/tests/privacy_regression.rs spawns a child that installs that configuration, constructs the second client, then panics with a synthetic string. Re-ran `cargo test -p breadclipd --test privacy_regression` at ec4e1b1: 2 passed. The marker message is "(message omitted by the app)", app_version is 0.3.0, and the synthetic string is absent from the wire payload. The fix is on the pilot branch, not main, because PR19 itself has not merged. Nothing further to commit for this card.
Author
Owner

Correction to my earlier comment: PR19 has merged. The fix is on breadclip main, not only on the pilot branch. ec4e1b1 is an ancestor of origin/main, which is 7d1d3bc (PR19 merge). It was independently reviewed as part of CLIP-19 (Grok, PASS at ec4e1b1, PR19 comment 5433) and verified on the merge tree. I re-ran the privacy regression today (2 passed). The earlier statement that the fix 'lives on the pilot branch until PR19 merges' was wrong.

Correction to my earlier comment: PR19 has merged. The fix is on breadclip main, not only on the pilot branch. ec4e1b1 is an ancestor of origin/main, which is 7d1d3bc (PR19 merge). It was independently reviewed as part of CLIP-19 (Grok, PASS at ec4e1b1, PR19 comment 5433) and verified on the merge tree. I re-ran the privacy regression today (2 passed). The earlier statement that the fix 'lives on the pilot branch until PR19 merges' was wrong.
Sign in to join this conversation.
No labels
ci
enhancement
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/breadclip#20
No description provided.