@aifabrix/builder 2.50.0 → 2.51.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/.cursor/plans/Done/157.1-security-quality-violations-by-type.csv +374 -0
  2. package/.cursor/rules/assistant-driven-integration-build.mdc +40 -0
  3. package/integration/hubspot-test/create-hubspot.js +1 -16
  4. package/jest.isolated-projects.js +77 -1
  5. package/jest.projects.js +5 -426
  6. package/lib/api/assistants.api.js +67 -0
  7. package/lib/api/datasources-extended.api.js +6 -6
  8. package/lib/api/evidence-authoring-helpers.js +267 -0
  9. package/lib/api/evidence-authoring.api.js +337 -0
  10. package/lib/api/evidence-kinds.api.js +128 -0
  11. package/lib/api/evidence.api.js +57 -1
  12. package/lib/api/index.js +24 -7
  13. package/lib/api/pipeline.api.js +47 -3
  14. package/lib/api/records-bulk.api.js +28 -3
  15. package/lib/api/resource-types.api.js +4 -4
  16. package/lib/api/roles.api.js +121 -0
  17. package/lib/api/types/evidence-kinds.types.js +42 -0
  18. package/lib/api/types/evidence.types.js +156 -8
  19. package/lib/api/types/roles.types.js +36 -0
  20. package/lib/api/work.api.js +283 -0
  21. package/lib/app/certification-verify-rows.js +1 -1
  22. package/lib/app/run-deploy-job.js +108 -0
  23. package/lib/app/run-helpers.js +10 -3
  24. package/lib/app/run.js +8 -0
  25. package/lib/app/show.js +2 -2
  26. package/lib/certification/merge-certification-from-artifact.js +1 -1
  27. package/lib/channels/add-channel.js +54 -23
  28. package/lib/channels/approval-guides/chatgpt.js +8 -7
  29. package/lib/channels/approval-guides/microsoft-copilot.js +7 -8
  30. package/lib/channels/channel-artifact-generator.js +16 -3
  31. package/lib/channels/channel-credential.js +3 -1
  32. package/lib/channels/channel-probe-evidence.js +79 -0
  33. package/lib/channels/channel-probe.js +265 -13
  34. package/lib/channels/channel-runtime-resolver.js +120 -29
  35. package/lib/channels/channel-status-display.js +44 -0
  36. package/lib/channels/channel-targets.js +7 -0
  37. package/lib/channels/chatgpt-runtime-contract.js +29 -0
  38. package/lib/channels/microsoft-copilot-package.js +280 -0
  39. package/lib/channels/runtime-tool-catalog.js +165 -0
  40. package/lib/cli/index.js +6 -0
  41. package/lib/cli/setup-app.js +26 -5
  42. package/lib/cli/setup-dev.js +23 -7
  43. package/lib/cli/setup-external-system-help.js +8 -2
  44. package/lib/cli/setup-external-system.js +12 -0
  45. package/lib/cli/setup-utility-help-after.js +12 -0
  46. package/lib/cli/setup-utility-validate.js +41 -2
  47. package/lib/commands/app-test.js +2 -14
  48. package/lib/commands/datasource-load-export-cli.js +6 -1
  49. package/lib/commands/deploy-gate-failure-details.js +23 -0
  50. package/lib/commands/deploy-gate-orchestrator.js +64 -18
  51. package/lib/commands/dev-cli-handlers.js +6 -3
  52. package/lib/commands/dev-down.js +2 -6
  53. package/lib/commands/dev-init.js +7 -109
  54. package/lib/commands/dev-refresh.js +197 -0
  55. package/lib/commands/evidence-kind.js +478 -0
  56. package/lib/commands/governance-command-action.js +4 -2
  57. package/lib/commands/governance-generate-external.js +56 -21
  58. package/lib/commands/lifecycle-external.js +10 -4
  59. package/lib/commands/repair-datasource-apply.js +10 -1
  60. package/lib/commands/repair-datasource-run.js +4 -2
  61. package/lib/commands/repair-datasource-test-payload.js +80 -19
  62. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +42 -3
  63. package/lib/commands/repair-internal.js +9 -1
  64. package/lib/commands/repair-openapi-export.js +1 -1
  65. package/lib/commands/repair-openapi-sync.js +43 -18
  66. package/lib/commands/resource-type.js +101 -18
  67. package/lib/commands/role-assistant.js +313 -0
  68. package/lib/commands/role.js +452 -0
  69. package/lib/commands/setup.js +1 -1
  70. package/lib/commands/upload-data-sync-finalize.js +5 -4
  71. package/lib/commands/upload-sidecar-followups.js +144 -47
  72. package/lib/commands/upload.js +43 -6
  73. package/lib/commands/validate-json.js +230 -0
  74. package/lib/commands/verify-governance-combined-external.js +73 -9
  75. package/lib/commands/verify-governance-db.js +80 -25
  76. package/lib/commands/verify-governance-external.js +29 -5
  77. package/lib/commands/verify-operations-step-plan.js +78 -40
  78. package/lib/commands/wizard-core-helpers.js +7 -3
  79. package/lib/commands/wizard-core.js +78 -9
  80. package/lib/core/audit-logger.js +1 -1
  81. package/lib/core/secrets-load.js +1 -3
  82. package/lib/datasource/bulk-loader-run-batches.js +4 -2
  83. package/lib/datasource/bulk-loader-service.js +5 -1
  84. package/lib/datasource/capability/relate-operations.js +1 -1
  85. package/lib/datasource/datasource-validate-summary.js +2 -2
  86. package/lib/datasource/validate.js +13 -6
  87. package/lib/external-system/deploy-helpers.js +35 -1
  88. package/lib/external-system/deploy.js +23 -10
  89. package/lib/external-system/download-helpers.js +111 -2
  90. package/lib/external-system/download-role-assistant.js +55 -0
  91. package/lib/external-system/download.js +45 -26
  92. package/lib/external-system/test-helpers.js +1 -1
  93. package/lib/external-system/test.js +39 -3
  94. package/lib/generator/builders.js +3 -0
  95. package/lib/generator/helpers.js +13 -5
  96. package/lib/generator/split-variables.js +9 -3
  97. package/lib/generator/wizard.js +51 -4
  98. package/lib/infrastructure/helpers-docker-check.js +6 -0
  99. package/lib/infrastructure/helpers.js +1 -1
  100. package/lib/lifecycle/access-control-abac.js +121 -0
  101. package/lib/lifecycle/lifecycle-governance-options.js +4 -1
  102. package/lib/lifecycle/product-model.js +3 -2
  103. package/lib/lifecycle/report-display.js +14 -2
  104. package/lib/programmatic/auth-config.js +3 -2
  105. package/lib/programmatic/bearer-auth.js +1 -1
  106. package/lib/programmatic/capability-registry.js +20 -1
  107. package/lib/programmatic/command-options.js +1 -0
  108. package/lib/programmatic/enterprise-mcp-client.js +18 -2
  109. package/lib/programmatic/index.js +4 -0
  110. package/lib/programmatic/manifest-patch-section.js +48 -9
  111. package/lib/programmatic/manifest-section-registry-data.js +3 -2
  112. package/lib/programmatic/manifest-section-registry.js +18 -1
  113. package/lib/programmatic/openapi-apply-result-schemas.js +44 -0
  114. package/lib/programmatic/openapi-component-schemas.js +16 -1
  115. package/lib/programmatic/openapi-description-enricher.js +3 -1
  116. package/lib/programmatic/openapi-descriptions.js +55 -5
  117. package/lib/programmatic/openapi-evidence-schemas.js +161 -0
  118. package/lib/programmatic/openapi-manifest-schemas.js +6 -2
  119. package/lib/programmatic/openapi-operation-bindings.js +99 -0
  120. package/lib/programmatic/openapi-request-schemas.js +36 -1
  121. package/lib/programmatic/openapi-result-schemas.js +29 -12
  122. package/lib/programmatic/openapi-schema-descriptions-certify.js +5 -1
  123. package/lib/programmatic/openapi-schema-descriptions-core.js +6 -3
  124. package/lib/programmatic/openapi-schema-descriptions-evidence.js +156 -0
  125. package/lib/programmatic/openapi-schema-descriptions-manifest.js +4 -3
  126. package/lib/programmatic/openapi-schema-descriptions-operations.js +70 -0
  127. package/lib/programmatic/openapi-schema-helpers.js +16 -1
  128. package/lib/programmatic/openapi-spec.js +48 -29
  129. package/lib/programmatic/orchestration-openapi-meta.js +5 -0
  130. package/lib/programmatic/request-timeout.js +3 -0
  131. package/lib/programmatic/route-handler-map.js +89 -2
  132. package/lib/programmatic/run-certify.js +15 -2
  133. package/lib/programmatic/run-deploy.js +74 -0
  134. package/lib/programmatic/run-evidence-authoring.js +80 -0
  135. package/lib/programmatic/run-protection.js +124 -0
  136. package/lib/programmatic/run-repository-emcp.js +11 -3
  137. package/lib/programmatic/run-template-workspace.js +42 -2
  138. package/lib/programmatic/workspace-context.js +6 -0
  139. package/lib/protection/auth-context.js +48 -6
  140. package/lib/protection/paths.js +22 -0
  141. package/lib/protection/run-protection-create-helpers.js +22 -1
  142. package/lib/protection/run-protection-create.js +1 -1
  143. package/lib/protection/sync-after-upload.js +1 -1
  144. package/lib/resolvers/evidence-kind-file.js +230 -0
  145. package/lib/resolvers/resource-type-file.js +36 -1
  146. package/lib/resolvers/role-file.js +227 -0
  147. package/lib/role-assistant/evidence-sync.js +450 -0
  148. package/lib/role-assistant/github-workflow.js +96 -0
  149. package/lib/role-assistant/knowledge-sync.js +465 -0
  150. package/lib/role-assistant/settings.js +126 -0
  151. package/lib/role-assistant/test-cases-evaluate.js +170 -0
  152. package/lib/role-assistant/test-cases-honesty.js +184 -0
  153. package/lib/role-assistant/test-cases.js +364 -0
  154. package/lib/role-assistant/test-runner-workhub-answers.js +203 -0
  155. package/lib/role-assistant/test-runner-workhub.js +385 -0
  156. package/lib/role-assistant/test-runner.js +500 -0
  157. package/lib/schema/application-schema.json +36 -2
  158. package/lib/schema/deployment-rules.yaml +1 -0
  159. package/lib/schema/external-datasource.schema.json +121 -4
  160. package/lib/schema/external-system.schema.json +20 -6
  161. package/lib/schema/infra.parameter.yaml +45 -1
  162. package/lib/schema/role-assistant-settings.schema.json +108 -0
  163. package/lib/schema/type/credential-field-registry.json +19 -3
  164. package/lib/utils/api.js +52 -21
  165. package/lib/utils/app-path-resolve.js +72 -24
  166. package/lib/utils/app-register-config.js +4 -3
  167. package/lib/utils/authentication-shape.js +3 -1
  168. package/lib/utils/cli-sync-options.js +59 -3
  169. package/lib/utils/cli-utils.js +11 -3
  170. package/lib/utils/deployment-validation.js +28 -3
  171. package/lib/utils/dev-ca-install.js +5 -6
  172. package/lib/utils/dev-config.js +2 -2
  173. package/lib/utils/dev-list-sort.js +145 -0
  174. package/lib/utils/dev-platform-tls.js +0 -63
  175. package/lib/utils/docker-build.js +46 -27
  176. package/lib/utils/docker-daemon-tls-ca.js +1 -1
  177. package/lib/utils/docker-exec.js +91 -6
  178. package/lib/utils/docker-run-ephemeral.js +55 -0
  179. package/lib/utils/enterprise-knowledge-paths.js +29 -12
  180. package/lib/utils/env-copy-keycloak.js +196 -0
  181. package/lib/utils/env-copy.js +35 -4
  182. package/lib/utils/error-formatters/error-parser.js +0 -3
  183. package/lib/utils/external-env-template.js +1 -1
  184. package/lib/utils/external-system-readiness-compact-blocks.js +28 -1
  185. package/lib/utils/external-system-readiness-compact-display.js +3 -0
  186. package/lib/utils/health-check-request.js +2 -3
  187. package/lib/utils/help-builder.js +4 -0
  188. package/lib/utils/image-name.js +22 -4
  189. package/lib/utils/logger.js +37 -4
  190. package/lib/utils/manifest-source-emit.js +1 -1
  191. package/lib/utils/paths.js +98 -26
  192. package/lib/utils/pipeline-upload-auth-retry.js +19 -3
  193. package/lib/utils/postgres-platform-bootstrap.js +24 -17
  194. package/lib/utils/postgres-wipe.js +5 -2
  195. package/lib/utils/remote-dev-auth.js +39 -4
  196. package/lib/utils/resolve-docker-image-ref.js +36 -6
  197. package/lib/utils/role-assistant-paths.js +98 -0
  198. package/lib/utils/schema-loader.js +41 -0
  199. package/lib/utils/schema-resolver.js +36 -4
  200. package/lib/utils/token-manager.js +47 -22
  201. package/lib/utils/upload-sync-options.js +17 -3
  202. package/lib/utils/url-declarative-resolve-load-doc.js +38 -1
  203. package/lib/validation/external-manifest-validator.js +31 -8
  204. package/lib/validation/openapi-contract-surface-validator.js +4 -0
  205. package/lib/validation/validate-external-file.js +8 -1
  206. package/lib/validation/validator.js +6 -5
  207. package/package.json +35 -12
  208. package/scripts/export-builder-api-evidence.js +3 -3
  209. package/scripts/lib/plan-actor.js +2 -2
  210. package/scripts/lib/plan-meta.js +1 -1
  211. package/scripts/lib/plan-parse.js +1 -1
  212. package/scripts/lib/plan-prevalidate-gates.js +12 -1
  213. package/scripts/lib/plan-run-report.js +13 -2
  214. package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +10 -10
  215. package/templates/applications/dataplane/application.yaml +47 -17
  216. package/templates/applications/dataplane/env.template +28 -9
  217. package/templates/applications/dataplane/rbac.yaml +78 -2
  218. package/templates/applications/miso-controller/application.yaml +10 -1
  219. package/templates/applications/miso-controller/env.template +13 -8
  220. package/templates/applications/miso-controller/rbac.yaml +72 -0
  221. package/templates/channels/chatgpt/install.template.md.hbs +42 -24
  222. package/templates/channels/chatgpt/integration/README.md +10 -7
  223. package/templates/channels/chatgpt/integration/application.json +2 -2
  224. package/templates/channels/chatgpt/integration/chatgpt-system.json +3 -3
  225. package/templates/channels/chatgpt/integration/env.template +1 -1
  226. package/templates/channels/chatgpt/manifest.template.json.hbs +36 -5
  227. package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +28 -0
  228. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +22 -0
  229. package/templates/channels/microsoft-copilot/install.template.md.hbs +32 -22
  230. package/templates/channels/microsoft-copilot/integration/README.md +9 -7
  231. package/templates/channels/microsoft-copilot/integration/application.json +2 -2
  232. package/templates/channels/microsoft-copilot/integration/env.template +1 -1
  233. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +7 -6
  234. package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -6
  235. package/templates/channels/slack/integration/slack-system.json +60 -2
  236. package/templates/python/requirements.txt +1 -1
