instar 1.3.233 → 1.3.235

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 (53) hide show
  1. package/dashboard/index.html +140 -0
  2. package/dist/commands/reflect.d.ts.map +1 -1
  3. package/dist/commands/reflect.js +5 -0
  4. package/dist/commands/reflect.js.map +1 -1
  5. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  6. package/dist/config/ConfigDefaults.js +14 -4
  7. package/dist/config/ConfigDefaults.js.map +1 -1
  8. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  9. package/dist/core/PostUpdateMigrator.js +22 -2
  10. package/dist/core/PostUpdateMigrator.js.map +1 -1
  11. package/dist/core/SessionManager.d.ts +12 -0
  12. package/dist/core/SessionManager.d.ts.map +1 -1
  13. package/dist/core/SessionManager.js +30 -0
  14. package/dist/core/SessionManager.js.map +1 -1
  15. package/dist/core/types.d.ts +22 -0
  16. package/dist/core/types.d.ts.map +1 -1
  17. package/dist/core/types.js.map +1 -1
  18. package/dist/monitoring/CommitmentSentinel.d.ts +6 -0
  19. package/dist/monitoring/CommitmentSentinel.d.ts.map +1 -1
  20. package/dist/monitoring/CommitmentSentinel.js +46 -1
  21. package/dist/monitoring/CommitmentSentinel.js.map +1 -1
  22. package/dist/monitoring/ResourceLedger.d.ts +62 -0
  23. package/dist/monitoring/ResourceLedger.d.ts.map +1 -1
  24. package/dist/monitoring/ResourceLedger.js +152 -2
  25. package/dist/monitoring/ResourceLedger.js.map +1 -1
  26. package/dist/monitoring/ResourceSampler.d.ts +63 -0
  27. package/dist/monitoring/ResourceSampler.d.ts.map +1 -0
  28. package/dist/monitoring/ResourceSampler.js +277 -0
  29. package/dist/monitoring/ResourceSampler.js.map +1 -0
  30. package/dist/monitoring/SessionWatchdog.d.ts.map +1 -1
  31. package/dist/monitoring/SessionWatchdog.js +5 -0
  32. package/dist/monitoring/SessionWatchdog.js.map +1 -1
  33. package/dist/scaffold/templates.js +4 -4
  34. package/dist/scaffold/templates.js.map +1 -1
  35. package/dist/server/AgentServer.d.ts +1 -0
  36. package/dist/server/AgentServer.d.ts.map +1 -1
  37. package/dist/server/AgentServer.js +48 -5
  38. package/dist/server/AgentServer.js.map +1 -1
  39. package/dist/server/CapabilityIndex.d.ts.map +1 -1
  40. package/dist/server/CapabilityIndex.js +4 -2
  41. package/dist/server/CapabilityIndex.js.map +1 -1
  42. package/dist/server/routes.d.ts.map +1 -1
  43. package/dist/server/routes.js +43 -0
  44. package/dist/server/routes.js.map +1 -1
  45. package/package.json +1 -1
  46. package/src/data/builtin-manifest.json +65 -65
  47. package/src/scaffold/templates.ts +4 -4
  48. package/upgrades/1.3.234.md +33 -0
  49. package/upgrades/1.3.235.md +110 -0
  50. package/upgrades/commitment-bare-continuation-guard.eli16.md +26 -0
  51. package/upgrades/side-effects/commitment-bare-continuation-guard.md +42 -0
  52. package/upgrades/side-effects/esm-require-fixes-gate-rearm.md +110 -0
  53. package/upgrades/side-effects/resource-ledger.md +110 -0
@@ -16,8 +16,12 @@
16
16
  * emission, with a real per-event identity (not a content hash) so legitimate
17
17
  * same-millisecond events don't collapse and a restart can't replay-double-count.
18
18
  *
19
- * CPU/memory sampling (resource_samples) + retention is Phase B; the table and
20
- * its methods are not in this file yet.
19
+ * Phase B adds continuous CPU% + memory sampling (resource_samples) of the
20
+ * agent's OWN server process and its spawned session processes, written by
21
+ * ResourceSampler on a cadence. Same discipline: read-only, fail-open, bounded
22
+ * (retention prune). This closes the "instar tracks zero CPU and zero memory"
23
+ * gap — token usage was well-tracked (TokenLedger) but per-agent CPU/RSS was
24
+ * unaccounted for.
21
25
  *
