@askexenow/exe-os 0.9.393 → 0.9.394

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.
@@ -5042,11 +5042,277 @@
5042
5042
  "composeSha256": "220b251375f372107e8d8d54a9c3e4ceab1f57aae80f4babf2933c3887532263",
5043
5043
  "composeOverrideSha256": "af295ca2f75b85788416e4df51cab86d8b773bf4cafe6cf6df9c7c26b9a42d6d"
5044
5044
  }
5045
+ },
5046
+ "0.9.54": {
5047
+ "version": "0.9.54",
5048
+ "releasedAt": "2026-09-23T22:31:53.000Z",
5049
+ "npmVersion": "0.9.393",
5050
+ "notes": "CRM DEMO routing canary from the applied Dashboard 0.9.53 baseline. Update only CRM web and worker to v0.9.67 with signed DEMO workspace routing; preserve Dashboard v0.9.392, Auth v0.6.10, and all other pins. Operator DEMO bootstrap remains a separate scoped step after image acceptance.",
5051
+ "services": {
5052
+ "exe-db": {
5053
+ "image": "update.askexe.com/askexe/pgvector:0.8.0-pg16@sha256:a132765ec351c65111b5b675928a3a0515a466a40f97277329db8b8209ad8bc9",
5054
+ "env": "EXE_DB_IMAGE",
5055
+ "composeService": "exe-db",
5056
+ "required": true,
5057
+ "category": "core",
5058
+ "description": "Postgres (pgvector) — digest-pinned (bug 32d6e02f; was tag-only in 0.9.25, regressed from 0.9.24)"
5059
+ },
5060
+ "exe-os": {
5061
+ "image": "update.askexe.com/askexe/exe-os:v0.9.382@sha256:266a59a482865eab9f79497999acb33c1fe1868ec54ea5cd1ce971c492f11bd6",
5062
+ "env": "EXE_OS_IMAGE_TAG",
5063
+ "composeService": "exe-os",
5064
+ "healthUrl": "http://127.0.0.1:8765/health",
5065
+ "required": true,
5066
+ "category": "core",
5067
+ "description": "exe-os daemon + MCP server"
5068
+ },
5069
+ "crm": {
5070
+ "image": "update.askexe.com/askexe/exe-crm:v0.9.67@sha256:56452b7df4361e157e4d727dd71c8ed3f1cffd4b345bbddecf651609c0de9b48",
5071
+ "env": "CRM_IMAGE_TAG",
5072
+ "composeService": "exe-crm",
5073
+ "healthUrl": "http://127.0.0.1:3000/healthz",
5074
+ "category": "app",
5075
+ "gitSha": "9127619259b7ba2ff8963fbf302827e3cf518ece",
5076
+ "description": "Central authentication and recovery with server-validated shared sessions for CRM web and worker."
5077
+ },
5078
+ "wiki": {
5079
+ "image": "update.askexe.com/askexe/exe-wiki:v0.9.37@sha256:8fa22e77c0742fbb690f7b4c8431a186692a20ebd335fb141782df4289dc337f",
5080
+ "env": "WIKI_IMAGE_TAG",
5081
+ "composeService": "exe-wiki",
5082
+ "healthUrl": "http://127.0.0.1:3001/api/ping",
5083
+ "category": "app",
5084
+ "description": "Central hosted authentication and recovery with server-validated shared sessions, membership enforcement, and no product-local credential form.",
5085
+ "gitSha": "713a4370c2b641b8f8b07fd1e7390afa79a9c931"
5086
+ },
5087
+ "gateway": {
5088
+ "image": "update.askexe.com/askexe/exe-gateway:v2026.08.07-c15f093-stamped@sha256:1bc11a2a0ad1f3929d59d2685696f22a72042b9fca9c75e15c02dc7d3c640105",
5089
+ "env": "GATEWAY_IMAGE_TAG",
5090
+ "composeService": "exe-gateway",
5091
+ "healthUrl": "http://127.0.0.1:3100/health",
5092
+ "category": "app",
5093
+ "description": "WhatsApp/messaging gateway — provenance-stamped rebuild of main (outbound message persistence fix); pinned by digest, dated immutable tag.",
5094
+ "gitSha": "c15f093a0f59730bd5c2c73791ff77059dfa7cc1"
5095
+ },
5096
+ "monitorAgent": {
5097
+ "image": "update.askexe.com/askexe/exe-monitor-agent:v2026.08.09-10660eb4-stamped@sha256:29fbd445f79484df04f000603e4ff445e76f0380f86d687a0033e3a0ef7d1b7a",
5098
+ "env": "MONITOR_AGENT_IMAGE_TAG",
5099
+ "composeService": "exe-monitor-agent",
5100
+ "category": "monitoring",
5101
+ "gitSha": "10660eb4abdeffbcba2aad13549aa58e208ac7a3"
5102
+ },
5103
+ "monitorHub": {
5104
+ "image": "update.askexe.com/askexe/exe-monitor-hub:v2026.08.09-10660eb4-stamped@sha256:c9a9218c2713b8dffea7e1cf8c0702a614657d311a7a4e821c6a543bab29bb97",
5105
+ "env": "MONITOR_HUB_IMAGE_TAG",
5106
+ "composeService": "exe-monitor-hub",
5107
+ "healthUrl": "http://127.0.0.1:8090/api/health",
5108
+ "category": "monitoring",
5109
+ "gitSha": "10660eb4abdeffbcba2aad13549aa58e208ac7a3"
5110
+ },
5111
+ "auth": {
5112
+ "image": "update.askexe.com/askexe/exe-auth:v0.6.10@sha256:0260349962d087cd3c33fed1d362029416e82ae9cc60abca7969beac2cb8639f",
5113
+ "env": "AUTH_IMAGE_TAG",
5114
+ "composeService": "exe-auth",
5115
+ "healthUrl": "http://127.0.0.1:3300/",
5116
+ "category": "auth",
5117
+ "description": "GoTrue SSO and privileged license authority bridge; stateless auth proxy.",
5118
+ "gitSha": "29fe7015d90b80c94db3a1e3904852b934071711"
5119
+ },
5120
+ "erp": {
5121
+ "image": "update.askexe.com/askexe/exe-erp:v0.3.17@sha256:ef61b59d94c04189fe2975045a3816d2fecc8efe3027e0ee8c17d0fa2efdbc3b",
5122
+ "env": "ERP_IMAGE_TAG",
5123
+ "composeService": "exe-erp",
5124
+ "healthUrl": "http://127.0.0.1:8069/api/method/ping",
5125
+ "healthHost": "localhost",
5126
+ "required": false,
5127
+ "category": "app",
5128
+ "description": "Enterprise Resource Planning with central hosted authentication and subject-bound organization admission.",
5129
+ "gitSha": "a769ec5e0ae53bc5944715845869715ebbffd63a"
5130
+ },
5131
+ "gotrue": {
5132
+ "image": "update.askexe.com/askexe/gotrue:v2.172.1@sha256:b0dd7aa28dd1f9a8bd31f136c8b912661f701d9b863171e5843cb08f18f49de4",
5133
+ "composeService": "gotrue",
5134
+ "healthUrl": "http://127.0.0.1:9999/health",
5135
+ "category": "infra"
5136
+ },
5137
+ "redis": {
5138
+ "image": "update.askexe.com/askexe/redis:7.4-alpine@sha256:6ab0b6e7381779332f97b8ca76193e45b0756f38d4c0dcda72dbb3c32061ab99",
5139
+ "composeService": "redis",
5140
+ "category": "infra"
5141
+ },
5142
+ "clickhouse": {
5143
+ "image": "update.askexe.com/askexe/clickhouse-server:24.8.4.13-alpine@sha256:88a45f9e328549b2579256c46ee38e5c0e25ae58303d9eb6d9c7ed8d6d2bbf3c",
5144
+ "composeService": "clickhouse",
5145
+ "category": "infra"
5146
+ },
5147
+ "cloudflared": {
5148
+ "image": "update.askexe.com/askexe/cloudflared:2026-07@sha256:ba461b8aa9c042156dbd39c38657fe7431bafa063220eab8d5330a523863da9f",
5149
+ "composeService": "cloudflared",
5150
+ "category": "infra"
5151
+ },
5152
+ "exe-sso-edge": {
5153
+ "image": "update.askexe.com/askexe/nginx:alpine@sha256:20316569d8f81a160065d7d2a5eeffc7ca97d79022462ee255fd23fa103a6b5c",
5154
+ "composeService": "exe-sso-edge",
5155
+ "category": "infra"
5156
+ },
5157
+ "exe-otel-collector": {
5158
+ "image": "update.askexe.com/askexe/otel-collector-contrib:0.114.0@sha256:37fa87091cfaaec7234a27e4e395a40c31c2bfaea97a349a4afef6d9e9681197",
5159
+ "composeService": "exe-otel-collector",
5160
+ "category": "infra"
5161
+ },
5162
+ "dashboard": {
5163
+ "image": "update.askexe.com/askexe/exe-dashboard:v0.9.392@sha256:d151441554c00e216084bd1caf2278e8c41fde188c039e0f167e158a511cbeec",
5164
+ "env": "DASHBOARD_IMAGE_TAG",
5165
+ "composeService": "exe-dashboard",
5166
+ "healthUrl": "http://127.0.0.1:3301/health",
5167
+ "required": false,
5168
+ "category": "optional",
5169
+ "description": "Customer dashboard at dashboard.<apex> — credits, usage, API keys, billing",
5170
+ "gitSha": "e11b25ad567389440da8ed5e566a9c59bce24123"
5171
+ }
5172
+ },
5173
+ "rolloutStage": "canary",
5174
+ "config": {
5175
+ "composeSha256": "220b251375f372107e8d8d54a9c3e4ceab1f57aae80f4babf2933c3887532263",
5176
+ "composeOverrideSha256": "af295ca2f75b85788416e4df51cab86d8b773bf4cafe6cf6df9c7c26b9a42d6d"
5177
+ }
5178
+ },
5179
+ "0.9.55": {
5180
+ "version": "0.9.55",
5181
+ "releasedAt": "2026-09-23T23:14:06.000Z",
5182
+ "npmVersion": "0.9.394",
5183
+ "notes": "CRM DEMO routing canary superseding unapplied stack 0.9.54. The scoped updater now validates, restarts, witnesses, and rolls back CRM web and worker together under the one signed CRM_IMAGE_TAG. From the applied Dashboard 0.9.53 baseline, update only CRM to v0.9.67; preserve Dashboard v0.9.392, Auth v0.6.10, and every other image pin. Operator DEMO bootstrap remains separate after image acceptance.",
5184
+ "services": {
5185
+ "exe-db": {
5186
+ "image": "update.askexe.com/askexe/pgvector:0.8.0-pg16@sha256:a132765ec351c65111b5b675928a3a0515a466a40f97277329db8b8209ad8bc9",
5187
+ "env": "EXE_DB_IMAGE",
5188
+ "composeService": "exe-db",
5189
+ "required": true,
5190
+ "category": "core",
5191
+ "description": "Postgres (pgvector) — digest-pinned (bug 32d6e02f; was tag-only in 0.9.25, regressed from 0.9.24)"
5192
+ },
5193
+ "exe-os": {
5194
+ "image": "update.askexe.com/askexe/exe-os:v0.9.382@sha256:266a59a482865eab9f79497999acb33c1fe1868ec54ea5cd1ce971c492f11bd6",
5195
+ "env": "EXE_OS_IMAGE_TAG",
5196
+ "composeService": "exe-os",
5197
+ "healthUrl": "http://127.0.0.1:8765/health",
5198
+ "required": true,
5199
+ "category": "core",
5200
+ "description": "exe-os daemon + MCP server"
5201
+ },
5202
+ "crm": {
5203
+ "image": "update.askexe.com/askexe/exe-crm:v0.9.67@sha256:56452b7df4361e157e4d727dd71c8ed3f1cffd4b345bbddecf651609c0de9b48",
5204
+ "env": "CRM_IMAGE_TAG",
5205
+ "composeService": "exe-crm",
5206
+ "healthUrl": "http://127.0.0.1:3000/healthz",
5207
+ "category": "app",
5208
+ "gitSha": "9127619259b7ba2ff8963fbf302827e3cf518ece",
5209
+ "description": "Central authentication and recovery with server-validated shared sessions for CRM web and worker."
5210
+ },
5211
+ "wiki": {
5212
+ "image": "update.askexe.com/askexe/exe-wiki:v0.9.37@sha256:8fa22e77c0742fbb690f7b4c8431a186692a20ebd335fb141782df4289dc337f",
5213
+ "env": "WIKI_IMAGE_TAG",
5214
+ "composeService": "exe-wiki",
5215
+ "healthUrl": "http://127.0.0.1:3001/api/ping",
5216
+ "category": "app",
5217
+ "description": "Central hosted authentication and recovery with server-validated shared sessions, membership enforcement, and no product-local credential form.",
5218
+ "gitSha": "713a4370c2b641b8f8b07fd1e7390afa79a9c931"
5219
+ },
5220
+ "gateway": {
5221
+ "image": "update.askexe.com/askexe/exe-gateway:v2026.08.07-c15f093-stamped@sha256:1bc11a2a0ad1f3929d59d2685696f22a72042b9fca9c75e15c02dc7d3c640105",
5222
+ "env": "GATEWAY_IMAGE_TAG",
5223
+ "composeService": "exe-gateway",
5224
+ "healthUrl": "http://127.0.0.1:3100/health",
5225
+ "category": "app",
5226
+ "description": "WhatsApp/messaging gateway — provenance-stamped rebuild of main (outbound message persistence fix); pinned by digest, dated immutable tag.",
5227
+ "gitSha": "c15f093a0f59730bd5c2c73791ff77059dfa7cc1"
5228
+ },
5229
+ "monitorAgent": {
5230
+ "image": "update.askexe.com/askexe/exe-monitor-agent:v2026.08.09-10660eb4-stamped@sha256:29fbd445f79484df04f000603e4ff445e76f0380f86d687a0033e3a0ef7d1b7a",
5231
+ "env": "MONITOR_AGENT_IMAGE_TAG",
5232
+ "composeService": "exe-monitor-agent",
5233
+ "category": "monitoring",
5234
+ "gitSha": "10660eb4abdeffbcba2aad13549aa58e208ac7a3"
5235
+ },
5236
+ "monitorHub": {
5237
+ "image": "update.askexe.com/askexe/exe-monitor-hub:v2026.08.09-10660eb4-stamped@sha256:c9a9218c2713b8dffea7e1cf8c0702a614657d311a7a4e821c6a543bab29bb97",
5238
+ "env": "MONITOR_HUB_IMAGE_TAG",
5239
+ "composeService": "exe-monitor-hub",
5240
+ "healthUrl": "http://127.0.0.1:8090/api/health",
5241
+ "category": "monitoring",
5242
+ "gitSha": "10660eb4abdeffbcba2aad13549aa58e208ac7a3"
5243
+ },
5244
+ "auth": {
5245
+ "image": "update.askexe.com/askexe/exe-auth:v0.6.10@sha256:0260349962d087cd3c33fed1d362029416e82ae9cc60abca7969beac2cb8639f",
5246
+ "env": "AUTH_IMAGE_TAG",
5247
+ "composeService": "exe-auth",
5248
+ "healthUrl": "http://127.0.0.1:3300/",
5249
+ "category": "auth",
5250
+ "description": "GoTrue SSO and privileged license authority bridge; stateless auth proxy.",
5251
+ "gitSha": "29fe7015d90b80c94db3a1e3904852b934071711"
5252
+ },
5253
+ "erp": {
5254
+ "image": "update.askexe.com/askexe/exe-erp:v0.3.17@sha256:ef61b59d94c04189fe2975045a3816d2fecc8efe3027e0ee8c17d0fa2efdbc3b",
5255
+ "env": "ERP_IMAGE_TAG",
5256
+ "composeService": "exe-erp",
5257
+ "healthUrl": "http://127.0.0.1:8069/api/method/ping",
5258
+ "healthHost": "localhost",
5259
+ "required": false,
5260
+ "category": "app",
5261
+ "description": "Enterprise Resource Planning with central hosted authentication and subject-bound organization admission.",
5262
+ "gitSha": "a769ec5e0ae53bc5944715845869715ebbffd63a"
5263
+ },
5264
+ "gotrue": {
5265
+ "image": "update.askexe.com/askexe/gotrue:v2.172.1@sha256:b0dd7aa28dd1f9a8bd31f136c8b912661f701d9b863171e5843cb08f18f49de4",
5266
+ "composeService": "gotrue",
5267
+ "healthUrl": "http://127.0.0.1:9999/health",
5268
+ "category": "infra"
5269
+ },
5270
+ "redis": {
5271
+ "image": "update.askexe.com/askexe/redis:7.4-alpine@sha256:6ab0b6e7381779332f97b8ca76193e45b0756f38d4c0dcda72dbb3c32061ab99",
5272
+ "composeService": "redis",
5273
+ "category": "infra"
5274
+ },
5275
+ "clickhouse": {
5276
+ "image": "update.askexe.com/askexe/clickhouse-server:24.8.4.13-alpine@sha256:88a45f9e328549b2579256c46ee38e5c0e25ae58303d9eb6d9c7ed8d6d2bbf3c",
5277
+ "composeService": "clickhouse",
5278
+ "category": "infra"
5279
+ },
5280
+ "cloudflared": {
5281
+ "image": "update.askexe.com/askexe/cloudflared:2026-07@sha256:ba461b8aa9c042156dbd39c38657fe7431bafa063220eab8d5330a523863da9f",
5282
+ "composeService": "cloudflared",
5283
+ "category": "infra"
5284
+ },
5285
+ "exe-sso-edge": {
5286
+ "image": "update.askexe.com/askexe/nginx:alpine@sha256:20316569d8f81a160065d7d2a5eeffc7ca97d79022462ee255fd23fa103a6b5c",
5287
+ "composeService": "exe-sso-edge",
5288
+ "category": "infra"
5289
+ },
5290
+ "exe-otel-collector": {
5291
+ "image": "update.askexe.com/askexe/otel-collector-contrib:0.114.0@sha256:37fa87091cfaaec7234a27e4e395a40c31c2bfaea97a349a4afef6d9e9681197",
5292
+ "composeService": "exe-otel-collector",
5293
+ "category": "infra"
5294
+ },
5295
+ "dashboard": {
5296
+ "image": "update.askexe.com/askexe/exe-dashboard:v0.9.392@sha256:d151441554c00e216084bd1caf2278e8c41fde188c039e0f167e158a511cbeec",
5297
+ "env": "DASHBOARD_IMAGE_TAG",
5298
+ "composeService": "exe-dashboard",
5299
+ "healthUrl": "http://127.0.0.1:3301/health",
5300
+ "required": false,
5301
+ "category": "optional",
5302
+ "description": "Customer dashboard at dashboard.<apex> — credits, usage, API keys, billing",
5303
+ "gitSha": "e11b25ad567389440da8ed5e566a9c59bce24123"
5304
+ }
5305
+ },
5306
+ "rolloutStage": "canary",
5307
+ "config": {
5308
+ "composeSha256": "220b251375f372107e8d8d54a9c3e4ceab1f57aae80f4babf2933c3887532263",
5309
+ "composeOverrideSha256": "af295ca2f75b85788416e4df51cab86d8b773bf4cafe6cf6df9c7c26b9a42d6d"
5310
+ }
5045
5311
  }
