@askexenow/exe-os 0.9.286 → 0.9.287
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/deploy/stack-manifests/v0.9.json +1 -1
- package/dist/bin/stack-update.js +2 -2
- package/dist/bin/vps-health-gate.js +1 -1
- package/dist/chunk-ASL5PHCT.js +1934 -0
- package/dist/chunk-XLF5F55U.js +230 -0
- package/dist/hooks/manifest.json +1 -1
- package/dist/stack-update-45SNTDZ6.js +76 -0
- package/package.json +1 -1
- package/release-notes.json +43 -43
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
// src/bin/vps-health-gate.ts
|
|
2
|
+
import { spawnSync } from "child_process";
|
|
3
|
+
import { appendFileSync, existsSync, mkdirSync, readdirSync } from "fs";
|
|
4
|
+
import http from "http";
|
|
5
|
+
import path from "path";
|
|
6
|
+
var DEPLOY_LOG = "/opt/exe-stack/deploy-log.jsonl";
|
|
7
|
+
var BACKUP_DIR = "/opt/exe-stack/backups";
|
|
8
|
+
async function checkCRM() {
|
|
9
|
+
const start = Date.now();
|
|
10
|
+
try {
|
|
11
|
+
const status = await httpGet("http://localhost:3000/api");
|
|
12
|
+
return {
|
|
13
|
+
check: "crm",
|
|
14
|
+
status: status >= 200 && status < 400 ? "pass" : "fail",
|
|
15
|
+
message: status >= 200 && status < 400 ? `CRM healthy (HTTP ${status})` : `CRM unhealthy (HTTP ${status})`,
|
|
16
|
+
durationMs: Date.now() - start
|
|
17
|
+
};
|
|
18
|
+
} catch (err) {
|
|
19
|
+
return {
|
|
20
|
+
check: "crm",
|
|
21
|
+
status: "fail",
|
|
22
|
+
message: `CRM unreachable: ${err instanceof Error ? err.message : err}`,
|
|
23
|
+
durationMs: Date.now() - start
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
async function checkGateway() {
|
|
28
|
+
const start = Date.now();
|
|
29
|
+
try {
|
|
30
|
+
const status = await httpGet("http://localhost:3100/health");
|
|
31
|
+
return {
|
|
32
|
+
check: "gateway",
|
|
33
|
+
status: status >= 200 && status < 300 ? "pass" : "fail",
|
|
34
|
+
message: status >= 200 && status < 300 ? `Gateway healthy (HTTP ${status})` : `Gateway unhealthy (HTTP ${status})`,
|
|
35
|
+
durationMs: Date.now() - start
|
|
36
|
+
};
|
|
37
|
+
} catch (err) {
|
|
38
|
+
return {
|
|
39
|
+
check: "gateway",
|
|
40
|
+
status: "fail",
|
|
41
|
+
message: `Gateway unreachable: ${err instanceof Error ? err.message : err}`,
|
|
42
|
+
durationMs: Date.now() - start
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function checkPostgres() {
|
|
47
|
+
const start = Date.now();
|
|
48
|
+
const databaseUrl = process.env.DATABASE_URL || "postgres://exe@localhost:5432/exedb";
|
|
49
|
+
const result = spawnSync("psql", [databaseUrl, "-c", "SELECT 1"], {
|
|
50
|
+
encoding: "utf8",
|
|
51
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
52
|
+
timeout: 1e4
|
|
53
|
+
});
|
|
54
|
+
return {
|
|
55
|
+
check: "postgres",
|
|
56
|
+
status: result.status === 0 ? "pass" : "fail",
|
|
57
|
+
message: result.status === 0 ? "Postgres responding" : `Postgres failed: ${result.stderr?.trim() || `exit ${result.status}`}`,
|
|
58
|
+
durationMs: Date.now() - start
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function checkRawEvents() {
|
|
62
|
+
const start = Date.now();
|
|
63
|
+
const databaseUrl = process.env.DATABASE_URL || "postgres://exe@localhost:5432/exedb";
|
|
64
|
+
const result = spawnSync(
|
|
65
|
+
"psql",
|
|
66
|
+
[databaseUrl, "-t", "-c", "SELECT count(*) FROM raw.raw_events"],
|
|
67
|
+
{
|
|
68
|
+
encoding: "utf8",
|
|
69
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
70
|
+
timeout: 1e4
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
if (result.status !== 0) {
|
|
74
|
+
return {
|
|
75
|
+
check: "raw_events",
|
|
76
|
+
status: "fail",
|
|
77
|
+
message: `raw.raw_events query failed: ${result.stderr?.trim() || `exit ${result.status}`}`,
|
|
78
|
+
durationMs: Date.now() - start
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
const count = parseInt(result.stdout?.trim() || "0", 10);
|
|
82
|
+
return {
|
|
83
|
+
check: "raw_events",
|
|
84
|
+
status: count > 0 ? "pass" : "fail",
|
|
85
|
+
message: count > 0 ? `raw.raw_events has ${count} rows` : "raw.raw_events is empty",
|
|
86
|
+
durationMs: Date.now() - start
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async function checkGoTrue() {
|
|
90
|
+
const start = Date.now();
|
|
91
|
+
try {
|
|
92
|
+
const status = await httpGet("http://localhost:9999/health");
|
|
93
|
+
return {
|
|
94
|
+
check: "gotrue",
|
|
95
|
+
status: status >= 200 && status < 300 ? "pass" : "fail",
|
|
96
|
+
message: status >= 200 && status < 300 ? `GoTrue healthy (HTTP ${status})` : `GoTrue unhealthy (HTTP ${status})`,
|
|
97
|
+
durationMs: Date.now() - start
|
|
98
|
+
};
|
|
99
|
+
} catch (err) {
|
|
100
|
+
return {
|
|
101
|
+
check: "gotrue",
|
|
102
|
+
status: "fail",
|
|
103
|
+
message: `GoTrue unreachable: ${err instanceof Error ? err.message : err}`,
|
|
104
|
+
durationMs: Date.now() - start
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async function runHealthGate() {
|
|
109
|
+
console.log("[health-gate] Running post-deploy health checks...\n");
|
|
110
|
+
const results = [];
|
|
111
|
+
results.push(checkPostgres());
|
|
112
|
+
results.push(checkRawEvents());
|
|
113
|
+
results.push(await checkCRM());
|
|
114
|
+
results.push(await checkGateway());
|
|
115
|
+
results.push(await checkGoTrue());
|
|
116
|
+
const passed = results.every((r) => r.status === "pass");
|
|
117
|
+
for (const r of results) {
|
|
118
|
+
const icon = r.status === "pass" ? "\u2713" : "\u2717";
|
|
119
|
+
const color = r.status === "pass" ? "\x1B[32m" : "\x1B[31m";
|
|
120
|
+
console.log(` ${color}${icon}\x1B[0m ${r.check.padEnd(12)} ${r.message} (${r.durationMs}ms)`);
|
|
121
|
+
}
|
|
122
|
+
console.log("");
|
|
123
|
+
const result = {
|
|
124
|
+
passed,
|
|
125
|
+
results,
|
|
126
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
127
|
+
};
|
|
128
|
+
return result;
|
|
129
|
+
}
|
|
130
|
+
function logResult(result) {
|
|
131
|
+
mkdirSync(path.dirname(DEPLOY_LOG), { recursive: true });
|
|
132
|
+
const line = JSON.stringify({
|
|
133
|
+
...result,
|
|
134
|
+
type: "health_gate"
|
|
135
|
+
}) + "\n";
|
|
136
|
+
try {
|
|
137
|
+
appendFileSync(DEPLOY_LOG, line);
|
|
138
|
+
console.log(`[health-gate] Result logged to ${DEPLOY_LOG}`);
|
|
139
|
+
} catch (err) {
|
|
140
|
+
console.warn(`[health-gate] Failed to write deploy log: ${err instanceof Error ? err.message : err}`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
function restorePreDeployBackup() {
|
|
144
|
+
if (!existsSync(BACKUP_DIR)) return false;
|
|
145
|
+
const backups = readdirSync(BACKUP_DIR).filter((f) => f.startsWith("pg-pre-deploy-") && f.endsWith(".dump")).sort().reverse();
|
|
146
|
+
if (backups.length === 0) {
|
|
147
|
+
console.warn("[health-gate] No pre-deploy backup found to restore");
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
const latest = backups[0];
|
|
151
|
+
const filepath = path.join(BACKUP_DIR, latest);
|
|
152
|
+
const databaseUrl = process.env.DATABASE_URL || "postgres://exe@localhost:5432/exedb";
|
|
153
|
+
console.log(`[health-gate] Restoring pre-deploy backup: ${latest}`);
|
|
154
|
+
const result = spawnSync("pg_restore", ["-d", databaseUrl, "--clean", "--if-exists", filepath], {
|
|
155
|
+
encoding: "utf8",
|
|
156
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
157
|
+
timeout: 3e5
|
|
158
|
+
});
|
|
159
|
+
if (result.status !== 0) {
|
|
160
|
+
console.error(`[health-gate] pg_restore failed: ${result.stderr?.trim() || `exit ${result.status}`}`);
|
|
161
|
+
return false;
|
|
162
|
+
}
|
|
163
|
+
console.log("[health-gate] \u2713 Pre-deploy backup restored");
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
function httpGet(url) {
|
|
167
|
+
return new Promise((resolve, reject) => {
|
|
168
|
+
const req = http.request(url, { method: "GET", timeout: 1e4 }, (res) => {
|
|
169
|
+
res.resume();
|
|
170
|
+
resolve(res.statusCode ?? 0);
|
|
171
|
+
});
|
|
172
|
+
req.on("timeout", () => req.destroy(new Error("timeout")));
|
|
173
|
+
req.on("error", reject);
|
|
174
|
+
req.end();
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
async function main(args) {
|
|
178
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
179
|
+
console.log(`
|
|
180
|
+
exe-os vps-health-gate \u2014 Post-deploy health checks
|
|
181
|
+
|
|
182
|
+
Runs 5 checks: Postgres, raw_events, CRM, Gateway, GoTrue.
|
|
183
|
+
If any check fails, triggers rollback and exits with code 1.
|
|
184
|
+
|
|
185
|
+
Usage:
|
|
186
|
+
exe-os vps-health-gate Run health gate
|
|
187
|
+
exe-os vps-health-gate --check-only Run checks without rollback on failure
|
|
188
|
+
`);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const checkOnly = args.includes("--check-only");
|
|
192
|
+
const result = await runHealthGate();
|
|
193
|
+
logResult(result);
|
|
194
|
+
if (result.passed) {
|
|
195
|
+
console.log("[health-gate] \u2713 All checks passed \u2014 deploy is healthy");
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
const failed = result.results.filter((r) => r.status === "fail");
|
|
199
|
+
console.error(`[health-gate] \u2717 ${failed.length} check(s) failed`);
|
|
200
|
+
if (checkOnly) {
|
|
201
|
+
process.exitCode = 1;
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
console.log("[health-gate] Starting rollback...");
|
|
205
|
+
restorePreDeployBackup();
|
|
206
|
+
try {
|
|
207
|
+
const { rollbackStackUpdate, defaultStackPaths } = await import("./stack-update-45SNTDZ6.js");
|
|
208
|
+
const paths = defaultStackPaths();
|
|
209
|
+
await rollbackStackUpdate({
|
|
210
|
+
manifestRef: paths.manifestRef,
|
|
211
|
+
composeFile: paths.composeFile,
|
|
212
|
+
envFile: paths.envFile
|
|
213
|
+
});
|
|
214
|
+
console.log("[health-gate] \u2713 Stack rolled back to previous version");
|
|
215
|
+
} catch (err) {
|
|
216
|
+
console.error(`[health-gate] Stack rollback failed: ${err instanceof Error ? err.message : err}`);
|
|
217
|
+
}
|
|
218
|
+
process.exitCode = 1;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export {
|
|
222
|
+
checkCRM,
|
|
223
|
+
checkGateway,
|
|
224
|
+
checkPostgres,
|
|
225
|
+
checkRawEvents,
|
|
226
|
+
checkGoTrue,
|
|
227
|
+
runHealthGate,
|
|
228
|
+
logResult,
|
|
229
|
+
main
|
|
230
|
+
};
|
package/dist/hooks/manifest.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 1,
|
|
3
|
-
"generatedAt": "2026-06-18T07:
|
|
3
|
+
"generatedAt": "2026-06-18T07:04:35.545Z",
|
|
4
4
|
"hashes": {
|
|
5
5
|
"bug-report-worker.js": "16d6fab856fd34eeeb4406f0b63578abbab9b85a2c5b552918b2dc096bff45b2",
|
|
6
6
|
"codex-stop-task-finalizer.js": "2e1b30d86acf2359fe6e555e486ffc80c8b525ab43646c523e272b92d8cdaa93",
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProgressReporter,
|
|
3
|
+
assertBreakingChangesAllowed,
|
|
4
|
+
assertDeploymentScopeAllowed,
|
|
5
|
+
assertHostReadyForApply,
|
|
6
|
+
assertProductionDeployGate,
|
|
7
|
+
bootstrapStackHost,
|
|
8
|
+
buildDefaultServiceSelection,
|
|
9
|
+
canonicalizeStackManifest,
|
|
10
|
+
collectImageAvailabilityIssues,
|
|
11
|
+
collectProductionDeployGateIssues,
|
|
12
|
+
createStackUpdatePlan,
|
|
13
|
+
defaultStackPaths,
|
|
14
|
+
detectDanglingVolumes,
|
|
15
|
+
filterServicesBySelection,
|
|
16
|
+
findLatestBackupEnvFile,
|
|
17
|
+
hardenHost,
|
|
18
|
+
listAvailableVersions,
|
|
19
|
+
loadServiceSelection,
|
|
20
|
+
loadStackManifest,
|
|
21
|
+
pairMonitorAgent,
|
|
22
|
+
parseEnv,
|
|
23
|
+
parseStackManifest,
|
|
24
|
+
patchEnv,
|
|
25
|
+
printDanglingVolumes,
|
|
26
|
+
printVolumeCleanupResult,
|
|
27
|
+
readCurrentStackVersion,
|
|
28
|
+
removeDanglingVolumes,
|
|
29
|
+
rollbackStackUpdate,
|
|
30
|
+
runStackUpdate,
|
|
31
|
+
saveServiceSelection,
|
|
32
|
+
serviceSelectionPath,
|
|
33
|
+
verifyManifestImagesAvailable,
|
|
34
|
+
verifyReleaseHealth,
|
|
35
|
+
verifyStackManifestSignature
|
|
36
|
+
} from "./chunk-ASL5PHCT.js";
|
|
37
|
+
import "./chunk-YMKUXZIG.js";
|
|
38
|
+
import "./chunk-T3B5RK4H.js";
|
|
39
|
+
import "./chunk-LYH5HE24.js";
|
|
40
|
+
import "./chunk-MLKGABMK.js";
|
|
41
|
+
export {
|
|
42
|
+
ProgressReporter,
|
|
43
|
+
assertBreakingChangesAllowed,
|
|
44
|
+
assertDeploymentScopeAllowed,
|
|
45
|
+
assertHostReadyForApply,
|
|
46
|
+
assertProductionDeployGate,
|
|
47
|
+
bootstrapStackHost,
|
|
48
|
+
buildDefaultServiceSelection,
|
|
49
|
+
canonicalizeStackManifest,
|
|
50
|
+
collectImageAvailabilityIssues,
|
|
51
|
+
collectProductionDeployGateIssues,
|
|
52
|
+
createStackUpdatePlan,
|
|
53
|
+
defaultStackPaths,
|
|
54
|
+
detectDanglingVolumes,
|
|
55
|
+
filterServicesBySelection,
|
|
56
|
+
findLatestBackupEnvFile,
|
|
57
|
+
hardenHost,
|
|
58
|
+
listAvailableVersions,
|
|
59
|
+
loadServiceSelection,
|
|
60
|
+
loadStackManifest,
|
|
61
|
+
pairMonitorAgent,
|
|
62
|
+
parseEnv,
|
|
63
|
+
parseStackManifest,
|
|
64
|
+
patchEnv,
|
|
65
|
+
printDanglingVolumes,
|
|
66
|
+
printVolumeCleanupResult,
|
|
67
|
+
readCurrentStackVersion,
|
|
68
|
+
removeDanglingVolumes,
|
|
69
|
+
rollbackStackUpdate,
|
|
70
|
+
runStackUpdate,
|
|
71
|
+
saveServiceSelection,
|
|
72
|
+
serviceSelectionPath,
|
|
73
|
+
verifyManifestImagesAvailable,
|
|
74
|
+
verifyReleaseHealth,
|
|
75
|
+
verifyStackManifestSignature
|
|
76
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@askexenow/exe-os",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.287",
|
|
4
4
|
"description": "AI employee operating system — persistent memory, task management, and multi-agent coordination for Claude Code.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"type": "module",
|
package/release-notes.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"current": "0.9.
|
|
2
|
+
"current": "0.9.287",
|
|
3
3
|
"notes": {
|
|
4
|
-
"0.9.
|
|
5
|
-
"version": "0.9.
|
|
4
|
+
"0.9.287": {
|
|
5
|
+
"version": "0.9.287",
|
|
6
6
|
"date": "2026-06-18",
|
|
7
7
|
"features": [
|
|
8
8
|
"add image availability + platform verification to deploy gate",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"hot-path session summary — compress last checkpoint into ~200 tokens at boot (edaf4eb3) (#128)"
|
|
33
33
|
],
|
|
34
34
|
"fixes": [
|
|
35
|
+
"skip image-availability check for private registry + exe-erp v0.2.1",
|
|
35
36
|
"exe-erp v0.2.0-final8 with socketio.js + realtime/ baked in",
|
|
36
37
|
"erp-nginx backend IP .32 (not .28, taken by erp-queue)",
|
|
37
38
|
"unique frontend IPs — auth 10.43.0.35, erp-nginx 10.43.0.28 (no collisions)",
|
|
@@ -55,11 +56,11 @@
|
|
|
55
56
|
"CRM_SERVER_URL uses crm. subdomain + add EXE_CRM_ADMIN_EMAIL (bugs 8d20e779, 7debf355)",
|
|
56
57
|
"use update.askexe.com for exe-auth image in manifest 0.9.24 (bug 97f2d288)",
|
|
57
58
|
"ensure description field is never empty in feature request upstream payload (bug 0a8e16d0)",
|
|
58
|
-
"add WSL clip.exe detection to shipped tmux.conf (bug 3396fb26)"
|
|
59
|
-
"include node binary dir in exe-os-node shim PATH (bug 71adcb68)"
|
|
59
|
+
"add WSL clip.exe detection to shipped tmux.conf (bug 3396fb26)"
|
|
60
60
|
],
|
|
61
61
|
"security": [],
|
|
62
62
|
"other": [
|
|
63
|
+
"bump v0.9.287 — deploy gate auth fix + exe-erp v0.2.1",
|
|
63
64
|
"bump v0.9.286 — exe-erp final8 in manifest",
|
|
64
65
|
"add cross-service SSO + key rotation + daemon restart tests (35 tests)",
|
|
65
66
|
"45 tests for image validation, ${VAR:-default} resolution, platform checks",
|
|
@@ -83,14 +84,13 @@
|
|
|
83
84
|
"session lifecycle — 3-layer automatic state preservation",
|
|
84
85
|
"integrate session closeout, model registry, dreaming into platform procedures",
|
|
85
86
|
"route all memory benchmarks through the embed daemon",
|
|
86
|
-
"make daemon smoke gate CI-safe under load (#96)"
|
|
87
|
-
"release: stack 0.9.23 — exe-gateway v0.9.21 (WhatsApp pipeline fixes)"
|
|
87
|
+
"make daemon smoke gate CI-safe under load (#96)"
|
|
88
88
|
],
|
|
89
89
|
"migration_notes": []
|
|
90
90
|
},
|
|
91
|
-
"0.9.
|
|
92
|
-
"version": "0.9.
|
|
93
|
-
"date": "2026-06-
|
|
91
|
+
"0.9.286": {
|
|
92
|
+
"version": "0.9.286",
|
|
93
|
+
"date": "2026-06-18",
|
|
94
94
|
"features": [
|
|
95
95
|
"add image availability + platform verification to deploy gate",
|
|
96
96
|
"GoTrue JWT auth for MCP — exe-os login/logout/whoami",
|
|
@@ -119,6 +119,14 @@
|
|
|
119
119
|
"hot-path session summary — compress last checkpoint into ~200 tokens at boot (edaf4eb3) (#128)"
|
|
120
120
|
],
|
|
121
121
|
"fixes": [
|
|
122
|
+
"exe-erp v0.2.0-final8 with socketio.js + realtime/ baked in",
|
|
123
|
+
"erp-nginx backend IP .32 (not .28, taken by erp-queue)",
|
|
124
|
+
"unique frontend IPs — auth 10.43.0.35, erp-nginx 10.43.0.28 (no collisions)",
|
|
125
|
+
"frontend subnet 10.43.0.x (not 10.42.1.x) for erp-nginx + auth",
|
|
126
|
+
"erp-nginx port 8000→80 (nginx listens on 80, not 8000) + fix frontend subnet",
|
|
127
|
+
"ERP_PORT→ERP_API_PORT + port :80→:8000 + CRM version in test (bug 23ee1ab2)",
|
|
128
|
+
"lift rate limits — resolve merge conflicts",
|
|
129
|
+
"lift rate limits on bug/feature filing — every report matters",
|
|
122
130
|
"add otel-collector to official image allowlist — unblocks stack-update",
|
|
123
131
|
"correct exe-os + exe-auth digests for amd64 in manifest 0.9.24 (bug e0c3b3fb)",
|
|
124
132
|
"update exe-os daemon image to v0.9.281 in manifest 0.9.24",
|
|
@@ -135,18 +143,15 @@
|
|
|
135
143
|
"use update.askexe.com for exe-auth image in manifest 0.9.24 (bug 97f2d288)",
|
|
136
144
|
"ensure description field is never empty in feature request upstream payload (bug 0a8e16d0)",
|
|
137
145
|
"add WSL clip.exe detection to shipped tmux.conf (bug 3396fb26)",
|
|
138
|
-
"include node binary dir in exe-os-node shim PATH (bug 71adcb68)"
|
|
139
|
-
"add minimum daemon age guard to prevent crash-loop (bug 25faecf3)",
|
|
140
|
-
"digest-pin all 0.9.24 images + remove control-plane from customer manifest",
|
|
141
|
-
"resolve full UUID before upstream delivery — fixes update_bug/update_feature 400s (bug 31b1d2e3)",
|
|
142
|
-
"dual-key JWT verification — accept tokens signed by previous key (bug 2f5d6166)",
|
|
143
|
-
"add sync_meta to SQL guard allowlist — fixes cloud sync (bug 9fbbe145)",
|
|
144
|
-
"accept digest-only official images in deploy gate",
|
|
145
|
-
"prevent empty/duplicate company_procedure rows at the source",
|
|
146
|
-
"remove duplicate if-block causing TS build failure"
|
|
146
|
+
"include node binary dir in exe-os-node shim PATH (bug 71adcb68)"
|
|
147
147
|
],
|
|
148
148
|
"security": [],
|
|
149
149
|
"other": [
|
|
150
|
+
"bump v0.9.286 — exe-erp final8 in manifest",
|
|
151
|
+
"add cross-service SSO + key rotation + daemon restart tests (35 tests)",
|
|
152
|
+
"45 tests for image validation, ${VAR:-default} resolution, platform checks",
|
|
153
|
+
"add 16 activate fallback chain tests — covers bug 2f5d6166 failure modes",
|
|
154
|
+
"add 18 key rotation tests — dual-key verify, grace, fallback chain",
|
|
150
155
|
"bump v0.9.285 — deploy gate image verification",
|
|
151
156
|
"bump v0.9.284 — otel deploy gate fix",
|
|
152
157
|
"bump v0.9.283 — amd64 digest fix",
|
|
@@ -166,19 +171,15 @@
|
|
|
166
171
|
"integrate session closeout, model registry, dreaming into platform procedures",
|
|
167
172
|
"route all memory benchmarks through the embed daemon",
|
|
168
173
|
"make daemon smoke gate CI-safe under load (#96)",
|
|
169
|
-
"release: stack 0.9.23 — exe-gateway v0.9.21 (WhatsApp pipeline fixes)"
|
|
170
|
-
"expect Exe Embeddings v1 default modelFile",
|
|
171
|
-
"update release-notes.json",
|
|
172
|
-
"bump 0.9.275 — bundle stack 0.9.22 manifest for stack-update",
|
|
173
|
-
"release: stack 0.9.22 — exe-os v0.9.270, exe-crm v0.9.48, exe-gateway v0.9.18 (digest-pinned)",
|
|
174
|
-
"bump 0.9.273 — graph/send_whatsapp/phantom-notif fixes"
|
|
174
|
+
"release: stack 0.9.23 — exe-gateway v0.9.21 (WhatsApp pipeline fixes)"
|
|
175
175
|
],
|
|
176
176
|
"migration_notes": []
|
|
177
177
|
},
|
|
178
|
-
"0.9.
|
|
179
|
-
"version": "0.9.
|
|
178
|
+
"0.9.285": {
|
|
179
|
+
"version": "0.9.285",
|
|
180
180
|
"date": "2026-06-17",
|
|
181
181
|
"features": [
|
|
182
|
+
"add image availability + platform verification to deploy gate",
|
|
182
183
|
"GoTrue JWT auth for MCP — exe-os login/logout/whoami",
|
|
183
184
|
"admin backfill endpoint for api_key_hash — fixes all encrypted keys",
|
|
184
185
|
"implement startMonitor for Slack/Discord/Telegram/WhatsApp + SMTP via nodemailer",
|
|
@@ -202,8 +203,7 @@
|
|
|
202
203
|
"emotional baselines per agent role (dbfbe67f) (#131)",
|
|
203
204
|
"split exe-os into server (~200MB) and worker (~1GB) images (#130)",
|
|
204
205
|
"out-of-process socket watchdog (c3b287cc) (#129)",
|
|
205
|
-
"hot-path session summary — compress last checkpoint into ~200 tokens at boot (edaf4eb3) (#128)"
|
|
206
|
-
"cloud-synced cross-device reminders via Cloudflare Worker KV (a4195632) (#127)"
|
|
206
|
+
"hot-path session summary — compress last checkpoint into ~200 tokens at boot (edaf4eb3) (#128)"
|
|
207
207
|
],
|
|
208
208
|
"fixes": [
|
|
209
209
|
"add otel-collector to official image allowlist — unblocks stack-update",
|
|
@@ -234,6 +234,7 @@
|
|
|
234
234
|
],
|
|
235
235
|
"security": [],
|
|
236
236
|
"other": [
|
|
237
|
+
"bump v0.9.285 — deploy gate image verification",
|
|
237
238
|
"bump v0.9.284 — otel deploy gate fix",
|
|
238
239
|
"bump v0.9.283 — amd64 digest fix",
|
|
239
240
|
"bump v0.9.282 — daemon image v0.9.281 in manifest",
|
|
@@ -257,13 +258,12 @@
|
|
|
257
258
|
"update release-notes.json",
|
|
258
259
|
"bump 0.9.275 — bundle stack 0.9.22 manifest for stack-update",
|
|
259
260
|
"release: stack 0.9.22 — exe-os v0.9.270, exe-crm v0.9.48, exe-gateway v0.9.18 (digest-pinned)",
|
|
260
|
-
"bump 0.9.273 — graph/send_whatsapp/phantom-notif fixes"
|
|
261
|
-
"Add daemon smoke gate"
|
|
261
|
+
"bump 0.9.273 — graph/send_whatsapp/phantom-notif fixes"
|
|
262
262
|
],
|
|
263
263
|
"migration_notes": []
|
|
264
264
|
},
|
|
265
|
-
"0.9.
|
|
266
|
-
"version": "0.9.
|
|
265
|
+
"0.9.284": {
|
|
266
|
+
"version": "0.9.284",
|
|
267
267
|
"date": "2026-06-17",
|
|
268
268
|
"features": [
|
|
269
269
|
"GoTrue JWT auth for MCP — exe-os login/logout/whoami",
|
|
@@ -293,6 +293,7 @@
|
|
|
293
293
|
"cloud-synced cross-device reminders via Cloudflare Worker KV (a4195632) (#127)"
|
|
294
294
|
],
|
|
295
295
|
"fixes": [
|
|
296
|
+
"add otel-collector to official image allowlist — unblocks stack-update",
|
|
296
297
|
"correct exe-os + exe-auth digests for amd64 in manifest 0.9.24 (bug e0c3b3fb)",
|
|
297
298
|
"update exe-os daemon image to v0.9.281 in manifest 0.9.24",
|
|
298
299
|
"mcp_ping reports alive when running inside daemon process (bug b5fb9404)",
|
|
@@ -316,11 +317,11 @@
|
|
|
316
317
|
"add sync_meta to SQL guard allowlist — fixes cloud sync (bug 9fbbe145)",
|
|
317
318
|
"accept digest-only official images in deploy gate",
|
|
318
319
|
"prevent empty/duplicate company_procedure rows at the source",
|
|
319
|
-
"remove duplicate if-block causing TS build failure"
|
|
320
|
-
"watchdog self-heal + restart-intent propagation (belt & suspenders)"
|
|
320
|
+
"remove duplicate if-block causing TS build failure"
|
|
321
321
|
],
|
|
322
322
|
"security": [],
|
|
323
323
|
"other": [
|
|
324
|
+
"bump v0.9.284 — otel deploy gate fix",
|
|
324
325
|
"bump v0.9.283 — amd64 digest fix",
|
|
325
326
|
"bump v0.9.282 — daemon image v0.9.281 in manifest",
|
|
326
327
|
"prepare v0.9.281 — 50 bugs fixed, stack 0.9.24 fully deployable",
|
|
@@ -344,13 +345,12 @@
|
|
|
344
345
|
"bump 0.9.275 — bundle stack 0.9.22 manifest for stack-update",
|
|
345
346
|
"release: stack 0.9.22 — exe-os v0.9.270, exe-crm v0.9.48, exe-gateway v0.9.18 (digest-pinned)",
|
|
346
347
|
"bump 0.9.273 — graph/send_whatsapp/phantom-notif fixes",
|
|
347
|
-
"Add daemon smoke gate"
|
|
348
|
-
"Publish Claude Fable model support as 0.9.272"
|
|
348
|
+
"Add daemon smoke gate"
|
|
349
349
|
],
|
|
350
350
|
"migration_notes": []
|
|
351
351
|
},
|
|
352
|
-
"0.9.
|
|
353
|
-
"version": "0.9.
|
|
352
|
+
"0.9.283": {
|
|
353
|
+
"version": "0.9.283",
|
|
354
354
|
"date": "2026-06-17",
|
|
355
355
|
"features": [
|
|
356
356
|
"GoTrue JWT auth for MCP — exe-os login/logout/whoami",
|
|
@@ -380,6 +380,7 @@
|
|
|
380
380
|
"cloud-synced cross-device reminders via Cloudflare Worker KV (a4195632) (#127)"
|
|
381
381
|
],
|
|
382
382
|
"fixes": [
|
|
383
|
+
"correct exe-os + exe-auth digests for amd64 in manifest 0.9.24 (bug e0c3b3fb)",
|
|
383
384
|
"update exe-os daemon image to v0.9.281 in manifest 0.9.24",
|
|
384
385
|
"mcp_ping reports alive when running inside daemon process (bug b5fb9404)",
|
|
385
386
|
"add exe-erp-nginx for static assets + remove direct gunicorn port (bug 6776edf0)",
|
|
@@ -403,11 +404,11 @@
|
|
|
403
404
|
"accept digest-only official images in deploy gate",
|
|
404
405
|
"prevent empty/duplicate company_procedure rows at the source",
|
|
405
406
|
"remove duplicate if-block causing TS build failure",
|
|
406
|
-
"watchdog self-heal + restart-intent propagation (belt & suspenders)"
|
|
407
|
-
"skip junk/empty company_procedure rows that bloated prompts to 1.6MB"
|
|
407
|
+
"watchdog self-heal + restart-intent propagation (belt & suspenders)"
|
|
408
408
|
],
|
|
409
409
|
"security": [],
|
|
410
410
|
"other": [
|
|
411
|
+
"bump v0.9.283 — amd64 digest fix",
|
|
411
412
|
"bump v0.9.282 — daemon image v0.9.281 in manifest",
|
|
412
413
|
"prepare v0.9.281 — 50 bugs fixed, stack 0.9.24 fully deployable",
|
|
413
414
|
"bump v0.9.280 — GoTrue MCP auth, support fixes",
|
|
@@ -431,8 +432,7 @@
|
|
|
431
432
|
"release: stack 0.9.22 — exe-os v0.9.270, exe-crm v0.9.48, exe-gateway v0.9.18 (digest-pinned)",
|
|
432
433
|
"bump 0.9.273 — graph/send_whatsapp/phantom-notif fixes",
|
|
433
434
|
"Add daemon smoke gate",
|
|
434
|
-
"Publish Claude Fable model support as 0.9.272"
|
|
435
|
-
"Add Claude Fable model whitelist"
|
|
435
|
+
"Publish Claude Fable model support as 0.9.272"
|
|
436
436
|
],
|
|
437
437
|
"migration_notes": []
|
|
438
438
|
}
|