22
26
  * Spec: docs/specs/per-agent-resource-ledger.md.
23
27
  */
@@ -40,10 +44,25 @@ const SCHEMA = [
40
44
  `CREATE INDEX IF NOT EXISTS idx_rle_ts ON rate_limit_events (ts)`,
41
45
  `CREATE INDEX IF NOT EXISTS idx_rle_kind_ts ON rate_limit_events (kind, ts)`,
42
46
  `CREATE INDEX IF NOT EXISTS idx_rle_source_ts ON rate_limit_events (source, ts)`,
47
+ // Phase B: continuous CPU% + RSS samples. One row per source per sampling
48
+ // tick (server + each session + an aggregate). No primary key beyond rowid:
49
+ // a sample is a point-in-time reading, not an idempotent event — re-inserts
50
+ // are real data. Bounded by retention prune (pruneOlderThan).
51
+ `CREATE TABLE IF NOT EXISTS resource_samples (
52
+ ts INTEGER NOT NULL,
53
+ source TEXT NOT NULL,
54
+ pid INTEGER,
55
+ cpu_percent REAL NOT NULL DEFAULT 0,
56
+ rss_bytes INTEGER NOT NULL DEFAULT 0,
57
+ heap_used_bytes INTEGER
58
+ )`,
59
+ `CREATE INDEX IF NOT EXISTS idx_rs_ts ON resource_samples (ts)`,
60
+ `CREATE INDEX IF NOT EXISTS idx_rs_source_ts ON resource_samples (source, ts)`,
43
61
  ];
