@rubytech/create-maxy-code 0.1.476 → 0.1.477

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.
Files changed (59) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.d.ts +2 -0
  3. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.d.ts.map +1 -0
  4. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.js +150 -0
  5. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block-sqlite.test.js.map +1 -0
  6. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.d.ts +2 -0
  7. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.d.ts.map +1 -0
  8. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.js +248 -0
  9. package/payload/platform/plugins/scheduling/mcp/dist/lib/__tests__/booking-block.test.js.map +1 -0
  10. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts +90 -0
  11. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.d.ts.map +1 -1
  12. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js +105 -0
  13. package/payload/platform/plugins/scheduling/mcp/dist/lib/booking-reconcile.js.map +1 -1
  14. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js +88 -10
  15. package/payload/platform/plugins/scheduling/mcp/dist/scripts/reconcile-bookings.js.map +1 -1
  16. package/payload/platform/scripts/cpu-triage.sh +313 -0
  17. package/payload/server/{chunk-LBCMFD4O.js → chunk-JECAP3Z2.js} +126 -37
  18. package/payload/server/maxy-edge.js +1 -1
  19. package/payload/server/public/activity.html +6 -6
  20. package/payload/server/public/assets/{AdminLoginScreens-DximwPlS.js → AdminLoginScreens-mEKP4pDi.js} +1 -1
  21. package/payload/server/public/assets/{AdminShell-BehbH-Oa.js → AdminShell-BwSaZ88d.js} +1 -1
  22. package/payload/server/public/assets/{Checkbox-DM-eHqOS.js → Checkbox-CN4uQ80w.js} +1 -1
  23. package/payload/server/public/assets/activity-CIQ8ozNZ.js +1 -0
  24. package/payload/server/public/assets/{admin-CAkDnGdk.js → admin-BVhgfgs1.js} +1 -1
  25. package/payload/server/public/assets/{browser-DXl8hOoi.js → browser-D-HMmHcM.js} +1 -1
  26. package/payload/server/public/assets/{calendar-DP6hn4-6.js → calendar-tGWvFyFn.js} +1 -1
  27. package/payload/server/public/assets/chat-DkttVxAz.js +1 -0
  28. package/payload/server/public/assets/chevron-left-CZ4ez9G5.js +1 -0
  29. package/payload/server/public/assets/data-P-mcmnNi.js +1 -0
  30. package/payload/server/public/assets/{graph-labels-CZykslZM.js → graph-labels-qnBleOE6.js} +1 -1
  31. package/payload/server/public/assets/{graph-CHcYoEJ5.js → graph-zEw610xK.js} +1 -1
  32. package/payload/server/public/assets/{maximize-2-31AZEcMS.js → maximize-2-BlTjXT_Y.js} +1 -1
  33. package/payload/server/public/assets/{operator-BGGpdsO_.js → operator-C7oIw2PG.js} +1 -1
  34. package/payload/server/public/assets/{page-DOeiiqbR.js → page-CTP7OFZa.js} +1 -1
  35. package/payload/server/public/assets/{page-BloC6ygA.js → page-DL6Zsdvk.js} +1 -1
  36. package/payload/server/public/assets/{public-CGgO6IZv.js → public-r1A9dqR_.js} +1 -1
  37. package/payload/server/public/assets/{rotate-ccw-BlAi6iFg.js → rotate-ccw-CzkkKx4-.js} +1 -1
  38. package/payload/server/public/assets/{tasks-C1giFRRL.js → tasks-fIJwYFWG.js} +1 -1
  39. package/payload/server/public/assets/{time-entry-format-CiUUQdq7.js → time-entry-format-j669DgXj.js} +1 -1
  40. package/payload/server/public/assets/{triangle-alert-CVqKuLoa.js → triangle-alert-BPgCgIef.js} +1 -1
  41. package/payload/server/public/assets/{useCopyFeedback-ksyUe_g1.js → useCopyFeedback-BmLa2aes.js} +1 -1
  42. package/payload/server/public/assets/{useSelectionMode-BPrBkdTd.js → useSelectionMode-DnnM7A8-.js} +1 -1
  43. package/payload/server/public/assets/{useSubAccountSwitcher-K4kYeN6i.css → useSubAccountSwitcher-C_E8h07P.css} +1 -1
  44. package/payload/server/public/assets/{useVoiceRecorder-CTXP8oTW.js → useVoiceRecorder-u2dwZfen.js} +1 -1
  45. package/payload/server/public/browser.html +5 -5
  46. package/payload/server/public/calendar.html +6 -6
  47. package/payload/server/public/chat.html +12 -12
  48. package/payload/server/public/data.html +11 -11
  49. package/payload/server/public/graph.html +11 -11
  50. package/payload/server/public/index.html +14 -14
  51. package/payload/server/public/operator.html +14 -14
  52. package/payload/server/public/public.html +12 -12
  53. package/payload/server/public/tasks.html +5 -5
  54. package/payload/server/server.js +173 -60
  55. package/payload/server/public/assets/activity-hDwUeQd6.js +0 -1
  56. package/payload/server/public/assets/chat-DhOfVGYM.js +0 -1
  57. package/payload/server/public/assets/chevron-left-DYNBoLii.js +0 -1
  58. package/payload/server/public/assets/data-bq8fTo_s.js +0 -1
  59. /package/payload/server/public/assets/{useSubAccountSwitcher-DzgzTRRn.js → useSubAccountSwitcher-CFa6ZAT1.js} +0 -0
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env bash
2
+ # cpu-triage.sh — sustained CPU triage for a Maxy Code device.
3
+ #
4
+ # WHY THIS EXISTS, AND WHY IT SAMPLES FOR MINUTES RATHER THAN SECONDS
5
+ #
6
+ # The booking reconcile loop runs on a 120 s cycle and a tick costs roughly
7
+ # 800 ms of network wait plus a garbage-collection burst. Measured on laptop
8
+ # 192.168.88.10 (2026-07-20), the SAME server process over the SAME method read
9
+ # 0.2%, 0.2%, 0.2% in three consecutive 25 s windows and 10.8% in a 20 s window.
10
+ # Every one of those readings was correct. Any sample shorter than the period
11
+ # either lands on a tick or misses it, so spot checks on this platform produce
12
+ # contradictory answers indefinitely. This tool therefore samples across at
13
+ # least one full cycle and reports a DISTRIBUTION (mean, peak, and what share of
14
+ # the window sat above threshold), never a single number.
15
+ #
16
+ # THREE INSTRUMENTS THIS DELIBERATELY DOES NOT USE, EACH HAVING PRODUCED A FALSE
17
+ # CONCLUSION IN THE 2026-07-20 INVESTIGATION:
18
+ # * `ps %cpu` / `top` %CPU — LIFETIME averages. A 40-minute-old process read
19
+ # 8.5% against an 8-day-old peer at 0.1%; both were actually 0.2% live. This
20
+ # nearly shipped as an "85x regression".
21
+ # * `iostat -c` first line — a SINCE-BOOT average. Read as live it reported a
22
+ # machine "42% busy" that was 87% idle at that moment.
23
+ # * `ns_last_pid` deltas — counts THREAD creation as well as forks, and was
24
+ # compared against a single 10 s sample used as a "baseline". Produced a
25
+ # false 5.6x churn regression. Fork rate here comes from /proc/stat's
26
+ # `processes` counter, which counts forks only.
27
+ # Everything below is a DELTA over a stated window. No lifetime averages.
28
+ #
29
+ # Aggregate CPU is also avoided as a headline: two hot cores out of twenty
30
+ # average down to ~3% and vanish, which is exactly how a real, operator-visible
31
+ # condition was dismissed as "nothing changed". Per-core is the primary view.
32
+ #
33
+ # Unprivileged by design: the admin assistant runs without sudo, so this uses
34
+ # only /proc and the user's own cgroup tree. `perf` and `bpftrace` need root and
35
+ # are named in the escalation hint rather than invoked.
36
+ #
37
+ # EXIT CODES (gates, for deterministic callers)
38
+ # 0 no core sustained above threshold — nothing to escalate
39
+ # 1 one or more cores sustained above threshold — findings in the report
40
+ # 2 usage error or unmet precondition (nothing measured)
41
+
42
+ set -uo pipefail
43
+
44
+ WINDOW=300 # total sampling window, seconds (>= 2 reconcile cycles)
45
+ INTERVAL=10 # sample cadence, seconds
46
+ THRESHOLD=15 # per-core busy % that counts as "hot"
47
+ SUSTAIN=50 # % of samples above THRESHOLD to call a core "sustained"
48
+ TOPN=12 # processes to report
49
+ JSON=0
50
+ CONTROL="" # optional peer brand known NOT to have the change
51
+
52
+ usage() {
53
+ cat >&2 <<USAGE
54
+ usage: cpu-triage.sh [--window S] [--interval S] [--threshold PCT]
55
+ [--sustain PCT] [--top N] [--control BRAND] [--json]
56
+
57
+ --window total sampling window in seconds (default 300, min 120)
58
+ --interval sample cadence in seconds (default 10)
59
+ --threshold per-core busy %% treated as hot (default 15)
60
+ --sustain %% of samples above threshold to call it sustained (default 50)
61
+ --top processes to report (default 12)
62
+ --control a brand on the PREVIOUS build, for like-for-like comparison.
63
+ The single most valuable input: on 2026-07-20 an un-upgraded
64
+ peer collapsed a suspected regression into a measurement artifact.
65
+ --json emit machine-readable JSON instead of the text report
66
+ USAGE
67
+ exit 2
68
+ }
69
+
70
+ while [ $# -gt 0 ]; do
71
+ case "$1" in
72
+ --window) WINDOW="${2:-}"; shift 2 ;;
73
+ --interval) INTERVAL="${2:-}"; shift 2 ;;
74
+ --threshold) THRESHOLD="${2:-}"; shift 2 ;;
75
+ --sustain) SUSTAIN="${2:-}"; shift 2 ;;
76
+ --top) TOPN="${2:-}"; shift 2 ;;
77
+ --control) CONTROL="${2:-}"; shift 2 ;;
78
+ --json) JSON=1; shift ;;
79
+ -h|--help) usage ;;
80
+ *) echo "cpu-triage: unknown argument '$1'" >&2; usage ;;
81
+ esac
82
+ done
83
+
84
+ case "$WINDOW$INTERVAL$THRESHOLD$SUSTAIN$TOPN" in *[!0-9]*) usage ;; esac
85
+ [ "$INTERVAL" -ge 1 ] || usage
86
+ if [ "$WINDOW" -lt 120 ]; then
87
+ echo "cpu-triage: refusing a window under 120s — shorter than the reconcile cycle," >&2
88
+ echo " which is what makes spot readings contradict each other." >&2
89
+ exit 2
90
+ fi
91
+ [ -r /proc/stat ] || { echo "cpu-triage: /proc/stat unreadable — Linux only" >&2; exit 2; }
92
+
93
+ SAMPLES=$(( WINDOW / INTERVAL ))
94
+ [ "$SAMPLES" -ge 2 ] || { echo "cpu-triage: window/interval must yield >= 2 samples" >&2; exit 2; }
95
+
96
+ CLK=$(getconf CLK_TCK 2>/dev/null || echo 100)
97
+ TMP=$(mktemp -d "${TMPDIR:-/tmp}/cpu-triage.XXXXXX") || exit 2
98
+ trap 'rm -rf "$TMP"' EXIT INT TERM
99
+
100
+ CG_BASE="/sys/fs/cgroup/user.slice/user-$(id -u).slice/user@$(id -u).service/app.slice"
101
+
102
+ # ---------------------------------------------------------------------------
103
+ # Sampling. One loop, one cadence, every measure derived from the same instants
104
+ # so per-core, per-process and per-service figures are directly comparable.
105
+ # ---------------------------------------------------------------------------
106
+ snapshot() {
107
+ local idx="$1"
108
+ # NOTE: every redirect below MUST be `>>`. Each sample is a fresh awk process,
109
+ # and awk's `>` truncates the file once per invocation — so `>` silently keeps
110
+ # only the LAST sample, leaving nothing to diff. That bug shipped into the
111
+ # first test run and produced an empty per-core report with mean 0%.
112
+ awk -v idx="$idx" -v out="$TMP" '
113
+ FILENAME == "/proc/stat" {
114
+ if ($1 ~ /^cpu[0-9]+$/) {
115
+ total = 0
116
+ for (i = 2; i <= NF; i++) total += $i
117
+ # busy excludes idle (field 5) and iowait (field 6)
118
+ print idx, $1, total - $5 - $6, total >> (out "/cores.raw")
119
+ }
120
+ if ($1 == "processes") print idx, $2 >> (out "/forks.raw")
121
+ next
122
+ }
123
+ # /proc/<pid>/stat — comm may contain spaces and parens; the greedy .*\)
124
+ # anchors on the LAST close paren, which is the only safe split.
125
+ {
126
+ if (match($0, /^[0-9]+ \(.*\) /)) {
127
+ pid = $1
128
+ rest = substr($0, RSTART + RLENGTH)
129
+ n = split(rest, f, " ")
130
+ if (n >= 13) print idx, pid, f[12] + f[13] >> (out "/procs.raw")
131
+ }
132
+ }
133
+ ' /proc/stat /proc/[0-9]*/stat 2>/dev/null
134
+
135
+ # Per-service cgroup CPU. Counts CHILD processes, which per-process sampling
136
+ # attributes nowhere — the original wrangler churn lived entirely in children.
137
+ #
138
+ # Read every cpu.stat in ONE awk rather than a shell loop forking per service.
139
+ # This tool reports fork rate, so its own churn is measurement noise it would
140
+ # otherwise attribute to the box: the loop form cost ~16 forks per sample.
141
+ if [ -d "$CG_BASE" ]; then
142
+ awk -v idx="$idx" '
143
+ /^usage_usec/ {
144
+ n = split(FILENAME, p, "/")
145
+ svc = p[n-1]; sub(/\.service$/, "", svc)
146
+ print idx, svc, $2
147
+ }
148
+ ' "$CG_BASE"/*.service/cpu.stat >> "$TMP/cgroup.raw" 2>/dev/null
149
+ fi
150
+ }
151
+
152
+ HOST=$(hostname 2>/dev/null || echo unknown)
153
+ NCPU=$(awk '/^cpu[0-9]+/{n++} END{print n+0}' /proc/stat)
154
+ STARTED=$(date -Is 2>/dev/null || date)
155
+
156
+ if [ "$JSON" -eq 0 ]; then
157
+ echo "cpu-triage on $HOST — sampling ${WINDOW}s at ${INTERVAL}s cadence (${SAMPLES} samples, ${NCPU} cores)"
158
+ echo "this spans at least one 120s reconcile cycle; spot readings on this platform are not reliable"
159
+ echo
160
+ fi
161
+
162
+ i=0
163
+ while [ "$i" -lt "$SAMPLES" ]; do
164
+ snapshot "$i"
165
+ i=$(( i + 1 ))
166
+ [ "$i" -lt "$SAMPLES" ] && sleep "$INTERVAL"
167
+ done
168
+ ENDED=$(date -Is 2>/dev/null || date)
169
+
170
+ [ -s "$TMP/cores.raw" ] || { echo "cpu-triage: no samples captured" >&2; exit 2; }
171
+
172
+ # ---------------------------------------------------------------------------
173
+ # Analysis — distribution per core, not a single number.
174
+ # ---------------------------------------------------------------------------
175
+ awk -v thr="$THRESHOLD" '
176
+ { key = $2
177
+ if (prev_total[key] != "") {
178
+ dt = $4 - prev_total[key]
179
+ db = $3 - prev_busy[key]
180
+ if (dt > 0) {
181
+ pct = db / dt * 100
182
+ sum[key] += pct; n[key]++
183
+ if (pct > peak[key]) peak[key] = pct
184
+ if (pct > thr) hot[key]++
185
+ }
186
+ }
187
+ prev_total[key] = $4; prev_busy[key] = $3
188
+ }
189
+ END {
190
+ for (k in sum)
191
+ printf "%s %.2f %.2f %.1f %d\n", k, sum[k]/n[k], peak[k], (hot[k]+0)/n[k]*100, n[k]
192
+ }
193
+ ' "$TMP/cores.raw" | sort -k2 -rn > "$TMP/cores.out"
194
+
195
+ awk -v clk="$CLK" -v iv="$INTERVAL" '
196
+ { key = $2
197
+ if (prev[key] != "") {
198
+ d = $3 - prev[key]
199
+ if (d >= 0) {
200
+ pct = d / (clk * iv) * 100
201
+ sum[key] += pct; n[key]++
202
+ if (pct > peak[key]) peak[key] = pct
203
+ }
204
+ }
205
+ prev[key] = $3
206
+ }
207
+ END { for (k in sum) if (sum[k]/n[k] >= 0.05) printf "%s %.2f %.2f\n", k, sum[k]/n[k], peak[k] }
208
+ ' "$TMP/procs.raw" | sort -k2 -rn > "$TMP/procs.out"
209
+
210
+ if [ -s "${TMP}/cgroup.raw" ]; then
211
+ awk -v iv="$INTERVAL" '
212
+ { key = $2
213
+ if (prev[key] != "") {
214
+ d = $3 - prev[key]
215
+ if (d >= 0) { pct = d / (iv * 1000000) * 100; sum[key] += pct; n[key]++
216
+ if (pct > peak[key]) peak[key] = pct }
217
+ }
218
+ prev[key] = $3
219
+ }
220
+ END { for (k in sum) printf "%s %.2f %.2f\n", k, sum[k]/n[k], peak[k] }
221
+ ' "$TMP/cgroup.raw" | sort -k2 -rn > "$TMP/cgroup.out"
222
+ fi
223
+
224
+ FORKS_MIN=$(awk -v iv="$INTERVAL" 'NR==1{f=$2;i=$1} END{ if (NR>1) printf "%.0f", ($2-f)/((($1-i)*iv))*60 }' "$TMP/forks.raw" 2>/dev/null)
225
+ [ -n "$FORKS_MIN" ] || FORKS_MIN=0
226
+
227
+ HOT_COUNT=$(awk -v s="$SUSTAIN" '$4 >= s {n++} END{print n+0}' "$TMP/cores.out")
228
+ MEAN_CORE=$(awk '{s+=$2; n++} END{ if(n) printf "%.2f", s/n; else print "0" }' "$TMP/cores.out")
229
+
230
+ resolve() { tr '\0' ' ' < "/proc/$1/cmdline" 2>/dev/null | cut -c1-78 || true; }
231
+
232
+ # ---------------------------------------------------------------------------
233
+ # Report
234
+ # ---------------------------------------------------------------------------
235
+ if [ "$JSON" -eq 1 ]; then
236
+ printf '{\n "host": %s,\n "started": %s,\n "ended": %s,\n' "\"$HOST\"" "\"$STARTED\"" "\"$ENDED\""
237
+ printf ' "windowSec": %s, "intervalSec": %s, "samples": %s, "cores": %s,\n' "$WINDOW" "$INTERVAL" "$SAMPLES" "$NCPU"
238
+ printf ' "thresholdPct": %s, "sustainPct": %s,\n' "$THRESHOLD" "$SUSTAIN"
239
+ printf ' "meanPerCorePct": %s, "sustainedHotCores": %s, "forksPerMin": %s,\n' "$MEAN_CORE" "$HOT_COUNT" "$FORKS_MIN"
240
+ printf ' "perCore": ['
241
+ awk '{ printf "%s{\"cpu\":\"%s\",\"meanPct\":%s,\"peakPct\":%s,\"aboveThresholdPct\":%s}", (NR>1?",":""), $1,$2,$3,$4 }' "$TMP/cores.out"
242
+ printf '],\n "topProcesses": ['
243
+ head -n "$TOPN" "$TMP/procs.out" | while read -r pid mean peak; do
244
+ cl=$(resolve "$pid" | sed 's/\\/\\\\/g; s/"/\\"/g')
245
+ printf '{"pid":%s,"meanPct":%s,"peakPct":%s,"cmd":"%s"},' "$pid" "$mean" "$peak" "$cl"
246
+ done | sed 's/,$//'
247
+ printf '],\n "perService": ['
248
+ if [ -s "${TMP}/cgroup.out" ]; then
249
+ awk '{ printf "%s{\"service\":\"%s\",\"meanPct\":%s,\"peakPct\":%s}", (NR>1?",":""), $1,$2,$3 }' "$TMP/cgroup.out"
250
+ fi
251
+ printf ']\n}\n'
252
+ else
253
+ echo "PER-CORE over the window (mean / peak / share of window above ${THRESHOLD}%)"
254
+ echo " a core is 'sustained' when it exceeds threshold in >= ${SUSTAIN}% of samples"
255
+ awk -v thr="$THRESHOLD" -v s="$SUSTAIN" '
256
+ $2 >= 1 || $4 > 0 {
257
+ flag = ($4 >= s) ? " <== SUSTAINED" : ""
258
+ printf " %-7s mean=%6.2f%% peak=%6.2f%% above=%5.1f%% of window%s\n", $1, $2, $3, $4, flag
259
+ }' "$TMP/cores.out"
260
+ echo " ---"
261
+ printf " mean per-core %s%% sustained hot cores: %s of %s forks %s/min\n\n" "$MEAN_CORE" "$HOT_COUNT" "$NCPU" "$FORKS_MIN"
262
+
263
+ echo "TOP PROCESSES by measured delta (100% = one full core; NOT a lifetime average)"
264
+ head -n "$TOPN" "$TMP/procs.out" | while read -r pid mean peak; do
265
+ printf " %6.2f%% mean %6.2f%% peak pid=%-8s %s\n" "$mean" "$peak" "$pid" "$(resolve "$pid")"
266
+ done
267
+ echo
268
+
269
+ if [ -s "${TMP}/cgroup.out" ]; then
270
+ echo "PER-SERVICE cgroup CPU (child processes included — the platform's true footprint)"
271
+ tot=$(awk '{s+=$2} END{printf "%.2f", s}' "$TMP/cgroup.out")
272
+ awk '$2 >= 0.01 { printf " %-32s mean=%6.2f%% peak=%6.2f%%\n", $1, $2, $3 }' "$TMP/cgroup.out"
273
+ printf " ---\n all services %s%% of one core (%.2f%% of the %s-core box)\n\n" \
274
+ "$tot" "$(awk -v t="$tot" -v c="$NCPU" 'BEGIN{print t/c}')" "$NCPU"
275
+ if [ -n "$CONTROL" ]; then
276
+ cval=$(awk -v c="$CONTROL" '$1 == c {print $2}' "$TMP/cgroup.out")
277
+ if [ -n "$cval" ]; then
278
+ echo "CONTROL: '$CONTROL' is on the previous build and measured ${cval}% of one core."
279
+ echo " Compare peers against this, not against their own past readings. A peer that"
280
+ echo " did not get the change is worth more than any before/after inference."
281
+ echo
282
+ else
283
+ echo "CONTROL: '$CONTROL' not found among running services — comparison skipped."; echo
284
+ fi
285
+ fi
286
+ fi
287
+
288
+ if command -v sar >/dev/null 2>&1; then
289
+ y=$(date -d yesterday +%d 2>/dev/null)
290
+ if [ -n "$y" ] && [ -r "/var/log/sysstat/sa$y" ]; then
291
+ echo "HISTORY — same instrument, yesterday, for like-for-like regression checking"
292
+ sar -P ALL -f "/var/log/sysstat/sa$y" 2>/dev/null | awk -v thr="$THRESHOLD" '
293
+ /Average/ && $2 ~ /^[0-9]+$/ { b = 100 - $8; s += b; n++; if (b > thr) h++ }
294
+ END { if (n) printf " yesterday: mean per-core %.2f%% cores above %s%%: %d/%d\n", s/n, thr, h+0, n }'
295
+ echo
296
+ fi
297
+ fi
298
+
299
+ if [ "$HOT_COUNT" -gt 0 ]; then
300
+ echo "VERDICT: ${HOT_COUNT} core(s) sustained above ${THRESHOLD}%. Findings above."
301
+ echo " Before calling it a regression, check the desktop stack in the process list."
302
+ echo " On 2026-07-20 gnome-shell + gnome-system-monitor + Xorg accounted for ~41% of"
303
+ echo " a core, roughly three times the entire four-brand platform, and the System"
304
+ echo " Monitor window doing the observing was itself a third of that."
305
+ echo " To attribute short-lived process churn, escalate (needs root):"
306
+ echo " bpftrace -e 'tracepoint:syscalls:sys_enter_execve { @[comm, str(args->filename)] = count(); }'"
307
+ else
308
+ echo "VERDICT: no core sustained above ${THRESHOLD}%."
309
+ fi
310
+ fi
311
+
312
+ [ "$HOT_COUNT" -gt 0 ] && exit 1
313
+ exit 0