5046
5312
  },
5047
5313
  "signature": {
5048
5314
  "keyId": "exe-stack-1",
5049
5315
  "alg": "ed25519",
5050
- "signature": "sr79I2vY2ZVjMGGV/aGJp5i3sT3+nZX0urNqH7jw10Zu1yZNZa62y1973V6b2N5DKNwjE7aZHlQn5aF6nouBDg=="
5316
+ "signature": "BTPhDNOLpsQWb4XWYhc4B76lw+lAa0+t6RP1wC9B5D/9NNvkFcRTPrrf56YxL2bjBgx1IMWaBi4eM5Fbv2WEDA=="
5051
5317
  }
5052
5318
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "verified_at": "2026-09-23T22:15:04.008Z",
4
- "manifest_sha256": "c3c456977d8ec9e709146a39b984af444449c4bc1716922aa8323e33f06bdfa9",
5
- "package_version": "0.9.393"
3
+ "verified_at": "2026-09-23T23:35:24.863Z",
4
+ "manifest_sha256": "6448e6d55002816a5c2c682844a5a0d84f5f006dc21386948f690951ae6ad15f",
5
+ "package_version": "0.9.394"
6
6
  }
package/dist/bin/cli.js CHANGED
@@ -798,14 +798,14 @@ ${JSON.stringify(stormAlert, null, 2)}`);
798
798
  const { runStackUpdateCli } = await import("./stack-update.js");
799
799
  await runStackUpdateCli(args.slice(1));
800
800
  } else if (args[0] === "release") {
801
- const { parseReleaseArgs, runStackRelease } = await import("../stack-release-YEO6BFVR.js");
801
+ const { parseReleaseArgs, runStackRelease } = await import("../stack-release-YCNRPK6R.js");
802
802
  const releaseFlags = parseReleaseArgs(args.slice(1));
803
803
  await runStackRelease(releaseFlags);
804
804
  } else if (args[0] === "stack-promote") {
805
- const { runStackPromoteCli } = await import("../stack-promote-EAPCVGKJ.js");
805
+ const { runStackPromoteCli } = await import("../stack-promote-4EF7RNIV.js");
806
806
  await runStackPromoteCli(args.slice(1));
807
807
  } else if (args[0] === "stack-generate-manifest") {
808
- const { runStackGenerateManifestCli } = await import("../stack-generate-manifest-XZ534AJH.js");
808
+ const { runStackGenerateManifestCli } = await import("../stack-generate-manifest-H6LJQ2HV.js");
809
809
  process.exit(await runStackGenerateManifestCli(args.slice(1)));
810
810
  } else if (args[0] === "repo-truth") {
811
811
  const { runRepoTruthCli } = await import("./exe-repo-truth.js");
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  registryProxyOptionsFromEnv,
4
4
  runRegistryProxy
5
- } from "../chunk-NJ57AHX4.js";
5
+ } from "../chunk-RLUDQYOA.js";
6
6
  import {
7
7
  isMainModule
8
8
  } from "../chunk-6Y4B3QF6.js";
@@ -18,6 +18,7 @@ import {
18
18
  defaultStackPaths,
19
19
  detectDanglingVolumes,
20
20
  detectMissingRequiredEnvVars,
21
+ expandComposeServicesWithSidecars,
21
22
  listAvailableVersions,
22
23
  listHostComposeServices,
23
24
  loadServiceSelection,
@@ -46,7 +47,7 @@ import {
46
47
  verifyManifestImagesAvailable,
47
48
  warnUnmanagedManifestServices,
48
49
  withStackUpdateOperationLock
49
- } from "../chunk-WMGS5U2J.js";
50
+ } from "../chunk-DYFTZWG2.js";
50
51
  import "../chunk-EC5H53YD.js";
51
52
  import {
52
53
  runVerifyStack
@@ -62,7 +63,7 @@ import {
62
63
  import {
63
64
  logResult,
64
65
  runHealthGate
65
- } from "../chunk-POBFVHIS.js";
66
+ } from "../chunk-5OWHYOIF.js";
66
67
  import "../chunk-L25OAFOU.js";
67
68
  import "../chunk-RT57D7C4.js";
68
69
  import "../chunk-FTZET5YX.js";
@@ -2141,8 +2142,9 @@ function captureRetainedHealthForCli(composeFile, envFile, selectedService, requ
2141
2142
  stdio: ["pipe", "pipe", "pipe"],
2142
2143
  timeout: 2e4
2143
2144
  });
2144
- const critical = retainedCriticalServices(config.status === 0 ? config.stdout : null, selectedService, requiredCore);
2145
- const completedDependencies = retainedCompletedDependencies(config.stdout, critical, selectedService, requiredCore);
2145
+ const companions = expandComposeServicesWithSidecars([selectedService]).slice(1);
2146
+ const critical = retainedCriticalServices(config.status === 0 ? config.stdout : null, selectedService, requiredCore, companions);
2147
+ const completedDependencies = retainedCompletedDependencies(config.stdout, critical, selectedService, requiredCore, companions);
2146
2148
  const ps = spawnSync3("docker", [...args, "ps", "--all", "--format", "json"], {
2147
2149
  encoding: "utf8",
2148
2150
  stdio: ["pipe", "pipe", "pipe"],
@@ -2451,20 +2453,20 @@ async function main(args = process.argv.slice(2)) {
2451
2453
  }, plan, liveComposeRaw, envRaw, process.env, retainedComposeFiles.override);
2452
2454
  console.log(`[stack-update] Signed live compose retained: base SHA256 ${manifest.stacks[plan.targetVersion]?.config?.composeSha256}` + (retainedComposeFiles.override === null ? " (no override)" : `, override SHA256 ${manifest.stacks[plan.targetVersion]?.config?.composeOverrideSha256}`));
2453
2455
  const selectedService = Object.values(plan.release.services)[0];
2454
- assertRetainedComposeRunningService(
2455
- composeArgsForStack(opts.composeFile, opts.envFile),
2456
- selectedService.composeService ?? opts.serviceName
2457
- );
2458
- assertRetainedComposeRenderedImage(
2459
- composeArgsForStack(opts.composeFile, opts.envFile),
2460
- selectedService.composeService ?? opts.serviceName,
2461
- selectedService.env,
2462
- plan.changes[0].after,
2463
- void 0,
2464
- { ...process.env, [selectedService.env]: plan.changes[0].after }
2465
- );
2456
+ const composeTargets = expandComposeServicesWithSidecars([selectedService.composeService ?? opts.serviceName]);
2457
+ for (const target of composeTargets) {
2458
+ assertRetainedComposeRunningService(composeArgsForStack(opts.composeFile, opts.envFile), target);
2459
+ assertRetainedComposeRenderedImage(
2460
+ composeArgsForStack(opts.composeFile, opts.envFile),
2461
+ target,
2462
+ selectedService.env,
2463
+ plan.changes[0].after,
2464
+ void 0,
2465
+ { ...process.env, [selectedService.env]: plan.changes[0].after }
2466
+ );
2467
+ }
2466
2468
  console.log(
2467
- `[stack-update] If applied: back up stack config and attempt the configured database/off-host backups; write only ${selectedService.env} in the stack .env; update the stack lock and deploy audit; pull and recreate only ${selectedService.composeService ?? opts.serviceName}. Compose, bind-mounted assets, gateway overlays, host hardening, and service selection remain unchanged.`
2469
+ `[stack-update] If applied: back up stack config and attempt the configured database/off-host backups; write only ${selectedService.env} in the stack .env; update the stack lock and deploy audit; pull and recreate only ${composeTargets.join(", ")}. Compose, bind-mounted assets, gateway overlays, host hardening, and service selection remain unchanged.`
2468
2470
  );
2469
2471
  }
2470
2472
  const targetRelease = manifest.stacks[plan.targetVersion];
@@ -8,7 +8,7 @@ import {
8
8
  logResult,
9
9
  main,
10
10
  runHealthGate
11
- } from "../chunk-POBFVHIS.js";
11
+ } from "../chunk-5OWHYOIF.js";
12
12
  import "../chunk-MLKGABMK.js";
13
13
  export {
14
14
  checkCRM,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 2,
3
- "generated_at": "2026-09-23T22:15:03.947Z",
3
+ "generated_at": "2026-09-23T23:35:24.804Z",
4
4
  "files": [
5
5
  {
6
6
  "path": "active-agent-KMGOYJTP.js",
@@ -179,7 +179,7 @@
179
179
  },
180
180
  {
181
181
  "path": "bin/cli.js",
182
- "sha256": "a26f29a3a9652a702b0bdafd1bbceb13389b3fffc4d49477eae926e855a59ee6",
182
+ "sha256": "407694f935b3d6c4613ca6c24229ac39e53d9022bf4bc62303bc4436920089f5",
183
183
  "bytes": 69792
184
184
  },
185
185
  {
@@ -524,7 +524,7 @@
524
524
  },
525
525
  {
526
526
  "path": "bin/registry-proxy.js",
527
- "sha256": "e4b41eb986a2f7baf4371bb8a1bd5ec046ef6741c5df16a1f7aaeda5cb946675",
527
+ "sha256": "224728a8c04ed51bd21488f26c521f39776d6d5c67d40e6b05acfa30aaa47eb8",
528
528
  "bytes": 1885
529
529
  },
530
530
  {
@@ -549,8 +549,8 @@
549
549
  },
550
550
  {
551
551
  "path": "bin/stack-update.js",
552
- "sha256": "45e9139c3b040aff8c4e863ada54ca75c58c4c14b7c8571f67a599372a0978bb",
553
- "bytes": 131290
552
+ "sha256": "39605342987fd37972f577aa1619e9fdc7aef0e339bc5188f820251392c45242",
553
+ "bytes": 131487
554
554
  },
555
555
  {
556
556
  "path": "bin/update.js",
@@ -569,7 +569,7 @@
569
569
  },
570
570
  {
571
571
  "path": "bin/vps-health-gate.js",
572
- "sha256": "1b4e8961edf1b549fc3900950e8ddd6bf1bff6dc02fed969028f31b4c730a3d3",
572
+ "sha256": "386e8e34d613c6ed0511ff3380532e9bc24176de7c6a955770134c6a29853940",
573
573
  "bytes": 333
574
574
  },
575
575
  {
@@ -782,6 +782,11 @@
782
782
  "sha256": "c2e2367cffa3e57666f0307f2374f6ca8cbf2f07ba45b7361d680e8271be90ec",
783
783
  "bytes": 3297
784
784
  },
785
+ {
786
+ "path": "chunk-5OWHYOIF.js",
787
+ "sha256": "7321323a90b487e2f95b3f6c6dd72a177e546aa7aace189d3f725f879fa560c5",
788
+ "bytes": 7587
789
+ },
785
790
  {
786
791
  "path": "chunk-5V7BD7Z4.js",
787
792
  "sha256": "ca37d6e8b8481a988ed41264e604ce992de1d8d63fff23e07b3d2367cba5af21",
@@ -1092,6 +1097,11 @@
1092
1097
  "sha256": "cf3ce4cf6c9cdba17a8a5e3d9f0c78ae42f1cb72f1a06608cc8da1fb27f06a76",
1093
1098
  "bytes": 3292
1094
1099
  },
1100
+ {
1101
+ "path": "chunk-DYFTZWG2.js",
1102
+ "sha256": "72d0060a08f4996dfe65b4fe9718b00fc053f2bfd2747d176f7a4539954ec4fc",
1103
+ "bytes": 261313
1104
+ },
1095
1105
  {
1096
1106
  "path": "chunk-E23LNUWJ.js",
1097
1107
  "sha256": "6d692be7ac73bf481e7013c4b948b70acd8282234f645d562457754afaa7a02e",
@@ -1527,11 +1537,6 @@
1527
1537
  "sha256": "cfdcf9141d53bd73b7b8cc3a4097773d1f854a9dffb7a81324f2782c7d70fe6c",
1528
1538
  "bytes": 14891
1529
1539
  },
1530
- {
1531
- "path": "chunk-NJ57AHX4.js",
1532
- "sha256": "37cd6a8a4df230eca98e5fc2792fa39027c3ca8cbfbb5438f87680a1c996a755",
1533
- "bytes": 40844
1534
- },
1535
1540
  {
1536
1541
  "path": "chunk-NKPPPX6I.js",
1537
1542
  "sha256": "4a5f8acc2c7b70708de8b68c7c3b7b3f5981395f2bd1a4db3b3b7151769910db",
@@ -1658,9 +1663,9 @@
1658
1663
  "bytes": 3317
1659
1664
  },
1660
1665
  {
1661
- "path": "chunk-POBFVHIS.js",
1662
- "sha256": "398f78513e36934eebeaceb2644137c3a95acb515783aa0bdf6dd970bb33cbb9",
1663
- "bytes": 7587
1666
+ "path": "chunk-PS77SULS.js",
1667
+ "sha256": "6c337e635c575f47a50c8587d2bfa2fcdd0ebfdf43a967f38170ce684ff63dbb",
1668
+ "bytes": 3766
1664
1669
  },
1665
1670
  {
1666
1671
  "path": "chunk-PYS43F2X.js",
@@ -1757,6 +1762,11 @@
1757
1762
  "sha256": "627baf16bbe786e186075ad51849ac4460738fb2e185216bddefca23d2ae55b2",
1758
1763
  "bytes": 11048
1759
1764
  },
1765
+ {
1766
+ "path": "chunk-RLUDQYOA.js",
1767
+ "sha256": "5e1fb642dcb8ed9d6fdb95fae00346afafff51fddd4b60d2b11c1c878d7b1c3b",
1768
+ "bytes": 40844
1769
+ },
1760
1770
  {
1761
1771
  "path": "chunk-RT57D7C4.js",
1762
1772
  "sha256": "054f2262b18d6c727b18c7bc34491d1d30f20d4d8fb42eb21704ac9c190e5477",
@@ -1907,11 +1917,6 @@
1907
1917
  "sha256": "697ecdef6991c061baab1e9759bc14aecd28631954b2edfdb721c98c72d41c82",
1908
1918
  "bytes": 1813
1909
1919
  },
1910
- {
1911
- "path": "chunk-V57YDQQA.js",
1912
- "sha256": "6284d4a8d979d18fdb3b863f59f91c7cd616c169349bb77766a94693477706e9",
1913
- "bytes": 3766
1914
- },
1915
1920
  {
1916
1921
  "path": "chunk-VGMACSEV.js",
1917
1922
  "sha256": "4a51d1fb50f1389160ec2d06ebeb702976a647212f7731ab58f562de3f53f215",
@@ -1967,11 +1972,6 @@
1967
1972
  "sha256": "288099f4b532013a4c9ba4c6129273a6f5036fc99f574e4b4d2b0fddc3792b67",
1968
1973
  "bytes": 1549
1969
1974
  },
1970
- {
1971
- "path": "chunk-WMGS5U2J.js",
1972
- "sha256": "688da29e942b4732af8dc9d226f26a1c57c37e30581a97e30be5af4bfc4ad4ae",
1973
- "bytes": 260597
1974
- },
1975
1975
  {
1976
1976
  "path": "chunk-WPTIHQ6M.js",
1977
1977
  "sha256": "a999baf6db449dcd8c856393a0721a50aceb27e74a49f71bbc6b553081d98fc2",
@@ -2574,7 +2574,7 @@
2574
2574
  },
2575
2575
  {
2576
2576
  "path": "hooks/manifest.json",
2577
- "sha256": "af052428c7e0f413b988ae47ed6a7120020847a8d665eb125ff24e0f5571b633",
2577
+ "sha256": "4140c8729b945f17c2a19a259a8aa0a1e3f753237a95e005be4362d4fb90cc4f",
2578
2578
  "bytes": 1841
2579
2579
  },
2580
2580
  {
@@ -2879,7 +2879,7 @@
2879
2879
  },
2880
2880
  {
2881
2881
  "path": "lib/registry-proxy.js",
2882
- "sha256": "086622c69175e1c94ca91d2ac0dab2042db655eb14252e8acabc3e02fc2dd40b",
2882
+ "sha256": "94c2d851ff177536c9e0def91d5d55c740005ae6c96b9ee4b9543852a470d25f",
2883
2883
  "bytes": 749
2884
2884
  },
2885
2885
  {
@@ -3463,8 +3463,8 @@
3463
3463
  "bytes": 111
3464
3464
  },
3465
3465
  {
3466
- "path": "stack-generate-manifest-XZ534AJH.js",
3467
- "sha256": "5a3b5b3ab0b6160c45abf107a099e188db1cd3239f983c774bb32a4304d02fa9",
3466
+ "path": "stack-generate-manifest-H6LJQ2HV.js",
3467
+ "sha256": "d790293379cf08251382c3076496f39824ddb800e345e24ef00fff1d21e36335",
3468
3468
  "bytes": 56960
3469
3469
  },
3470
3470
  {
@@ -3473,18 +3473,18 @@
3473
3473
  "bytes": 4761
3474
3474
  },
3475
3475
  {
3476
- "path": "stack-promote-EAPCVGKJ.js",
3477
- "sha256": "5dbfd92d46224fa325522dcb29a0c37a04503bcbc240338e6dd81999915e41df",
3476
+ "path": "stack-promote-4EF7RNIV.js",
3477
+ "sha256": "d9db50f30a0a97cbe56b4e566be8e9c1327d9ecb5c96a6a46967bf57ea76f8a9",
3478
3478
  "bytes": 7425
3479
3479
  },
3480
3480
  {
3481
- "path": "stack-release-YEO6BFVR.js",
3482
- "sha256": "59e8eb373abf14f60ab5c7b758b8ab9cebe044490622af22c1af3746f0bd2102",
3481
+ "path": "stack-release-YCNRPK6R.js",
3482
+ "sha256": "bd26b47386fa7849325c313b30e2eb0ee8f0ba77ea8dcaf95256fb0241a824bd",
3483
3483
  "bytes": 117550
3484
3484
  },
3485
3485
  {
3486
- "path": "stack-update-NEDES5S4.js",
3487
- "sha256": "f70a348356634acc818edf94d0deaf756ca7ad3198d6f339b39b8358a6962afe",
3486
+ "path": "stack-update-2F464W3N.js",
3487
+ "sha256": "8be2553c248e2067f8f4a0a0f342513af5080b88b79ce9b22ce07cf7a73bf5ce",
3488
3488
  "bytes": 7863
3489
3489
  },
3490
3490
  {
@@ -212,7 +212,7 @@ async function main(args) {
212
212
  console.log("[health-gate] Starting rollback...");
213
213
  restorePreDeployBackup();
214
214
  try {
215
- const { rollbackStackUpdate, defaultStackPaths } = await import("./stack-update-NEDES5S4.js");
215
+ const { rollbackStackUpdate, defaultStackPaths } = await import("./stack-update-2F464W3N.js");
216
216
  const paths = defaultStackPaths();
217
217
  await rollbackStackUpdate({
218
218
  manifestRef: paths.manifestRef,
@@ -176,7 +176,7 @@ function parseRenderedServices(renderedCompose) {
176
176
  }
177
177
  return services;
178
178
  }
179
- function retainedCriticalServices(renderedCompose, selectedService, requiredCore) {
179
+ function retainedCriticalServices(renderedCompose, selectedService, requiredCore, selectedCompanions = []) {
180
180
  const services = parseRenderedServices(renderedCompose);
181
181
  const critical = /* @__PURE__ */ new Set();
182
182
  const visit = (service) => {
@@ -202,10 +202,11 @@ function retainedCriticalServices(renderedCompose, selectedService, requiredCore
202
202
  }
203
203
  };
204
204
  visit(selectedService);
205
+ for (const service of selectedCompanions) visit(service);
205
206
  for (const service of requiredCore) visit(service);
206
207
  return critical;
207
208
  }
208
- function retainedCompletedDependencies(renderedCompose, critical, selectedService, requiredCore) {
209
+ function retainedCompletedDependencies(renderedCompose, critical, selectedService, requiredCore, selectedCompanions = []) {
209
210
  const services = parseRenderedServices(renderedCompose);
210
211
  const inbound = /* @__PURE__ */ new Map();
211
212
  for (const parent of critical) {
@@ -223,7 +224,7 @@ function retainedCompletedDependencies(renderedCompose, critical, selectedServic
223
224
  inbound.set(name, [...inbound.get(name) ?? [], condition]);
224
225
  }
225
226
  }
226
- const roots = /* @__PURE__ */ new Set([selectedService, ...requiredCore]);
227
+ const roots = /* @__PURE__ */ new Set([selectedService, ...selectedCompanions, ...requiredCore]);
227
228
  return new Set(
228
229
  [...inbound].filter(
229
230
  ([name, conditions]) => !roots.has(name) && // Compose's omitted restart policy is "no". An explicit policy
@@ -2476,8 +2477,9 @@ function assertRetainedComposePlan(input, plan, liveComposeRaw, envRaw, processE
2476
2477
  if (service.migrations || plan.release.migrations) {
2477
2478
  throw new Error("--retain-compose cannot run service or release migrations");
2478
2479
  }
2479
- if (expandComposeServicesWithSidecars([service.composeService ?? name]).length !== 1) {
2480
- throw new Error("--retain-compose requires a service with no companion sidecars");
2480
+ const composeServices = expandComposeServicesWithSidecars([service.composeService ?? name]);
2481
+ if (composeServices.length > 1 && !(name === "crm" && composeServices.length === 2 && composeServices[0] === "exe-crm" && composeServices[1] === "exe-crm-worker")) {
2482
+ throw new Error("--retain-compose requires a service with no unsupported companion sidecars");
2481
2483
  }
2482
2484
  if (!service.env || plan.changes.length !== 1 || plan.changes[0].service !== name || plan.changes[0].key !== service.env) {
2483
2485
  throw new Error("--retain-compose requires exactly one selected image-pin change");
@@ -2498,16 +2500,17 @@ function assertRetainedComposePlan(input, plan, liveComposeRaw, envRaw, processE
2498
2500
  } else if (config.composeOverrideSha256) {
2499
2501
  throw new Error("--retain-compose refused: signed compose override is absent from the live stack");
2500
2502
  }
2501
- const imageExpression = liveOverrideRaw === null ? parseComposeServiceImages(liveComposeRaw).get(service.composeService ?? name) : parseComposeServiceImages(liveOverrideRaw).get(service.composeService ?? name) ?? parseComposeServiceImages(liveComposeRaw).get(service.composeService ?? name);
2502
- if (!imageExpression || !envRefsInImageExpression(imageExpression).includes(service.env)) {
2503
- throw new Error("--retain-compose refused: selected service compose image does not use its signed image pin");
2504
- }
2505
- const plannedImage = resolveComposeImageExpression(
2506
- imageExpression,
2507
- parseEnv(patchEnv(envRaw, { [service.env]: plan.changes[0].after }))
2508
- );
2509
- if (plannedImage !== plan.changes[0].after) {
2510
- throw new Error("--retain-compose refused: rendered selected service image differs from signed image pin");
2503
+ const baseImages = parseComposeServiceImages(liveComposeRaw);
2504
+ const overrideImages = liveOverrideRaw === null ? /* @__PURE__ */ new Map() : parseComposeServiceImages(liveOverrideRaw);
2505
+ const plannedEnv = parseEnv(patchEnv(envRaw, { [service.env]: plan.changes[0].after }));
2506
+ for (const composeService of composeServices) {
2507
+ const imageExpression = overrideImages.get(composeService) ?? baseImages.get(composeService);
2508
+ if (!imageExpression || !envRefsInImageExpression(imageExpression).includes(service.env)) {
2509
+ throw new Error(`--retain-compose refused: selected service ${composeService} compose image does not use its signed image pin`);
2510
+ }
2511
+ if (resolveComposeImageExpression(imageExpression, plannedEnv) !== plan.changes[0].after) {
2512
+ throw new Error(`--retain-compose refused: rendered selected service ${composeService} image differs from signed image pin`);
2513
+ }
2511
2514
  }
2512
2515
  const env = parseEnv(envRaw);
2513
2516
  const monitorKey = env.get("EXE_MONITOR_KEY") ?? "";
@@ -3947,18 +3950,20 @@ ${lines.join("\n")}`
3947
3950
  if (options.retainCompose) {
3948
3951
  const [name, service] = Object.entries(plan.release.services)[0];
3949
3952
  const composeArgs2 = composeArgsForStack(options.composeFile, options.envFile);
3950
- assertRetainedComposeRunningService(
3951
- composeArgs2,
3952
- service.composeService ?? name,
3953
- options.composePsCapture ?? defaultComposePsCapture
3954
- );
3955
- assertRetainedComposeRenderedImage(
3956
- composeArgs2,
3957
- service.composeService ?? name,
3958
- service.env,
3959
- plan.changes[0].after,
3960
- options.composeConfigCapture ?? defaultComposeConfigCapture
3961
- );
3953
+ for (const target of expandComposeServicesWithSidecars([service.composeService ?? name])) {
3954
+ assertRetainedComposeRunningService(
3955
+ composeArgs2,
3956
+ target,
3957
+ options.composePsCapture ?? defaultComposePsCapture
3958
+ );
3959
+ assertRetainedComposeRenderedImage(
3960
+ composeArgs2,
3961
+ target,
3962
+ service.env,
3963
+ plan.changes[0].after,
3964
+ options.composeConfigCapture ?? defaultComposeConfigCapture
3965
+ );
3966
+ }
3962
3967
  }
