@aifabrix/builder 2.60.0 → 2.62.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 (177) hide show
  1. package/README.md +14 -11
  2. package/docs/README.md +80 -0
  3. package/docs/builder-help/evidence-patterns.json +155 -0
  4. package/docs/builder-help/golden-examples/crm-company.json +30 -0
  5. package/docs/builder-help/golden-examples/crm-deal.json +29 -0
  6. package/docs/builder-help/golden-examples/document-storage-keyed-get.json +85 -0
  7. package/docs/builder-help/golden-examples/document-storage.json +30 -0
  8. package/docs/builder-help/golden-examples/meeting-transcript.json +29 -0
  9. package/docs/builder-help/golden-examples/repository-template.json +29 -0
  10. package/docs/builder-help/golden-examples/service-ticket.json +29 -0
  11. package/docs/builder-help/platform-roles.json +98 -0
  12. package/docs/builder-help/resource-type-catalog.json +402 -0
  13. package/lib/api/applications.api.js +22 -2
  14. package/lib/api/bootstrap-snapshot.api.js +115 -0
  15. package/lib/api/configuration.api.js +131 -0
  16. package/lib/api/system-secrets.api.js +72 -0
  17. package/lib/app/deploy.js +14 -5
  18. package/lib/app/run-docker-fallback.js +6 -1
  19. package/lib/app/run-env-compose.js +5 -6
  20. package/lib/app/run-helpers.js +2 -1
  21. package/lib/app/run-parameter-sync.js +142 -0
  22. package/lib/app/run.js +6 -4
  23. package/lib/build/docker-build-args.js +5 -2
  24. package/lib/build/index.js +3 -2
  25. package/lib/build/standard-docker-build.js +6 -2
  26. package/lib/channels/channel-artifact-generator.js +13 -3
  27. package/lib/cli/infra-guided-footers.js +10 -8
  28. package/lib/cli/infra-guided.js +30 -10
  29. package/lib/cli/setup-app.js +5 -0
  30. package/lib/cli/setup-environment.js +156 -0
  31. package/lib/cli/setup-infra-up-platform-action.js +14 -1
  32. package/lib/cli/setup-platform.js +2 -0
  33. package/lib/commands/auth-config.js +2 -0
  34. package/lib/commands/datasource-capability-upsert-cli.js +112 -0
  35. package/lib/commands/datasource-capability.js +4 -2
  36. package/lib/commands/env-secret-context.js +113 -0
  37. package/lib/commands/env-secret-list.js +200 -0
  38. package/lib/commands/env-secret-push-confirm.js +54 -0
  39. package/lib/commands/env-secret-push-run.js +227 -0
  40. package/lib/commands/env-secret-push.js +168 -0
  41. package/lib/commands/login.js +4 -0
  42. package/lib/commands/repair-datasource-apply.js +5 -1
  43. package/lib/commands/repair-datasource-keyed-document.js +122 -0
  44. package/lib/commands/repair-datasource-legacy.js +94 -0
  45. package/lib/commands/repair-datasource-run.js +1 -0
  46. package/lib/commands/setup-image-refresh.js +26 -0
  47. package/lib/commands/setup-modes.js +8 -9
  48. package/lib/commands/setup-prompts-platform-mode.js +34 -0
  49. package/lib/commands/setup-prompts.js +2 -180
  50. package/lib/commands/setup.js +3 -0
  51. package/lib/commands/up-builder-api.js +24 -8
  52. package/lib/commands/up-common.js +16 -1
  53. package/lib/commands/up-dataplane-bootstrap.js +70 -14
  54. package/lib/commands/up-dataplane-credentials.js +21 -0
  55. package/lib/commands/up-dataplane.js +37 -18
  56. package/lib/commands/up-integration-server.js +112 -0
  57. package/lib/commands/verify-operations-skip-e2e.js +25 -1
  58. package/lib/commands/verify-operations-steps.js +13 -1
  59. package/lib/commands/wizard-config-normalizer.js +12 -5
  60. package/lib/commands/wizard-core.js +5 -157
  61. package/lib/commands/wizard-file-saving.js +163 -0
  62. package/lib/core/admin-secrets-env-overlay.js +8 -3
  63. package/lib/core/env-platform-expand.js +5 -1
  64. package/lib/core/environment-access-policy.js +121 -0
  65. package/lib/core/environment-mode-policy.js +177 -0
  66. package/lib/core/local-env-overrides.js +149 -0
  67. package/lib/core/secrets-ensure.js +4 -2
  68. package/lib/core/secrets-env-content.js +17 -10
  69. package/lib/core/secrets-env-write.js +11 -4
  70. package/lib/core/secrets-load.js +4 -2
  71. package/lib/datasource/binary-documents-validator.js +190 -0
  72. package/lib/datasource/capability/capability-manifest.js +1 -0
  73. package/lib/datasource/capability/run-capability-upsert.js +202 -0
  74. package/lib/datasource/capability/upsert-ingredients.js +291 -0
  75. package/lib/datasource/capability/upsert-operations.js +138 -0
  76. package/lib/datasource/capability/upsert-test-scaffold.js +189 -0
  77. package/lib/datasource/validate.js +12 -5
  78. package/lib/deployment/installation/index.js +14 -1
  79. package/lib/deployment/installation/infra-catalog.js +3 -0
  80. package/lib/deployment/installation/local-environment-stage.js +285 -0
  81. package/lib/deployment/installation/local-installation.js +76 -0
  82. package/lib/deployment/installation/stage-input.js +5 -1
  83. package/lib/generator/builders.js +3 -1
  84. package/lib/generator/index.js +3 -0
  85. package/lib/generator/split-variables.js +2 -2
  86. package/lib/lifecycle/product-model.js +4 -3
  87. package/lib/lifecycle/report-display.js +3 -2
  88. package/lib/parameters/database-adoption.js +125 -0
  89. package/lib/parameters/infra-parameter-catalog.js +1 -1
  90. package/lib/parameters/physical-database-naming.js +136 -0
  91. package/lib/parameters/physical-secret-name.js +194 -0
  92. package/lib/parameters/rsa-secret-values.js +165 -0
  93. package/lib/programmatic/builder-help-enterprise-sync-fabrix.js +1 -1
  94. package/lib/programmatic/builder-help-governance.js +1 -1
  95. package/lib/programmatic/builder-help.js +1 -1
  96. package/lib/programmatic/run-channel-install-artifacts.js +28 -2
  97. package/lib/programmatic/run-channel-package.js +3 -1
  98. package/lib/programmatic/workspace-context.js +37 -2
  99. package/lib/role-assistant/test-runner-workhub-answers.js +4 -1
  100. package/lib/role-assistant/test-runner-workhub-missing-fields.js +42 -0
  101. package/lib/role-assistant/test-runner-workhub-wait-stop.js +94 -0
  102. package/lib/role-assistant/test-runner-workhub.js +28 -19
  103. package/lib/schema/application-schema.json +14 -2
  104. package/lib/schema/external-datasource.schema.json +23 -3
  105. package/lib/schema/infra.parameter.yaml +440 -56
  106. package/lib/schema/infrastructure-schema.json +213 -120
  107. package/lib/utils/compose-generate-docker-compose.js +9 -14
  108. package/lib/utils/compose-generator.js +4 -7
  109. package/lib/utils/compose-miso-env.js +2 -2
  110. package/lib/utils/compose-traefik-ingress-base.js +3 -4
  111. package/lib/utils/datasource-binary-evidence.js +92 -0
  112. package/lib/utils/datasource-test-run-capability-scope.js +44 -1
  113. package/lib/utils/datasource-test-run-debug-display.js +2 -0
  114. package/lib/utils/datasource-test-run-display.js +8 -2
  115. package/lib/utils/datasource-test-run-issue-guidance.js +176 -0
  116. package/lib/utils/datasource-test-run-tty-log.js +2 -0
  117. package/lib/utils/declarative-url-ports.js +3 -0
  118. package/lib/utils/env-copy.js +11 -10
  119. package/lib/utils/env-environment-file-paths.js +105 -0
  120. package/lib/utils/environment-scoped-resources.js +48 -14
  121. package/lib/utils/external-system-system-test-tty.js +3 -2
  122. package/lib/utils/image-tags.js +2 -2
  123. package/lib/utils/paths-system-builder-keys.js +7 -1
  124. package/lib/utils/paths.js +7 -2
  125. package/lib/utils/platform-kv-ref.js +1 -1
  126. package/lib/utils/postgres-platform-bootstrap.js +35 -1
  127. package/lib/utils/prepare-local-data-mount.js +58 -0
  128. package/lib/utils/redis-env-scope.js +21 -1
  129. package/lib/utils/registry-auth-sources.js +154 -0
  130. package/lib/utils/registry-credentials.js +131 -14
  131. package/lib/utils/secrets-generator.js +30 -21
  132. package/lib/utils/secrets-helpers.js +5 -8
  133. package/lib/utils/secrets-kv-scope.js +127 -28
  134. package/lib/utils/secrets-materialize-local.js +9 -0
  135. package/lib/utils/secrets-missing-error.js +35 -1
  136. package/lib/utils/system-secret-mapping.js +125 -0
  137. package/lib/utils/test-log-writer.js +2 -1
  138. package/lib/utils/token-manager.js +14 -8
  139. package/lib/utils/url-public-path-prefix.js +6 -10
  140. package/lib/validation/external-manifest-validator.js +5 -0
  141. package/lib/validation/openapi-contract-surface-validator.js +3 -1
  142. package/lib/validation/validate-external-file.js +5 -1
  143. package/package.json +6 -4
  144. package/templates/agent-kit/agent-kit.yaml +1 -1
  145. package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +2 -1
  146. package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +15 -0
  147. package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +3 -2
  148. package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +6 -2
  149. package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +22 -0
  150. package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +7 -1
  151. package/templates/agent-kit/skills/aifabrix-role-assistant/references/testing-playbook.md +117 -0
  152. package/templates/agent-kit/skills/shared/interaction.md +83 -0
  153. package/templates/agent-kit/skills/shared/status.md +3 -12
  154. package/templates/applications/builder-api/application.yaml +1 -1
  155. package/templates/applications/builder-api/env.template +5 -1
  156. package/templates/applications/dataplane/application.yaml +2 -2
  157. package/templates/applications/dataplane/env.template +10 -12
  158. package/templates/applications/integration-server/application.yaml +91 -0
  159. package/templates/applications/integration-server/env.template +215 -0
  160. package/templates/applications/keycloak/application.yaml +6 -1
  161. package/templates/applications/mirrored-templates.json +52 -0
  162. package/templates/applications/miso-controller/application.yaml +116 -2
  163. package/templates/applications/miso-controller/env.template +62 -17
  164. package/templates/applications/miso-controller/rbac.yaml +17 -0
  165. package/templates/external-system/external-datasource.yaml.hbs +7 -1
  166. package/templates/marketplace/createUiDefinition.json +52 -4
  167. package/templates/marketplace/main.json +88 -10
  168. package/templates/python/docker-compose.hbs +1 -1
  169. package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +0 -41
  170. /package/{lib/programmatic/help-content → docs/builder-help/content}/channel-onboarding.md +0 -0
  171. /package/{lib/programmatic/help-content → docs/builder-help/content}/cip-overview.md +0 -0
  172. /package/{lib/programmatic/help-content → docs/builder-help/content}/connected-system-ui.md +0 -0
  173. /package/{lib/programmatic/help-content → docs/builder-help/content}/dimensions-guide.md +0 -0
  174. /package/{lib/programmatic/help-content → docs/builder-help/content}/enterprise-sync-fabrix.md +0 -0
  175. /package/{lib/programmatic/help-content → docs/builder-help/content}/overview.md +0 -0
  176. /package/{lib/programmatic/help-content → docs/builder-help/content}/subscription-guide.md +0 -0
  177. /package/{lib/programmatic/help-content → docs/builder-help/content}/workflow.md +0 -0