44
62
  export class ResourceLedger {
45
63
  db;
46
64
  insertEvent;
65
+ insertSample;
47
66
  closed = false;
48
67
  constructor(opts) {
49
68
  if (opts.dbPath !== ':memory:') {
@@ -71,6 +90,9 @@ export class ResourceLedger {
71
90
  this.insertEvent = this.db.prepare(`INSERT OR IGNORE INTO rate_limit_events
72
91
  (id, ts, kind, source, account_key, session_name, reason, detail)
73
92
  VALUES (@id, @ts, @kind, @source, @accountKey, @sessionName, @reason, @detail)`);
93
+ this.insertSample = this.db.prepare(`INSERT INTO resource_samples
94
+ (ts, source, pid, cpu_percent, rss_bytes, heap_used_bytes)
95
+ VALUES (@ts, @source, @pid, @cpuPercent, @rssBytes, @heapUsedBytes)`);
74
96
  }
75
97
  /** Per-event identity: ts + source + seq is unique within a process; the source
76
98
  * prefix keeps breaker and sentinel rows from ever colliding. NOT a content
@@ -150,6 +172,134 @@ export class ResourceLedger {
150
172
  LIMIT ?`)
151
173
  .all(since, limit);
152
174
  }
175
+ // ── Phase B: CPU + memory samples ─────────────────────────────────────────
176
+ /** Record one CPU/memory sample. Never throws — observability must not break
177
+ * the observed path. Negative/NaN numbers are clamped so a bad reading can't
178
+ * poison aggregates. */
179
+ record(s) {
180
+ if (this.closed)
181
+ return;
182
+ try {
183
+ this.insertSample.run({
184
+ ts: s.ts,
185
+ source: s.source,
186
+ pid: typeof s.pid === 'number' && Number.isFinite(s.pid) ? Math.trunc(s.pid) : null,
187
+ cpuPercent: ResourceLedger.clampNonNeg(s.cpuPercent),
188
+ rssBytes: ResourceLedger.clampNonNeg(s.rssBytes),
189
+ heapUsedBytes: s.heapUsedBytes == null ? null : ResourceLedger.clampNonNeg(s.heapUsedBytes),
190
+ });
191
+ }
192
+ catch {
193
+ /* swallow — never break the observed path */
194
+ }
195
+ }
196
+ /** Record a batch of samples in one transaction (one tick's worth). Fail-open:
197
+ * a write error rolls back this batch only and is swallowed. */
198
+ recordSamples(samples) {
199
+ if (this.closed || samples.length === 0)
200
+ return;
201
+ try {
202
+ const txn = this.db.transaction((rows) => {
203
+ for (const s of rows)
204
+ this.record(s);
205
+ });
206
+ txn(samples);
207
+ }
208
+ catch {
209
+ /* swallow */
210
+ }
211
+ }
212
+ static clampNonNeg(n) {
213
+ return Number.isFinite(n) && n > 0 ? n : 0;
214
+ }
215
+ /**
216
+ * Per-source CPU% + RSS rollup over the trailing window: current (latest
217
+ * sample), plus avg/peak across the window, plus the synthetic `aggregate`
218
+ * row if present. Newest-first ordering by recency of last sample.
219
+ */
220
+ summary(sinceMs) {
221
+ const rows = this.db
222
+ .prepare(`SELECT
223
+ source,
224
+ AVG(cpu_percent) AS avgCpuPercent,
225
+ MAX(cpu_percent) AS peakCpuPercent,
226
+ AVG(rss_bytes) AS avgRssBytes,
227
+ MAX(rss_bytes) AS peakRssBytes,
228
+ COUNT(*) AS sampleCount,
229
+ MAX(ts) AS newestTs
230
+ FROM resource_samples
231
+ WHERE ts >= ?
232
+ GROUP BY source
233
+ ORDER BY newestTs DESC`)
234
+ .all(sinceMs);
235
+ const latest = this.db.prepare(`SELECT cpu_percent AS cpuPercent, rss_bytes AS rssBytes, heap_used_bytes AS heapUsedBytes
236
+ FROM resource_samples
237
+ WHERE source = ? AND ts >= ?
238
+ ORDER BY ts DESC LIMIT 1`);
239
+ return rows.map((r) => {
240
+ const cur = latest.get(String(r.source), sinceMs);
241
+ return {
242
+ source: String(r.source),
243
+ currentCpuPercent: cur ? Number(cur.cpuPercent) : null,
244
+ currentRssBytes: cur ? Number(cur.rssBytes) : null,
245
+ currentHeapUsedBytes: cur && cur.heapUsedBytes != null ? Number(cur.heapUsedBytes) : null,
246
+ avgCpuPercent: +(Number(r.avgCpuPercent ?? 0)).toFixed(2),
247
+ peakCpuPercent: +(Number(r.peakCpuPercent ?? 0)).toFixed(2),
248
+ avgRssBytes: Math.round(Number(r.avgRssBytes ?? 0)),
249
+ peakRssBytes: Math.round(Number(r.peakRssBytes ?? 0)),
250
+ sampleCount: Number(r.sampleCount ?? 0),
251
+ newestTs: r.newestTs ?? null,
252
+ };
253
+ });
254
+ }
255
+ /** Recent raw samples, newest first (paginated). */
256
+ recentSamples(opts = {}) {
257
+ const limit = Math.min(Math.max(opts.limit ?? 100, 1), 2000);
258
+ const since = opts.sinceMs ?? 0;
259
+ if (opts.source) {
260
+ return this.db
261
+ .prepare(`SELECT ts, source, pid, cpu_percent AS cpuPercent,
262
+ rss_bytes AS rssBytes, heap_used_bytes AS heapUsedBytes
263
+ FROM resource_samples
264
+ WHERE ts >= ? AND source = ?
265
+ ORDER BY ts DESC LIMIT ?`)
266
+ .all(since, opts.source, limit);
267
+ }
268
+ return this.db
269
+ .prepare(`SELECT ts, source, pid, cpu_percent AS cpuPercent,
270
+ rss_bytes AS rssBytes, heap_used_bytes AS heapUsedBytes
271
+ FROM resource_samples
272
+ WHERE ts >= ?
273
+ ORDER BY ts DESC LIMIT ?`)
274
+ .all(since, limit);
275
+ }
276
+ /** Total number of CPU/mem samples stored. */
277
+ sampleCount() {
278
+ try {
279
+ const row = this.db.prepare(`SELECT COUNT(*) AS n FROM resource_samples`).get();
280
+ return Number(row?.n ?? 0);
281
+ }
282
+ catch {
283
+ // @silent-fallback-ok: read-only observability count. A DB read error must
284
+ // never break the observed path; "unknown count" degrades to 0, not a throw.
285
+ return 0;
286
+ }
287
+ }
288
+ /** Delete samples older than `cutoffMs`. Returns rows deleted. Fail-open. */
289
+ pruneOlderThan(cutoffMs) {
290
+ if (this.closed)
291
+ return 0;
292
+ try {
293
+ const res = this.db.prepare(`DELETE FROM resource_samples WHERE ts < ?`).run(cutoffMs);
294
+ return Number(res.changes ?? 0);
295
+ }
296
+ catch {
297
+ // @silent-fallback-ok: retention prune is best-effort housekeeping. A failed
298
+ // prune just leaves older rows for the next tick; it must not throw into the
299
+ // sampler's hot path.
300
+ return 0;
301
+ }
302
+ }
153
303
  close() {
154
304
  if (this.closed)
155
305
  return;
@@ -1 +1 @@
1
- {"version":3,"file":"ResourceLedger.js","sourceRoot":"","sources":["../../src/monitoring/ResourceLedger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAEtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAmErE,MAAM,MAAM,GAAG;IACb;;;;;;;;;KASG;IACH,iEAAiE;IACjE,4EAA4E;IAC5E,gFAAgF;CACjF,CAAC;AAEF,MAAM,OAAO,cAAc;IACjB,EAAE,CAAuB;IACzB,WAAW,CAA+C;IAC1D,MAAM,GAAG,KAAK,CAAC;IAEvB,YAAY,IAA2B;QACrC,IAAI,IAAI,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;YAC/B,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/D,CAAC;QACD,sEAAsE;QACtE,8EAA8E;QAC9E,IAAI,CAAC,EAAE,GAAG,kBAAkB,CAAC,gBAAgB,CAC3C,gBAAgB,EAChB,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CACvE,CAAC;QACF,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACvC,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;YACzB,IAAI,CAAC;gBACH,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACpB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,IAAI,EAAE,CAAC;gBACzC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,GAAG,CAAC;oBAAE,MAAM,GAAG,CAAC;YACrD,CAAC;QACH,CAAC;QACD,oBAAoB,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;YAAC,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzF,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAChC;;sFAEgF,CACjF,CAAC;IACJ,CAAC;IAED;;6DAEyD;IACjD,MAAM,CAAC,OAAO,CAAC,CAAsB;QAC3C,OAAO,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;IACxC,CAAC;IAED;0DACsD;IACtD,oBAAoB,CAAC,CAAsB;QACzC,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC;YACH,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC;gBACnB,EAAE,EAAE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;gBAC7B,EAAE,EAAE,CAAC,CAAC,EAAE;gBACR,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,UAAU,EAAE,CAAC,CAAC,UAAU,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS;gBACjF,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;gBAClC,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI;gBACxB,MAAM,EAAE,CAAC,CAAC,MAAM,IAAI,IAAI;aACzB,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,8EAA8E;QAChF,CAAC;IACH,CAAC;IAED,kEAAkE;IAClE,gBAAgB,CAAC,KAAa,EAAE,QAAgB;QAC9C,MAAM,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CACN;;;;;;;;uBAQe,CAChB;aACA,GAAG,CAAC,KAAK,CAAkC,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,CAAC,CAAC;QAChD,MAAM,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;QACnC,OAAO;YACL,gBAAgB,EAAE,KAAK;YACvB,mBAAmB,EAAE,MAAM,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,CAAC;YACzD,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,CAAC;YAC7C,WAAW,EAAE,MAAM,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,CAAC;YACzC,YAAY,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,IAAI;YACxC,aAAa,EAAE,GAAG,CAAC,aAAa,IAAI,IAAI;YACxC,QAAQ;SACT,CAAC;IACJ,CAAC;IAED,0CAA0C;IAC1C,eAAe,CAAC,KAAa,EAAE,QAAgB;QAC7C,MAAM,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;QAC/B,OAAO,IAAI,CAAC,EAAE;aACX,OAAO,CACN;;;;6BAIqB,CACtB;aACA,GAAG,CAAC,KAAK,CAAuB,CAAC;IACtC,CAAC;IAED,uCAAuC;IACvC,eAAe,CAAC,OAA6C,EAAE;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAChC,OAAO,IAAI,CAAC,EAAE;aACX,OAAO,CACN;;;;;iBAKS,CACV;aACA,GAAG,CAAC,KAAK,EAAE,KAAK,CAAwB,CAAC;IAC9C,CAAC;IAED,KAAK;QACH,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IACjD,CAAC;CACF"}
1
+ {"version":3,"file":"ResourceLedger.js","sourceRoot":"","sources":["../../src/monitoring/ResourceLedger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import type { ResourceLedger } from './ResourceLedger.js';
2
+ export interface ResourceSamplerOptions {
3
+ ledger: ResourceLedger;
4
+ /** Returns the live session pane PIDs to sample, keyed by session id. Called
5
+ * each tick; an error/empty result just means "no sessions this tick". */
6
+ getSessionPids: () => Array<{
7
+ id: string;
8
+ pid: number;
9
+ }>;
10
+ /** Active sampling cadence (ms). Defaults to 60_000. */
11
+ intervalMs?: number;
12
+ /** Idle sampling cadence (ms) — used when getSessionPids() is empty. Default 5min. */
13
+ idleIntervalMs?: number;
14
+ /** Retention window (ms) — samples older than this are pruned each tick. Default 7d. */
15
+ retentionMs?: number;
16
+ /** Test seam: read this process's CPU usage (microseconds). Defaults to process.cpuUsage. */
17
+ cpuUsageFn?: (previous?: NodeJS.CpuUsage) => NodeJS.CpuUsage;
18
+ /** Test seam: read this process's memory. Defaults to process.memoryUsage. */
19
+ memoryUsageFn?: () => NodeJS.MemoryUsage;
20
+ /** Test seam: monotonic clock (ms). Defaults to Date.now. */
21
+ now?: () => number;
22
+ /** Test seam: sample a batch of OS pids. Defaults to a batched `ps` call. */
23
+ samplePidsFn?: (pids: number[]) => Promise<Map<number, {
24
+ cpuPercent: number;
25
+ rssBytes: number;
26
+ }>>;
27
+ /** Optional error sink (defaults to a single console.warn). */
28
+ onError?: (err: unknown) => void;
29
+ }
30
+ export declare class ResourceSampler {
31
+ private readonly ledger;
32
+ private readonly getSessionPids;
33
+ private readonly intervalMs;
34
+ private readonly idleIntervalMs;
35
+ private readonly retentionMs;
36
+ private readonly cpuUsageFn;
37
+ private readonly memoryUsageFn;
38
+ private readonly now;
39
+ private readonly samplePidsFn;
40
+ private readonly onError;
41
+ private timer;
42
+ private running;
43
+ private started;
44
+ private closed;
45
+ private lastCpu;
46
+ private lastCpuAtMs;
47
+ constructor(opts: ResourceSamplerOptions);
48
+ start(): void;
49
+ stop(): void;
50
+ /** Self-rescheduling timer (NOT setInterval) so the cadence can adapt to
51
+ * idle/active each tick and a slow tick can't stack. unref()'d. */
52
+ private schedule;
53
+ /** Run one sampling pass. Public for tests. Never throws. */
54
+ tick(): Promise<void>;
55
+ /**
56
+ * CPU% for THIS process over the interval since the last tick: the
57
+ * (user+system) microseconds consumed divided by the wall-clock microseconds
58
+ * elapsed, ×100. One fully-busy core reads ~100. Returns 0 when there's no
59
+ * prior baseline yet (first tick) or the clock didn't advance.
60
+ */
61
+ private computeOwnCpuPercent;
62
+ }
63
+ //# sourceMappingURL=ResourceSampler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourceSampler.d.ts","sourceRoot":"","sources":["../../src/monitoring/ResourceSampler.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAE/E,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,cAAc,CAAC;IACvB;+EAC2E;IAC3E,cAAc,EAAE,MAAM,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACzD,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sFAAsF;IACtF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,6FAA6F;IAC7F,UAAU,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC;IAC7D,8EAA8E;IAC9E,aAAa,CAAC,EAAE,MAAM,MAAM,CAAC,WAAW,CAAC;IACzC,6DAA6D;IAC7D,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IAClG,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAC;CAClC;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA2C;IAC1E,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkD;IAC7E,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2B;IACzD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAEuC;IACpE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IAEjD,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IAGvB,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,WAAW,CAAuB;gBAE9B,IAAI,EAAE,sBAAsB;IAgBxC,KAAK,IAAI,IAAI;IAiBb,IAAI,IAAI,IAAI;IAQZ;wEACoE;IACpE,OAAO,CAAC,QAAQ;IAUhB,6DAA6D;IACvD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAsG3B;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;CAqB7B"}
@@ -0,0 +1,277 @@
1
+ /**
2
+ * ResourceSampler — Phase B of the per-agent ResourceLedger.
3
+ *
4
+ * A background poller (mirrors TokenLedgerPoller) that, on a cadence, samples:
5
+ * (a) the agent's OWN server process — CPU% via a process.cpuUsage() delta
6
+ * over the tick interval, and RSS + V8 heapUsed via process.memoryUsage();
7
+ * (b) the agent's spawned session processes — by their tracked pane PIDs, via
8
+ * ONE batched `ps -o %cpu=,rss= -p <pid>,<pid>,...` call (tolerating dead
9
+ * PIDs), so the resource tracker is itself cheap (a single child process
10
+ * per tick, no per-PID fork storm);
11
+ * and records each plus an `aggregate` (server + all sessions) into the
12
+ * ResourceLedger. After recording it prunes samples beyond the retention window.
13
+ *
14
+ * Discipline (read-only observability, identical to TokenLedgerPoller):
15
+ * - Strictly off the hot path. A sampling error NEVER throws or crashes — every
16
+ * OS call and DB write is guarded; a failed tick just records nothing and the
17
+ * next tick retries.
18
+ * - It never gates, throttles, or reaches back into any runtime flow. It only
19
+ * reads `ps`/`process.*` and writes the ledger.
20
+ * - The timer is unref()'d so it can never keep the process alive on its own,
21
+ * and backs off while the agent is idle (no running sessions) to keep the
22
+ * idle CPU floor low (Responsible Resource Usage).
23
+ *
24
+ * Spec: docs/specs/per-agent-resource-ledger.md.
25
+ */
26
+ import { execFile } from 'node:child_process';
27
+ export class ResourceSampler {
28
+ ledger;
29
+ getSessionPids;
30
+ intervalMs;
31
+ idleIntervalMs;
32
+ retentionMs;
33
+ cpuUsageFn;
34
+ memoryUsageFn;
35
+ now;
36
+ samplePidsFn;
37
+ onError;
38
+ timer = null;
39
+ running = false;
40
+ started = false;
41
+ closed = false;
42
+ // CPU% for the OWN process is a delta: (cpuMicros now - last) / (wallMs * 1000).
43
+ lastCpu = null;
44
+ lastCpuAtMs = null;
45
+ constructor(opts) {
46
+ this.ledger = opts.ledger;
47
+ this.getSessionPids = opts.getSessionPids;
48
+ this.intervalMs = opts.intervalMs && opts.intervalMs > 0 ? opts.intervalMs : 60_000;
49
+ this.idleIntervalMs =
50
+ opts.idleIntervalMs && opts.idleIntervalMs > 0 ? opts.idleIntervalMs : 5 * 60_000;
51
+ this.retentionMs =
52
+ opts.retentionMs && opts.retentionMs > 0 ? opts.retentionMs : 7 * 24 * 60 * 60 * 1000;
53
+ this.cpuUsageFn = opts.cpuUsageFn ?? ((prev) => process.cpuUsage(prev));
54
+ this.memoryUsageFn = opts.memoryUsageFn ?? (() => process.memoryUsage());
55
+ this.now = opts.now ?? (() => Date.now());
56
+ this.samplePidsFn = opts.samplePidsFn ?? ((pids) => samplePidsViaPs(pids));
57
+ this.onError =
58
+ opts.onError ?? ((err) => console.warn('[resource-ledger] sample error:', err));
59
+ }
60
+ start() {
61
+ if (this.started || this.closed)
62
+ return;
63
+ this.started = true;
64
+ // Prime the CPU baseline so the first real tick has a delta to compare.
65
+ try {
66
+ this.lastCpu = this.cpuUsageFn();
67
+ this.lastCpuAtMs = this.now();
68
+ }
69
+ catch {
70
+ // @silent-fallback-ok: priming the CPU baseline is best-effort. If cpuUsage
71
+ // is unavailable we leave the baseline null so the first real tick reports
72
+ // 0% rather than crashing the sampler at start.
73
+ this.lastCpu = null;
74
+ this.lastCpuAtMs = null;
75
+ }
76
+ this.schedule(this.intervalMs);
77
+ }
78
+ stop() {
79
+ this.started = false;
80
+ if (this.timer) {
81
+ clearTimeout(this.timer);
82
+ this.timer = null;
83
+ }
84
+ }
85
+ /** Self-rescheduling timer (NOT setInterval) so the cadence can adapt to
86
+ * idle/active each tick and a slow tick can't stack. unref()'d. */
87
+ schedule(delayMs) {
88
+ if (!this.started || this.closed)
89
+ return;
90
+ const t = setTimeout(() => {
91
+ this.timer = null;
92
+ void this.tick();
93
+ }, delayMs);
94
+ t.unref?.();
95
+ this.timer = t;
96
+ }
97
+ /** Run one sampling pass. Public for tests. Never throws. */
98
+ async tick() {
99
+ if (this.running) {
100
+ // A previous tick is still in flight (slow `ps`); skip and reschedule.
101
+ this.schedule(this.intervalMs);
102
+ return;
103
+ }
104
+ this.running = true;
105
+ let nextDelay = this.intervalMs;
106
+ try {
107
+ const ts = this.now();
108
+ const samples = [];
109
+ // (a) Own server process — CPU% from the cpuUsage delta over wall time.
110
+ const ownCpuPercent = this.computeOwnCpuPercent(ts);
111
+ let ownRss = 0;
112
+ let ownHeap = null;
113
+ try {
114
+ const mem = this.memoryUsageFn();
115
+ ownRss = mem.rss;
116
+ ownHeap = mem.heapUsed;
117
+ }
118
+ catch {
119
+ /* memoryUsage failed — record zero rather than skip the whole tick */
120
+ }
121
+ let aggCpu = ownCpuPercent;
122
+ let aggRss = ownRss;
123
+ samples.push({
124
+ ts,
125
+ source: 'agent-server',
126
+ pid: process.pid,
127
+ cpuPercent: ownCpuPercent,
128
+ rssBytes: ownRss,
129
+ heapUsedBytes: ownHeap,
130
+ });
131
+ // (b) Spawned session processes — one batched ps call for ALL pids.
132
+ let sessions = [];
133
+ try {
134
+ sessions = this.getSessionPids() ?? [];
135
+ }
136
+ catch {
137
+ sessions = [];
138
+ }
139
+ if (sessions.length > 0) {
140
+ const pids = sessions
141
+ .map((s) => s.pid)
142
+ .filter((p) => Number.isInteger(p) && p > 0);
143
+ let measured = new Map();
144
+ if (pids.length > 0) {
145
+ try {
146
+ measured = await this.samplePidsFn(pids);
147
+ }
148
+ catch {
149
+ measured = new Map();
150
+ }
151
+ }
152
+ for (const s of sessions) {
153
+ const m = measured.get(s.pid);
154
+ if (!m)
155
+ continue; // dead/unmeasurable pid — tolerate, skip
156
+ aggCpu += m.cpuPercent;
157
+ aggRss += m.rssBytes;
158
+ samples.push({
159
+ ts,
160
+ source: `session:${s.id}`,
161
+ pid: s.pid,
162
+ cpuPercent: m.cpuPercent,
163
+ rssBytes: m.rssBytes,
164
+ heapUsedBytes: null, // heapUsed is only knowable for our own V8
165
+ });
166
+ }
167
+ }
168
+ else {
169
+ // No running sessions → idle. Back off the cadence to keep the idle
170
+ // CPU floor low (Responsible Resource Usage).
171
+ nextDelay = this.idleIntervalMs;
172
+ }
173
+ // Aggregate = server + all sampled sessions.
174
+ samples.push({
175
+ ts,
176
+ source: 'aggregate',
177
+ pid: 0,
178
+ cpuPercent: +aggCpu.toFixed(2),
179
+ rssBytes: aggRss,
180
+ heapUsedBytes: null,
181
+ });
182
+ this.ledger.recordSamples(samples);
183
+ // Bounded retention — prune off the same cadence (cheap single DELETE).
184
+ try {
185
+ this.ledger.pruneOlderThan(ts - this.retentionMs);
186
+ }
187
+ catch {
188
+ /* swallow */
189
+ }
190
+ }
191
+ catch (err) {
192
+ // @silent-fallback-ok: a sampling error NEVER crashes the poller — log once
193
+ // and keep going; the next tick retries. Observability must not break the
194
+ // observed path.
195
+ try {
196
+ this.onError(err);
197
+ }
198
+ catch { /* ignore */ }
199
+ }
200
+ finally {
201
+ this.running = false;
202
+ this.schedule(nextDelay);
203
+ }
204
+ }
205
+ /**
206
+ * CPU% for THIS process over the interval since the last tick: the
207
+ * (user+system) microseconds consumed divided by the wall-clock microseconds
208
+ * elapsed, ×100. One fully-busy core reads ~100. Returns 0 when there's no
209
+ * prior baseline yet (first tick) or the clock didn't advance.
210
+ */
211
+ computeOwnCpuPercent(nowMs) {
212
+ let cpu;
213
+ try {
214
+ cpu = this.cpuUsageFn();
215
+ }
216
+ catch {
217
+ // @silent-fallback-ok: a CPU reading we can't take degrades to 0% for this
218
+ // tick (read-only observability); it must never throw into the sample loop.
219
+ return 0;
220
+ }
221
+ const prev = this.lastCpu;
222
+ const prevAt = this.lastCpuAtMs;
223
+ this.lastCpu = cpu;
224
+ this.lastCpuAtMs = nowMs;
225
+ if (!prev || prevAt == null)
226
+ return 0;
227
+ const wallMs = nowMs - prevAt;
228
+ if (wallMs <= 0)
229
+ return 0;
230
+ const cpuMicros = cpu.user + cpu.system - (prev.user + prev.system);
231
+ const wallMicros = wallMs * 1000;
232
+ const pct = (cpuMicros / wallMicros) * 100;
233
+ return pct > 0 && Number.isFinite(pct) ? +pct.toFixed(2) : 0;
234
+ }
235
+ }
236
+ /**
237
+ * Batch-sample OS pids with ONE `ps` call. macOS + Linux both support
238
+ * `ps -o %cpu=,rss= -p <pid>[,<pid>...]`; the `=` suffix suppresses headers so
239
+ * the output is just rows of "<cpu> <rss>" aligned with `-p` order... except
240
+ * `ps` reorders by pid, so we ask for pid too and key the result map by pid.
241
+ * rss is reported in KiB → bytes. Dead pids are simply absent from the output
242
+ * (no error). Returns an empty map on any failure (fail-open).
243
+ */
244
+ function samplePidsViaPs(pids) {
245
+ return new Promise((resolve) => {
246
+ const out = new Map();
247
+ if (pids.length === 0) {
248
+ resolve(out);
249
+ return;
250
+ }
251
+ const pidList = pids.join(',');
252
+ execFile('ps', ['-o', 'pid=,%cpu=,rss=', '-p', pidList], { timeout: 5000, maxBuffer: 1024 * 1024 }, (err, stdout) => {
253
+ // `ps` exits non-zero when ALL pids are dead; that's not an error for us.
254
+ if (!stdout) {
255
+ resolve(out);
256
+ return;
257
+ }
258
+ for (const line of stdout.split('\n')) {
259
+ const m = line.trim().match(/^(\d+)\s+([\d.]+)\s+(\d+)$/);
260
+ if (!m)
261
+ continue;
262
+ const pid = Number(m[1]);
263
+ const cpuPercent = Number(m[2]);
264
+ const rssKib = Number(m[3]);
265
+ if (!Number.isFinite(pid))
266
+ continue;
267
+ out.set(pid, {
268
+ cpuPercent: Number.isFinite(cpuPercent) && cpuPercent > 0 ? cpuPercent : 0,
269
+ rssBytes: Number.isFinite(rssKib) && rssKib > 0 ? rssKib * 1024 : 0,
270
+ });
271
+ }
272
+ void err; // already tolerated
273
+ resolve(out);
274
+ });
275
+ });
276
+ }
277
+ //# sourceMappingURL=ResourceSampler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResourceSampler.js","sourceRoot":"","sources":["../../src/monitoring/ResourceSampler.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SessionWatchdog.d.ts","sourceRoot":"","sources":["../../src/monitoring/SessionWatchdog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SessionWatchdog.d.ts","sourceRoot":"","sources":["../../src/monitoring/SessionWatchdog.ts"],"names":[],"mappings":"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"}
@@ -22,6 +22,11 @@ import { evaluateThrottleSettle, RATE_LIMIT_SETTLED_CAPTURE_LINES, RATE_LIMIT_DE
22
22
  function shellExec(cmd, timeout = 5000) {
23
23
  return spawnSync('/bin/sh', ['-c', cmd], { encoding: 'utf-8', timeout }).stdout ?? '';
24
24
  }
25
+ import { createRequire } from 'node:module';
26
+ // ESM module: a bare CJS `require` is undefined and throws at runtime. Bind a
27
+ // real require via createRequire so the lazy load below is genuinely ESM-legal
28
+ // (mirrors NativeModuleHealer.ts).
29
+ const require = createRequire(import.meta.url);
25
30
  export var EscalationLevel;
26
31
  (function (EscalationLevel) {
27
32
  EscalationLevel[EscalationLevel["Monitoring"] = 0] = "Monitoring";