Files
buzz/renovate.json
Tyler 2edacde4d4 chore(deps): pin earshot below 1.2.0 pending a VAD threshold re-pick (#6392)
## Problem

`earshot` is our huddle VAD. `desktop/src-tauri/Cargo.toml:143` declares
`earshot = "1.0"` — a caret range — so **only the lockfile** holds us at
1.1.0. `renovate.json` has `automerge: true` with `postUpdateOptions:
["cargo:updateLockfile"]`, and exempts only *major* bumps from
automerge. 1.2.2 published 2026-08-19 and satisfies the range, so it is
eligible on Renovate's next run.

That bump is not safe to take on its own. It is a **quantized
re-implementation, not a tuning release**: `weights.bin` goes 77,124 →
39,940 bytes, the RNN weights move `f32` → `i16`, the mel filterbank
offsets are rebuilt, and `sqrtf` is replaced with a fast `rsqrtf`. Same
crate name, different network — and the probability scale moves with it
(1.1.0 never exceeds 0.935 and puts 1.0% of frames above 0.9; 1.2.2
reaches 0.9909 with 35.4% above 0.9).

Measured on a matched 121-clip corpus (11 Pocket TTS voices × 11
conditions, 38,254 scored frames), at our shipped threshold:

| metric | 1.1.0 | 1.2.2 |
|---|---|---|
| TPR | 89.57% | **88.46%** |
| FPR | 1.54% | **2.79%** |
| CPU / frame | 6,550–6,777 ns | **3,841–3,978 ns** |

AUC does improve (+0.0045 all-conditions) and CPU is a genuine 1.70x
win, so the bump is worth taking — but the AUC gain is in an ROC region
we do not operate in, and the FPR-matched threshold for 1.2.2 is ~0.574,
not 0.5. It needs a threshold re-pick, not a lockfile bump.

The risk is the shape of the diff. The last earshot bump — #654, "update
rust crate earshot to v1.1.0" — was lockfile-only (+23/−26, one file)
and went from opened to merged in **15 minutes**. That is the correct
instinct for a lockfile bump and exactly wrong here: two lines in
`Cargo.lock` would silently re-tune the VAD.

## Fix

One `packageRules` entry pinning earshot below 1.2.0, following the
existing `evalexpr` and `@tiptap/*` pin pattern in the same file. The
rationale lives in the `description` field so the next person to hit the
pin sees why.

A source comment cannot prevent this, because Renovate does not read
comments. This is the mechanical guard.

## Verification

- `renovate.json` parses; the new entry's key set matches the two
existing `allowedVersions` pins.
- Range semantics checked: 1.0.0 / 1.1.0 / 1.1.9 allowed; 1.2.0 / 1.2.1
/ 1.2.2 / 2.0.0 blocked.
- All eight pre-push gates green (branch-skew, file-size, desktop
check/typecheck/test, mobile, rust-tests, desktop-tauri-checks).
- I could **not** run `renovate-config-validator` — the npm registry is
unreachable from this host (`ECONNRESET` via the Artifactory mirror).
The checks above are a structural and semantic substitute, not a
substitute for the official validator.

## Scope

Config-only. No behavior change, no code touched. Unblocking is a
deliberate follow-up: take 1.2.2 together with a threshold re-pick
against the same corpus, which is already parked in the Silero bake-off
arc.

Measurement details and the harness are in my workspace at
`RESEARCH/EARSHOT_1_1_0_TO_1_2_2_MEASUREMENT_2026_08_20.md` (not in this
repo).

Signed-off-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@buzz.block.builderlab.xyz>
Signed-off-by: Tyler <tlongwell@block.xyz>
Co-authored-by: Dawn <c6237ef84fa537c78dcee78efd2d4e59f728859c7f194da42ac51ededfa0be05@buzz.block.builderlab.xyz>
Co-authored-by: Tyler <tlongwell@block.xyz>
2026-08-21 09:02:21 -04:00

50 lines
2.2 KiB
JSON

{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": ["config:recommended", "helpers:pinGitHubActionDigests"],
"minimumReleaseAge": "3 days",
"minimumReleaseAgeBehaviour": "timestamp-required",
"internalChecksFilter": "strict",
"prCreation": "immediate",
"automerge": true,
"rebaseWhen": "conflicted",
"recreateWhen": "always",
"separateMinorPatch": true,
"postUpdateOptions": ["cargo:updateLockfile"],
"packageRules": [
{
"description": "Major version bumps often require code changes — require human review.",
"matchUpdateTypes": ["major"],
"automerge": false
},
{
"description": "Keep Rust crate updates isolated because 0.x minor releases often contain breaking changes. Group all minor updates per crate (don't split by individual version).",
"matchManagers": ["cargo"],
"groupName": null,
"separateMinorPatch": true,
"separateMultipleMinor": false
},
{
"description": "evalexpr v13 relicensed from MIT to AGPL-3.0 — pin below v13 until migrated to an MIT alternative.",
"matchPackageNames": ["evalexpr"],
"allowedVersions": "<13"
},
{
"description": "deadpool-redis re-exports redis types — version mismatch causes trait incompatibility.",
"matchPackageNames": ["redis", "deadpool-redis"],
"matchManagers": ["cargo"],
"groupName": "redis"
},
{
"description": "earshot 1.2.x is a quantized re-implementation, not a tuning release: RNN weights move f32 -> i16 and the probability scale shifts, so the huddle VAD's calibrated threshold regresses at the shipped operating point (TPR 89.57% -> 88.46%, FPR 1.54% -> 2.79% on a matched 121-clip corpus). Unpin only together with a threshold re-pick against that corpus — see the VAD threshold constants in desktop/src-tauri/src/huddle/stt.rs.",
"matchPackageNames": ["earshot"],
"matchManagers": ["cargo"],
"allowedVersions": "<1.2.0"
},
{
"description": "tiptap 3.23.x breaks editor lifecycle under real relay latency — pin until upstream stabilizes.",
"matchPackageNames": ["@tiptap/{/,}**"],
"allowedVersions": "<3.23.0"
}
]
}