@@ -5,7 +5,7 @@
5
5
  "_generator": {
6
6
  "name": "bicep",
7
7
  "version": "0.47.16.16243",
8
- "templateHash": "6752412774681258733"
8
+ "templateHash": "703508813427294425"
9
9
  }
10
10
  },
11
11
  "parameters": {
@@ -165,6 +165,13 @@
165
165
  "description": "Mori licence issuer public key in SPKI PEM form. Empty leaves the installation unpinned, and Miso then refuses a licence rather than trusting a key carried inside it."
166
166
  }
167
167
  },
168
+ "moriPolicyPublicKey": {
169
+ "type": "string",
170
+ "defaultValue": "",
171
+ "metadata": {
172
+ "description": "Mori policy signing anchor public key in SPKI PEM form. A different pair from the licence key. Empty leaves the policy bundle without an independent anchor, so it can only be checked against the key it carries."
173
+ }
174
+ },
168
175
  "moriLicenseIssuer": {
169
176
  "type": "string",
170
177
  "defaultValue": "mori-controller",
@@ -214,6 +221,21 @@
214
221
  "description": "License the installation requests from Mori during tenant activation: an edition name (COMMUNITY, STANDARD, ENTERPRISE) or an Azure Marketplace subscription ID (UUID). Plain string — Miso validates it. Emitted as LICENSE_EDITION."
215
222
  }
