fix(desktop-notification,markdown-format): assert the real C1 slow-sink invariant, not half the sleep - #1362
Conversation
…nk invariant, not half the sleep The #751 fix that closed #448 could not have worked: THRESHOLD_MS was derived as SINK_SLEEP * 1000 / 2, so widening SINK_SLEEP widened the threshold proportionally and left the margin ratio unchanged by construction. #448 was reopened after this reproduced on clean main (delta=3697ms false-fail with no leak present), and the same construction was found ported verbatim into markdown-format's C1 copy. THRESHOLD_MS now asserts the actual invariant directly -- sink-sleep-minus-a- safety-margin, not half the sleep -- and SINK_SLEEP widens from 6s to 8s (still under the 10s ceiling documented against EXIT-cleanup file-locking on Windows) for more absolute separation between ambient noise and the leak signal. Both were sized against measurements taken on this machine: the reported 3697ms false-fail, and up to ~2150ms of noise generated by 30 concurrent full-suite runs under heavy load. Verified on Windows Git Bash in both plugins: 10 consecutive clean runs, 40 runs under heavy concurrent load (worst observed no-leak delta ~1590ms against the new <6000ms threshold, no FAIL), and a deliberately reintroduced fd1 leak (dropped the >/dev/null redirect on the sink spawn in hook::emit_telemetry, then reverted) still fails the case (observed delta ~8065ms). Closes #448 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Claude finished @kyle-sexton's task in 1m 30s —— View job Security Review
No security issues found. The six changed files are: two
Injection surfaces: SLOW_SINK="$(make_sink "cat >/dev/null; sleep $SINK_SLEEP")"
Other vectors checked: No credentials or secrets involved. No network calls or dependency pins changed. No GitHub Actions files in scope. No authorization logic touched. No path construction using the new variables. Production hook code is entirely untouched — this is test-only. |
|
Claude finished @kyle-sexton's task in 2m 3s —— View job PR Review
SummaryThis fix is correct, well-reasoned, and adequately tested. The root cause analysis is sound, the arithmetic checks out, and the empirical verification data is solid. Two minor observations below, neither a blocker. Threshold math: correctThe core fix —
The new formula decouples the threshold from the sleep ratio: widening The identical change is correctly applied to the Minor observations (not blocking)1. desktop-notification.test.sh, line ~251 — The constant measures the gap between the threshold and the leak signal (how far below the leak signal the threshold sits), not the gap above the noise floor. The actual no-leak safety headroom is 2. desktop-notification.test.sh, line ~273 — The diagnostic line emits Version bumps and CHANGELOGsBoth correct:
CHANGELOG entries for both are accurate, cite the relevant issue numbers and empirical measurements, and follow the Keep a Changelog format already in use. Verdict: LGTM. The fix is correct and the test verification is thorough. The two observations above are cosmetic; merge at your discretion. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d5c9730366
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…al margin THRESHOLD_MS = SINK_SLEEP*1000 - 2000 left the two margins asymmetric: 3850ms on the noise side but only 2000ms on the leak side, below the 2150ms of worst observed no-leak noise. A load shift that inflates every baseline sample and then subsides before the slow run subtracts real leak signal out of the delta -- baselines ~4s against a ~1.5s slow run put a genuine leak at ~5500ms, under the 6000ms threshold, and the detector reports no leak. min-of-N baselines do not cover that: they protect against ONE unlucky sample, not a shift affecting all. SAFETY_MARGIN_MS 2000 -> 3000 moves the threshold to 5000ms, roughly midway between the leak signal and the noise: 2850ms noise-side, 3000ms leak-side, both above the 2150ms worst case. The recorded measurements already bracket it -- the deliberately reintroduced leak measured 8065ms (still detected) and 40 runs under 30x concurrent load peaked at ~1590ms (still passing).
…threshold-margin # Conflicts: # plugins/desktop-notification/CHANGELOG.md # plugins/markdown-format/.claude-plugin/plugin.json # plugins/markdown-format/CHANGELOG.md
|
Claude finished @kyle-sexton's task in 2m 33s —— View job PR Review
SummaryThe core fix is correct. The structural bug — Threshold math: correct (and improved since prior review)The chain of changes:
Commit The identical change is correctly applied to the Codex concern: acknowledged and directly addressedThe Codex review flagged that min-of-N baselines protect against one slow sample but not a load shift affecting all three. The code comment now explicitly documents this:
The 3000 ms leak-side clearance is the mitigation — a baseline inflation of >3000 ms would be required to mask a real leak, and the 40-run load test peaked at ~1590 ms. The tradeoff is accepted with eyes open, which is the right call for a test-only fix. Minor findings (not blocking)1. PR body test plan references the stale 6000 ms threshold The test plan bullet — "C1 deltas -175ms to 644ms against the new 2. Diagnostic echo still omits The log shows the result of the formula but not its inputs, so verifying the threshold value from a log line requires knowing Version bumps and CHANGELOGsBoth correct:
Verdict: LGTM. The fix is structurally sound, the commit history shows the margins were consciously sized against real measurements, and the code comment now fully documents the inherent tradeoff. The two nits above are cosmetic. |
|
Claude finished @kyle-sexton's task in 1m 37s —— View job Security Review
No security issues found. The six changed files across this PR's two substantive commits are: two
Injection surfaces:
SLOW_SINK="$(make_sink "cat >/dev/null; sleep $SINK_SLEEP")"
THRESHOLD_MS=$((SINK_SLEEP * 1000 - SAFETY_MARGIN_MS))
Other vectors checked: No credentials or secrets. No network calls. No dependency pins. No GitHub Actions files. No authorization logic. No path construction using the new variables. Production hook code is entirely untouched — this is test-only. |
Closes #448
Summary
#751fix that closed#448could not have worked:THRESHOLD_MSwas derived asSINK_SLEEP * 1000 / 2, so wideningSINK_SLEEPwidened the threshold by the same ratio and leftthe margin unchanged by construction.
#448was reopened after this reproduced on cleanmain(
delta=3697msfalse-fail with no leak present), and the same construction was found portedverbatim into
markdown-format's C1 copy (from#1209).THRESHOLD_MSin both plugins' C1 fd1-leak detector now asserts the actual invariant directly —sink-sleep-minus-a-safety-margin (
SAFETY_MARGIN_MS), not half the sleep — andSINK_SLEEPwidensfrom 6s to 8s (still under the 10s ceiling documented against EXIT-cleanup file-locking on Windows)
for more absolute separation between ambient noise and the leak signal.
false-fail, and up to ~2150ms of noise generated by 30 concurrent full-suite runs under heavy load
— the fixed threshold clears both with comfortable margin while staying meaningfully below the
~8000ms leak signal.
desktop-notificationandmarkdown-format.Test plan
Windows Git Bash (the platform this flake is specific to — Ubuntu CI spawns ~10x cheaper and was
always unaffected).
desktop-notification.test.sh— all green(
PASS=54 FAIL=0), C1 deltas -175ms to 644ms against the new<6000msthreshold.desktop-notification.test.sh+ 10xmarkdown-format.test.shlaunched simultaneously) — all green, worst observed no-leak delta~1590ms (desktop-notification) / ~1555ms (markdown-format), no
FAIL.>/dev/nullredirect on the sink spawn inhook::emit_telemetry,plugins/desktop-notification/hooks/hook-utils.sh:455) — C1 correctlywent red:
delta 8065ms ≈ sink's 8s sleep. Reverted (git diffagainst the reverted file isempty — confirmed clean).
shellcheckclean on both modified test files.desktop-notificationPASS=54 FAIL=0,markdown-formatPASS=65 FAIL=0.Related
#443 (the
hook::buffer_stdinmigration that thinned the original margin). #751 (the fix thatattempted to close #448 but could not — see Summary). Epic #313 (closed).
🤖 Generated with Claude Code