@celilo/cli 2.2.0 → 2.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/package.json +2 -2
  2. package/schemas/system_config.json +5 -0
  3. package/src/ansible/inventory.test.ts +2 -1
  4. package/src/api/sessions.test.ts +2 -1
  5. package/src/cli/backup-rename.test.ts +2 -1
  6. package/src/cli/cli.test.ts +2 -1
  7. package/src/cli/commands/console-get-chain.test.ts +2 -1
  8. package/src/cli/commands/firewall-interface-list.test.ts +2 -1
  9. package/src/cli/commands/module-config.test.ts +2 -1
  10. package/src/cli/commands/module-deploy.ts +8 -2
  11. package/src/cli/commands/module-generate.test.ts +53 -0
  12. package/src/cli/commands/module-generate.ts +31 -26
  13. package/src/cli/commands/module-import-aspect.test.ts +2 -1
  14. package/src/cli/commands/module-import-registry.test.ts +2 -1
  15. package/src/cli/commands/module-operations.test.ts +2 -1
  16. package/src/cli/commands/module-publish.test.ts +5 -12
  17. package/src/cli/commands/module-update.test.ts +6 -5
  18. package/src/cli/commands/module-upgrade.test.ts +15 -0
  19. package/src/cli/commands/module-upgrade.ts +54 -2
  20. package/src/cli/commands/module-verify.test.ts +2 -3
  21. package/src/cli/commands/module-verify.ts +0 -1
  22. package/src/cli/commands/notify-config.test.ts +5 -3
  23. package/src/cli/commands/registry-owner.test.ts +2 -1
  24. package/src/cli/commands/registry-token.test.ts +2 -1
  25. package/src/cli/commands/system-apply-config-equivalence.test.ts +5 -7
  26. package/src/cli/commands/system-config.test.ts +148 -0
  27. package/src/cli/commands/system-config.ts +26 -1
  28. package/src/cli/commands/system-doctor.test.ts +71 -0
  29. package/src/cli/commands/system-doctor.ts +110 -24
  30. package/src/cli/commands/system-init-deprecation.test.ts +6 -3
  31. package/src/cli/commands/system-migrate.test.ts +2 -1
  32. package/src/cli/index.ts +2 -1
  33. package/src/cli/restore-command.test.ts +2 -1
  34. package/src/cli/restore-migration-failure.test.ts +2 -1
  35. package/src/config/paths.test.ts +3 -3
  36. package/src/db/migrate.test.ts +2 -1
  37. package/src/db/migrate.ts +16 -16
  38. package/src/hooks/capability-loader.test.ts +78 -0
  39. package/src/hooks/capability-loader.ts +37 -2
  40. package/src/hooks/executor.test.ts +87 -1
  41. package/src/hooks/executor.ts +57 -21
  42. package/src/hooks/hook-store.test.ts +6 -0
  43. package/src/hooks/hook-trespass.test.ts +17 -7
  44. package/src/hooks/jail.test.ts +61 -2
  45. package/src/hooks/jail.ts +53 -1
  46. package/src/module/packaging/audit.ts +9 -26
  47. package/src/module/packaging/build-paths.test.ts +127 -0
  48. package/src/module/packaging/build-paths.ts +175 -0
  49. package/src/module/packaging/build.test.ts +71 -1
  50. package/src/module/packaging/build.ts +60 -0
  51. package/src/module/packaging/extract.ts +1 -5
  52. package/src/policy/module-script-scan.ts +0 -40
  53. package/src/policy/no-swallowed-refusal.test.ts +9 -10
  54. package/src/services/alerting/ack.test.ts +2 -1
  55. package/src/services/alerting/cadence-migration.test.ts +3 -2
  56. package/src/services/alerting/coverage-source.test.ts +2 -1
  57. package/src/services/alerting/deferral.test.ts +2 -1
  58. package/src/services/alerting/delivery-loop.test.ts +2 -1
  59. package/src/services/alerting/deploy-hooks.test.ts +2 -1
  60. package/src/services/alerting/inbound-poller.test.ts +2 -1
  61. package/src/services/alerting/inbound.test.ts +2 -1
  62. package/src/services/alerting/notification-responder.test.ts +2 -1
  63. package/src/services/alerting/run-monitor.test.ts +2 -1
  64. package/src/services/alerting/store.test.ts +2 -1
  65. package/src/services/alerting/sweep-runner.test.ts +2 -1
  66. package/src/services/alerting/tokens.test.ts +2 -1
  67. package/src/services/aspect-approvals.test.ts +2 -1
  68. package/src/services/aspect-reconcile.test.ts +4 -3
  69. package/src/services/aspect-runner.test.ts +2 -1
  70. package/src/services/audit/module-integrity.test.ts +0 -21
  71. package/src/services/audit/module-integrity.ts +0 -14
  72. package/src/services/backup-age-agreement.test.ts +2 -1
  73. package/src/services/backup-envelope-roundtrip.test.ts +2 -1
  74. package/src/services/backup-in-flight-refusal.test.ts +2 -1
  75. package/src/services/bus-ensure-flow.test.ts +2 -1
  76. package/src/services/bus-interview-park.test.ts +2 -1
  77. package/src/services/bus-secret-flow.test.ts +2 -1
  78. package/src/services/capability-table-rows.test.ts +2 -1
  79. package/src/services/consumer-cleanup.test.ts +3 -2
  80. package/src/services/container-service.test.ts +2 -1
  81. package/src/services/control-plane-bootstrap.test.ts +2 -1
  82. package/src/services/cross-module-read.test.ts +2 -1
  83. package/src/services/deploy-validation.test.ts +3 -2
  84. package/src/services/dns-internal-records.test.ts +3 -2
  85. package/src/services/dns-provider-backfill.test.ts +2 -1
  86. package/src/services/dns-registrations.test.ts +2 -1
  87. package/src/services/ensure-interview.test.ts +3 -2
  88. package/src/services/fleet-checks.test.ts +3 -2
  89. package/src/services/fleet-key.test.ts +3 -2
  90. package/src/services/infrastructure-selector.test.ts +2 -1
  91. package/src/services/infrastructure-variable-resolver.test.ts +2 -1
  92. package/src/services/machine-pool.test.ts +2 -1
  93. package/src/services/module-config.test.ts +2 -1
  94. package/src/services/module-deploy.dns-repoint.test.ts +2 -1
  95. package/src/services/module-deploy.ts +36 -20
  96. package/src/services/module-operations.test.ts +2 -1
  97. package/src/services/module-subscriptions.test.ts +2 -1
  98. package/src/services/port-forwards.test.ts +2 -1
  99. package/src/services/programmatic-responder.aspect.test.ts +2 -1
  100. package/src/services/proxmox-reconcile.test.ts +2 -1
  101. package/src/services/restore-from-file.test.ts +3 -2
  102. package/src/services/restore-preflight.test.ts +2 -1
  103. package/src/services/secret-schema-loader.test.ts +2 -1
  104. package/src/services/ssh-key-manager.test.ts +2 -1
  105. package/src/services/static-content-converge.test.ts +5 -4
  106. package/src/services/static-content-converge.ts +33 -10
  107. package/src/services/system-state-stage.test.ts +2 -1
  108. package/src/services/trusted-sources.test.ts +3 -2
  109. package/src/services/zone-detector.test.ts +2 -1
  110. package/src/test-utils/bus-responder.ts +5 -3
  111. package/src/test-utils/db-path.ts +25 -0
  112. package/src/test-utils/integration.ts +7 -0
  113. package/src/test-utils/module-fixtures.ts +5 -6
  114. package/src/module/packaging/generated-plane.test.ts +0 -79
  115. package/src/module/packaging/generated-plane.ts +0 -134
