@indigoai-us/hq-cli 5.109.13 → 5.109.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [5.109.14] — 2026-09-13
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Repeated "install tree was being rewritten" reports from a background reinstall
|
|
10
|
+
now collapse into one stable issue per outcome instead of spawning a fresh crash
|
|
11
|
+
report on every occurrence (Sentry HQ-CLI-21, HQ-CLI-22, HQ-CLI-23). hq already
|
|
12
|
+
groups these by their recovery outcome, but the grouping key led with a
|
|
13
|
+
placeholder that also told Sentry to fold in its own default grouping — and for
|
|
14
|
+
this error that default is the underlying loader failure, whose details differ
|
|
15
|
+
every time (which dependency file the reinstall happened to be rewriting, under
|
|
16
|
+
each machine's install path). So each occurrence minted a new issue and the
|
|
17
|
+
family never settled down. The key is now fully explicit and no longer inherits
|
|
18
|
+
that default, so future occurrences with the same outcome share one group. The
|
|
19
|
+
existing issues HQ-CLI-21/22/23 stay open as they are: a grouping change only
|
|
20
|
+
affects events reported after it ships.
|
|
21
|
+
|
|
5
22
|
## [5.109.13] — 2026-09-13
|
|
6
23
|
|
|
7
24
|
### Fixed
|
|
@@ -3,11 +3,16 @@
|
|
|
3
3
|
* carries no discriminator from the closed allowlist (in which case the caller
|
|
4
4
|
* must leave the fingerprint unset so Sentry's default grouping applies).
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* For the rpc/http carriers the shape is `[DEFAULT_GROUPING, errorName,
|
|
7
|
+
* discriminator]`:
|
|
7
8
|
* - a numeric `rpcCode` (only the gateway's IntegrationsCliError carries one)
|
|
8
9
|
* yields `rpc:<code>` for a known code, else `rpc:other`;
|
|
9
10
|
* - otherwise a numeric HTTP `status` yields `http:<status>` for a known
|
|
10
11
|
* status, else `http:other`.
|
|
12
|
+
* The InstallTreeTornError branch is the deliberate exception: it returns a
|
|
13
|
+
* fully explicit `["InstallTreeTornError", "outcome:<token>"]` with NO
|
|
14
|
+
* DEFAULT_GROUPING lead, because its chained loader cause makes the default
|
|
15
|
+
* component unbounded (see the module header — HQ-CLI-21/22/23).
|
|
11
16
|
*
|
|
12
17
|
* `rpcCode` is checked first so a gateway JSON-RPC fault groups by its protocol
|
|
13
18
|
* code; the two carriers are disjoint in practice (the JSON-RPC throw site sets
|
|
@@ -16,12 +16,33 @@
|
|
|
16
16
|
// bucket destroys the regression watermark for every lane keyed on the issue.
|
|
17
17
|
//
|
|
18
18
|
// The remedy is a client-side fingerprint that SPLITS by a bounded machine
|
|
19
|
-
// discriminator
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
//
|
|
23
|
-
//
|
|
24
|
-
// default
|
|
19
|
+
// discriminator. Two shapes are used, and the difference between them is
|
|
20
|
+
// load-bearing — it is the lesson HQ-CLI-21/22/23 taught:
|
|
21
|
+
//
|
|
22
|
+
// - MOST branches (qmd, rpc, http) LEAD the array with the `{{ default }}`
|
|
23
|
+
// placeholder, then append the error's own name plus one discriminator token
|
|
24
|
+
// from a finite set. Sentry expands `{{ default }}` into the event's default
|
|
25
|
+
// grouping component and SALTS the appended tokens with it, so the key is only
|
|
26
|
+
// as bounded as that default component. For those carriers that is fine: they
|
|
27
|
+
// are thrown from hq-cli's own code with no chained third-party cause, so
|
|
28
|
+
// their default component is itself bounded.
|
|
29
|
+
//
|
|
30
|
+
// - The InstallTreeTornError branch must NOT lead with the placeholder. Its
|
|
31
|
+
// carrier wraps a CHAINED loader failure whose stack differs on every
|
|
32
|
+
// occurrence — whichever dependency file a concurrent global reinstall was
|
|
33
|
+
// mid-rewrite, under each machine's absolute install path — so its default
|
|
34
|
+
// component is UNBOUNDED. Leading with `{{ default }}` salted the bounded
|
|
35
|
+
// `outcome:` key with that unbounded component and minted a brand-new Sentry
|
|
36
|
+
// issue per occurrence: three events carrying the byte-identical array
|
|
37
|
+
// ["{{ default }}", "InstallTreeTornError", "outcome:unsettled"] still landed
|
|
38
|
+
// in three different groups (hashes a4289a5e530e166ebdedea9d34dcad0a,
|
|
39
|
+
// b563c1b891bd975bdc605efc86034b44, b4ee254473ea249758617de1a98848fa —
|
|
40
|
+
// HQ-CLI-21/22/23). So that branch returns a FULLY EXPLICIT key with no
|
|
41
|
+
// default lead: ["InstallTreeTornError", "outcome:<token>"].
|
|
42
|
+
//
|
|
43
|
+
// Genuinely different failure classes therefore form distinct, PREDICTABLE
|
|
44
|
+
// groups, and everything with no bounded discriminator is left to default
|
|
45
|
+
// grouping untouched.
|
|
25
46
|
//
|
|
26
47
|
// Two hard rules, mirroring HQ-CLI-S:
|
|
27
48
|
// 1. CLOSED ALLOWLIST. The discriminator is one of a finite set of known
|
|
@@ -169,11 +190,16 @@ function qmdDispositionToken(status, signal) {
|
|
|
169
190
|
* carries no discriminator from the closed allowlist (in which case the caller
|
|
170
191
|
* must leave the fingerprint unset so Sentry's default grouping applies).
|
|
171
192
|
*
|
|
172
|
-
*
|
|
193
|
+
* For the rpc/http carriers the shape is `[DEFAULT_GROUPING, errorName,
|
|
194
|
+
* discriminator]`:
|
|
173
195
|
* - a numeric `rpcCode` (only the gateway's IntegrationsCliError carries one)
|
|
174
196
|
* yields `rpc:<code>` for a known code, else `rpc:other`;
|
|
175
197
|
* - otherwise a numeric HTTP `status` yields `http:<status>` for a known
|
|
176
198
|
* status, else `http:other`.
|
|
199
|
+
* The InstallTreeTornError branch is the deliberate exception: it returns a
|
|
200
|
+
* fully explicit `["InstallTreeTornError", "outcome:<token>"]` with NO
|
|
201
|
+
* DEFAULT_GROUPING lead, because its chained loader cause makes the default
|
|
202
|
+
* component unbounded (see the module header — HQ-CLI-21/22/23).
|
|
177
203
|
*
|
|
178
204
|
* `rpcCode` is checked first so a gateway JSON-RPC fault groups by its protocol
|
|
179
205
|
* code; the two carriers are disjoint in practice (the JSON-RPC throw site sets
|
|
@@ -214,8 +240,22 @@ export function sentryFingerprintFor(err) {
|
|
|
214
240
|
}
|
|
215
241
|
// A torn-install failure carries neither an rpcCode nor an HTTP status; its
|
|
216
242
|
// only bounded discriminator is the recovery `diagnostics.outcome`. Keyed
|
|
217
|
-
// BEFORE the rpc/status branches so the family groups into
|
|
218
|
-
// (guarded / unsettled / reexec-failed / lock-held
|
|
243
|
+
// BEFORE the rpc/status branches so the family groups into a bounded set of
|
|
244
|
+
// predictable issues (guarded / unsettled / reexec-failed / lock-held, plus the
|
|
245
|
+
// `outcome:other` fallback) rather than one fungible bucket.
|
|
246
|
+
//
|
|
247
|
+
// The key is FULLY EXPLICIT — it does NOT lead with DEFAULT_GROUPING. Leading
|
|
248
|
+
// with the placeholder salts the appended tokens with Sentry's default grouping
|
|
249
|
+
// component, and THIS carrier's default component is UNBOUNDED: it wraps a
|
|
250
|
+
// chained loader cause whose stack differs on every occurrence (the dependency
|
|
251
|
+
// file a concurrent global reinstall was mid-rewrite, under each machine's
|
|
252
|
+
// absolute install path). With the placeholder lead, three events carrying the
|
|
253
|
+
// byte-identical array ["{{ default }}", "InstallTreeTornError",
|
|
254
|
+
// "outcome:unsettled"] still split into three Sentry groups —
|
|
255
|
+
// a4289a5e530e166ebdedea9d34dcad0a, b563c1b891bd975bdc605efc86034b44 and
|
|
256
|
+
// b4ee254473ea249758617de1a98848fa (HQ-CLI-21/22/23) — defeating the very bound
|
|
257
|
+
// this branch exists to enforce. The explicit key collapses them to one stable
|
|
258
|
+
// group per outcome, independent of machine, install path and which module tore.
|
|
219
259
|
if (rawName === "InstallTreeTornError") {
|
|
220
260
|
const diagnostics = record.diagnostics;
|
|
221
261
|
const outcome = diagnostics !== null && typeof diagnostics === "object"
|
|
@@ -224,7 +264,7 @@ export function sentryFingerprintFor(err) {
|
|
|
224
264
|
const token = typeof outcome === "string" && KNOWN_INSTALL_TREE_OUTCOMES.has(outcome)
|
|
225
265
|
? `outcome:${outcome}`
|
|
226
266
|
: "outcome:other";
|
|
227
|
-
return [
|
|
267
|
+
return ["InstallTreeTornError", token];
|
|
228
268
|
}
|
|
229
269
|
const name = KNOWN_ERROR_NAMES.has(rawName) ? rawName : FALLBACK_ERROR_NAME;
|
|
230
270
|
const rpcCode = record.rpcCode;
|