instar 1.3.626 → 1.3.627
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/dist/core/PostUpdateMigrator.d.ts +1 -0
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +42 -0
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +2 -1
- package/dist/scaffold/templates.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +28 -20
- package/src/scaffold/templates.ts +2 -1
- package/src/templates/scripts/load-assess.sh +113 -0
- package/upgrades/1.3.627.md +23 -0
- package/upgrades/side-effects/robust-load-assessment-fleet.md +74 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAgG/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2E/F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2B1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,EAC5B,WAAW,GAAE,OAAe,GAC3B,MAAM,
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAgG/D;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CA2E/F;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAiBvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CA2B1D;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,EAC5B,WAAW,GAAE,OAAe,GAC3B,MAAM,CA4hDR;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,OAAO,EACpB,WAAW,GAAE,OAAe,GAC3B,MAAM,CA2TR"}
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
// existing-agent migration there) so the two can never drift. Imported as a runtime
|
|
14
14
|
// function call inside generateClaudeMd — no module-init cycle (PostUpdateMigrator
|
|
15
15
|
// never imports templates).
|
|
16
|
-
import { PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
|
|
16
|
+
import { PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION, MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
|
|
17
17
|
/**
|
|
18
18
|
* Generate AGENT.md — the agent's identity file.
|
|
19
19
|
*/
|
|
@@ -807,6 +807,7 @@ I declare owner/blockedOn at commitment creation; a later state change goes thro
|
|
|
807
807
|
- **The autonomous balancer surface** — \`GET /credentials/rebalancer\` (the use-it-or-lose-it drainer is Increment B; this surfaces the env-token applicability gate's verdict + WHY re-pointing would refuse, when enabled).
|
|
808
808
|
- **When to use** (PROACTIVE — these are the triggers): "flip my default account to X" / "make X my default" → \`POST /credentials/set-default\`; "which account is this session/slot on?" / "where does ~/.claude point?" → \`GET /credentials/locations\` (read it, don't infer from \`claude auth status\` — that reads a metadata file, not the live credential). Single-account agents are a no-op. (Spec: \`docs/specs/live-credential-repointing-rebalancer.md\`.)
|
|
809
809
|
${PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION(port)}
|
|
810
|
+
${MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION()}
|
|
810
811
|
**Per-Feature LLM Metrics & LLM Activity (Observable Intelligence)** — Audit what each of your LLM-driven gates/sentinels actually does: WHICH provider + model ran it, how often it ACTED (fired) vs found nothing (noop), how often it was skipped to save rate limits (shed), cost, and latency. This is the *Observable Intelligence* standard — no autonomous AI action the system takes is allowed to be invisible. Read-only observability — it never gates anything.
|
|
811
812
|
- Check: \`curl -H "Authorization: Bearer $AUTH" "http://localhost:${port}/metrics/features?sinceHours=24"\`
|
|
812
813
|
- Returns \`{ totals, features: [{ feature, frameworks, models, byModel, calls, realCalls, tokensIn, tokensOut, tokensCached, fired, noop, shed, fireRate, p50LatencyMs, p95LatencyMs, ... }] }\` — one row per system (e.g. MessagingToneGate, MessageSentinel). \`frameworks\`/\`models\` = which provider(s) actually served the call; \`fireRate\` = how often it acts; \`shed\` = skipped by the rate-limit guard. Filter with \`?feature=<name>\`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,oFAAoF;AACpF,qFAAqF;AACrF,oFAAoF;AACpF,mFAAmF;AACnF,4BAA4B;AAC5B,OAAO,EAAE,4CAA4C,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-06-
|
|
5
|
-
"instarVersion": "1.3.
|
|
6
|
-
"entryCount":
|
|
4
|
+
"generatedAt": "2026-06-19T20:44:32.422Z",
|
|
5
|
+
"instarVersion": "1.3.627",
|
|
6
|
+
"entryCount": 202,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
9
9
|
"id": "hook:session-start",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"domain": "identity",
|
|
12
12
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
13
13
|
"installedPath": ".instar/hooks/instar/session-start.sh",
|
|
14
|
-
"contentHash": "
|
|
14
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
15
15
|
"since": "2025-01-01"
|
|
16
16
|
},
|
|
17
17
|
"hook:dangerous-command-guard": {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"domain": "safety",
|
|
21
21
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
22
22
|
"installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
|
|
23
|
-
"contentHash": "
|
|
23
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
24
24
|
"since": "2025-01-01"
|
|
25
25
|
},
|
|
26
26
|
"hook:grounding-before-messaging": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"domain": "safety",
|
|
30
30
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
31
31
|
"installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
|
|
32
|
-
"contentHash": "
|
|
32
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
33
33
|
"since": "2025-01-01"
|
|
34
34
|
},
|
|
35
35
|
"hook:compaction-recovery": {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"domain": "identity",
|
|
39
39
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
40
40
|
"installedPath": ".instar/hooks/instar/compaction-recovery.sh",
|
|
41
|
-
"contentHash": "
|
|
41
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
42
42
|
"since": "2025-01-01"
|
|
43
43
|
},
|
|
44
44
|
"hook:external-operation-gate": {
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"domain": "safety",
|
|
48
48
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
49
49
|
"installedPath": ".instar/hooks/instar/external-operation-gate.js",
|
|
50
|
-
"contentHash": "
|
|
50
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
51
51
|
"since": "2025-01-01"
|
|
52
52
|
},
|
|
53
53
|
"hook:deferral-detector": {
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"domain": "safety",
|
|
57
57
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
58
58
|
"installedPath": ".instar/hooks/instar/deferral-detector.js",
|
|
59
|
-
"contentHash": "
|
|
59
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
60
60
|
"since": "2025-01-01"
|
|
61
61
|
},
|
|
62
62
|
"hook:self-stop-guard": {
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"domain": "coherence",
|
|
66
66
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
67
67
|
"installedPath": ".instar/hooks/instar/self-stop-guard.js",
|
|
68
|
-
"contentHash": "
|
|
68
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
69
69
|
"since": "2025-01-01"
|
|
70
70
|
},
|
|
71
71
|
"hook:post-action-reflection": {
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"domain": "evolution",
|
|
75
75
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
76
76
|
"installedPath": ".instar/hooks/instar/post-action-reflection.js",
|
|
77
|
-
"contentHash": "
|
|
77
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
78
78
|
"since": "2025-01-01"
|
|
79
79
|
},
|
|
80
80
|
"hook:external-communication-guard": {
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"domain": "safety",
|
|
84
84
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
85
85
|
"installedPath": ".instar/hooks/instar/external-communication-guard.js",
|
|
86
|
-
"contentHash": "
|
|
86
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
87
87
|
"since": "2025-01-01"
|
|
88
88
|
},
|
|
89
89
|
"hook:scope-coherence-collector": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"domain": "coherence",
|
|
93
93
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
94
94
|
"installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
|
|
95
|
-
"contentHash": "
|
|
95
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
96
96
|
"since": "2025-01-01"
|
|
97
97
|
},
|
|
98
98
|
"hook:scope-coherence-checkpoint": {
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"domain": "coherence",
|
|
102
102
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
103
103
|
"installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
|
|
104
|
-
"contentHash": "
|
|
104
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
105
105
|
"since": "2025-01-01"
|
|
106
106
|
},
|
|
107
107
|
"hook:free-text-guard": {
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
"domain": "safety",
|
|
111
111
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
112
112
|
"installedPath": ".instar/hooks/instar/free-text-guard.sh",
|
|
113
|
-
"contentHash": "
|
|
113
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
114
114
|
"since": "2025-01-01"
|
|
115
115
|
},
|
|
116
116
|
"hook:claim-intercept": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"domain": "coherence",
|
|
120
120
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
121
121
|
"installedPath": ".instar/hooks/instar/claim-intercept.js",
|
|
122
|
-
"contentHash": "
|
|
122
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
123
123
|
"since": "2025-01-01"
|
|
124
124
|
},
|
|
125
125
|
"hook:claim-intercept-response": {
|
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
"domain": "coherence",
|
|
129
129
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
130
130
|
"installedPath": ".instar/hooks/instar/claim-intercept-response.js",
|
|
131
|
-
"contentHash": "
|
|
131
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
132
132
|
"since": "2025-01-01"
|
|
133
133
|
},
|
|
134
134
|
"hook:stop-gate-router": {
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
"domain": "safety",
|
|
138
138
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
139
139
|
"installedPath": ".instar/hooks/instar/stop-gate-router.js",
|
|
140
|
-
"contentHash": "
|
|
140
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
141
141
|
"since": "2025-01-01"
|
|
142
142
|
},
|
|
143
143
|
"hook:auto-approve-permissions": {
|
|
@@ -146,7 +146,7 @@
|
|
|
146
146
|
"domain": "safety",
|
|
147
147
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
148
148
|
"installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
|
|
149
|
-
"contentHash": "
|
|
149
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
150
150
|
"since": "2025-01-01"
|
|
151
151
|
},
|
|
152
152
|
"job:health-check": {
|
|
@@ -1189,6 +1189,14 @@
|
|
|
1189
1189
|
"contentHash": "c258707dafb41518f376ffbab4ea3c5a824d6ab7dc9b1df5f8b8a2f7f99fbaee",
|
|
1190
1190
|
"since": "2025-01-01"
|
|
1191
1191
|
},
|
|
1192
|
+
"template:load-assess.sh": {
|
|
1193
|
+
"id": "template:load-assess.sh",
|
|
1194
|
+
"type": "template",
|
|
1195
|
+
"domain": "operations",
|
|
1196
|
+
"sourcePath": "src/templates/scripts/load-assess.sh",
|
|
1197
|
+
"contentHash": "0d8c335b167a7e46099b8636692849a48d4c0ca5722853a453d1a963427c9b88",
|
|
1198
|
+
"since": "2025-01-01"
|
|
1199
|
+
},
|
|
1192
1200
|
"template:secret-drop-retrieve.mjs": {
|
|
1193
1201
|
"id": "template:secret-drop-retrieve.mjs",
|
|
1194
1202
|
"type": "template",
|
|
@@ -1554,7 +1562,7 @@
|
|
|
1554
1562
|
"type": "subsystem",
|
|
1555
1563
|
"domain": "updates",
|
|
1556
1564
|
"sourcePath": "src/core/PostUpdateMigrator.ts",
|
|
1557
|
-
"contentHash": "
|
|
1565
|
+
"contentHash": "922bf0f5c403a51a5eaa0dd73a276219f3be302aa1cd122cdd1d0f279a019a12",
|
|
1558
1566
|
"since": "2025-01-01"
|
|
1559
1567
|
},
|
|
1560
1568
|
"subsystem:scheduler": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// existing-agent migration there) so the two can never drift. Imported as a runtime
|
|
15
15
|
// function call inside generateClaudeMd — no module-init cycle (PostUpdateMigrator
|
|
16
16
|
// never imports templates).
|
|
17
|
-
import { PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
|
|
17
|
+
import { PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION, MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION } from '../core/PostUpdateMigrator.js';
|
|
18
18
|
|
|
19
19
|
export interface AgentIdentity {
|
|
20
20
|
name: string;
|
|
@@ -828,6 +828,7 @@ I declare owner/blockedOn at commitment creation; a later state change goes thro
|
|
|
828
828
|
- **The autonomous balancer surface** — \`GET /credentials/rebalancer\` (the use-it-or-lose-it drainer is Increment B; this surfaces the env-token applicability gate's verdict + WHY re-pointing would refuse, when enabled).
|
|
829
829
|
- **When to use** (PROACTIVE — these are the triggers): "flip my default account to X" / "make X my default" → \`POST /credentials/set-default\`; "which account is this session/slot on?" / "where does ~/.claude point?" → \`GET /credentials/locations\` (read it, don't infer from \`claude auth status\` — that reads a metadata file, not the live credential). Single-account agents are a no-op. (Spec: \`docs/specs/live-credential-repointing-rebalancer.md\`.)
|
|
830
830
|
${PLAYWRIGHT_PROFILE_REGISTRY_CLAUDEMD_SECTION(port)}
|
|
831
|
+
${MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION()}
|
|
831
832
|
**Per-Feature LLM Metrics & LLM Activity (Observable Intelligence)** — Audit what each of your LLM-driven gates/sentinels actually does: WHICH provider + model ran it, how often it ACTED (fired) vs found nothing (noop), how often it was skipped to save rate limits (shed), cost, and latency. This is the *Observable Intelligence* standard — no autonomous AI action the system takes is allowed to be invisible. Read-only observability — it never gates anything.
|
|
832
833
|
- Check: \`curl -H "Authorization: Bearer $AUTH" "http://localhost:${port}/metrics/features?sinceHours=24"\`
|
|
833
834
|
- Returns \`{ totals, features: [{ feature, frameworks, models, byModel, calls, realCalls, tokensIn, tokensOut, tokensCached, fired, noop, shed, fireRate, p50LatencyMs, p95LatencyMs, ... }] }\` — one row per system (e.g. MessagingToneGate, MessageSentinel). \`frameworks\`/\`models\` = which provider(s) actually served the call; \`fireRate\` = how often it acts; \`shed\` = skipped by the rate-limit guard. Filter with \`?feature=<name>\`.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# load-assess.sh — the DURABLE go-to method for evaluating machine load.
|
|
3
|
+
#
|
|
4
|
+
# WHY THIS EXISTS: `uptime` 1-minute load average is the WRONG signal for "can I
|
|
5
|
+
# do work / is the machine genuinely loaded." It is (a) spike-susceptible (the
|
|
6
|
+
# 1-min figure swings wildly) and (b) on macOS INFLATED by threads stuck in
|
|
7
|
+
# uninterruptible disk I/O (e.g. Spotlight/mds reindex after a cold boot) — so a
|
|
8
|
+
# high load average can coexist with a mostly-idle CPU. On 2026-06-19 a load avg
|
|
9
|
+
# of ~40 was quoted as "heavy load" when the CPU was actually 62% IDLE and the
|
|
10
|
+
# load was Spotlight reindexing, not the agent. Never repeat that.
|
|
11
|
+
#
|
|
12
|
+
# THIS reports the RIGHT signals: real CPU idle% (sampled, not instantaneous),
|
|
13
|
+
# instar's time-windowed ResourceLedger (agent-attributed CPU avg/peak over the
|
|
14
|
+
# last hour), per-core load normalization, and WHAT is consuming CPU (so you can
|
|
15
|
+
# tell "my work" from external/transient like Spotlight). Then it emits a verdict.
|
|
16
|
+
#
|
|
17
|
+
# SCOPE HONESTY: the verdict is a CPU-CAPACITY signal. It does NOT assess
|
|
18
|
+
# memory/swap, thermal throttling, or disk-I/O saturation — OK means "CPU has
|
|
19
|
+
# headroom," not "everything is fine." Memory/pressure is covered separately by
|
|
20
|
+
# the ResourceLedger / reaper-pressure surfaces.
|
|
21
|
+
#
|
|
22
|
+
# Usage: load-assess.sh (human-readable verdict)
|
|
23
|
+
# load-assess.sh --json (machine-readable; human-diagnostic only,
|
|
24
|
+
# unversioned — a programmatic consumer must
|
|
25
|
+
# add a schemaVersion first, not assume shape)
|
|
26
|
+
set -uo pipefail
|
|
27
|
+
cd "$(dirname "$0")/../.." 2>/dev/null || true # agent home (.instar/scripts -> home)
|
|
28
|
+
|
|
29
|
+
JSON=0; [ "${1:-}" = "--json" ] && JSON=1
|
|
30
|
+
OS=$(uname -s 2>/dev/null || echo unknown)
|
|
31
|
+
|
|
32
|
+
# --- cores ---
|
|
33
|
+
if [ "$OS" = "Darwin" ]; then CORES=$(sysctl -n hw.ncpu 2>/dev/null || echo 0)
|
|
34
|
+
else CORES=$(nproc 2>/dev/null || grep -c ^processor /proc/cpuinfo 2>/dev/null || echo 0); fi
|
|
35
|
+
|
|
36
|
+
# --- real CPU idle%: sampled (NOT a single instantaneous read) ---
|
|
37
|
+
IDLE=""
|
|
38
|
+
if [ "$OS" = "Darwin" ]; then
|
|
39
|
+
# macOS: top -l 2, SECOND sample is the real one (first is bogus)
|
|
40
|
+
CPU_LINE=$(top -l 2 -n 0 -s 1 2>/dev/null | grep "CPU usage" | tail -1)
|
|
41
|
+
IDLE=$(echo "$CPU_LINE" | sed -n 's/.*[, ]\([0-9.]*\)% idle.*/\1/p')
|
|
42
|
+
elif [ -r /proc/stat ]; then
|
|
43
|
+
# Linux: TWO-SAMPLE /proc/stat delta. A single read CANNOT compute idle%.
|
|
44
|
+
read_stat() { awk '/^cpu /{idle=$5+$6; tot=0; for(i=2;i<=NF;i++)tot+=$i; print idle, tot}' /proc/stat; }
|
|
45
|
+
S1=$(read_stat); sleep 1; S2=$(read_stat)
|
|
46
|
+
IDLE=$(awk -v a="$S1" -v b="$S2" 'BEGIN{
|
|
47
|
+
split(a,x," "); split(b,y," ");
|
|
48
|
+
di=y[1]-x[1]; dt=y[2]-x[2];
|
|
49
|
+
if(dt>0) printf "%.1f", 100*di/dt; else print "";
|
|
50
|
+
}')
|
|
51
|
+
fi
|
|
52
|
+
[ -z "$IDLE" ] && IDLE="" # empty => CPU read unavailable (e.g. unknown OS / no top)
|
|
53
|
+
# Test-only seam: force the sampled idle% so the verdict-threshold boundaries can be
|
|
54
|
+
# exercised deterministically (the real CPU read is environment-dependent). Read-only,
|
|
55
|
+
# affects only the printed verdict; never set in production.
|
|
56
|
+
[ -n "${LOAD_ASSESS_FORCE_IDLE:-}" ] && IDLE="$LOAD_ASSESS_FORCE_IDLE"
|
|
57
|
+
if [ -n "$IDLE" ]; then BUSY=$(awk -v i="$IDLE" 'BEGIN{printf "%.1f", 100-i}'); else BUSY=""; fi
|
|
58
|
+
|
|
59
|
+
# --- load averages (CONTEXT ONLY — never the basis of the verdict) ---
|
|
60
|
+
LOADS=$(uptime 2>/dev/null | sed -n 's/.*load average[s]*: *//p')
|
|
61
|
+
L1=$(echo "$LOADS" | awk -F'[ ,]+' '{print $1}')
|
|
62
|
+
L5=$(echo "$LOADS" | awk -F'[ ,]+' '{print $2}')
|
|
63
|
+
LOAD_PER_CORE=$(awk -v l="${L5:-0}" -v c="${CORES:-0}" 'BEGIN{if(c+0>0)printf "%.2f", l/c; else print "?"}')
|
|
64
|
+
|
|
65
|
+
# --- instar ResourceLedger: time-windowed agent-attributed CPU (the durable signal) ---
|
|
66
|
+
LEDGER="unavailable"
|
|
67
|
+
AUTH=$(node .instar/scripts/secret-get.mjs authToken 2>/dev/null || echo "")
|
|
68
|
+
PORT=$(node -pe "require('./.instar/config.json').port" 2>/dev/null || echo 4042)
|
|
69
|
+
AGENT_ID="${INSTAR_AGENT_ID:-$(node -pe "require('./.instar/config.json').projectName" 2>/dev/null || echo "")}"
|
|
70
|
+
if [ -n "$AUTH" ]; then
|
|
71
|
+
LEDGER=$(curl -s -m 8 -H "Authorization: Bearer $AUTH" -H "X-Instar-AgentId: ${AGENT_ID}" "http://localhost:${PORT}/resources/summary?sinceHours=1" 2>/dev/null \
|
|
72
|
+
| node -e "let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{try{const j=JSON.parse(d);const a=(j.sources||[]).find(s=>s.source==='aggregate')||{};console.log('avg='+(a.avgCpuPercent??'?')+' peak='+(a.peakCpuPercent??'?')+' current='+(a.currentCpuPercent??'?')+' samples='+(j.sampleCount??'?'))}catch(e){console.log('unavailable')}})" 2>/dev/null || echo "unavailable")
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# --- top CPU consumers + classify my-work vs external ---
|
|
76
|
+
TOP=$(ps -Ao pcpu,comm -r 2>/dev/null | sed -n '2,4p')
|
|
77
|
+
TOP1=$(echo "$TOP" | head -1 | awk '{print $2}')
|
|
78
|
+
EXTERNAL="unknown"
|
|
79
|
+
case "$TOP1" in
|
|
80
|
+
*mds*|*mdworker*|*Spotlight*|*WindowServer*|*backupd*|*photoanalysisd*|*mediaanalysisd*) EXTERNAL="external-transient (macOS: $(basename "$TOP1" 2>/dev/null))";;
|
|
81
|
+
*instar*|*node*|*claude*|*tmux*|*python*) EXTERNAL="agent-work ($(basename "$TOP1" 2>/dev/null))";;
|
|
82
|
+
"") EXTERNAL="unknown";;
|
|
83
|
+
*) EXTERNAL="other ($(basename "$TOP1" 2>/dev/null))";;
|
|
84
|
+
esac
|
|
85
|
+
|
|
86
|
+
# --- VERDICT (based on real idle%, NOT load average) ---
|
|
87
|
+
awk_lt() { awk -v a="$1" -v b="$2" 'BEGIN{exit !(a+0<b+0)}'; }
|
|
88
|
+
if [ -z "$IDLE" ]; then
|
|
89
|
+
VERDICT="UNKNOWN"; REASON="CPU idle% unavailable on this platform; rely on the agent CPU ledger + load context"
|
|
90
|
+
elif awk_lt "$IDLE" 12; then VERDICT="SATURATED"; REASON="CPU genuinely saturated (idle <12%)";
|
|
91
|
+
elif awk_lt "$IDLE" 30; then VERDICT="ELEVATED"; REASON="CPU busy but not saturated";
|
|
92
|
+
else VERDICT="OK"; REASON="CPU mostly idle"; fi
|
|
93
|
+
|
|
94
|
+
if [ "$JSON" = "1" ]; then
|
|
95
|
+
printf '{"verdict":"%s","reason":"%s","cpuIdlePercent":%s,"cpuBusyPercent":%s,"cores":%s,"loadAvg1":"%s","loadAvg5":"%s","loadPerCore":"%s","ledger":"%s","topConsumer":"%s","topClass":"%s","scope":"cpu-capacity-only","os":"%s"}\n' \
|
|
96
|
+
"$VERDICT" "$REASON" "${IDLE:-null}" "${BUSY:-null}" "${CORES:-0}" "${L1:-}" "${L5:-}" "$LOAD_PER_CORE" "$LEDGER" "${TOP1:-}" "$EXTERNAL" "$OS"
|
|
97
|
+
else
|
|
98
|
+
echo "=== MACHINE LOAD ASSESSMENT ==="
|
|
99
|
+
echo "VERDICT: $VERDICT — $REASON"
|
|
100
|
+
echo " (scope: CPU capacity only — does NOT assess memory/swap/thermal/disk-IO)"
|
|
101
|
+
echo ""
|
|
102
|
+
echo "Real CPU: ${BUSY:-?}% busy / ${IDLE:-?}% idle (sampled, the primary signal)"
|
|
103
|
+
echo "Cores: ${CORES:-?} logical"
|
|
104
|
+
echo "Agent CPU (1h): $LEDGER (instar ResourceLedger, time-windowed)"
|
|
105
|
+
echo "Top consumer: ${TOP1:-?} → $EXTERNAL"
|
|
106
|
+
echo "Load avg (ctx): 1m=${L1:-?} 5m=${L5:-?} (per-core ${LOAD_PER_CORE}) ← context only; spike-prone + I/O-inflated, NOT the verdict"
|
|
107
|
+
echo ""
|
|
108
|
+
echo "Top 3 CPU:"; echo "$TOP" | sed 's/^/ /'
|
|
109
|
+
echo ""
|
|
110
|
+
echo "Interpretation: trust the real CPU idle% + the time-windowed agent CPU."
|
|
111
|
+
echo "A high load average with high idle% = external/transient (e.g. Spotlight), NOT agent pressure."
|
|
112
|
+
fi
|
|
113
|
+
exit 0
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
Added `load-assess.sh` — a robust, durable, go-to method for an agent to evaluate machine load — and shipped it fleet-wide. It reports the RIGHT signals (real CPU idle% sampled, instar's time-windowed ResourceLedger agent-CPU, per-core load, and what's actually consuming CPU) and emits a verdict (OK / ELEVATED / SATURATED), instead of the spike-prone, macOS-Spotlight-I/O-inflated `uptime` 1-minute load average. A static "use load-assess.sh, never trust the load average" reminder is wired into the session-start hook ABOVE its compact-`exec` delegate, so it survives compaction (not just session start), and a Machine Load Assessment section is added to the CLAUDE.md template (generate + migrate) so every agent knows the capability exists.
|
|
9
|
+
|
|
10
|
+
## What to Tell Your User
|
|
11
|
+
|
|
12
|
+
Your agent now judges whether the machine is genuinely busy using real CPU idle% (and its own recent CPU use), not the misleading 1-minute load average — so it won't mistake a quiet-but-disk-indexing machine for an overloaded one and unnecessarily hold off on work. It's read-only: it measures and reports, changing nothing.
|
|
13
|
+
|
|
14
|
+
## Summary of New Capabilities
|
|
15
|
+
|
|
16
|
+
- `.instar/scripts/load-assess.sh` (`--json` to parse) — go-to machine-load assessment with a verdict; CPU-capacity-scoped (does not assess memory/thermal). Installed on every agent on update.
|
|
17
|
+
|
|
18
|
+
## Evidence
|
|
19
|
+
|
|
20
|
+
- 14 new tests pass: verdict thresholds (both sides of each boundary via a `LOAD_ASSESS_FORCE_IDLE` test seam), `--json` contract, fail-soft when the ResourceLedger is unreachable, the compaction-survival property (`blockIdx < execIdx` in `getSessionStartHook()`), `migrateScripts` install (always-overwrite, executable), and `migrateClaudeMd` idempotent append.
|
|
21
|
+
- 568 existing PostUpdateMigrator + scaffold tests still green (no regression).
|
|
22
|
+
- Independent second-pass review (touches compaction) concurred after live simulation — bash builtin `echo` writes directly to fd 1, so the awareness block's stdout reaches the captured output before the process-replacing `exec` on the compact path.
|
|
23
|
+
- Spec converged through `/spec-converge` (2 rounds, `cross-model-review: codex-cli:gpt-5.5`); the review caught two critical bugs in the first draft (editing a dead template file; a mechanically-false compaction guarantee) before any code was written.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Side-Effects Review — Robust Load Assessment (fleet-wide + compaction-surviving)
|
|
2
|
+
|
|
3
|
+
**Version / slug:** `robust-load-assessment-fleet`
|
|
4
|
+
**Date:** 2026-06-19
|
|
5
|
+
**Author:** echo
|
|
6
|
+
**Second-pass reviewer:** echo-spawned reviewer subagent (required — touches compaction)
|
|
7
|
+
|
|
8
|
+
## Summary of the change
|
|
9
|
+
|
|
10
|
+
Ships a read-only machine-load diagnostic (`load-assess.sh`) to every agent as a script template, wires a static "use load-assess.sh / never trust the uptime load average" awareness block into the in-code session-start hook ABOVE its compact-`exec` delegate (so it survives compaction), and adds an Agent-Awareness CLAUDE.md section (generate + migrate). Born from a 2026-06-19 incident where the agent misread the spike-prone, Spotlight-I/O-inflated 1-minute load average as "heavy load" while the CPU was ~60% idle. Three source files + two test files; 14 new tests, 568 existing PostUpdateMigrator/scaffold tests still green.
|
|
11
|
+
|
|
12
|
+
## Decision-point inventory
|
|
13
|
+
|
|
14
|
+
- `load-assess.sh` verdict (OK/ELEVATED/SATURATED) — **add** — produces a SIGNAL (a load verdict printed to stdout); holds **zero** blocking authority. Nothing consumes it as a gate.
|
|
15
|
+
- session-start hook output — **modify** (additive) — adds a static doc block; no conditional logic, no decision.
|
|
16
|
+
- `migrateScripts` / `migrateClaudeMd` — **add** (install + append) — idempotent, content-sniffed; no decision surface.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## 1. Over-block
|
|
21
|
+
No block/allow surface — over-block not applicable. The script reads CPU/ledger and prints; the hook emits a static string. Nothing is rejected or gated.
|
|
22
|
+
|
|
23
|
+
## 2. Under-block
|
|
24
|
+
No block/allow surface — under-block not applicable. The change adds no enforcement, so there is no failure mode to "miss." (The script's verdict is advisory: a human/agent reading "OK" still makes the call. Scope honesty is built in — the verdict explicitly states it is CPU-capacity only, not a universal health oracle, so a reader does not over-trust an OK on a memory/thermal-pressured box.)
|
|
25
|
+
|
|
26
|
+
## 3. Level-of-abstraction fit
|
|
27
|
+
Right layer. A diagnostic script lives in `.instar/scripts/` alongside `secret-get.mjs`/`emit-session-clock.sh` (the established sibling pattern); the awareness lives in the session-start hook (the existing always-fires-on-lifecycle surface) and the CLAUDE.md template (the canonical agent-awareness surface). No smarter gate should own this — there is no gate; it is read-only observability feeding the agent's own judgment. The time-windowed signal it surfaces (ResourceLedger) is consumed, not duplicated.
|
|
28
|
+
|
|
29
|
+
## 4. Signal vs authority compliance
|
|
30
|
+
Compliant (`docs/signal-vs-authority.md`). `load-assess.sh` is a pure **detector/signal** — it computes a load verdict and prints it, with no power to block, delay, or rewrite anything. It does not add brittle logic with blocking authority; it adds a read-only signal a smart authority (the agent) consumes. The hook block and CLAUDE.md section are documentation, not decision points.
|
|
31
|
+
|
|
32
|
+
## 5. Interactions
|
|
33
|
+
- The hook block is placed ABOVE the `exec compaction-recovery.sh` branch so it is emitted on every event (startup/resume/clear/compact); it does not shadow or get shadowed by the recovery delegation (verified by a test asserting `blockIdx < execIdx`). It adds a few lines of static stdout to a hook that already emits many — no latency (no network), and the block precedes no `exit N` (the hook ends on an `echo`, which exits 0), so it cannot change the exit code. (Compaction-survival rests on bash builtin `echo` writing directly to fd 1 with no userspace stdio buffer for the subsequent `exec` to discard — verified empirically by the second-pass reviewer across tty/pipe/file-redirect.)
|
|
34
|
+
- `migrateScripts` adds a sibling install next to `secret-get.mjs`; independent try/catch, cannot affect the other script installs.
|
|
35
|
+
- `migrateClaudeMd` appends a content-sniffed section (`!includes('Machine Load Assessment')`) — idempotent, does not duplicate on re-run (tested), does not edit other sections in place.
|
|
36
|
+
- The CLAUDE.md section text is single-sourced (`MACHINE_LOAD_ASSESSMENT_CLAUDEMD_SECTION()`) and used by BOTH generate (new agents) and migrate (existing) — they cannot drift (tested).
|
|
37
|
+
|
|
38
|
+
## 6. External surfaces
|
|
39
|
+
- The script reads the existing `GET /resources/summary` endpoint (read-only; no new surface) and degrades to local-only if it is unreachable (fail-soft, tested). No new external API.
|
|
40
|
+
- `--json` is documented human-diagnostic-only and unversioned — no system consumes it; a future programmatic consumer must add a `schemaVersion` first (stated in the script + spec).
|
|
41
|
+
- The hook output is agent-internal stdout, not visible to other agents/users/systems.
|
|
42
|
+
- No timing/conversation-state dependence: the script samples CPU on demand; the hook block is static. A test-only `LOAD_ASSESS_FORCE_IDLE` env seam exists (read-only, affects only the printed verdict for boundary testing; never set in production).
|
|
43
|
+
|
|
44
|
+
## 7. Multi-machine posture (Cross-Machine Coherence)
|
|
45
|
+
- `load-assess.sh` — **machine-local BY DESIGN**: load is a property of the machine the script runs on; there is nothing to replicate. Cross-machine load reads are already served separately by `/guards?scope=pool` and `/resources/summary`.
|
|
46
|
+
- The hook block and CLAUDE.md section — **machine-local static template content**, installed identically on every machine by each machine's own migration; no replication needed, no strand-on-transfer risk (no durable per-topic state), no generated URLs.
|
|
47
|
+
|
|
48
|
+
## 8. Rollback cost
|
|
49
|
+
Low. Revert the PR (3 source files). The change is additive and idempotent: reverting stops shipping the script template + hook block + CLAUDE.md section to future migrations. Agents that already migrated keep a harmless read-only `load-assess.sh` on disk (no cleanup required; it gates nothing). No data migration, no agent-state repair. A hot-fix release is sufficient if needed.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Second-pass review (required — touches compaction)
|
|
54
|
+
|
|
55
|
+
**Reviewer:** echo-spawned independent reviewer subagent. **Verdict: Concur with the review.**
|
|
56
|
+
|
|
57
|
+
The reviewer independently audited the 4 additive blocks, ran the 14 tests, AND ran live simulations rather than trusting the framing:
|
|
58
|
+
1. **Compaction-survival — TRUE (verified by execution):** simulated the hook with stdout to a tty, a pipe, and a file redirect with the compact `exec` actually firing — the MACHINE LOAD block appeared before the delegate's output in every case. Robust because bash builtin `echo` writes via `write(2)` directly to fd 1 (no userspace stdio buffer for `exec` to discard); bytes are in the kernel before `exec` runs. The non-executable-recovery fallback also behaves correctly (exec skipped, block still emitted, hook continues).
|
|
59
|
+
2. **Timeout/exit code — no risk:** static echoes, zero network; precedes no `exit N`.
|
|
60
|
+
3. **Script safety — sound:** `set -uo pipefail` with NO `set -e`; ran under stripped env / empty-IDLE / faked unknown-OS — all exit 0 with a clean verdict (UNKNOWN + null JSON on genuine no-CPU-read, never a crash). All `set -u`-sensitive vars assigned before use; verdict chain exhaustive (VERDICT+REASON on every branch); `bash -n` clean.
|
|
61
|
+
4. **Test `blockIdx < execIdx`** pins the real property; combined with both-boundary script tests + the empirically-confirmed flush-survives-exec behavior, the guarantee is covered.
|
|
62
|
+
5. **Packaging — sound:** `loadRelayTemplate('load-assess.sh')` resolves via `src/templates/scripts/`, which IS in package.json `files` (ships to npm) — the same proven mechanism as `secret-get.mjs`. Content-sniff anchor `'Machine Load Assessment'` is unique (no cross-section collision); idempotency confirmed count==1 after repeated runs.
|
|
63
|
+
|
|
64
|
+
No concerns raised.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## CI-conformance follow-up (post-open, #1231)
|
|
69
|
+
|
|
70
|
+
CI shard 4/4 surfaced two required-conformance gaps (caught by the full suite, not my local subset run):
|
|
71
|
+
- `load-assess.sh`'s localhost API call to `/resources/summary` lacked the `X-Instar-AgentId` header that `template-agent-id-header.test.ts` requires of every Bearer call in a template. Added (AGENT_ID derived from `INSTAR_AGENT_ID`/config.json projectName, same as session-start.sh). No behavior change — the header is identification only; the call already fail-softs.
|
|
72
|
+
- The `Machine Load Assessment` migrateClaudeMd section was not registered in `feature-delivery-completeness.test.ts`'s `legacyMigratorSections` tracking list. Added (observe-only, ships ON, no framework-shadow marker → legacy migrator list, not featureSections). No runtime change — a test-registry entry.
|
|
73
|
+
|
|
74
|
+
Both are conformance fixes to the same change; the design + second-pass review above stand unchanged.
|