@aifabrix/builder 2.45.0 → 2.46.0

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 (352) hide show
  1. package/.cursor/rules/cli-layout.mdc +2 -0
  2. package/.cursor/rules/cli-product-neutral.mdc +43 -0
  3. package/.cursor/rules/docs-rules.mdc +3 -1
  4. package/.cursor/rules/project-rules.mdc +1 -0
  5. package/README.md +43 -17
  6. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
  7. package/jest.config.default.js +2 -1
  8. package/jest.config.isolated.js +2 -1
  9. package/jest.global-live-fabrix-hooks.js +36 -0
  10. package/jest.isolated-projects.js +130 -0
  11. package/jest.projects.js +69 -121
  12. package/lib/api/agent-metadata-validation.api.js +93 -0
  13. package/lib/api/api-response-errors.js +124 -0
  14. package/lib/api/audit-api-helpers.js +68 -0
  15. package/lib/api/audit.api.js +119 -0
  16. package/lib/api/auth-cache.api.js +44 -0
  17. package/lib/api/certificates.api.js +4 -4
  18. package/lib/api/credential.api.js +2 -2
  19. package/lib/api/dataplane-health.api.js +137 -0
  20. package/lib/api/dataplane-sync.api.js +27 -0
  21. package/lib/api/datasources-core.api.js +21 -18
  22. package/lib/api/datasources-extended.api.js +22 -22
  23. package/lib/api/dimensions.api.js +3 -0
  24. package/lib/api/external-systems.api.js +13 -13
  25. package/lib/api/governance-scenario-pack.api.js +159 -0
  26. package/lib/api/governance-scenarios.api.js +39 -0
  27. package/lib/api/groups.api.js +79 -0
  28. package/lib/api/index.js +88 -5
  29. package/lib/api/lifecycle.api.js +77 -0
  30. package/lib/api/pipeline.api.js +7 -5
  31. package/lib/api/protection.api.js +157 -0
  32. package/lib/api/records-bulk.api.js +43 -0
  33. package/lib/api/records-search-parse.js +49 -0
  34. package/lib/api/records-search.api.js +29 -0
  35. package/lib/api/types/agent-metadata-validation.types.js +67 -0
  36. package/lib/api/types/audit.types.js +72 -0
  37. package/lib/api/types/dataplane-health.types.js +27 -0
  38. package/lib/api/types/dimensions.types.js +2 -0
  39. package/lib/api/types/governance-scenarios.types.js +39 -0
  40. package/lib/api/types/protection.types.js +69 -0
  41. package/lib/api/types/records-bulk.types.js +35 -0
  42. package/lib/api/types/records-search.types.js +28 -0
  43. package/lib/api/user-groups.api.js +50 -0
  44. package/lib/api/users.api.js +95 -0
  45. package/lib/api/validation-run.api.js +3 -3
  46. package/lib/api/validation-runner.js +5 -3
  47. package/lib/api/wizard-platform.api.js +3 -3
  48. package/lib/api/wizard.api.js +21 -21
  49. package/lib/app/deploy-config.js +4 -1
  50. package/lib/app/deploy.js +34 -19
  51. package/lib/app/down.js +20 -1
  52. package/lib/app/push.js +4 -5
  53. package/lib/app/register.js +7 -4
  54. package/lib/app/run-env-compose.js +84 -30
  55. package/lib/build/index.js +5 -0
  56. package/lib/certification/sync-system-certification.js +13 -6
  57. package/lib/cli/index.js +8 -2
  58. package/lib/cli/infra-guided-auth.js +109 -0
  59. package/lib/cli/infra-guided.js +91 -69
  60. package/lib/cli/setup-app.help.js +19 -2
  61. package/lib/cli/setup-app.js +58 -23
  62. package/lib/cli/setup-app.test-commands.js +28 -21
  63. package/lib/cli/setup-auth.js +55 -3
  64. package/lib/cli/setup-certification-commands.js +147 -0
  65. package/lib/cli/setup-certification.help.js +141 -0
  66. package/lib/cli/setup-environment.js +19 -2
  67. package/lib/cli/setup-external-system-help.js +62 -0
  68. package/lib/cli/setup-external-system.js +62 -6
  69. package/lib/cli/setup-infra.js +9 -1
  70. package/lib/cli/setup-platform.js +6 -1
  71. package/lib/cli/setup-secrets.js +33 -1
  72. package/lib/cli/setup-utility-help-after.js +65 -0
  73. package/lib/cli/setup-utility-repair.js +198 -0
  74. package/lib/cli/setup-utility-resolve.js +42 -6
  75. package/lib/cli/setup-utility-validate.js +197 -0
  76. package/lib/cli/setup-utility.js +41 -258
  77. package/lib/commands/auth-status-client-tokens.js +214 -0
  78. package/lib/commands/auth-status-dataplane-version.js +269 -0
  79. package/lib/commands/auth-status-display.js +94 -0
  80. package/lib/commands/auth-status.js +111 -53
  81. package/lib/commands/credential-push.js +10 -5
  82. package/lib/commands/datasource-load-export-cli.js +178 -0
  83. package/lib/commands/datasource-test-trust-cli.js +118 -0
  84. package/lib/commands/datasource-unified-test-cli.js +31 -20
  85. package/lib/commands/datasource-unified-test-cli.options.js +22 -3
  86. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
  87. package/lib/commands/datasource-verify-audit-cli.js +96 -0
  88. package/lib/commands/datasource.js +68 -1
  89. package/lib/commands/dev-show-display.js +8 -1
  90. package/lib/commands/dimension-value.js +43 -13
  91. package/lib/commands/dimension.js +38 -7
  92. package/lib/commands/governance-cli-shared.js +94 -0
  93. package/lib/commands/governance-command-action.js +132 -0
  94. package/lib/commands/governance-download-external.js +34 -0
  95. package/lib/commands/governance-generate-external.js +71 -0
  96. package/lib/commands/governance-upload-external.js +36 -0
  97. package/lib/commands/governance-verify-external.js +64 -0
  98. package/lib/commands/governance.js +144 -0
  99. package/lib/commands/identity-apply-sync.js +131 -0
  100. package/lib/commands/identity-group-cli.js +146 -0
  101. package/lib/commands/identity-membership-role-cache.js +175 -0
  102. package/lib/commands/identity-shared.js +94 -0
  103. package/lib/commands/identity-user-cli.js +158 -0
  104. package/lib/commands/identity.js +43 -0
  105. package/lib/commands/lifecycle-command-action.js +123 -0
  106. package/lib/commands/lifecycle-external.js +268 -0
  107. package/lib/commands/login.js +56 -17
  108. package/lib/commands/protection-cli-leaves.js +286 -0
  109. package/lib/commands/protection.js +50 -0
  110. package/lib/commands/repair-auth-apply.js +127 -0
  111. package/lib/commands/repair-changed-files.js +41 -0
  112. package/lib/commands/repair-datasource-keys.js +4 -1
  113. package/lib/commands/repair-datasource-run.js +59 -0
  114. package/lib/commands/repair-datasource-test-payload.js +259 -0
  115. package/lib/commands/repair-datasource.js +1 -51
  116. package/lib/commands/repair-env-template.js +64 -13
  117. package/lib/commands/repair-external-run.js +216 -0
  118. package/lib/commands/repair-openapi-sync.js +23 -0
  119. package/lib/commands/repair-persist.js +4 -0
  120. package/lib/commands/repair-rbac.js +52 -1
  121. package/lib/commands/repair-steps.js +145 -0
  122. package/lib/commands/repair.js +29 -286
  123. package/lib/commands/secrets-get.js +184 -0
  124. package/lib/commands/secrets-remove-all.js +3 -1
  125. package/lib/commands/setup-image-refresh.js +146 -0
  126. package/lib/commands/setup-modes.js +158 -162
  127. package/lib/commands/setup-platform-auth.js +76 -0
  128. package/lib/commands/setup-prompts-admin.js +244 -0
  129. package/lib/commands/setup-prompts-platform-mode.js +67 -0
  130. package/lib/commands/setup-prompts-validators.js +36 -0
  131. package/lib/commands/setup-prompts.js +24 -76
  132. package/lib/commands/setup-run-context.js +45 -0
  133. package/lib/commands/setup-spinners.js +39 -0
  134. package/lib/commands/setup.js +27 -5
  135. package/lib/commands/teardown.js +39 -0
  136. package/lib/commands/test-e2e-external.js +61 -14
  137. package/lib/commands/test-governance-cli-options.js +47 -0
  138. package/lib/commands/test-governance-external.js +67 -0
  139. package/lib/commands/test-trust-cli-options.js +32 -0
  140. package/lib/commands/test-trust-external.js +126 -0
  141. package/lib/commands/up-common.js +25 -13
  142. package/lib/commands/up-dataplane.js +50 -13
  143. package/lib/commands/upload-publish-context.js +75 -0
  144. package/lib/commands/upload-sidecar-followups.js +89 -0
  145. package/lib/commands/upload.js +108 -105
  146. package/lib/commands/verify-governance-combined-external.js +61 -0
  147. package/lib/commands/verify-governance-command-action.js +64 -0
  148. package/lib/commands/verify-governance-db.js +102 -0
  149. package/lib/commands/verify-governance-external.js +77 -0
  150. package/lib/commands/verify-governance-result-builders.js +71 -0
  151. package/lib/commands/verify-operations-command-action.js +68 -0
  152. package/lib/commands/verify-operations-external.js +268 -0
  153. package/lib/commands/verify-operations-persist.js +75 -0
  154. package/lib/commands/verify-operations-step-plan.js +68 -0
  155. package/lib/commands/verify-operations-steps.js +111 -0
  156. package/lib/commands/verify-trust-command-action.js +70 -0
  157. package/lib/commands/verify-trust-external.js +67 -0
  158. package/lib/commands/wizard-config-normalizer.js +43 -23
  159. package/lib/commands/wizard-core.js +5 -0
  160. package/lib/core/admin-password-generator.js +38 -0
  161. package/lib/core/admin-secrets-bundle.js +111 -0
  162. package/lib/core/admin-secrets-env-overlay.js +62 -0
  163. package/lib/core/admin-secrets.js +32 -4
  164. package/lib/core/config-attach-extensions.js +3 -0
  165. package/lib/core/config-device-dataplane.js +185 -0
  166. package/lib/core/config-platform-controller.js +44 -0
  167. package/lib/core/config-setup-installation-profile.js +42 -0
  168. package/lib/core/config-setup-platform-mode.js +46 -0
  169. package/lib/core/config.js +46 -36
  170. package/lib/core/secrets-admin-env.js +6 -2
  171. package/lib/core/secrets-ensure.js +4 -0
  172. package/lib/core/secrets-env-content.js +54 -48
  173. package/lib/core/secrets-env-write.js +10 -1
  174. package/lib/core/secrets-infra-placeholder-sync.js +2 -0
  175. package/lib/core/setup-installation-profile.js +43 -0
  176. package/lib/core/setup-platform-mode.js +55 -0
  177. package/lib/datasource/agent-trust-debug-log.js +45 -0
  178. package/lib/datasource/agent-trust-fetch.js +115 -0
  179. package/lib/datasource/agent-trust-map.js +101 -0
  180. package/lib/datasource/agent-trust-mock.js +44 -0
  181. package/lib/datasource/agent-trust-run.js +95 -0
  182. package/lib/datasource/agent-trust-timeout.js +25 -0
  183. package/lib/datasource/audit-evidence-display.js +80 -0
  184. package/lib/datasource/audit-evidence-extract-debug.js +115 -0
  185. package/lib/datasource/audit-evidence-extract.js +180 -0
  186. package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
  187. package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
  188. package/lib/datasource/audit-evidence-poll.js +109 -0
  189. package/lib/datasource/audit-evidence-run.js +177 -0
  190. package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
  191. package/lib/datasource/audit-evidence-verify-matrix.js +205 -0
  192. package/lib/datasource/audit-evidence-verify.js +108 -0
  193. package/lib/datasource/bulk-loader-run-batches.js +100 -0
  194. package/lib/datasource/bulk-loader-service-retry.js +52 -0
  195. package/lib/datasource/bulk-loader-service.js +127 -0
  196. package/lib/datasource/capability/run-capability-dimension.js +2 -1
  197. package/lib/datasource/datasource-exporter-resolve.js +82 -0
  198. package/lib/datasource/datasource-exporter-service.js +144 -0
  199. package/lib/datasource/datasource-identifier.js +148 -0
  200. package/lib/datasource/datasource-load-export-context.js +95 -0
  201. package/lib/datasource/integration-context.js +6 -4
  202. package/lib/datasource/local-data-paths.js +145 -0
  203. package/lib/datasource/log-cleaner.js +241 -0
  204. package/lib/datasource/log-viewer.js +111 -6
  205. package/lib/datasource/record-file-parser.js +85 -0
  206. package/lib/datasource/record-mapper.js +129 -0
  207. package/lib/datasource/resolve-app.js +74 -55
  208. package/lib/datasource/test-e2e.js +29 -2
  209. package/lib/datasource/unified-validation-run-body.js +3 -1
  210. package/lib/datasource/unified-validation-run-resolve.js +45 -12
  211. package/lib/datasource/unified-validation-run.js +47 -18
  212. package/lib/datasource/validate.js +37 -20
  213. package/lib/deployment/environment-poll-status.js +138 -0
  214. package/lib/deployment/environment.js +42 -34
  215. package/lib/external-system/download.js +21 -20
  216. package/lib/external-system/generator.js +5 -1
  217. package/lib/external-system/integration-auth-context.js +45 -0
  218. package/lib/external-system/test-auth.js +12 -5
  219. package/lib/external-system/test-system-level.js +25 -4
  220. package/lib/external-system/test.js +9 -7
  221. package/lib/generator/external-controller-manifest.js +15 -0
  222. package/lib/governance/governance-cli-errors.js +96 -0
  223. package/lib/governance/governance-download-display.js +38 -0
  224. package/lib/governance/governance-pack-loader.js +70 -0
  225. package/lib/governance/governance-run-display.js +309 -0
  226. package/lib/identity/identity-apply-core.js +108 -0
  227. package/lib/identity/identity-apply-phases.js +244 -0
  228. package/lib/identity/identity-apply-service.js +77 -0
  229. package/lib/identity/identity-csv-parser.js +114 -0
  230. package/lib/infrastructure/admin-secrets-apply.js +84 -0
  231. package/lib/infrastructure/admin-secrets-ensure.js +130 -0
  232. package/lib/infrastructure/admin-secrets-resolve.js +95 -0
  233. package/lib/infrastructure/admin-secrets-sync.js +91 -0
  234. package/lib/infrastructure/helpers.js +23 -129
  235. package/lib/infrastructure/index.js +5 -6
  236. package/lib/infrastructure/orphan-infra-docker-teardown.js +11 -5
  237. package/lib/internal/fs-real-sync.js +29 -1
  238. package/lib/lifecycle/certification-progress.js +231 -0
  239. package/lib/lifecycle/dataplane-ui-url.js +145 -0
  240. package/lib/lifecycle/exit-codes.js +24 -0
  241. package/lib/lifecycle/json-envelope.js +25 -0
  242. package/lib/lifecycle/lifecycle-governance-options.js +51 -0
  243. package/lib/lifecycle/logger-quiet.js +29 -0
  244. package/lib/lifecycle/open-api-published.js +59 -0
  245. package/lib/lifecycle/operations-readiness-metrics.js +101 -0
  246. package/lib/lifecycle/product-model.js +196 -0
  247. package/lib/lifecycle/report-display.js +471 -0
  248. package/lib/lifecycle/scenario-upload.js +191 -0
  249. package/lib/lifecycle/verify-step-progress.js +87 -0
  250. package/lib/parameters/infra-kv-discovery.js +27 -2
  251. package/lib/protection/auth-context.js +51 -0
  252. package/lib/protection/convert-batch.js +90 -0
  253. package/lib/protection/load.js +41 -0
  254. package/lib/protection/paths.js +158 -0
  255. package/lib/protection/preflight-datasource-ready.js +46 -0
  256. package/lib/protection/protection-create-probe-lines.js +142 -0
  257. package/lib/protection/protection-create-probes.js +95 -0
  258. package/lib/protection/protection-create-scaffold.js +281 -0
  259. package/lib/protection/protection-display-helpers.js +445 -0
  260. package/lib/protection/protection-display.js +215 -0
  261. package/lib/protection/protection-preset-registry.js +97 -0
  262. package/lib/protection/report-exit.js +62 -0
  263. package/lib/protection/resolve.js +202 -0
  264. package/lib/protection/run-commands-validate.js +130 -0
  265. package/lib/protection/run-commands.js +216 -0
  266. package/lib/protection/run-protection-create-helpers.js +134 -0
  267. package/lib/protection/run-protection-create-probes-flow.js +43 -0
  268. package/lib/protection/run-protection-create.js +191 -0
  269. package/lib/protection/scope.js +22 -0
  270. package/lib/protection/sync-after-upload.js +64 -0
  271. package/lib/protection/upload-batch.js +127 -0
  272. package/lib/protection/validate-batch.js +113 -0
  273. package/lib/protection/validate-local.js +65 -0
  274. package/lib/resolvers/dimension-file.js +29 -4
  275. package/lib/schema/application-schema.json +1 -1
  276. package/lib/schema/datasource-test-run.schema.json +89 -6
  277. package/lib/schema/external-datasource.schema.json +2636 -2588
  278. package/lib/schema/external-system.schema.json +1089 -761
  279. package/lib/schema/flag-map-validation-run.json +2 -2
  280. package/lib/schema/infra.parameter.yaml +45 -0
  281. package/lib/schema/protection.schema.json +374 -0
  282. package/lib/schema/type/credential-field-registry.json +642 -0
  283. package/lib/schema/wizard-config.schema.json +1 -1
  284. package/lib/utils/agent-trust-run-display.js +231 -0
  285. package/lib/utils/agent-trust-run-exit.js +59 -0
  286. package/lib/utils/agent-trust-wait-ui.js +94 -0
  287. package/lib/utils/aifabrix-test-runtime-guard.js +125 -0
  288. package/lib/utils/api.js +55 -31
  289. package/lib/utils/app-relative-path-env.js +112 -0
  290. package/lib/utils/cli-exit-codes.js +30 -0
  291. package/lib/utils/cli-secrets-error-format.js +83 -21
  292. package/lib/utils/cli-sync-options.js +33 -0
  293. package/lib/utils/cli-utils.js +16 -4
  294. package/lib/utils/compose-generate-docker-compose.js +4 -0
  295. package/lib/utils/compose-traefik-ingress-base.js +16 -1
  296. package/lib/utils/config-secrets-path.js +46 -0
  297. package/lib/utils/controller-url.js +88 -1
  298. package/lib/utils/credential-push-ui.js +90 -0
  299. package/lib/utils/credential-secrets-env.js +137 -9
  300. package/lib/utils/dataplane-cli-version-gate.js +202 -0
  301. package/lib/utils/dataplane-cli-version-help.js +74 -0
  302. package/lib/utils/dataplane-resolver.js +129 -2
  303. package/lib/utils/datasource-export-display.js +137 -0
  304. package/lib/utils/datasource-load-display.js +174 -0
  305. package/lib/utils/datasource-load-export-ui.js +120 -0
  306. package/lib/utils/datasource-test-run-capability-scope.js +3 -3
  307. package/lib/utils/datasource-test-run-display.js +3 -3
  308. package/lib/utils/datasource-test-run-tty-log.js +5 -1
  309. package/lib/utils/declarative-url-ports.js +3 -3
  310. package/lib/utils/deployment-auth-mode.js +41 -0
  311. package/lib/utils/developer-volume-id.js +33 -0
  312. package/lib/utils/env-copy.js +14 -9
  313. package/lib/utils/env-kv-orphan-lines.js +43 -0
  314. package/lib/utils/error-formatters/network-errors.js +13 -4
  315. package/lib/utils/external-env-template.js +1 -0
  316. package/lib/utils/external-system-readiness-core.js +10 -0
  317. package/lib/utils/external-system-readiness-display.js +80 -23
  318. package/lib/utils/health-check.js +4 -1
  319. package/lib/utils/help-builder.js +35 -26
  320. package/lib/utils/keycloak-realm-ready.js +101 -0
  321. package/lib/utils/load-cip-capacity-display-config.js +61 -15
  322. package/lib/utils/manifest-source-emit.js +24 -0
  323. package/lib/utils/pipeline-upload-auth-retry.js +82 -0
  324. package/lib/utils/platform-controller-url.js +156 -0
  325. package/lib/utils/postgres-platform-bootstrap.js +199 -0
  326. package/lib/utils/postgres-wipe.js +9 -2
  327. package/lib/utils/resolve-env-mode.js +47 -0
  328. package/lib/utils/secrets-generator.js +31 -25
  329. package/lib/utils/secrets-missing-error.js +164 -0
  330. package/lib/utils/semver-compare.js +127 -0
  331. package/lib/utils/service-url-label.js +81 -0
  332. package/lib/utils/setup-quiet-output.js +25 -0
  333. package/lib/utils/template-helpers.js +15 -0
  334. package/lib/utils/token-manager-client-credentials.js +201 -0
  335. package/lib/utils/token-manager-messages.js +8 -0
  336. package/lib/utils/token-manager-refresh.js +12 -2
  337. package/lib/utils/token-manager.js +86 -105
  338. package/lib/utils/upload-pipeline-ui.js +98 -0
  339. package/lib/utils/upload-sync-options.js +42 -0
  340. package/lib/utils/url-declarative-public-base.js +21 -3
  341. package/lib/utils/url-declarative-vdir-inactive-env.js +14 -4
  342. package/lib/utils/validation-poll-ui.js +22 -7
  343. package/lib/utils/validation-run-stage.js +45 -0
  344. package/lib/validation/wizard-config-validator.js +58 -19
  345. package/package.json +1 -1
  346. package/templates/applications/dataplane/application.yaml +2 -1
  347. package/templates/applications/dataplane/env.template +36 -1
  348. package/templates/applications/dataplane/rbac.yaml +4 -0
  349. package/templates/applications/miso-controller/env.template +16 -0
  350. package/templates/external-system/README.md.hbs +116 -11
  351. package/templates/python/docker-compose.hbs +19 -18
  352. package/templates/typescript/docker-compose.hbs +18 -17