216
223
  },
224
+ "adminEmail": {
225
+ "type": "string",
226
+ "minLength": 3,
227
+ "metadata": {
228
+ "description": "Email of the initial platform administrator, used for the installation welcome."
229
+ }
230
+ },
231
+ "installationResourceModel": {
232
+ "type": "string",
233
+ "defaultValue": "shared",
234
+ "allowedValues": ["shared", "dedicated"],
235
+ "metadata": {
236
+ "description": "Initial installation topology, protected by Azure application configuration: shared for CE/SE; dedicated for EE DEV. Does not grant later licence entitlements."
237
+ }
238
+ },
217
239
  "onboardingMode": {
218
240
  "type": "string",
219
241
  "defaultValue": "customerOwned",
@@ -1047,7 +1069,7 @@
1047
1069
  "_generator": {
1048
1070
  "name": "bicep",
1049
1071
  "version": "0.47.16.16243",
1050
- "templateHash": "11131379543865133238"
1072
+ "templateHash": "9369439869727192513"
1051
1073
  }
1052
1074
  },
1053
1075
  "parameters": {
@@ -1099,7 +1121,7 @@
1099
1121
  {
1100
1122
  "type": "Microsoft.KeyVault/vaults/secrets",
1101
1123
  "apiVersion": "2023-07-01",
1102
- "name": "[format('{0}/{1}', parameters('keyVaultName'), 'azureopenai-endpoint')]",
1124
+ "name": "[format('{0}/{1}', parameters('keyVaultName'), 'dev-dataplane-azure-openai-endpoint')]",
1103
1125
  "properties": {
1104
1126
  "value": "[reference(resourceId('Microsoft.CognitiveServices/accounts', variables('accountName')), '2023-05-01').endpoint]"
1105
1127
  },
@@ -1110,7 +1132,7 @@
1110
1132
  {
1111
1133
  "type": "Microsoft.KeyVault/vaults/secrets",
1112
1134
  "apiVersion": "2023-07-01",
1113
- "name": "[format('{0}/{1}', parameters('keyVaultName'), 'azureopenai-apikey')]",
1135
+ "name": "[format('{0}/{1}', parameters('keyVaultName'), 'dev-dataplane-azure-openai-api-key')]",
1114
1136
  "properties": {
1115
1137
  "value": "[listKeys(resourceId('Microsoft.CognitiveServices/accounts', variables('accountName')), '2023-05-01').key1]"
1116
1138
  },
@@ -2216,7 +2238,7 @@
2216
2238
  "_generator": {
2217
2239
  "name": "bicep",
2218
2240
  "version": "0.47.16.16243",
2219
- "templateHash": "10929433789276981779"
2241
+ "templateHash": "6426728474798954933"
2220
2242
  }
2221
2243
  },
2222
2244
  "parameters": {
@@ -2409,7 +2431,7 @@
2409
2431
  "appCommandLine": "start --optimized=false",
2410
2432
  "healthCheckPath": "[variables('keycloakHealthCheckPath')]",
2411
2433
  "alwaysOn": true,
2412
- "appSettings": "[concat(createArray(createObject('name', 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', 'value', 'false'), createObject('name', 'WEBSITES_PORT', 'value', '8080'), createObject('name', 'KEYCLOAK_ADMIN', 'value', parameters('keycloakAdminUser')), createObject('name', 'KEYCLOAK_ADMIN_PASSWORD', 'value', format('@Microsoft.KeyVault(SecretUri={0})', reference(resourceId('Microsoft.KeyVault/vaults/secrets', last(split(parameters('keyVaultId'), '/')), format('{0}-keycloak-admin-password', parameters('prefix'))), '2023-07-01').secretUriWithVersion)), createObject('name', 'KC_DB', 'value', 'postgres'), createObject('name', 'KC_DB_URL_HOST', 'value', parameters('postgresServerFqdn')), createObject('name', 'KC_DB_URL_DATABASE', 'value', parameters('postgresDatabaseName')), createObject('name', 'KC_DB_URL_PORT', 'value', '5432'), createObject('name', 'KC_DB_URL', 'value', format('jdbc:postgresql://{0}:5432/{1}', parameters('postgresServerFqdn'), parameters('postgresDatabaseName'))), createObject('name', 'KC_DB_USERNAME', 'value', parameters('postgresAdminLogin')), createObject('name', 'KC_DB_PASSWORD', 'value', format('@Microsoft.KeyVault(SecretUri={0})', reference(resourceId('Microsoft.KeyVault/vaults/secrets', last(split(parameters('keyVaultId'), '/')), format('{0}-postgres-admin-password', parameters('prefix'))), '2023-07-01').secretUriWithVersion)), createObject('name', 'KC_HOSTNAME', 'value', format('{0}.azurewebsites.net', parameters('name'))), createObject('name', 'KC_HOSTNAME_URL', 'value', format('https://{0}.azurewebsites.net', parameters('name'))), createObject('name', 'KC_HOSTNAME_ADMIN_URL', 'value', format('https://{0}.azurewebsites.net', parameters('name'))), createObject('name', 'KC_HOSTNAME_STRICT', 'value', 'false'), createObject('name', 'KC_HOSTNAME_STRICT_BACKEND', 'value', 'false'), createObject('name', 'KC_HOSTNAME_STRICT_HTTPS', 'value', 'false'), createObject('name', 'KC_HTTP_ENABLED', 'value', 'true'), createObject('name', 'KC_HTTP_RELATIVE_PATH', 'value', variables('keycloakHttpRelativePath')), createObject('name', 'KC_HTTP_MANAGEMENT_ENABLED', 'value', 'true'), createObject('name', 'KC_HTTP_MANAGEMENT_PORT', 'value', '9000'), createObject('name', 'KC_HTTP_MANAGEMENT_HEALTH_ENABLED', 'value', 'false'), createObject('name', 'KC_PROXY', 'value', 'edge'), createObject('name', 'KC_PROXY_HEADERS', 'value', 'xforwarded'), createObject('name', 'KC_PROXY_HEADERS_FORWARDED', 'value', 'true'), createObject('name', 'KC_HEALTH_ENABLED', 'value', 'true'), createObject('name', 'KC_CACHE', 'value', 'local'), createObject('name', 'KC_FEATURES', 'value', 'preview,cimd'), createObject('name', 'KC_SPI_EMAIL_SENDER__PROVIDER', 'value', 'mori'), createObject('name', 'KC_METRICS_ENABLED', 'value', 'true'), createObject('name', 'WEBSITE_VNET_ROUTE_ALL', 'value', if(parameters('enablePostgresPublicAccess'), '0', '1')), createObject('name', 'WEBSITE_DNS_SERVER', 'value', '168.63.129.16'), createObject('name', 'WEBSITES_CONTAINER_START_TIME_LIMIT', 'value', '1800'), createObject('name', 'KC_LOG', 'value', 'console'), createObject('name', 'KC_LOG_LEVEL', 'value', 'INFO')), variables('appInsightsAppSettings'), variables('acrRegistryUrlAppSettings'), variables('acrRegistryCredentialAppSettings'))]",
2434
+ "appSettings": "[concat(createArray(createObject('name', 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', 'value', 'false'), createObject('name', 'WEBSITES_PORT', 'value', '8080'), createObject('name', 'KEYCLOAK_ADMIN', 'value', parameters('keycloakAdminUser')), createObject('name', 'KEYCLOAK_ADMIN_PASSWORD', 'value', format('@Microsoft.KeyVault(SecretUri={0})', reference(resourceId('Microsoft.KeyVault/vaults/secrets', last(split(parameters('keyVaultId'), '/')), format('{0}-keycloak-admin-password', parameters('prefix'))), '2023-07-01').secretUriWithVersion)), createObject('name', 'KC_DB', 'value', 'postgres'), createObject('name', 'KC_DB_URL_HOST', 'value', parameters('postgresServerFqdn')), createObject('name', 'KC_DB_URL_DATABASE', 'value', parameters('postgresDatabaseName')), createObject('name', 'KC_DB_URL_PORT', 'value', '5432'), createObject('name', 'KC_DB_URL', 'value', format('jdbc:postgresql://{0}:5432/{1}', parameters('postgresServerFqdn'), parameters('postgresDatabaseName'))), createObject('name', 'KC_DB_USERNAME', 'value', parameters('postgresAdminLogin')), createObject('name', 'KC_DB_PASSWORD', 'value', format('@Microsoft.KeyVault(SecretUri={0})', reference(resourceId('Microsoft.KeyVault/vaults/secrets', last(split(parameters('keyVaultId'), '/')), format('{0}-postgres-admin-password', parameters('prefix'))), '2023-07-01').secretUriWithVersion)), createObject('name', 'KC_HOSTNAME_STRICT', 'value', 'false'), createObject('name', 'KC_HOSTNAME_BACKCHANNEL_DYNAMIC', 'value', 'false'), createObject('name', 'KC_HOSTNAME_STRICT_BACKEND', 'value', 'false'), createObject('name', 'KC_HOSTNAME_STRICT_HTTPS', 'value', 'false'), createObject('name', 'KC_HTTP_ENABLED', 'value', 'true'), createObject('name', 'KC_HTTP_RELATIVE_PATH', 'value', variables('keycloakHttpRelativePath')), createObject('name', 'KC_HTTP_MANAGEMENT_ENABLED', 'value', 'true'), createObject('name', 'KC_HTTP_MANAGEMENT_PORT', 'value', '9000'), createObject('name', 'KC_HTTP_MANAGEMENT_HEALTH_ENABLED', 'value', 'false'), createObject('name', 'KC_PROXY', 'value', 'edge'), createObject('name', 'KC_PROXY_HEADERS', 'value', 'xforwarded'), createObject('name', 'KC_PROXY_HEADERS_FORWARDED', 'value', 'true'), createObject('name', 'KC_HEALTH_ENABLED', 'value', 'true'), createObject('name', 'KC_CACHE', 'value', 'local'), createObject('name', 'KC_FEATURES', 'value', 'preview,cimd'), createObject('name', 'KC_SPI_EMAIL_SENDER__PROVIDER', 'value', 'mori'), createObject('name', 'KC_METRICS_ENABLED', 'value', 'true'), createObject('name', 'WEBSITE_VNET_ROUTE_ALL', 'value', if(parameters('enablePostgresPublicAccess'), '0', '1')), createObject('name', 'WEBSITE_DNS_SERVER', 'value', '168.63.129.16'), createObject('name', 'WEBSITES_CONTAINER_START_TIME_LIMIT', 'value', '1800'), createObject('name', 'KC_LOG', 'value', 'console'), createObject('name', 'KC_LOG_LEVEL', 'value', 'INFO')), variables('appInsightsAppSettings'), variables('acrRegistryUrlAppSettings'), variables('acrRegistryCredentialAppSettings'))]",
2413
2435
  "vnetRouteAllEnabled": "[not(parameters('enablePostgresPublicAccess'))]"
2414
2436
  },
2415
2437
  "vnetRouteAllEnabled": "[not(parameters('enablePostgresPublicAccess'))]"
@@ -2524,6 +2546,9 @@
2524
2546
  "moriLicensePublicKey": {
2525
2547
  "value": "[parameters('moriLicensePublicKey')]"
2526
2548
  },
2549
+ "moriPolicyPublicKey": {
2550
+ "value": "[parameters('moriPolicyPublicKey')]"
2551
+ },
2527
2552
  "moriBaseUrl": {
2528
2553
  "value": "[parameters('moriBaseUrl')]"
2529
2554
  }
@@ -2535,7 +2560,7 @@
2535
2560
  "_generator": {
2536
2561
  "name": "bicep",
2537
2562
  "version": "0.47.16.16243",
2538
- "templateHash": "445562478593270876"
2563
+ "templateHash": "4650500285752133401"
2539
2564
  }
2540
2565
  },
2541
2566
  "parameters": {
@@ -2618,6 +2643,13 @@
2618
2643
  "description": "Mori licence issuer public key (SPKI PEM). Empty leaves the installation unpinned."
2619
2644
  }
2620
2645
  },
