@aifabrix/builder 2.51.0 → 2.52.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 (198) hide show
  1. package/jest.isolated-projects.js +77 -1
  2. package/jest.projects.js +5 -426
  3. package/lib/api/assistants.api.js +67 -0
  4. package/lib/api/datasources-extended.api.js +6 -6
  5. package/lib/api/evidence-authoring-helpers.js +267 -0
  6. package/lib/api/evidence-authoring.api.js +337 -0
  7. package/lib/api/evidence.api.js +57 -1
  8. package/lib/api/index.js +24 -7
  9. package/lib/api/pipeline.api.js +43 -3
  10. package/lib/api/records-bulk.api.js +28 -3
  11. package/lib/api/types/evidence.types.js +156 -8
  12. package/lib/api/work.api.js +283 -0
  13. package/lib/app/run-container-start.js +4 -0
  14. package/lib/app/run-deploy-job.js +216 -0
  15. package/lib/app/run-env-compose.js +32 -0
  16. package/lib/app/run-env-recovery.js +35 -0
  17. package/lib/app/run-helpers.js +15 -9
  18. package/lib/app/run.js +18 -2
  19. package/lib/channels/add-channel.js +54 -23
  20. package/lib/channels/approval-guides/chatgpt.js +13 -9
  21. package/lib/channels/approval-guides/microsoft-copilot.js +7 -8
  22. package/lib/channels/channel-artifact-generator.js +14 -2
  23. package/lib/channels/channel-credential.js +3 -1
  24. package/lib/channels/channel-probe-evidence.js +79 -0
  25. package/lib/channels/channel-probe.js +265 -13
  26. package/lib/channels/channel-runtime-resolver.js +120 -29
  27. package/lib/channels/channel-status-display.js +44 -0
  28. package/lib/channels/channel-targets.js +25 -1
  29. package/lib/channels/chatgpt-runtime-contract.js +29 -0
  30. package/lib/channels/microsoft-copilot-package.js +280 -0
  31. package/lib/channels/runtime-tool-catalog.js +165 -0
  32. package/lib/cli/index.js +2 -0
  33. package/lib/cli/infra-guided-footers.js +1 -1
  34. package/lib/cli/infra-guided-public-url-warn.js +55 -0
  35. package/lib/cli/infra-guided.js +65 -56
  36. package/lib/cli/setup-app.help.js +4 -0
  37. package/lib/cli/setup-app.js +4 -0
  38. package/lib/cli/setup-app.test-commands.js +59 -28
  39. package/lib/cli/setup-external-system-help.js +8 -2
  40. package/lib/cli/setup-external-system.js +62 -12
  41. package/lib/commands/app-test.js +2 -14
  42. package/lib/commands/channel-add-setup.js +8 -2
  43. package/lib/commands/channel.js +16 -5
  44. package/lib/commands/datasource-load-export-cli.js +6 -1
  45. package/lib/commands/deploy-gate-failure-details.js +19 -17
  46. package/lib/commands/deploy-gate-orchestrator.js +3 -2
  47. package/lib/commands/dev-down.js +2 -6
  48. package/lib/commands/evidence-kind.js +65 -15
  49. package/lib/commands/governance-generate-external.js +56 -21
  50. package/lib/commands/governance-verify-external.js +2 -5
  51. package/lib/commands/lifecycle-external.js +21 -8
  52. package/lib/commands/repair-datasource-apply.js +10 -1
  53. package/lib/commands/repair-datasource-run.js +4 -2
  54. package/lib/commands/repair-datasource-test-payload.js +80 -19
  55. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +42 -3
  56. package/lib/commands/repair-internal.js +9 -1
  57. package/lib/commands/repair-openapi-sync.js +34 -17
  58. package/lib/commands/role-assistant.js +371 -0
  59. package/lib/commands/test-governance-external.js +2 -5
  60. package/lib/commands/up-miso.js +61 -24
  61. package/lib/commands/upload-data-sync-finalize.js +25 -7
  62. package/lib/commands/upload-sidecar-followups.js +144 -47
  63. package/lib/commands/upload.js +43 -6
  64. package/lib/commands/verify-governance-combined-external.js +73 -9
  65. package/lib/commands/verify-governance-db.js +80 -25
  66. package/lib/commands/verify-governance-external.js +31 -10
  67. package/lib/commands/verify-operations-external.js +2 -5
  68. package/lib/commands/verify-operations-step-plan.js +31 -0
  69. package/lib/commands/verify-trust-command-action.js +2 -5
  70. package/lib/commands/wizard-core-helpers.js +7 -3
  71. package/lib/commands/wizard-core.js +78 -9
  72. package/lib/datasource/bulk-loader-run-batches.js +4 -2
  73. package/lib/datasource/bulk-loader-service.js +5 -1
  74. package/lib/datasource/datasource-identifier.js +4 -3
  75. package/lib/datasource/datasource-validate-summary.js +2 -2
  76. package/lib/datasource/integration-context.js +3 -3
  77. package/lib/datasource/resolve-app.js +90 -8
  78. package/lib/datasource/test-e2e.js +2 -2
  79. package/lib/datasource/unified-validation-run-body.js +15 -1
  80. package/lib/datasource/unified-validation-run-resolve.js +2 -2
  81. package/lib/datasource/validate.js +13 -6
  82. package/lib/external-system/deploy-helpers.js +39 -1
  83. package/lib/external-system/deploy.js +25 -11
  84. package/lib/external-system/download-helpers.js +111 -2
  85. package/lib/external-system/download-role-assistant.js +55 -0
  86. package/lib/external-system/download.js +45 -26
  87. package/lib/external-system/test-helpers.js +1 -1
  88. package/lib/external-system/test-system-level.js +21 -3
  89. package/lib/external-system/test.js +43 -7
  90. package/lib/generator/builders.js +12 -15
  91. package/lib/generator/wizard.js +51 -4
  92. package/lib/lifecycle/access-control-abac.js +121 -0
  93. package/lib/lifecycle/lifecycle-governance-options.js +4 -1
  94. package/lib/lifecycle/product-model.js +3 -2
  95. package/lib/lifecycle/report-display.js +14 -2
  96. package/lib/programmatic/capability-registry.js +20 -1
  97. package/lib/programmatic/command-options.js +1 -0
  98. package/lib/programmatic/index.js +4 -0
  99. package/lib/programmatic/manifest-patch-section.js +48 -9
  100. package/lib/programmatic/manifest-section-registry-data.js +3 -2
  101. package/lib/programmatic/openapi-apply-result-schemas.js +44 -0
  102. package/lib/programmatic/openapi-component-schemas.js +16 -1
  103. package/lib/programmatic/openapi-description-enricher.js +3 -1
  104. package/lib/programmatic/openapi-descriptions.js +55 -5
  105. package/lib/programmatic/openapi-evidence-schemas.js +161 -0
  106. package/lib/programmatic/openapi-manifest-schemas.js +6 -2
  107. package/lib/programmatic/openapi-operation-bindings.js +99 -0
  108. package/lib/programmatic/openapi-request-schemas.js +36 -1
  109. package/lib/programmatic/openapi-result-schemas.js +1 -1
  110. package/lib/programmatic/openapi-schema-descriptions-certify.js +5 -1
  111. package/lib/programmatic/openapi-schema-descriptions-core.js +1 -1
  112. package/lib/programmatic/openapi-schema-descriptions-evidence.js +156 -0
  113. package/lib/programmatic/openapi-schema-descriptions-manifest.js +4 -3
  114. package/lib/programmatic/openapi-schema-descriptions-operations.js +70 -0
  115. package/lib/programmatic/openapi-spec.js +47 -28
  116. package/lib/programmatic/orchestration-openapi-meta.js +5 -0
  117. package/lib/programmatic/request-timeout.js +3 -0
  118. package/lib/programmatic/route-handler-map.js +89 -2
  119. package/lib/programmatic/run-certify.js +15 -2
  120. package/lib/programmatic/run-deploy.js +74 -0
  121. package/lib/programmatic/run-evidence-authoring.js +80 -0
  122. package/lib/programmatic/run-protection.js +124 -0
  123. package/lib/programmatic/run-template-workspace.js +28 -1
  124. package/lib/programmatic/workspace-context.js +6 -0
  125. package/lib/protection/auth-context.js +48 -6
  126. package/lib/protection/paths.js +22 -0
  127. package/lib/protection/run-protection-create-helpers.js +22 -1
  128. package/lib/protection/run-protection-create.js +1 -1
  129. package/lib/protection/sync-after-upload.js +1 -1
  130. package/lib/role-assistant/evidence-sync.js +450 -0
  131. package/lib/role-assistant/github-workflow.js +96 -0
  132. package/lib/role-assistant/knowledge-markdown-frontmatter.js +75 -0
  133. package/lib/role-assistant/knowledge-sync.js +485 -0
  134. package/lib/role-assistant/settings.js +126 -0
  135. package/lib/role-assistant/test-cases-evaluate.js +170 -0
  136. package/lib/role-assistant/test-cases-honesty.js +184 -0
  137. package/lib/role-assistant/test-cases.js +364 -0
  138. package/lib/role-assistant/test-runner-workhub-answers.js +221 -0
  139. package/lib/role-assistant/test-runner-workhub.js +399 -0
  140. package/lib/role-assistant/test-runner.js +500 -0
  141. package/lib/schema/application-schema.json +24 -28
  142. package/lib/schema/deployment-rules.yaml +1 -0
  143. package/lib/schema/external-datasource.schema.json +38 -4
  144. package/lib/schema/external-system.schema.json +4 -4
  145. package/lib/schema/role-assistant-settings.schema.json +108 -0
  146. package/lib/utils/api.js +52 -27
  147. package/lib/utils/app-path-resolve.js +72 -24
  148. package/lib/utils/authentication-shape.js +3 -1
  149. package/lib/utils/certify-external-workspace.js +40 -0
  150. package/lib/utils/deployment-validation.js +28 -3
  151. package/lib/utils/docker-run-ephemeral.js +115 -0
  152. package/lib/utils/enterprise-knowledge-paths.js +29 -12
  153. package/lib/utils/env-copy-keycloak.js +196 -0
  154. package/lib/utils/env-copy.js +34 -1
  155. package/lib/utils/external-system-readiness-compact-display.js +3 -0
  156. package/lib/utils/health-check-public-warn.js +31 -13
  157. package/lib/utils/health-check.js +11 -1
  158. package/lib/utils/help-builder.js +1 -0
  159. package/lib/utils/paths.js +80 -38
  160. package/lib/utils/pipeline-upload-auth-retry.js +15 -3
  161. package/lib/utils/role-assistant-paths.js +160 -0
  162. package/lib/utils/schema-loader.js +41 -0
  163. package/lib/utils/schema-resolver.js +36 -4
  164. package/lib/utils/token-manager.js +38 -29
  165. package/lib/utils/upload-sync-options.js +7 -4
  166. package/lib/utils/url-declarative-resolve-load-doc.js +38 -1
  167. package/lib/validation/external-manifest-validator.js +31 -8
  168. package/lib/validation/reserved-system-key-prefixes.js +56 -0
  169. package/lib/validation/validate-external-file.js +8 -1
  170. package/lib/validation/validate.js +54 -19
  171. package/package.json +2 -1
  172. package/scripts/export-builder-api-evidence.js +1 -1
  173. package/templates/applications/builder-api/application.yaml +3 -3
  174. package/templates/applications/dataplane/application.yaml +24 -17
  175. package/templates/applications/dataplane/env.template +2 -2
  176. package/templates/applications/dataplane/rbac.yaml +24 -10
  177. package/templates/applications/keycloak/application.yaml +2 -2
  178. package/templates/applications/keycloak/env.template +5 -2
  179. package/templates/applications/miso-controller/application.yaml +3 -3
  180. package/templates/applications/miso-controller/env.template +17 -2
  181. package/templates/channels/chatgpt/install.template.md.hbs +82 -26
  182. package/templates/channels/chatgpt/integration/README.md +11 -7
  183. package/templates/channels/chatgpt/integration/application.json +2 -2
  184. package/templates/channels/chatgpt/integration/chatgpt-system.json +3 -3
  185. package/templates/channels/chatgpt/integration/env.template +1 -1
  186. package/templates/channels/chatgpt/manifest.template.json.hbs +36 -5
  187. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +28 -0
  188. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +22 -0
  189. package/templates/channels/microsoft-copilot/install.template.md.hbs +32 -22
  190. package/templates/channels/microsoft-copilot/integration/README.md +9 -7
  191. package/templates/channels/microsoft-copilot/integration/application.json +2 -2
  192. package/templates/channels/microsoft-copilot/integration/env.template +1 -1
  193. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +7 -6
  194. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -6
  195. package/templates/channels/slack/install.template.md.hbs +6 -1
  196. package/templates/python/docker-compose.hbs +10 -0
  197. package/templates/typescript/docker-compose.hbs +10 -0
  198. /package/.cursor/plans/{157.1-security-quality-violations-by-type.csv → Done/157.1-security-quality-violations-by-type.csv} +0 -0