@@ -226,14 +226,12 @@ describe('recurrence gate: a hook does not swallow a refused framework call', ()
226
226
  );
227
227
  const sites = violations.map((v) => v.file.replace(`${repoRoot()}/`, '')).sort();
228
228
  // Pinned to the exact sites from e2e-suite-recovery task 4.2, as measured
229
- // on 2026-09-07 at on_backup.ts:52 and health-check.ts:73 (a third,
230
- // on-install.ts:69, converted by ce-pvii the same day). A converted site
231
- // drops out and the debt entry must go; a NEW site appearing here is the
232
- // next instance this scan exists to stop.
233
- expect(sites).toEqual([
234
- 'modules/celilo-mgmt/scripts/on_backup.ts',
235
- 'modules/wireguard/scripts/health-check.ts',
236
- ]);
229
+ // on 2026-09-07 at on_backup.ts:52 (a third, on-install.ts:69, converted
230
+ // by ce-pvii the same day, and wireguard's health-check.ts converted by
231
+ // 01575380 the same evening). A converted site drops out and the debt
232
+ // entry must go; a NEW site appearing here is the next instance this scan
233
+ // exists to stop.
234
+ expect(sites).toEqual(['modules/celilo-mgmt/scripts/on_backup.ts']);
237
235
  });
238
236
  });
239
237
 
@@ -259,7 +257,8 @@ describe('recurrence gate: the swallow debt list is honest', () => {
259
257
 
260
258
  test('the debt list is non-trivial (the guard actually reached the entries)', () => {
261
259
  // The list held three entries until ce-pvii converted the on-install.ts
262
- // entry (2026-09-07); two remain, so the guard still proves engagement.
263
- expect(SWALLOWED_REFUSAL_DEBT.length).toBeGreaterThan(1);
260
+ // entry and 01575380 converted wireguard's health-check (both
261
+ // 2026-09-07); one remains, so the guard still proves engagement.
262
+ expect(SWALLOWED_REFUSAL_DEBT.length).toBeGreaterThan(0);
264
263
  });
265
264
  });
@@ -5,6 +5,7 @@ import { join } from 'node:path';
5
5
  import type { DbClient } from '../../db/client';
6
6
  import { type Route, alerts, modules, monitors } from '../../db/schema';