2646
+ "moriPolicyPublicKey": {
2647
+ "type": "string",
2648
+ "defaultValue": "",
2649
+ "metadata": {
2650
+ "description": "Mori policy signing anchor public key (SPKI PEM). Empty leaves the policy bundle without an independent anchor."
2651
+ }
2652
+ },
2621
2653
  "moriBaseUrl": {
2622
2654
  "type": "string",
2623
2655
  "defaultValue": "",
@@ -2735,6 +2767,15 @@
2735
2767
  "value": "[parameters('moriLicensePublicKey')]"
2736
2768
  }
2737
2769
  },
2770
+ {
2771
+ "condition": "[not(empty(parameters('moriPolicyPublicKey')))]",
2772
+ "type": "Microsoft.KeyVault/vaults/secrets",
2773
+ "apiVersion": "2023-07-01",
2774
+ "name": "[format('{0}/{1}', parameters('keyVaultName'), 'mori-policy-public-keyKeyVault')]",
2775
+ "properties": {
2776
+ "value": "[parameters('moriPolicyPublicKey')]"
2777
+ }
2778
+ },
2738
2779
  {
2739
2780
  "condition": "[not(empty(parameters('moriBaseUrl')))]",
2740
2781
  "type": "Microsoft.KeyVault/vaults/secrets",
@@ -2856,9 +2897,15 @@
2856
2897
  "entraIdTenantId": {
2857
2898
  "value": "[variables('effectiveEntraIdTenantId')]"
2858
2899
  },
2900
+ "adminEmail": {
2901
+ "value": "[parameters('adminEmail')]"
2902
+ },
2859
2903
  "licenseEdition": {
2860
2904
  "value": "[parameters('licenseEdition')]"
2861
2905
  },
2906
+ "installationResourceModel": {
2907
+ "value": "[parameters('installationResourceModel')]"
2908
+ },
2862
2909
  "onboardingMode": {
2863
2910
  "value": "[parameters('onboardingMode')]"
2864
2911
  },
@@ -2879,7 +2926,7 @@
2879
2926
  "_generator": {
2880
2927
  "name": "bicep",
2881
2928
  "version": "0.47.16.16243",
2882
- "templateHash": "13342696621269025420"
2929
+ "templateHash": "9991546815810387946"
2883
2930
  }
2884
2931
  },