@@ -12,10 +12,15 @@ const { enrichOpenApiComponentSchemas } = require('./openapi-description-enriche
12
12
  const { buildSuccessEnvelopeSchema } = require('./openapi-schema-helpers');
13
13
  const { OPENAPI_REQUEST_SCHEMAS } = require('./openapi-request-schemas');
14
14
  const { OPENAPI_RESULT_SCHEMAS } = require('./openapi-result-schemas');
15
+ const { OPENAPI_APPLY_RESULT_SCHEMAS } = require('./openapi-apply-result-schemas');
15
16
  const {
16
17
  OPENAPI_MANIFEST_REQUEST_SCHEMAS,
17
18
  OPENAPI_MANIFEST_RESULT_SCHEMAS
18
19
  } = require('./openapi-manifest-schemas');
20
+ const {
21
+ OPENAPI_EVIDENCE_REQUEST_SCHEMAS,
22
+ OPENAPI_EVIDENCE_RESULT_SCHEMAS
23
+ } = require('./openapi-evidence-schemas');
19
24
 
20
25
  const RESPONSE_ENVELOPES = [
21
26
  ['ListSystemsResponse', 'ListSystemsData'],
@@ -27,6 +32,9 @@ const RESPONSE_ENVELOPES = [
27
32
  ['ValidateResultResponse', 'ValidateResultData'],
28
33
  ['PreviewUploadResponse', 'PreviewUploadData'],
29
34
  ['UploadResultResponse', 'UploadResultData'],
35
+ ['DeployResultResponse', 'DeployResultData'],
36
+ ['ProtectionUploadResponse', 'ProtectionUploadData'],
37
+ ['ProtectionCreateResponse', 'ProtectionCreateData'],
30
38
  ['TestResultResponse', 'TestResultData'],
31
39
  ['CertifyResultResponse', 'CertifyResultData'],
32
40
  ['LifecycleReportResponse', 'LifecycleReportData'],
@@ -39,7 +47,11 @@ const RESPONSE_ENVELOPES = [
39
47
  ['ManifestSectionViewResponse', 'ManifestSectionViewData'],
40
48
  ['ManifestPatchResultResponse', 'ManifestPatchResultData'],
41
49
  ['ManifestSectionsListResponse', 'ManifestSectionsListData'],
42
- ['ManifestRepairResultResponse', 'ManifestRepairResultData']
50
+ ['ManifestRepairResultResponse', 'ManifestRepairResultData'],
51
+ ['EvidenceAuthoringMetadataResponse', 'EvidenceAuthoringMetadataData'],
52
+ ['EvidenceDownloadResponse', 'EvidenceDownloadData'],
53
+ ['EvidenceUploadResponse', 'EvidenceUploadData'],
54
+ ['EvidenceActivateResponse', 'EvidenceActivateData']
43
55
  ];
44
56
 
45
57
  /**
@@ -53,8 +65,11 @@ function buildOpenApiComponentSchemas() {
53
65
  return enrichOpenApiComponentSchemas({
54
66
  ...OPENAPI_REQUEST_SCHEMAS,
55
67
  ...OPENAPI_MANIFEST_REQUEST_SCHEMAS,
68
+ ...OPENAPI_EVIDENCE_REQUEST_SCHEMAS,
56
69
  ...OPENAPI_RESULT_SCHEMAS,
70
+ ...OPENAPI_APPLY_RESULT_SCHEMAS,
57
71
  ...OPENAPI_MANIFEST_RESULT_SCHEMAS,
72
+ ...OPENAPI_EVIDENCE_RESULT_SCHEMAS,
58
73
  EmptyResultData: { type: 'object', properties: {}, additionalProperties: false },
59
74
  ...envelopes
60
75
  });
@@ -14,6 +14,7 @@ const { CERTIFY_SCHEMA_DESCRIPTIONS } = require('./openapi-schema-descriptions-c
14
14
  const { MANIFEST_SCHEMA_DESCRIPTIONS } = require('./openapi-schema-descriptions-manifest');
15
15
  const { MCP_SCHEMA_DESCRIPTIONS } = require('./openapi-schema-descriptions-mcp');
16
16
  const { HELP_SCHEMA_DESCRIPTIONS } = require('./openapi-schema-descriptions-help');
17
+ const { EVIDENCE_SCHEMA_DESCRIPTIONS } = require('./openapi-schema-descriptions-evidence');
17
18
 
18
19
  /** @type {Record<string, Object>} */
19
20
  const MERGED_SCHEMA_DESCRIPTIONS = {
@@ -22,7 +23,8 @@ const MERGED_SCHEMA_DESCRIPTIONS = {
22
23
  ...CERTIFY_SCHEMA_DESCRIPTIONS,
23
24
  ...MANIFEST_SCHEMA_DESCRIPTIONS,
24
25
  ...MCP_SCHEMA_DESCRIPTIONS,
25
- ...HELP_SCHEMA_DESCRIPTIONS
26
+ ...HELP_SCHEMA_DESCRIPTIONS,
27
+ ...EVIDENCE_SCHEMA_DESCRIPTIONS
26
28
  };
27
29
 
28
30
  /**
@@ -53,25 +53,32 @@ const OPERATION_DESCRIPTIONS = Object.freeze({
53
53
  getManifestSection: {
54
54
  summary: 'Read one system manifest section',
55
55
  description:
56
- 'Return section value, schema fragment, quality, dependency graph, and sectionReadToken. MUST call before patchSection.',
56
+ 'Return section value, schema fragment, quality, dependency graph, and sectionReadToken. ' +
57
+ 'Recommended before patch when quality or missingInputs are needed; token is optional on PATCH.',
57
58
  tags: ['manifest']
58
59
  },
59
60
  patchManifestSection: {
60
61
  summary: 'Patch one system manifest section',
61
62
  description:
62
- 'Apply governed merge/replace to a system section. Requires intent and sectionReadToken from GET. Mutating.',
63
+ 'Apply governed merge/replace to a system section. Requires intent. ' +
64
+ 'sectionReadToken from GET is optional — when omitted, the server re-reads the section before write. ' +
65
+ 'Stale tokens return 409. Mutating.',
63
66
  tags: ['manifest']
64
67
  },
65
68
  getDatasourceManifestSection: {
66
69
  summary: 'Read one datasource manifest section',
67
70
  description:
68
- 'Return datasource section value, quality, missingInputs, and sectionReadToken. MUST call before patchSection.',
71
+ 'Return datasource section value, quality, missingInputs, and sectionReadToken. ' +
72
+ 'Recommended before patch when quality or missingInputs are needed; token is optional on PATCH.',
69
73
  tags: ['manifest']
70
74
  },
71
75
  patchDatasourceManifestSection: {
72
76
  summary: 'Patch one datasource manifest section',
73
77
  description:
74
- 'Apply governed merge/replace to a datasource section. Requires intent and sectionReadToken. Mutating.',
78
+ 'Apply governed merge/replace to a datasource section. Requires intent. ' +
79
+ 'sectionReadToken is optional (server re-reads when omitted; stale token → 409). ' +
80
+ 'For scalar sections (e.g. datasource.resourceType), send patch as { "value": "<scalar>" } or ' +
81
+ '{ "<leafName>": "<scalar>" }. Mutating.',
75
82
  tags: ['manifest']
76
83
  },
77
84
  runManifestRepair: {
@@ -115,6 +122,24 @@ const OPERATION_DESCRIPTIONS = Object.freeze({
115
122
  'Full dev publish: validate, sync deploy JSON, push credentials, pipeline upload. Requires external-system:publish in dev. Mutating; use Idempotency-Key; may take up to MAX_UPLOAD_TIMEOUT_MS.',
116
123
  tags: ['apply']
117
124
  },
125
+ runDeploySystem: {
126
+ summary: 'Deploy integration via controller (promote)',
127
+ description:
128
+ 'Controller deploy for external systems (CLI aifabrix deploy parity). Optional body.gate matches CLI --gate (operations,trust,governance,full). Certificate seal is a platform side-effect of published Deploy — not a separate certificates issue call. Mutating; use Idempotency-Key.',
129
+ tags: ['apply']
130
+ },
131
+ runProtectionUpload: {
132
+ summary: 'Upload protection manifest for a datasource',
133
+ description:
134
+ 'Validate and upload the workspace protection manifest for the datasource (CLI aifabrix protection upload parity). Optional sync after upload. Mutating; use Idempotency-Key.',
135
+ tags: ['apply']
136
+ },
137
+ runProtectionCreate: {
138
+ summary: 'Scaffold a local protection manifest',
139
+ description:
140
+ 'Probe dataplane + dimension catalog and write integration/.protection scaffold (CLI aifabrix protection create parity). Mutating; use Idempotency-Key.',
141
+ tags: ['apply']
142
+ },
118
143
  materializeTemplate: {
119
144
  summary: 'Materialize workspace from template',
120
145
  description:
@@ -128,7 +153,8 @@ const OPERATION_DESCRIPTIONS = Object.freeze({
128
153
  },
129
154
  runWorkspaceDiff: {
130
155
  summary: 'Diff workspace draft',
131
- description: 'Invoke Enterprise MCP workspace.diff for local draft vs remote/template baseline.',
156
+ description:
157
+ 'Diff local workspace draft vs remote/template baseline via Enterprise MCP workspace.diff when published; otherwise returns a local draft snapshot (source=local) without failing.',
132
158
  tags: ['workspace']
133
159
  },
134
160
  resetWorkspaceFromTemplate: {
@@ -167,6 +193,30 @@ const OPERATION_DESCRIPTIONS = Object.freeze({
167
193
  summary: 'Readiness probe',
168
194
  description: 'Returns ready with configured dataplaneUrl. Does not verify Dataplane connectivity in V1.',
169
195
  tags: ['infra']
196
+ },
197
+ getEvidenceMetadata: {
198
+ summary: 'Evidence authoring metadata',
199
+ description:
200
+ 'Return live Evidence kinds, aspects, resource types, Role Assistant capabilities, writable fields, and certification/activation constraints for the selected roleKey. Read-only aggregation over Dataplane and Controller catalogs.',
201
+ tags: ['evidence']
202
+ },
203
+ downloadEvidence: {
204
+ summary: 'Download Role Assistant Evidence',
205
+ description:
206
+ 'List or search Evidence for the selected roleKey using existing Dataplane Evidence filters. Read-only projection for AI authoring.',
207
+ tags: ['evidence']
208
+ },
209
+ uploadEvidenceCandidates: {
210
+ summary: 'Upload Evidence candidates',
211
+ description:
212
+ 'Load one or many Evidence rows as inactive candidates, validate each row, and technically certify valid rows. Never activates. Mutating; use Idempotency-Key.',
213
+ tags: ['evidence']
214
+ },
215
+ activateEvidenceCandidates: {
216
+ summary: 'Activate certified Evidence',
217
+ description:
218
+ 'Activate one or many human-approved certified Evidence ids. Organizational gate after technical certification. Mutating; use Idempotency-Key.',
219
+ tags: ['evidence']
170
220
  }
171
221
  });
172
222
 
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Frozen OpenAPI request/result schemas for Evidence authoring routes (162.0).
3
+ *
4
+ * @fileoverview BTA-facing Evidence metadata/download/upload/activate models
5
+ * @author AI Fabrix Team
6
+ * @version 1.0.0
7
+ */
8
+
9
+ 'use strict';
10
+
11
+ const { frozenObject, schemaRef, stringArraySchema } = require('./openapi-schema-helpers');
12
+
13
+ /** @type {Record<string, Object>} */
14
+ const OPENAPI_EVIDENCE_REQUEST_SCHEMAS = {
15
+ EvidenceUploadRow: frozenObject(
16
+ {
17
+ key: { type: 'string' },
18
+ resourceType: { type: 'string' },
19
+ roleKey: { type: 'string' },
20
+ kindKey: { type: 'string' },
21
+ kindVersion: { type: 'string' },
22
+ title: { type: 'string' },
23
+ description: { type: 'string' },
24
+ when: { type: 'string' },
25
+ expectedBehavior: { type: 'string' },
26
+ aspect: { type: 'string' },
27
+ order: { type: 'integer' },
28
+ status: { type: 'string', enum: ['candidate', 'active', 'disabled', 'archived'] }
29
+ },
30
+ ['title', 'when', 'expectedBehavior']
31
+ ),
32
+ EvidenceUploadRequest: frozenObject(
33
+ {
34
+ roleKey: {
35
+ type: 'string',
36
+ description: 'Optional override; defaults to the path roleKey.'
37
+ },
38
+ rows: { type: 'array', items: schemaRef('EvidenceUploadRow') },
39
+ comment: { type: 'string' }
40
+ },
41
+ ['rows']
42
+ ),
43
+ EvidenceActivateRequest: frozenObject(
44
+ {
45
+ evidenceIds: stringArraySchema()
46
+ },
47
+ ['evidenceIds']
48
+ )
49
+ };
50
+
51
+ /** @type {Record<string, Object>} */
52
+ const OPENAPI_EVIDENCE_RESULT_SCHEMAS = {
53
+ EvidenceKindSummary: frozenObject({
54
+ key: { type: ['string', 'null'] },
55
+ version: { type: ['string', 'null'] },
56
+ displayName: { type: ['string', 'null'] },
57
+ purpose: { type: ['string', 'null'] }
58
+ }),
59
+ EvidenceResourceTypeSummary: frozenObject({
60
+ key: { type: ['string', 'null'] },
61
+ displayName: { type: ['string', 'null'] },
62
+ category: { type: ['string', 'null'] }
63
+ }),
64
+ EvidenceAuthoringConstraints: frozenObject({
65
+ certification: frozenObject({
66
+ validationStatus: { type: 'string' },
67
+ candidateStatus: { type: 'string' }
68
+ }),
69
+ activation: frozenObject({
70
+ requiresCertified: { type: 'boolean' },
71
+ requiresAuthority: { type: 'boolean' }
72
+ })
73
+ }),
74
+ EvidenceAuthoringMetadataData: frozenObject(
75
+ {
76
+ roleKey: { type: 'string' },
77
+ evidenceKinds: { type: 'array', items: schemaRef('EvidenceKindSummary') },
78
+ aspects: stringArraySchema(),
79
+ resourceTypes: { type: 'array', items: schemaRef('EvidenceResourceTypeSummary') },
80
+ assistantCapabilities: stringArraySchema(),
81
+ writableFields: stringArraySchema(),
82
+ requiredFields: stringArraySchema(),
83
+ constraints: schemaRef('EvidenceAuthoringConstraints')
84
+ },
85
+ [
86
+ 'roleKey',
87
+ 'evidenceKinds',
88
+ 'aspects',
89
+ 'resourceTypes',
90
+ 'assistantCapabilities',
91
+ 'writableFields',
92
+ 'requiredFields',
93
+ 'constraints'
94
+ ]
95
+ ),
96
+ EvidenceRowProjection: frozenObject({
97
+ id: { type: 'string' },
98
+ key: { type: ['string', 'null'] },
99
+ resourceType: { type: ['string', 'null'] },
100
+ roleKey: { type: ['string', 'null'] },
101
+ kindKey: { type: ['string', 'null'] },
102
+ kindVersion: { type: ['string', 'null'] },
103
+ title: { type: 'string' },
104
+ description: { type: ['string', 'null'] },
105
+ when: { type: 'string' },
106
+ expectedBehavior: { type: 'string' },
107
+ aspect: { type: ['string', 'null'] },
108
+ order: { type: 'integer' },
109
+ status: { type: 'string' },
110
+ fingerprint: { type: ['string', 'null'] }
111
+ }),
112
+ EvidenceDownloadData: frozenObject(
113
+ {
114
+ roleKey: { type: 'string' },
115
+ count: { type: 'integer', minimum: 0 },
116
+ data: { type: 'array', items: schemaRef('EvidenceRowProjection') }
117
+ },
118
+ ['roleKey', 'count', 'data']
119
+ ),
120
+ EvidenceUploadItemOutcome: frozenObject({
121
+ rowIndex: { type: 'integer' },
122
+ evidenceId: { type: ['string', 'null'] },
123
+ evidenceRef: { type: ['string', 'null'] },
124
+ status: { type: 'string' },
125
+ message: { type: 'string' },
126
+ issues: { type: 'array', items: { type: 'string' } }
127
+ }),
128
+ EvidenceUploadData: frozenObject(
129
+ {
130
+ roleKey: { type: 'string' },
131
+ inserted: { type: 'integer', minimum: 0 },
132
+ updated: { type: 'integer', minimum: 0 },
133
+ accepted: { type: 'array', items: schemaRef('EvidenceUploadItemOutcome') },
134
+ rejected: { type: 'array', items: schemaRef('EvidenceUploadItemOutcome') },
135
+ warnings: { type: 'array', items: schemaRef('EvidenceUploadItemOutcome') },
136
+ certified: { type: 'array', items: schemaRef('EvidenceUploadItemOutcome') },
137
+ readyToActivate: { type: 'boolean' }
138
+ },
139
+ ['roleKey', 'accepted', 'rejected', 'warnings', 'certified', 'readyToActivate']
140
+ ),
141
+ EvidenceActivateItemOutcome: frozenObject({
142
+ evidenceId: { type: 'string' },
143
+ result: schemaRef('EvidenceRowProjection'),
144
+ error: { type: 'string' },
145
+ status: { type: ['integer', 'null'] }
146
+ }),
147
+ EvidenceActivateData: frozenObject(
148
+ {
149
+ requested: { type: 'integer', minimum: 0 },
150
+ activated: { type: 'array', items: schemaRef('EvidenceActivateItemOutcome') },
151
+ failed: { type: 'array', items: schemaRef('EvidenceActivateItemOutcome') },
152
+ success: { type: 'boolean' }
153
+ },
154
+ ['requested', 'activated', 'failed', 'success']
155
+ )
156
+ };
157
+
158
+ module.exports = {
159
+ OPENAPI_EVIDENCE_REQUEST_SCHEMAS,
160
+ OPENAPI_EVIDENCE_RESULT_SCHEMAS
161
+ };
@@ -54,10 +54,14 @@ const OPENAPI_MANIFEST_REQUEST_SCHEMAS = {
54
54
  intent: { type: 'string', minLength: 1, description: 'Why this patch is made — audit and repair hints.' },
55
55
  patch: { type: 'object', description: 'Section-scoped merge/replace payload.' },
56
56
  mode: { type: 'string', enum: ['merge', 'replace'], description: 'Merge into or replace section value.' },
57
- sectionReadToken: { type: 'string', description: 'Token from prior GET; stale token returns 409.' },
57
+ sectionReadToken: {
58
+ type: 'string',
59
+ description:
60
+ 'Optional token from prior GET. When omitted, the server re-reads the section immediately before write. Stale token returns 409.'
61
+ },
58
62
  dryRun: { type: 'boolean', description: 'Validate patch without writing files.' }
59
63
  },
60
- ['intent', 'patch', 'mode', 'sectionReadToken']
64
+ ['intent', 'patch', 'mode']
61
65
  ),
62
66
  ManifestRepairRequest: frozenObject(
63
67
  {
@@ -40,6 +40,14 @@ const DATASOURCE_KEY_PARAM = {
40
40
  description: 'Datasource key within the integration workspace.'
41
41
  };
42
42
 
43
+ const ROLE_KEY_PARAM = {
44
+ name: 'roleKey',
45
+ in: 'path',
46
+ required: true,
47
+ schema: { type: 'string' },
48
+ description: 'Role Assistant key that scopes Evidence authoring.'
49
+ };
50
+
43
51
  const IDEMPOTENCY_HEADER = {
44
52
  name: 'Idempotency-Key',
45
53
  in: 'header',
@@ -208,6 +216,21 @@ const OPERATION_BINDINGS = Object.freeze({
208
216
  requestBody: jsonRequestBody('UploadRequest'),
209
217
  successResponse: 'UploadResultResponse'
210
218
  },
219
+ runDeploySystem: {
220
+ parameters: [SYSTEM_KEY_PARAM],
221
+ requestBody: jsonRequestBody('DeployRequest'),
222
+ successResponse: 'DeployResultResponse'
223
+ },
224
+ runProtectionUpload: {
225
+ parameters: [SYSTEM_KEY_PARAM, DATASOURCE_KEY_PARAM],
226
+ requestBody: jsonRequestBody('ProtectionUploadRequest'),
227
+ successResponse: 'ProtectionUploadResponse'
228
+ },
229
+ runProtectionCreate: {
230
+ parameters: [SYSTEM_KEY_PARAM, DATASOURCE_KEY_PARAM],
231
+ requestBody: jsonRequestBody('ProtectionCreateRequest'),
232
+ successResponse: 'ProtectionCreateResponse'
233
+ },
211
234
  materializeTemplate: {
212
235
  parameters: [SYSTEM_KEY_PARAM],
213
236
  requestBody: jsonRequestBody('TemplateMaterializeRequest'),
@@ -251,6 +274,82 @@ const OPERATION_BINDINGS = Object.freeze({
251
274
  },
252
275
  ready: {
253
276
  successResponse: 'ReadyResponse'
277
+ },
278
+ getEvidenceMetadata: {
279
+ parameters: [ROLE_KEY_PARAM],
280
+ successResponse: 'EvidenceAuthoringMetadataResponse'
281
+ },
282
+ downloadEvidence: {
283
+ parameters: [ROLE_KEY_PARAM],
284
+ queryParameters: [
285
+ {
286
+ name: 'resourceType',
287
+ in: 'query',
288
+ required: false,
289
+ schema: { type: 'string' },
290
+ description: 'Filter Evidence by catalog resource type key.'
291
+ },
292
+ {
293
+ name: 'status',
294
+ in: 'query',
295
+ required: false,
296
+ schema: { type: 'string', enum: ['candidate', 'active', 'disabled', 'archived'] },
297
+ description: 'Filter Evidence by lifecycle status.'
298
+ },
299
+ {
300
+ name: 'kindKey',
301
+ in: 'query',
302
+ required: false,
303
+ schema: { type: 'string' },
304
+ description: 'Filter Evidence by kind key.'
305
+ },
306
+ {
307
+ name: 'aspect',
308
+ in: 'query',
309
+ required: false,
310
+ schema: { type: 'string' },
311
+ description: 'Filter Evidence by aspect label.'
312
+ },
313
+ {
314
+ name: 'search',
315
+ in: 'query',
316
+ required: false,
317
+ schema: { type: 'string' },
318
+ description: 'Search Evidence title or text fields.'
319
+ },
320
+ {
321
+ name: 'genericOnly',
322
+ in: 'query',
323
+ required: false,
324
+ schema: { type: 'boolean' },
325
+ description: 'When true, return only generic (non role-bound) Evidence.'
326
+ },
327
+ {
328
+ name: 'limit',
329
+ in: 'query',
330
+ required: false,
331
+ schema: { type: 'integer', minimum: 1 },
332
+ description: 'Maximum number of Evidence rows to return.'
333
+ },
334
+ {
335
+ name: 'offset',
336
+ in: 'query',
337
+ required: false,
338
+ schema: { type: 'integer', minimum: 0 },
339
+ description: 'Offset for Evidence list pagination.'
340
+ }
341
+ ],
342
+ successResponse: 'EvidenceDownloadResponse'
343
+ },
344
+ uploadEvidenceCandidates: {
345
+ parameters: [ROLE_KEY_PARAM],
346
+ requestBody: jsonRequestBody('EvidenceUploadRequest'),
347
+ successResponse: 'EvidenceUploadResponse'
348
+ },
349
+ activateEvidenceCandidates: {
350
+ parameters: [ROLE_KEY_PARAM],
351
+ requestBody: jsonRequestBody('EvidenceActivateRequest'),
352
+ successResponse: 'EvidenceActivateResponse'
254
353
  }
255
354
  });
256
355
 
@@ -96,6 +96,37 @@ const OPENAPI_REQUEST_SCHEMAS = {
96
96
  force: { type: 'boolean' },
97
97
  probe: { type: 'boolean' }
98
98
  }),
99
+ DeployRequest: frozenObject({
100
+ gate: {
101
+ type: 'string',
102
+ description:
103
+ 'Optional pre-promote gates, same as CLI --gate (comma-separated: operations, trust, governance, full).'
104
+ },
105
+ subjectEmail: { type: 'string', format: 'email' },
106
+ probe: { type: 'boolean' },
107
+ sync: { type: 'boolean' },
108
+ verbose: { type: 'boolean' }
109
+ }),
110
+ ProtectionUploadRequest: frozenObject({
111
+ dryRun: { type: 'boolean' },
112
+ sync: { type: 'boolean' },
113
+ verbose: { type: 'boolean' }
114
+ }),
115
+ ProtectionCreateRequest: frozenObject({
116
+ type: { type: 'string' },
117
+ dimensionKey: { type: 'string' },
118
+ field: { type: 'string' },
119
+ fkName: { type: 'string' },
120
+ protectionKey: { type: 'string' },
121
+ displayName: { type: 'string' },
122
+ ruleKey: { type: 'string' },
123
+ principalExpression: { type: 'string' },
124
+ valueExpression: { type: 'string' },
125
+ dryRun: { type: 'boolean' },
126
+ force: { type: 'boolean' },
127
+ verbose: { type: 'boolean' },
128
+ disabled: { type: 'boolean' }
129
+ }),
99
130
  TestRequest: frozenObject({
100
131
  runType: schemaRef('TestRunType'),
101
132
  noPublish: { type: 'boolean' }
@@ -103,7 +134,11 @@ const OPENAPI_REQUEST_SCHEMAS = {
103
134
  CertifyRequest: frozenObject({
104
135
  noPublish: { type: 'boolean' },
105
136
  pack: { type: 'string' },
106
- lifecycleBody: schemaRef('LifecycleRunRequest')
137
+ lifecycleBody: schemaRef('LifecycleRunRequest'),
138
+ subjectEmail: { type: 'string', format: 'email' },
139
+ subjectEmails: stringArraySchema(),
140
+ subjectUserIds: stringArraySchema(),
141
+ certificationProfile: { type: 'string' }
107
142
  }),
108
143
  LifecycleRunRequest: frozenObject({
109
144
  subjectEmail: { type: 'string', format: 'email' },
@@ -12,18 +12,35 @@ const { frozenObject, schemaRef, stringArraySchema } = require('./openapi-schema
12
12
 
13
13
  /** @type {Record<string, Object>} */
14
14
  const OPENAPI_RESULT_SCHEMAS = {
15
- ProblemDetails: frozenObject(
16
- {
17
- type: { type: 'string', format: 'uri-reference' },
18
- title: { type: 'string' },
19
- status: { type: 'integer', minimum: 100, maximum: 599 },
20
- detail: { type: 'string' },
21
- instance: { type: 'string' },
22
- correlationId: { type: 'string' },
23
- errors: { type: 'array', items: schemaRef('ProblemValidationError') }
24
- },
25
- ['type', 'title', 'status', 'detail']
15
+ ProblemDetail: Object.assign(
16
+ frozenObject(
17
+ {
18
+ type: { type: 'string', format: 'uri-reference' },
19
+ title: { type: 'string' },
20
+ status: { type: 'integer', minimum: 100, maximum: 599 },
21
+ detail: { type: 'string' },
22
+ instance: { type: 'string' },
23
+ correlationId: { type: 'string' },
24
+ errors: { type: 'array', items: schemaRef('ProblemValidationError') }
25
+ },
26
+ ['type', 'title', 'status', 'detail', 'correlationId', 'instance', 'errors']
27
+ ),
28
+ {
29
+ example: {
30
+ type: '/Errors/Unauthorized',
31
+ title: 'Unauthorized',
32
+ status: 401,
33
+ detail: 'Missing or invalid Bearer token.',
34
+ instance: '/api/v1/builder/workspaces/me/systems',
35
+ correlationId: '00000000-0000-4000-8000-000000000003',
36
+ errors: []
37
+ }
38
+ }
26
39
  ),
40
+ /** Prefer ProblemDetail; allOf alias for published REST lint (OAPI-148). */
41
+ ProblemDetails: {
42
+ allOf: [schemaRef('ProblemDetail')]
43
+ },
27
44
  ProblemValidationError: frozenObject(
28
45
  {
29
46
  field: { type: 'string' },
@@ -34,7 +51,7 @@ const OPENAPI_RESULT_SCHEMAS = {
34
51
  ),
35
52
  LifecycleVerdict: {
36
53
  type: 'string',
37
- enum: ['VERIFIED', 'FAILED', 'NOT_VERIFIED']
54
+ enum: ['VERIFIED', 'FAILED', 'NOT_VERIFIED', 'NOT_APPLICABLE']
38
55
  },
39
56
  CertificationLevel: {
40
57
  type: 'string',
@@ -14,7 +14,11 @@ const CERTIFY_SCHEMA_DESCRIPTIONS = {
14
14
  _schema: 'Optional flags for certification pillar commands.',
15
15
  noPublish: 'When true, skip publishing local files before verify commands.',
16
16
  pack: 'Governance scenario pack key for verify-governance.',
17
- lifecycleBody: 'Optional subject and dry-run options when pillar is lifecycle-run.'
17
+ lifecycleBody: 'Optional subject and dry-run options when pillar is lifecycle-run.',
18
+ subjectEmail: 'Subject user email for governance pack generate (governance pillar).',
19
+ subjectEmails: 'Additional subject emails for governance pack generate.',
20
+ subjectUserIds: 'Subject user ids for governance pack generate.',
21
+ certificationProfile: 'Certification profile for governance generate (bronze, silver, …).'
18
22
  },
19
23
  LifecycleRunRequest: {
20
24
  _schema: 'Options for lifecycle-run certification pillar.',
@@ -22,7 +22,7 @@ const CORE_SCHEMA_DESCRIPTIONS = {
22
22
  RepositorySyncDirection: {
23
23
  _schema: 'Repository sync direction: pull remote into workspace or push workspace to remote.'
24
24
  },
25
- ProblemDetails: {
25
+ ProblemDetail: {
26
26
  _schema: 'RFC 7807 problem response for builder-api errors (application/problem+json).',
27
27
  type: 'Problem type URI or identifier.',
28
28
  title: 'Short human-readable error title.',
@@ -32,14 +32,17 @@ const CORE_SCHEMA_DESCRIPTIONS = {
32
32
  correlationId: 'Correlation id for log lookup across services.',
33
33
  errors: 'Field-level validation errors when status is 400.'
34
34
  },
35
+ ProblemDetails: {
36
+ _schema: 'Alias of ProblemDetail (allOf) for backward-compatible $refs.'
37
+ },
35
38
  ProblemValidationError: {
36
- _schema: 'Single field validation error inside ProblemDetails.errors.',
39
+ _schema: 'Single field validation error inside ProblemDetail.errors.',
37
40
  field: 'JSON pointer or field name that failed validation.',
38
41
  message: 'Validation failure message.',
39
42
  value: 'Rejected value when safe to echo (may be omitted for secrets).'
40
43
  },
41
44
  LifecycleVerdict: {
42
- _schema: 'Lifecycle verification outcome: VERIFIED, FAILED, or NOT_VERIFIED.'
45
+ _schema: 'Lifecycle verification outcome: VERIFIED, FAILED, NOT_VERIFIED, or NOT_APPLICABLE.'
43
46
  },
44
47
  CertificationLevel: {
45
48
  _schema: 'Certification tier: BRONZE through PLATINUM, or NONE when uncertified.'