7
7
  import { setupTestDatabaseAt } from '../../test-utils/database';
8
+ import { resetTestDbPath } from '../../test-utils/db-path';
8
9
  import { acknowledgeAlert, findLiveAlertByKey, resolveAlertManually, silenceAlert } from './ack';
9
10
  import { moduleCheckAlertKey } from './keys';
10
11
  import { createPerson, createRoute } from './people';
@@ -79,7 +80,7 @@ describe('ack / silence / resolve', () => {
79
80
 
80
81
  afterEach(() => {
81
82
  db.$client.close();
82
- process.env.CELILO_DB_PATH = undefined;
83
+ resetTestDbPath();
83
84
  try {
84
85
  rmSync(dir, { recursive: true, force: true });
85
86
  } catch {
@@ -16,6 +16,7 @@ import { join } from 'node:path';
16
16
  import { closeDb, getDb } from '../../db/client';
17
17
  import { runMigrations } from '../../db/migrate';
18
18
  import { modules, monitors } from '../../db/schema';
19
+ import { resetTestDbPath } from '../../test-utils/db-path';
19
20
  import { getModuleConfigValue, upsertModuleConfig } from '../module-config';
20
21
  import { migrateMonitorCadences } from './cadence-migration';
21
22
  import { HEALTH_CHECK_INTERVAL_CONFIG_KEY, loadModuleHealthCadences } from './health-cadence';
@@ -66,7 +67,7 @@ describe('migrateMonitorCadences', () => {
66
67
 
67
68
  afterEach(() => {
68
69
  closeDb();
69
- process.env.CELILO_DB_PATH = undefined;
70
+ resetTestDbPath();
70
71
  rmSync(dir, { recursive: true, force: true });
71
72
  });
72
73
 
@@ -132,7 +133,7 @@ describe("a module_hook row's stored cadence is not consulted", () => {
132
133
 
133
134
  afterEach(() => {
134
135
  closeDb();
135
- process.env.CELILO_DB_PATH = undefined;
136
+ resetTestDbPath();
136
137
  rmSync(dir, { recursive: true, force: true });
137
138
  });
138
139
 
@@ -20,6 +20,7 @@ import { join } from 'node:path';
20
20
  import type { DbClient } from '../../db/client';
21
21
  import { modules } from '../../db/schema';
22
22
  import { setupTestDatabaseAt } from '../../test-utils/database';
23
+ import { resetTestDbPath } from '../../test-utils/db-path';
23
24
  import { CONTROL_PLANE_MODULE_ID } from '../deployed-systems';
24
25
  import { loadModuleCoverage } from './coverage-source';
25
26
  import { healthCoverageFailingKeys } from './health-coverage';
@@ -37,7 +38,7 @@ describe('health coverage and the control plane', () => {
37
38
 
38
39
  afterEach(() => {
39
40
  db.$client.close();
40
- process.env.CELILO_DB_PATH = undefined;
41
+ resetTestDbPath();
41
42
  try {
42
43
  rmSync(dir, { recursive: true, force: true });
43
44
  } catch {
@@ -6,6 +6,7 @@ import { eq } from 'drizzle-orm';
6
6
  import type { DbClient } from '../../db/client';
7
7
  import { type Alert, type Route, alerts, modules, monitors } from '../../db/schema';
8
8
  import { setupTestDatabaseAt } from '../../test-utils/database';
9
+ import { resetTestDbPath } from '../../test-utils/db-path';
9
10
  import { moduleCheckAlertKey } from './keys';
10
11
  import { deliverDeferred } from './notifier';
11
12
  import { createPerson, createRoute } from './people';
@@ -80,7 +81,7 @@ describe('quiet-hours deferral', () => {
80
81
 
81
82
  afterEach(() => {
82
83
  db.$client.close();
83
- process.env.CELILO_DB_PATH = undefined;
84
+ resetTestDbPath();
84
85
  try {
85
86
  rmSync(dir, { recursive: true, force: true });
86
87
  } catch {
@@ -21,6 +21,7 @@ import { join } from 'node:path';
21
21
  import type { DbClient } from '../../db/client';
22
22
  import { type Alert, type Route, modules } from '../../db/schema';
23
23
  import { setupTestDatabaseAt } from '../../test-utils/database';
24
+ import { resetTestDbPath } from '../../test-utils/db-path';
24
25
  import type { EscalationStep, RouteForEscalation } from './escalation';
25
26
  import { interpretInbound } from './inbound';
26
27
  import {
@@ -249,7 +250,7 @@ describe('delivery loop against the signal-cli simulator', () => {
249
250
 
250
251
  afterEach(() => {
251
252
  db.$client.close();
252
- process.env.CELILO_DB_PATH = undefined;
253
+ resetTestDbPath();
253
254
  try {
254
255
  rmSync(dir, { recursive: true, force: true });
255
256
  } catch {
@@ -5,6 +5,7 @@ import { join } from 'node:path';
5
5
  import type { DbClient } from '../../db/client';
6
6
  import { modules, monitors } from '../../db/schema';
7
7
  import { setupTestDatabaseAt } from '../../test-utils/database';
8
+ import { resetTestDbPath } from '../../test-utils/db-path';
8
9
  import {
9
10
  closeDeployWindows,
10
11
  ensureMonitorOnDeploy,
@@ -34,7 +35,7 @@ describe('deploy hooks', () => {
34
35
 
35
36
  afterEach(() => {
36
37
  db.$client.close();
37
- process.env.CELILO_DB_PATH = undefined;
38
+ resetTestDbPath();
38
39
  try {
39
40
  rmSync(dir, { recursive: true, force: true });
40
41
  } catch {
@@ -7,6 +7,7 @@ import { eq } from 'drizzle-orm';
7
7
  import type { DbClient } from '../../db/client';
8
8
  import { type Route, alerts, modules, monitors, notificationDeliveries } from '../../db/schema';
9
9
  import { setupTestDatabaseAt } from '../../test-utils/database';
10
+ import { resetTestDbPath } from '../../test-utils/db-path';
10
11
  import {
11
12
  type InboundPollDeps,
12
13
  type TransportReadRecord,
@@ -105,7 +106,7 @@ describe('pollInbound', () => {
105
106
 
106
107
  afterEach(() => {
107
108
  db.$client.close();
108
- process.env.CELILO_DB_PATH = undefined;
109
+ resetTestDbPath();
109
110
  try {
110
111
  rmSync(dir, { recursive: true, force: true });
111
112
  } catch {
@@ -5,6 +5,7 @@ import { join } from 'node:path';
5
5
  import type { DbClient } from '../../db/client';
6
6
  import { type NotificationDelivery, modules, people, routes } from '../../db/schema';
7
7
  import { setupTestDatabaseAt } from '../../test-utils/database';
8
+ import { resetTestDbPath } from '../../test-utils/db-path';
8
9
  import { interpretInbound, parseInbound } from './inbound';
9
10
  import { mintDelivery } from './tokens';
10
11
 
@@ -107,7 +108,7 @@ describe('interpretInbound', () => {
107
108
 
108
109
  afterEach(() => {
109
110
  db.$client.close();
110
- process.env.CELILO_DB_PATH = undefined;
111
+ resetTestDbPath();
111
112
  try {
112
113
  rmSync(dir, { recursive: true, force: true });
113
114
  } catch {
@@ -6,6 +6,7 @@ import { defineEvents, openBus } from '@celilo/event-bus';
6
6
  import type { DbClient } from '../../db/client';
7
7
  import { type Route, modules } from '../../db/schema';
8
8
  import { setupTestDatabaseAt } from '../../test-utils/database';
9
+ import { resetTestDbPath } from '../../test-utils/db-path';
9
10
  import {
10
11
  type NotificationResponderHandle,
11
12
  startNotificationResponder,
@@ -88,7 +89,7 @@ describe('notification responder', () => {
88
89
  handle?.stop();
89
90
  handle = undefined;
90
91
  db.$client.close();
91
- process.env.CELILO_DB_PATH = undefined;
92
+ resetTestDbPath();
92
93
  try {
93
94
  rmSync(dir, { recursive: true, force: true });
94
95
  } catch {
@@ -6,6 +6,7 @@ import { eq } from 'drizzle-orm';
6
6
  import type { DbClient } from '../../db/client';
7
7
  import { type Monitor, alerts, monitorRuns, monitors } from '../../db/schema';
8
8
  import { setupTestDatabaseAt } from '../../test-utils/database';
9
+ import { resetTestDbPath } from '../../test-utils/db-path';
9
10
  import type { HealthCheckResult } from '../health-runner';
10
11
  import { HOOK_JAIL_CHECK, type HookJailState } from './hook-jail';
11
12
  import { moduleAlertKey, moduleCheckAlertKey } from './keys';
@@ -71,7 +72,7 @@ describe('runOneMonitor', () => {
71
72
 
72
73
  afterEach(() => {
73
74
  db.$client.close();
74
- process.env.CELILO_DB_PATH = undefined;
75
+ resetTestDbPath();
75
76
  try {
76
77
  rmSync(dir, { recursive: true, force: true });
77
78
  } catch {
@@ -6,6 +6,7 @@ import { eq } from 'drizzle-orm';
6
6
  import type { DbClient } from '../../db/client';
7
7
  import { alerts, monitors } from '../../db/schema';
8
8
  import { setupTestDatabaseAt } from '../../test-utils/database';
9
+ import { resetTestDbPath } from '../../test-utils/db-path';
9
10
  import { moduleAlertKey, moduleCheckAlertKey } from './keys';
10
11
  import type { ReconcileAction } from './reconcile';
11
12
  import {
@@ -55,7 +56,7 @@ describe('alert store', () => {
55
56
 
56
57
  afterEach(() => {
57
58
  db.$client.close();
58
- process.env.CELILO_DB_PATH = undefined;
59
+ resetTestDbPath();
59
60
  try {
60
61
  rmSync(dir, { recursive: true, force: true });
61
62
  } catch {
@@ -6,6 +6,7 @@ import { eq } from 'drizzle-orm';
6
6
  import type { DbClient } from '../../db/client';
7
7
  import { type Alert, type Monitor, alerts, modules, monitors } from '../../db/schema';
8
8
  import { setupTestDatabaseAt } from '../../test-utils/database';
9
+ import { resetTestDbPath } from '../../test-utils/db-path';
9
10
  import type { HealthCheckResult } from '../health-runner';
10
11
  import { deleteModuleConfig, upsertModuleConfig } from '../module-config';
11
12
  import { HEALTH_CHECK_INTERVAL_CONFIG_KEY, reconcileModuleWatchState } from './health-cadence';
@@ -99,7 +100,7 @@ describe('runSweep', () => {
99
100
 
100
101
  afterEach(() => {
101
102
  db.$client.close();
102
- process.env.CELILO_DB_PATH = undefined;
103
+ resetTestDbPath();
103
104
  try {
104
105
  rmSync(dir, { recursive: true, force: true });
105
106
  } catch {
@@ -5,6 +5,7 @@ import { join } from 'node:path';
5
5
  import type { DbClient } from '../../db/client';
6
6
  import { modules, people, routes } from '../../db/schema';
7
7
  import { setupTestDatabaseAt } from '../../test-utils/database';
8
+ import { resetTestDbPath } from '../../test-utils/db-path';
8
9
  import {
9
10
  consumeDelivery,
10
11
  deliveriesForAlert,
@@ -75,7 +76,7 @@ describe('delivery records', () => {
75
76
 
76
77
  afterEach(() => {
77
78
  db.$client.close();
78
- process.env.CELILO_DB_PATH = undefined;
79
+ resetTestDbPath();
79
80
  try {
80
81
  rmSync(dir, { recursive: true, force: true });
81
82
  } catch {
@@ -6,6 +6,7 @@ import { closeDb, getDb } from '../db/client';
6
6
  import { runMigrations } from '../db/migrate';
7
7
  import { modules } from '../db/schema';
8
8
  import type { BaseModuleAspect } from '../manifest/schema';
9
+ import { resetTestDbPath } from '../test-utils/db-path';
9
10
  import {
10
11
  checkAspectApproval,
11
12
  computeAspectScopeHash,
@@ -44,7 +45,7 @@ describe('aspect-approvals', () => {
44
45
 
45
46
  afterEach(() => {
46
47
  closeDb();
47
- process.env.CELILO_DB_PATH = undefined;
48
+ resetTestDbPath();
48
49
  try {
49
50
  rmSync(dir, { recursive: true, force: true });
50
51
  } catch {
@@ -20,6 +20,7 @@ import { closeDb, getDb } from '../db/client';
20
20
  import { runMigrations } from '../db/migrate';
21
21
  import { type ModuleState, modules } from '../db/schema';
22
22
  import type { BaseModuleAspect } from '../manifest/schema';
23
+ import { resetTestDbPath } from '../test-utils/db-path';
23
24
  import {
24
25
  computeAspectScopeHash,
25
26
  recordAspectApproval,
@@ -159,7 +160,7 @@ describe('reconcileAspectsForSystems', () => {
159
160
 
160
161
  afterEach(() => {
161
162
  closeDb();
162
- process.env.CELILO_DB_PATH = undefined;
163
+ resetTestDbPath();
163
164
  try {
164
165
  rmSync(dir, { recursive: true, force: true });
165
166
  } catch {
@@ -310,7 +311,7 @@ describe('planAspectFanOut onlyHostnames', () => {
310
311
 
311
312
  afterEach(() => {
312
313
  closeDb();
313
- process.env.CELILO_DB_PATH = undefined;
314
+ resetTestDbPath();
314
315
  try {
315
316
  rmSync(dir, { recursive: true, force: true });
316
317
  } catch {
@@ -352,7 +353,7 @@ describe('verifyAspectCoverage', () => {
352
353
 
353
354
  afterEach(() => {
354
355
  closeDb();
355
- process.env.CELILO_DB_PATH = undefined;
356
+ resetTestDbPath();
356
357
  try {
357
358
  rmSync(dir, { recursive: true, force: true });
358
359
  } catch {
@@ -20,6 +20,7 @@ import { closeDb, getDb } from '../db/client';
20
20
  import { runMigrations } from '../db/migrate';
21
21
  import { modules } from '../db/schema';
22
22
  import type { BaseModuleAspect, ModuleManifest } from '../manifest/schema';
23
+ import { resetTestDbPath } from '../test-utils/db-path';
23
24
  import {
24
25
  computeAspectScopeHash,
25
26
  findAspectApproval,
@@ -109,7 +110,7 @@ describe('aspect-runner', () => {
109
110
 
110
111
  afterEach(() => {
111
112
  closeDb();
112
- process.env.CELILO_DB_PATH = undefined;
113
+ resetTestDbPath();
113
114
  try {
114
115
  rmSync(dir, { recursive: true, force: true });
115
116
  } catch {
@@ -82,27 +82,6 @@ describe('auditModuleIntegrity', () => {
82
82
  expect(findings[0]?.details).toContain('scripts/new.ts');
83
83
  });
84
84
 
85
- test('a stale generated project is drift, and says a deploy would ship the wrong bytes', () => {
86
- const findings = auditModuleIntegrity({
87
- results: [
88
- {
89
- ...clean('wireguard-manager'),
90
- success: false,
91
- violations: [
92
- {
93
- type: 'stale-generated',
94
- path: 'ansible/roles/vpn/files/bin',
95
- message: 'Generated project holds different bytes',
96
- },
97
- ],
98
- },
99
- ],
100
- });
101
- expect(findings.map((f) => f.code)).toEqual(['module_generated_stale']);
102
- expect(findings[0]?.severity).toBe('drift');
103
- expect(findings[0]?.remediation).toBe('celilo module generate wireguard-manager');
104
- });
105
-
106
85
  test('host-plane results carry through with the right severity', () => {
107
86
  const findings = auditModuleIntegrity({
108
87
  results: [
@@ -58,20 +58,6 @@ export function auditModuleIntegrity(deps: ModuleIntegrityAuditDeps): DriftFindi
58
58
  });
59
59
  }
60
60
 
61
- const generated = result.violations.filter((v) => v.type === 'stale-generated');
62
- if (generated.length > 0) {
63
- findings.push({
64
- category: 'module_integrity',
65
- severity: 'drift',
66
- code: 'module_generated_stale',
67
- message: `${result.moduleId}: ${generated.length} generated asset(s) do not match the installed module — a deploy would ship the wrong bytes`,
68
- details: generated.map((v) => ` • ${v.path}`).join('\n'),
69
- remediation: `celilo module generate ${result.moduleId}`,
70
- actionable: true,
71
- subject: result.moduleId,
72
- });
73
- }
74
-
75
61
  // File differences are only meaningful once the baseline is trustworthy.
76
62
  // Reporting them under a stale baseline is what made `module verify`
77
63
  // unreadable: 72 violations across two healthy modules, nearly all of them
@@ -18,6 +18,7 @@ import { join } from 'node:path';
18
18
  import { closeDb, getDb } from '../db/client';
19
19
  import { runMigrations } from '../db/migrate';
20
20
  import { backupStorages, backups, modules } from '../db/schema';
21
+ import { resetTestDbPath } from '../test-utils/db-path';
21
22
  import { loadBackupAuditInfo } from './audit/backup-source';
22
23
  import { findBackupEligibleModules } from './backup-create';
23
24
  import { loadBackupHistory } from './backup-metadata';
@@ -79,7 +80,7 @@ describe('backup age: the run path and the audit path read the same column', ()
79
80
 
80
81
  afterEach(() => {
81
82
  closeDb();
82
- process.env.CELILO_DB_PATH = undefined;
83
+ resetTestDbPath();
83
84
  rmSync(dir, { recursive: true, force: true });
84
85
  });
85
86
 
@@ -32,6 +32,7 @@ import { closeDb, getDb } from '../db/client';
32
32
  import { runMigrations } from '../db/migrate';
33
33
  import { backups, systemConfig } from '../db/schema';
34
34
  import { getOrCreateMasterKey } from '../secrets/master-key';
35
+ import { resetTestDbPath } from '../test-utils/db-path';
35
36
  import { decryptFileToFile, encryptFileToFile } from './backup-cipher';
36
37
  import { createSystemStateBackup } from './backup-create';
37
38
  import { MANIFEST_SCHEMA_VERSION, buildManifest, parseManifest } from './backup-manifest';
@@ -64,7 +65,7 @@ describe('backup envelope round-trip', () => {
64
65
 
65
66
  afterEach(() => {
66
67
  closeDb();
67
- process.env.CELILO_DB_PATH = undefined;
68
+ resetTestDbPath();
68
69
  process.env.CELILO_MASTER_KEY_PATH = undefined;
69
70
  try {
70
71
  rmSync(dir, { recursive: true, force: true });
@@ -18,6 +18,7 @@ import { join } from 'node:path';
18
18
  import { closeDb, getDb } from '../db/client';
19
19
  import { runMigrations } from '../db/migrate';
20
20
  import { backups, moduleOperations } from '../db/schema';
21
+ import { resetTestDbPath } from '../test-utils/db-path';
21
22
  import { createModuleBackup, createSystemStateBackup } from './backup-create';
22
23
  import { restoreModuleBackup, restoreSystemStateBackup } from './backup-restore';
23
24
  import { InFlightError } from './module-operations';
@@ -34,7 +35,7 @@ describe('backup/restore in-flight refusal', () => {
34
35
 
35
36
  afterEach(() => {
36
37
  closeDb();
37
- process.env.CELILO_DB_PATH = undefined;
38
+ resetTestDbPath();
38
39
  process.env.CELILO_MASTER_KEY_PATH = undefined;
39
40
  try {
40
41
  rmSync(dir, { recursive: true, force: true });
@@ -27,6 +27,7 @@ import { moduleConfigs, modules, secrets } from '../db/schema';
27
27
  import type { Ensure } from '../manifest/schema';
28
28
  import { decryptSecret } from '../secrets/encryption';
29
29
  import { getOrCreateMasterKey } from '../secrets/master-key';
30
+ import { resetTestDbPath } from '../test-utils/db-path';
30
31
  import type { EnsureRequiredPayload } from './bus-interview';
31
32
  import { interviewForEnsureInputs, writeModuleSecretKey } from './config-interview';
32
33
 
@@ -174,7 +175,7 @@ describe('bus-mediated interviewForEnsureInputs', () => {
174
175
  afterEach(() => {
175
176
  bus.close();
176
177
  rmSync(tempDir, { recursive: true, force: true });
177
- process.env.CELILO_DB_PATH = undefined;
178
+ resetTestDbPath();
178
179
  process.env.EVENT_BUS_DB = undefined;
179
180
  });
180
181
 
@@ -26,6 +26,7 @@ import { type Bus, type BusEvent, defineEvents, openBus } from '@celilo/event-bu
26
26
  import { handleModuleUpdate } from '../cli/commands/module-update';
27
27
  import { getDb } from '../db/client';
28
28
  import { modules } from '../db/schema';
29
+ import { resetTestDbPath } from '../test-utils/db-path';
29
30
  import { RESPONDER_PROBE_EVENT } from './responder-probe';
30
31
 
31
32
  const NO_SCHEMAS = defineEvents({});
@@ -91,7 +92,7 @@ beforeEach(() => {
91
92
  afterEach(() => {
92
93
  server.stop(true);
93
94
  rmSync(dir, { recursive: true, force: true });
94
- process.env.CELILO_DB_PATH = undefined;
95
+ resetTestDbPath();
95
96
  process.env.CELILO_ORIGINAL_CWD = undefined;
96
97
  process.env.EVENT_BUS_DB = undefined;
97
98
  });
@@ -21,6 +21,7 @@ import { type Bus, defineEvents, openBus } from '@celilo/event-bus';
21
21
  import { type DbClient, getDb } from '../db/client';
22
22
  import { modules } from '../db/schema';
23
23
  import { getOrCreateMasterKey } from '../secrets/master-key';
24
+ import { resetTestDbPath } from '../test-utils/db-path';
24
25
  import type { SecretRequiredPayload } from './bus-interview';
25
26
  import {
26
27
  interviewForMissingSecrets,
@@ -154,7 +155,7 @@ describe('bus-mediated interviewForMissingSecrets', () => {
154
155
  afterEach(() => {
155
156
  bus.close();
156
157
  rmSync(tempDir, { recursive: true, force: true });
157
- process.env.CELILO_DB_PATH = undefined;
158
+ resetTestDbPath();
158
159
  process.env.EVENT_BUS_DB = undefined;
159
160
  });
160
161
 
@@ -20,6 +20,7 @@ import { allDeclaredTables } from '@celilo/capabilities';
20
20
  import type { DbClient } from '../db/client';
21
21
  import { dnsInternalRecords, modules, portForwards, trustedSources, webRoutes } from '../db/schema';
22
22
  import { setupTestDatabaseAt } from '../test-utils/database';
23
+ import { resetTestDbPath } from '../test-utils/db-path';
23
24
  import { deleteClaimedRows, planClaimedRowDeletion } from './capability-table-rows';
24
25
 
25
26
  const FW = '192.168.0.254';
@@ -74,7 +75,7 @@ describe('deleteClaimedRows', () => {
74
75
 
75
76
  afterEach(() => {
76
77
  db.$client.close();
77
- process.env.CELILO_DB_PATH = undefined;
78
+ resetTestDbPath();
78
79
  rmSync(dir, { recursive: true, force: true });
79
80
  });
80
81
 
@@ -5,6 +5,7 @@ import { join } from 'node:path';
5
5
  import type { DbClient } from '../db/client';
6
6
  import type { ModuleManifest } from '../manifest/schema';
7
7
  import { setupTestDatabaseAt } from '../test-utils/database';
8
+ import { resetTestDbPath } from '../test-utils/db-path';
8
9
  import {
9
10
  type CleanupTarget,
10
11
  type ProviderRow,
@@ -216,7 +217,7 @@ describe('runConsumerCleanup — the paused skip is reported, not silent', () =>
216
217
  });
217
218
  afterEach(() => {
218
219
  db.$client.close();
219
- process.env.CELILO_DB_PATH = undefined;
220
+ resetTestDbPath();
220
221
  rmSync(dir, { recursive: true, force: true });
221
222
  });
222
223
 
@@ -285,7 +286,7 @@ describe('runConsumerCleanup — dispatch', () => {
285
286
  });
286
287
  afterEach(() => {
287
288
  db.$client.close();
288
- process.env.CELILO_DB_PATH = undefined;
289
+ resetTestDbPath();
289
290
  rmSync(dir, { recursive: true, force: true });
290
291
  });
291
292
 
@@ -10,6 +10,7 @@ import { eq } from 'drizzle-orm';
10
10
  import { closeDb, createDbClient } from '../db/client';
11
11
  import { runMigrations } from '../db/migrate';
12
12
  import { containerServices } from '../db/schema';
13
+ import { resetTestDbPath } from '../test-utils/db-path';
13
14
  import {
14
15
  addContainerService,
15
16
  getContainerService,
@@ -53,7 +54,7 @@ describe('container-service', () => {
53
54
  }
54
55
 
55
56
  // Clear environment variables
56
- process.env.CELILO_DB_PATH = undefined;
57
+ resetTestDbPath();
57
58
  process.env.CELILO_MASTER_KEY_PATH = undefined;
58
59
  });
59
60
 
@@ -17,6 +17,7 @@ import { eq } from 'drizzle-orm';
17
17
  import type { DbClient } from '../db/client';
18
18
  import { capabilities, modules, systemConfig } from '../db/schema';
19
19
  import { setupTestDatabaseAt } from '../test-utils/database';
20
+ import { resetTestDbPath } from '../test-utils/db-path';
20
21
  import {
21
22
  type ControlPlaneBootstrapOptions,
22
23
  bootstrapControlPlane,
@@ -58,7 +59,7 @@ describe('bootstrapControlPlane', () => {
58
59
 
59
60
  afterEach(() => {
60
61
  db.$client.close();
61
- process.env.CELILO_DB_PATH = undefined;
62
+ resetTestDbPath();
62
63
  try {
63
64
  rmSync(dir, { recursive: true, force: true });
64
65
  } catch {
@@ -15,6 +15,7 @@ import { closeDb, getDb } from '../db/client';
15
15
  import { runMigrations } from '../db/migrate';
16
16
  import { modules } from '../db/schema';
17
17
  import type { ModuleManifest } from '../manifest/schema';
18
+ import { resetTestDbPath } from '../test-utils/db-path';
18
19
  import {
19
20
  type CrossModuleIndex,
20
21
  applyCrossModuleWriteRoot,
@@ -70,7 +71,7 @@ describe('materializeCrossModuleRoot', () => {
70
71
 
71
72
  afterEach(() => {
72
73
  closeDb();
73
- process.env.CELILO_DB_PATH = undefined;
74
+ resetTestDbPath();
74
75
  process.env.CELILO_DATA_DIR = undefined;
75
76
  try {
76
77
  rmSync(dir, { recursive: true, force: true });
@@ -21,6 +21,7 @@ import { join } from 'node:path';
21
21
  import { type DbClient, getDb } from '../db/client';
22
22
  import { modules, secrets } from '../db/schema';
23
23
  import type { ModuleManifest } from '../manifest/schema';
24
+ import { resetTestDbPath } from '../test-utils/db-path';
24
25
  import { findMissingSecrets } from './config-interview';
25
26
  import { findMissingBuildArtifacts, findMissingRequiredVariables } from './deploy-validation';
26
27
 
@@ -89,7 +90,7 @@ describe('findMissingRequiredVariables (deploy path)', () => {
89
90
 
90
91
  afterEach(() => {
91
92
  rmSync(tempDir, { recursive: true, force: true });
92
- process.env.CELILO_DB_PATH = undefined;
93
+ resetTestDbPath();
93
94
  });
94
95
 
95
96
  // The bug we're guarding against: the deploy used to drop type +
@@ -210,7 +211,7 @@ describe('findMissingSecrets (shared)', () => {
210
211
 
211
212
  afterEach(() => {
212
213
  rmSync(tempDir, { recursive: true, force: true });
213
- process.env.CELILO_DB_PATH = undefined;
214
+ resetTestDbPath();
214
215
  });
215
216
 
216
217
  test('accepts loose unknown[] declares (manifest read off disk)', async () => {
@@ -8,6 +8,7 @@ import { eq } from 'drizzle-orm';
8
8
  import type { DbClient } from '../db/client';
9
9
  import { dnsInternalRecords, modules } from '../db/schema';
10
10
  import { setupTestDatabaseAt } from '../test-utils/database';
11
+ import { resetTestDbPath } from '../test-utils/db-path';
11
12
  import {
12
13
  listDnsInternalRecords,
13
14
  listViewOverrides,
@@ -42,7 +43,7 @@ describe('dns-internal-records ledger', () => {
42
43
  });
43
44
  afterEach(() => {
44
45
  db.$client.close();
45
- process.env.CELILO_DB_PATH = undefined;
46
+ resetTestDbPath();
46
47
  try {
47
48
  rmSync(dir, { recursive: true, force: true });
48
49
  } catch {
@@ -248,7 +249,7 @@ describe('provider cascade (celilo#1010)', () => {
248
249
 
249
250
  afterEach(() => {
250
251
  db.$client.close();
251
- process.env.CELILO_DB_PATH = undefined;
252
+ resetTestDbPath();
252
253
  rmSync(dir, { recursive: true, force: true });
253
254
  });
254
255