3963
3968
  const hostState = listHostComposeServices(
3964
3969
  composeArgsForStack(options.composeFile, options.envFile),
@@ -4113,11 +4118,12 @@ ${lines.join("\n")}`
4113
4118
  if (options.retainCompose) {
4114
4119
  const [selectedName, selectedEntry] = Object.entries(plan.release.services)[0];
4115
4120
  const selected = selectedEntry.composeService ?? selectedName;
4121
+ const selectedCompanions = expandComposeServicesWithSidecars([selected]).slice(1);
4116
4122
  const requiredCore = Object.entries(targetRelease.services).filter(([, service]) => service.required === true && service.category === "core").map(([name, service]) => service.composeService ?? name);
4117
4123
  const args = composeArgsForStack(options.composeFile, options.envFile);
4118
4124
  const rendered = (options.composeConfigCapture ?? defaultComposeConfigCapture)(args, process.env);
4119
- const critical = retainedCriticalServices(rendered, selected, requiredCore);
4120
- const completedDependencies = retainedCompletedDependencies(rendered, critical, selected, requiredCore);
4125
+ const critical = retainedCriticalServices(rendered, selected, requiredCore, selectedCompanions);
4126
+ const completedDependencies = retainedCompletedDependencies(rendered, critical, selected, requiredCore, selectedCompanions);
4121
4127
  const rawHealth = (options.composePsCapture ?? defaultComposePsCapture)(args);
4122
4128
  retainedHealthBaseline = { critical, completedDependencies, containers: parseRetainedContainerHealth(rawHealth) };
4123
4129
  const failures = assessRetainedHealthBefore(retainedHealthBaseline);
@@ -4470,7 +4476,7 @@ Push the missing image(s) to the registry, or re-run with --break-glass <reason>
4470
4476
  for (const service of restartOrder) {
4471
4477
  restartIndex++;
4472
4478
  const endRestart = startPhase(`restart ${service}`);
4473
- const manifestServiceName = Object.entries(plan.release.services).find(([name, svc]) => (svc.composeService ?? name) === service)?.[0] ?? service;
4479
+ const manifestServiceName = resolveOwningManifestService(service, plan.release.services);
4474
4480
  if (bundledIsolation && (failedComposeServices.has(service) || failedManifestServices.has(resolveOwningManifestService(service, plan.release.services)))) {
4475
4481
  continue;
4476
4482
  }
@@ -4484,12 +4490,13 @@ Push the missing image(s) to the registry, or re-run with --break-glass <reason>
4484
4490
  continue;
4485
4491
  }
4486
4492
  if (options.retainCompose) {
4493
+ const owner = plan.release.services[manifestServiceName];
4487
4494
  assertRetainedComposeFilesUnchanged(options.composeFile, composeRaw, retainedOverrideHash);
4488
4495
  assertRetainedComposeRunningService(composeArgs, service, options.composePsCapture ?? defaultComposePsCapture);
4489
4496
  assertRetainedComposeRenderedImage(
4490
4497
  composeArgs,
4491
4498
  service,
4492
- plan.release.services[manifestServiceName].env,
4499
+ owner.env,
4493
4500
  plan.changes[0].after,
4494
4501
  options.composeConfigCapture ?? defaultComposeConfigCapture
4495
4502
  );
@@ -4856,9 +4863,12 @@ Fix these before the stack is safe to operate.`);
4856
4863
  const composeService = service.composeService ?? name;
