@lumenflow/cli 5.4.0 → 5.7.12

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 (227) hide show
  1. package/README.md +42 -40
  2. package/dist/db-journal-recover.js +400 -0
  3. package/dist/db-journal-recover.js.map +1 -0
  4. package/dist/docs-sync.js +8 -3
  5. package/dist/docs-sync.js.map +1 -1
  6. package/dist/gate-defaults.js +191 -9
  7. package/dist/gate-defaults.js.map +1 -1
  8. package/dist/gate-registry.js.map +1 -1
  9. package/dist/gates/monolithic-file-contention-guard.js +167 -0
  10. package/dist/gates/monolithic-file-contention-guard.js.map +1 -0
  11. package/dist/gates/prod-migration-drift.js +207 -0
  12. package/dist/gates/prod-migration-drift.js.map +1 -0
  13. package/dist/gates/test-over-deletion-guard.js +255 -0
  14. package/dist/gates/test-over-deletion-guard.js.map +1 -0
  15. package/dist/gates-runners.js +401 -2
  16. package/dist/gates-runners.js.map +1 -1
  17. package/dist/gates.js +349 -4
  18. package/dist/gates.js.map +1 -1
  19. package/dist/lumenflow-setup.js +144 -0
  20. package/dist/lumenflow-setup.js.map +1 -0
  21. package/dist/lumenflow-upgrade.js +2 -1
  22. package/dist/lumenflow-upgrade.js.map +1 -1
  23. package/dist/mem-create.js +10 -1
  24. package/dist/mem-create.js.map +1 -1
  25. package/dist/mem-signal.js +21 -4
  26. package/dist/mem-signal.js.map +1 -1
  27. package/dist/metrics-cli.js +19 -2
  28. package/dist/metrics-cli.js.map +1 -1
  29. package/dist/metrics-snapshot.js +25 -2
  30. package/dist/metrics-snapshot.js.map +1 -1
  31. package/dist/orchestrate-initiative.js +28 -3
  32. package/dist/orchestrate-initiative.js.map +1 -1
  33. package/dist/public-manifest.js +17 -0
  34. package/dist/public-manifest.js.map +1 -1
  35. package/dist/release.js +53 -18
  36. package/dist/release.js.map +1 -1
  37. package/dist/wu-done-gates.js +121 -8
  38. package/dist/wu-done-gates.js.map +1 -1
  39. package/dist/wu-done.js +30 -6
  40. package/dist/wu-done.js.map +1 -1
  41. package/dist/wu-edit-operations.js +74 -0
  42. package/dist/wu-edit-operations.js.map +1 -1
  43. package/dist/wu-edit-validators.js +58 -0
  44. package/dist/wu-edit-validators.js.map +1 -1
  45. package/dist/wu-edit.js +106 -4
  46. package/dist/wu-edit.js.map +1 -1
  47. package/dist/wu-prep.js +132 -8
  48. package/dist/wu-prep.js.map +1 -1
  49. package/dist/wu-recover.js +6 -0
  50. package/dist/wu-recover.js.map +1 -1
  51. package/dist/wu-release.js +120 -2
  52. package/dist/wu-release.js.map +1 -1
  53. package/dist/wu-sizing-validation.js +47 -17
  54. package/dist/wu-sizing-validation.js.map +1 -1
  55. package/dist/wu-status.js +33 -0
  56. package/dist/wu-status.js.map +1 -1
  57. package/package.json +13 -11
  58. package/packs/agent-runtime/package.json +1 -1
  59. package/packs/sidekick/package.json +1 -1
  60. package/packs/software-delivery/package.json +1 -1
  61. package/templates/core/AGENTS.md.template +162 -26
  62. package/templates/core/LUMENFLOW.md.template +381 -70
  63. package/templates/core/ai/onboarding/agent-invocation-guide.md.template +0 -5
  64. package/templates/core/ai/onboarding/agent-safety-card.md.template +63 -17
  65. package/templates/core/ai/onboarding/initiative-orchestration.md.template +4 -0
  66. package/templates/core/ai/onboarding/release-process.md.template +7 -7
  67. package/templates/core/ai/onboarding/vendor-support.md.template +74 -10
  68. package/templates/vendors/claude/.claude/skills/frontend-design/SKILL.md.template +1 -1
  69. package/templates/vendors/claude/.claude/skills/wu-lifecycle/SKILL.md.template +28 -0
  70. package/packs/agent-runtime/agent-heartbeat.ts +0 -163
  71. package/packs/agent-runtime/auto-session-integration.ts +0 -888
  72. package/packs/agent-runtime/capability-factory.ts +0 -104
  73. package/packs/agent-runtime/constants.ts +0 -21
  74. package/packs/agent-runtime/delegation-registry-schema.ts +0 -220
  75. package/packs/agent-runtime/delegation-registry-store.ts +0 -269
  76. package/packs/agent-runtime/delegation-tree.ts +0 -328
  77. package/packs/agent-runtime/index.ts +0 -20
  78. package/packs/agent-runtime/manifest.ts +0 -348
  79. package/packs/agent-runtime/memory-coordination-contract.ts +0 -86
  80. package/packs/agent-runtime/orchestration.ts +0 -2027
  81. package/packs/agent-runtime/pack-registration.ts +0 -110
  82. package/packs/agent-runtime/policy-factory.ts +0 -165
  83. package/packs/agent-runtime/remote-controls/index.ts +0 -7
  84. package/packs/agent-runtime/remote-controls/operations.ts +0 -405
  85. package/packs/agent-runtime/remote-controls/port.ts +0 -48
  86. package/packs/agent-runtime/remote-controls/state-store.ts +0 -258
  87. package/packs/agent-runtime/remote-controls/types.ts +0 -105
  88. package/packs/agent-runtime/session-schema.ts +0 -467
  89. package/packs/agent-runtime/tool-impl/agent-turn-tools.ts +0 -793
  90. package/packs/agent-runtime/tool-impl/index.ts +0 -6
  91. package/packs/agent-runtime/tool-impl/provider-adapters.ts +0 -1245
  92. package/packs/agent-runtime/tool-impl/remote-controls.mock.ts +0 -256
  93. package/packs/agent-runtime/tool-impl/remote-controls.ts +0 -273
  94. package/packs/agent-runtime/tools/index.ts +0 -4
  95. package/packs/agent-runtime/tools/types.ts +0 -47
  96. package/packs/agent-runtime/turn-lifecycle-events.ts +0 -590
  97. package/packs/agent-runtime/types.ts +0 -128
  98. package/packs/agent-runtime/vitest.config.ts +0 -11
  99. package/packs/sidekick/channel-ingress.ts +0 -137
  100. package/packs/sidekick/constants.ts +0 -10
  101. package/packs/sidekick/index.ts +0 -8
  102. package/packs/sidekick/manifest-schema.ts +0 -49
  103. package/packs/sidekick/manifest.ts +0 -512
  104. package/packs/sidekick/pack-registration.ts +0 -110
  105. package/packs/sidekick/policy-factory.ts +0 -38
  106. package/packs/sidekick/sidekick-events.ts +0 -694
  107. package/packs/sidekick/src/adapters/cloud-queue.ts +0 -101
  108. package/packs/sidekick/src/adapters/control-plane-bridge.adapter.ts +0 -386
  109. package/packs/sidekick/src/adapters/filesystem-bridge.adapter.ts +0 -228
  110. package/packs/sidekick/src/domain/channel.types.ts +0 -64
  111. package/packs/sidekick/src/ports/channel-bridge.port.ts +0 -92
  112. package/packs/sidekick/src/routines/commit.ts +0 -74
  113. package/packs/sidekick/tool-impl/channel-tools.ts +0 -577
  114. package/packs/sidekick/tool-impl/channel-transports.ts +0 -75
  115. package/packs/sidekick/tool-impl/index.ts +0 -29
  116. package/packs/sidekick/tool-impl/memory-tools.ts +0 -290
  117. package/packs/sidekick/tool-impl/routine-commit.ts +0 -102
  118. package/packs/sidekick/tool-impl/routine-tools.ts +0 -440
  119. package/packs/sidekick/tool-impl/runtime-context.ts +0 -28
  120. package/packs/sidekick/tool-impl/shared.ts +0 -125
  121. package/packs/sidekick/tool-impl/storage.ts +0 -325
  122. package/packs/sidekick/tool-impl/system-tools.ts +0 -160
  123. package/packs/sidekick/tool-impl/task-tools.ts +0 -506
  124. package/packs/sidekick/tools/channel-tools.ts +0 -53
  125. package/packs/sidekick/tools/index.ts +0 -9
  126. package/packs/sidekick/tools/memory-tools.ts +0 -53
  127. package/packs/sidekick/tools/routine-tools.ts +0 -53
  128. package/packs/sidekick/tools/system-tools.ts +0 -47
  129. package/packs/sidekick/tools/task-tools.ts +0 -61
  130. package/packs/sidekick/tools/types.ts +0 -57
  131. package/packs/sidekick/vitest.config.ts +0 -11
  132. package/packs/software-delivery/constants.ts +0 -10
  133. package/packs/software-delivery/extensions.ts +0 -140
  134. package/packs/software-delivery/gate-policies.ts +0 -134
  135. package/packs/software-delivery/index.ts +0 -8
  136. package/packs/software-delivery/manifest-schema.ts +0 -268
  137. package/packs/software-delivery/manifest.ts +0 -657
  138. package/packs/software-delivery/pack-registration.ts +0 -113
  139. package/packs/software-delivery/src/commands/index.ts +0 -5
  140. package/packs/software-delivery/src/config/delivery-review-contract.ts +0 -256
  141. package/packs/software-delivery/src/config/env-accessors.ts +0 -66
  142. package/packs/software-delivery/src/config/index.ts +0 -8
  143. package/packs/software-delivery/src/config/normalize-config-keys.ts +0 -9
  144. package/packs/software-delivery/src/config/schemas/lumenflow-config-schema-types.ts +0 -460
  145. package/packs/software-delivery/src/config/workspace-reader.ts +0 -375
  146. package/packs/software-delivery/src/constants/backlog-patterns.ts +0 -31
  147. package/packs/software-delivery/src/constants/client-ids.ts +0 -19
  148. package/packs/software-delivery/src/constants/config-contract.ts +0 -7
  149. package/packs/software-delivery/src/constants/docs-layout-presets.ts +0 -50
  150. package/packs/software-delivery/src/constants/duration-constants.ts +0 -20
  151. package/packs/software-delivery/src/constants/gate-constants.ts +0 -32
  152. package/packs/software-delivery/src/constants/index.ts +0 -29
  153. package/packs/software-delivery/src/constants/lock-constants.ts +0 -35
  154. package/packs/software-delivery/src/constants/object-guards.ts +0 -12
  155. package/packs/software-delivery/src/constants/section-headings.ts +0 -107
  156. package/packs/software-delivery/src/constants/wu-cli-constants.ts +0 -488
  157. package/packs/software-delivery/src/constants/wu-domain-constants.ts +0 -466
  158. package/packs/software-delivery/src/constants/wu-git-constants.ts +0 -7
  159. package/packs/software-delivery/src/constants/wu-id-format.ts +0 -327
  160. package/packs/software-delivery/src/constants/wu-paths-constants.ts +0 -384
  161. package/packs/software-delivery/src/constants/wu-statuses.ts +0 -287
  162. package/packs/software-delivery/src/constants/wu-type-helpers.ts +0 -67
  163. package/packs/software-delivery/src/constants/wu-ui-constants.ts +0 -267
  164. package/packs/software-delivery/src/constants/wu-validation-constants.ts +0 -73
  165. package/packs/software-delivery/src/domain/index.ts +0 -5
  166. package/packs/software-delivery/src/domain/orchestration.constants.ts +0 -166
  167. package/packs/software-delivery/src/domain/orchestration.schemas.ts +0 -238
  168. package/packs/software-delivery/src/domain/orchestration.types.ts +0 -176
  169. package/packs/software-delivery/src/methodology/incremental-test.ts +0 -122
  170. package/packs/software-delivery/src/methodology/index.ts +0 -6
  171. package/packs/software-delivery/src/methodology/manual-test-validator.ts +0 -292
  172. package/packs/software-delivery/src/policy/coverage-gate.ts +0 -270
  173. package/packs/software-delivery/src/policy/gates-agent-mode.ts +0 -223
  174. package/packs/software-delivery/src/policy/gates-config-internal.ts +0 -121
  175. package/packs/software-delivery/src/policy/gates-config.ts +0 -300
  176. package/packs/software-delivery/src/policy/gates-coverage.ts +0 -356
  177. package/packs/software-delivery/src/policy/gates-presets.ts +0 -134
  178. package/packs/software-delivery/src/policy/gates-schemas.ts +0 -173
  179. package/packs/software-delivery/src/policy/index.ts +0 -22
  180. package/packs/software-delivery/src/policy/package-manager-resolver.ts +0 -319
  181. package/packs/software-delivery/src/policy/resolve-policy.ts +0 -601
  182. package/packs/software-delivery/src/ports/config.ports.ts +0 -90
  183. package/packs/software-delivery/src/ports/dashboard-renderer.port.ts +0 -125
  184. package/packs/software-delivery/src/ports/index.ts +0 -10
  185. package/packs/software-delivery/src/ports/sync-validator.ports.ts +0 -59
  186. package/packs/software-delivery/src/ports/wu-helpers.ports.ts +0 -168
  187. package/packs/software-delivery/src/ports/wu-state.ports.ts +0 -241
  188. package/packs/software-delivery/src/primitives/index.ts +0 -5
  189. package/packs/software-delivery/src/runtime/index.ts +0 -6
  190. package/packs/software-delivery/src/runtime/work-classifier.ts +0 -561
  191. package/packs/software-delivery/src/sandbox/index.ts +0 -10
  192. package/packs/software-delivery/src/sandbox/sandbox-allowlist.ts +0 -118
  193. package/packs/software-delivery/src/sandbox/sandbox-backend-linux.ts +0 -88
  194. package/packs/software-delivery/src/sandbox/sandbox-backend-macos.ts +0 -154
  195. package/packs/software-delivery/src/sandbox/sandbox-backend-windows.ts +0 -47
  196. package/packs/software-delivery/src/sandbox/sandbox-profile.ts +0 -153
  197. package/packs/software-delivery/src/schemas/index.ts +0 -5
  198. package/packs/software-delivery/src/state/date-utils.ts +0 -158
  199. package/packs/software-delivery/src/state/index.ts +0 -15
  200. package/packs/software-delivery/src/state/state-machine.ts +0 -119
  201. package/packs/software-delivery/src/state/wu-doc-types.ts +0 -51
  202. package/packs/software-delivery/src/state/wu-paths.ts +0 -381
  203. package/packs/software-delivery/src/state/wu-schema.ts +0 -1139
  204. package/packs/software-delivery/src/state/wu-state-schema.ts +0 -255
  205. package/packs/software-delivery/src/state/wu-yaml.ts +0 -338
  206. package/packs/software-delivery/tool-impl/agent-tools.ts +0 -263
  207. package/packs/software-delivery/tool-impl/delegation-tools.ts +0 -66
  208. package/packs/software-delivery/tool-impl/flow-metrics-tools.ts +0 -219
  209. package/packs/software-delivery/tool-impl/git-runner.ts +0 -113
  210. package/packs/software-delivery/tool-impl/git-tools.ts +0 -316
  211. package/packs/software-delivery/tool-impl/index.ts +0 -15
  212. package/packs/software-delivery/tool-impl/initiative-orchestration-tools.ts +0 -720
  213. package/packs/software-delivery/tool-impl/lane-lock.ts +0 -246
  214. package/packs/software-delivery/tool-impl/memory-tools.ts +0 -470
  215. package/packs/software-delivery/tool-impl/pending-runtime-tools.ts +0 -21
  216. package/packs/software-delivery/tool-impl/runtime-cli-adapter.ts +0 -329
  217. package/packs/software-delivery/tool-impl/runtime-native-tools.ts +0 -687
  218. package/packs/software-delivery/tool-impl/worker-loader.ts +0 -52
  219. package/packs/software-delivery/tool-impl/worktree-tools.ts +0 -46
  220. package/packs/software-delivery/tool-impl/wu-lifecycle-tools.ts +0 -807
  221. package/packs/software-delivery/tools/delegation-tools.ts +0 -23
  222. package/packs/software-delivery/tools/git-tools.ts +0 -55
  223. package/packs/software-delivery/tools/index.ts +0 -8
  224. package/packs/software-delivery/tools/lane-lock-tool.ts +0 -37
  225. package/packs/software-delivery/tools/types.ts +0 -71
  226. package/packs/software-delivery/tools/worktree-tools.ts +0 -49
  227. package/packs/software-delivery/vitest.config.ts +0 -11