@@ -22,6 +22,7 @@ const { generateControllerManifest } = require('../generator/external-controller
22
22
  const { validateControllerManifest } = require('./external-manifest-validator');
23
23
  const { runExternalValidateWithOptionalCertSync } = require('./validate-external-cert-sync');
24
24
  const { validateExternalFile } = require('./validate-external-file');
25
+ const { reservedSystemKeyError } = require('./reserved-system-key-prefixes');
25
26
 
26
27
  /**
27
28
  * Validates a file path (detects type and validates)
@@ -276,6 +277,52 @@ async function validateManifestStep(appName, options = {}) {
276
277
  }
277
278
  }
278
279
 
280
+ /**
281
+ * Early-fail payload when system key uses a reserved prefix.
282
+ * @param {string} reservedError
283
+ * @param {string} appPath
284
+ * @returns {Object}
285
+ */
286
+ function reservedSystemKeyValidationResult(reservedError, appPath) {
287
+ return {
288
+ valid: false,
289
+ errors: [reservedError],
290
+ warnings: [],
291
+ steps: {
292
+ application: { valid: false, errors: [reservedError], warnings: [] },
293
+ components: { valid: true, errors: [], warnings: [], files: [], skipped: true },
294
+ manifest: { valid: true, errors: [], warnings: [], skipped: true }
295
+ },
296
+ appPath
297
+ };
298
+ }
299
+
300
+ /**
301
+ * Aggregate step results into the complete validation response.
302
+ * @param {Object} steps
303
+ * @param {string} appPath
304
+ * @returns {Object}
305
+ */
306
+ function aggregateExternalValidationSteps(steps, appPath) {
307
+ const allErrors = [
308
+ ...steps.application.errors,
309
+ ...steps.components.errors,
310
+ ...steps.manifest.errors
311
+ ];
312
+ const allWarnings = [
313
+ ...steps.application.warnings,
314
+ ...steps.components.warnings,
315
+ ...steps.manifest.warnings
316
+ ];
317
+ return {
318
+ valid: allErrors.length === 0,
319
+ errors: allErrors,
320
+ warnings: allWarnings,
321
+ steps,
322
+ appPath
323
+ };
324
+ }
325
+
279
326
  /**
280
327
  * Validates external system completely (components + full manifest)
281
328
  * Performs step-by-step validation: application config → components → full manifest
@@ -295,7 +342,12 @@ async function validateExternalSystemComplete(appName, options = {}) {
295
342
  throw new Error('App name is required and must be a string');
296
343
  }
297
344
 
298
- const { appPath } = await detectAppType(appName, options);
345
+ const { appPath, baseDir } = await detectAppType(appName, options);
346
+ const reservedError = reservedSystemKeyError(appName, baseDir);
347
+ if (reservedError) {
348
+ return reservedSystemKeyValidationResult(reservedError, appPath);
349
+ }
350
+
299
351
  const steps = {
300
352
  application: { valid: false, errors: [], warnings: [] },
301
353
  components: { valid: false, errors: [], warnings: [], files: [] },
@@ -303,14 +355,9 @@ async function validateExternalSystemComplete(appName, options = {}) {
303
355
  };
304
356
 
305
357
  const externalOptions = { ...options };
306
-
307
- // Step 1: Validate Application Config
308
358
  steps.application = await validateApplicationStep(appName, externalOptions);
309
-
310
- // Step 2: Validate Individual Components
311
359
  steps.components = await validateComponentsStep(appName, externalOptions);
312
360
 
313
- // If components have errors, return early (don't validate manifest)
314
361
  if (!steps.components.valid) {
315
362
  steps.manifest = { valid: true, errors: [], warnings: [], skipped: true };
316
363
  return {
@@ -322,20 +369,8 @@ async function validateExternalSystemComplete(appName, options = {}) {
322
369
  };
323
370
  }
324
371
 
325
- // Step 3 & 4: Generate and Validate Full Manifest (only if Step 2 passes)
326
372
  steps.manifest = await validateManifestStep(appName, { ...externalOptions, appPath });
327
-
328
- // Aggregate Results
329
- const allErrors = [...steps.application.errors, ...steps.components.errors, ...steps.manifest.errors];
330
- const allWarnings = [...steps.application.warnings, ...steps.components.warnings, ...steps.manifest.warnings];
331
-
332
- return {
333
- valid: allErrors.length === 0,
334
- errors: allErrors,
335
- warnings: allWarnings,
336
- steps,
337
- appPath
338
- };
373
+ return aggregateExternalValidationSteps(steps, appPath);
339
374
  }
340
375
 
341
376
  async function validateAppOrFile(appOrFile, options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aifabrix/builder",
3
- "version": "2.51.0",
3
+ "version": "2.52.0",
4
4
  "description": "AI Fabrix Builder — CLI and developer scripts (pnpm + af)",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -114,6 +114,7 @@
114
114
  },
115
115
  "dependencies": {
116
116
  "@aifabrix/miso-client": "^4.19.0",
117
+ "adm-zip": "^0.6.0",
117
118
  "ajv": "^8.20.0",
118
119
  "ajv-formats": "^3.0.1",
119
120
  "axios": "^1.18.1",
@@ -238,7 +238,7 @@ function rowsFromManifestGuides() {
238
238
  title: 'Section quality and missing inputs',
239
239
  when: 'GET manifest section returns quality.missingInputs',
240
240
  expectedBehavior:
241
- 'Collect required missing inputs from the user before PATCH. Do not guess values. Include sectionReadToken from GET in PATCH body.',
241
+ 'Collect required missing inputs from the user before PATCH. Do not guess values. sectionReadToken from GET is optional on PATCH (server re-reads when omitted; stale token returns 409). Prefer GET when you need quality or missingInputs.',
242
242
  order: 17
243
243
  })
244
244
  ];
@@ -2,7 +2,7 @@
2
2
  app:
3
3
  key: builder-api
4
4
  displayName: 'AI Fabrix Builder API'
5
- description: 'Stateless HTTP orchestration for external-system workspace lifecycle. Provider-neutral integration flows via Dataplane Enterprise MCP and governance APIs (154.0 / 154.1).'
5
+ description: 'Business Transformation services — HTTP orchestration for connected-system workspace lifecycle via Dataplane Enterprise MCP and governance APIs.'
6
6
  type: webapp
7
7
  language: typescript
8
8
  version: 1.0.0
@@ -11,8 +11,8 @@ app:
11
11
  image:
12
12
  name: aifabrix/builder-api
13
13
  tag: latest
14
- registry: aifabrixdevacr.azurecr.io
15
- registryMode: acr
14
+ registry: aifabrixacr.azurecr.io
15
+ registryMode: external
16
16
 
17
17
  # Port Configuration (container port; host port = port + developer_id * 100)
18
18
  port: 3005
@@ -4,16 +4,16 @@ app:
4
4
  displayName: "AI Fabrix Dataplane"
5
5
  description: "AI Fabrix Dataplane is a secure, in-tenant integration and automation layer that supplies governed, normalized, and explainable enterprise data to AI agents. Using CIP as a declarative standard, it enforces RBAC and ABAC, executes integrations, and exposes trusted data via MCP and OpenAPI."
6
6
  type: webapp
7
- language: python # Explicitly specify Python language
8
- version: 2.0.10
7
+ language: python # Explicitly specify Python language
8
+ version: 2.0.20
9
9
  # Image Configuration
10
- # Set tag to match your build (e.g. aifabrix build dataplane -t 1.0.0 then tag: 1.0.0)
11
- # Registry is required so the controller can pull the image (avoids "docker: not found" on the controller host).
10
+ # Set tag to match your build (example: aifabrix build dataplane -t 1.0.0).
11
+ # Registry is required so the controller can pull the image (avoids docker-not-found on the controller host).
12
12
  image:
13
13
  name: aifabrix/dataplane
14
14
  tag: latest
15
- registry: aifabrixdevacr.azurecr.io
16
- registryMode: acr
15
+ registry: aifabrixacr.azurecr.io
16
+ registryMode: external
17
17
 
18
18
  # Port Configuration
19
19
  port: 3001
@@ -34,10 +34,10 @@ frontDoorRouting:
34
34
  requires:
35
35
  database: true
36
36
  databases:
37
- - name: dataplane # Main database - configuration only
38
- - name: dataplane-vector # Vector and document store: chunks, embeddings, vector indexes (pgvector)
39
- - name: dataplane-logs # Logs database - execution, audit, ABAC traces
40
- - name: dataplane-records # Records database - external records storage
37
+ - name: dataplane # Main database - configuration only
38
+ - name: dataplane-vector # Vector and document store: chunks, embeddings, vector indexes (pgvector)
39
+ - name: dataplane-logs # Logs database - execution, audit, ABAC traces
40
+ - name: dataplane-records # Records database - external records storage
41
41
  redis: true
42
42
  storage: true
43
43
 
@@ -59,10 +59,10 @@ authentication:
59
59
  # Build Configuration
60
60
  # Dataplane builds from published image; context is project root (like miso-controller)
61
61
  build:
62
- context: ../.. # Docker build context (relative to builder/dataplane/)
63
- dockerfile: builder/dataplane/Dockerfile # Dockerfile path (relative to project root)
64
- envOutputPath: ../../.env # Copy to repo root for local dev
65
- language: python # Runtime language for template selection (typescript or python)
62
+ context: ../.. # Docker build context (relative to builder/dataplane/)
63
+ dockerfile: builder/dataplane/Dockerfile # Dockerfile path (relative to project root)
64
+ envOutputPath: ../../.env # Copy to repo root for local dev
65
+ language: python # Runtime language for template selection (typescript or python)
66
66
  # Dev reload: polling + watch /app/app only (avoids EMFILE on full repo bind-mount). See run_local.py, make af-reload.
67
67
  reloadStart: WATCHFILES_FORCE_POLLING=1 uvicorn app.main:app --host 0.0.0.0 --port ${PORT:-3001} --reload --reload-dir /app/app
68
68
  # Pulled-image local compose (no bind-mount): drives `command` in generated docker-compose. Override for non-standard images (e.g. stub ACR tags).
@@ -72,6 +72,10 @@ build:
72
72
  worker: true
73
73
  imageRunWorker: exec python -m app.core.celery_worker_main
74
74
  imageRunBeat: exec python -m app.core.celery_beat_main
75
+ # Optional one-shot before ANY long-running role (api/worker/beat). Run exactly once per
76
+ # aifabrix run / Deployment — never once-per-container. Schema: application-schema build.deployJob.
77
+ # Local: aifabrix run; remote: miso Deployment via miso-azure (not Docker on controller).
78
+ deployJob: python -m app.db.migrate upgrade
75
79
 
76
80
  # =============================================================================
77
81
  # Portal Input Configuration (Deployment Wizard)
@@ -81,7 +85,7 @@ build:
81
85
  #
82
86
  # NOT included (auto-configured):
83
87
  # - Database URLs, Redis → auto-generated during Azure install
84
- # - MISO_*, KEYCLOAK_* → auto-generated during Azure install
88
+ # - MISO_*, KEYCLOAK_* → auto-generated during Azure install
85
89
  # - AI params / provider secrets → LLM external systems + secret store
86
90
  # (never product OPENAI_* / AZURE_OPENAI_*). ≥2 providers →
87
91
  # ENTERPRISE_LLM_DEFAULT_SELECTOR (portal LLM category).
@@ -135,8 +139,9 @@ configuration:
135
139
  category: Trust
136
140
  portalInput:
137
141
  field: select
138
- label: "Enforce trust gate on datasource publish"
142
+ label: "Enforce trust gate on datasource publish (empty=ENVIRONMENT default)"
139
143
  options:
144
+ - ""
140
145
  - "false"
141
146
  - "true"
142
147
 
@@ -144,8 +149,9 @@ configuration:
144
149
  category: Trust
145
150
  portalInput:
146
151
  field: select
147
- label: "Enforce trust gate on external system publish (promote scope)"
152
+ label: "Enforce trust gate on Deploy / system publish (empty=ENVIRONMENT default)"
148
153
  options:
154
+ - ""
149
155
  - "false"
150
156
  - "true"
151
157
 
@@ -225,3 +231,4 @@ configuration:
225
231
  field: text
226
232
  label: "Default LLM provider (system key when two or more providers)"
227
233
  placeholder: "openai"
234
+
@@ -44,7 +44,7 @@ API_KEY_BYPASS_ROLES=full-access
44
44
 
45
45
  # API Configuration
46
46
  API_V1_STR=/api/v1
47
- VERSION=2.0.10
47
+ VERSION=2.0.20
48
48
  # Minimum supported aifabrix-builder CLI semver (advertised on /health and /api/v1/health; empty = no gate)
49
49
  # MIN_BUILDER_CLI_VERSION=2.45.0
50
50
  MIN_BUILDER_CLI_VERSION=2.45.5
@@ -284,7 +284,7 @@ VALIDATION_AUTO_ISSUE_INTEGRATION_CERTIFICATE=true
284
284
  CIP_EXECUTION_MAX_RESPONSE_SIZE_MB=100.0
285
285
  CIP_EXECUTION_MAX_RECORDS=100000
286
286
  CIP_EXECUTION_OPERATION_TIMEOUT=300.0
287
- CIP_EXECUTION_HTTP_TIMEOUT=30.0
287
+ CIP_EXECUTION_HTTP_TIMEOUT=120.0
288
288
  CIP_EXECUTION_MAX_RETRIES=3
289
289
  CIP_EXECUTION_RETRY_BACKOFF_FACTOR=2.0
290
290
  CIP_EXECUTION_RETRY_INITIAL_DELAY=1.0
@@ -5,47 +5,47 @@
5
5
  # MisoClient validates environment access automatically based on user/application permissions.
6
6
 
7
7
  roles:
8
- - name: "AI Fabrix Platform Admin"
8
+ - name: "Platform Admin"
9
9
  value: "aifabrix-platform-admin"
10
10
  description: "Full platform infrastructure management and enterprise controller access"
11
11
  groups: ["AI-Fabrix-Platform-Admins"]
12
12
 
13
- - name: "AI Fabrix Security Admin"
13
+ - name: "Security Admin"
14
14
  value: "aifabrix-security-admin"
15
15
  description: "Security and compliance management for enterprise controller"
16
16
  groups: ["AI-Fabrix-Security-Admins"]
17
17
 
18
- - name: "AI Fabrix Deployment Admin"
18
+ - name: "Deployment Admin"
19
19
  value: "aifabrix-deployment-admin"
20
20
  description: "Application deployment orchestration and environment management"
21
21
  groups: ["AI-Fabrix-Deployment-Admins"]
22
22
 
23
- - name: "AI Fabrix Compliance Admin"
23
+ - name: "Compliance Admin"
24
24
  value: "aifabrix-compliance-admin"
25
25
  description: "ISO 27001 compliance monitoring and audit management"
26
26
  groups: ["AI-Fabrix-Compliance-Admins"]
27
27
 
28
- - name: "AI Fabrix Developer"
28
+ - name: "Developer"
29
29
  value: "aifabrix-developer"
30
30
  description: "Developer access to deploy applications via CI pipelines"
31
31
  groups: ["AI-Fabrix-Developers"]
32
32
 
33
- - name: "AI Fabrix Business Transformation"
34
- value: "aifabrix-business-transformation"
33
+ - name: "Business Transformation"
34
+ value: "business-transformation"
35
35
  description: "Built-in assistant: business intention → governed Connected Systems via Runtime and builder-api"
36
36
  groups: ["AI-Fabrix-Business-Transformation"]
37
37
 
38
- - name: "AI Fabrix Observer"
38
+ - name: "Observer"
39
39
  value: "aifabrix-observer"
40
40
  description: "Read-only access to monitoring, logs, and compliance reports"
41
41
  groups: ["AI-Fabrix-Observers"]
42
42
 
43
- - name: "AI Fabrix AI Trust Operator"
43
+ - name: "AI Trust Operator"
44
44
  value: "aifabrix-ai-trust-operator"
45
45
  description: "Run AI Trust access evaluation and explain visibility for governed users"
46
46
  groups: ["AI-Fabrix-AI-Trust-Operators"]
47
47
 
48
- - name: "AI Fabrix External System Discoverer"
48
+ - name: "External System Discoverer"
49
49
  value: "aifabrix-external-system-discoverer"
50
50
  description: "Discover business context for external systems via REST and MCP"
51
51
  groups: ["AI-Fabrix-External-System-Discoverers"]
@@ -143,6 +143,20 @@ permissions:
143
143
  - name: "integration-template:delete"
144
144
  roles: ["aifabrix-platform-admin", "aifabrix-developer"]
145
145
  description: "Delete integration templates"
146
+
147
+ # Resource type catalog (public read; Miso owns writes via controller sync)
148
+ - name: "resource-type:read"
149
+ roles:
150
+ [
151
+ "aifabrix-platform-admin",
152
+ "aifabrix-security-admin",
153
+ "aifabrix-deployment-admin",
154
+ "aifabrix-compliance-admin",
155
+ "aifabrix-developer",
156
+ "aifabrix-observer",
157
+ "aifabrix-ai-trust-operator",
158
+ ]
159
+ description: "Read the global Resource Type catalog (list/get)"
146
160
 
147
161
  # Generic dataplane operations
148
162
  - name: "dataplane:read"
@@ -10,8 +10,8 @@ app:
10
10
  image:
11
11
  name: aifabrix/keycloak
12
12
  tag: 'latest'
13
- registry: aifabrixdevacr.azurecr.io
14
- registryMode: acr
13
+ registry: aifabrixacr.azurecr.io
14
+ registryMode: external
15
15
 
16
16
  # Port Configuration (base for host; host port = 8082 + developer_id*100 from ~/.aifabrix/config.yaml)
17
17
  port: 8082
@@ -9,11 +9,14 @@
9
9
  KC_BOOTSTRAP_ADMIN_USERNAME=admin
10
10
  KC_BOOTSTRAP_ADMIN_PASSWORD=kv://keycloak-admin-passwordKeyVault
11
11
  KC_HOSTNAME_STRICT=false
12
- KC_HTTP_ENABLED=${HTTP_ENABLED}
12
+ # Follows tlsEnabled in ~/.aifabrix/config.yaml (same as ${TLS_ENABLED}).
13
+ # Traefik/edge HTTPS on → true (proxy forwards HTTP to Keycloak :8080).
14
+ # Single container without HTTPS (tlsEnabled false) → false.
15
+ KC_HTTP_ENABLED=${TLS_ENABLED}
13
16
  # When Traefik + frontDoorRouting.enabled are on, same vdir as url://public. If the front door is off, env generation
14
17
  # rewrites url://vdir-public to "/" before expansion (empty path is invalid — Keycloak 26 SRCFG00040).
15
18
  # Docker-only templates may use url://vdir-internal instead.
16
- KC_HTTP_RELATIVE_PATH=url://vdir-public
19
+ KC_HTTP_RELATIVE_PATH=/auth
17
20
 
18
21
  # =============================================================================
19
22
  # HOSTNAME / ISSUER (Docker vs localhost)
@@ -4,7 +4,7 @@ app:
4
4
  displayName: 'Miso Controller'
5
5
  description: 'Miso is the AI Fabrix in-tenant controller and portal layer for securely operating enterprise AI apps inside a customer’s Azure tenant. It provides Entra ID SSO, RBAC, audit logs, environment/app configuration via schemas, and safe secret handling via Key Vault references—ensuring governance, traceability, and predictable UX across portal, SDK, and CLI.'
6
6
  type: webapp
7
- version: '2.0.8'
7
+ version: '2.0.20'
8
8
 
9
9
  # Image Configuration
10
10
  # Set tag to match your build (e.g. aifabrix build miso-controller -t 1.0.0 then tag: 1.0.0)
@@ -12,8 +12,8 @@ app:
12
12
  image:
13
13
  name: aifabrix/miso-controller
14
14
  tag: latest
15
- registry: aifabrixdevacr.azurecr.io
16
- registryMode: acr
15
+ registry: aifabrixacr.azurecr.io
16
+ registryMode: external
17
17
 
18
18
  # Port Configuration (container port; host port = 3000 + developer_id*100 from ~/.aifabrix/config.yaml)
19
19
  port: 3000
@@ -49,6 +49,10 @@ ONBOARDING_ADMIN_EMAIL=kv://miso-controller-admin-emailKeyVault
49
49
  # When true, supersedes ONBOARDING_CREATE_DEV_ENV for which extra environments are created
50
50
  ONBOARDING_FULL_PLATFORM=false
51
51
 
52
+ # When true, run Azure env deploy for onboarding envs (SDK modules). Default false —
53
+ # Marketplace already provisions infra; TA owns customer env deploy.
54
+ ONBOARDING_CREATE_MISO_ENV=false
55
+
52
56
  # Set to true to create both miso and dev environments during onboarding
53
57
  # When false (default), only the miso environment is created (ignored when ONBOARDING_FULL_PLATFORM=true)
54
58
  ONBOARDING_CREATE_DEV_ENV=true
@@ -236,6 +240,14 @@ SKIP_DB_REDEPLOY=true
236
240
  # Bootstrap (SKIP_FIRST_TIME_SETUP=false) is separate from the activation wizard.
237
241
  DEPLOYMENT=database
238
242
 
243
+ # Dev/test: open /tenant-activation on Platform Apps (last step). Default false.
244
+ # Does not skip server-side TA — use only when env is already activated/deployed.
245
+ TA_SKIP_TO_APP_DEPLOY=false
246
+
247
+ # Dev/test: show TA Entra "Completing setup" countdown (120s cap). Default false.
248
+ # Exposed to UI via GET /api/v1/tenant/status → showTaCountdown (restart controller after change).
249
+ SHOW_TA_COUNT_DOWN=false
250
+
239
251
  # =============================================================================
240
252
  # SECURITY & ENCRYPTION
241
253
  # =============================================================================
@@ -287,8 +299,11 @@ ENTRA_GRAPH_DELEGATED_REDIRECT_URI=https://aifabrix-pro-mori-web-we.azurewebsite
287
299
  # =============================================================================
288
300
  # MORI SERVICE CONFIGURATION
289
301
  # =============================================================================
290
-
291
- MORI_BASE_URL=url://mori-controller-public
302
+ # Shared Mori (handoff poll + Entra callback). Local `url://mori-controller-public`
303
+ # only works when a local Mori app is registered and running for this developer.
304
+ # MORI_CALLBACK_API_KEY must be the same secret as Mori MORI_CONTROLLER_CALLBACK_API_KEY
305
+ # (both resolve from kv://mori-callback-api-keyKeyVault — do not generate separate values).
306
+ MORI_BASE_URL=https://aifabrix-pro-mori-web-we.azurewebsites.net
292
307
  MORI_AUTH_METHOD=kv://mori-controller-auth-methodKeyVault
293
308
  MORI_CALLBACK_API_KEY=kv://mori-callback-api-keyKeyVault
294
309
  MORI_API_KEY=kv://mori-controller-api-keyKeyVault
@@ -1,46 +1,102 @@
1
- # {{appName}} — ChatGPT assistant channel install
1
+ # {{appName}} — ChatGPT custom MCP app setup
2
2
 
3
3
  {{appDescription}}
4
4
 
5
- Environment: **{{environment}}** · Credential key: `{{credentialKey}}`
5
+ **Environment:** {{environment}}
6
+ **AI Fabrix credential reference:** `{{credentialKey}}`
6
7
 
7
- ## Connect ChatGPT workspace (admin)
8
+ > This document and `dist/channels/chatgpt/channel-chatgpt.json` are deployment references for administrators. ChatGPT does not install the JSON file as a plugin archive. ChatGPT connects directly to the remote MCP endpoint and discovers the tools exposed by that server.
8
9
 
9
- 1. Sign in to [OpenAI Platform](https://platform.openai.com/) or your **ChatGPT Enterprise** workspace admin console.
10
- 2. Create a custom GPT, workspace connector, or MCP integration using the generated manifest from `dist/channels/chatgpt/channel-chatgpt.json`.
11
- 3. Configure the **OpenAPI specification URL** and **MCP endpoint** from **Platform endpoints** below.
12
- 4. Complete OAuth or API key setup as required by your ChatGPT deployment model.
13
- 5. Save the **API key** or **OAuth client credentials** in AI Fabrix: [Authentication settings]({{credentialPortalUrl}})
14
- 6. Publish the connector to your workspace and complete admin approval if your organization requires it.
10
+ ## ChatGPT workspace setup
15
11
 
16
- ## Platform endpoints
12
+ 1. Sign in to the ChatGPT web app as a workspace admin or owner.
13
+ 2. Enable Developer mode for custom MCP apps:
14
+ - **Business:** **Workspace settings → Apps → Create**, or **Settings → Apps → Advanced settings**.
15
+ - **Enterprise/Edu:** grant the appropriate Developer mode permission under **Workspace settings → Permissions & roles → Connected data**, then enable it under **Settings → Apps → Advanced settings**.
16
+ 3. Open **Settings → Apps → Create** (or the equivalent **Workspace settings → Apps → Create** entry).
17
+ 4. Enter the app name `{{appName}}` and the remote MCP URL shown under **Runtime connection** below.
18
+ 5. Select **OAuth** as the authentication mechanism. Do not configure a custom API key in ChatGPT; custom API-key authentication is not supported for a remote custom MCP app.
19
+ 6. Select **Scan tools**. If prompted, complete the OAuth authorization flow and wait for ChatGPT to finish scanning the Runtime tool list.
20
+ 7. Review the discovered tools and create the app as a draft.
21
+ 8. Test representative read and write workflows. Confirm that user authorization and action confirmations behave as expected.
22
+ 9. Publish the app to the workspace and configure its access and action controls. Only workspace admins or owners can publish it.
23
+ 10. After MCP tool names, schemas, annotations, or authentication metadata change, use **Refresh** in the app's action controls and review the changes before enabling them.
17
24
 
18
- Configure these on the ChatGPT connector / custom GPT. Do not embed secrets in generated files — use AI Fabrix credential storage only.
25
+ ## Runtime connection
19
26
 
20
- {{#if openapiUrl}}
21
- - **OpenAPI spec:** {{openapiUrl}}
22
- {{/if}}
27
+ Configure the following values in the ChatGPT custom MCP app. Never place access tokens, client secrets, or API keys in generated files.
28
+
29
+ - **App name:** `{{appName}}`
23
30
  {{#if mcpUrl}}
24
- - **MCP:** {{mcpUrl}}
25
- {{/if}}
26
- {{#if actionsBaseUrl}}
27
- - **Actions base:** {{actionsBaseUrl}}
31
+ - **Remote MCP URL:** `{{{mcpUrl}}}`
28
32
  {{/if}}
33
+ - **Runtime system key:** `{{runtimeSystemKey}}`
34
+ - **Transport:** Streamable HTTP
35
+ - **Authentication:** OAuth 2.1 authorization-code flow with PKCE (`S256`)
36
+ - **AI Fabrix credential reference:** `{{credentialKey}}`
37
+ - **AI Fabrix authentication settings:** [Open authentication settings]({{{credentialPortalUrl}}})
29
38
 
30
- ## Assistant catalog
39
+ The `{{credentialKey}}` value is an AI Fabrix credential reference. It is not a secret to paste into ChatGPT.
31
40
 
32
- Runtime lists **assistants** available to each user from:
41
+ ## OAuth requirements
33
42
 
34
- {{assistantCatalogUrl}}
43
+ Before ChatGPT can connect successfully, the MCP deployment must meet all of these requirements:
35
44
 
36
- ## After workspace approval
45
+ - The MCP endpoint is reachable over public HTTPS with a publicly trusted TLS certificate chain.
46
+ - The MCP server publishes OAuth protected-resource metadata, normally at `/.well-known/oauth-protected-resource`, or points to it in the `WWW-Authenticate` header returned with a `401 Unauthorized` response.
47
+ - The protected-resource document identifies the canonical resource URL, authorization server, and supported scopes.
48
+ - The authorization server publishes OAuth or OpenID Connect discovery metadata.
49
+ - The authorization server supports the authorization-code flow and PKCE with `S256`.
50
+ - The OAuth flow preserves the MCP `resource` parameter, and issued access tokens contain the expected audience and scopes.
51
+ - The redirect URI shown by ChatGPT when the app is created is allowlisted in the authorization server.
52
+ - The MCP server validates every access token's signature, issuer, audience, expiry, and scopes.
53
+ - Each authenticated MCP tool declares an `oauth2` security scheme with the scopes it needs.
37
54
 
38
- ```bash
39
- aifabrix channel add {{channelTarget}} --name "{{baseName}}"
40
- ```
55
+ If this development endpoint is deliberately anonymous, select **No authentication** instead and declare `noauth` on the applicable tools. Do not describe the app as “OAuth or API key”; the selected mechanism must match the behavior advertised by the MCP server.
56
+
57
+ ## Expected Runtime Layer B tools
58
+
59
+ ChatGPT should discover the following tools from the live MCP server during **Scan tools**:
60
+
61
+ {{#each layerBToolNames}}
62
+ - `{{this}}`
63
+ {{/each}}
64
+
65
+ The live server response is authoritative. This list is an expected deployment contract, not a substitute for MCP tool discovery.
66
+
67
+ ## Runtime and Role Assistant boundaries
41
68
 
42
- Optional validation:
69
+ - Runtime resolves assistants dynamically for the current user from `{{{assistantCatalogUrl}}}`.
70
+ - ChatGPT's top-level tool surface remains limited to the Runtime Layer B tools listed above.
71
+ - Evidence authoring remains an internal Business Transformation Assistant capability. It is reached through `ChatGPT → runtime-orchestration → Business Transformation Assistant → internal evidence capabilities` and is not exposed as a top-level ChatGPT tool.
72
+ - One authenticated Runtime connection can support multiple Role Assistants, subject to the current user's authorization.
73
+
74
+ ## BTA evidence-authoring proof scenario
75
+
76
+ Use this scenario to verify the ChatGPT → Runtime → BTA path without exposing Evidence commands as top-level ChatGPT tools:
77
+
78
+ 1. Ask {{baseName}} to improve an existing Role Assistant from process documentation.
79
+ 2. Confirm that {{baseName}} starts or continues Business Transformation Assistant work through Runtime.
80
+ 3. Confirm that BTA performs evidence metadata, download, upload, and reasoning operations internally and presents certified proposals.
81
+ 4. Approve selected proposals and confirm that activation remains an explicit human action.
82
+
83
+ ## AI Fabrix validation
84
+
85
+ Before workspace publication, validate the live Streamable HTTP endpoint with MCP Inspector and confirm that initialization, tool discovery, representative calls, invalid inputs, OAuth challenges, and authorization checks all work.
86
+
87
+ Then run the AI Fabrix probe:
43
88
 
44
89
  ```bash
45
90
  aifabrix channel add {{channelTarget}} --name "{{baseName}}" --probe
46
91
  ```
92
+
93
+ The probe should validate Runtime through the first-party MCP gateway, including Layer B discovery and BTA Evidence-authoring reachability. A successful AI Fabrix probe does not replace ChatGPT's own **Scan tools**, OAuth, and workspace publication checks.
94
+
95
+ Use `--force` only to regenerate artifacts and patch channel metadata. It does not rotate credentials.
96
+
97
+ ## Current validation status
98
+
99
+ - Local artifact validation: complete
100
+ - Live Runtime validation: pending
101
+ - ChatGPT workspace tool scan: pending
102
+ - ChatGPT workspace publication: requires a workspace admin or owner
@@ -1,11 +1,15 @@
1
- # ChatGPT assistant channel (lab fixture)
1
+ # ChatGPT custom MCP app channel
2
2
 
3
- SSOT for `aifabrix channel scaffold chatgpt` templates (`make sync-json` → builder).
3
+ Generated by `aifabrix channel scaffold chatgpt`.
4
+
5
+ Recommended flow:
4
6
 
5
7
  ```bash
6
- cd aifabrix-dataplane
7
- aifabrix validate chatgpt
8
- aifabrix upload chatgpt --probe
9
- aifabrix deploy chatgpt
10
- aifabrix app add-channel chatgpt --name "Your Assistant"
8
+ aifabrix upload chatgpt --force
9
+ aifabrix channel add chatgpt --name "Your Assistant" --probe
11
10
  ```
11
+
12
+ The `channel add` step generates `dist/channels/chatgpt/channel-chatgpt.json` and
13
+ `INSTALL.md`. Those files are deployment references for workspace admins: ChatGPT
14
+ connects to the remote Runtime MCP URL (OAuth) and discovers tools; it does not
15
+ install the JSON as a plugin archive.
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "app": {
3
3
  "key": "chatgpt",
4
- "displayName": "ChatGPT assistant channel",
5
- "description": "Assistant communication channel — deploy then app add-channel",
4
+ "displayName": "ChatGPT custom MCP app channel",
5
+ "description": "Assistant communication channel — deploy then channel add",
6
6
  "type": "external"
7
7
  },
8
8
  "externalIntegration": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "key": "chatgpt",
3
- "displayName": "ChatGPT assistant channel",
4
- "description": "Communication external system for ChatGPT assistant channel install",
3
+ "displayName": "ChatGPT custom MCP app channel",
4
+ "description": "Communication external system for ChatGPT custom MCP app onboarding",
5
5
  "type": "custom",
6
6
  "systemKind": "communication",
7
7
  "enabled": true,
@@ -9,7 +9,7 @@
9
9
  "authType": "credential",
10
10
  "credential": {
11
11
  "credentialKey": "chatgpt-channel",
12
- "displayName": "ChatGPT assistant channel",
12
+ "displayName": "ChatGPT custom MCP app channel",
13
13
  "method": "apikey",
14
14
  "writeOnce": true,
15
15
  "variables": {
@@ -1,4 +1,4 @@
1
- # ChatGPT assistant channel — lab fixture secrets
1
+ # ChatGPT custom MCP app channel credential reference
2
2
  # aifabrix secret set chatgpt/apiKey "<value>" --shared
3
3
 
4
4
  KV_CHATGPT_APIKEY=kv://chatgpt/apiKey