Repository navigation
release: 0.1.0-beta.3 - #49
Conversation
Version bump (one version everywhere via scripts/bump-version.mjs) plus a more robust linearity guard: up to three measurements decided by majority, so neither a loaded machine nor a noisy runner flips the verdict. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
There was a problem hiding this comment.
Deep review: release: 0.1.0-beta.3
Intent: ship 0.1.0-beta.3 as the first MIT-licensed public beta (version everywhere + BUGSEE_SDK_VERSION), and stop the linearity ReDoS gate from flipping on a single noisy sample — majority of up to three measurements instead of first-success.
Checked (not just the diff): bump script vs loadPackages(); check-publishable.mjs (locally: 49 publishable packages, all at 0.1.0-beta.3); leftover 0.1.0-beta.2 (only example comments in bump/check scripts); launch files taking version from core; majority arithmetic vs the old any-pass loop; callers in sanitize.test.ts / pairs.test.ts / linear-time.test.ts; GitHub CI on this SHA (Lint · Typecheck · Cycles · Coverage and E2E both SUCCESS). Also ran vitest run src/linear-time.test.ts in @bugsee/protocol (20 passed).
No production or release-blocking defect. The version bump is complete and consistent. The majority early-exit is equivalent to majority-of-3 (two agreeing votes cannot be overturned by a third).
Findings
P3 Low — packages/protocol/src/linear-time.test-helper.ts:291 — majority tie-break is untested. See inline.
Overall
- Risk: Low
- Merge recommendation: Approve
- Most important to fix: optional follow-up — pin the 2-1 split so a revert to first-success cannot sneak through. Not a release blocker.
- Positives: one-version gate actually ran (
check-publishablein CI); majority closes the exact false-negative the previous any-pass policy had (a loaded machine reading quadratic under 4 once); healthy XML/JSON/pairs guards still have ~2.7× headroom vs the 180s hang budget after the extra attempt.
Sent by Cursor Automation: Bugsee code review
| for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt += 1) { | ||
| const result = measureLinearity(prepare, work, size, benign); | ||
| if (best === undefined || result.verdict < best.verdict) { | ||
| best = result; | ||
| } | ||
| if (result.verdict < LINEAR_TOLERANCE) { | ||
| break; | ||
| results.push(measureLinearity(prepare, work, size, benign)); | ||
| if ( | ||
| attempt === 2 && | ||
| passed(results[0] as { verdict: number }) === passed(results[1] as { verdict: number }) | ||
| ) { | ||
| break; // the first two agree: no third measurement needed | ||
| } | ||
| } | ||
| const sorted = [...results].sort((a, b) => a.verdict - b.verdict); | ||
| const median = sorted[Math.floor((sorted.length - 1) / 2)] as { | ||
| verdict: number; | ||
| message: string; | ||
| }; | ||
| // EVERY number rides along in the message. This fails on machines that cannot be inspected, and | ||
| // the verdict alone does not say whether the subject grew, the baseline shrank, or the machine | ||
| // simply reads a 16x step as more than 16x for everything — which is the whole reason the ceiling | ||
| // is relative. The reference reading is what separates those. | ||
| expect(best?.verdict, best?.message).toBeLessThan(LINEAR_TOLERANCE); | ||
| expect(median.verdict, median.message).toBeLessThan(LINEAR_TOLERANCE); |
There was a problem hiding this comment.
P3 Low — majority / median decision is not pinned
Problem: This is the only behavioral change in the release, and the path that distinguishes it from the old any-pass policy never runs in tests. linear-time.test.ts only asserts consistently-linear work accepts and consistently-quadratic work rejects. Both agree on the first two attempts, so they take the early break and never exercise the third measurement or a 2-1 split. The previous policy (break on first success, report the min) would still satisfy every existing assertion.
Impact: This helper is the ReDoS gate for sanitizeBody / redactSensitivePairs. The change exists because a single lucky under-4 reading of quadratic work can pass. Without a split test, a one-token inversion of the agree check (!== instead of ===) would stop at two disagreeing samples and report the lower (always passing) verdict — restoring that false negative — and CI would stay green.
Scenario: First two measurements disagree (the file already documents both directions: CI read healthy work at 8.7 vs ceiling 4; a loaded machine read quadratic under 4 once). If the early-exit condition is inverted, the function reports sorted[0] of [pass, fail], which is the pass, and a quadratic sanitizer ships.
Fix: Drive expectLinearIn with an injectable sequence of verdicts (or a work that is linear on some attempts and quadratic on others) and assert: two agreeing passes stop at 2 and accept; two agreeing fails stop at 2 and reject; a 2-1 split follows the majority, not the min. Not a merge blocker for the version bump.
🤖 Generated with [Claude Code](https://claude.com/claude-code)


Version bump of all 49 packages and
BUGSEE_SDK_VERSIONto0.1.0-beta.3(viascripts/bump-version.mjs;check:publishablepasses), plus a more robust linearity guard in@bugsee/protocol(up to three measurements decided by majority, so neither a loaded machine nor a noisy runner flips the verdict).beta.3 is the first version whose npm metadata says
license: MIT, ships aLICENSEfile and a real README in every package, and carries the comment cleanup from #48.The full gate (
pnpm ci:local --e2e) passed locally on this exact tree. After merge: runrelease.yml(dry run, then real) frommain, tagv0.1.0-beta.3.🤖 Generated with Claude Code