4857
4864
  try {
4858
4865
  syncImagePinsWithProcessEnv(envRaw, [service.env]);
4859
- exec("docker", [...composeArgs, "up", "-d", "--no-deps", composeService]);
4860
- console.error(`[stack-update] Scoped fallback restored ${composeService} after rollback error: ${rbReason}`);
4861
- rollbackDetail += `; scoped fallback restored ${composeService}`;
4866
+ const restored = expandComposeServicesWithSidecars([composeService]);
4867
+ for (const target of restored) {
4868
+ exec("docker", [...composeArgs, "up", "-d", "--no-deps", target]);
4869
+ }
4870
+ console.error(`[stack-update] Scoped fallback restored ${restored.join(", ")} after rollback error: ${rbReason}`);
4871
+ rollbackDetail += `; scoped fallback restored ${restored.join(", ")}`;
4862
4872
  } catch (scopedError) {
4863
4873
  console.error(`[stack-update] Scoped fallback failed for ${composeService}: ${errorMessage(scopedError)}`);
4864
4874
  rollbackDetail += `; scoped fallback failed for ${composeService}: ${errorMessage(scopedError)}`;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  canonicalizeStackManifest
3
- } from "./chunk-WMGS5U2J.js";
3
+ } from "./chunk-DYFTZWG2.js";
4
4
 
