@aifabrix/builder 2.53.1 → 2.55.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 (470) hide show
  1. package/README.md +8 -0
  2. package/bin/aifabrix.js +2 -2
  3. package/lib/agent-kit/apply-ops.js +82 -0
  4. package/lib/agent-kit/checksums.js +28 -0
  5. package/lib/agent-kit/classify.js +113 -0
  6. package/lib/agent-kit/claude-shim.js +61 -0
  7. package/lib/agent-kit/constants.js +55 -0
  8. package/lib/agent-kit/file-list.js +103 -0
  9. package/lib/agent-kit/host-approve.js +130 -0
  10. package/lib/agent-kit/hosting/github.js +63 -0
  11. package/lib/agent-kit/hosts.js +71 -0
  12. package/lib/agent-kit/init.js +319 -0
  13. package/lib/agent-kit/kit-root.js +17 -0
  14. package/lib/agent-kit/managed-section.js +79 -0
  15. package/lib/agent-kit/package-load.js +45 -0
  16. package/lib/agent-kit/plan-ops.js +69 -0
  17. package/lib/agent-kit/remote-prompts.js +239 -0
  18. package/lib/agent-kit/render-host-markdown.js +40 -0
  19. package/lib/agent-kit/repo-guard.js +47 -0
  20. package/lib/agent-kit/report.js +107 -0
  21. package/lib/agent-kit/run.js +82 -0
  22. package/lib/agent-kit/scm/git.js +122 -0
  23. package/lib/agent-kit/state-file.js +83 -0
  24. package/lib/agent-kit/status.js +50 -0
  25. package/lib/agent-kit/v1-detect.js +81 -0
  26. package/lib/agent-kit/validate-kit.js +87 -0
  27. package/lib/agent-kit/workspace-name.js +40 -0
  28. package/lib/agent-kit/workspace-skeleton.js +103 -0
  29. package/lib/api/assistants.api.js +8 -5
  30. package/lib/api/channel-identity.api.js +41 -0
  31. package/lib/api/evidence-authoring.api.js +5 -1
  32. package/lib/api/evidence.api.js +2 -0
  33. package/lib/api/role-assistant-test-pack.api.js +86 -0
  34. package/lib/api/types/evidence.types.js +2 -0
  35. package/lib/api/work-search.api.js +163 -0
  36. package/lib/api/work.api.js +19 -12
  37. package/lib/app/list-external-systems.js +2 -1
  38. package/lib/app/show-display.js +33 -6
  39. package/lib/app/show.js +25 -2
  40. package/lib/channels/add-channel.js +164 -126
  41. package/lib/channels/approval-guides/chatgpt.js +14 -18
  42. package/lib/channels/approval-guides/claude.js +29 -0
  43. package/lib/channels/approval-guides/index.js +88 -22
  44. package/lib/channels/approval-guides/mcp-client.js +27 -0
  45. package/lib/channels/approval-guides/microsoft-copilot.js +52 -3
  46. package/lib/channels/approval-guides/slack.js +10 -10
  47. package/lib/channels/approval-guides/teams-bot.js +8 -12
  48. package/lib/channels/channel-add-continuations.js +91 -0
  49. package/lib/channels/channel-add-ensure.js +124 -27
  50. package/lib/channels/channel-add-existing.js +160 -28
  51. package/lib/channels/channel-add-failure.js +61 -0
  52. package/lib/channels/channel-add-remaining.js +492 -0
  53. package/lib/channels/channel-add-tty.js +190 -0
  54. package/lib/channels/channel-add-wizard-config.js +138 -0
  55. package/lib/channels/channel-add-wizard.js +250 -0
  56. package/lib/channels/channel-artifact-generator.js +27 -13
  57. package/lib/channels/channel-cardinality.js +83 -0
  58. package/lib/channels/channel-catalog-icon.js +45 -0
  59. package/lib/channels/channel-cli-instructions.js +75 -0
  60. package/lib/channels/channel-configuration-map.js +213 -0
  61. package/lib/channels/channel-credential.js +11 -14
  62. package/lib/channels/channel-definition-project.js +101 -0
  63. package/lib/channels/channel-definition-registry.js +154 -0
  64. package/lib/channels/channel-definition-status.js +115 -0
  65. package/lib/channels/channel-description.js +60 -2
  66. package/lib/channels/channel-discovery.js +16 -2
  67. package/lib/channels/channel-external-system.js +86 -9
  68. package/lib/channels/channel-install-envelope-actions.js +88 -0
  69. package/lib/channels/channel-install-envelope-microsoft.js +155 -0
  70. package/lib/channels/channel-install-envelope.js +358 -0
  71. package/lib/channels/channel-install-help-md.js +172 -0
  72. package/lib/channels/channel-install-http-payload.js +62 -0
  73. package/lib/channels/channel-install-inventory.js +115 -0
  74. package/lib/channels/channel-install-profiles.js +90 -0
  75. package/lib/channels/channel-instance-collision.js +118 -0
  76. package/lib/channels/channel-instance-key.js +100 -0
  77. package/lib/channels/channel-instance-materialize.js +240 -0
  78. package/lib/channels/channel-integration-generator.js +18 -9
  79. package/lib/channels/channel-integration-template.js +101 -22
  80. package/lib/channels/channel-inventory-fetch.js +79 -0
  81. package/lib/channels/channel-oauth-preflight.js +104 -0
  82. package/lib/channels/channel-package-version.js +76 -0
  83. package/lib/channels/channel-predefined-client.js +154 -0
  84. package/lib/channels/channel-probe.js +7 -2
  85. package/lib/channels/channel-runtime-resolver.js +194 -72
  86. package/lib/channels/channel-status-display.js +86 -16
  87. package/lib/channels/channel-targets.js +132 -92
  88. package/lib/channels/chatgpt-callback.js +318 -0
  89. package/lib/channels/chatgpt-channel-add.js +229 -0
  90. package/lib/channels/chatgpt-preflight.js +396 -0
  91. package/lib/channels/chatgpt-runtime-contract.js +17 -0
  92. package/lib/channels/chatgpt-setup-values.js +124 -0
  93. package/lib/channels/claude-callback.js +67 -0
  94. package/lib/channels/claude-channel-add.js +254 -0
  95. package/lib/channels/claude-runtime-contract.js +40 -0
  96. package/lib/channels/claude-runtime.js +58 -0
  97. package/lib/channels/claude-setup-values.js +92 -0
  98. package/lib/channels/mcp-client/config-merge.js +148 -0
  99. package/lib/channels/mcp-client/ensure-client.js +231 -0
  100. package/lib/channels/mcp-client/paths.js +53 -0
  101. package/lib/channels/mcp-client/profiles.js +122 -0
  102. package/lib/channels/mcp-client/redirect-uris.js +99 -0
  103. package/lib/channels/mcp-client/runtime.js +59 -0
  104. package/lib/channels/mcp-client-channel-add.js +186 -0
  105. package/lib/channels/microsoft-copilot-channel-add.js +117 -7
  106. package/lib/channels/microsoft-copilot-entra-identifier-uris.js +187 -0
  107. package/lib/channels/microsoft-copilot-entra-sso-form.js +106 -18
  108. package/lib/channels/microsoft-copilot-entra-sso.js +31 -2
  109. package/lib/channels/microsoft-copilot-package-prior.js +107 -0
  110. package/lib/channels/microsoft-copilot-package.js +29 -28
  111. package/lib/channels/microsoft-provisioning/a365.js +80 -0
  112. package/lib/channels/microsoft-provisioning/auth-config.js +240 -0
  113. package/lib/channels/microsoft-provisioning/auth.js +179 -0
  114. package/lib/channels/microsoft-provisioning/cli.js +71 -0
  115. package/lib/channels/microsoft-provisioning/constants.js +75 -0
  116. package/lib/channels/microsoft-provisioning/errors.js +117 -0
  117. package/lib/channels/microsoft-provisioning/index.js +55 -0
  118. package/lib/channels/microsoft-provisioning/install-atk.js +158 -0
  119. package/lib/channels/microsoft-provisioning/install-teams.js +115 -0
  120. package/lib/channels/microsoft-provisioning/login-portal-device.js +236 -0
  121. package/lib/channels/microsoft-provisioning/login-portal-parse.js +71 -0
  122. package/lib/channels/microsoft-provisioning/login-portal-teams.js +193 -0
  123. package/lib/channels/microsoft-provisioning/login-portal.js +230 -0
  124. package/lib/channels/microsoft-provisioning/persist.js +110 -0
  125. package/lib/channels/microsoft-provisioning/teams-bot-args.js +119 -0
  126. package/lib/channels/microsoft-provisioning/teams-bot-controller.js +123 -0
  127. package/lib/channels/microsoft-provisioning/teams-bot-parse.js +134 -0
  128. package/lib/channels/microsoft-provisioning/teams-bot-persist.js +113 -0
  129. package/lib/channels/microsoft-provisioning/teams-bot-provision.js +234 -0
  130. package/lib/channels/microsoft-provisioning/teams-bot-secrets.js +45 -0
  131. package/lib/channels/microsoft-provisioning/teams-cli.js +82 -0
  132. package/lib/channels/runtime-tool-catalog.js +5 -2
  133. package/lib/channels/slack-channel-add-portal.js +130 -0
  134. package/lib/channels/slack-channel-add-tty-auth.js +95 -0
  135. package/lib/channels/slack-channel-add.js +311 -0
  136. package/lib/channels/slack-mcp-callback.js +51 -0
  137. package/lib/channels/slack-mcp-runtime.js +156 -0
  138. package/lib/channels/slack-provisioning/apps.js +181 -0
  139. package/lib/channels/slack-provisioning/auth-store.js +110 -0
  140. package/lib/channels/slack-provisioning/auth-ticket.js +185 -0
  141. package/lib/channels/slack-provisioning/auth.js +115 -0
  142. package/lib/channels/slack-provisioning/callbacks.js +41 -0
  143. package/lib/channels/slack-provisioning/cli.js +226 -0
  144. package/lib/channels/slack-provisioning/constants.js +37 -0
  145. package/lib/channels/slack-provisioning/credentials.js +169 -0
  146. package/lib/channels/slack-provisioning/curl-shim.js +132 -0
  147. package/lib/channels/slack-provisioning/developer-install.js +118 -0
  148. package/lib/channels/slack-provisioning/env-file.js +120 -0
  149. package/lib/channels/slack-provisioning/errors.js +47 -0
  150. package/lib/channels/slack-provisioning/go-ca-bundle.js +137 -0
  151. package/lib/channels/slack-provisioning/index.js +250 -0
  152. package/lib/channels/slack-provisioning/install-cli.js +335 -0
  153. package/lib/channels/slack-provisioning/manifest.js +89 -0
  154. package/lib/channels/slack-provisioning/oauth-lock.js +33 -0
  155. package/lib/channels/slack-provisioning/offer-cli.js +113 -0
  156. package/lib/channels/slack-provisioning/onboard-members.js +122 -0
  157. package/lib/channels/slack-provisioning/onboard.js +89 -0
  158. package/lib/channels/slack-provisioning/persist.js +95 -0
  159. package/lib/channels/slack-provisioning/remaining-urls.js +158 -0
  160. package/lib/channels/slack-provisioning/with-curl-on-path.js +53 -0
  161. package/lib/channels/teams-bot-channel-add.js +94 -0
  162. package/lib/channels/vendor-dataplane-url.js +249 -0
  163. package/lib/cli/index.js +4 -0
  164. package/lib/cli/setup-certification-commands.js +2 -2
  165. package/lib/cli/setup-certification.help.js +5 -1
  166. package/lib/cli/setup-external-system-help.js +2 -0
  167. package/lib/cli/setup-external-system.js +1 -1
  168. package/lib/commands/agent-kit-help.js +79 -0
  169. package/lib/commands/agent-kit.js +346 -0
  170. package/lib/commands/channel-add-help.js +366 -0
  171. package/lib/commands/channel-add-setup.js +162 -80
  172. package/lib/commands/channel-configure.js +118 -0
  173. package/lib/commands/channel.js +10 -1
  174. package/lib/commands/datasource-capability-relate-cli.js +5 -4
  175. package/lib/commands/governance-upload-external.js +6 -3
  176. package/lib/commands/lifecycle-command-action.js +2 -5
  177. package/lib/commands/lifecycle-external.js +93 -21
  178. package/lib/commands/repair-auth-apply.js +1 -1
  179. package/lib/commands/repair-datasource-key-skip.js +39 -0
  180. package/lib/commands/repair-datasource-keys.js +24 -12
  181. package/lib/commands/repair-datasource-test-payload.js +4 -2
  182. package/lib/commands/repair-datasource-webhooks-sync-bridge.js +23 -2
  183. package/lib/commands/repair-datasource.js +3 -0
  184. package/lib/commands/repair-external-run.js +59 -25
  185. package/lib/commands/repair-openapi-rest-runtime.js +127 -0
  186. package/lib/commands/repair-orchestration-tag-merge.js +339 -0
  187. package/lib/commands/repair-rbac-catalog-defaults.js +96 -0
  188. package/lib/commands/repair-rbac-platform-preset.js +26 -15
  189. package/lib/commands/repair-rbac-reader-roles.js +8 -21
  190. package/lib/commands/repair-rbac.js +26 -44
  191. package/lib/commands/repair-system-permissions.js +24 -22
  192. package/lib/commands/role-assistant-copy-output.js +61 -0
  193. package/lib/commands/role-assistant-copy.js +155 -0
  194. package/lib/commands/role-assistant-test-output.js +22 -9
  195. package/lib/commands/role-assistant-test-result-rows.js +42 -0
  196. package/lib/commands/role-assistant.js +150 -43
  197. package/lib/commands/search.js +143 -0
  198. package/lib/commands/test-e2e-external.js +148 -21
  199. package/lib/commands/test-trust-external.js +7 -5
  200. package/lib/commands/upload-credential-push-log.js +2 -1
  201. package/lib/commands/upload-publish-context.js +1 -1
  202. package/lib/commands/upload-role-assistant-shell.js +124 -0
  203. package/lib/commands/upload-sidecar-followups.js +10 -4
  204. package/lib/commands/upload.js +18 -3
  205. package/lib/commands/verify-operations-skip-e2e.js +131 -0
  206. package/lib/commands/verify-operations-step-plan.js +6 -33
  207. package/lib/commands/verify-operations-steps.js +3 -1
  208. package/lib/core/secrets-docker-env.js +4 -1
  209. package/lib/core/secrets-env-content.js +17 -3
  210. package/lib/datasource/capability/capability-manifest.js +0 -3
  211. package/lib/datasource/capability/copy-test-payload.js +3 -0
  212. package/lib/datasource/capability/relate-operations.js +28 -10
  213. package/lib/datasource/capability/run-capability-relate.js +48 -25
  214. package/lib/datasource/datasource-identifier.js +13 -5
  215. package/lib/deployment/deployer-poll-run.js +117 -35
  216. package/lib/external-system/deploy-dataplane-published.js +70 -0
  217. package/lib/external-system/deploy-helpers.js +26 -1
  218. package/lib/external-system/deploy.js +22 -8
  219. package/lib/external-system/download-helpers.js +29 -2
  220. package/lib/external-system/download-role-assistant.js +109 -4
  221. package/lib/external-system/download.js +46 -30
  222. package/lib/external-system/sync-deploy-manifest.js +3 -2
  223. package/lib/external-system/upload-identity.js +42 -0
  224. package/lib/generator/index.js +19 -15
  225. package/lib/generator/split.js +13 -2
  226. package/lib/generator/wizard-datasource-key.js +54 -0
  227. package/lib/generator/wizard.js +55 -54
  228. package/lib/integration-definition/apply-datasource-keys.js +75 -0
  229. package/lib/integration-definition/apply-relationships.js +195 -0
  230. package/lib/integration-definition/apply-static-enterprise.js +229 -0
  231. package/lib/integration-definition/apply-system-file.js +71 -0
  232. package/lib/integration-definition/apply-test-endpoint.js +89 -0
  233. package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
  234. package/lib/integration-definition/apply.js +78 -59
  235. package/lib/integration-definition/enrich-openapi-operations.js +36 -10
  236. package/lib/integration-definition/enrich-openapi-pick.js +87 -0
  237. package/lib/lifecycle/role-assistant-governance.js +181 -0
  238. package/lib/lifecycle/scenario-upload.js +181 -30
  239. package/lib/programmatic/builder-api-cors.js +143 -0
  240. package/lib/programmatic/builder-api-request.js +6 -0
  241. package/lib/programmatic/builder-api-route-dispatch.js +56 -42
  242. package/lib/programmatic/builder-api-server.js +8 -1
  243. package/lib/programmatic/capability-registry.js +55 -0
  244. package/lib/programmatic/channel-install-help-resolve.js +359 -0
  245. package/lib/programmatic/channel-install-session.js +218 -0
  246. package/lib/programmatic/help-content/channel-onboarding.md +2 -0
  247. package/lib/programmatic/help-content/cip-overview.md +3 -1
  248. package/lib/programmatic/http-raw-response.js +62 -0
  249. package/lib/programmatic/index.js +2 -0
  250. package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
  251. package/lib/programmatic/openapi-channel-install-bindings.js +179 -0
  252. package/lib/programmatic/openapi-channel-install-schemas.js +289 -0
  253. package/lib/programmatic/openapi-component-schemas.js +19 -1
  254. package/lib/programmatic/openapi-description-enricher.js +3 -1
  255. package/lib/programmatic/openapi-descriptions.js +80 -3
  256. package/lib/programmatic/openapi-envelope-examples.js +124 -0
  257. package/lib/programmatic/openapi-operation-bindings.js +9 -1
  258. package/lib/programmatic/openapi-request-schemas.js +5 -0
  259. package/lib/programmatic/openapi-schema-descriptions-channel.js +319 -0
  260. package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
  261. package/lib/programmatic/openapi-spec.js +13 -8
  262. package/lib/programmatic/platform-rbac-catalog.js +36 -18
  263. package/lib/programmatic/request-timeout.js +3 -0
  264. package/lib/programmatic/route-handler-map.js +58 -1
  265. package/lib/programmatic/route-handlers-context.js +2 -1
  266. package/lib/programmatic/run-auth-permissions.js +54 -0
  267. package/lib/programmatic/run-channel-catalog.js +238 -0
  268. package/lib/programmatic/run-channel-install-artifacts.js +137 -0
  269. package/lib/programmatic/run-channel-install-copilot.js +353 -0
  270. package/lib/programmatic/run-channel-install-options.js +236 -0
  271. package/lib/programmatic/run-channel-install-teams-bot.js +204 -0
  272. package/lib/programmatic/run-channel-install.js +346 -0
  273. package/lib/programmatic/run-channel-package.js +87 -7
  274. package/lib/programmatic/run-download.js +41 -0
  275. package/lib/programmatic/workspace-context.js +2 -0
  276. package/lib/protection/auth-context.js +3 -1
  277. package/lib/protection/protection-display.js +3 -2
  278. package/lib/protection/report-exit.js +50 -0
  279. package/lib/protection/run-commands.js +2 -0
  280. package/lib/role-assistant/evidence-sync.js +4 -2
  281. package/lib/role-assistant/evidence-validation-issues.js +51 -0
  282. package/lib/role-assistant/knowledge-sync.js +10 -4
  283. package/lib/role-assistant/package-validate.js +175 -0
  284. package/lib/role-assistant/settings.js +49 -2
  285. package/lib/role-assistant/test-case-assertion-row.js +36 -0
  286. package/lib/role-assistant/test-case-copy-bind.js +77 -0
  287. package/lib/role-assistant/test-case-copy-expected.js +127 -0
  288. package/lib/role-assistant/test-case-copy-from-work.js +90 -0
  289. package/lib/role-assistant/test-case-copy-interactions.js +67 -0
  290. package/lib/role-assistant/test-case-copy.js +119 -0
  291. package/lib/role-assistant/test-case-expected-catalog.js +135 -0
  292. package/lib/role-assistant/test-case-validate.js +88 -0
  293. package/lib/role-assistant/test-cases-bid.js +117 -4
  294. package/lib/role-assistant/test-cases-evaluate.js +159 -24
  295. package/lib/role-assistant/test-cases-evidence.js +175 -0
  296. package/lib/role-assistant/test-cases-honesty.js +155 -6
  297. package/lib/role-assistant/test-cases-lifecycle.js +291 -0
  298. package/lib/role-assistant/test-cases-search-graph.js +122 -0
  299. package/lib/role-assistant/test-cases-search.js +247 -0
  300. package/lib/role-assistant/test-cases.js +71 -172
  301. package/lib/role-assistant/test-pack-map.js +180 -0
  302. package/lib/role-assistant/test-pack-sync.js +187 -0
  303. package/lib/role-assistant/test-runner-debug.js +54 -0
  304. package/lib/role-assistant/test-runner-respond-body.js +36 -0
  305. package/lib/role-assistant/test-runner-search.js +164 -0
  306. package/lib/role-assistant/test-runner-start-payload.js +63 -10
  307. package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
  308. package/lib/role-assistant/test-runner-workhub-helpers.js +40 -2
  309. package/lib/role-assistant/test-runner-workhub-soft.js +9 -3
  310. package/lib/role-assistant/test-runner-workhub.js +74 -32
  311. package/lib/role-assistant/test-runner.js +66 -11
  312. package/lib/schema/external-datasource.schema.json +146 -21
  313. package/lib/schema/external-system.schema.json +177 -2
  314. package/lib/schema/mcp-client-profile.schema.json +103 -0
  315. package/lib/schema/role-assistant-test-case.schema.json +408 -0
  316. package/lib/search/dataplane-context.js +23 -0
  317. package/lib/search/search-args.js +211 -0
  318. package/lib/search/search-display.js +238 -0
  319. package/lib/search/search-errors.js +50 -0
  320. package/lib/search/search-prompts.js +119 -0
  321. package/lib/search/search-roles.js +85 -0
  322. package/lib/search/search-run.js +241 -0
  323. package/lib/search/search-skills.js +198 -0
  324. package/lib/utils/app-path-resolve.js +4 -0
  325. package/lib/utils/authentication-env-template.js +44 -6
  326. package/lib/utils/authentication-slot-show.js +153 -0
  327. package/lib/utils/credential-display.js +43 -1
  328. package/lib/utils/credential-secrets-env.js +6 -1
  329. package/lib/utils/env-copy.js +19 -7
  330. package/lib/utils/external-env-template.js +20 -2
  331. package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
  332. package/lib/utils/external-system-readiness-compact-display.js +30 -1
  333. package/lib/utils/external-system-validators.js +2 -1
  334. package/lib/utils/help-builder.js +3 -1
  335. package/lib/utils/paths.js +18 -1
  336. package/lib/utils/platform-shell-package.js +69 -0
  337. package/lib/utils/port-resolver.js +50 -1
  338. package/lib/utils/rewrite-name-flag.js +20 -0
  339. package/lib/utils/role-assistant-paths.js +13 -10
  340. package/lib/utils/schema-loader.js +37 -0
  341. package/lib/utils/schema-resolver.js +11 -1
  342. package/lib/utils/secrets-helpers.js +12 -21
  343. package/lib/utils/token-manager.js +10 -5
  344. package/lib/validation/validate-external-file.js +5 -1
  345. package/lib/validation/validate.js +41 -0
  346. package/package.json +1 -1
  347. package/templates/README.md +1 -1
  348. package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
  349. package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
  350. package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
  351. package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
  352. package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
  353. package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
  354. package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
  355. package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
  356. package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
  357. package/templates/agent-kit/agent-kit.yaml +45 -0
  358. package/templates/agent-kit/instructions/AGENTKIT.md +83 -0
  359. package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
  360. package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
  361. package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
  362. package/templates/agent-kit/parity-inventory.yaml +188 -0
  363. package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +58 -0
  364. package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
  365. package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
  366. package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
  367. package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
  368. package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +51 -0
  369. package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
  370. package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
  371. package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
  372. package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +50 -0
  373. package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
  374. package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
  375. package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
  376. package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +42 -0
  377. package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
  378. package/templates/agent-kit/skills/shared/hosts.md +78 -0
  379. package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
  380. package/templates/agent-kit/workspace/LICENSE.mit +21 -0
  381. package/templates/agent-kit/workspace/README.md +89 -0
  382. package/templates/applications/builder-api/Dockerfile +3 -1
  383. package/templates/applications/builder-api/env.template +7 -0
  384. package/templates/applications/dataplane/application.yaml +6 -5
  385. package/templates/applications/dataplane/env.template +2 -2
  386. package/templates/applications/dataplane/rbac.yaml +35 -2
  387. package/templates/applications/keycloak/Dockerfile +30 -4
  388. package/templates/applications/keycloak/application.yaml +2 -2
  389. package/templates/applications/keycloak/cimd-lenient-parse/AbstractClientIdMetadataDocumentExecutor.java +896 -0
  390. package/templates/applications/keycloak/cimd-lenient-parse/SOURCE.md +19 -0
  391. package/templates/applications/keycloak/env.template +3 -0
  392. package/templates/applications/miso-controller/application.yaml +1 -2
  393. package/templates/applications/miso-controller/env.template +10 -9
  394. package/templates/channels/README.md +5 -5
  395. package/templates/channels/chatgpt/TROUBLESHOOTING.md +51 -0
  396. package/templates/channels/chatgpt/channel.json +59 -0
  397. package/templates/channels/chatgpt/icon.svg +1 -0
  398. package/templates/channels/chatgpt/install.template.md.hbs +20 -95
  399. package/templates/channels/chatgpt/integration/README.md +1 -1
  400. package/templates/channels/chatgpt/integration/application.json +2 -2
  401. package/templates/channels/chatgpt/integration/chatgpt-system.json +49 -4
  402. package/templates/channels/chatgpt/integration/env.template +2 -4
  403. package/templates/channels/chatgpt/integration/rbac.json +13 -0
  404. package/templates/channels/claude/TROUBLESHOOTING.md +44 -0
  405. package/templates/channels/claude/channel.json +59 -0
  406. package/templates/channels/claude/icon.svg +1 -0
  407. package/templates/channels/claude/install.template.md.hbs +22 -0
  408. package/templates/channels/claude/integration/README.md +14 -0
  409. package/templates/channels/claude/integration/application.json +15 -0
  410. package/templates/channels/claude/integration/claude-system.json +59 -0
  411. package/templates/channels/claude/integration/env.template +2 -0
  412. package/templates/channels/claude/integration/rbac.json +13 -0
  413. package/templates/channels/claude/manifest.template.json.hbs +40 -0
  414. package/templates/channels/mcp-client/channel.json +72 -0
  415. package/templates/channels/mcp-client/icon.svg +1 -0
  416. package/templates/channels/mcp-client/install.template.md.hbs +24 -0
  417. package/templates/channels/mcp-client/integration/README.md +13 -0
  418. package/templates/channels/mcp-client/integration/application.json +15 -0
  419. package/templates/channels/mcp-client/integration/env.template +2 -0
  420. package/templates/channels/mcp-client/integration/mcp-client-system.json +72 -0
  421. package/templates/channels/mcp-client/integration/rbac.json +13 -0
  422. package/templates/channels/mcp-client/manifest.template.json.hbs +41 -0
  423. package/templates/channels/mcp-client/profiles/cursor.json +26 -0
  424. package/templates/channels/mcp-client/profiles/github-copilot.json +29 -0
  425. package/templates/channels/mcp-client/profiles/vscode.json +29 -0
  426. package/templates/channels/microsoft-copilot/channel.json +73 -0
  427. package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +8 -4
  428. package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +65 -5
  429. package/templates/channels/microsoft-copilot/icon.svg +1 -0
  430. package/templates/channels/microsoft-copilot/install.template.md.hbs +9 -9
  431. package/templates/channels/microsoft-copilot/integration/README.md +1 -1
  432. package/templates/channels/microsoft-copilot/integration/application.json +2 -2
  433. package/templates/channels/microsoft-copilot/integration/env.template +3 -6
  434. package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +63 -4
  435. package/templates/channels/microsoft-copilot/integration/rbac.json +13 -0
  436. package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +5 -5
  437. package/templates/channels/slack/channel.json +234 -0
  438. package/templates/channels/slack/icon.svg +1 -0
  439. package/templates/channels/slack/install.template.md.hbs +45 -28
  440. package/templates/channels/slack/integration/README.md +245 -22
  441. package/templates/channels/slack/integration/application.json +44 -7
  442. package/templates/channels/slack/integration/env.template +15 -6
  443. package/templates/channels/slack/integration/openapi/openapi.json +126 -0
  444. package/templates/channels/slack/integration/rbac.json +84 -0
  445. package/templates/channels/slack/integration/slack-datasource-commands.json +154 -0
  446. package/templates/channels/slack/integration/slack-datasource-conversations.json +28 -3
  447. package/templates/channels/slack/integration/slack-datasource-events.json +154 -0
  448. package/templates/channels/slack/integration/slack-datasource-interactive.json +154 -0
  449. package/templates/channels/slack/integration/slack-datasource-messages.json +40 -2
  450. package/templates/channels/slack/integration/slack-system.json +161 -72
  451. package/templates/channels/slack/manifest.template.json.hbs +10 -4
  452. package/templates/channels/teams-bot/channel.json +162 -0
  453. package/templates/channels/teams-bot/icon.svg +1 -0
  454. package/templates/channels/teams-bot/install.template.md.hbs +12 -13
  455. package/templates/channels/teams-bot/integration/README.md +5 -4
  456. package/templates/channels/teams-bot/integration/application.json +6 -4
  457. package/templates/channels/teams-bot/integration/env.template +5 -4
  458. package/templates/channels/teams-bot/integration/openapi/openapi.json +68 -0
  459. package/templates/channels/teams-bot/integration/rbac.json +21 -0
  460. package/templates/channels/teams-bot/integration/teams-bot-datasource-activities.json +154 -0
  461. package/templates/channels/teams-bot/integration/teams-bot-system.json +128 -23
  462. package/templates/channels/web-embed/channel.json +60 -0
  463. package/templates/channels/web-embed/install.template.md.hbs +1 -1
  464. package/templates/channels/web-embed/integration/README.md +2 -2
  465. package/templates/channels/web-embed/integration/application.json +2 -2
  466. package/templates/channels/web-embed/integration/env.template +1 -1
  467. package/templates/channels/web-embed/integration/rbac.json +13 -0
  468. package/templates/channels/web-embed/integration/web-embed-system.json +50 -4
  469. package/templates/python/docker-compose.hbs +14 -0
  470. package/templates/typescript/docker-compose.hbs +14 -0
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Nested expected-field catalog for Role Assistant YAML cases.
3
+ * @fileoverview Fail-closed coverage walk after AJV nested schema
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const HONESTY_KEYS = [
9
+ 'requireWorkResult',
10
+ 'schemaVersion',
11
+ 'requireCompletion',
12
+ 'requireContributionObservation',
13
+ 'minResourceChanges',
14
+ 'softResourceChanges',
15
+ 'forbidBuilderKeysInObjective'
16
+ ];
17
+ const SEARCH_KEYS = [
18
+ 'statusCode',
19
+ 'operation',
20
+ 'resultMode',
21
+ 'minRows',
22
+ 'errorContains',
23
+ 'graphDepth',
24
+ 'relatedTypes',
25
+ 'related'
26
+ ];
27
+ const SEARCH_RELATED_KEYS = ['minRows', 'resultMode'];
28
+ const SKILLS_KEYS = ['resourceType', 'operations', 'filterFields', 'operationRequired'];
29
+ const EVIDENCE_KEYS = ['requiredKeys', 'roleKey', 'resourceType', 'requireStatus'];
30
+ const BID_KEYS = [
31
+ 'schemaName',
32
+ 'schemaVersion',
33
+ 'requireDefinitionHash',
34
+ 'requireSuiteRunId',
35
+ 'forbidGoldPaths',
36
+ 'minDatasources',
37
+ 'requireCapability'
38
+ ];
39
+ const EXPECTED_KEYS = [
40
+ 'soft',
41
+ 'softNotes',
42
+ 'honesty',
43
+ 'lifecycleState',
44
+ 'capabilities',
45
+ 'search',
46
+ 'skills',
47
+ 'evidence',
48
+ 'bid',
49
+ 'facts',
50
+ 'prohibited'
51
+ ];
52
+ const CAPABILITY_KEYS = ['allowed', 'required', 'forbidden'];
53
+ const NESTED = {
54
+ 'expected.honesty': HONESTY_KEYS,
55
+ 'expected.search': SEARCH_KEYS,
56
+ 'expected.skills': SKILLS_KEYS,
57
+ 'expected.evidence': EVIDENCE_KEYS,
58
+ 'expected.bid': BID_KEYS,
59
+ 'expected.capabilities': CAPABILITY_KEYS,
60
+ 'preflight.evidence': EVIDENCE_KEYS
61
+ };
62
+
63
+ function objectKeys(value) {
64
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
65
+ return [];
66
+ }
67
+ return Object.keys(value);
68
+ }
69
+
70
+ function unknownKeyError(filePath, pointer, key, allowed) {
71
+ const allowedText = allowed.join(', ');
72
+ return (
73
+ `${filePath}: unknown field ${pointer}.${key}. ` +
74
+ `Allowed properties: ${allowedText}. ` +
75
+ 'Remove the field or rename it to a listed property.'
76
+ );
77
+ }
78
+
79
+ function collectUnknownInObject(filePath, pointer, value, allowed, errors) {
80
+ for (const key of objectKeys(value)) {
81
+ if (!allowed.includes(key)) {
82
+ errors.push(unknownKeyError(filePath, pointer, key, allowed));
83
+ }
84
+ }
85
+ }
86
+
87
+ function collectSearchRelatedUnknown(filePath, related, errors) {
88
+ for (const resourceType of objectKeys(related)) {
89
+ collectUnknownInObject(
90
+ filePath,
91
+ `expected.search.related.${resourceType}`,
92
+ related[resourceType],
93
+ SEARCH_RELATED_KEYS,
94
+ errors
95
+ );
96
+ }
97
+ }
98
+
99
+ function collectNestedUnknown(filePath, parsed, errors) {
100
+ const expected = parsed.expected && typeof parsed.expected === 'object' ? parsed.expected : {};
101
+ collectUnknownInObject(filePath, 'expected', expected, EXPECTED_KEYS, errors);
102
+ collectUnknownInObject(filePath, 'expected.honesty', expected.honesty, HONESTY_KEYS, errors);
103
+ collectUnknownInObject(filePath, 'expected.search', expected.search, SEARCH_KEYS, errors);
104
+ collectSearchRelatedUnknown(filePath, expected.search && expected.search.related, errors);
105
+ collectUnknownInObject(filePath, 'expected.skills', expected.skills, SKILLS_KEYS, errors);
106
+ collectUnknownInObject(filePath, 'expected.evidence', expected.evidence, EVIDENCE_KEYS, errors);
107
+ collectUnknownInObject(filePath, 'expected.bid', expected.bid, BID_KEYS, errors);
108
+ collectUnknownInObject(
109
+ filePath,
110
+ 'expected.capabilities',
111
+ expected.capabilities,
112
+ CAPABILITY_KEYS,
113
+ errors
114
+ );
115
+ const preflight = parsed.preflight && typeof parsed.preflight === 'object' ? parsed.preflight : {};
116
+ collectUnknownInObject(filePath, 'preflight.evidence', preflight.evidence, EVIDENCE_KEYS, errors);
117
+ }
118
+
119
+ function assertExpectedCoverage(parsed, filePath) {
120
+ const errors = [];
121
+ collectNestedUnknown(filePath, parsed || {}, errors);
122
+ return errors;
123
+ }
124
+
125
+ module.exports = {
126
+ HONESTY_KEYS,
127
+ SEARCH_KEYS,
128
+ SEARCH_RELATED_KEYS,
129
+ SKILLS_KEYS,
130
+ EVIDENCE_KEYS,
131
+ BID_KEYS,
132
+ EXPECTED_KEYS,
133
+ NESTED,
134
+ assertExpectedCoverage
135
+ };
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Offline Role Assistant test-case schema validation.
3
+ * @fileoverview AJV check for YAML cases before auth or package publish
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const path = require('path');
9
+ const { parseJsonFileContent } = require('../validation/validate-external-file');
10
+ const { loadRoleAssistantTestCaseSchema } = require('../utils/schema-loader');
11
+ const { formatValidationErrors } = require('../utils/error-formatter');
12
+ const { assertExpectedCoverage } = require('./test-case-expected-catalog');
13
+
14
+ const TEST_CASE_TYPE = 'role-assistant-test-case';
15
+
16
+ function formatCaseErrors(filePath, ajvErrors) {
17
+ return formatValidationErrors(ajvErrors, { dedupe: true }).map((msg) => {
18
+ const fix = /additional properties/i.test(msg)
19
+ ? ' Remove the field or rename it to a listed property.'
20
+ : '';
21
+ return `${filePath}: ${msg}${fix}`;
22
+ });
23
+ }
24
+
25
+ function validateTestCaseDocument(parsed, filePath) {
26
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
27
+ return {
28
+ valid: false,
29
+ errors: [`${filePath}: Test case must be an object`],
30
+ warnings: []
31
+ };
32
+ }
33
+ const validate = loadRoleAssistantTestCaseSchema();
34
+ const ok = validate(parsed);
35
+ const errors = ok
36
+ ? assertExpectedCoverage(parsed, filePath)
37
+ : formatCaseErrors(filePath, validate.errors);
38
+ return { valid: errors.length === 0, errors, warnings: [] };
39
+ }
40
+
41
+ function validateTestCaseFile(filePath) {
42
+ const parseResult = parseJsonFileContent(filePath);
43
+ if (parseResult.error) {
44
+ return { ...parseResult.error, file: filePath, type: TEST_CASE_TYPE };
45
+ }
46
+ const result = validateTestCaseDocument(parseResult.parsed, filePath);
47
+ return { ...result, file: filePath, type: TEST_CASE_TYPE };
48
+ }
49
+
50
+ function assertTestCaseDocument(parsed, filePath) {
51
+ const result = validateTestCaseDocument(parsed, filePath);
52
+ if (!result.valid) {
53
+ throw new Error(result.errors.join('\n'));
54
+ }
55
+ }
56
+
57
+ function throwIfCaseFileInvalid(filePath) {
58
+ const result = validateTestCaseFile(filePath);
59
+ if (!result.valid) {
60
+ throw new Error(result.errors.join('\n'));
61
+ }
62
+ }
63
+
64
+ function assertLocalCasesBeforeAuth(systemKey, opts) {
65
+ if (!opts || opts.fromDataplane || opts.listCases) {
66
+ return;
67
+ }
68
+ const { listTestCaseFiles, loadRoleAssistantTestCase } = require('./test-cases');
69
+ if (opts.case) {
70
+ loadRoleAssistantTestCase(systemKey, opts.case, { testsDir: opts.testsDir || null });
71
+ return;
72
+ }
73
+ if (!opts.suite) {
74
+ return;
75
+ }
76
+ const testsDir = opts.testsDir || path.join(process.cwd(), 'role-assistant', systemKey, 'tests');
77
+ for (const filePath of listTestCaseFiles(testsDir)) {
78
+ throwIfCaseFileInvalid(filePath);
79
+ }
80
+ }
81
+
82
+ module.exports = {
83
+ TEST_CASE_TYPE,
84
+ validateTestCaseDocument,
85
+ validateTestCaseFile,
86
+ assertTestCaseDocument,
87
+ assertLocalCasesBeforeAuth
88
+ };
@@ -5,6 +5,8 @@
5
5
 
