@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.
- package/README.md +8 -0
- package/bin/aifabrix.js +2 -2
- package/lib/agent-kit/apply-ops.js +82 -0
- package/lib/agent-kit/checksums.js +28 -0
- package/lib/agent-kit/classify.js +113 -0
- package/lib/agent-kit/claude-shim.js +61 -0
- package/lib/agent-kit/constants.js +55 -0
- package/lib/agent-kit/file-list.js +103 -0
- package/lib/agent-kit/host-approve.js +130 -0
- package/lib/agent-kit/hosting/github.js +63 -0
- package/lib/agent-kit/hosts.js +71 -0
- package/lib/agent-kit/init.js +319 -0
- package/lib/agent-kit/kit-root.js +17 -0
- package/lib/agent-kit/managed-section.js +79 -0
- package/lib/agent-kit/package-load.js +45 -0
- package/lib/agent-kit/plan-ops.js +69 -0
- package/lib/agent-kit/remote-prompts.js +239 -0
- package/lib/agent-kit/render-host-markdown.js +40 -0
- package/lib/agent-kit/repo-guard.js +47 -0
- package/lib/agent-kit/report.js +107 -0
- package/lib/agent-kit/run.js +82 -0
- package/lib/agent-kit/scm/git.js +122 -0
- package/lib/agent-kit/state-file.js +83 -0
- package/lib/agent-kit/status.js +50 -0
- package/lib/agent-kit/v1-detect.js +81 -0
- package/lib/agent-kit/validate-kit.js +87 -0
- package/lib/agent-kit/workspace-name.js +40 -0
- package/lib/agent-kit/workspace-skeleton.js +103 -0
- package/lib/api/assistants.api.js +8 -5
- package/lib/api/channel-identity.api.js +41 -0
- package/lib/api/evidence-authoring.api.js +5 -1
- package/lib/api/evidence.api.js +2 -0
- package/lib/api/role-assistant-test-pack.api.js +86 -0
- package/lib/api/types/evidence.types.js +2 -0
- package/lib/api/work-search.api.js +163 -0
- package/lib/api/work.api.js +19 -12
- package/lib/app/list-external-systems.js +2 -1
- package/lib/app/show-display.js +33 -6
- package/lib/app/show.js +25 -2
- package/lib/channels/add-channel.js +164 -126
- package/lib/channels/approval-guides/chatgpt.js +14 -18
- package/lib/channels/approval-guides/claude.js +29 -0
- package/lib/channels/approval-guides/index.js +88 -22
- package/lib/channels/approval-guides/mcp-client.js +27 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +52 -3
- package/lib/channels/approval-guides/slack.js +10 -10
- package/lib/channels/approval-guides/teams-bot.js +8 -12
- package/lib/channels/channel-add-continuations.js +91 -0
- package/lib/channels/channel-add-ensure.js +124 -27
- package/lib/channels/channel-add-existing.js +160 -28
- package/lib/channels/channel-add-failure.js +61 -0
- package/lib/channels/channel-add-remaining.js +492 -0
- package/lib/channels/channel-add-tty.js +190 -0
- package/lib/channels/channel-add-wizard-config.js +138 -0
- package/lib/channels/channel-add-wizard.js +250 -0
- package/lib/channels/channel-artifact-generator.js +27 -13
- package/lib/channels/channel-cardinality.js +83 -0
- package/lib/channels/channel-catalog-icon.js +45 -0
- package/lib/channels/channel-cli-instructions.js +75 -0
- package/lib/channels/channel-configuration-map.js +213 -0
- package/lib/channels/channel-credential.js +11 -14
- package/lib/channels/channel-definition-project.js +101 -0
- package/lib/channels/channel-definition-registry.js +154 -0
- package/lib/channels/channel-definition-status.js +115 -0
- package/lib/channels/channel-description.js +60 -2
- package/lib/channels/channel-discovery.js +16 -2
- package/lib/channels/channel-external-system.js +86 -9
- package/lib/channels/channel-install-envelope-actions.js +88 -0
- package/lib/channels/channel-install-envelope-microsoft.js +155 -0
- package/lib/channels/channel-install-envelope.js +358 -0
- package/lib/channels/channel-install-help-md.js +172 -0
- package/lib/channels/channel-install-http-payload.js +62 -0
- package/lib/channels/channel-install-inventory.js +115 -0
- package/lib/channels/channel-install-profiles.js +90 -0
- package/lib/channels/channel-instance-collision.js +118 -0
- package/lib/channels/channel-instance-key.js +100 -0
- package/lib/channels/channel-instance-materialize.js +240 -0
- package/lib/channels/channel-integration-generator.js +18 -9
- package/lib/channels/channel-integration-template.js +101 -22
- package/lib/channels/channel-inventory-fetch.js +79 -0
- package/lib/channels/channel-oauth-preflight.js +104 -0
- package/lib/channels/channel-package-version.js +76 -0
- package/lib/channels/channel-predefined-client.js +154 -0
- package/lib/channels/channel-probe.js +7 -2
- package/lib/channels/channel-runtime-resolver.js +194 -72
- package/lib/channels/channel-status-display.js +86 -16
- package/lib/channels/channel-targets.js +132 -92
- package/lib/channels/chatgpt-callback.js +318 -0
- package/lib/channels/chatgpt-channel-add.js +229 -0
- package/lib/channels/chatgpt-preflight.js +396 -0
- package/lib/channels/chatgpt-runtime-contract.js +17 -0
- package/lib/channels/chatgpt-setup-values.js +124 -0
- package/lib/channels/claude-callback.js +67 -0
- package/lib/channels/claude-channel-add.js +254 -0
- package/lib/channels/claude-runtime-contract.js +40 -0
- package/lib/channels/claude-runtime.js +58 -0
- package/lib/channels/claude-setup-values.js +92 -0
- package/lib/channels/mcp-client/config-merge.js +148 -0
- package/lib/channels/mcp-client/ensure-client.js +231 -0
- package/lib/channels/mcp-client/paths.js +53 -0
- package/lib/channels/mcp-client/profiles.js +122 -0
- package/lib/channels/mcp-client/redirect-uris.js +99 -0
- package/lib/channels/mcp-client/runtime.js +59 -0
- package/lib/channels/mcp-client-channel-add.js +186 -0
- package/lib/channels/microsoft-copilot-channel-add.js +117 -7
- package/lib/channels/microsoft-copilot-entra-identifier-uris.js +187 -0
- package/lib/channels/microsoft-copilot-entra-sso-form.js +106 -18
- package/lib/channels/microsoft-copilot-entra-sso.js +31 -2
- package/lib/channels/microsoft-copilot-package-prior.js +107 -0
- package/lib/channels/microsoft-copilot-package.js +29 -28
- package/lib/channels/microsoft-provisioning/a365.js +80 -0
- package/lib/channels/microsoft-provisioning/auth-config.js +240 -0
- package/lib/channels/microsoft-provisioning/auth.js +179 -0
- package/lib/channels/microsoft-provisioning/cli.js +71 -0
- package/lib/channels/microsoft-provisioning/constants.js +75 -0
- package/lib/channels/microsoft-provisioning/errors.js +117 -0
- package/lib/channels/microsoft-provisioning/index.js +55 -0
- package/lib/channels/microsoft-provisioning/install-atk.js +158 -0
- package/lib/channels/microsoft-provisioning/install-teams.js +115 -0
- package/lib/channels/microsoft-provisioning/login-portal-device.js +236 -0
- package/lib/channels/microsoft-provisioning/login-portal-parse.js +71 -0
- package/lib/channels/microsoft-provisioning/login-portal-teams.js +193 -0
- package/lib/channels/microsoft-provisioning/login-portal.js +230 -0
- package/lib/channels/microsoft-provisioning/persist.js +110 -0
- package/lib/channels/microsoft-provisioning/teams-bot-args.js +119 -0
- package/lib/channels/microsoft-provisioning/teams-bot-controller.js +123 -0
- package/lib/channels/microsoft-provisioning/teams-bot-parse.js +134 -0
- package/lib/channels/microsoft-provisioning/teams-bot-persist.js +113 -0
- package/lib/channels/microsoft-provisioning/teams-bot-provision.js +234 -0
- package/lib/channels/microsoft-provisioning/teams-bot-secrets.js +45 -0
- package/lib/channels/microsoft-provisioning/teams-cli.js +82 -0
- package/lib/channels/runtime-tool-catalog.js +5 -2
- package/lib/channels/slack-channel-add-portal.js +130 -0
- package/lib/channels/slack-channel-add-tty-auth.js +95 -0
- package/lib/channels/slack-channel-add.js +311 -0
- package/lib/channels/slack-mcp-callback.js +51 -0
- package/lib/channels/slack-mcp-runtime.js +156 -0
- package/lib/channels/slack-provisioning/apps.js +181 -0
- package/lib/channels/slack-provisioning/auth-store.js +110 -0
- package/lib/channels/slack-provisioning/auth-ticket.js +185 -0
- package/lib/channels/slack-provisioning/auth.js +115 -0
- package/lib/channels/slack-provisioning/callbacks.js +41 -0
- package/lib/channels/slack-provisioning/cli.js +226 -0
- package/lib/channels/slack-provisioning/constants.js +37 -0
- package/lib/channels/slack-provisioning/credentials.js +169 -0
- package/lib/channels/slack-provisioning/curl-shim.js +132 -0
- package/lib/channels/slack-provisioning/developer-install.js +118 -0
- package/lib/channels/slack-provisioning/env-file.js +120 -0
- package/lib/channels/slack-provisioning/errors.js +47 -0
- package/lib/channels/slack-provisioning/go-ca-bundle.js +137 -0
- package/lib/channels/slack-provisioning/index.js +250 -0
- package/lib/channels/slack-provisioning/install-cli.js +335 -0
- package/lib/channels/slack-provisioning/manifest.js +89 -0
- package/lib/channels/slack-provisioning/oauth-lock.js +33 -0
- package/lib/channels/slack-provisioning/offer-cli.js +113 -0
- package/lib/channels/slack-provisioning/onboard-members.js +122 -0
- package/lib/channels/slack-provisioning/onboard.js +89 -0
- package/lib/channels/slack-provisioning/persist.js +95 -0
- package/lib/channels/slack-provisioning/remaining-urls.js +158 -0
- package/lib/channels/slack-provisioning/with-curl-on-path.js +53 -0
- package/lib/channels/teams-bot-channel-add.js +94 -0
- package/lib/channels/vendor-dataplane-url.js +249 -0
- package/lib/cli/index.js +4 -0
- package/lib/cli/setup-certification-commands.js +2 -2
- package/lib/cli/setup-certification.help.js +5 -1
- package/lib/cli/setup-external-system-help.js +2 -0
- package/lib/cli/setup-external-system.js +1 -1
- package/lib/commands/agent-kit-help.js +79 -0
- package/lib/commands/agent-kit.js +346 -0
- package/lib/commands/channel-add-help.js +366 -0
- package/lib/commands/channel-add-setup.js +162 -80
- package/lib/commands/channel-configure.js +118 -0
- package/lib/commands/channel.js +10 -1
- package/lib/commands/datasource-capability-relate-cli.js +5 -4
- package/lib/commands/governance-upload-external.js +6 -3
- package/lib/commands/lifecycle-command-action.js +2 -5
- package/lib/commands/lifecycle-external.js +93 -21
- package/lib/commands/repair-auth-apply.js +1 -1
- package/lib/commands/repair-datasource-key-skip.js +39 -0
- package/lib/commands/repair-datasource-keys.js +24 -12
- package/lib/commands/repair-datasource-test-payload.js +4 -2
- package/lib/commands/repair-datasource-webhooks-sync-bridge.js +23 -2
- package/lib/commands/repair-datasource.js +3 -0
- package/lib/commands/repair-external-run.js +59 -25
- package/lib/commands/repair-openapi-rest-runtime.js +127 -0
- package/lib/commands/repair-orchestration-tag-merge.js +339 -0
- package/lib/commands/repair-rbac-catalog-defaults.js +96 -0
- package/lib/commands/repair-rbac-platform-preset.js +26 -15
- package/lib/commands/repair-rbac-reader-roles.js +8 -21
- package/lib/commands/repair-rbac.js +26 -44
- package/lib/commands/repair-system-permissions.js +24 -22
- package/lib/commands/role-assistant-copy-output.js +61 -0
- package/lib/commands/role-assistant-copy.js +155 -0
- package/lib/commands/role-assistant-test-output.js +22 -9
- package/lib/commands/role-assistant-test-result-rows.js +42 -0
- package/lib/commands/role-assistant.js +150 -43
- package/lib/commands/search.js +143 -0
- package/lib/commands/test-e2e-external.js +148 -21
- package/lib/commands/test-trust-external.js +7 -5
- package/lib/commands/upload-credential-push-log.js +2 -1
- package/lib/commands/upload-publish-context.js +1 -1
- package/lib/commands/upload-role-assistant-shell.js +124 -0
- package/lib/commands/upload-sidecar-followups.js +10 -4
- package/lib/commands/upload.js +18 -3
- package/lib/commands/verify-operations-skip-e2e.js +131 -0
- package/lib/commands/verify-operations-step-plan.js +6 -33
- package/lib/commands/verify-operations-steps.js +3 -1
- package/lib/core/secrets-docker-env.js +4 -1
- package/lib/core/secrets-env-content.js +17 -3
- package/lib/datasource/capability/capability-manifest.js +0 -3
- package/lib/datasource/capability/copy-test-payload.js +3 -0
- package/lib/datasource/capability/relate-operations.js +28 -10
- package/lib/datasource/capability/run-capability-relate.js +48 -25
- package/lib/datasource/datasource-identifier.js +13 -5
- package/lib/deployment/deployer-poll-run.js +117 -35
- package/lib/external-system/deploy-dataplane-published.js +70 -0
- package/lib/external-system/deploy-helpers.js +26 -1
- package/lib/external-system/deploy.js +22 -8
- package/lib/external-system/download-helpers.js +29 -2
- package/lib/external-system/download-role-assistant.js +109 -4
- package/lib/external-system/download.js +46 -30
- package/lib/external-system/sync-deploy-manifest.js +3 -2
- package/lib/external-system/upload-identity.js +42 -0
- package/lib/generator/index.js +19 -15
- package/lib/generator/split.js +13 -2
- package/lib/generator/wizard-datasource-key.js +54 -0
- package/lib/generator/wizard.js +55 -54
- package/lib/integration-definition/apply-datasource-keys.js +75 -0
- package/lib/integration-definition/apply-relationships.js +195 -0
- package/lib/integration-definition/apply-static-enterprise.js +229 -0
- package/lib/integration-definition/apply-system-file.js +71 -0
- package/lib/integration-definition/apply-test-endpoint.js +89 -0
- package/lib/integration-definition/apply-viewpoint-defaults.js +157 -0
- package/lib/integration-definition/apply.js +78 -59
- package/lib/integration-definition/enrich-openapi-operations.js +36 -10
- package/lib/integration-definition/enrich-openapi-pick.js +87 -0
- package/lib/lifecycle/role-assistant-governance.js +181 -0
- package/lib/lifecycle/scenario-upload.js +181 -30
- package/lib/programmatic/builder-api-cors.js +143 -0
- package/lib/programmatic/builder-api-request.js +6 -0
- package/lib/programmatic/builder-api-route-dispatch.js +56 -42
- package/lib/programmatic/builder-api-server.js +8 -1
- package/lib/programmatic/capability-registry.js +55 -0
- package/lib/programmatic/channel-install-help-resolve.js +359 -0
- package/lib/programmatic/channel-install-session.js +218 -0
- package/lib/programmatic/help-content/channel-onboarding.md +2 -0
- package/lib/programmatic/help-content/cip-overview.md +3 -1
- package/lib/programmatic/http-raw-response.js +62 -0
- package/lib/programmatic/index.js +2 -0
- package/lib/programmatic/openapi-apply-result-schemas.js +8 -0
- package/lib/programmatic/openapi-channel-install-bindings.js +179 -0
- package/lib/programmatic/openapi-channel-install-schemas.js +289 -0
- package/lib/programmatic/openapi-component-schemas.js +19 -1
- package/lib/programmatic/openapi-description-enricher.js +3 -1
- package/lib/programmatic/openapi-descriptions.js +80 -3
- package/lib/programmatic/openapi-envelope-examples.js +124 -0
- package/lib/programmatic/openapi-operation-bindings.js +9 -1
- package/lib/programmatic/openapi-request-schemas.js +5 -0
- package/lib/programmatic/openapi-schema-descriptions-channel.js +319 -0
- package/lib/programmatic/openapi-schema-descriptions-operations.js +19 -0
- package/lib/programmatic/openapi-spec.js +13 -8
- package/lib/programmatic/platform-rbac-catalog.js +36 -18
- package/lib/programmatic/request-timeout.js +3 -0
- package/lib/programmatic/route-handler-map.js +58 -1
- package/lib/programmatic/route-handlers-context.js +2 -1
- package/lib/programmatic/run-auth-permissions.js +54 -0
- package/lib/programmatic/run-channel-catalog.js +238 -0
- package/lib/programmatic/run-channel-install-artifacts.js +137 -0
- package/lib/programmatic/run-channel-install-copilot.js +353 -0
- package/lib/programmatic/run-channel-install-options.js +236 -0
- package/lib/programmatic/run-channel-install-teams-bot.js +204 -0
- package/lib/programmatic/run-channel-install.js +346 -0
- package/lib/programmatic/run-channel-package.js +87 -7
- package/lib/programmatic/run-download.js +41 -0
- package/lib/programmatic/workspace-context.js +2 -0
- package/lib/protection/auth-context.js +3 -1
- package/lib/protection/protection-display.js +3 -2
- package/lib/protection/report-exit.js +50 -0
- package/lib/protection/run-commands.js +2 -0
- package/lib/role-assistant/evidence-sync.js +4 -2
- package/lib/role-assistant/evidence-validation-issues.js +51 -0
- package/lib/role-assistant/knowledge-sync.js +10 -4
- package/lib/role-assistant/package-validate.js +175 -0
- package/lib/role-assistant/settings.js +49 -2
- package/lib/role-assistant/test-case-assertion-row.js +36 -0
- package/lib/role-assistant/test-case-copy-bind.js +77 -0
- package/lib/role-assistant/test-case-copy-expected.js +127 -0
- package/lib/role-assistant/test-case-copy-from-work.js +90 -0
- package/lib/role-assistant/test-case-copy-interactions.js +67 -0
- package/lib/role-assistant/test-case-copy.js +119 -0
- package/lib/role-assistant/test-case-expected-catalog.js +135 -0
- package/lib/role-assistant/test-case-validate.js +88 -0
- package/lib/role-assistant/test-cases-bid.js +117 -4
- package/lib/role-assistant/test-cases-evaluate.js +159 -24
- package/lib/role-assistant/test-cases-evidence.js +175 -0
- package/lib/role-assistant/test-cases-honesty.js +155 -6
- package/lib/role-assistant/test-cases-lifecycle.js +291 -0
- package/lib/role-assistant/test-cases-search-graph.js +122 -0
- package/lib/role-assistant/test-cases-search.js +247 -0
- package/lib/role-assistant/test-cases.js +71 -172
- package/lib/role-assistant/test-pack-map.js +180 -0
- package/lib/role-assistant/test-pack-sync.js +187 -0
- package/lib/role-assistant/test-runner-debug.js +54 -0
- package/lib/role-assistant/test-runner-respond-body.js +36 -0
- package/lib/role-assistant/test-runner-search.js +164 -0
- package/lib/role-assistant/test-runner-start-payload.js +63 -10
- package/lib/role-assistant/test-runner-workhub-answers.js +45 -16
- package/lib/role-assistant/test-runner-workhub-helpers.js +40 -2
- package/lib/role-assistant/test-runner-workhub-soft.js +9 -3
- package/lib/role-assistant/test-runner-workhub.js +74 -32
- package/lib/role-assistant/test-runner.js +66 -11
- package/lib/schema/external-datasource.schema.json +146 -21
- package/lib/schema/external-system.schema.json +177 -2
- package/lib/schema/mcp-client-profile.schema.json +103 -0
- package/lib/schema/role-assistant-test-case.schema.json +408 -0
- package/lib/search/dataplane-context.js +23 -0
- package/lib/search/search-args.js +211 -0
- package/lib/search/search-display.js +238 -0
- package/lib/search/search-errors.js +50 -0
- package/lib/search/search-prompts.js +119 -0
- package/lib/search/search-roles.js +85 -0
- package/lib/search/search-run.js +241 -0
- package/lib/search/search-skills.js +198 -0
- package/lib/utils/app-path-resolve.js +4 -0
- package/lib/utils/authentication-env-template.js +44 -6
- package/lib/utils/authentication-slot-show.js +153 -0
- package/lib/utils/credential-display.js +43 -1
- package/lib/utils/credential-secrets-env.js +6 -1
- package/lib/utils/env-copy.js +19 -7
- package/lib/utils/external-env-template.js +20 -2
- package/lib/utils/external-system-readiness-compact-blocks.js +5 -1
- package/lib/utils/external-system-readiness-compact-display.js +30 -1
- package/lib/utils/external-system-validators.js +2 -1
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/paths.js +18 -1
- package/lib/utils/platform-shell-package.js +69 -0
- package/lib/utils/port-resolver.js +50 -1
- package/lib/utils/rewrite-name-flag.js +20 -0
- package/lib/utils/role-assistant-paths.js +13 -10
- package/lib/utils/schema-loader.js +37 -0
- package/lib/utils/schema-resolver.js +11 -1
- package/lib/utils/secrets-helpers.js +12 -21
- package/lib/utils/token-manager.js +10 -5
- package/lib/validation/validate-external-file.js +5 -1
- package/lib/validation/validate.js +41 -0
- package/package.json +1 -1
- package/templates/README.md +1 -1
- package/templates/agent-kit/adapters/claude/nested.CLAUDE.md +1 -0
- package/templates/agent-kit/adapters/claude/root.CLAUDE.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-0-plan.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-3-push.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-1-validate.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-2-build.md +5 -0
- package/templates/agent-kit/adapters/cursor/commands/cust-biz-3-prove.md +5 -0
- package/templates/agent-kit/agent-kit.yaml +45 -0
- package/templates/agent-kit/instructions/AGENTKIT.md +83 -0
- package/templates/agent-kit/instructions/integration.AGENTS.md +25 -0
- package/templates/agent-kit/instructions/role-assistant.AGENTS.md +22 -0
- package/templates/agent-kit/instructions/root.AGENTS.md +37 -0
- package/templates/agent-kit/parity-inventory.yaml +188 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/SKILL.md +58 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/contract-checklist.md +40 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/delivery-gates.md +54 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/references/production-safety.md +35 -0
- package/templates/agent-kit/skills/aifabrix-connected-system/scripts/reserved-system-key.js +19 -0
- package/templates/agent-kit/skills/aifabrix-plan/SKILL.md +51 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/challenge-checklist.md +108 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/interaction.md +34 -0
- package/templates/agent-kit/skills/aifabrix-plan/references/plan-template.md +182 -0
- package/templates/agent-kit/skills/aifabrix-prove/SKILL.md +50 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/demo-template.md +65 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/evidence-lifecycle.md +68 -0
- package/templates/agent-kit/skills/aifabrix-prove/references/learning-template.md +66 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/SKILL.md +42 -0
- package/templates/agent-kit/skills/aifabrix-role-assistant/references/package-boundary.md +21 -0
- package/templates/agent-kit/skills/shared/hosts.md +78 -0
- package/templates/agent-kit/workspace/.cursor/plans/README.md +22 -0
- package/templates/agent-kit/workspace/LICENSE.mit +21 -0
- package/templates/agent-kit/workspace/README.md +89 -0
- package/templates/applications/builder-api/Dockerfile +3 -1
- package/templates/applications/builder-api/env.template +7 -0
- package/templates/applications/dataplane/application.yaml +6 -5
- package/templates/applications/dataplane/env.template +2 -2
- package/templates/applications/dataplane/rbac.yaml +35 -2
- package/templates/applications/keycloak/Dockerfile +30 -4
- package/templates/applications/keycloak/application.yaml +2 -2
- package/templates/applications/keycloak/cimd-lenient-parse/AbstractClientIdMetadataDocumentExecutor.java +896 -0
- package/templates/applications/keycloak/cimd-lenient-parse/SOURCE.md +19 -0
- package/templates/applications/keycloak/env.template +3 -0
- package/templates/applications/miso-controller/application.yaml +1 -2
- package/templates/applications/miso-controller/env.template +10 -9
- package/templates/channels/README.md +5 -5
- package/templates/channels/chatgpt/TROUBLESHOOTING.md +51 -0
- package/templates/channels/chatgpt/channel.json +59 -0
- package/templates/channels/chatgpt/icon.svg +1 -0
- package/templates/channels/chatgpt/install.template.md.hbs +20 -95
- package/templates/channels/chatgpt/integration/README.md +1 -1
- package/templates/channels/chatgpt/integration/application.json +2 -2
- package/templates/channels/chatgpt/integration/chatgpt-system.json +49 -4
- package/templates/channels/chatgpt/integration/env.template +2 -4
- package/templates/channels/chatgpt/integration/rbac.json +13 -0
- package/templates/channels/claude/TROUBLESHOOTING.md +44 -0
- package/templates/channels/claude/channel.json +59 -0
- package/templates/channels/claude/icon.svg +1 -0
- package/templates/channels/claude/install.template.md.hbs +22 -0
- package/templates/channels/claude/integration/README.md +14 -0
- package/templates/channels/claude/integration/application.json +15 -0
- package/templates/channels/claude/integration/claude-system.json +59 -0
- package/templates/channels/claude/integration/env.template +2 -0
- package/templates/channels/claude/integration/rbac.json +13 -0
- package/templates/channels/claude/manifest.template.json.hbs +40 -0
- package/templates/channels/mcp-client/channel.json +72 -0
- package/templates/channels/mcp-client/icon.svg +1 -0
- package/templates/channels/mcp-client/install.template.md.hbs +24 -0
- package/templates/channels/mcp-client/integration/README.md +13 -0
- package/templates/channels/mcp-client/integration/application.json +15 -0
- package/templates/channels/mcp-client/integration/env.template +2 -0
- package/templates/channels/mcp-client/integration/mcp-client-system.json +72 -0
- package/templates/channels/mcp-client/integration/rbac.json +13 -0
- package/templates/channels/mcp-client/manifest.template.json.hbs +41 -0
- package/templates/channels/mcp-client/profiles/cursor.json +26 -0
- package/templates/channels/mcp-client/profiles/github-copilot.json +29 -0
- package/templates/channels/mcp-client/profiles/vscode.json +29 -0
- package/templates/channels/microsoft-copilot/channel.json +73 -0
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +8 -4
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +65 -5
- package/templates/channels/microsoft-copilot/icon.svg +1 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +9 -9
- package/templates/channels/microsoft-copilot/integration/README.md +1 -1
- package/templates/channels/microsoft-copilot/integration/application.json +2 -2
- package/templates/channels/microsoft-copilot/integration/env.template +3 -6
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +63 -4
- package/templates/channels/microsoft-copilot/integration/rbac.json +13 -0
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +5 -5
- package/templates/channels/slack/channel.json +234 -0
- package/templates/channels/slack/icon.svg +1 -0
- package/templates/channels/slack/install.template.md.hbs +45 -28
- package/templates/channels/slack/integration/README.md +245 -22
- package/templates/channels/slack/integration/application.json +44 -7
- package/templates/channels/slack/integration/env.template +15 -6
- package/templates/channels/slack/integration/openapi/openapi.json +126 -0
- package/templates/channels/slack/integration/rbac.json +84 -0
- package/templates/channels/slack/integration/slack-datasource-commands.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-conversations.json +28 -3
- package/templates/channels/slack/integration/slack-datasource-events.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-interactive.json +154 -0
- package/templates/channels/slack/integration/slack-datasource-messages.json +40 -2
- package/templates/channels/slack/integration/slack-system.json +161 -72
- package/templates/channels/slack/manifest.template.json.hbs +10 -4
- package/templates/channels/teams-bot/channel.json +162 -0
- package/templates/channels/teams-bot/icon.svg +1 -0
- package/templates/channels/teams-bot/install.template.md.hbs +12 -13
- package/templates/channels/teams-bot/integration/README.md +5 -4
- package/templates/channels/teams-bot/integration/application.json +6 -4
- package/templates/channels/teams-bot/integration/env.template +5 -4
- package/templates/channels/teams-bot/integration/openapi/openapi.json +68 -0
- package/templates/channels/teams-bot/integration/rbac.json +21 -0
- package/templates/channels/teams-bot/integration/teams-bot-datasource-activities.json +154 -0
- package/templates/channels/teams-bot/integration/teams-bot-system.json +128 -23
- package/templates/channels/web-embed/channel.json +60 -0
- package/templates/channels/web-embed/install.template.md.hbs +1 -1
- package/templates/channels/web-embed/integration/README.md +2 -2
- package/templates/channels/web-embed/integration/application.json +2 -2
- package/templates/channels/web-embed/integration/env.template +1 -1
- package/templates/channels/web-embed/integration/rbac.json +13 -0
- package/templates/channels/web-embed/integration/web-embed-system.json +50 -4
- package/templates/python/docker-compose.hbs +14 -0
- package/templates/typescript/docker-compose.hbs +14 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Role Assistant case Evidence preflight — live dataplane rows only.
|
|
3
|
+
* @fileoverview Hard-stop when required Evidence keys are missing or not active
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const { listEvidence } = require('../api/evidence.api');
|
|
9
|
+
const { bareRoleKey } = require('../utils/role-assistant-paths');
|
|
10
|
+
|
|
11
|
+
function asStringList(value) {
|
|
12
|
+
if (!Array.isArray(value)) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
return value.map((item) => String(item || '').trim()).filter(Boolean);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function evidenceSpecFromCase(testCase) {
|
|
19
|
+
const preflight = testCase?.preflight?.evidence;
|
|
20
|
+
const expected = testCase?.expected?.evidence;
|
|
21
|
+
const requiredKeys = asStringList(preflight?.requiredKeys).concat(
|
|
22
|
+
asStringList(expected?.requiredKeys)
|
|
23
|
+
);
|
|
24
|
+
const unique = [...new Set(requiredKeys)];
|
|
25
|
+
if (unique.length === 0) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
const roleKey =
|
|
29
|
+
String(preflight?.roleKey || expected?.roleKey || '').trim() ||
|
|
30
|
+
bareRoleKey(testCase?.input?.businessRoleRef || '') ||
|
|
31
|
+
'';
|
|
32
|
+
const resourceType = String(preflight?.resourceType || expected?.resourceType || '').trim();
|
|
33
|
+
return {
|
|
34
|
+
requiredKeys: unique,
|
|
35
|
+
roleKey,
|
|
36
|
+
resourceType,
|
|
37
|
+
requireStatus: String(preflight?.requireStatus || expected?.requireStatus || 'active')
|
|
38
|
+
.trim()
|
|
39
|
+
.toLowerCase() || 'active'
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function rowKey(row) {
|
|
44
|
+
return String(row?.key || row?.evidenceKey || '').trim();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function rowStatus(row) {
|
|
48
|
+
return String(row?.status || '').trim().toLowerCase();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function isActiveStatus(status, requiredStatus) {
|
|
52
|
+
if (requiredStatus === 'active') {
|
|
53
|
+
return !status || status === 'active';
|
|
54
|
+
}
|
|
55
|
+
return status === requiredStatus;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function findMissingEvidenceKeys(spec, rows) {
|
|
59
|
+
const byKey = new Map();
|
|
60
|
+
for (const row of rows) {
|
|
61
|
+
const key = rowKey(row);
|
|
62
|
+
if (key) {
|
|
63
|
+
byKey.set(key, row);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const missing = [];
|
|
67
|
+
for (const key of spec.requiredKeys) {
|
|
68
|
+
const row = byKey.get(key);
|
|
69
|
+
if (!row) {
|
|
70
|
+
missing.push(`${key} (not in dataplane)`);
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
const status = rowStatus(row);
|
|
74
|
+
if (!isActiveStatus(status, spec.requireStatus)) {
|
|
75
|
+
missing.push(`${key} (status=${status || 'unknown'}, need ${spec.requireStatus})`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return missing;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async function loadLiveEvidenceRows(authContext, spec) {
|
|
82
|
+
const dataplaneUrl = authContext?.dataplaneUrl;
|
|
83
|
+
const authConfig = authContext?.authConfig;
|
|
84
|
+
if (!dataplaneUrl || !authConfig) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
'Evidence preflight failed: dataplane URL or auth is missing. Run aifabrix login and retry.'
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
const params = {
|
|
90
|
+
roleKey: spec.roleKey || undefined,
|
|
91
|
+
resourceType: spec.resourceType || undefined,
|
|
92
|
+
status: spec.requireStatus === 'active' ? 'active' : spec.requireStatus,
|
|
93
|
+
page: 1,
|
|
94
|
+
pageSize: 100
|
|
95
|
+
};
|
|
96
|
+
try {
|
|
97
|
+
return await listEvidence(dataplaneUrl, authConfig, params);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
const detail = error && error.message ? error.message : String(error);
|
|
100
|
+
throw new Error(`Evidence preflight failed: could not read Evidence from the dataplane (${detail}).`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Hard-stop before work.start when the case requires live Evidence.
|
|
106
|
+
* @returns {Promise<{ skipped: boolean, requiredKeys: string[], rows: Object[] }>}
|
|
107
|
+
*/
|
|
108
|
+
async function assertRoleAssistantEvidencePreflight(testCase, authContext) {
|
|
109
|
+
const spec = evidenceSpecFromCase(testCase);
|
|
110
|
+
if (!spec) {
|
|
111
|
+
return { skipped: true, requiredKeys: [], rows: [] };
|
|
112
|
+
}
|
|
113
|
+
if (!spec.roleKey) {
|
|
114
|
+
throw new Error(
|
|
115
|
+
'Evidence preflight failed: roleKey is required (preflight.evidence.roleKey or input.businessRoleRef).'
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
const rows = await loadLiveEvidenceRows(authContext, spec);
|
|
119
|
+
const missing = findMissingEvidenceKeys(spec, rows);
|
|
120
|
+
if (missing.length > 0) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
'Evidence preflight failed: required Evidence is not active in the dataplane: ' +
|
|
123
|
+
`${missing.join('; ')}. Upload the Role Assistant package to the target dataplane, ` +
|
|
124
|
+
'then retry. Hard stop.'
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
return { skipped: false, requiredKeys: spec.requiredKeys, rows };
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function evaluateEvidenceExpectations(evidenceSpec, observation) {
|
|
131
|
+
const requiredKeys = asStringList(evidenceSpec?.requiredKeys);
|
|
132
|
+
if (requiredKeys.length === 0) {
|
|
133
|
+
return [];
|
|
134
|
+
}
|
|
135
|
+
const preflight = observation?.evidencePreflight || {};
|
|
136
|
+
const liveKeys = new Set(
|
|
137
|
+
(Array.isArray(preflight.rows) ? preflight.rows : []).map(rowKey).filter(Boolean)
|
|
138
|
+
);
|
|
139
|
+
return requiredKeys.map((key) => {
|
|
140
|
+
const passed = liveKeys.has(key);
|
|
141
|
+
return {
|
|
142
|
+
id: `expected.evidence.requiredKeys:${key}`,
|
|
143
|
+
passed,
|
|
144
|
+
message: passed
|
|
145
|
+
? `Evidence key "${key}" was active in the dataplane at test start.`
|
|
146
|
+
: `Evidence key "${key}" was not active in the dataplane at test start.`
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function evaluateForbiddenCapabilities(forbiddenList, observedCapabilities) {
|
|
152
|
+
if (!Array.isArray(forbiddenList) || forbiddenList.length === 0) {
|
|
153
|
+
return [];
|
|
154
|
+
}
|
|
155
|
+
const observedSet = new Set(observedCapabilities);
|
|
156
|
+
return forbiddenList.map((capability) => {
|
|
157
|
+
const key = String(capability || '').trim();
|
|
158
|
+
const passed = !observedSet.has(key);
|
|
159
|
+
return {
|
|
160
|
+
id: `expected.capabilities.forbidden:${key}`,
|
|
161
|
+
passed,
|
|
162
|
+
message: passed
|
|
163
|
+
? `Forbidden capability "${key}" was not observed.`
|
|
164
|
+
: `Forbidden capability "${key}" was observed.`
|
|
165
|
+
};
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = {
|
|
170
|
+
evidenceSpecFromCase,
|
|
171
|
+
findMissingEvidenceKeys,
|
|
172
|
+
assertRoleAssistantEvidencePreflight,
|
|
173
|
+
evaluateEvidenceExpectations,
|
|
174
|
+
evaluateForbiddenCapabilities
|
|
175
|
+
};
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
'use strict';
|
|
6
6
|
|
|
7
|
+
const { skipRow, notesRow } = require('./test-case-assertion-row');
|
|
8
|
+
|
|
7
9
|
const HONESTY_COMPLETION_STATES = new Set([
|
|
8
10
|
'notEvaluated',
|
|
9
11
|
'waiting',
|
|
@@ -26,6 +28,14 @@ const HONESTY_CONTRIB_STATUSES = new Set([
|
|
|
26
28
|
'notRealized',
|
|
27
29
|
'partial'
|
|
28
30
|
]);
|
|
31
|
+
const OBJECTIVE_TEXT_KEYS = new Set([
|
|
32
|
+
'objective',
|
|
33
|
+
'goal',
|
|
34
|
+
'planObjective',
|
|
35
|
+
'objectiveSummary',
|
|
36
|
+
'acceptedObjective'
|
|
37
|
+
]);
|
|
38
|
+
const FORBIDDEN_BUILDER_TOKEN = /\b(?:knownPlatform|gold-package|[a-z][a-z0-9-]*\.[a-z][a-zA-Z0-9]+)\b/i;
|
|
29
39
|
|
|
30
40
|
function emptyHonestyObservation() {
|
|
31
41
|
return {
|
|
@@ -83,7 +93,59 @@ function pushHonestyAssertion(assertions, id, passed, message, options = {}) {
|
|
|
83
93
|
assertions.push({ id, passed, message });
|
|
84
94
|
}
|
|
85
95
|
|
|
86
|
-
function
|
|
96
|
+
function collectObjectiveStrings(value, acc) {
|
|
97
|
+
if (Array.isArray(value)) {
|
|
98
|
+
value.forEach((item) => collectObjectiveStrings(item, acc));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
if (!value || typeof value !== 'object') {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
for (const [key, child] of Object.entries(value)) {
|
|
105
|
+
if (OBJECTIVE_TEXT_KEYS.has(key) && typeof child === 'string') {
|
|
106
|
+
acc.push(child);
|
|
107
|
+
} else if (child && typeof child === 'object') {
|
|
108
|
+
collectObjectiveStrings(child, acc);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function interactionObjectiveText(row) {
|
|
114
|
+
if (!row || typeof row !== 'object') {
|
|
115
|
+
return '';
|
|
116
|
+
}
|
|
117
|
+
const role = String(row.role || row.type || '').toLowerCase();
|
|
118
|
+
if (role === 'user' || role === 'human') {
|
|
119
|
+
return '';
|
|
120
|
+
}
|
|
121
|
+
return [row.message, row.content, row.text, row.objective]
|
|
122
|
+
.filter((item) => typeof item === 'string')
|
|
123
|
+
.join('\n');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function governedObjectiveHaystack(observation) {
|
|
127
|
+
const parts = [];
|
|
128
|
+
collectObjectiveStrings(observation.workResult || {}, parts);
|
|
129
|
+
collectObjectiveStrings(observation.emittedBid || {}, parts);
|
|
130
|
+
for (const row of Array.isArray(observation.interactions) ? observation.interactions : []) {
|
|
131
|
+
const text = interactionObjectiveText(row);
|
|
132
|
+
if (text) {
|
|
133
|
+
parts.push(text);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return parts.join('\n');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
function assertWorkResultPresent(assertions, honestySpec, honesty, observation, soft) {
|
|
140
|
+
if (honestySpec.requireWorkResult === false) {
|
|
141
|
+
assertions.push(
|
|
142
|
+
skipRow(
|
|
143
|
+
'expected.honesty.requireWorkResult',
|
|
144
|
+
'requireWorkResult is false — work.result is not required.'
|
|
145
|
+
)
|
|
146
|
+
);
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
87
149
|
const present = honesty.present === true;
|
|
88
150
|
const missingSuffix = observation.workResultError
|
|
89
151
|
? `: ${observation.workResultError}`
|
|
@@ -94,7 +156,8 @@ function assertWorkResultPresent(assertions, honesty, observation) {
|
|
|
94
156
|
present,
|
|
95
157
|
present
|
|
96
158
|
? 'work.result Output was present.'
|
|
97
|
-
: `work.result Output missing${missingSuffix}
|
|
159
|
+
: `work.result Output missing${missingSuffix}`,
|
|
160
|
+
{ soft }
|
|
98
161
|
);
|
|
99
162
|
}
|
|
100
163
|
|
|
@@ -102,6 +165,15 @@ function assertSchemaVersion(assertions, honestySpec, honesty, soft) {
|
|
|
102
165
|
if (!honestySpec.schemaVersion) {
|
|
103
166
|
return;
|
|
104
167
|
}
|
|
168
|
+
if (!honesty.present) {
|
|
169
|
+
assertions.push(
|
|
170
|
+
skipRow(
|
|
171
|
+
'expected.honesty.schemaVersion',
|
|
172
|
+
'schemaVersion skipped because work.result is absent.'
|
|
173
|
+
)
|
|
174
|
+
);
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
105
177
|
const expected = String(honestySpec.schemaVersion);
|
|
106
178
|
const passed = String(honesty.schemaVersion || '') === expected;
|
|
107
179
|
pushHonestyAssertion(
|
|
@@ -117,6 +189,12 @@ function assertSchemaVersion(assertions, honestySpec, honesty, soft) {
|
|
|
117
189
|
|
|
118
190
|
function assertCompletion(assertions, honestySpec, honesty, soft) {
|
|
119
191
|
if (honestySpec.requireCompletion === false) {
|
|
192
|
+
assertions.push(
|
|
193
|
+
skipRow(
|
|
194
|
+
'expected.honesty.requireCompletion',
|
|
195
|
+
'requireCompletion is false — completion check skipped.'
|
|
196
|
+
)
|
|
197
|
+
);
|
|
120
198
|
return;
|
|
121
199
|
}
|
|
122
200
|
const stateOk = HONESTY_COMPLETION_STATES.has(String(honesty.completionState || ''));
|
|
@@ -134,6 +212,12 @@ function assertCompletion(assertions, honestySpec, honesty, soft) {
|
|
|
134
212
|
|
|
135
213
|
function assertContribution(assertions, honestySpec, honesty, soft) {
|
|
136
214
|
if (honestySpec.requireContributionObservation === false) {
|
|
215
|
+
assertions.push(
|
|
216
|
+
skipRow(
|
|
217
|
+
'expected.honesty.requireContributionObservation',
|
|
218
|
+
'requireContributionObservation is false — contribution check skipped.'
|
|
219
|
+
)
|
|
220
|
+
);
|
|
137
221
|
return;
|
|
138
222
|
}
|
|
139
223
|
const ok = HONESTY_CONTRIB_STATUSES.has(String(honesty.contributionStatus || ''));
|
|
@@ -149,9 +233,28 @@ function assertContribution(assertions, honestySpec, honesty, soft) {
|
|
|
149
233
|
}
|
|
150
234
|
|
|
151
235
|
function assertMinResourceChanges(assertions, honestySpec, honesty, soft) {
|
|
236
|
+
if (typeof honestySpec.softResourceChanges === 'boolean') {
|
|
237
|
+
assertions.push(
|
|
238
|
+
notesRow(
|
|
239
|
+
'expected.honesty.softResourceChanges',
|
|
240
|
+
honestySpec.softResourceChanges
|
|
241
|
+
? 'softResourceChanges: true — minResourceChanges misses are warnings.'
|
|
242
|
+
: 'softResourceChanges: false — minResourceChanges misses are blocking.'
|
|
243
|
+
)
|
|
244
|
+
);
|
|
245
|
+
}
|
|
152
246
|
if (typeof honestySpec.minResourceChanges !== 'number') {
|
|
153
247
|
return;
|
|
154
248
|
}
|
|
249
|
+
if (!honesty.present) {
|
|
250
|
+
assertions.push(
|
|
251
|
+
skipRow(
|
|
252
|
+
'expected.honesty.minResourceChanges',
|
|
253
|
+
'minResourceChanges skipped because work.result is absent.'
|
|
254
|
+
)
|
|
255
|
+
);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
155
258
|
const count = Number(honesty.resourceChangeCount || 0);
|
|
156
259
|
const passed = count >= honestySpec.minResourceChanges;
|
|
157
260
|
const softChange = soft || honestySpec.softResourceChanges === true;
|
|
@@ -171,6 +274,53 @@ function assertMinResourceChanges(assertions, honestySpec, honesty, soft) {
|
|
|
171
274
|
}
|
|
172
275
|
}
|
|
173
276
|
|
|
277
|
+
function assertForbidBuilderKeys(assertions, honestySpec, observation, soft) {
|
|
278
|
+
if (honestySpec.forbidBuilderKeysInObjective === false) {
|
|
279
|
+
assertions.push(
|
|
280
|
+
skipRow(
|
|
281
|
+
'expected.honesty.forbidBuilderKeysInObjective',
|
|
282
|
+
'forbidBuilderKeysInObjective is false — Builder-key check skipped.'
|
|
283
|
+
)
|
|
284
|
+
);
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
if (honestySpec.forbidBuilderKeysInObjective !== true) {
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
const haystack = governedObjectiveHaystack(observation);
|
|
291
|
+
const match = haystack.match(FORBIDDEN_BUILDER_TOKEN);
|
|
292
|
+
const passed = !match;
|
|
293
|
+
pushHonestyAssertion(
|
|
294
|
+
assertions,
|
|
295
|
+
'expected.honesty.forbidBuilderKeysInObjective',
|
|
296
|
+
passed,
|
|
297
|
+
passed
|
|
298
|
+
? 'Objective text has no Builder capability keys or generation tokens.'
|
|
299
|
+
: `Objective text contains forbidden token "${match[0]}".`,
|
|
300
|
+
{ soft }
|
|
301
|
+
);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function emitPresentFlagRows(assertions, honestySpec, honesty, observation, soft) {
|
|
305
|
+
if (honestySpec.requireCompletion === false || honestySpec.requireCompletion === true) {
|
|
306
|
+
assertCompletion(assertions, honestySpec, honesty, soft);
|
|
307
|
+
}
|
|
308
|
+
if (
|
|
309
|
+
honestySpec.requireContributionObservation === false ||
|
|
310
|
+
honestySpec.requireContributionObservation === true
|
|
311
|
+
) {
|
|
312
|
+
assertContribution(assertions, honestySpec, honesty, soft);
|
|
313
|
+
}
|
|
314
|
+
if (
|
|
315
|
+
typeof honestySpec.minResourceChanges === 'number' ||
|
|
316
|
+
typeof honestySpec.softResourceChanges === 'boolean'
|
|
317
|
+
) {
|
|
318
|
+
assertMinResourceChanges(assertions, honestySpec, honesty, soft);
|
|
319
|
+
}
|
|
320
|
+
assertSchemaVersion(assertions, honestySpec, honesty, soft);
|
|
321
|
+
assertForbidBuilderKeys(assertions, honestySpec, observation, soft);
|
|
322
|
+
}
|
|
323
|
+
|
|
174
324
|
function evaluateHonestyExpectations(honestySpec, observation, options = {}) {
|
|
175
325
|
if (!honestySpec || typeof honestySpec !== 'object' || Array.isArray(honestySpec)) {
|
|
176
326
|
return [];
|
|
@@ -178,17 +328,16 @@ function evaluateHonestyExpectations(honestySpec, observation, options = {}) {
|
|
|
178
328
|
const soft = options.soft === true;
|
|
179
329
|
const honesty = observation.honesty || {};
|
|
180
330
|
const assertions = [];
|
|
181
|
-
|
|
182
|
-
assertWorkResultPresent(assertions, honesty, observation);
|
|
183
|
-
}
|
|
331
|
+
assertWorkResultPresent(assertions, honestySpec, honesty, observation, soft);
|
|
184
332
|
if (!honesty.present) {
|
|
185
|
-
|
|
333
|
+
emitPresentFlagRows(assertions, honestySpec, honesty, observation, soft);
|
|
186
334
|
return assertions;
|
|
187
335
|
}
|
|
188
336
|
assertSchemaVersion(assertions, honestySpec, honesty, soft);
|
|
189
337
|
assertCompletion(assertions, honestySpec, honesty, soft);
|
|
190
338
|
assertContribution(assertions, honestySpec, honesty, soft);
|
|
191
339
|
assertMinResourceChanges(assertions, honestySpec, honesty, soft);
|
|
340
|
+
assertForbidBuilderKeys(assertions, honestySpec, observation, soft);
|
|
192
341
|
return assertions;
|
|
193
342
|
}
|
|
194
343
|
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Map role-assistant test results to expected lifecycleState tokens.
|
|
3
|
+
* @fileoverview Prefer work.result completion over coarse work.status.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const { VERDICT } = require('../lifecycle/product-model');
|
|
9
|
+
|
|
10
|
+
const SUPPORTED_LIFECYCLE_STATES = new Set([
|
|
11
|
+
'completed',
|
|
12
|
+
'question',
|
|
13
|
+
'approval-required',
|
|
14
|
+
'dependency',
|
|
15
|
+
'safe-stop',
|
|
16
|
+
'rejected',
|
|
17
|
+
'failed'
|
|
18
|
+
]);
|
|
19
|
+
const LIFECYCLE_STATE_ALIASES = Object.freeze({
|
|
20
|
+
completed: ['completed', 'complete', 'done', 'success', 'verified'],
|
|
21
|
+
question: ['question', 'question_required', 'awaiting_question', 'pending_question'],
|
|
22
|
+
'approval-required': [
|
|
23
|
+
'approval_required',
|
|
24
|
+
'awaiting_approval',
|
|
25
|
+
'pending_approval',
|
|
26
|
+
'requires_approval'
|
|
27
|
+
],
|
|
28
|
+
dependency: ['dependency', 'dependency_wait', 'dependency_blocked', 'awaiting_dependency'],
|
|
29
|
+
'safe-stop': ['safe_stop', 'safe_stopped', 'policy_blocked', 'halted', 'paused'],
|
|
30
|
+
rejected: ['rejected', 'denied', 'declined', 'policy_rejected'],
|
|
31
|
+
failed: ['failed', 'error', 'errored', 'timeout', 'cancelled', 'canceled']
|
|
32
|
+
});
|
|
33
|
+
const WORK_STATUS_TO_LIFECYCLE = Object.freeze({
|
|
34
|
+
completed: 'completed',
|
|
35
|
+
waiting: 'question',
|
|
36
|
+
running: 'dependency',
|
|
37
|
+
stopped: 'safe-stop'
|
|
38
|
+
});
|
|
39
|
+
const WAIT_REASON_TO_LIFECYCLE = Object.freeze({
|
|
40
|
+
ask: 'question',
|
|
41
|
+
approval: 'approval-required',
|
|
42
|
+
ownerroute: 'dependency',
|
|
43
|
+
realityconfirm: 'question',
|
|
44
|
+
knowledgeconfirm: 'question'
|
|
45
|
+
});
|
|
46
|
+
const WORKER_TASK_STATUS_TO_LIFECYCLE = Object.freeze({
|
|
47
|
+
draft: 'dependency',
|
|
48
|
+
pendingapproval: 'approval-required',
|
|
49
|
+
approved: 'dependency',
|
|
50
|
+
running: 'dependency',
|
|
51
|
+
completed: 'completed',
|
|
52
|
+
failed: 'failed',
|
|
53
|
+
cancelled: 'rejected',
|
|
54
|
+
canceled: 'rejected'
|
|
55
|
+
});
|
|
56
|
+
const WORKER_APPROVAL_STATE_TO_LIFECYCLE = Object.freeze({
|
|
57
|
+
pending: 'approval-required',
|
|
58
|
+
approved: 'dependency',
|
|
59
|
+
rejected: 'rejected'
|
|
60
|
+
});
|
|
61
|
+
const COMPLETION_STATE_TO_LIFECYCLE = Object.freeze({
|
|
62
|
+
safestopped: 'safe-stop',
|
|
63
|
+
safe_stopped: 'safe-stop',
|
|
64
|
+
cancelled: 'rejected',
|
|
65
|
+
canceled: 'rejected',
|
|
66
|
+
completed: 'completed',
|
|
67
|
+
waiting: 'question'
|
|
68
|
+
});
|
|
69
|
+
const STEP_SIGNAL_FIELDS = [
|
|
70
|
+
'lifecycleState',
|
|
71
|
+
'state',
|
|
72
|
+
'status',
|
|
73
|
+
'code',
|
|
74
|
+
'errorCode',
|
|
75
|
+
'reason',
|
|
76
|
+
'kind',
|
|
77
|
+
'type',
|
|
78
|
+
'error',
|
|
79
|
+
'failure',
|
|
80
|
+
'details',
|
|
81
|
+
'result'
|
|
82
|
+
];
|
|
83
|
+
const OBJECT_SIGNAL_FIELDS = [
|
|
84
|
+
'lifecycleState',
|
|
85
|
+
'state',
|
|
86
|
+
'status',
|
|
87
|
+
'code',
|
|
88
|
+
'type',
|
|
89
|
+
'reason',
|
|
90
|
+
'kind',
|
|
91
|
+
'category',
|
|
92
|
+
'errorCode'
|
|
93
|
+
];
|
|
94
|
+
const TOP_LEVEL_SIGNAL_PATHS = [
|
|
95
|
+
'lifecycleState',
|
|
96
|
+
'state',
|
|
97
|
+
'status',
|
|
98
|
+
'lifecycle.state',
|
|
99
|
+
'report.lifecycleState',
|
|
100
|
+
'report.state',
|
|
101
|
+
'report.status',
|
|
102
|
+
'report.lifecycle.state',
|
|
103
|
+
'report.runtime.state',
|
|
104
|
+
'report.work.state'
|
|
105
|
+
];
|
|
106
|
+
|
|
107
|
+
function normalizeLifecycleStateToken(value) {
|
|
108
|
+
if (typeof value !== 'string') {
|
|
109
|
+
return '';
|
|
110
|
+
}
|
|
111
|
+
return value
|
|
112
|
+
.trim()
|
|
113
|
+
.toLowerCase()
|
|
114
|
+
.replace(/[^a-z0-9]+/g, '_')
|
|
115
|
+
.replace(/^_+|_+$/g, '');
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function lifecycleStateFromToken(token) {
|
|
119
|
+
if (!token) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
for (const [state, aliases] of Object.entries(LIFECYCLE_STATE_ALIASES)) {
|
|
123
|
+
for (const alias of aliases) {
|
|
124
|
+
if (token === alias || token.startsWith(`${alias}_`)) {
|
|
125
|
+
return state;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
function lifecycleStateFromSignalValue(value) {
|
|
133
|
+
if (value === null || value === undefined) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
if (typeof value === 'string') {
|
|
137
|
+
return lifecycleStateFromToken(normalizeLifecycleStateToken(value));
|
|
138
|
+
}
|
|
139
|
+
if (Array.isArray(value)) {
|
|
140
|
+
return firstLifecycleFromValues(value);
|
|
141
|
+
}
|
|
142
|
+
if (typeof value === 'object') {
|
|
143
|
+
return firstLifecycleFromValues(OBJECT_SIGNAL_FIELDS.map((field) => value[field]));
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function firstLifecycleFromValues(values) {
|
|
149
|
+
for (const candidate of values) {
|
|
150
|
+
const state = lifecycleStateFromSignalValue(candidate);
|
|
151
|
+
if (state) {
|
|
152
|
+
return state;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function mapWorkStatusFromResult(result) {
|
|
159
|
+
const rawStatus = normalizeLifecycleStateToken(result?.status);
|
|
160
|
+
if (rawStatus && WORK_STATUS_TO_LIFECYCLE[rawStatus]) {
|
|
161
|
+
const waitReason = normalizeLifecycleStateToken(result?.wait?.waitReason || '');
|
|
162
|
+
if (rawStatus === 'waiting' && waitReason && WAIT_REASON_TO_LIFECYCLE[waitReason]) {
|
|
163
|
+
return WAIT_REASON_TO_LIFECYCLE[waitReason];
|
|
164
|
+
}
|
|
165
|
+
return WORK_STATUS_TO_LIFECYCLE[rawStatus];
|
|
166
|
+
}
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function mapWorkerTaskStateFromResult(result) {
|
|
171
|
+
const statusCandidates = [result?.task?.status, result?.status, result?.workerTask?.status];
|
|
172
|
+
for (const row of statusCandidates) {
|
|
173
|
+
const token = normalizeLifecycleStateToken(row);
|
|
174
|
+
if (token && WORKER_TASK_STATUS_TO_LIFECYCLE[token]) {
|
|
175
|
+
return WORKER_TASK_STATUS_TO_LIFECYCLE[token];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const approvalCandidates = [
|
|
179
|
+
result?.task?.approvalState,
|
|
180
|
+
result?.approvalState,
|
|
181
|
+
result?.workerTask?.approvalState
|
|
182
|
+
];
|
|
183
|
+
for (const row of approvalCandidates) {
|
|
184
|
+
const token = normalizeLifecycleStateToken(row);
|
|
185
|
+
if (token && WORKER_APPROVAL_STATE_TO_LIFECYCLE[token]) {
|
|
186
|
+
return WORKER_APPROVAL_STATE_TO_LIFECYCLE[token];
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function workResultCompletionObject(result) {
|
|
193
|
+
const workResult =
|
|
194
|
+
result?.workResult && typeof result.workResult === 'object' ? result.workResult : null;
|
|
195
|
+
const completion =
|
|
196
|
+
workResult?.completion && typeof workResult.completion === 'object'
|
|
197
|
+
? workResult.completion
|
|
198
|
+
: null;
|
|
199
|
+
return { workResult, completion };
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
function mapWorkResultCompletionToLifecycle(result) {
|
|
203
|
+
const { workResult, completion } = workResultCompletionObject(result);
|
|
204
|
+
const state = normalizeLifecycleStateToken(completion?.state);
|
|
205
|
+
if (!workResult || !completion || !state) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
if (state === 'failed') {
|
|
209
|
+
return workResultSignalsRejected(workResult) ? 'rejected' : 'failed';
|
|
210
|
+
}
|
|
211
|
+
return COMPLETION_STATE_TO_LIFECYCLE[state] || lifecycleStateFromToken(state);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
function completionReasonBag(processExecution) {
|
|
215
|
+
const pe = processExecution && typeof processExecution === 'object' ? processExecution : {};
|
|
216
|
+
if (pe.completionReason && typeof pe.completionReason === 'object') {
|
|
217
|
+
return pe.completionReason;
|
|
218
|
+
}
|
|
219
|
+
if (pe.completion_reason && typeof pe.completion_reason === 'object') {
|
|
220
|
+
return pe.completion_reason;
|
|
221
|
+
}
|
|
222
|
+
return {};
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function workResultSignalsRejected(workResult) {
|
|
226
|
+
const reasonBag = completionReasonBag(workResult?.processExecution);
|
|
227
|
+
const kind = normalizeLifecycleStateToken(reasonBag.kind || reasonBag.Kind);
|
|
228
|
+
if (kind === 'rejected' || kind === 'denied' || kind === 'unauthorized') {
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
const text = [
|
|
232
|
+
reasonBag.summary,
|
|
233
|
+
workResult?.completion?.businessLanguage?.reason,
|
|
234
|
+
workResult?.completion?.businessLanguage?.summary,
|
|
235
|
+
workResult?.completion?.businessLanguage?.outcomeState,
|
|
236
|
+
workResult?.task?.resultSummary
|
|
237
|
+
]
|
|
238
|
+
.filter((row) => typeof row === 'string' && row.trim())
|
|
239
|
+
.join(' ')
|
|
240
|
+
.toLowerCase();
|
|
241
|
+
return /\b(trust|authority|denied|rejected|unauthorized|not authorized)\b/.test(text);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function valueAtDottedPath(source, dottedPath) {
|
|
245
|
+
return dottedPath.split('.').reduce((cursor, key) => {
|
|
246
|
+
if (!cursor || typeof cursor !== 'object') {
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
return cursor[key];
|
|
250
|
+
}, source);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
function lifecycleStateFromStepsRun(result) {
|
|
254
|
+
const steps = Array.isArray(result?.stepsRun) ? result.stepsRun : [];
|
|
255
|
+
for (const row of steps) {
|
|
256
|
+
const state = firstLifecycleFromValues(STEP_SIGNAL_FIELDS.map((field) => row?.[field]));
|
|
257
|
+
if (state) {
|
|
258
|
+
return state;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return null;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
function resolveLifecycleStateFromResult(result) {
|
|
265
|
+
// Prefer governed work.result completion over coarse work.status "stopped"
|
|
266
|
+
// (which collapses failed + safeStopped + cancelled into safe-stop).
|
|
267
|
+
return (
|
|
268
|
+
mapWorkResultCompletionToLifecycle(result) ||
|
|
269
|
+
mapWorkStatusFromResult(result) ||
|
|
270
|
+
mapWorkerTaskStateFromResult(result) ||
|
|
271
|
+
firstLifecycleFromValues(TOP_LEVEL_SIGNAL_PATHS.map((path) => valueAtDottedPath(result, path))) ||
|
|
272
|
+
lifecycleStateFromStepsRun(result)
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
function deriveLifecycleState(result, lifecycleVerdict) {
|
|
277
|
+
if (lifecycleVerdict === VERDICT.VERIFIED) {
|
|
278
|
+
return 'completed';
|
|
279
|
+
}
|
|
280
|
+
const structuredState = resolveLifecycleStateFromResult(result);
|
|
281
|
+
if (structuredState) {
|
|
282
|
+
return structuredState;
|
|
283
|
+
}
|
|
284
|
+
if (lifecycleVerdict === VERDICT.NOT_VERIFIED) return 'safe-stop';
|
|
285
|
+
return 'failed';
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
module.exports = {
|
|
289
|
+
SUPPORTED_LIFECYCLE_STATES,
|
|
290
|
+
deriveLifecycleState
|
|
291
|
+
};
|