5
5
  // src/lib/stack-manifest-write.ts
6
6
  import { readFileSync, statSync, writeFileSync } from "fs";
@@ -138,7 +138,7 @@ async function assertManifestSignature(manifest, publicKeyPem) {
138
138
  "manifest carries no `signature`. Fleets that enforce EXE_STACK_PUBLIC_KEY reject unsigned manifests, so publishing one would ship a release no host can install. Re-sign with the custodied key: node scripts/sign-stack-manifest.mjs deploy/stack-manifests/v0.9.json"
139
139
  );
140
140
  }
141
- const { verifyStackManifestSignature } = await import("./stack-update-NEDES5S4.js");
141
+ const { verifyStackManifestSignature } = await import("./stack-update-2F464W3N.js");
142
142
  try {
143
143
  verifyStackManifestSignature(manifest, publicKeyPem);
144
144
  } catch (err) {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "generatedAt": "2026-09-23T22:15:03.718Z",
3
+ "generatedAt": "2026-09-23T23:35:24.596Z",
4
4
  "hashes": {
5
5
  "bug-report-worker.js": "7c5f5951fe30192e374d9047c3a7f2975a879a5951457aafea5db95d5d6be6af",
6
6
  "codex-stop-task-finalizer.js": "f963449525e068ebf3f04a2950adf21464de71774b60165a84d69621a5eca30a",
@@ -11,7 +11,7 @@ import {
11
11
  resolveRegistryProxyBuildIdentity,
12
12
  resolveStackManifestChannel,
13
13
  runRegistryProxy
14
- } from "../chunk-NJ57AHX4.js";
14
+ } from "../chunk-RLUDQYOA.js";
15
15
  import "../chunk-MLKGABMK.js";
16
16
  export {
17
17
  SERVED_VERSION_PATH,
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  writeSignedStackManifest
4
- } from "./chunk-V57YDQQA.js";
5
- import "./chunk-WMGS5U2J.js";
4
+ } from "./chunk-PS77SULS.js";
5
+ import "./chunk-DYFTZWG2.js";
6
6
  import "./chunk-EC5H53YD.js";