2885
2932
  "parameters": {
@@ -3110,6 +3157,21 @@
3110
3157
  "description": "Requested license: edition name (COMMUNITY, STANDARD, ENTERPRISE) or Azure Marketplace subscription ID (UUID). Validated by Miso. Emitted as LICENSE_EDITION."
3111
3158
  }
3112
3159
  },
3160
+ "adminEmail": {
3161
+ "type": "string",
3162
+ "defaultValue": "",
3163
+ "metadata": {
3164
+ "description": "Initial platform administrator email."
3165
+ }
3166
+ },
3167
+ "installationResourceModel": {
3168
+ "type": "string",
3169
+ "defaultValue": "shared",
3170
+ "allowedValues": ["shared", "dedicated"],
3171
+ "metadata": {
3172
+ "description": "Initial installation topology, protected by Azure application configuration: shared for CE/SE; dedicated for EE DEV. Does not grant later licence entitlements."
3173
+ }
3174
+ },
3113
3175
  "onboardingMode": {
3114
3176
  "type": "string",
3115
3177
  "defaultValue": "customerOwned",
@@ -3206,7 +3268,7 @@
3206
3268
  "acrUseManagedIdentityCreds": "[not(parameters('registryPasswordConfigured'))]",
3207
3269
  "healthCheckPath": "/health",
3208
3270
  "alwaysOn": true,
3209
- "appSettings": "[concat(createArray(createObject('name', 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', 'value', 'false'), createObject('name', 'WEBSITES_CONTAINER_START_TIME_LIMIT', 'value', '1800'), createObject('name', 'DATABASE_URL', 'value', variables('databaseUrlAppSettingValue')), createObject('name', 'JWT_SECRET', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-secrets-jwtKeyVault)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'NODE_ENV', 'value', 'production'), createObject('name', 'LOCATION', 'value', parameters('location')), createObject('name', 'PORT', 'value', '3000'), createObject('name', 'ALLOWED_ORIGINS', 'value', format('http://localhost:*,http://127.0.0.1:*,https://{0}.azurewebsites.net', parameters('name'))), createObject('name', 'WEBSITE_VNET_ROUTE_ALL', 'value', if(parameters('enablePostgresPublicAccess'), '0', '1')), createObject('name', 'WEBSITE_DNS_SERVER', 'value', '168.63.129.16'), createObject('name', 'DATABASELOG_URL', 'value', variables('databaseLogUrlAppSettingValue')), createObject('name', 'KEY_VAULT_ENABLED', 'value', 'true'), createObject('name', 'SECURITY_STORAGE_MODE', 'value', 'keyvault'), createObject('name', 'KEY_VAULT_URL', 'value', format('https://{0}.vault.azure.net/', last(split(parameters('keyVaultId'), '/')))), createObject('name', 'ENCRYPTION_KEY', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-encryption-keyKeyVault)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'AUTO_CREATE_TABLES', 'value', if(parameters('autoCreateTables'), 'true', 'false')), createObject('name', 'KEYCLOAK_REALM', 'value', parameters('keycloakRealm')), createObject('name', 'KEYCLOAK_CLIENT_ID', 'value', parameters('keycloakClientId')), createObject('name', 'KEYCLOAK_ADMIN_USERNAME', 'value', parameters('keycloakAdminUsername')), createObject('name', 'KEYCLOAK_ADMIN_PASSWORD', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-keycloak-admin-password)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'ONBOARDING_ADMIN_PASSWORD', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-onboarding-admin-password)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'KEYCLOAK_SERVER_URL', 'value', variables('keycloakPublicUrl')), createObject('name', 'KEYCLOAK_INTERNAL_SERVER_URL', 'value', variables('keycloakInternalUrl')), createObject('name', 'KEYCLOAK_TOKEN_TIMEOUT', 'value', '5000'), createObject('name', 'KEYCLOAK_VERIFY_AUDIENCE', 'value', if(parameters('keycloakVerifyAudience'), 'true', 'false')), createObject('name', 'DISABLE_RATE_LIMIT', 'value', variables('shouldDisableRateLimit')), createObject('name', 'SKIP_DB_REDEPLOY', 'value', 'true'), createObject('name', 'MISO_WEB_SERVER_URL', 'value', variables('misoPublicUrl')), createObject('name', 'MISO_CONTROLLER_URL', 'value', variables('misoInternalUrl')), createObject('name', 'MISO_RELATIVE_PATH', 'value', variables('misoVdirValue')), createObject('name', 'CONTROLLER_BASE_URL', 'value', if(not(empty(parameters('misoControllerUrl'))), parameters('misoControllerUrl'), format('https://{0}.azurewebsites.net', parameters('name')))), createObject('name', 'AZURE_SUBSCRIPTION_ID', 'value', subscription().subscriptionId), createObject('name', 'TENANT_ID', 'value', subscription().tenantId), createObject('name', 'DEPLOYMENT', 'value', 'azure'), createObject('name', 'AZURE_RESOURCE_GROUP_NAME', 'value', parameters('resourceGroupName')), createObject('name', 'INFRASTRUCTURE_NAME', 'value', parameters('prefix')), createObject('name', 'ENTRA_ID_TENANT_ID', 'value', parameters('entraIdTenantId')), createObject('name', 'MISO_CLIENTID', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-miso-clientIdKeyVault)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'MISO_CLIENTSECRET', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName=miso-controller-client-secretKeyVault)', last(split(parameters('keyVaultId'), '/')))), createObject('name', 'MORI_BASE_URL', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName=mori-base-urlKeyVault)', last(split(parameters('keyVaultId'), '/')))), createObject('name', 'MORI_LICENSE_PUBLIC_KEY', 'value', if(empty(parameters('moriLicensePublicKey')), '', format('@Microsoft.KeyVault(VaultName={0};SecretName=mori-license-public-keyKeyVault)', last(split(parameters('keyVaultId'), '/'))))), createObject('name', 'MORI_LICENSE_ISSUER', 'value', parameters('moriLicenseIssuer')), createObject('name', 'ENTRA_GRAPH_DELEGATED_REDIRECT_URI', 'value', variables('moriEntraGraphDelegatedRedirectUri')), createObject('name', 'ENTRA_ID_CENTRAL_CALLBACK_URI', 'value', variables('moriEntraCentralCallbackUri')), createObject('name', 'DOCKER_ENABLE_CI', 'value', 'true'), createObject('name', 'DOCKER_REGISTRY_SERVER_URL', 'value', if(not(empty(parameters('acrLoginServer'))), format('https://{0}', parameters('acrLoginServer')), '')), createObject('name', 'ONBOARDING_CREATE_PIPELINE_CREDENTIALS', 'value', 'true'), createObject('name', 'BOOTSTRAP_APPKEYS', 'value', parameters('bootstrapAppKeys')), createObject('name', 'LICENSE_JWT', 'value', parameters('licenseJwt')), createObject('name', 'LICENSE_EDITION', 'value', parameters('licenseEdition')), createObject('name', 'ONBOARDING_MODE', 'value', parameters('onboardingMode')), createObject('name', 'INSTALLATION_CAPACITY_PROFILE', 'value', parameters('capacityProfile'))), variables('registryCredentialAppSettings'))]",
3271
+ "appSettings": "[concat(createArray(createObject('name', 'WEBSITES_ENABLE_APP_SERVICE_STORAGE', 'value', 'false'), createObject('name', 'WEBSITES_CONTAINER_START_TIME_LIMIT', 'value', '1800'), createObject('name', 'DATABASE_URL', 'value', variables('databaseUrlAppSettingValue')), createObject('name', 'JWT_SECRET', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-secrets-jwtKeyVault)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'NODE_ENV', 'value', 'production'), createObject('name', 'LOCATION', 'value', parameters('location')), createObject('name', 'PORT', 'value', '3000'), createObject('name', 'ALLOWED_ORIGINS', 'value', format('http://localhost:*,http://127.0.0.1:*,https://{0}.azurewebsites.net', parameters('name'))), createObject('name', 'WEBSITE_VNET_ROUTE_ALL', 'value', if(parameters('enablePostgresPublicAccess'), '0', '1')), createObject('name', 'WEBSITE_DNS_SERVER', 'value', '168.63.129.16'), createObject('name', 'DATABASELOG_URL', 'value', variables('databaseLogUrlAppSettingValue')), createObject('name', 'KEY_VAULT_ENABLED', 'value', 'true'), createObject('name', 'SECURITY_STORAGE_MODE', 'value', 'keyvault'), createObject('name', 'KEY_VAULT_URL', 'value', format('https://{0}.vault.azure.net/', last(split(parameters('keyVaultId'), '/')))), createObject('name', 'ENCRYPTION_KEY', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-encryption-keyKeyVault)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'AUTO_CREATE_TABLES', 'value', if(parameters('autoCreateTables'), 'true', 'false')), createObject('name', 'KEYCLOAK_REALM', 'value', parameters('keycloakRealm')), createObject('name', 'KEYCLOAK_CLIENT_ID', 'value', parameters('keycloakClientId')), createObject('name', 'KEYCLOAK_ADMIN_USERNAME', 'value', parameters('keycloakAdminUsername')), createObject('name', 'KEYCLOAK_ADMIN_PASSWORD', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-keycloak-admin-password)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'ONBOARDING_ADMIN_PASSWORD', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-onboarding-admin-password)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'ONBOARDING_ADMIN_EMAIL', 'value', parameters('adminEmail')), createObject('name', 'KEYCLOAK_SERVER_URL', 'value', variables('keycloakPublicUrl')), createObject('name', 'KEYCLOAK_INTERNAL_SERVER_URL', 'value', variables('keycloakInternalUrl')), createObject('name', 'KEYCLOAK_TOKEN_TIMEOUT', 'value', '5000'), createObject('name', 'KEYCLOAK_VERIFY_AUDIENCE', 'value', if(parameters('keycloakVerifyAudience'), 'true', 'false')), createObject('name', 'DISABLE_RATE_LIMIT', 'value', variables('shouldDisableRateLimit')), createObject('name', 'SKIP_DB_REDEPLOY', 'value', 'true'), createObject('name', 'MISO_WEB_SERVER_URL', 'value', variables('misoPublicUrl')), createObject('name', 'MISO_CONTROLLER_URL', 'value', variables('misoInternalUrl')), createObject('name', 'MISO_RELATIVE_PATH', 'value', variables('misoVdirValue')), createObject('name', 'CONTROLLER_BASE_URL', 'value', if(not(empty(parameters('misoControllerUrl'))), parameters('misoControllerUrl'), format('https://{0}.azurewebsites.net', parameters('name')))), createObject('name', 'AZURE_SUBSCRIPTION_ID', 'value', subscription().subscriptionId), createObject('name', 'TENANT_ID', 'value', subscription().tenantId), createObject('name', 'DEPLOYMENT', 'value', 'azure'), createObject('name', 'AZURE_RESOURCE_GROUP_NAME', 'value', parameters('resourceGroupName')), createObject('name', 'INFRASTRUCTURE_NAME', 'value', parameters('prefix')), createObject('name', 'ENTRA_ID_TENANT_ID', 'value', parameters('entraIdTenantId')), createObject('name', 'MISO_CLIENTID', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName={1}-miso-clientIdKeyVault)', last(split(parameters('keyVaultId'), '/')), parameters('prefix'))), createObject('name', 'MISO_CLIENTSECRET', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName=miso-controller-client-secretKeyVault)', last(split(parameters('keyVaultId'), '/')))), createObject('name', 'MORI_BASE_URL', 'value', format('@Microsoft.KeyVault(VaultName={0};SecretName=mori-base-urlKeyVault)', last(split(parameters('keyVaultId'), '/')))), createObject('name', 'MORI_LICENSE_PUBLIC_KEY', 'value', if(empty(parameters('moriLicensePublicKey')), '', format('@Microsoft.KeyVault(VaultName={0};SecretName=mori-license-public-keyKeyVault)', last(split(parameters('keyVaultId'), '/'))))), createObject('name', 'MORI_LICENSE_ISSUER', 'value', parameters('moriLicenseIssuer')), createObject('name', 'ENTRA_GRAPH_DELEGATED_REDIRECT_URI', 'value', variables('moriEntraGraphDelegatedRedirectUri')), createObject('name', 'ENTRA_ID_CENTRAL_CALLBACK_URI', 'value', variables('moriEntraCentralCallbackUri')), createObject('name', 'DOCKER_ENABLE_CI', 'value', 'true'), createObject('name', 'DOCKER_REGISTRY_SERVER_URL', 'value', if(not(empty(parameters('acrLoginServer'))), format('https://{0}', parameters('acrLoginServer')), '')), createObject('name', 'ONBOARDING_CREATE_PIPELINE_CREDENTIALS', 'value', 'true'), createObject('name', 'BOOTSTRAP_APPKEYS', 'value', parameters('bootstrapAppKeys')), createObject('name', 'LICENSE_JWT', 'value', parameters('licenseJwt')), createObject('name', 'INSTALLATION_RESOURCE_MODEL', 'value', parameters('installationResourceModel')), createObject('name', 'LICENSE_EDITION', 'value', parameters('licenseEdition')), createObject('name', 'ONBOARDING_MODE', 'value', parameters('onboardingMode')), createObject('name', 'INSTALLATION_CAPACITY_PROFILE', 'value', parameters('capacityProfile'))), variables('registryCredentialAppSettings'))]",
3210
3272
  "vnetRouteAllEnabled": "[not(parameters('enablePostgresPublicAccess'))]"
3211
3273
  },
