@aifabrix/builder 2.52.0 → 2.53.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/lib/api/datasources-extended.api.js +8 -8
- package/lib/api/keycloak.api.js +92 -0
- package/lib/api/token-providers.api.js +77 -0
- package/lib/api/types/keycloak.types.js +23 -0
- package/lib/api/types/token-providers.types.js +65 -0
- package/lib/app/deploy-config.js +3 -2
- package/lib/app/down.js +16 -1
- package/lib/channels/add-channel.js +134 -57
- package/lib/channels/approval-guides/chatgpt.js +1 -1
- package/lib/channels/approval-guides/index.js +3 -0
- package/lib/channels/approval-guides/microsoft-copilot.js +27 -14
- package/lib/channels/channel-add-ensure.js +128 -0
- package/lib/channels/channel-add-existing.js +72 -0
- package/lib/channels/channel-artifact-generator.js +11 -1
- package/lib/channels/channel-branding.js +94 -0
- package/lib/channels/channel-credential.js +8 -0
- package/lib/channels/channel-discovery.js +330 -0
- package/lib/channels/channel-external-system.js +1 -1
- package/lib/channels/channel-runtime-resolver.js +107 -14
- package/lib/channels/channel-status-display.js +36 -3
- package/lib/channels/microsoft-copilot-channel-add.js +138 -0
- package/lib/channels/microsoft-copilot-entra-sso-form.js +251 -0
- package/lib/channels/microsoft-copilot-entra-sso.js +285 -0
- package/lib/channels/microsoft-copilot-icons.js +74 -0
- package/lib/channels/microsoft-copilot-limits.js +103 -0
- package/lib/channels/microsoft-copilot-package.js +178 -52
- package/lib/channels/microsoft-copilot-validate.js +227 -0
- package/lib/cli/attach-default-help-examples.js +102 -0
- package/lib/cli/index.js +4 -0
- package/lib/cli/infra-guided.js +13 -6
- package/lib/cli/setup-credential-deployment.js +7 -5
- package/lib/cli/setup-infra.js +31 -4
- package/lib/cli/setup-utility-validate.js +1 -0
- package/lib/commands/channel-add-setup.js +28 -9
- package/lib/commands/channel.js +14 -10
- package/lib/commands/credential-push.js +37 -5
- package/lib/commands/integration-definition.js +158 -0
- package/lib/commands/package-score.js +72 -0
- package/lib/commands/repair-auth-apply.js +19 -5
- package/lib/commands/repair-datasource-sync-operations.js +4 -1
- package/lib/commands/role-assistant-test-output.js +200 -0
- package/lib/commands/role-assistant.js +163 -166
- package/lib/datasource/capability/capability-resolve.js +15 -5
- package/lib/datasource/capability/copy-operations.js +14 -4
- package/lib/deployment/deployer-poll-run.js +2 -2
- package/lib/deployment/deployer.js +1 -1
- package/lib/deployment/environment.js +2 -2
- package/lib/external-system/deploy.js +11 -21
- package/lib/infrastructure/index.js +19 -4
- package/lib/integration-definition/apply.js +476 -0
- package/lib/integration-definition/canonical-json.js +51 -0
- package/lib/integration-definition/emit-suite-bid.js +94 -0
- package/lib/integration-definition/enrich-crm-field-mappings.js +240 -0
- package/lib/integration-definition/enrich-openapi-operations.js +433 -0
- package/lib/integration-definition/from-discovery.js +339 -0
- package/lib/integration-definition/hash.js +37 -0
- package/lib/integration-definition/index.js +37 -0
- package/lib/integration-definition/resource-type-catalog.js +59 -0
- package/lib/integration-definition/system-kind-enum.js +40 -0
- package/lib/integration-definition/validate.js +148 -0
- package/lib/lab/package-parity-score.js +417 -0
- package/lib/programmatic/builder-api-request.js +5 -1
- package/lib/programmatic/builder-help-governance.js +3 -2
- package/lib/programmatic/capability-registry.js +20 -0
- package/lib/programmatic/help-content/channel-onboarding.md +35 -0
- package/lib/programmatic/help-content/cip-overview.md +27 -0
- package/lib/programmatic/help-content/connected-system-ui.md +70 -0
- package/lib/programmatic/help-content/dimensions-guide.md +23 -0
- package/lib/programmatic/help-content/enterprise-sync-fabrix.md +123 -0
- package/lib/programmatic/help-content/overview.md +25 -0
- package/lib/programmatic/help-content/subscription-guide.md +27 -0
- package/lib/programmatic/help-content/workflow.md +50 -0
- package/lib/programmatic/openapi-component-schemas.js +7 -1
- package/lib/programmatic/openapi-descriptions.js +46 -0
- package/lib/programmatic/openapi-envelope-examples.js +280 -0
- package/lib/programmatic/openapi-operation-bindings.js +50 -0
- package/lib/programmatic/openapi-request-schemas.js +40 -0
- package/lib/programmatic/openapi-result-schemas-overflow.js +101 -0
- package/lib/programmatic/openapi-result-schemas.js +76 -99
- package/lib/programmatic/openapi-schema-descriptions-core.js +25 -4
- package/lib/programmatic/openapi-schema-descriptions-help.js +1 -1
- package/lib/programmatic/openapi-schema-descriptions-operations.js +43 -0
- package/lib/programmatic/openapi-schema-helpers.js +9 -9
- package/lib/programmatic/openapi-spec.js +11 -1
- package/lib/programmatic/orchestration-openapi-meta.js +10 -0
- package/lib/programmatic/persist-supplied-openapi.js +180 -0
- package/lib/programmatic/route-handler-map.js +35 -1
- package/lib/programmatic/run-channel-package.js +236 -0
- package/lib/programmatic/run-integration-definition.js +77 -0
- package/lib/role-assistant/evidence-sync.js +55 -7
- package/lib/role-assistant/knowledge-sync-logging.js +58 -0
- package/lib/role-assistant/knowledge-sync.js +88 -93
- package/lib/role-assistant/test-cases-bid.js +155 -0
- package/lib/role-assistant/test-cases-evaluate.js +9 -1
- package/lib/role-assistant/test-cases-honesty.js +24 -10
- package/lib/role-assistant/test-cases.js +28 -0
- package/lib/role-assistant/test-runner-attachments.js +118 -0
- package/lib/role-assistant/test-runner-bid-apply.js +201 -0
- package/lib/role-assistant/test-runner-bid-document.js +278 -0
- package/lib/role-assistant/test-runner-start-payload.js +96 -0
- package/lib/role-assistant/test-runner-workhub-answers.js +249 -20
- package/lib/role-assistant/test-runner-workhub-helpers.js +100 -0
- package/lib/role-assistant/test-runner-workhub-soft.js +86 -0
- package/lib/role-assistant/test-runner-workhub.js +152 -107
- package/lib/role-assistant/test-runner.js +5 -63
- package/lib/role-assistant/test-suite.js +112 -0
- package/lib/schema/application-schema.json +56 -6
- package/lib/schema/external-datasource.schema.json +103 -17
- package/lib/schema/external-system.schema.json +54 -3
- package/lib/schema/integration-definition.schema.json +195 -0
- package/lib/utils/authentication-shape.js +6 -0
- package/lib/utils/compose-generator.js +10 -1
- package/lib/utils/compose-traefik-extra-routes.js +107 -0
- package/lib/utils/docker-build.js +2 -2
- package/lib/utils/help-builder.js +3 -1
- package/lib/utils/promote-dev-docker-image.js +102 -18
- package/lib/utils/transient-developer-id.js +28 -0
- package/package.json +14 -16
- package/templates/README.md +12 -1
- package/templates/applications/dataplane/application.yaml +10 -2
- package/templates/applications/dataplane/env.template +7 -6
- package/templates/applications/miso-controller/application.yaml +23 -8
- package/templates/applications/miso-controller/env.template +8 -2
- package/templates/applications/miso-controller/rbac.yaml +1 -0
- package/templates/channels/README.md +11 -1
- package/templates/channels/brand/color-192.png +0 -0
- package/templates/channels/brand/dark/128.png +0 -0
- package/templates/channels/brand/dark/192.png +0 -0
- package/templates/channels/brand/dark/256.png +0 -0
- package/templates/channels/brand/dark/32.png +0 -0
- package/templates/channels/brand/dark/512.png +0 -0
- package/templates/channels/brand/dark/64.png +0 -0
- package/templates/channels/brand/light/128.png +0 -0
- package/templates/channels/brand/light/192.png +0 -0
- package/templates/channels/brand/light/256.png +0 -0
- package/templates/channels/brand/light/32.png +0 -0
- package/templates/channels/brand/light/512.png +0 -0
- package/templates/channels/brand/light/64.png +0 -0
- package/templates/channels/brand/mono-white/128.png +0 -0
- package/templates/channels/brand/mono-white/192.png +0 -0
- package/templates/channels/brand/mono-white/256.png +0 -0
- package/templates/channels/brand/mono-white/32.png +0 -0
- package/templates/channels/brand/mono-white/512.png +0 -0
- package/templates/channels/brand/mono-white/64.png +0 -0
- package/templates/channels/brand/outline-32.png +0 -0
- package/templates/channels/chatgpt/install.template.md.hbs +6 -4
- package/templates/channels/chatgpt/integration/README.md +4 -5
- package/templates/channels/chatgpt/integration/chatgpt-system.json +1 -16
- package/templates/channels/microsoft-copilot/ai-plugin.template.json.hbs +14 -16
- package/templates/channels/microsoft-copilot/declarative-agent.template.json.hbs +5 -3
- package/templates/channels/microsoft-copilot/entra-sso-registration.template.md.hbs +30 -0
- package/templates/channels/microsoft-copilot/fi-fi.template.json.hbs +7 -0
- package/templates/channels/microsoft-copilot/install.template.md.hbs +93 -22
- package/templates/channels/microsoft-copilot/integration/README.md +2 -3
- package/templates/channels/microsoft-copilot/integration/microsoft-copilot-system.json +1 -22
- package/templates/channels/microsoft-copilot/manifest.template.json.hbs +34 -19
- package/templates/channels/microsoft-copilot/oauth-plugin-vault-required.template.md.hbs +15 -0
- package/templates/channels/slack/integration/README.md +2 -4
- package/templates/channels/teams-bot/install.template.md.hbs +4 -0
- package/templates/channels/teams-bot/integration/README.md +3 -5
- package/templates/channels/web-embed/integration/web-embed-system.json +1 -16
- package/templates/python/docker-compose.hbs +36 -0
- package/templates/typescript/docker-compose.hbs +36 -0
- package/.cursor/plans/Done/157.1-security-quality-violations-by-type.csv +0 -374
- package/.cursor/process/README.md +0 -9
- package/.cursor/rules/anchor-docs.mdc +0 -15
- package/.cursor/rules/assistant-driven-integration-build.mdc +0 -40
- package/.cursor/rules/cli-layout.mdc +0 -81
- package/.cursor/rules/cli-product-neutral.mdc +0 -43
- package/.cursor/rules/deploy-rules/docker-image-ip-policy.mdc +0 -49
- package/.cursor/rules/docs-rules.mdc +0 -32
- package/.cursor/rules/plan-rules/application-lifecycle.mdc +0 -30
- package/.cursor/rules/plan-rules/plan-frontmatter.mdc +0 -35
- package/.cursor/rules/plan-rules/plan-lifecycle.mdc +0 -31
- package/.cursor/rules/plan-rules/plan-validation-gate.mdc +0 -34
- package/.cursor/rules/project-rules.mdc +0 -913
- package/.cursor/skills/README.md +0 -15
- package/.dockerignore +0 -52
- package/.eslintignore +0 -22
- package/.markdownlint.json +0 -14
- package/anchor-docs/README.md +0 -10
- package/anchor-docs/_TEMPLATE +0 -24
- package/babel.config.js +0 -6
- package/bin/builder-api-cleanup.js +0 -26
- package/bin/builder-api-nest.js +0 -10
- package/bin/builder-api-spike.js +0 -19
- package/enterprise-knowledge/README.md +0 -50
- package/enterprise-knowledge/enterprise-integration-lifecycle/README.md +0 -22
- package/enterprise-knowledge/enterprise-integration-lifecycle/application.json +0 -15
- package/enterprise-knowledge/enterprise-integration-lifecycle/deploy.js +0 -69
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-deploy.json +0 -52
- package/enterprise-knowledge/enterprise-integration-lifecycle/enterprise-integration-lifecycle-system.json +0 -29
- package/enterprise-knowledge/enterprise-integration-lifecycle/env.template +0 -2
- package/integration/README.md +0 -81
- package/integration/github/README.md +0 -53
- package/integration/github/application.json +0 -21
- package/integration/github/deploy.js +0 -72
- package/integration/github/env.template +0 -11
- package/integration/github/github-datasource-issue-comments.json +0 -239
- package/integration/github/github-datasource-issues.json +0 -399
- package/integration/github/github-datasource-repository.json +0 -354
- package/integration/github/github-deploy.json +0 -1202
- package/integration/github/github-system.json +0 -82
- package/integration/hubspot-test/README.md +0 -159
- package/integration/hubspot-test/application.json +0 -54
- package/integration/hubspot-test/companies.json +0 -2048
- package/integration/hubspot-test/create-hubspot.js +0 -523
- package/integration/hubspot-test/env.template +0 -4
- package/integration/hubspot-test/hubspot-test-datasource-company.json +0 -138
- package/integration/hubspot-test/hubspot-test-datasource-contact.json +0 -146
- package/integration/hubspot-test/hubspot-test-datasource-deal.json +0 -146
- package/integration/hubspot-test/hubspot-test-datasource-users.json +0 -76
- package/integration/hubspot-test/hubspot-test-deploy.json +0 -2160
- package/integration/hubspot-test/hubspot-test-system.json +0 -74
- package/integration/hubspot-test/rbac.json +0 -166
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +0 -20
- package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +0 -9
- package/integration/hubspot-test/test-artifacts/wizard-invalid-add-datasource.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-app-name.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-create.yaml +0 -7
- package/integration/hubspot-test/test-artifacts/wizard-invalid-credential-select.yaml +0 -7
- package/integration/hubspot-test/test-artifacts/wizard-invalid-known-platform.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-app.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-missing-source.yaml +0 -2
- package/integration/hubspot-test/test-artifacts/wizard-invalid-mode.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-file.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-invalid-openapi-url.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-invalid-source.yaml +0 -4
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-array-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-key-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-path-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-dimension-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-test.yaml +0 -5
- package/integration/hubspot-test/test-artifacts/wizard-valid-for-rbac-yaml-test.yaml +0 -5
- package/integration/hubspot-test/test-dataplane-down-helpers.js +0 -249
- package/integration/hubspot-test/test-dataplane-down-tests.js +0 -386
- package/integration/hubspot-test/test-dataplane-down.js +0 -209
- package/integration/hubspot-test/test.js +0 -1588
- package/integration/hubspot-test/wizard-hubspot-e2e.yaml +0 -16
- package/integration/hubspot-test/wizard-hubspot-platform.yaml +0 -8
- package/integration/hubspot-test/wizard-hubspot-test-headless.yaml +0 -23
- package/integration/roundtrip-test-local/README.md +0 -143
- package/integration/roundtrip-test-local/application.yaml +0 -13
- package/integration/roundtrip-test-local/env.template +0 -15
- package/integration/roundtrip-test-local/roundtrip-test-local-datasource-roundtrip-test-company.yaml +0 -14
- package/integration/roundtrip-test-local/roundtrip-test-local-deploy.json +0 -61
- package/integration/roundtrip-test-local/roundtrip-test-local-system.yaml +0 -25
- package/integration/roundtrip-test-local2/README.md +0 -143
- package/integration/roundtrip-test-local2/application.yaml +0 -13
- package/integration/roundtrip-test-local2/env.template +0 -15
- package/integration/roundtrip-test-local2/roundtrip-test-local2-datasource-company.yaml +0 -31
- package/integration/roundtrip-test-local2/roundtrip-test-local2-deploy.json +0 -86
- package/integration/roundtrip-test-local2/roundtrip-test-local2-system.yaml +0 -25
- package/integration/test/wizard.yaml +0 -8
- package/jest.config.coverage.js +0 -37
- package/jest.config.default.js +0 -11
- package/jest.config.integration.fixtures.js +0 -22
- package/jest.config.integration.js +0 -33
- package/jest.config.isolated.js +0 -11
- package/jest.config.manual.js +0 -30
- package/jest.global-live-fabrix-hooks.js +0 -36
- package/jest.isolated-projects.js +0 -260
- package/jest.projects.js +0 -76
- package/packages/builder-api/README.md +0 -120
- package/packages/builder-api/package.json +0 -30
- package/packages/builder-api/src/app.module.ts +0 -7
- package/packages/builder-api/src/auth/auth.module.ts +0 -5
- package/packages/builder-api/src/external-system/external-system.module.ts +0 -5
- package/packages/builder-api/src/main.ts +0 -16
- package/packages/builder-api/tsconfig.json +0 -15
- package/scripts/check-builder-api-architecture-grep.js +0 -79
- package/scripts/check-datasource-test-run-schema-sync.js +0 -34
- package/scripts/ci-fix.sh +0 -19
- package/scripts/ci-simulate.sh +0 -19
- package/scripts/diagnose-cli.js +0 -150
- package/scripts/docker_image_content_gate.js +0 -47
- package/scripts/docker_image_content_gate.sh +0 -5
- package/scripts/export-builder-api-evidence.js +0 -262
- package/scripts/install-local.js +0 -490
- package/scripts/lib/builder-api-docker-staging-copy.js +0 -60
- package/scripts/lib/builder-api-docker-staging-core.js +0 -183
- package/scripts/lib/docker-image-content-gate-core.js +0 -166
- package/scripts/lib/plan-actor.js +0 -109
- package/scripts/lib/plan-config.js +0 -20
- package/scripts/lib/plan-gates.js +0 -154
- package/scripts/lib/plan-meta.js +0 -104
- package/scripts/lib/plan-parse.js +0 -162
- package/scripts/lib/plan-prevalidate-gates.js +0 -337
- package/scripts/lib/plan-run-core.js +0 -125
- package/scripts/lib/plan-run-report.js +0 -119
- package/scripts/plan-approve.js +0 -24
- package/scripts/plan-archive.js +0 -49
- package/scripts/plan-run.js +0 -13
- package/scripts/plan-set-actor.js +0 -21
- package/scripts/plan-validate.js +0 -80
- package/scripts/pnpm/af.mjs +0 -110
- package/scripts/pnpm/check-quiet.mjs +0 -32
- package/scripts/pnpm/dev-install.mjs +0 -29
- package/scripts/pnpm/dev-reload.mjs +0 -18
- package/scripts/pnpm/help.mjs +0 -55
- package/scripts/pnpm/lib/dev-reload-core.mjs +0 -189
- package/scripts/pnpm/lib/dev-reload-log-capture.mjs +0 -67
- package/scripts/pnpm/lib/dev-reload-log-utils.mjs +0 -32
- package/scripts/pnpm/lib/resolve-aifabrix-bin.mjs +0 -124
- package/scripts/pnpm/lib/resolve-app-url.mjs +0 -183
- package/scripts/pnpm/lib/spinner.mjs +0 -42
- package/scripts/pnpm-global-remove.js +0 -48
- package/scripts/stage_builder_api_for_docker.js +0 -65
- package/scripts/sync-builder-api-template.js +0 -44
- package/scripts/test-dataplane-bootstrap.js +0 -331
|
@@ -27,6 +27,10 @@ const EVIDENCE_DIR_NAME = 'evidence';
|
|
|
27
27
|
const EVIDENCE_EXPORT_FILE = 'evidence.json';
|
|
28
28
|
const VALIDATION_FAILED = 'failed';
|
|
29
29
|
const VALIDATION_PASSED = 'passed';
|
|
30
|
+
/** Builder-keyed Category B catalogue — never import as Evidence (517.3 / 517.4.1). */
|
|
31
|
+
const SKIP_EVIDENCE_BASENAMES = new Set(['capability-business-catalog.json']);
|
|
32
|
+
/** PoC draft folders under evidence/ — never import as governed Evidence. */
|
|
33
|
+
const SKIP_EVIDENCE_DIR_NAMES = new Set(['candidates', 'candidate']);
|
|
30
34
|
|
|
31
35
|
const EVIDENCE_MUTABLE_KEYS = [
|
|
32
36
|
'key',
|
|
@@ -79,6 +83,23 @@ function isEvidenceFileName(fileName) {
|
|
|
79
83
|
return lower.endsWith('.json') || lower.endsWith('.yaml') || lower.endsWith('.yml');
|
|
80
84
|
}
|
|
81
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Skip retired / forbidden evidence payloads (517.4.1 scrub).
|
|
88
|
+
* @param {string} filePath
|
|
89
|
+
* @param {unknown} parsed
|
|
90
|
+
* @returns {boolean}
|
|
91
|
+
*/
|
|
92
|
+
function shouldSkipEvidencePayload(filePath, parsed) {
|
|
93
|
+
const base = path.basename(String(filePath || '')).toLowerCase();
|
|
94
|
+
if (SKIP_EVIDENCE_BASENAMES.has(base)) {
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
97
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed) && parsed._retired === true) {
|
|
98
|
+
return true;
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
|
|
82
103
|
function collectEvidenceFiles(dirPath) {
|
|
83
104
|
if (!fs.existsSync(dirPath)) {
|
|
84
105
|
return [];
|
|
@@ -88,6 +109,10 @@ function collectEvidenceFiles(dirPath) {
|
|
|
88
109
|
for (const entry of entries) {
|
|
89
110
|
const fullPath = path.join(dirPath, entry.name);
|
|
90
111
|
if (entry.isDirectory()) {
|
|
112
|
+
const dirName = String(entry.name || '').trim().toLowerCase();
|
|
113
|
+
if (SKIP_EVIDENCE_DIR_NAMES.has(dirName)) {
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
91
116
|
files.push(...collectEvidenceFiles(fullPath));
|
|
92
117
|
continue;
|
|
93
118
|
}
|
|
@@ -152,8 +177,13 @@ function sanitizeEvidenceRow(row, systemKey, options = {}) {
|
|
|
152
177
|
function loadEvidenceRowsFromFolder(evidencePath, systemKey) {
|
|
153
178
|
const files = collectEvidenceFiles(evidencePath);
|
|
154
179
|
const rows = [];
|
|
180
|
+
const skippedFiles = [];
|
|
155
181
|
for (const filePath of files) {
|
|
156
182
|
const parsed = parseEvidenceFile(filePath);
|
|
183
|
+
if (shouldSkipEvidencePayload(filePath, parsed)) {
|
|
184
|
+
skippedFiles.push(path.relative(evidencePath, filePath));
|
|
185
|
+
continue;
|
|
186
|
+
}
|
|
157
187
|
const extractedRows = extractEvidenceRows(parsed);
|
|
158
188
|
for (const row of extractedRows) {
|
|
159
189
|
if (!row || typeof row !== 'object' || Array.isArray(row)) {
|
|
@@ -169,7 +199,7 @@ function loadEvidenceRowsFromFolder(evidencePath, systemKey) {
|
|
|
169
199
|
rows.push(normalized);
|
|
170
200
|
}
|
|
171
201
|
}
|
|
172
|
-
return { files, rows };
|
|
202
|
+
return { files, rows, skippedFiles };
|
|
173
203
|
}
|
|
174
204
|
|
|
175
205
|
function resolveEvidenceDirectory(systemKey, pathOptions = {}) {
|
|
@@ -277,21 +307,25 @@ function buildFailureSummary(failures) {
|
|
|
277
307
|
return `${preview}${more}`;
|
|
278
308
|
}
|
|
279
309
|
|
|
280
|
-
function buildEvidenceDryRunSummary(evidencePath, files, rows) {
|
|
310
|
+
function buildEvidenceDryRunSummary(evidencePath, files, rows, skippedFiles = []) {
|
|
281
311
|
return {
|
|
282
312
|
skipped: false,
|
|
283
313
|
dryRun: true,
|
|
284
314
|
evidencePath,
|
|
285
315
|
filesDiscovered: files.length,
|
|
316
|
+
filesSkipped: skippedFiles.length,
|
|
317
|
+
skippedFiles: [...skippedFiles],
|
|
286
318
|
discovered: rows.length
|
|
287
319
|
};
|
|
288
320
|
}
|
|
289
321
|
|
|
290
|
-
function buildEvidenceImportSummary(evidencePath, files, rows, loadResult) {
|
|
322
|
+
function buildEvidenceImportSummary(evidencePath, files, rows, loadResult, skippedFiles = []) {
|
|
291
323
|
return {
|
|
292
324
|
skipped: false,
|
|
293
325
|
evidencePath,
|
|
294
326
|
filesDiscovered: files.length,
|
|
327
|
+
filesSkipped: skippedFiles.length,
|
|
328
|
+
skippedFiles: [...skippedFiles],
|
|
295
329
|
discovered: rows.length,
|
|
296
330
|
loaded: Number(loadResult.inserted || 0) + Number(loadResult.updated || 0),
|
|
297
331
|
validated: 0,
|
|
@@ -347,12 +381,18 @@ async function importRoleAssistantEvidence(params) {
|
|
|
347
381
|
return { skipped: true, reason: 'not-role-assistant' };
|
|
348
382
|
}
|
|
349
383
|
const evidencePath = resolveEvidenceDirectory(systemKey, pathOptions);
|
|
350
|
-
const { files, rows } = loadEvidenceRowsFromFolder(evidencePath, systemKey);
|
|
384
|
+
const { files, rows, skippedFiles } = loadEvidenceRowsFromFolder(evidencePath, systemKey);
|
|
351
385
|
if (rows.length === 0) {
|
|
352
|
-
return {
|
|
386
|
+
return {
|
|
387
|
+
skipped: true,
|
|
388
|
+
reason: 'no-evidence-files',
|
|
389
|
+
evidencePath,
|
|
390
|
+
filesSkipped: (skippedFiles || []).length,
|
|
391
|
+
skippedFiles: [...(skippedFiles || [])]
|
|
392
|
+
};
|
|
353
393
|
}
|
|
354
394
|
if (dryRun) {
|
|
355
|
-
return buildEvidenceDryRunSummary(evidencePath, files, rows);
|
|
395
|
+
return buildEvidenceDryRunSummary(evidencePath, files, rows, skippedFiles);
|
|
356
396
|
}
|
|
357
397
|
const { loadResult, refs } = await loadEvidenceAndResolveRefs(
|
|
358
398
|
dataplaneUrl,
|
|
@@ -360,7 +400,13 @@ async function importRoleAssistantEvidence(params) {
|
|
|
360
400
|
systemKey,
|
|
361
401
|
rows
|
|
362
402
|
);
|
|
363
|
-
const summary = buildEvidenceImportSummary(
|
|
403
|
+
const summary = buildEvidenceImportSummary(
|
|
404
|
+
evidencePath,
|
|
405
|
+
files,
|
|
406
|
+
rows,
|
|
407
|
+
loadResult,
|
|
408
|
+
skippedFiles
|
|
409
|
+
);
|
|
364
410
|
const failures = await runEvidenceLifecycleBatch(dataplaneUrl, authConfig, refs, summary);
|
|
365
411
|
appendUnresolvedEvidenceFailures(summary, failures, refs.length, rows.length);
|
|
366
412
|
throwWhenEvidenceLifecycleFailed(summary, failures);
|
|
@@ -443,6 +489,8 @@ function logRoleAssistantEvidenceExportSummary(systemKey, result, options = {})
|
|
|
443
489
|
|
|
444
490
|
module.exports = {
|
|
445
491
|
isDigitalWorkerModel,
|
|
492
|
+
shouldSkipEvidencePayload,
|
|
493
|
+
loadEvidenceRowsFromFolder,
|
|
446
494
|
importRoleAssistantEvidence,
|
|
447
495
|
exportRoleAssistantEvidence,
|
|
448
496
|
logRoleAssistantEvidenceImportSummary,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const logger = require('../utils/logger');
|
|
4
|
+
const { formatSuccessLine, formatWarningLine, metadata } = require('../utils/cli-test-layout-chalk');
|
|
5
|
+
|
|
6
|
+
function logKnowledgeImportSummary(systemKey, result, options = {}) {
|
|
7
|
+
if (result.skipped) {
|
|
8
|
+
if (options.verbose === true) {
|
|
9
|
+
logger.log(metadata(`Knowledge sync skipped (${systemKey}): ${result.reason}`));
|
|
10
|
+
}
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
if (result.dryRun) {
|
|
14
|
+
logger.log(formatWarningLine(
|
|
15
|
+
`Role assistant knowledge dry-run: ${result.fileCount} file(s), ${result.recordCount} record(s), datasource ${result.datasourceKey}`
|
|
16
|
+
));
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
logger.log(formatSuccessLine(
|
|
20
|
+
`Role assistant knowledge synced (${result.datasourceKey}): ${result.recordCount} record(s) from ${result.fileCount} file(s).`
|
|
21
|
+
));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function logDocumentStorageSettingsPushSummary(systemKey, result, options = {}) {
|
|
25
|
+
if (result.skipped) {
|
|
26
|
+
if (options.verbose === true) {
|
|
27
|
+
logger.log(metadata(`Knowledge document storage settings skipped (${systemKey}): ${result.reason}`));
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (result.dryRun) {
|
|
32
|
+
logger.log(formatWarningLine(
|
|
33
|
+
`Knowledge document storage settings dry-run (${systemKey}): ${result.documentStorageKey || '(clear)'}`
|
|
34
|
+
));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
logger.log(formatSuccessLine(
|
|
38
|
+
`Knowledge document storage settings updated (${systemKey}): ${result.documentStorageKey || '(cleared)'}`
|
|
39
|
+
));
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function logKnowledgeExportSummary(systemKey, result, options = {}) {
|
|
43
|
+
if (result.skipped) {
|
|
44
|
+
if (options.verbose === true) {
|
|
45
|
+
logger.log(metadata(`Knowledge export skipped (${systemKey}): ${result.reason}`));
|
|
46
|
+
}
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
logger.log(formatSuccessLine(
|
|
50
|
+
`Role assistant knowledge exported (${result.datasourceKey}): ${result.count} document(s) to ${result.knowledgePath}.`
|
|
51
|
+
));
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
logKnowledgeImportSummary,
|
|
56
|
+
logDocumentStorageSettingsPushSummary,
|
|
57
|
+
logKnowledgeExportSummary
|
|
58
|
+
};
|
|
@@ -12,8 +12,6 @@ const path = require('path');
|
|
|
12
12
|
const crypto = require('crypto');
|
|
13
13
|
const fs = require('../internal/fs-real-sync');
|
|
14
14
|
const yaml = require('js-yaml');
|
|
15
|
-
const logger = require('../utils/logger');
|
|
16
|
-
const { formatSuccessLine, formatWarningLine, metadata } = require('../utils/cli-test-layout-chalk');
|
|
17
15
|
const { listDocuments, validateDocuments, bulkDocuments } = require('../api/datasources-extended.api');
|
|
18
16
|
const {
|
|
19
17
|
extractDocumentStorageKeyFromAssistantDetails,
|
|
@@ -32,6 +30,11 @@ const {
|
|
|
32
30
|
knowledgeSearchMetadataFromFrontmatter,
|
|
33
31
|
splitMarkdownFrontmatter
|
|
34
32
|
} = require('./knowledge-markdown-frontmatter');
|
|
33
|
+
const {
|
|
34
|
+
logKnowledgeImportSummary,
|
|
35
|
+
logDocumentStorageSettingsPushSummary,
|
|
36
|
+
logKnowledgeExportSummary
|
|
37
|
+
} = require('./knowledge-sync-logging');
|
|
35
38
|
|
|
36
39
|
function resolveSystemNode(input) {
|
|
37
40
|
if (!input || typeof input !== 'object') {
|
|
@@ -80,53 +83,91 @@ async function resolveDocumentStorageKeyFromDataplane(dataplaneUrl, authConfig,
|
|
|
80
83
|
}
|
|
81
84
|
|
|
82
85
|
/**
|
|
83
|
-
*
|
|
86
|
+
* Map role-assistant.yaml debug.* → Assistants settings PATCH fields.
|
|
87
|
+
* includePromptTrace → fullDebugEnabled (LLM prompt capture gate).
|
|
88
|
+
* enabled → debugEnabled (runtime debug traces).
|
|
89
|
+
* @param {Object|null|undefined} debugSection
|
|
90
|
+
* @returns {{ debugEnabled?: boolean, fullDebugEnabled?: boolean }}
|
|
91
|
+
*/
|
|
92
|
+
function mapRoleAssistantDebugToAssistantsSettings(debugSection) {
|
|
93
|
+
if (!debugSection || typeof debugSection !== 'object') {
|
|
94
|
+
return {};
|
|
95
|
+
}
|
|
96
|
+
const body = {};
|
|
97
|
+
if (typeof debugSection.enabled === 'boolean') {
|
|
98
|
+
body.debugEnabled = debugSection.enabled;
|
|
99
|
+
}
|
|
100
|
+
if (typeof debugSection.includePromptTrace === 'boolean') {
|
|
101
|
+
body.fullDebugEnabled = debugSection.includePromptTrace;
|
|
102
|
+
}
|
|
103
|
+
return body;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Push role-assistant.yaml knowledge + debug settings to dataplane Assistants.
|
|
84
108
|
* Called on upload/deploy so the operator UI and CLI stay aligned.
|
|
85
109
|
*/
|
|
86
|
-
|
|
110
|
+
function resolveAssistantSettingsPush(params) {
|
|
87
111
|
const {
|
|
88
112
|
systemKey,
|
|
89
|
-
dataplaneUrl,
|
|
90
|
-
authConfig,
|
|
91
113
|
environment = 'dev',
|
|
92
|
-
pathOptions = {}
|
|
93
|
-
dryRun = false
|
|
114
|
+
pathOptions = {}
|
|
94
115
|
} = params;
|
|
95
116
|
const settingsEnv = resolveRoleAssistantSettingsEnvKey(environment);
|
|
96
117
|
const settings = readRoleAssistantSettings(systemKey, { required: false, pathOptions });
|
|
97
118
|
if (!settings) {
|
|
98
|
-
return { skipped: true, reason: 'missing-role-assistant-settings' };
|
|
119
|
+
return { result: { skipped: true, reason: 'missing-role-assistant-settings' } };
|
|
99
120
|
}
|
|
100
121
|
const section = resolveRoleAssistantEnvironmentSettings(settings, settingsEnv, {
|
|
101
122
|
required: false
|
|
102
123
|
});
|
|
103
124
|
if (!section) {
|
|
104
|
-
return { skipped: true, reason: 'missing-env-settings' };
|
|
125
|
+
return { result: { skipped: true, reason: 'missing-env-settings' } };
|
|
105
126
|
}
|
|
106
127
|
const documentStorageKey =
|
|
107
128
|
resolveDocumentStorageKeyFromRoleAssistantSettings(settings, settingsEnv) || '';
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
dryRun: true,
|
|
112
|
-
documentStorageKey: documentStorageKey || null
|
|
113
|
-
};
|
|
129
|
+
const debugBody = mapRoleAssistantDebugToAssistantsSettings(section.debug);
|
|
130
|
+
if (!documentStorageKey && Object.keys(debugBody).length === 0) {
|
|
131
|
+
return { result: { skipped: true, reason: 'no-document-storage-key', documentStorageKey: null } };
|
|
114
132
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
133
|
+
const patchBody = { ...debugBody };
|
|
134
|
+
if (documentStorageKey) {
|
|
135
|
+
patchBody.documentStorageKey = documentStorageKey;
|
|
136
|
+
}
|
|
137
|
+
return { documentStorageKey, debugBody, patchBody };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function applyAssistantSettingsPush(dataplaneUrl, systemKey, authConfig, settingsPush) {
|
|
141
|
+
const { documentStorageKey, debugBody, patchBody } = settingsPush;
|
|
142
|
+
const hasDocumentStorageKey = documentStorageKey !== '';
|
|
143
|
+
const hasDebugSettings = Object.keys(debugBody).length > 0;
|
|
144
|
+
let response = await updateAssistantSettings(
|
|
145
|
+
dataplaneUrl,
|
|
146
|
+
systemKey,
|
|
147
|
+
authConfig,
|
|
148
|
+
patchBody
|
|
149
|
+
);
|
|
150
|
+
if (response && response.success === false && hasDocumentStorageKey && hasDebugSettings) {
|
|
151
|
+
response = await updateAssistantSettings(
|
|
152
|
+
dataplaneUrl,
|
|
153
|
+
systemKey,
|
|
154
|
+
authConfig,
|
|
155
|
+
debugBody
|
|
156
|
+
);
|
|
157
|
+
if (response && response.success === false) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
response.formattedError ||
|
|
160
|
+
response.error ||
|
|
161
|
+
'Failed to update Assistants debug settings'
|
|
162
|
+
);
|
|
163
|
+
}
|
|
118
164
|
return {
|
|
119
|
-
skipped:
|
|
120
|
-
|
|
121
|
-
|
|
165
|
+
skipped: false,
|
|
166
|
+
documentStorageKey: null,
|
|
167
|
+
documentStoragePushFailed: true,
|
|
168
|
+
...debugBody
|
|
122
169
|
};
|
|
123
170
|
}
|
|
124
|
-
if (!dataplaneUrl || !authConfig) {
|
|
125
|
-
return { skipped: true, reason: 'missing-dataplane-auth' };
|
|
126
|
-
}
|
|
127
|
-
const response = await updateAssistantSettings(dataplaneUrl, systemKey, authConfig, {
|
|
128
|
-
documentStorageKey
|
|
129
|
-
});
|
|
130
171
|
if (response && response.success === false) {
|
|
131
172
|
throw new Error(
|
|
132
173
|
response.formattedError ||
|
|
@@ -136,10 +177,27 @@ async function pushRoleAssistantDocumentStorageSettings(params) {
|
|
|
136
177
|
}
|
|
137
178
|
return {
|
|
138
179
|
skipped: false,
|
|
139
|
-
documentStorageKey: documentStorageKey || null
|
|
180
|
+
documentStorageKey: documentStorageKey || null,
|
|
181
|
+
...debugBody
|
|
140
182
|
};
|
|
141
183
|
}
|
|
142
184
|
|
|
185
|
+
async function pushRoleAssistantDocumentStorageSettings(params) {
|
|
186
|
+
const { systemKey, dataplaneUrl, authConfig, dryRun = false } = params;
|
|
187
|
+
const settingsPush = resolveAssistantSettingsPush(params);
|
|
188
|
+
if (settingsPush.result) {
|
|
189
|
+
return settingsPush.result;
|
|
190
|
+
}
|
|
191
|
+
const { documentStorageKey, debugBody } = settingsPush;
|
|
192
|
+
if (dryRun) {
|
|
193
|
+
return { skipped: false, dryRun: true, documentStorageKey: documentStorageKey || null, ...debugBody };
|
|
194
|
+
}
|
|
195
|
+
if (!dataplaneUrl || !authConfig) {
|
|
196
|
+
return { skipped: true, reason: 'missing-dataplane-auth' };
|
|
197
|
+
}
|
|
198
|
+
return applyAssistantSettingsPush(dataplaneUrl, systemKey, authConfig, settingsPush);
|
|
199
|
+
}
|
|
200
|
+
|
|
143
201
|
/**
|
|
144
202
|
* Resolve Knowledge document storage key.
|
|
145
203
|
* Order: role-assistant.yaml → dataplane Assistants settings → package dataSources.
|
|
@@ -408,74 +466,11 @@ async function exportRoleAssistantKnowledge(params) {
|
|
|
408
466
|
return { skipped: false, datasourceKey, count: rows.length, knowledgePath, settingsPath };
|
|
409
467
|
}
|
|
410
468
|
|
|
411
|
-
function logKnowledgeImportSummary(systemKey, result, options = {}) {
|
|
412
|
-
if (result.skipped) {
|
|
413
|
-
if (options.verbose === true) {
|
|
414
|
-
logger.log(metadata(`Knowledge sync skipped (${systemKey}): ${result.reason}`));
|
|
415
|
-
}
|
|
416
|
-
return;
|
|
417
|
-
}
|
|
418
|
-
if (result.dryRun) {
|
|
419
|
-
logger.log(
|
|
420
|
-
formatWarningLine(
|
|
421
|
-
`Role assistant knowledge dry-run: ${result.fileCount} file(s), ${result.recordCount} record(s), datasource ${result.datasourceKey}`
|
|
422
|
-
)
|
|
423
|
-
);
|
|
424
|
-
return;
|
|
425
|
-
}
|
|
426
|
-
logger.log(
|
|
427
|
-
formatSuccessLine(
|
|
428
|
-
`Role assistant knowledge synced (${result.datasourceKey}): ${result.recordCount} record(s) from ${result.fileCount} file(s).`
|
|
429
|
-
)
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
function logDocumentStorageSettingsPushSummary(systemKey, result, options = {}) {
|
|
434
|
-
if (result.skipped) {
|
|
435
|
-
if (options.verbose === true) {
|
|
436
|
-
logger.log(
|
|
437
|
-
metadata(`Knowledge document storage settings skipped (${systemKey}): ${result.reason}`)
|
|
438
|
-
);
|
|
439
|
-
}
|
|
440
|
-
return;
|
|
441
|
-
}
|
|
442
|
-
if (result.dryRun) {
|
|
443
|
-
logger.log(
|
|
444
|
-
formatWarningLine(
|
|
445
|
-
`Knowledge document storage settings dry-run (${systemKey}): ${
|
|
446
|
-
result.documentStorageKey || '(clear)'
|
|
447
|
-
}`
|
|
448
|
-
)
|
|
449
|
-
);
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
logger.log(
|
|
453
|
-
formatSuccessLine(
|
|
454
|
-
`Knowledge document storage settings updated (${systemKey}): ${
|
|
455
|
-
result.documentStorageKey || '(cleared)'
|
|
456
|
-
}`
|
|
457
|
-
)
|
|
458
|
-
);
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
function logKnowledgeExportSummary(systemKey, result, options = {}) {
|
|
462
|
-
if (result.skipped) {
|
|
463
|
-
if (options.verbose === true) {
|
|
464
|
-
logger.log(metadata(`Knowledge export skipped (${systemKey}): ${result.reason}`));
|
|
465
|
-
}
|
|
466
|
-
return;
|
|
467
|
-
}
|
|
468
|
-
logger.log(
|
|
469
|
-
formatSuccessLine(
|
|
470
|
-
`Role assistant knowledge exported (${result.datasourceKey}): ${result.count} document(s) to ${result.knowledgePath}.`
|
|
471
|
-
)
|
|
472
|
-
);
|
|
473
|
-
}
|
|
474
|
-
|
|
475
469
|
module.exports = {
|
|
476
470
|
isDigitalWorkerModel,
|
|
477
471
|
resolveRoleAssistantSettingsEnvKey,
|
|
478
472
|
resolveRoleAssistantDocumentStorageKey,
|
|
473
|
+
mapRoleAssistantDebugToAssistantsSettings,
|
|
479
474
|
pushRoleAssistantDocumentStorageSettings,
|
|
480
475
|
importRoleAssistantKnowledge,
|
|
481
476
|
exportRoleAssistantKnowledge,
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Evaluate expected.bid assertions for suite 002 hard GP.
|
|
3
|
+
* @fileoverview BID emission / apply expectation checks
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
function asArray(value) {
|
|
9
|
+
return Array.isArray(value) ? value : [];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
function softWrap(assertion, soft) {
|
|
13
|
+
if (!assertion || assertion.passed || !soft) {
|
|
14
|
+
return assertion;
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
...assertion,
|
|
18
|
+
passed: true,
|
|
19
|
+
soft: true,
|
|
20
|
+
warn: true,
|
|
21
|
+
message: `${assertion.message} (soft — warning only)`
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function findInteraction(interactions, type) {
|
|
26
|
+
return asArray(interactions).find((row) => row && row.type === type) || null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function pushBidAssertion(assertions, soft, id, passed, okMsg, failMsg) {
|
|
30
|
+
assertions.push(
|
|
31
|
+
softWrap(
|
|
32
|
+
{
|
|
33
|
+
id,
|
|
34
|
+
passed,
|
|
35
|
+
message: passed ? okMsg : failMsg
|
|
36
|
+
},
|
|
37
|
+
soft
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function hasEmitOrApply(observed) {
|
|
43
|
+
return Boolean(observed.emitRow || observed.applyRow || observed.emitted);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function collectBidSchemaAssertions(expectedBid, observed, assertions, soft) {
|
|
47
|
+
const { emitRow, applyRow, emitted } = observed;
|
|
48
|
+
if (expectedBid.schemaName) {
|
|
49
|
+
const actualSchema = (emitted && emitted.schemaName) || expectedBid.schemaName;
|
|
50
|
+
pushBidAssertion(
|
|
51
|
+
assertions,
|
|
52
|
+
soft,
|
|
53
|
+
'expected.bid.schemaName',
|
|
54
|
+
hasEmitOrApply(observed) && actualSchema === expectedBid.schemaName,
|
|
55
|
+
`BID schemaName observed (${expectedBid.schemaName}).`,
|
|
56
|
+
`BID schemaName "${expectedBid.schemaName}" not observed in suite emit/apply.`
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
if (expectedBid.schemaVersion) {
|
|
60
|
+
const version = emitted && emitted.schemaVersion;
|
|
61
|
+
const versionOk =
|
|
62
|
+
version === null || version === undefined || version === expectedBid.schemaVersion;
|
|
63
|
+
pushBidAssertion(
|
|
64
|
+
assertions,
|
|
65
|
+
soft,
|
|
66
|
+
'expected.bid.schemaVersion',
|
|
67
|
+
hasEmitOrApply({ emitRow, applyRow, emitted }) && versionOk,
|
|
68
|
+
`BID schemaVersion "${expectedBid.schemaVersion}" accepted.`,
|
|
69
|
+
`BID schemaVersion "${expectedBid.schemaVersion}" not observed.`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function assertDefinitionHash(expectedBid, observed, assertions, soft) {
|
|
75
|
+
if (expectedBid.requireDefinitionHash !== true) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const { emitRow, applyRow, emitted } = observed;
|
|
79
|
+
const hash =
|
|
80
|
+
(emitted && emitted.definitionHash) ||
|
|
81
|
+
(emitRow && emitRow.definitionHash) ||
|
|
82
|
+
(applyRow && applyRow.definitionHash) ||
|
|
83
|
+
'';
|
|
84
|
+
pushBidAssertion(
|
|
85
|
+
assertions,
|
|
86
|
+
soft,
|
|
87
|
+
'expected.bid.requireDefinitionHash',
|
|
88
|
+
typeof hash === 'string' && hash.startsWith('sha256:'),
|
|
89
|
+
`BID definitionHash present (${String(hash).slice(0, 18)}…).`,
|
|
90
|
+
'BID definitionHash (sha256:…) not observed on emit/apply.'
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function assertSuiteRunId(expectedBid, observed, assertions, soft) {
|
|
95
|
+
if (expectedBid.requireSuiteRunId !== true) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const { emitRow, applyRow, emitted } = observed;
|
|
99
|
+
const suiteRunId =
|
|
100
|
+
(emitted && emitted.meta && emitted.meta.suiteRunId) ||
|
|
101
|
+
(emitRow && emitRow.suiteRunId) ||
|
|
102
|
+
(applyRow && applyRow.suiteRunId) ||
|
|
103
|
+
'';
|
|
104
|
+
pushBidAssertion(
|
|
105
|
+
assertions,
|
|
106
|
+
soft,
|
|
107
|
+
'expected.bid.requireSuiteRunId',
|
|
108
|
+
Boolean(String(suiteRunId).trim()),
|
|
109
|
+
`BID suiteRunId present (${suiteRunId}).`,
|
|
110
|
+
'BID meta.suiteRunId not observed on emit/apply.'
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function collectBidProvenanceAssertions(expectedBid, observed, assertions, soft) {
|
|
115
|
+
assertDefinitionHash(expectedBid, observed, assertions, soft);
|
|
116
|
+
assertSuiteRunId(expectedBid, observed, assertions, soft);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function collectBidPathAssertions(expectedBid, observed, assertions, soft) {
|
|
120
|
+
if (expectedBid.forbidGoldPaths === true) {
|
|
121
|
+
const { emitRow, applyRow, emitted } = observed;
|
|
122
|
+
const blob = JSON.stringify(emitted || emitRow || applyRow || {});
|
|
123
|
+
const banned = /test-e2e-hubspot|knownPlatform|gold-package/i.test(blob);
|
|
124
|
+
pushBidAssertion(
|
|
125
|
+
assertions,
|
|
126
|
+
soft,
|
|
127
|
+
'expected.bid.forbidGoldPaths',
|
|
128
|
+
!banned,
|
|
129
|
+
'BID trail has no gold/knownPlatform generation paths.',
|
|
130
|
+
'BID trail references forbidden gold/knownPlatform generation paths.'
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function collectBidAssertions(expectedBid, observation, options = {}) {
|
|
136
|
+
if (!expectedBid || typeof expectedBid !== 'object') {
|
|
137
|
+
return [];
|
|
138
|
+
}
|
|
139
|
+
const interactions = asArray(observation.interactions || observation.workInteractions);
|
|
140
|
+
const observed = {
|
|
141
|
+
emitRow: findInteraction(interactions, 'bid-emit'),
|
|
142
|
+
applyRow: findInteraction(interactions, 'bid-apply'),
|
|
143
|
+
emitted: observation.emittedBid || null
|
|
144
|
+
};
|
|
145
|
+
const assertions = [];
|
|
146
|
+
const soft = options.soft === true;
|
|
147
|
+
collectBidSchemaAssertions(expectedBid, observed, assertions, soft);
|
|
148
|
+
collectBidProvenanceAssertions(expectedBid, observed, assertions, soft);
|
|
149
|
+
collectBidPathAssertions(expectedBid, observed, assertions, soft);
|
|
150
|
+
return assertions;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
module.exports = {
|
|
154
|
+
collectBidAssertions
|
|
155
|
+
};
|
|
@@ -9,6 +9,7 @@ const {
|
|
|
9
9
|
buildHonestyObservation,
|
|
10
10
|
evaluateHonestyExpectations
|
|
11
11
|
} = require('./test-cases-honesty');
|
|
12
|
+
const { collectBidAssertions } = require('./test-cases-bid');
|
|
12
13
|
|
|
13
14
|
function getValueAtPath(obj, dottedPath) {
|
|
14
15
|
const parts = String(dottedPath || '').split('.').filter(Boolean);
|
|
@@ -109,7 +110,13 @@ function buildCaseObservation(result, lifecycleVerdict, portalUrl) {
|
|
|
109
110
|
processExecutionId: result?.processExecutionId || null,
|
|
110
111
|
workResult,
|
|
111
112
|
workResultError: result?.workResultError || null,
|
|
112
|
-
honesty: buildHonestyObservation(workResult)
|
|
113
|
+
honesty: buildHonestyObservation(workResult),
|
|
114
|
+
interactions: Array.isArray(result?.interactions)
|
|
115
|
+
? result.interactions
|
|
116
|
+
: Array.isArray(result?.workInteractions)
|
|
117
|
+
? result.workInteractions
|
|
118
|
+
: [],
|
|
119
|
+
emittedBid: result?.emittedBid || null
|
|
113
120
|
};
|
|
114
121
|
}
|
|
115
122
|
|
|
@@ -146,6 +153,7 @@ function collectCaseAssertions(expected, observation) {
|
|
|
146
153
|
assertions.push(...evaluateFactExpectations(expected.facts, observation));
|
|
147
154
|
assertions.push(...evaluateProhibitedExpectations(expected.prohibited, observation));
|
|
148
155
|
assertions.push(...evaluateHonestyExpectations(expected.honesty, observation, { soft }));
|
|
156
|
+
assertions.push(...collectBidAssertions(expected.bid, observation, { soft }));
|
|
149
157
|
return assertions;
|
|
150
158
|
}
|
|
151
159
|
|