7
7
  import "./chunk-YYRI2AGK.js";
8
8
  import "./chunk-L25OAFOU.js";
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  writeSignedStackManifest
4
- } from "./chunk-V57YDQQA.js";
5
- import "./chunk-WMGS5U2J.js";
4
+ } from "./chunk-PS77SULS.js";
5
+ import "./chunk-DYFTZWG2.js";
6
6
  import "./chunk-EC5H53YD.js";
7
7
  import "./chunk-YYRI2AGK.js";
8
8
  import "./chunk-L25OAFOU.js";
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  writeSignedStackManifest
4
- } from "./chunk-V57YDQQA.js";
5
- import "./chunk-WMGS5U2J.js";
4
+ } from "./chunk-PS77SULS.js";
5
+ import "./chunk-DYFTZWG2.js";
6
6
  import "./chunk-EC5H53YD.js";
7
7
  import {
8
8
  assertPreflightGate,
@@ -2028,7 +2028,7 @@ async function warmProxyCache(imageRef) {
2028
2028
  async function resolveImageGitShaLabel(ref, dryRun) {
2029
2029
  if (!ref || dryRun) return void 0;
2030
2030
  try {
2031
- const { readProvenanceLabels } = await import("./stack-generate-manifest-XZ534AJH.js");
2031
+ const { readProvenanceLabels } = await import("./stack-generate-manifest-H6LJQ2HV.js");
2032
2032
  const labels = await readProvenanceLabels(ref);
2033
2033
  return labels["org.exe.git_sha"] ?? labels["org.opencontainers.image.revision"];
2034
2034
  } catch (err) {
@@ -132,7 +132,7 @@ import {
132
132
  waitForHttpOk,
133
133
  warnUnmanagedManifestServices,
134
134
  withStackUpdateOperationLock
135
- } from "./chunk-WMGS5U2J.js";
135
+ } from "./chunk-DYFTZWG2.js";
136
136
  import "./chunk-EC5H53YD.js";
137
137
  import "./chunk-YYRI2AGK.js";
138
138
  import "./chunk-L25OAFOU.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.393",
3
+ "version": "0.9.394",
4
4
  "description": "AI employee operating system \u2014 persistent memory, task management, and multi-agent coordination for Claude Code.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -1,8 +1,8 @@
1
1
  {
2
- "current": "0.9.393",
2
+ "current": "0.9.394",
3
3
  "notes": {
4
- "0.9.393": {
5
- "version": "0.9.393",
4
+ "0.9.394": {
5
+ "version": "0.9.394",
6
6
  "date": "2026-09-23",
7
7
  "features": [
8
8
  "local CI triage — classify failing checks at zero token cost (#1441)",
@@ -41,6 +41,10 @@
41
41
  ],
42
42
  "security": [],
43
43
  "other": [
44
+ "Prepare signed CRM companion canary stack 0.9.55",
45
+ "Allow signed retained CRM web and worker image group",
46
+ "Prepare signed CRM DEMO canary stack 0.9.54",
47
+ "Add fixed-source npm-only publisher for exe-os 0.9.393",
44
48
  "Prepare signed Dashboard canary stack 0.9.53 with scoped updater 0.9.393",
45
49
  "assert required core failure in retained scope",
46
50
  "release(npm): publish 0.9.392 from exact green main source",