@askexenow/exe-os 0.9.311 → 0.9.312

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.
@@ -1488,7 +1488,7 @@
1488
1488
  "version": "0.9.25",
1489
1489
  "releasedAt": "2026-06-22T07:00:00Z",
1490
1490
  "notes": "17 bug fixes: monitor volume/key (P1), CI flaky tests (P2), CRM bridge contract (P0), stack manifest infra deps (P0), DB image pin (P0), BYOK env alias (P1), SQL race (P2), ERP hardcoded defaults (P1), task resume DB init (P1), monitor :latest images (P1), docs/setup stale claims (P2), monitor healthcheck self-heal (P0), concurrent build chunk corruption (P1), monitor auto-pairing/alerts (P1), SSO CORS whitelist (P1), wiki SSO callback (P1), exe-chat JWT fallback (P3). Baileys WA version floor for WhatsApp pairing. Gateway v0.9.24 with all fixes.",
1491
- "npmVersion": "0.9.310",
1491
+ "npmVersion": "0.9.312",
1492
1492
  "services": {
1493
1493
  "exe-db": {
1494
1494
  "image": "pgvector/pgvector:0.8.0-pg16",
@@ -1498,19 +1498,19 @@
1498
1498
  "description": "Postgres (pgvector) \u2014 pinned versioned tag (bug ee16e7ef)"
1499
1499
  },
1500
1500
  "exe-os": {
1501
- "image": "update.askexe.com/askexe/exe-os:v0.9.297@sha256:9fb38b3972202c410bb03d437a7fbaaf34a474f123285f45cbd9ceb039d276c1",
1501
+ "image": "update.askexe.com/askexe/exe-os:v0.9.311@sha256:011730042f55277724dbe83fde1a6416db2f3e8bf62d3254738d68d8de33e1f9",
1502
1502
  "env": "EXE_OS_IMAGE_TAG",
1503
1503
  "required": true,
1504
1504
  "category": "core",
1505
1505
  "description": "exe-os daemon + MCP server"
1506
1506
  },
1507
1507
  "crm": {
1508
- "image": "update.askexe.com/askexe/exe-crm:v0.9.49@sha256:656512528d2cecc7c0424f917a9b3d0a999f91b160c7b7e7e05778dd8b1319cc",
1508
+ "image": "update.askexe.com/askexe/exe-crm:v0.9.51@sha256:73864ce14aaac06b73d67100bbf88e669fd13c7da39edd9644107037211559b7",
1509
1509
  "env": "CRM_IMAGE_TAG",
1510
1510
  "category": "app"
1511
1511
  },
1512
1512
  "wiki": {
1513
- "image": "update.askexe.com/askexe/exe-wiki:v0.9.24@sha256:3acf72b992d34ce1e802b075cef8e4e1dd5e4b5681a4681398545f1f7e13e331",
1513
+ "image": "update.askexe.com/askexe/exe-wiki:v0.9.26@sha256:e6c1b67d5c431898248f845abfd36dc136575795f35e3652bb4f6164e8a9dd34",
1514
1514
  "env": "WIKI_IMAGE_TAG",
1515
1515
  "category": "app"
1516
1516
  },
@@ -25,7 +25,7 @@ var SIGTERM_GRACE_MS = 1e4;
25
25
  var KICKSTART_SUPPRESS_TICKS = 3;
26
26
  var MIN_DAEMON_AGE_S = 60;
27
27
  var STEAL_SUPPRESS_PERCENT = 20;
28
- var LOAD_PER_CORE_SUPPRESS = 4;
28
+ var LOAD_PER_CORE_SUPPRESS = 2;
29
29
  var consecutiveFailures = 0;
30
30
  var suppressTicks = 0;
31
31
  function log(msg) {
@@ -17,7 +17,7 @@ import {
17
17
  runStackUpdate,
18
18
  saveServiceSelection,
19
19
  verifyManifestImagesAvailable
20
- } from "../chunk-DKHBMIVE.js";
20
+ } from "../chunk-KMIAYKIH.js";
21
21
  import {
22
22
  runVerifyStack
23
23
  } from "../chunk-IRHNV4GY.js";
@@ -31,7 +31,7 @@ import {
31
31
  import {
32
32
  logResult,
33
33
  runHealthGate
34
- } from "../chunk-JDYO76PI.js";
34
+ } from "../chunk-JMHKK7A5.js";
35
35
  import "../chunk-JV225JBX.js";
36
36
  import "../chunk-2EJ636HI.js";
37
37
  import "../chunk-DFIOOK5R.js";
@@ -8,7 +8,7 @@ import {
8
8
  logResult,
9
9
  main,
10
10
  runHealthGate
11
- } from "../chunk-JDYO76PI.js";
11
+ } from "../chunk-JMHKK7A5.js";
12
12
  import "../chunk-MLKGABMK.js";