@@ -0,0 +1,231 @@
1
+ /**
2
+ * @fileoverview UX certification progress for lifecycle CLI (aligned with dataplane overview / app-ui).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { VERDICT } = require('./product-model');
10
+ const { formatOpenApiPublishNextStep } = require('./dataplane-ui-url');
11
+
12
+ /** @typedef {'governanceCoverage'|'operationalReadiness'|'openApiPublished'|'aiTrust'|'activeWarnings'} CertificationCriterionId */
13
+
14
+ /**
15
+ * @typedef {Object} CertificationCriterionRow
16
+ * @property {CertificationCriterionId} id
17
+ * @property {string} label
18
+ * @property {boolean} met
19
+ */
20
+
21
+ /**
22
+ * @typedef {Object} CertificationProgressViewModel
23
+ * @property {'progress'|'gaps'} mode
24
+ * @property {string} currentLevel
25
+ * @property {string} targetLevel
26
+ * @property {CertificationCriterionRow[]} criteria
27
+ * @property {number|null} progressPercent
28
+ * @property {boolean} highestTierAchieved
29
+ */
30
+
31
+ const SILVER_TO_GOLD_CRITERIA = [
32
+ {
33
+ id: 'governanceCoverage',
34
+ label: 'Governance Coverage ≥ 95%',
35
+ evaluate: ctx =>
36
+ (ctx.report.governance?.policyCoveragePercent ?? 0) >= 95 &&
37
+ ctx.report.governance?.verdict === VERDICT.VERIFIED
38
+ },
39
+ {
40
+ id: 'operationalReadiness',
41
+ label: 'Operational Readiness ≥ 90%',
42
+ evaluate: ctx => (ctx.report.operations?.operationalReadinessPercent ?? 0) >= 90
43
+ },
44
+ {
45
+ id: 'openApiPublished',
46
+ label: 'OpenAPI Published',
47
+ evaluate: ctx => ctx.openApiPublished === true
48
+ },
49
+ {
50
+ id: 'aiTrust',
51
+ label: 'AI Trust ≥ 95%',
52
+ evaluate: ctx => (ctx.report.trust?.businessContextConfidencePercent ?? 0) >= 95
53
+ },
54
+ {
55
+ id: 'activeWarnings',
56
+ label: '0 Active Warnings',
57
+ evaluate: ctx => ctx.activeWarningCount === 0
58
+ }
59
+ ];
60
+
61
+ /** @type {Record<CertificationCriterionId, string>} */
62
+ const NEXT_COMMAND_BY_CRITERION = {
63
+ governanceCoverage: 'governance verify',
64
+ operationalReadiness: 'verify-operations',
65
+ openApiPublished: '',
66
+ aiTrust: 'verify-trust',
67
+ activeWarnings: ''
68
+ };
69
+
70
+ /**
71
+ * @param {string} level
72
+ * @returns {string}
73
+ */
74
+ function formatCertificationLevel(level) {
75
+ if (!level || level === 'NONE') return 'Uncertified';
76
+ return level.charAt(0) + level.slice(1).toLowerCase();
77
+ }
78
+
79
+ /**
80
+ * @param {string} current
81
+ * @returns {string|null}
82
+ */
83
+ function resolveTargetLevel(current) {
84
+ if (current === 'NONE' || current === 'BRONZE') return 'SILVER';
85
+ if (current === 'SILVER') return 'GOLD';
86
+ if (current === 'GOLD') return 'PLATINUM';
87
+ return null;
88
+ }
89
+
90
+ /**
91
+ * @param {string} current
92
+ * @param {string} target
93
+ * @param {{ report: Object, openApiPublished?: boolean, activeWarningCount: number }} ctx
94
+ * @returns {CertificationCriterionRow[]}
95
+ */
96
+ function buildCriteriaForTarget(current, target, ctx) {
97
+ if (current === 'SILVER' && target === 'GOLD') {
98
+ return SILVER_TO_GOLD_CRITERIA.map(def => ({
99
+ id: def.id,
100
+ label: def.label,
101
+ met: def.evaluate(ctx)
102
+ }));
103
+ }
104
+ return [];
105
+ }
106
+
107
+ /**
108
+ * @param {Object|null|undefined} report - SystemLifecycleReport
109
+ * @param {{ openApiPublished?: boolean }} [options]
110
+ * @returns {CertificationProgressViewModel|null}
111
+ */
112
+ function buildCertificationProgress(report, options = {}) {
113
+ if (!report?.certification?.level) {
114
+ return null;
115
+ }
116
+ const currentLevel = report.certification.level;
117
+ const targetLevel = resolveTargetLevel(currentLevel);
118
+ if (!targetLevel) {
119
+ return {
120
+ mode: 'gaps',
121
+ currentLevel,
122
+ targetLevel: currentLevel,
123
+ criteria: [],
124
+ progressPercent: 100,
125
+ highestTierAchieved: true
126
+ };
127
+ }
128
+
129
+ const activeWarningCount = Array.isArray(report.warnings) ? report.warnings.length : 0;
130
+ const ctx = {
131
+ report,
132
+ openApiPublished: options.openApiPublished === true,
133
+ activeWarningCount
134
+ };
135
+ const criteria = buildCriteriaForTarget(currentLevel, targetLevel, ctx);
136
+ if (criteria.length === 0) {
137
+ return {
138
+ mode: 'gaps',
139
+ currentLevel,
140
+ targetLevel,
141
+ criteria: [],
142
+ progressPercent: null,
143
+ highestTierAchieved: false
144
+ };
145
+ }
146
+
147
+ const metCount = criteria.filter(c => c.met).length;
148
+ const progressPercent = Math.round((metCount / criteria.length) * 100);
149
+ return {
150
+ mode: 'progress',
151
+ currentLevel,
152
+ targetLevel,
153
+ criteria,
154
+ progressPercent,
155
+ highestTierAchieved: false
156
+ };
157
+ }
158
+
159
+ /**
160
+ * @param {CertificationCriterionId} id
161
+ * @param {Object} report
162
+ * @param {boolean} openApiPublished
163
+ * @returns {string|null}
164
+ */
165
+ function formatCriterionCurrentHint(id, report, openApiPublished) {
166
+ if (id === 'aiTrust') {
167
+ const p = report.trust?.businessContextConfidencePercent;
168
+ return typeof p === 'number' ? `(current: ${p}%)` : null;
169
+ }
170
+ if (id === 'operationalReadiness') {
171
+ const p = report.operations?.operationalReadinessPercent;
172
+ return typeof p === 'number' ? `(current: ${p}%)` : null;
173
+ }
174
+ if (id === 'governanceCoverage') {
175
+ const p = report.governance?.policyCoveragePercent;
176
+ return typeof p === 'number' ? `(current: ${p}%)` : null;
177
+ }
178
+ if (id === 'openApiPublished' && !openApiPublished) {
179
+ return '(not published)';
180
+ }
181
+ if (id === 'activeWarnings') {
182
+ const n = Array.isArray(report.warnings) ? report.warnings.length : 0;
183
+ return n > 0 ? `(current: ${n})` : null;
184
+ }
185
+ return null;
186
+ }
187
+
188
+ /**
189
+ * @param {string} systemKey
190
+ * @param {CertificationProgressViewModel} progress
191
+ * @param {{ dataplaneUrl?: string|null }} [options]
192
+ * @returns {string|null}
193
+ */
194
+ function resolveNextStepCommand(systemKey, progress, options = {}) {
195
+ const firstUnmet = progress.criteria.find(c => !c.met);
196
+ if (!firstUnmet) return null;
197
+ const cmd = NEXT_COMMAND_BY_CRITERION[firstUnmet.id];
198
+ if (firstUnmet.id === 'openApiPublished') {
199
+ return formatOpenApiPublishNextStep(systemKey, {
200
+ dataplaneUrl: options.dataplaneUrl,
201
+ dataplaneUiBaseUrl: options.dataplaneUiBaseUrl
202
+ });
203
+ }
204
+ if (firstUnmet.id === 'activeWarnings') {
205
+ return 'Resolve lifecycle warnings, then re-run lifecycle';
206
+ }
207
+ if (!cmd) return null;
208
+ return `aifabrix ${cmd} ${systemKey} -v`;
209
+ }
210
+
211
+ /**
212
+ * @param {number|null} percent
213
+ * @param {number} [width]
214
+ * @returns {string}
215
+ */
216
+ function formatProgressBar(percent, width = 10) {
217
+ if (typeof percent !== 'number' || Number.isNaN(percent)) {
218
+ return '—'.repeat(width);
219
+ }
220
+ const filled = Math.round((Math.max(0, Math.min(100, percent)) / 100) * width);
221
+ return `${'█'.repeat(filled)}${'░'.repeat(width - filled)}`;
222
+ }
223
+
224
+ module.exports = {
225
+ buildCertificationProgress,
226
+ formatCertificationLevel,
227
+ formatCriterionCurrentHint,
228
+ resolveNextStepCommand,
229
+ formatProgressBar,
230
+ NEXT_COMMAND_BY_CRITERION
231
+ };
@@ -0,0 +1,145 @@
1
+ /**
2
+ * @fileoverview Resolve dataplane app-ui base URL for lifecycle CLI hints.
3
+ * @author AI Fabrix Team
4
+ * @version 1.1.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { getConfig } = require('../core/config');
10
+ const {
11
+ expandDeclarativeUrlsInEnvContent,
12
+ parseSimpleEnvMap
13
+ } = require('../utils/url-declarative-resolve');
14
+
15
+ const EXTERNAL_SYSTEMS_UI_PATH = '/external-systems';
16
+
17
+ /**
18
+ * @param {string} url
19
+ * @returns {number|null}
20
+ */
21
+ function portFromUrl(url) {
22
+ try {
23
+ const u = new URL(url);
24
+ if (u.port) {
25
+ const port = parseInt(u.port, 10);
26
+ return Number.isFinite(port) ? port : null;
27
+ }
28
+ return u.protocol === 'https:' ? 443 : 80;
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+
34
+ /**
35
+ * @param {string} hostname
36
+ * @returns {boolean}
37
+ */
38
+ function isLoopbackHost(hostname) {
39
+ const h = String(hostname || '').toLowerCase();
40
+ return h === 'localhost' || h === '127.0.0.1' || h === '[::1]';
41
+ }
42
+
43
+ /**
44
+ * Browser-reachable origin from the resolved dataplane API base URL (same host/port).
45
+ * @param {string|null|undefined} dataplaneUrl
46
+ * @returns {string|null}
47
+ */
48
+ function resolveDataplaneUiBaseUrlFromApiOrigin(dataplaneUrl) {
49
+ if (!dataplaneUrl || typeof dataplaneUrl !== 'string') {
50
+ return null;
51
+ }
52
+ try {
53
+ const u = new URL(dataplaneUrl.replace(/\/$/, ''));
54
+ return `${u.protocol}//${u.host}`;
55
+ } catch {
56
+ return null;
57
+ }
58
+ }
59
+
60
+ /**
61
+ * Resolve `url://dataplane-host-public` from builder registry + user config.
62
+ * @async
63
+ * @returns {Promise<string|null>}
64
+ */
65
+ async function resolveDataplaneUiBaseUrlFromRegistry() {
66
+ try {
67
+ const userCfg = await getConfig();
68
+ const content = 'DATAPLANE_UI=url://dataplane-host-public';
69
+ const expanded = await expandDeclarativeUrlsInEnvContent(content, {
70
+ profile: 'local',
71
+ currentAppKey: 'dataplane',
72
+ useEnvironmentScopedResources: userCfg.useEnvironmentScopedResources === true,
73
+ appEnvironmentScopedResources: false,
74
+ remoteServer: userCfg['remote-server'] || userCfg.remoteServer || null,
75
+ developerIdRaw: userCfg['developer-id'] ?? userCfg.developerId ?? null,
76
+ traefik: userCfg.traefik === true,
77
+ userCfg
78
+ });
79
+ const map = parseSimpleEnvMap(expanded);
80
+ const url = map.DATAPLANE_UI;
81
+ if (url && typeof url === 'string' && !url.startsWith('url://')) {
82
+ return url.replace(/\/$/, '');
83
+ }
84
+ } catch {
85
+ // Fall back to API origin below.
86
+ }
87
+ return null;
88
+ }
89
+
90
+ /**
91
+ * @async
92
+ * @param {string|null|undefined} dataplaneUrl - Resolved dataplane API base URL
93
+ * @returns {Promise<string|null>}
94
+ */
95
+ async function resolveDataplaneUiBaseUrl(dataplaneUrl) {
96
+ const fromRegistry = await resolveDataplaneUiBaseUrlFromRegistry();
97
+ if (fromRegistry) {
98
+ return fromRegistry;
99
+ }
100
+ return resolveDataplaneUiBaseUrlFromApiOrigin(dataplaneUrl);
101
+ }
102
+
103
+ /**
104
+ * @param {string|null|undefined} dataplaneUiBaseUrl
105
+ * @param {string} systemKey
106
+ * @returns {string|null}
107
+ */
108
+ function buildExternalSystemUiUrl(dataplaneUiBaseUrl, systemKey) {
109
+ if (!dataplaneUiBaseUrl || !systemKey) {
110
+ return null;
111
+ }
112
+ const base = String(dataplaneUiBaseUrl).replace(/\/$/, '');
113
+ const key = encodeURIComponent(String(systemKey).trim());
114
+ if (!key) {
115
+ return null;
116
+ }
117
+ return `${base}${EXTERNAL_SYSTEMS_UI_PATH}/${key}`;
118
+ }
119
+
120
+ /**
121
+ * @param {string} systemKey
122
+ * @param {{ dataplaneUrl?: string|null, dataplaneUiBaseUrl?: string|null }} [options]
123
+ * @returns {string}
124
+ */
125
+ function formatOpenApiPublishNextStep(systemKey, options = {}) {
126
+ const uiBase =
127
+ options.dataplaneUiBaseUrl ||
128
+ resolveDataplaneUiBaseUrlFromApiOrigin(options.dataplaneUrl);
129
+ const uiUrl = buildExternalSystemUiUrl(uiBase, systemKey);
130
+ if (uiUrl) {
131
+ return `Publish OpenAPI in dataplane UI: ${uiUrl}`;
132
+ }
133
+ return `Publish OpenAPI in dataplane UI — open external system "${systemKey}"`;
134
+ }
135
+
136
+ module.exports = {
137
+ EXTERNAL_SYSTEMS_UI_PATH,
138
+ portFromUrl,
139
+ isLoopbackHost,
140
+ resolveDataplaneUiBaseUrlFromApiOrigin,
141
+ resolveDataplaneUiBaseUrlFromRegistry,
142
+ resolveDataplaneUiBaseUrl,
143
+ buildExternalSystemUiUrl,
144
+ formatOpenApiPublishNextStep
145
+ };
@@ -0,0 +1,24 @@
1
+ /**
2
+ * @fileoverview Exit codes for Enterprise AI Certification verify commands.
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { VERDICT } = require('./product-model');
10
+
11
+ /**
12
+ * @param {string} verdict
13
+ * @param {{ partial?: boolean }} [opts]
14
+ * @returns {number}
15
+ */
16
+ function exitCodeFromVerdict(verdict, opts = {}) {
17
+ if (opts.partial === true) return 2;
18
+ if (verdict === VERDICT.VERIFIED) return 0;
19
+ return 1;
20
+ }
21
+
22
+ module.exports = {
23
+ exitCodeFromVerdict
24
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @fileoverview Machine-readable --json envelopes for verify + lifecycle commands.
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * @param {Object} base
11
+ * @param {boolean} includeDetails
12
+ * @returns {Object}
13
+ */
14
+ function buildJsonEnvelope(base, includeDetails) {
15
+ const out = { ...base };
16
+ if (!includeDetails) {
17
+ delete out.details;
18
+ delete out.readinessMetrics;
19
+ }
20
+ return out;
21
+ }
22
+
23
+ module.exports = {
24
+ buildJsonEnvelope
25
+ };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * @fileoverview Map lifecycle CLI flags to governance verify/generate options.
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const { VERDICT } = require('./product-model');
8
+
9
+ /**
10
+ * @param {Object} options
11
+ * @returns {boolean}
12
+ */
13
+ function lifecycleHasGovernanceSubjects(options) {
14
+ const emails = options.subjectEmail || options.subjectEmails || [];
15
+ const ids = options.subjectUserId || options.subjectUserIds || [];
16
+ return [...emails, ...ids].some(value => String(value || '').trim());
17
+ }
18
+
19
+ /**
20
+ * @param {Object} report
21
+ * @returns {boolean}
22
+ */
23
+ function lifecycleGovernanceNeedsWork(report) {
24
+ return report?.governance?.verdict !== VERDICT.VERIFIED;
25
+ }
26
+
27
+ /**
28
+ * @param {Object} options
29
+ * @param {{ authConfig?: Object, dataplaneUrl?: string }} [context]
30
+ * @returns {Object}
31
+ */
32
+ function buildGovernanceOptsFromLifecycle(options, context = {}) {
33
+ return {
34
+ env: options.env || 'dev',
35
+ verbose: options.verbose === true,
36
+ debug: options.debug === true,
37
+ noSync: true,
38
+ force: options.force === true,
39
+ certificationProfile: options.certificationProfile || 'bronze',
40
+ subjectEmails: options.subjectEmail || options.subjectEmails || [],
41
+ subjectUserIds: options.subjectUserId || options.subjectUserIds || [],
42
+ authConfig: context.authConfig,
43
+ dataplaneUrl: context.dataplaneUrl
44
+ };
45
+ }
46
+
47
+ module.exports = {
48
+ lifecycleHasGovernanceSubjects,
49
+ lifecycleGovernanceNeedsWork,
50
+ buildGovernanceOptsFromLifecycle
51
+ };
@@ -0,0 +1,29 @@
1
+ /**
2
+ * @fileoverview Suppress CLI logger output during orchestration (verify-operations).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const logger = require('../utils/logger');
10
+
11
+ /**
12
+ * Run async fn with logger.log temporarily disabled.
13
+ * @template T
14
+ * @param {() => Promise<T>} fn
15
+ * @returns {Promise<T>}
16
+ */
17
+ async function withQuietLogs(fn) {
18
+ const prev = logger.log;
19
+ logger.log = () => {};
20
+ try {
21
+ return await fn();
22
+ } finally {
23
+ logger.log = prev;
24
+ }
25
+ }
26
+
27
+ module.exports = {
28
+ withQuietLogs
29
+ };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview Resolve OpenAPI published flag for lifecycle certification progress.
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const { getExternalSystem } = require('../api/external-systems.api');
10
+ const { unwrapApiData } = require('../utils/external-system-readiness-core');
11
+
12
+ /**
13
+ * Dataplane ExternalSystemStatus serializes as lowercase (e.g. "published").
14
+ * @param {string|undefined} status
15
+ * @returns {boolean}
16
+ */
17
+ function isExternalSystemPublishedStatus(status) {
18
+ return String(status || '')
19
+ .trim()
20
+ .toLowerCase() === 'published';
21
+ }
22
+
23
+ /**
24
+ * Mirrors dataplane SystemOverviewService openApiPublished logic.
25
+ * @param {Object|null|undefined} system - ExternalSystemResponse body
26
+ * @returns {boolean}
27
+ */
28
+ function evaluateOpenApiPublished(system) {
29
+ if (!system || typeof system !== 'object') {
30
+ return false;
31
+ }
32
+ const published = isExternalSystemPublishedStatus(system.status);
33
+ const showDocs = system.showOpenApiDocs === true;
34
+ const hasUrl = !!(system.openApiDocsPageUrl || system.apiDocumentUrl);
35
+ return published && showDocs && hasUrl;
36
+ }
37
+
38
+ /**
39
+ * @async
40
+ * @param {string} dataplaneUrl
41
+ * @param {Object} authConfig
42
+ * @param {string} systemKey
43
+ * @returns {Promise<boolean>}
44
+ */
45
+ async function resolveOpenApiPublished(dataplaneUrl, authConfig, systemKey) {
46
+ try {
47
+ const res = await getExternalSystem(dataplaneUrl, systemKey, authConfig);
48
+ const system = unwrapApiData(res);
49
+ return evaluateOpenApiPublished(system);
50
+ } catch {
51
+ return false;
52
+ }
53
+ }
54
+
55
+ module.exports = {
56
+ isExternalSystemPublishedStatus,
57
+ evaluateOpenApiPublished,
58
+ resolveOpenApiPublished
59
+ };
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @fileoverview Operational readiness metric rollup for verify-operations (422.0).
3
+ * Human-facing labels for ICC/PDS/DTS; extraction from lifecycle reliability envelopes.
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ /** @type {readonly string[]} */
9
+ const METRIC_KEYS = Object.freeze(['icc', 'pds', 'dts']);
10
+
11
+ /** @type {Readonly<Record<string, string>>} */
12
+ const OPERATIONS_METRIC_LABELS = Object.freeze({
13
+ icc: 'Integration contract coverage',
14
+ pds: 'Pipeline determinism',
15
+ dts: 'Data trust'
16
+ });
17
+
18
+ /**
19
+ * @param {unknown} raw
20
+ * @returns {number|null}
21
+ */
22
+ function metricScorePercent(raw) {
23
+ if (!raw || typeof raw !== 'object') {
24
+ return null;
25
+ }
26
+ const score = raw.score;
27
+ if (typeof score === 'number' && Number.isFinite(score)) {
28
+ return Math.max(0, Math.min(100, Math.round(score * 100)));
29
+ }
30
+ const pct = raw.percentage;
31
+ if (typeof pct === 'number' && Number.isFinite(pct)) {
32
+ return Math.max(0, Math.min(100, Math.round(pct)));
33
+ }
34
+ return null;
35
+ }
36
+
37
+ /**
38
+ * @param {unknown} envelope
39
+ * @returns {Record<string, number>|null}
40
+ */
41
+ function metricsFromEnvelope(envelope) {
42
+ if (!envelope || typeof envelope !== 'object') {
43
+ return null;
44
+ }
45
+ let metrics = envelope.metricsOutput;
46
+ if (!metrics && envelope.validation && typeof envelope.validation === 'object') {
47
+ metrics = envelope.validation.metricsOutput;
48
+ }
49
+ if (!metrics || typeof metrics !== 'object') {
50
+ return null;
51
+ }
52
+ const out = {};
53
+ for (const key of METRIC_KEYS) {
54
+ const pct = metricScorePercent(metrics[key]);
55
+ if (pct !== null) {
56
+ out[key] = pct;
57
+ }
58
+ }
59
+ return Object.keys(out).length > 0 ? out : null;
60
+ }
61
+
62
+ /**
63
+ * Conservative rollup: min(ICC,PDS,DTS) per leg across validation + integration envelopes.
64
+ * E2E legs without metrics are ignored (runtime gate only).
65
+ * @param {unknown} reliability
66
+ * @returns {Record<string, number>|null}
67
+ */
68
+ function rollupReadinessMetrics(reliability) {
69
+ if (!reliability || typeof reliability !== 'object') {
70
+ return null;
71
+ }
72
+ const legs = [reliability.validation, reliability.integration].filter(Boolean);
73
+ const rolled = {};
74
+ for (const key of METRIC_KEYS) {
75
+ const values = legs
76
+ .map(leg => metricsFromEnvelope(leg)?.[key])
77
+ .filter(v => typeof v === 'number');
78
+ if (values.length > 0) {
79
+ rolled[key] = Math.min(...values);
80
+ }
81
+ }
82
+ return Object.keys(rolled).length > 0 ? rolled : null;
83
+ }
84
+
85
+ /**
86
+ * @param {Object|null} lifecycleReport
87
+ * @returns {Record<string, number>|null}
88
+ */
89
+ function extractReadinessMetricsFromLifecycleReport(lifecycleReport) {
90
+ const reliability = lifecycleReport?.operations?.details?.reliability;
91
+ return rollupReadinessMetrics(reliability);
92
+ }
93
+
94
+ module.exports = {
95
+ METRIC_KEYS,
96
+ OPERATIONS_METRIC_LABELS,
97
+ metricScorePercent,
98
+ metricsFromEnvelope,
99
+ rollupReadinessMetrics,
100
+ extractReadinessMetricsFromLifecycleReport
101
+ };