3212
3274
  "vnetRouteAllEnabled": "[not(parameters('enablePostgresPublicAccess'))]"
@@ -3613,7 +3675,7 @@
3613
3675
  "_generator": {
3614
3676
  "name": "bicep",
3615
3677
  "version": "0.47.16.16243",
3616
- "templateHash": "445562478593270876"
3678
+ "templateHash": "4650500285752133401"
3617
3679
  }
3618
3680
  },
3619
3681
  "parameters": {
@@ -3696,6 +3758,13 @@
3696
3758
  "description": "Mori licence issuer public key (SPKI PEM). Empty leaves the installation unpinned."
3697
3759
  }
3698
3760
  },
3761
+ "moriPolicyPublicKey": {
3762
+ "type": "string",
3763
+ "defaultValue": "",
3764
+ "metadata": {
3765
+ "description": "Mori policy signing anchor public key (SPKI PEM). Empty leaves the policy bundle without an independent anchor."
3766
+ }
3767
+ },
3699
3768
  "moriBaseUrl": {
3700
3769
  "type": "string",
3701
3770
  "defaultValue": "",
@@ -3813,6 +3882,15 @@
3813
3882
  "value": "[parameters('moriLicensePublicKey')]"
3814
3883
  }
3815
3884
  },
3885
+ {
3886
+ "condition": "[not(empty(parameters('moriPolicyPublicKey')))]",
3887
+ "type": "Microsoft.KeyVault/vaults/secrets",
3888
+ "apiVersion": "2023-07-01",
3889
+ "name": "[format('{0}/{1}', parameters('keyVaultName'), 'mori-policy-public-keyKeyVault')]",
3890
+ "properties": {
3891
+ "value": "[parameters('moriPolicyPublicKey')]"
3892
+ }
3893
+ },
3816
3894
  {
3817
3895
  "condition": "[not(empty(parameters('moriBaseUrl')))]",
3818
3896
  "type": "Microsoft.KeyVault/vaults/secrets",
@@ -327,4 +327,4 @@ volumes:
327
327
 
328
328
  networks:
329
329
  {{networkName}}:
330
- external: true
330
+ external: true
@@ -1,41 +0,0 @@
1
- # Phase and result interaction
2
-
3
- Use structured questions. Do not start the next phase from chat prose alone.
4
-
5
- ## After success
6
-
7
- Offer the next eligible phase. Proceed only on `next-yes`.
8
-
9
- Shared option ids: `next-yes` · `next-no` · `next-stop`.
10
-
11
- | Completed | Next offer |
12
- | --- | --- |
13
- | aifabrix-plan PLAN_READY | connected-system validate |
14
- | connected-system READY | connected-system build |
15
- | connected-system BUILT | connected-system publish |
16
- | connected-system PASS or PASS_WITH_SKIPS | archive (separate) and/or prove validate |
17
- | prove READY / BUILT / UPDATED | prove next phase |
18
- | prove PASS or PASS_WITH_SKIPS | iterate validate/build |
19
-
20
- Archive is a distinct user decision (`archive-yes` / `archive-no`). Never archive as a side effect of PASS.
21
-
22
- ## On gaps
23
-
24
- - NEEDS_DECISIONS: AskQuestion challenge rows. No `cust-next`.
25
- - BLOCKED / FAIL / NEEDS_FIXES / ABORTED: do not offer the next phase as if success.
26
-
27
- A phase gate is per-gate, not overall. Offer the next phase only when the **Delivery** row
28
- supports it; a passing package gate beside `Delivery: NEEDS_FIXES` is not success and the
29
- offer must name what is still open.
30
-
31
- ## Phase detection (connected-system and prove)
32
-
33
- 1. Explicit phase from the user
34
- 2. Ask, offering the routes in [status.md](../../shared/status.md)
35
-
36
- There is no third step. Package and plan state decide what you *recommend*, never what you
37
- run: a bare invocation reports status and stops ([status.md](../../shared/status.md)).
38
- Inferring "the safe next eligible phase" is what makes a skill start working before the
39
- user has said what they want.
40
-
41
- Never silently run the following phase after success.