13
13
  export {
14
14
  checkCRM,
@@ -45,8 +45,7 @@ async function checkGateway() {
45
45
  }
46
46
  function checkPostgres() {
47
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"], {
48
+ const result = spawnSync("docker", ["exec", "exe-db", "pg_isready", "-U", "exe"], {
50
49
  encoding: "utf8",
51
50
  stdio: ["pipe", "pipe", "pipe"],
52
51
  timeout: 1e4
@@ -54,16 +53,15 @@ function checkPostgres() {
54
53
  return {
55
54
  check: "postgres",
56
55
  status: result.status === 0 ? "pass" : "fail",
57
- message: result.status === 0 ? "Postgres responding" : `Postgres failed: ${result.stderr?.trim() || `exit ${result.status}`}`,
56
+ message: result.status === 0 ? "Postgres responding (container)" : `Postgres failed: ${result.stderr?.trim() || result.stdout?.trim() || `exit ${result.status}`}`,
58
57
  durationMs: Date.now() - start
59
58
  };
60
59
  }
61
60
  function checkRawEvents(probe) {
62
61
  const start = Date.now();
63
- const databaseUrl = process.env.DATABASE_URL || "postgres://exe@localhost:5432/exedb";
64
62
  const result = probe ?? spawnSync(
65
- "psql",
66
- [databaseUrl, "-t", "-c", "SELECT count(*) FROM raw.raw_events"],
63
+ "docker",
64
+ ["exec", "exe-db", "psql", "-U", "exe", "-d", "exedb", "-t", "-c", "SELECT count(*) FROM raw.raw_events"],
67
65
  {
68
66
  encoding: "utf8",
69
67
  stdio: ["pipe", "pipe", "pipe"],
@@ -149,9 +147,19 @@ function restorePreDeployBackup() {
149
147
  }
150
148
  const latest = backups[0];
151
149
  const filepath = path.join(BACKUP_DIR, latest);
152
- const databaseUrl = process.env.DATABASE_URL || "postgres://exe@localhost:5432/exedb";
153
150
  console.log(`[health-gate] Restoring pre-deploy backup: ${latest}`);
154
- const result = spawnSync("pg_restore", ["-d", databaseUrl, "--clean", "--if-exists", filepath], {
151
+ const result = spawnSync("docker", [
152
+ "exec",
153
+ "exe-db",
154
+ "pg_restore",
155
+ "-U",
156
+ "exe",
157
+ "-d",
158
+ "exedb",
159
+ "--clean",
160
+ "--if-exists",
161
+ filepath
162
+ ], {
155
163
  encoding: "utf8",
156
164
  stdio: ["pipe", "pipe", "pipe"],
157
165
  timeout: 3e5
@@ -204,7 +212,7 @@ async function main(args) {
204
212
  console.log("[health-gate] Starting rollback...");
205
213
  restorePreDeployBackup();
206
214
  try {
207
- const { rollbackStackUpdate, defaultStackPaths } = await import("./stack-update-XHQJRJEP.js");
215
+ const { rollbackStackUpdate, defaultStackPaths } = await import("./stack-update-TUBZTY7Z.js");
208
216
  const paths = defaultStackPaths();
209
217
  await rollbackStackUpdate({
210
218
  manifestRef: paths.manifestRef,
@@ -47,9 +47,86 @@ function saveServiceSelection(envFile, selectedServices) {
47
47
  };
48
48
  writeFileSync(selPath, JSON.stringify(data, null, 2) + "\n", { mode: 384 });
49
49
  }
50
- function filterServicesBySelection(release, selection) {
50
+ function parseComposeDependsOn(composeRaw) {
51
+ const deps = /* @__PURE__ */ new Map();
52
+ const lines = composeRaw.split(/\r?\n/);
53
+ let currentService = null;
54
+ let inDependsOn = false;
55
+ let dependsOnIndent = 0;
56
+ for (const line of lines) {
57
+ if (!line.trim() || line.trim().startsWith("#")) {
58
+ continue;
59
+ }
60
+ const indent = line.length - line.trimStart().length;
61
+ const trimmed = line.trim();
62
+ if (indent === 2 && /^[a-zA-Z0-9_-]+:\s*$/.test(trimmed)) {
63
+ currentService = trimmed.replace(/:.*$/, "");
64
+ inDependsOn = false;
65
+ continue;
66
+ }
67
+ if (!currentService) continue;
68
+ if (indent <= 2 && /^[a-zA-Z0-9_-]+:/.test(trimmed)) {
69
+ currentService = indent === 2 ? trimmed.replace(/:.*$/, "") : null;
70
+ inDependsOn = false;
71
+ continue;
72
+ }
73
+ if (indent === 4 && trimmed.startsWith("depends_on:")) {
74
+ inDependsOn = true;
75
+ dependsOnIndent = 4;
76
+ if (!deps.has(currentService)) deps.set(currentService, /* @__PURE__ */ new Set());
77
+ const inlineMatch = trimmed.match(/depends_on:\s*\[([^\]]*)\]/);
78
+ if (inlineMatch) {
79
+ for (const dep of inlineMatch[1].split(",").map((s) => s.trim()).filter(Boolean)) {
80
+ deps.get(currentService).add(dep);
81
+ }
82
+ inDependsOn = false;
83
+ }
84
+ continue;
85
+ }
86
+ if (inDependsOn && indent === 6 && /^[a-zA-Z0-9_-]+:/.test(trimmed)) {
87
+ deps.get(currentService).add(trimmed.replace(/:.*$/, ""));
88
+ continue;
89
+ }
90
+ if (inDependsOn && indent <= dependsOnIndent && !trimmed.startsWith("#")) {
91
+ inDependsOn = false;
92
+ }
93
+ }
94
+ return deps;
95
+ }
96
+ function resolveTransitiveDeps(selected, depsMap) {
97
+ const resolved = new Set(selected);
98
+ const queue = [...selected];
99
+ while (queue.length > 0) {
100
+ const svc = queue.pop();
101
+ const deps = depsMap.get(svc);
102
+ if (!deps) continue;
103
+ for (const dep of deps) {
104
+ if (!resolved.has(dep)) {
105
+ resolved.add(dep);
106
+ queue.push(dep);
107
+ }
108
+ }
109
+ }
110
+ return resolved;
111
+ }
112
+ function filterServicesBySelection(release, selection, composeRaw) {
51
113
  if (!selection) return release;
52
114
  const selected = new Set(selection.selectedServices);
115
+ if (composeRaw) {
116
+ const depsMap = parseComposeDependsOn(composeRaw);
117
+ const composeNames = /* @__PURE__ */ new Set();
118
+ for (const [name, service] of Object.entries(release.services)) {
119
+ if (selected.has(name) || selected.has(service.composeService ?? name) || service.required) {
120
+ composeNames.add(service.composeService ?? name);
121
+ }
122
+ }
123
+ const closedComposeNames = resolveTransitiveDeps(composeNames, depsMap);
124
+ for (const [name, service] of Object.entries(release.services)) {
125
+ if (closedComposeNames.has(service.composeService ?? name)) {
126
+ selected.add(name);
127
+ }
128
+ }
129
+ }
53
130
  const filteredServices = {};
54
131
  for (const [name, service] of Object.entries(release.services)) {
55
132
  if (service.required) {
@@ -543,11 +620,11 @@ function detectMissingRequiredEnvVars(composeRaw, envRaw) {
543
620
  }
544
621
  return { derived, unresolvable };
545
622
  }
546
- function createStackUpdatePlan(manifest, envRaw, targetVersion, serviceNames, selection) {
623
+ function createStackUpdatePlan(manifest, envRaw, targetVersion, serviceNames, selection, composeRaw) {
547
624
  const version = targetVersion ?? manifest.latest;
548
625
  const manifestRelease = manifest.stacks[version];
549
626
  if (!manifestRelease) throw new Error(`Stack version ${version} not found in manifest`);
550
- const selectedRelease = filterServicesBySelection(manifestRelease, selection);
627
+ const selectedRelease = filterServicesBySelection(manifestRelease, selection, composeRaw);
551
628
  const release = serviceNames && serviceNames.length > 0 ? cloneReleaseWithServices(selectedRelease, serviceNames) : selectedRelease;
552
629
  const env = parseEnv(envRaw);
553
630
  const changes = [];
@@ -1593,12 +1670,12 @@ async function runStackUpdate(options) {
1593
1670
  if (options.resume && resumeServices.length === 0) throw new Error("Cannot resume stack update: no incomplete services found in lock file");
1594
1671
  const scopedServiceNames = options.serviceName ? [options.serviceName] : resumeServices;
1595
1672
  const effectiveTargetVersion = options.targetVersion ?? resumeLock?.stackVersion;
1596
- const plan = createStackUpdatePlan(manifest, envRaw, effectiveTargetVersion, scopedServiceNames, serviceSelection);
1597
- const fullTargetPlan = scopedServiceNames.length > 0 ? createStackUpdatePlan(manifest, envRaw, effectiveTargetVersion, void 0, serviceSelection) : plan;
1673
+ const composeRaw = readFileSync(options.composeFile, "utf8");
1674
+ const plan = createStackUpdatePlan(manifest, envRaw, effectiveTargetVersion, scopedServiceNames, serviceSelection, composeRaw);
1675
+ const fullTargetPlan = scopedServiceNames.length > 0 ? createStackUpdatePlan(manifest, envRaw, effectiveTargetVersion, void 0, serviceSelection, composeRaw) : plan;
1598
1676
  assertBreakingChangesAllowed(plan, options.allowedBreakingChangeIds ?? []);
1599
1677
  assertDeploymentScopeAllowed(plan, options.deploymentPersona ?? "customer");
1600
1678
  const plannedEnvRaw = patchEnv(envRaw, Object.fromEntries(plan.changes.map((c) => [c.key, c.after])));
1601
- const composeRaw = readFileSync(options.composeFile, "utf8");
1602
1679
  assertProductionDeployGate(plan, plannedEnvRaw, composeRaw, {
1603
1680
  breakGlassReason: options.breakGlassReason,
1604
1681
  breakGlassAuditFile: options.breakGlassAuditFile,
@@ -2523,6 +2600,8 @@ export {
2523
2600
  serviceSelectionPath,
2524
2601
  loadServiceSelection,
2525
2602
  saveServiceSelection,
2603
+ parseComposeDependsOn,
2604
+ resolveTransitiveDeps,
2526
2605
  filterServicesBySelection,
2527
2606
  buildDefaultServiceSelection,
2528
2607
  ProgressReporter,
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": 1,
3
- "generatedAt": "2026-06-22T07:44:55.636Z",
3
+ "generatedAt": "2026-06-23T04:10:46.733Z",
4
4
  "hashes": {
5
5
  "bug-report-worker.js": "de2c15a312082f7dbc40c0cc54401fd09125e55f49bc88243b209a2d0b8cc74c",
6
6
  "codex-stop-task-finalizer.js": "7c2e9ec456c478b8bf87acb66f1c06a5e9a416049fb94deffe83e286832ba4e8",
@@ -28,6 +28,7 @@ import {
28
28
  loadServiceSelection,
29
29
  loadStackManifest,
30
30
  pairMonitorAgent,
31
+ parseComposeDependsOn,
31
32
  parseEnv,
32
33
  parseRequiredEnvRefs,
33
34
  parseStackManifest,
@@ -38,6 +39,7 @@ import {
38
39
  removeDanglingVolumes,
39
40
  resolveServerImageOverride,
40
41
  resolveServiceHealthTimeout,
42
+ resolveTransitiveDeps,
41
43
  rollbackStackUpdate,
42
44
  runReleaseMigrations,
43
45
  runStackUpdate,
@@ -48,7 +50,7 @@ import {
48
50
  verifyReleaseHealth,
49
51
  verifyStackManifestSignature,
50
52
  waitForHttpOk
51
- } from "./chunk-DKHBMIVE.js";
53
+ } from "./chunk-KMIAYKIH.js";
52
54
  import "./chunk-JV225JBX.js";
53
55
  import "./chunk-2EJ636HI.js";
54
56
  import "./chunk-DFIOOK5R.js";
@@ -84,6 +86,7 @@ export {
84
86
  loadServiceSelection,
85
87
  loadStackManifest,
86
88
  pairMonitorAgent,
89
+ parseComposeDependsOn,
87
90
  parseEnv,
88
91
  parseRequiredEnvRefs,
89
92
  parseStackManifest,
@@ -94,6 +97,7 @@ export {
94
97
  removeDanglingVolumes,
95
98
  resolveServerImageOverride,
96
99
  resolveServiceHealthTimeout,
100
+ resolveTransitiveDeps,
97
101
  rollbackStackUpdate,
98
102
  runReleaseMigrations,
99
103
  runStackUpdate,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@askexenow/exe-os",
3
- "version": "0.9.311",
3
+ "version": "0.9.312",
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",
@@ -1,30 +1,26 @@
1
1
  {
2
- "current": "0.9.311",
2
+ "current": "0.9.312",
3
3
  "notes": {
4
- "0.9.311": {
5
- "version": "0.9.311",
6
- "date": "2026-06-22",
7
- "features": [],
8
- "fixes": [],
9
- "security": [],
10
- "other": [
11
- "bump v0.9.311 — CI release gate poll + build-lock fix"
12
- ],
13
- "migration_notes": []
14
- },
15
- "0.9.310": {
16
- "version": "0.9.310",
17
- "date": "2026-06-22",
4
+ "0.9.312": {
5
+ "version": "0.9.312",
6
+ "date": "2026-06-23",
18
7
  "features": [],
19
8
  "fixes": [
9
+ "stop excluding src/ from build context — builder stage needs it for tsup",
10
+ "bypass build-lock.sh in Docker — run tsup directly (no concurrency in container builds)",
11
+ "add bash to Alpine builder (build-lock.sh requires bash, Alpine only has sh)",
12
+ "add util-linux for flock in Alpine builder (build-lock.sh)",
13
+ "3 P0 bugs — health-gate container probe, watchdog starvation threshold, service dep closure (dad93c21, a77bbb7d, 600681b1)",
14
+ "null-safe signup DOM bindings + add .dockerignore (bugs 61184416 P0, d73073b2 P1)",
20
15
  "poll for CI completion in release gate + resilient build-lock.sh (was instant check, always failed on bump commits)",
21
16
  "kill the version-bump reload storm — surface-hash marker + reload debounce",
22
17
  "enforce canonical 4096 daemon heap cap, correct stale 6144 (bug f215433d)",
23
- "fail-closed BYOK env-contract — direct keys only on explicit BYOK (bug df8823d0)",
24
- "erp healthHost localhost not askexe.com (preflight gate)"
18
+ "fail-closed BYOK env-contract — direct keys only on explicit BYOK (bug df8823d0)"
25
19
  ],
26
20
  "security": [],
27
21
  "other": [
22
+ "stack 0.9.25 final — all 4 images fresh (exe-os v0.9.311, gateway v0.9.24, crm v0.9.51, wiki v0.9.26)",
23
+ "bump v0.9.311 — CI release gate poll + build-lock fix",
28
24
  "stack manifest v0.9.25 — 17 bug fixes, gateway v0.9.24 with WhatsApp/CRM/BYOK fixes"
29
25
  ],
30
26
  "migration_notes": []
@@ -289,6 +285,19 @@
289
285
  "bump v0.9.285 — deploy gate image verification"
290
286
  ],
291
287
  "migration_notes": []
288
+ },
289
+ "0.9.299": {
290
+ "version": "0.9.299",
291
+ "date": "2026-06-19",
292
+ "features": [],
293
+ "fixes": [
294
+ "report accurate per-version release notes (bug b69eac42 follow-up — entries no longer mirror the prior version)"
295
+ ],
296
+ "security": [],
297
+ "other": [
298
+ "release v0.9.299 — published after 0.9.298 SQLCipher/boot/SSO/plist wave"
299
+ ],
300
+ "migration_notes": []
292
301
  }
293
302
  }
294
303
  }
@@ -4,58 +4,58 @@
4
4
  "repo": "AskExe/exe-os",
5
5
  "service": "exe-os",
6
6
  "packageName": "@askexenow/exe-os",
7
- "version": "0.9.310",
8
- "image": "ghcr.io/askexe/exe-os:v0.9.310",
7
+ "version": "0.9.312",
8
+ "image": "ghcr.io/askexe/exe-os:v0.9.312",
9
9
  "imageEnv": "EXE_OS_IMAGE_TAG",
10
10
  "components": {
11
11
  "erp": {
12
- "image": "ghcr.io/askexe/exe-erp:v0.9.310",
12
+ "image": "ghcr.io/askexe/exe-erp:v0.9.312",
13
13
  "env": "ERP_IMAGE_TAG",
14
14
  "composeService": "exe-erp",
15
15
  "note": "Bug 790794e8: pinned to v0.2.0-final8 — first ERP image shipping the realtime/socketio entrypoint (exe-erp PR #15). Earlier final3/final7 crash-looped exe-erp-websocket (missing socketio.js)."
16
16
  },
17
17
  "exe-db": {
18
- "image": "pgvector/pgvector:0.8.0-pg16@sha256:a132765ec351c65111b5b675928a3a0515a466a40f97277329db8b8209ad8bc9:v0.9.310",
18
+ "image": "pgvector/pgvector:0.8.0-pg16@sha256:a132765ec351c65111b5b675928a3a0515a466a40f97277329db8b8209ad8bc9:v0.9.312",
19
19
  "env": "EXE_DB_IMAGE",
20
20
  "composeService": "exe-db",
21
21
  "category": "infra",
22
22
  "note": "Bug ee16e7ef: pinned to versioned 0.8.0-pg16 tag (was mutable :pg16)."
23
23
  },
24
24
  "redis": {
25
- "image": "redis:7.4-alpine@sha256:6ab0b6e7381779332f97b8ca76193e45b0756f38d4c0dcda72dbb3c32061ab99:v0.9.310",
25
+ "image": "redis:7.4-alpine@sha256:6ab0b6e7381779332f97b8ca76193e45b0756f38d4c0dcda72dbb3c32061ab99:v0.9.312",
26
26
  "env": "REDIS_IMAGE",
27
27
  "composeService": "redis",
28
28
  "category": "infra",
29
29
  "note": "Bug 4948fc48: compose-pinned infra dep required by CRM, gateway, ERP."
30
30
  },
31
31
  "clickhouse": {
32
- "image": "clickhouse/clickhouse-server:24.8.4.13-alpine@sha256:88a45f9e328549b2579256c46ee38e5c0e25ae58303d9eb6d9c7ed8d6d2bbf3c:v0.9.310",
32
+ "image": "clickhouse/clickhouse-server:24.8.4.13-alpine@sha256:88a45f9e328549b2579256c46ee38e5c0e25ae58303d9eb6d9c7ed8d6d2bbf3c:v0.9.312",
33
33
  "env": "CLICKHOUSE_IMAGE",
34
34
  "composeService": "clickhouse",
35
35
  "category": "infra",
36
36
  "note": "Bug 4948fc48: compose-pinned infra dep required by CRM."
37
37
  },
38
38
  "cloudflared": {
39
- "image": "cloudflare/cloudflared@sha256:ba461b8aa9c042156dbd39c38657fe7431bafa063220eab8d5330a523863da9f:v0.9.310",
39
+ "image": "cloudflare/cloudflared@sha256:ba461b8aa9c042156dbd39c38657fe7431bafa063220eab8d5330a523863da9f:v0.9.312",
40
40
  "composeService": "cloudflared",
41
41
  "category": "infra",
42
42
  "note": "Bug 4948fc48: digest-pinned tunnel — no env override, managed in compose."
43
43
  },
44
44
  "exe-sso-edge": {
45
- "image": "nginx:alpine@sha256:20316569d8f81a160065d7d2a5eeffc7ca97d79022462ee255fd23fa103a6b5c:v0.9.310",
45
+ "image": "nginx:alpine@sha256:20316569d8f81a160065d7d2a5eeffc7ca97d79022462ee255fd23fa103a6b5c:v0.9.312",
46
46
  "composeService": "exe-sso-edge",
47
47
  "category": "infra",
48
48
  "note": "Bug 4948fc48: SSO reverse proxy for CRM/wiki/ERP — uses stock nginx:alpine."
49
49
  },
50
50
  "exe-otel-collector": {
51
- "image": "otel/opentelemetry-collector-contrib:0.114.0@sha256:37fa87091cfaaec7234a27e4e395a40c31c2bfaea97a349a4afef6d9e9681197:v0.9.310",
51
+ "image": "otel/opentelemetry-collector-contrib:0.114.0@sha256:37fa87091cfaaec7234a27e4e395a40c31c2bfaea97a349a4afef6d9e9681197:v0.9.312",
52
52
  "env": "OTEL_COLLECTOR_IMAGE",
53
53
  "composeService": "exe-otel-collector",
54
54
  "category": "infra",
55
55
  "note": "Bug 4948fc48: OTLP collector for traces/metrics/logs."
56
56
  },
57
57
  "gotrue": {
58
- "image": "supabase/gotrue:v2.172.1@sha256:b0dd7aa28dd1f9a8bd31f136c8b912661f701d9b863171e5843cb08f18f49de4:v0.9.310",
58
+ "image": "supabase/gotrue:v2.172.1@sha256:b0dd7aa28dd1f9a8bd31f136c8b912661f701d9b863171e5843cb08f18f49de4:v0.9.312",
59
59
  "composeService": "gotrue",
60
60
  "category": "infra",
61
61
  "note": "Bug 4948fc48: GoTrue auth backend — digest-pinned in compose."
@@ -102,5 +102,5 @@
102
102
  },
103
103
  "deploymentScope": "customer",
104
104
  "highGhostStack": "0.9.9",
105
- "sourceVersion": "0.9.310"
105
+ "sourceVersion": "0.9.312"
106
106
  }