6
6
  'use strict';
7
7
 
8
+ const { skipRow } = require('./test-case-assertion-row');
9
+
8
10
  function asArray(value) {
9
11
  return Array.isArray(value) ? value : [];
10
12
  }
@@ -71,10 +73,71 @@ function collectBidSchemaAssertions(expectedBid, observed, assertions, soft) {
71
73
  }
72
74
  }
73
75
 
74
- function assertDefinitionHash(expectedBid, observed, assertions, soft) {
75
- if (expectedBid.requireDefinitionHash !== true) {
76
+ function isDatasourceRecord(value) {
77
+ const key = String(value.key || value.datasourceKey || '').trim();
78
+ return Boolean(key && (Array.isArray(value.capabilities) || value.entityType || value.resourceType));
79
+ }
80
+
81
+ function nestedBidContainers(value) {
82
+ const nested = [];
83
+ if (Array.isArray(value.datasources)) {
84
+ nested.push(value.datasources);
85
+ }
86
+ if (value.spec && typeof value.spec === 'object') {
87
+ nested.push(value.spec);
88
+ }
89
+ if (value.emitted && typeof value.emitted === 'object') {
90
+ nested.push(value.emitted);
91
+ }
92
+ if (value.bid && typeof value.bid === 'object') {
93
+ nested.push(value.bid);
94
+ }
95
+ return nested;
96
+ }
97
+
98
+ function collectBidObjects(value, acc) {
99
+ if (Array.isArray(value)) {
100
+ value.forEach((item) => collectBidObjects(item, acc));
76
101
  return;
77
102
  }
103
+ if (!value || typeof value !== 'object') {
104
+ return;
105
+ }
106
+ nestedBidContainers(value).forEach((child) => collectBidObjects(child, acc));
107
+ if (isDatasourceRecord(value)) {
108
+ acc.push(value);
109
+ }
110
+ }
111
+
112
+ function bidBlob(observed) {
113
+ return observed.emitted || observed.emitRow || observed.applyRow || {};
114
+ }
115
+
116
+ function datasourceKeysFromBid(observed) {
117
+ const objects = [];
118
+ collectBidObjects(bidBlob(observed), objects);
119
+ return new Set(objects.map((row) => String(row.key || row.datasourceKey || '').trim()).filter(Boolean));
120
+ }
121
+
122
+ function datasourceHasCapability(observed, datasource, capKey) {
123
+ const objects = [];
124
+ collectBidObjects(bidBlob(observed), objects);
125
+ const match = objects.find((row) => String(row.key || row.datasourceKey || '') === datasource);
126
+ const caps = asArray(match && match.capabilities);
127
+ return caps.some((cap) => String((cap && cap.key) || cap || '') === capKey);
128
+ }
129
+
130
+ function pushBooleanBidFlag(expectedBid, field, observed, assertions, soft, assertFn) {
131
+ if (expectedBid[field] === false) {
132
+ assertions.push(skipRow(`expected.bid.${field}`, `${field} is false — check skipped.`));
133
+ return;
134
+ }
135
+ if (expectedBid[field] === true) {
136
+ assertFn(expectedBid, observed, assertions, soft);
137
+ }
138
+ }
139
+
140
+ function assertDefinitionHash(expectedBid, observed, assertions, soft) {
78
141
  const { emitRow, applyRow, emitted } = observed;
79
142
  const hash =
80
143
  (emitted && emitted.definitionHash) ||
@@ -112,11 +175,60 @@ function assertSuiteRunId(expectedBid, observed, assertions, soft) {
112
175
  }
113
176
 
114
177
  function collectBidProvenanceAssertions(expectedBid, observed, assertions, soft) {
115
- assertDefinitionHash(expectedBid, observed, assertions, soft);
116
- assertSuiteRunId(expectedBid, observed, assertions, soft);
178
+ pushBooleanBidFlag(expectedBid, 'requireDefinitionHash', observed, assertions, soft, assertDefinitionHash);
179
+ pushBooleanBidFlag(expectedBid, 'requireSuiteRunId', observed, assertions, soft, assertSuiteRunId);
180
+ }
181
+
182
+ function collectBidDatasourceAssertions(expectedBid, observed, assertions, soft) {
183
+ if (Array.isArray(expectedBid.minDatasources)) {
184
+ collectMinDatasources(expectedBid.minDatasources, observed, assertions, soft);
185
+ }
186
+ if (expectedBid.requireCapability && typeof expectedBid.requireCapability === 'object') {
187
+ collectRequireCapability(expectedBid.requireCapability, observed, assertions, soft);
188
+ }
189
+ }
190
+
191
+ function collectMinDatasources(requiredKeys, observed, assertions, soft) {
192
+ if (requiredKeys.length === 0) {
193
+ assertions.push(skipRow('expected.bid.minDatasources', 'minDatasources is empty — nothing to assert.'));
194
+ return;
195
+ }
196
+ const actual = datasourceKeysFromBid(observed);
197
+ for (const raw of requiredKeys) {
198
+ const key = String(raw || '').trim();
199
+ const passed = hasEmitOrApply(observed) && actual.has(key);
200
+ pushBidAssertion(
201
+ assertions,
202
+ soft,
203
+ `expected.bid.minDatasources:${key}`,
204
+ passed,
205
+ `BID lists datasource "${key}".`,
206
+ `BID does not list required datasource "${key}".`
207
+ );
208
+ }
209
+ }
210
+
211
+ function collectRequireCapability(spec, observed, assertions, soft) {
212
+ const datasource = String(spec.datasource || '').trim();
213
+ const capKey = String(spec.key || '').trim();
214
+ const passed = hasEmitOrApply(observed) && datasourceHasCapability(observed, datasource, capKey);
215
+ pushBidAssertion(
216
+ assertions,
217
+ soft,
218
+ 'expected.bid.requireCapability',
219
+ passed,
220
+ `BID datasource "${datasource}" lists capability "${capKey}".`,
221
+ `BID datasource "${datasource}" does not list capability "${capKey}".`
222
+ );
117
223
  }
118
224
 
119
225
  function collectBidPathAssertions(expectedBid, observed, assertions, soft) {
226
+ if (expectedBid.forbidGoldPaths === false) {
227
+ assertions.push(
228
+ skipRow('expected.bid.forbidGoldPaths', 'forbidGoldPaths is false — gold-path check skipped.')
229
+ );
230
+ return;
231
+ }
120
232
  if (expectedBid.forbidGoldPaths === true) {
121
233
  const { emitRow, applyRow, emitted } = observed;
122
234
  const blob = JSON.stringify(emitted || emitRow || applyRow || {});
@@ -146,6 +258,7 @@ function collectBidAssertions(expectedBid, observation, options = {}) {
146
258
  const soft = options.soft === true;
147
259
  collectBidSchemaAssertions(expectedBid, observed, assertions, soft);
148
260
  collectBidProvenanceAssertions(expectedBid, observed, assertions, soft);
261
+ collectBidDatasourceAssertions(expectedBid, observed, assertions, soft);
149
262
  collectBidPathAssertions(expectedBid, observed, assertions, soft);
150
263
  return assertions;
151
264
  }
@@ -10,12 +10,49 @@ const {
10
10
  evaluateHonestyExpectations
11
11
  } = require('./test-cases-honesty');
12
12
  const { collectBidAssertions } = require('./test-cases-bid');
13
+ const {
14
+ evaluateEvidenceExpectations,
15
+ evaluateForbiddenCapabilities
16
+ } = require('./test-cases-evidence');
17
+ const {
18
+ evaluateSearchExpectations,
19
+ evaluateSkillsExpectations
20
+ } = require('./test-cases-search');
21
+ const { notesRow, withKind } = require('./test-case-assertion-row');
22
+
23
+ const UNSAFE_FACT_SEGMENTS = new Set(['__proto__', 'prototype', 'constructor']);
24
+ const WILDCARD_FACT_SEGMENTS = new Set(['*', '**']);
25
+
26
+ function splitDottedPath(dottedPath) {
27
+ return String(dottedPath || '').split('.').filter((part) => part.length > 0);
28
+ }
29
+
30
+ function factPathSafetyMessage(parts) {
31
+ for (const part of parts) {
32
+ if (UNSAFE_FACT_SEGMENTS.has(part)) {
33
+ return `Fact path rejects prototype segment "${part}" before lookup.`;
34
+ }
35
+ if (WILDCARD_FACT_SEGMENTS.has(part)) {
36
+ return `Fact path rejects wildcard segment "${part}".`;
37
+ }
38
+ if (part === 'latest') {
39
+ return 'Fact path rejects latest-global record lookup.';
40
+ }
41
+ }
42
+ return null;
43
+ }
13
44
 
14
45
  function getValueAtPath(obj, dottedPath) {
15
- const parts = String(dottedPath || '').split('.').filter(Boolean);
46
+ const parts = splitDottedPath(dottedPath);
47
+ if (factPathSafetyMessage(parts)) {
48
+ return undefined;
49
+ }
16
50
  let cursor = obj;
17
51
  for (const key of parts) {
18
- if (!cursor || typeof cursor !== 'object' || !(key in cursor)) {
52
+ if (cursor === null || cursor === undefined || typeof cursor !== 'object') {
53
+ return undefined;
54
+ }
55
+ if (!Object.prototype.hasOwnProperty.call(cursor, key)) {
19
56
  return undefined;
20
57
  }
21
58
  cursor = cursor[key];
@@ -23,6 +60,10 @@ function getValueAtPath(obj, dottedPath) {
23
60
  return cursor;
24
61
  }
25
62
 
63
+ function stringifyObserved(value) {
64
+ return value === undefined ? 'missing' : JSON.stringify(value);
65
+ }
66
+
26
67
  function evaluateLifecycleStateExpectation(expectedState, observedState) {
27
68
  if (!expectedState) {
28
69
  return null;
@@ -38,7 +79,7 @@ function evaluateLifecycleStateExpectation(expectedState, observedState) {
38
79
  };
39
80
  }
40
81
 
41
- function evaluateCapabilityExpectations(requiredList, observedCapabilities) {
82
+ function evaluateCapabilityExpectations(kind, requiredList, observedCapabilities) {
42
83
  if (!Array.isArray(requiredList) || requiredList.length === 0) {
43
84
  return [];
44
85
  }
@@ -47,29 +88,39 @@ function evaluateCapabilityExpectations(requiredList, observedCapabilities) {
47
88
  const key = String(capability || '').trim();
48
89
  const passed = observedSet.has(key);
49
90
  return {
50
- id: `expected.capabilities.required:${key}`,
91
+ id: `expected.capabilities.${kind}:${key}`,
51
92
  passed,
52
93
  message: passed
53
- ? `Required capability "${key}" observed.`
54
- : `Required capability "${key}" was not observed.`
94
+ ? `${kind === 'allowed' ? 'Allowed' : 'Required'} capability "${key}" observed.`
95
+ : `${kind === 'allowed' ? 'Allowed' : 'Required'} capability "${key}" was not observed.`
55
96
  };
56
97
  });
57
98
  }
58
99
 
100
+ function evaluateOneFact(factPath, expectedValue, observation) {
101
+ const parts = splitDottedPath(factPath);
102
+ const safety = factPathSafetyMessage(parts);
103
+ const id = `expected.facts:${factPath}`;
104
+ if (safety) {
105
+ return { id, passed: false, message: safety };
106
+ }
107
+ const actualValue = getValueAtPath(observation, factPath);
108
+ const passed = JSON.stringify(actualValue) === JSON.stringify(expectedValue);
109
+ return {
110
+ id,
111
+ passed,
112
+ message: passed
113
+ ? `Fact "${factPath}" matched expected value.`
114
+ : `Fact "${factPath}" expected ${JSON.stringify(expectedValue)} but got ${stringifyObserved(actualValue)}.`
115
+ };
116
+ }
117
+
59
118
  function evaluateFactExpectations(expectedFacts, observation) {
60
119
  if (!expectedFacts || typeof expectedFacts !== 'object' || Array.isArray(expectedFacts)) {
61
120
  return [];
62
121
  }
63
122
  return Object.entries(expectedFacts).map(([factPath, expectedValue]) => {
64
- const actualValue = getValueAtPath(observation, factPath);
65
- const passed = JSON.stringify(actualValue) === JSON.stringify(expectedValue);
66
- return {
67
- id: `expected.facts:${factPath}`,
68
- passed,
69
- message: passed
70
- ? `Fact "${factPath}" matched expected value.`
71
- : `Fact "${factPath}" expected ${JSON.stringify(expectedValue)} but got ${JSON.stringify(actualValue)}.`
72
- };
123
+ return evaluateOneFact(factPath, expectedValue, observation);
73
124
  });
74
125
  }
75
126
 
@@ -78,6 +129,11 @@ function evaluateProhibitedExpectations(prohibited, observation) {
78
129
  return [];
79
130
  }
80
131
  return prohibited.map((factPath) => {
132
+ const parts = splitDottedPath(factPath);
133
+ const safety = factPathSafetyMessage(parts);
134
+ if (safety) {
135
+ return { id: `expected.prohibited:${factPath}`, passed: false, message: safety };
136
+ }
81
137
  const actualValue = getValueAtPath(observation, factPath);
82
138
  const passed = actualValue === undefined || actualValue === null || actualValue === false;
83
139
  return {
@@ -85,7 +141,7 @@ function evaluateProhibitedExpectations(prohibited, observation) {
85
141
  passed,
86
142
  message: passed
87
143
  ? `Prohibited marker "${factPath}" was not observed.`
88
- : `Prohibited marker "${factPath}" observed: ${JSON.stringify(actualValue)}.`
144
+ : `Prohibited marker "${factPath}" observed: ${stringifyObserved(actualValue)}.`
89
145
  };
90
146
  });
91
147
  }
@@ -111,6 +167,10 @@ function buildCaseObservation(result, lifecycleVerdict, portalUrl) {
111
167
  workResult,
112
168
  workResultError: result?.workResultError || null,
113
169
  honesty: buildHonestyObservation(workResult),
170
+ evidencePreflight: result?.evidencePreflight || null,
171
+ search: result?.search || null,
172
+ skills: result?.skills || null,
173
+ roleRef: result?.roleRef || null,
114
174
  interactions: Array.isArray(result?.interactions)
115
175
  ? result.interactions
116
176
  : Array.isArray(result?.workInteractions)
@@ -136,30 +196,103 @@ function softWrapLifecycleAssertion(lifecycleAssertion, soft) {
136
196
  };
137
197
  }
138
198
 
139
- function collectCaseAssertions(expected, observation) {
199
+ function softWrapFailedAssertion(assertion, soft) {
200
+ return softWrapLifecycleAssertion(assertion, soft);
201
+ }
202
+
203
+ function collectSoftModifierRows(expected) {
204
+ const rows = [];
205
+ if (Object.prototype.hasOwnProperty.call(expected, 'soft')) {
206
+ rows.push(
207
+ notesRow(
208
+ 'expected.soft',
209
+ expected.soft === true
210
+ ? 'soft: true — failures become warnings'
211
+ : 'soft: false — failures are blocking'
212
+ )
213
+ );
214
+ }
215
+ const notes = Array.isArray(expected.softNotes) ? expected.softNotes : [];
216
+ notes.forEach((item, index) => {
217
+ const text = typeof item === 'string'
218
+ ? item
219
+ : String((item && (item.description || item.note)) || JSON.stringify(item));
220
+ rows.push(notesRow(`expected.softNotes[${index}]`, text));
221
+ });
222
+ return rows;
223
+ }
224
+
225
+ function collectEvidenceContextRows(spec, prefix) {
226
+ if (!spec || typeof spec !== 'object' || Array.isArray(spec)) {
227
+ return [];
228
+ }
229
+ const rows = [];
230
+ if (spec.roleKey) {
231
+ rows.push(notesRow(`${prefix}.roleKey`, `Evidence roleKey "${spec.roleKey}" (preflight context).`));
232
+ }
233
+ if (spec.resourceType) {
234
+ rows.push(
235
+ notesRow(`${prefix}.resourceType`, `Evidence resourceType "${spec.resourceType}" (preflight context).`)
236
+ );
237
+ }
238
+ if (spec.requireStatus) {
239
+ rows.push(
240
+ notesRow(`${prefix}.requireStatus`, `Evidence requireStatus "${spec.requireStatus}" (preflight context).`)
241
+ );
242
+ }
243
+ return rows;
244
+ }
245
+
246
+ function collectCapabilityAssertions(capabilities, observedCapabilities, soft) {
247
+ const spec = capabilities && typeof capabilities === 'object' ? capabilities : {};
248
+ const rows = [
249
+ ...evaluateCapabilityExpectations('required', spec.required, observedCapabilities),
250
+ ...evaluateCapabilityExpectations('allowed', spec.allowed, observedCapabilities),
251
+ ...evaluateForbiddenCapabilities(spec.forbidden, observedCapabilities)
252
+ ];
253
+ return rows.map((row) => softWrapFailedAssertion(row, soft));
254
+ }
255
+
256
+ function collectCaseAssertions(expected, observation, preflight = {}) {
140
257
  const soft = expected.soft === true;
141
258
  const observedCapabilities = observation.capabilities?.observed || [];
142
259
  const assertions = [];
143
- const lifecycleAssertion = softWrapLifecycleAssertion(
260
+ const lifecycleAssertion = softWrapFailedAssertion(
144
261
  evaluateLifecycleStateExpectation(expected.lifecycleState, observation.lifecycleState),
145
262
  soft
146
263
  );
147
264
  if (lifecycleAssertion) {
148
265
  assertions.push(lifecycleAssertion);
149
266
  }
267
+ assertions.push(...collectSoftModifierRows(expected));
268
+ assertions.push(...collectCapabilityAssertions(expected.capabilities, observedCapabilities, soft));
150
269
  assertions.push(
151
- ...evaluateCapabilityExpectations(expected?.capabilities?.required, observedCapabilities)
270
+ ...evaluateFactExpectations(expected.facts, observation).map((row) =>
271
+ softWrapFailedAssertion(row, soft)
272
+ )
273
+ );
274
+ assertions.push(
275
+ ...evaluateProhibitedExpectations(expected.prohibited, observation).map((row) =>
276
+ softWrapFailedAssertion(row, soft)
277
+ )
152
278
  );
153
- assertions.push(...evaluateFactExpectations(expected.facts, observation));
154
- assertions.push(...evaluateProhibitedExpectations(expected.prohibited, observation));
155
279
  assertions.push(...evaluateHonestyExpectations(expected.honesty, observation, { soft }));
156
280
  assertions.push(...collectBidAssertions(expected.bid, observation, { soft }));
157
- return assertions;
281
+ assertions.push(...evaluateEvidenceExpectations(expected.evidence, observation));
282
+ assertions.push(...collectEvidenceContextRows(expected.evidence, 'expected.evidence'));
283
+ assertions.push(...collectEvidenceContextRows(preflight.evidence, 'preflight.evidence'));
284
+ assertions.push(...evaluateSearchExpectations(expected.search, observation));
285
+ assertions.push(...evaluateSkillsExpectations(expected.skills, observation));
286
+ return assertions.map(withKind);
158
287
  }
159
288
 
160
289
  function evaluateRoleAssistantTestCase(testCase, result, lifecycleVerdict, portalUrl) {
161
290
  const observation = buildCaseObservation(result, lifecycleVerdict, portalUrl);
162
- const assertions = collectCaseAssertions(testCase.expected || {}, observation);
291
+ const assertions = collectCaseAssertions(
292
+ testCase.expected || {},
293
+ observation,
294
+ testCase.preflight || {}
295
+ );
163
296
  const failed = assertions.filter((row) => !row.passed);
164
297
  return {
165
298
  caseId: testCase.caseId,
@@ -174,5 +307,7 @@ function evaluateRoleAssistantTestCase(testCase, result, lifecycleVerdict, porta
174
307
  }
175
308
 
176
309
  module.exports = {
177
- evaluateRoleAssistantTestCase
310
+ evaluateRoleAssistantTestCase,
311
+ evaluateFactExpectations,
312
+ getValueAtPath
178
313
  };