@@ -0,0 +1,207 @@
1
+ // Copyright (c) 2026 Hellmai Ltd
2
+ // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
3
+ /**
4
+ * prod-migration-drift gate (WU-2944, INIT-069 Item 14)
5
+ *
6
+ * Detects when the production database is N+ migrations behind the canonical
7
+ * migrations/ directory on main. Driver: cloud INIT-105 item 14 — prod
8
+ * silently accumulated 7+ migrations of drift before any human noticed; no
9
+ * automated detection caught it.
10
+ *
11
+ * Contract (INIT-068 / WU-2926):
12
+ * - checkApplicability: 'applicable' iff repo has migrations/ AND
13
+ * `software_delivery.gates.overrides.prod-migration-drift.connection_string_env_var`
14
+ * is configured. Default behaviour for repos that have not opted in is
15
+ * 'not-applicable' (clean opt-out — no DB credentials required).
16
+ * - checkPreconditions: 'satisfied' iff the configured env var resolves AND
17
+ * the prod DB is reachable (probe). Otherwise 'missing'.
18
+ * - prereq_strategy: 'auto-skip' (advisory; non-prod / disconnected runs
19
+ * auto-skip rather than block).
20
+ * - skippable_default: true (per-repo override surface to make safety-critical).
21
+ *
22
+ * NOT registered into local `wu:prep` by default — most repos won't have
23
+ * PROD_DATABASE_URL configured locally. The gate auto-skips not-applicable
24
+ * until the override is set, so adding it to the registry is safe.
25
+ *
26
+ * Per-repo override surface:
27
+ * software_delivery.gates.overrides.prod-migration-drift.connection_string_env_var=PROD_DATABASE_URL
28
+ * software_delivery.gates.overrides.prod-migration-drift.threshold=5
29
+ * software_delivery.gates.overrides.prod-migration-drift.skippable=false # tighten
30
+ *
31
+ * @module gates/prod-migration-drift
32
+ */
33
+ import { existsSync, readdirSync, statSync } from 'node:fs';
34
+ import path from 'node:path';
35
+ import { GATE_NAMES } from '@lumenflow/core/wu-constants';
36
+ import { getGatesSection } from '@lumenflow/packs-software-delivery/policy/gates-config-internal';
37
+ import { makeGateLogger } from '../gates-utils.js';
38
+ /** WU-2944: default drift threshold (failed when drift > threshold). */
39
+ export const DEFAULT_DRIFT_THRESHOLD = 5;
40
+ /** WU-2944: canonical override key for `pnpm config:set`. */
41
+ export const PROD_MIGRATION_DRIFT_OVERRIDE_KEY = 'software_delivery.gates.overrides.prod-migration-drift';
42
+ const MIGRATIONS_DIRNAME = 'migrations';
43
+ const SQL_FILE_PATTERN = /\.sql$/i;
44
+ /**
45
+ * Compute the set of migrations present on main but not applied to prod.
46
+ *
47
+ * Pure function: deterministic, no IO. The "drift" we surface is one-directional
48
+ * (main → prod). Migrations applied on prod that no longer exist on main are
49
+ * a separate concern (rollback / stale snapshot) and not flagged here.
50
+ */
51
+ export function detectMigrationDrift(input) {
52
+ const applied = new Set(input.appliedMigrations);
53
+ const missingFromProd = input.mainMigrations.filter((m) => !applied.has(m));
54
+ const driftCount = missingFromProd.length;
55
+ return {
56
+ missingFromProd,
57
+ driftCount,
58
+ failed: driftCount > input.threshold,
59
+ };
60
+ }
61
+ /**
62
+ * Read the canonical migrations/ directory and return `.sql` filenames in
63
+ * lexicographic order. Returns `[]` when the directory does not exist (which
64
+ * is also the clean opt-out signal for `checkApplicability`).
65
+ */
66
+ export function readMigrationsDir(cwd) {
67
+ const dir = path.join(cwd, MIGRATIONS_DIRNAME);
68
+ try {
69
+ if (!existsSync(dir))
70
+ return [];
71
+ if (!statSync(dir).isDirectory())
72
+ return [];
73
+ return readdirSync(dir)
74
+ .filter((f) => SQL_FILE_PATTERN.test(f))
75
+ .sort();
76
+ }
77
+ catch {
78
+ return [];
79
+ }
80
+ }
81
+ /**
82
+ * Read `software_delivery.gates.overrides.prod-migration-drift` from
83
+ * workspace.yaml. Returns undefined when missing or malformed so callers
84
+ * fall through to "not-applicable" (clean opt-out).
85
+ */
86
+ function readOverride(cwd) {
87
+ try {
88
+ const section = getGatesSection(cwd);
89
+ const raw = section?.overrides?.[GATE_NAMES.PROD_MIGRATION_DRIFT];
90
+ if (raw && typeof raw === 'object' && !Array.isArray(raw)) {
91
+ return raw;
92
+ }
93
+ return undefined;
94
+ }
95
+ catch {
96
+ return undefined;
97
+ }
98
+ }
99
+ function resolveThreshold(override) {
100
+ const t = override?.threshold;
101
+ if (typeof t === 'number' && Number.isInteger(t) && t >= 0)
102
+ return t;
103
+ return DEFAULT_DRIFT_THRESHOLD;
104
+ }
105
+ /**
106
+ * Default probe: refuses to attempt a real DB connection from the gate
107
+ * runtime — the gate intentionally ships without a Postgres driver dependency
108
+ * to keep `@lumenflow/cli` slim. Real prod-drift detection happens in CI
109
+ * workflows (or via a project-supplied probe), not on every local `wu:prep`.
110
+ *
111
+ * In CI, the gate is invoked with a probe injected via
112
+ * `ctx.__prodDriftProbe` (see scheduled prod-drift workflow). When no probe
113
+ * is supplied, we report unreachable so the runtime cleanly auto-skips
114
+ * (`prereq_strategy: 'auto-skip'`) rather than fabricating a passing result.
115
+ */
116
+ const defaultProbe = () => Promise.resolve({ reachable: false, applied: [] });
117
+ function readProbe(ctx) {
118
+ const ext = ctx;
119
+ return ext.__prodDriftProbe ?? defaultProbe;
120
+ }
121
+ // ─────────────────────────────────────────────────────────────────────────
122
+ // Gate definition (INIT-068 contract)
123
+ // ─────────────────────────────────────────────────────────────────────────
124
+ async function checkApplicability(ctx) {
125
+ const cwd = ctx.cwd ?? process.cwd();
126
+ const override = readOverride(cwd);
127
+ if (!override?.connection_string_env_var)
128
+ return 'not-applicable';
129
+ if (readMigrationsDir(cwd).length === 0)
130
+ return 'not-applicable';
131
+ return 'applicable';
132
+ }
133
+ async function checkPreconditions(ctx) {
134
+ const cwd = ctx.cwd ?? process.cwd();
135
+ const override = readOverride(cwd);
136
+ const envVar = override?.connection_string_env_var;
137
+ if (!envVar)
138
+ return 'missing';
139
+ const connectionString = process.env[envVar];
140
+ if (!connectionString || connectionString.length === 0)
141
+ return 'missing';
142
+ // Probe reachability. Default probe always reports unreachable so missing
143
+ // CI/probe injection auto-skips cleanly under `prereq_strategy: 'auto-skip'`.
144
+ const probe = readProbe(ctx);
145
+ try {
146
+ const result = await probe({ connectionString, cwd });
147
+ return result.reachable ? 'satisfied' : 'missing';
148
+ }
149
+ catch {
150
+ return 'missing';
151
+ }
152
+ }
153
+ async function run(ctx) {
154
+ const start = Date.now();
155
+ const cwd = ctx.cwd ?? process.cwd();
156
+ const logLine = makeGateLogger({
157
+ agentLog: ctx.agentLog ?? null,
158
+ useAgentMode: ctx.useAgentMode,
159
+ });
160
+ logLine('\n> prod-migration-drift check\n');
161
+ const override = readOverride(cwd);
162
+ const envVar = override?.connection_string_env_var;
163
+ if (!envVar) {
164
+ // checkApplicability should have prevented this; defensive auto-pass.
165
+ logLine('ℹ️ No prod-migration-drift override configured; skipping.');
166
+ return { ok: true, duration: Date.now() - start };
167
+ }
168
+ const connectionString = process.env[envVar];
169
+ if (!connectionString) {
170
+ logLine(`ℹ️ Env var ${envVar} not set; skipping (auto-skip).`);
171
+ return { ok: true, duration: Date.now() - start };
172
+ }
173
+ const mainMigrations = readMigrationsDir(cwd);
174
+ const probe = readProbe(ctx);
175
+ const probeResult = await probe({ connectionString, cwd });
176
+ if (!probeResult.reachable) {
177
+ logLine(`⚠️ Prod DB unreachable via ${envVar}; skipping (auto-skip).`);
178
+ return { ok: true, duration: Date.now() - start };
179
+ }
180
+ const threshold = resolveThreshold(override);
181
+ const drift = detectMigrationDrift({
182
+ mainMigrations,
183
+ appliedMigrations: probeResult.applied,
184
+ threshold,
185
+ });
186
+ if (!drift.failed) {
187
+ logLine(`prod-migration-drift check passed (drift=${drift.driftCount}, threshold=${threshold}).`);
188
+ return { ok: true, duration: Date.now() - start };
189
+ }
190
+ logLine(`❌ prod-migration-drift: prod is ${drift.driftCount} migration(s) behind main (threshold=${threshold}).`);
191
+ for (const m of drift.missingFromProd) {
192
+ logLine(` - missing from prod: ${m}`);
193
+ }
194
+ logLine('Hint: review the migration backlog before deploying. Apply migrations to prod incrementally, ' +
195
+ 'or split deploys to land smaller migration sequences. To raise/lower the threshold per repo: ' +
196
+ `\`pnpm config:set ${PROD_MIGRATION_DRIFT_OVERRIDE_KEY}.threshold=<n>\`.`);
197
+ return { ok: false, duration: Date.now() - start };
198
+ }
199
+ export const prodMigrationDriftGate = {
200
+ name: GATE_NAMES.PROD_MIGRATION_DRIFT,
201
+ run,
202
+ skippable_default: true,
203
+ prereq_strategy: 'auto-skip',
204
+ checkApplicability,
205
+ checkPreconditions,
206
+ };
207
+ //# sourceMappingURL=prod-migration-drift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prod-migration-drift.js","sourceRoot":"","sources":["../../src/gates/prod-migration-drift.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,255 @@
1
+ // Copyright (c) 2026 Hellmai Ltd
2
+ // SPDX-License-Identifier: LicenseRef-LumenFlow-Proprietary
3
+ /**
4
+ * test-over-deletion-guard (WU-2943, INIT-069 Item 12)
5
+ *
6
+ * Heuristic gate riding the INIT-068 GateDefinition contract. When `wu:prep`
7
+ * runs, scan deleted `.test.ts` / `.test.tsx` files; parse top-level
8
+ * `describe()` / `describe.each()` string literals; flag any whose described
9
+ * symbols are NOT inside the current WU's `code_paths`.
10
+ *
11
+ * Driver: cloud INIT-105 item 12. WU-1502 dropped a substrate and incidentally
12
+ * over-deleted tests covering other concerns. Codex flagged it during review.
13
+ *
14
+ * Contract (INIT-068 / WU-2926):
15
+ * - checkApplicability: 'applicable' iff diff includes deleted .test.ts(x)
16
+ * - checkPreconditions: 'satisfied' (no env prereqs)
17
+ * - prereq_strategy: 'auto-skip'
18
+ * - skippable_default: true (advisory — agents can --skip-gate when intentional)
19
+ * - Per-repo configurable via software_delivery.gates.overrides.<gate_id>
20
+ *
21
+ * @module gates/test-over-deletion-guard
22
+ */
23
+ import { existsSync } from 'node:fs';
24
+ import path from 'node:path';
25
+ import { GATE_NAMES } from '@lumenflow/core/wu-constants';
26
+ import { createGitForPath } from '@lumenflow/core/git-adapter';
27
+ import { getCurrentWU } from '@lumenflow/core/telemetry';
28
+ import { createWuPaths } from '@lumenflow/core/wu-paths';
29
+ import { readWURaw } from '@lumenflow/core/wu-yaml';
30
+ import { resolveIntegrationTargetRef } from '@lumenflow/core/integration-target';
31
+ import { makeGateLogger } from '../gates-utils.js';
32
+ const TEST_FILE_PATTERN = /\.test\.tsx?$/;
33
+ // Bounded literal regex: the inner class explicitly excludes the matching
34
+ // quote, the `[^)]{0,256}` chunk is bounded, and the outer engine is RE2-safe
35
+ // (no nested quantifiers over the same captured class). Suppresses
36
+ // security/detect-unsafe-regex which heuristically flags any class.
37
+ // eslint-disable-next-line security/detect-unsafe-regex
38
+ const DESCRIBE_LITERAL_RE = /\bdescribe(?:\.each\s*\([^)]{0,256}\))?\s*\(\s*(['"`])([^'"`]+)\1/g;
39
+ // ─────────────────────────────────────────────────────────────────────────
40
+ // Pure helpers (exported for tests)
41
+ // ─────────────────────────────────────────────────────────────────────────
42
+ /**
43
+ * Parse top-level describe()/describe.each() string literals from test source.
44
+ *
45
+ * Simple regex parser (no AST) per the WU-2943 spec: "via simple AST or regex".
46
+ * Captures the first string-literal argument of `describe(...)` and
47
+ * `describe.each(...)(...)`.
48
+ */
49
+ export function parseDescribedSymbols(source) {
50
+ const out = new Set();
51
+ for (const match of source.matchAll(DESCRIBE_LITERAL_RE)) {
52
+ const literal = match[2];
53
+ if (typeof literal === 'string' && literal.length > 0) {
54
+ out.add(literal);
55
+ }
56
+ }
57
+ return [...out];
58
+ }
59
+ /**
60
+ * For each deleted test file, decide whether its described symbols are
61
+ * "outside" the current WU's code_paths.
62
+ *
63
+ * Heuristic match: a described symbol is considered IN scope if any
64
+ * code_paths entry's basename (without `.ts/.tsx`) equals the symbol, or if
65
+ * any code_paths entry's path normalised contains the symbol as a substring.
66
+ * Otherwise the symbol is flagged.
67
+ */
68
+ export function detectCrossScopeDeletions(input) {
69
+ const { deletedTestFiles, codePaths } = input;
70
+ const tokens = buildScopeTokens(codePaths);
71
+ const findings = [];
72
+ for (const file of deletedTestFiles) {
73
+ const symbols = parseDescribedSymbols(file.content);
74
+ const unrecognised = symbols.filter((s) => !isSymbolInScope(s, tokens));
75
+ if (unrecognised.length > 0) {
76
+ findings.push({ testFile: file.path, unrecognisedSymbols: unrecognised });
77
+ }
78
+ }
79
+ return findings;
80
+ }
81
+ function buildScopeTokens(codePaths) {
82
+ const basenames = new Set();
83
+ const paths = [];
84
+ for (const p of codePaths) {
85
+ if (typeof p !== 'string' || p.length === 0)
86
+ continue;
87
+ const normalised = p.replace(/\\/g, '/').toLowerCase();
88
+ paths.push(normalised);
89
+ const base = path.basename(normalised).replace(/\.[^.]+$/, '');
90
+ if (base.length > 0)
91
+ basenames.add(base);
92
+ // Also kebab → camel/pascal token, so 'payment-gateway' matches 'PaymentGateway'.
93
+ const camel = base.replace(/[-_]([a-z])/g, (_, c) => c.toUpperCase());
94
+ if (camel.length > 0)
95
+ basenames.add(camel.toLowerCase());
96
+ }
97
+ return { basenames, paths };
98
+ }
99
+ function isSymbolInScope(symbol, tokens) {
100
+ const lower = symbol.toLowerCase();
101
+ if (tokens.basenames.has(lower))
102
+ return true;
103
+ for (const p of tokens.paths) {
104
+ if (p.includes(lower))
105
+ return true;
106
+ }
107
+ return false;
108
+ }
109
+ async function getDiffNameStatus(cwd, baseRef) {
110
+ try {
111
+ const git = createGitForPath(cwd);
112
+ const out = await git.raw(['diff', '--name-status', `${baseRef}...HEAD`]);
113
+ return out
114
+ .split('\n')
115
+ .map((line) => line.trim())
116
+ .filter(Boolean)
117
+ .map((line) => {
118
+ const [status, ...rest] = line.split(/\s+/);
119
+ return { status: status ?? '', path: rest.join(' ') };
120
+ });
121
+ }
122
+ catch {
123
+ return [];
124
+ }
125
+ }
126
+ async function resolveMergeBase(cwd) {
127
+ // Prefer the configured tracking ref (origin/main or override). Fall back
128
+ // to local `main` when no remote exists (fresh clones, ephemeral test
129
+ // repos). Final fallback: empty repo with no main → null.
130
+ const candidates = [resolveIntegrationTargetRef(), 'main'];
131
+ const seen = new Set();
132
+ const git = createGitForPath(cwd);
133
+ for (const candidate of candidates) {
134
+ if (!candidate || seen.has(candidate))
135
+ continue;
136
+ seen.add(candidate);
137
+ try {
138
+ const base = await git.mergeBase('HEAD', candidate);
139
+ if (base)
140
+ return base;
141
+ }
142
+ catch {
143
+ // try next candidate
144
+ }
145
+ }
146
+ return null;
147
+ }
148
+ async function getDeletedTestFiles(cwd) {
149
+ const mergeBase = await resolveMergeBase(cwd);
150
+ if (!mergeBase)
151
+ return [];
152
+ const entries = await getDiffNameStatus(cwd, mergeBase);
153
+ const deletedTests = entries.filter((e) => e.status.startsWith('D') && TEST_FILE_PATTERN.test(e.path));
154
+ const out = [];
155
+ const git = createGitForPath(cwd);
156
+ for (const entry of deletedTests) {
157
+ // Read content from the merge-base (where the file still existed).
158
+ // showFileAtRef returns '' when the file is unreadable — treat that as
159
+ // a best-effort skip rather than a gate block.
160
+ const content = await git.showFileAtRef(mergeBase, entry.path);
161
+ if (content.length > 0) {
162
+ out.push({ path: entry.path, content });
163
+ }
164
+ }
165
+ return out;
166
+ }
167
+ async function loadCurrentWUCodePathsForCwd(cwd) {
168
+ // Mirror gates-utils.loadCurrentWUCodePaths but rooted at an arbitrary cwd
169
+ // (the gate runs against the worktree, not necessarily process.cwd()).
170
+ let wuId = getCurrentWU();
171
+ if (!wuId) {
172
+ try {
173
+ const branch = await createGitForPath(cwd).getCurrentBranch();
174
+ const m = branch.match(/wu-(\d+)/i);
175
+ if (m)
176
+ wuId = `WU-${m[1]}`;
177
+ }
178
+ catch {
179
+ // ignore
180
+ }
181
+ }
182
+ if (!wuId)
183
+ return [];
184
+ try {
185
+ const wuPaths = createWuPaths({ projectRoot: cwd });
186
+ const yamlPath = wuPaths.WU(wuId);
187
+ const abs = path.isAbsolute(yamlPath) ? yamlPath : path.join(cwd, yamlPath);
188
+ if (!existsSync(abs))
189
+ return [];
190
+ const doc = readWURaw(abs);
191
+ if (doc && Array.isArray(doc.code_paths)) {
192
+ return doc.code_paths.filter((p) => typeof p === 'string');
193
+ }
194
+ }
195
+ catch {
196
+ // ignore — return empty so gate auto-skips not-applicable on missing WU
197
+ }
198
+ return [];
199
+ }
200
+ // ─────────────────────────────────────────────────────────────────────────
201
+ // Gate definition (INIT-068 contract)
202
+ // ─────────────────────────────────────────────────────────────────────────
203
+ async function checkApplicability(ctx) {
204
+ const cwd = ctx.cwd ?? process.cwd();
205
+ const deleted = await getDeletedTestFiles(cwd);
206
+ return deleted.length > 0 ? 'applicable' : 'not-applicable';
207
+ }
208
+ async function checkPreconditions(_ctx) {
209
+ // No environmental prerequisites: this gate only consults the git diff +
210
+ // the current WU spec, both of which are repo-local.
211
+ return 'satisfied';
212
+ }
213
+ async function run(ctx) {
214
+ const start = Date.now();
215
+ const cwd = ctx.cwd ?? process.cwd();
216
+ const logLine = makeGateLogger({
217
+ agentLog: ctx.agentLog ?? null,
218
+ useAgentMode: ctx.useAgentMode,
219
+ });
220
+ logLine('\n> test-over-deletion check\n');
221
+ const deleted = await getDeletedTestFiles(cwd);
222
+ if (deleted.length === 0) {
223
+ logLine('ℹ️ No deleted test files; nothing to evaluate.');
224
+ return { ok: true, duration: Date.now() - start };
225
+ }
226
+ const codePaths = await loadCurrentWUCodePathsForCwd(cwd);
227
+ if (codePaths.length === 0) {
228
+ // Without a WU spec we can't decide scope. Auto-pass (advisory) and warn.
229
+ logLine('⚠️ No WU code_paths resolvable; skipping describe()-symbol scope check.');
230
+ return { ok: true, duration: Date.now() - start };
231
+ }
232
+ const findings = detectCrossScopeDeletions({ deletedTestFiles: deleted, codePaths });
233
+ if (findings.length === 0) {
234
+ logLine('test-over-deletion check passed.');
235
+ return { ok: true, duration: Date.now() - start };
236
+ }
237
+ logLine("❌ test-over-deletion: deleted tests reference symbols outside this WU's code_paths.");
238
+ for (const f of findings) {
239
+ logLine(` - ${f.testFile}`);
240
+ for (const s of f.unrecognisedSymbols) {
241
+ logLine(` describe('${s}') — not found in code_paths`);
242
+ }
243
+ }
244
+ logLine('Hint: confirm the deletion is intentional and in scope, or split the unrelated removal into its own WU.');
245
+ return { ok: false, duration: Date.now() - start };
246
+ }
247
+ export const testOverDeletionGate = {
248
+ name: GATE_NAMES.TEST_OVER_DELETION,
249
+ run,
250
+ skippable_default: true,
251
+ prereq_strategy: 'auto-skip',
252
+ checkApplicability,
253
+ checkPreconditions,
254
+ };
255
+ //# sourceMappingURL=test-over-deletion-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-over-deletion-guard.js","sourceRoot":"","sources":["../../src/gates/test-over-deletion-guard.ts"],"names":[],"mappings":"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"}