@aifabrix/builder 2.45.0 → 2.45.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (180) hide show
  1. package/.cursor/rules/docs-rules.mdc +3 -1
  2. package/integration/hubspot-test/test-artifacts/wizard-hubspot-credential-real.yaml +1 -1
  3. package/integration/hubspot-test/test-artifacts/wizard-hubspot-env-vars.yaml +1 -1
  4. package/integration/hubspot-test/wizard-hubspot-e2e.yaml +1 -1
  5. package/jest.projects.js +44 -1
  6. package/lib/api/agent-metadata-validation.api.js +93 -0
  7. package/lib/api/audit-api-helpers.js +68 -0
  8. package/lib/api/audit.api.js +119 -0
  9. package/lib/api/auth-cache.api.js +44 -0
  10. package/lib/api/certificates.api.js +4 -4
  11. package/lib/api/credential.api.js +2 -2
  12. package/lib/api/dataplane-health.api.js +137 -0
  13. package/lib/api/dataplane-sync.api.js +27 -0
  14. package/lib/api/datasources-core.api.js +21 -18
  15. package/lib/api/datasources-extended.api.js +22 -22
  16. package/lib/api/dimensions.api.js +3 -0
  17. package/lib/api/external-systems.api.js +13 -13
  18. package/lib/api/governance-scenarios.api.js +39 -0
  19. package/lib/api/groups.api.js +79 -0
  20. package/lib/api/index.js +45 -2
  21. package/lib/api/pipeline.api.js +4 -4
  22. package/lib/api/protection.api.js +157 -0
  23. package/lib/api/records-bulk.api.js +30 -0
  24. package/lib/api/records-search-parse.js +49 -0
  25. package/lib/api/records-search.api.js +29 -0
  26. package/lib/api/types/agent-metadata-validation.types.js +67 -0
  27. package/lib/api/types/audit.types.js +72 -0
  28. package/lib/api/types/dataplane-health.types.js +27 -0
  29. package/lib/api/types/dimensions.types.js +2 -0
  30. package/lib/api/types/governance-scenarios.types.js +39 -0
  31. package/lib/api/types/protection.types.js +69 -0
  32. package/lib/api/types/records-bulk.types.js +35 -0
  33. package/lib/api/types/records-search.types.js +28 -0
  34. package/lib/api/user-groups.api.js +50 -0
  35. package/lib/api/users.api.js +95 -0
  36. package/lib/api/validation-run.api.js +3 -3
  37. package/lib/api/validation-runner.js +3 -3
  38. package/lib/api/wizard-platform.api.js +3 -3
  39. package/lib/api/wizard.api.js +21 -21
  40. package/lib/app/deploy.js +34 -19
  41. package/lib/cli/index.js +4 -2
  42. package/lib/cli/infra-guided.js +22 -3
  43. package/lib/cli/setup-app.help.js +50 -2
  44. package/lib/cli/setup-app.js +33 -24
  45. package/lib/cli/setup-app.test-commands.js +80 -21
  46. package/lib/cli/setup-auth.js +30 -3
  47. package/lib/cli/setup-external-system.js +37 -3
  48. package/lib/cli/setup-utility-help-after.js +45 -0
  49. package/lib/cli/setup-utility-resolve.js +2 -2
  50. package/lib/cli/setup-utility.js +99 -81
  51. package/lib/commands/auth-status-dataplane-version.js +231 -0
  52. package/lib/commands/auth-status-display.js +94 -0
  53. package/lib/commands/auth-status.js +70 -6
  54. package/lib/commands/credential-push.js +10 -5
  55. package/lib/commands/datasource-load-export-cli.js +178 -0
  56. package/lib/commands/datasource-test-trust-cli.js +114 -0
  57. package/lib/commands/datasource-unified-test-cli.js +25 -17
  58. package/lib/commands/datasource-unified-test-cli.options.js +18 -3
  59. package/lib/commands/datasource-unified-test-e2e-cli-helpers.js +5 -5
  60. package/lib/commands/datasource-verify-audit-cli.js +96 -0
  61. package/lib/commands/datasource.js +68 -1
  62. package/lib/commands/dimension-value.js +43 -13
  63. package/lib/commands/dimension.js +38 -7
  64. package/lib/commands/identity-apply-sync.js +131 -0
  65. package/lib/commands/identity-group-cli.js +146 -0
  66. package/lib/commands/identity-membership-role-cache.js +175 -0
  67. package/lib/commands/identity-shared.js +94 -0
  68. package/lib/commands/identity-user-cli.js +158 -0
  69. package/lib/commands/identity.js +43 -0
  70. package/lib/commands/login.js +46 -16
  71. package/lib/commands/protection-cli-leaves.js +286 -0
  72. package/lib/commands/protection.js +50 -0
  73. package/lib/commands/repair.js +13 -3
  74. package/lib/commands/test-e2e-external.js +40 -9
  75. package/lib/commands/test-governance-cli-options.js +47 -0
  76. package/lib/commands/test-governance-command-action.js +55 -0
  77. package/lib/commands/test-governance-external.js +88 -0
  78. package/lib/commands/test-trust-cli-options.js +32 -0
  79. package/lib/commands/test-trust-command-action.js +118 -0
  80. package/lib/commands/test-trust-external.js +127 -0
  81. package/lib/commands/upload.js +34 -13
  82. package/lib/commands/wizard-core.js +3 -0
  83. package/lib/core/config-device-dataplane.js +185 -0
  84. package/lib/datasource/agent-trust-debug-log.js +45 -0
  85. package/lib/datasource/agent-trust-fetch.js +115 -0
  86. package/lib/datasource/agent-trust-map.js +101 -0
  87. package/lib/datasource/agent-trust-mock.js +44 -0
  88. package/lib/datasource/agent-trust-run.js +93 -0
  89. package/lib/datasource/agent-trust-timeout.js +25 -0
  90. package/lib/datasource/audit-evidence-display.js +80 -0
  91. package/lib/datasource/audit-evidence-extract-debug.js +103 -0
  92. package/lib/datasource/audit-evidence-extract.js +177 -0
  93. package/lib/datasource/audit-evidence-matrix-rows.js +158 -0
  94. package/lib/datasource/audit-evidence-operation-aliases.js +63 -0
  95. package/lib/datasource/audit-evidence-poll.js +109 -0
  96. package/lib/datasource/audit-evidence-run.js +177 -0
  97. package/lib/datasource/audit-evidence-verify-helpers.js +167 -0
  98. package/lib/datasource/audit-evidence-verify-matrix.js +177 -0
  99. package/lib/datasource/audit-evidence-verify.js +108 -0
  100. package/lib/datasource/bulk-loader-run-batches.js +88 -0
  101. package/lib/datasource/bulk-loader-service-retry.js +52 -0
  102. package/lib/datasource/bulk-loader-service.js +127 -0
  103. package/lib/datasource/capability/run-capability-dimension.js +2 -1
  104. package/lib/datasource/datasource-exporter-resolve.js +82 -0
  105. package/lib/datasource/datasource-exporter-service.js +144 -0
  106. package/lib/datasource/datasource-identifier.js +148 -0
  107. package/lib/datasource/datasource-load-export-context.js +92 -0
  108. package/lib/datasource/integration-context.js +6 -4
  109. package/lib/datasource/local-data-paths.js +145 -0
  110. package/lib/datasource/log-cleaner.js +241 -0
  111. package/lib/datasource/log-viewer.js +111 -6
  112. package/lib/datasource/record-file-parser.js +85 -0
  113. package/lib/datasource/record-mapper.js +129 -0
  114. package/lib/datasource/resolve-app.js +74 -55
  115. package/lib/datasource/test-e2e.js +26 -2
  116. package/lib/datasource/unified-validation-run-resolve.js +45 -12
  117. package/lib/datasource/unified-validation-run.js +43 -17
  118. package/lib/datasource/validate.js +37 -20
  119. package/lib/external-system/test-system-level.js +25 -4
  120. package/lib/external-system/test.js +3 -1
  121. package/lib/governance/governance-pack-loader.js +70 -0
  122. package/lib/governance/governance-run-display.js +119 -0
  123. package/lib/identity/identity-apply-core.js +108 -0
  124. package/lib/identity/identity-apply-phases.js +244 -0
  125. package/lib/identity/identity-apply-service.js +77 -0
  126. package/lib/identity/identity-csv-parser.js +114 -0
  127. package/lib/internal/fs-real-sync.js +29 -1
  128. package/lib/protection/auth-context.js +45 -0
  129. package/lib/protection/convert-batch.js +90 -0
  130. package/lib/protection/load.js +41 -0
  131. package/lib/protection/paths.js +158 -0
  132. package/lib/protection/preflight-datasource-ready.js +46 -0
  133. package/lib/protection/protection-create-probe-lines.js +142 -0
  134. package/lib/protection/protection-create-probes.js +95 -0
  135. package/lib/protection/protection-create-scaffold.js +281 -0
  136. package/lib/protection/protection-display-helpers.js +445 -0
  137. package/lib/protection/protection-display.js +215 -0
  138. package/lib/protection/protection-preset-registry.js +97 -0
  139. package/lib/protection/report-exit.js +62 -0
  140. package/lib/protection/resolve.js +202 -0
  141. package/lib/protection/run-commands-validate.js +130 -0
  142. package/lib/protection/run-commands.js +216 -0
  143. package/lib/protection/run-protection-create-helpers.js +134 -0
  144. package/lib/protection/run-protection-create-probes-flow.js +43 -0
  145. package/lib/protection/run-protection-create.js +191 -0
  146. package/lib/protection/scope.js +22 -0
  147. package/lib/protection/sync-after-upload.js +64 -0
  148. package/lib/protection/upload-batch.js +127 -0
  149. package/lib/protection/validate-batch.js +113 -0
  150. package/lib/protection/validate-local.js +65 -0
  151. package/lib/resolvers/dimension-file.js +29 -4
  152. package/lib/schema/external-datasource.schema.json +47 -13
  153. package/lib/schema/flag-map-validation-run.json +2 -2
  154. package/lib/schema/protection.schema.json +374 -0
  155. package/lib/schema/type/credential-field-registry.json +636 -0
  156. package/lib/schema/wizard-config.schema.json +1 -1
  157. package/lib/utils/agent-trust-run-display.js +231 -0
  158. package/lib/utils/agent-trust-run-exit.js +59 -0
  159. package/lib/utils/agent-trust-wait-ui.js +94 -0
  160. package/lib/utils/cli-exit-codes.js +30 -0
  161. package/lib/utils/cli-sync-options.js +33 -0
  162. package/lib/utils/credential-push-ui.js +90 -0
  163. package/lib/utils/dataplane-cli-version-gate.js +202 -0
  164. package/lib/utils/dataplane-cli-version-help.js +74 -0
  165. package/lib/utils/datasource-export-display.js +137 -0
  166. package/lib/utils/datasource-load-display.js +174 -0
  167. package/lib/utils/datasource-load-export-ui.js +120 -0
  168. package/lib/utils/datasource-test-run-capability-scope.js +3 -3
  169. package/lib/utils/datasource-test-run-display.js +3 -3
  170. package/lib/utils/datasource-test-run-tty-log.js +5 -1
  171. package/lib/utils/help-builder.js +30 -24
  172. package/lib/utils/manifest-source-emit.js +22 -0
  173. package/lib/utils/semver-compare.js +127 -0
  174. package/lib/utils/upload-pipeline-ui.js +91 -0
  175. package/lib/utils/validation-poll-ui.js +14 -7
  176. package/lib/validation/wizard-config-validator.js +58 -19
  177. package/package.json +1 -1
  178. package/templates/applications/dataplane/env.template +13 -1
  179. package/templates/applications/dataplane/rbac.yaml +4 -0
  180. package/templates/external-system/README.md.hbs +56 -8
@@ -0,0 +1,115 @@
1
+ /**
2
+ * @fileoverview Dataplane fetch paths for agent trust runs (POST validate / GET latest).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const {
8
+ runAgentMetadataValidation,
9
+ getLatestAgentMetadataValidation
10
+ } = require('../api/agent-metadata-validation.api');
11
+ const { parseTrustTimeoutMs } = require('./agent-trust-timeout');
12
+ const { isAgentTrustMockEnabled, buildMockTrustRun } = require('./agent-trust-mock');
13
+ const { mapRunResponseToTrustRun, mapLatestResultToTrustRun } = require('./agent-trust-map');
14
+ const {
15
+ runWithAgentTrustWaitSpinner,
16
+ logAgentTrustWaitHintOnce
17
+ } = require('../utils/agent-trust-wait-ui');
18
+
19
+ function unwrapApiData(response) {
20
+ if (response && response.data !== undefined) return response.data;
21
+ return response;
22
+ }
23
+
24
+ /**
25
+ * @param {Object} options
26
+ * @returns {boolean}
27
+ */
28
+ function shouldPreferLatestRead(options = {}) {
29
+ if (options.revalidate === true) return false;
30
+ return options.summary === true;
31
+ }
32
+
33
+ /**
34
+ * @param {Error} err
35
+ * @returns {boolean}
36
+ */
37
+ function isLatestNotFoundError(err) {
38
+ const code = err && (err.statusCode || err.status);
39
+ if (code === 404) return true;
40
+ const msg = err && err.message ? String(err.message) : '';
41
+ return /no agent metadata validation/i.test(msg);
42
+ }
43
+
44
+ /**
45
+ * @async
46
+ * @param {Object} params
47
+ * @returns {Promise<Object>}
48
+ */
49
+ async function postValidateTrustRun(params) {
50
+ const { dataplaneUrl, datasourceKey, systemKey, authConfig, body, options } = params;
51
+ const timeoutMs = parseTrustTimeoutMs(options);
52
+ logAgentTrustWaitHintOnce(datasourceKey, timeoutMs);
53
+ const raw = await runWithAgentTrustWaitSpinner(
54
+ () =>
55
+ runAgentMetadataValidation(dataplaneUrl, datasourceKey, authConfig, body, { timeoutMs }),
56
+ { datasourceKey, timeoutMs }
57
+ );
58
+ return mapRunResponseToTrustRun({
59
+ datasourceKey,
60
+ systemKey,
61
+ runResponse: unwrapApiData(raw)
62
+ });
63
+ }
64
+
65
+ /**
66
+ * @async
67
+ * @param {Object} params
68
+ * @returns {Promise<Object>}
69
+ */
70
+ async function getLatestTrustRun(params) {
71
+ const { dataplaneUrl, datasourceKey, systemKey, authConfig, options } = params;
72
+ const timeoutMs = parseTrustTimeoutMs(options);
73
+ const raw = await getLatestAgentMetadataValidation(dataplaneUrl, datasourceKey, authConfig, {
74
+ timeoutMs
75
+ });
76
+ return mapLatestResultToTrustRun({
77
+ datasourceKey,
78
+ systemKey,
79
+ latestResult: unwrapApiData(raw)
80
+ });
81
+ }
82
+
83
+ /**
84
+ * @async
85
+ * @param {Object} params
86
+ * @returns {Promise<Object>}
87
+ */
88
+ async function fetchTrustRunFromDataplane(params) {
89
+ const { datasourceKey, systemKey, dataplaneUrl, authConfig, options } = params;
90
+ if (isAgentTrustMockEnabled()) {
91
+ return buildMockTrustRun(datasourceKey, systemKey);
92
+ }
93
+
94
+ const body = { forceRevalidate: options.revalidate === true };
95
+ if (options.peerDatasourceConfigs && typeof options.peerDatasourceConfigs === 'object') {
96
+ body.peerDatasourceConfigs = options.peerDatasourceConfigs;
97
+ }
98
+
99
+ if (!shouldPreferLatestRead(options)) {
100
+ return postValidateTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, body, options });
101
+ }
102
+
103
+ try {
104
+ return await getLatestTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, options });
105
+ } catch (err) {
106
+ if (!isLatestNotFoundError(err)) throw err;
107
+ return postValidateTrustRun({ dataplaneUrl, datasourceKey, systemKey, authConfig, body, options });
108
+ }
109
+ }
110
+
111
+ module.exports = {
112
+ shouldPreferLatestRead,
113
+ fetchTrustRunFromDataplane,
114
+ isLatestNotFoundError
115
+ };
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @fileoverview Map dataplane agent metadata validation API payloads to CLI trust runs.
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * @param {string} trustDecision
11
+ * @returns {'ok'|'warn'|'fail'}
12
+ */
13
+ function trustDecisionToRowStatus(trustDecision) {
14
+ const td = String(trustDecision || '').trim();
15
+ if (td === 'trusted') return 'ok';
16
+ if (td === 'usableWithWarnings') return 'warn';
17
+ return 'fail';
18
+ }
19
+
20
+ /**
21
+ * @param {Object} result - AgentMetadataValidationResult from dataplane
22
+ * @returns {string[]}
23
+ */
24
+ function highLevelWarningsFromResult(result) {
25
+ if (!result || !Array.isArray(result.findings)) return [];
26
+ return result.findings
27
+ .filter(f => f && (f.severity === 'warning' || f.severity === 'error'))
28
+ .slice(0, 8)
29
+ .map(f => {
30
+ const code = f.code ? String(f.code) : 'FINDING';
31
+ const msg = f.message ? String(f.message) : '';
32
+ return msg ? `${code} — ${msg}` : code;
33
+ });
34
+ }
35
+
36
+ /**
37
+ * @param {Object} params
38
+ * @param {string} params.datasourceKey
39
+ * @param {string} params.systemKey
40
+ * @param {Object} params.runResponse - POST run response body
41
+ * @returns {Object} AgentTrustRun-shaped object for CLI display/exit
42
+ */
43
+ function mapRunResponseToTrustRun({ datasourceKey, systemKey, runResponse }) {
44
+ const body = runResponse && typeof runResponse === 'object' ? runResponse : {};
45
+ const result = body.result && typeof body.result === 'object' ? body.result : {};
46
+ const trustDecision = result.trustDecision || 'pending';
47
+ return {
48
+ datasourceKey,
49
+ systemKey,
50
+ status: trustDecisionToRowStatus(trustDecision),
51
+ trustDecision,
52
+ validationStatus: result.status || 'pending',
53
+ confidence: typeof result.confidence === 'number' ? result.confidence : 0,
54
+ summary: result.summary || '',
55
+ validatedAt: result.validatedAt || '',
56
+ inputHash: result.inputHash || '',
57
+ contractVersion: result.contractVersion || '',
58
+ cacheHit: body.reused === true,
59
+ highLevelWarnings: highLevelWarningsFromResult(result),
60
+ findings: Array.isArray(result.findings) ? result.findings : [],
61
+ observedBusinessModel: result.observedBusinessModel || null,
62
+ runId: body.id || null
63
+ };
64
+ }
65
+
66
+ /**
67
+ * @param {Object} params
68
+ * @param {string} params.datasourceKey
69
+ * @param {string} params.systemKey
70
+ * @param {Object} params.latestResult - GET /agent-validation body
71
+ * @returns {Object}
72
+ */
73
+ function mapLatestResultToTrustRun({ datasourceKey, systemKey, latestResult }) {
74
+ const result = latestResult && typeof latestResult === 'object' ? latestResult : {};
75
+ const trustDecision = result.trustDecision || 'pending';
76
+ return {
77
+ datasourceKey,
78
+ systemKey,
79
+ status: trustDecisionToRowStatus(trustDecision),
80
+ trustDecision,
81
+ validationStatus: result.status || 'pending',
82
+ confidence: typeof result.confidence === 'number' ? result.confidence : 0,
83
+ summary: result.summary || '',
84
+ validatedAt: result.validatedAt || '',
85
+ inputHash: result.inputHash || '',
86
+ contractVersion: result.contractVersion || '',
87
+ cacheHit: true,
88
+ highLevelWarnings: highLevelWarningsFromResult(result),
89
+ findings: Array.isArray(result.findings) ? result.findings : [],
90
+ observedBusinessModel: result.observedBusinessModel || null,
91
+ runId: null,
92
+ readLatest: true
93
+ };
94
+ }
95
+
96
+ module.exports = {
97
+ trustDecisionToRowStatus,
98
+ highLevelWarningsFromResult,
99
+ mapRunResponseToTrustRun,
100
+ mapLatestResultToTrustRun
101
+ };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * @fileoverview Dev-only mock trust runs when AIFABRIX_AGENT_TRUST_MOCK=1 (plan 143).
3
+ * Not documented in user-facing CLI docs; for local CLI development without dataplane 404.5.
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ /**
9
+ * @returns {boolean}
10
+ */
11
+ function isAgentTrustMockEnabled() {
12
+ return String(process.env.AIFABRIX_AGENT_TRUST_MOCK || '').trim() === '1';
13
+ }
14
+
15
+ /**
16
+ * @param {string} datasourceKey
17
+ * @param {string} systemKey
18
+ * @returns {Object}
19
+ */
20
+ function buildMockTrustRun(datasourceKey, systemKey) {
21
+ return {
22
+ datasourceKey,
23
+ systemKey,
24
+ status: 'warn',
25
+ trustDecision: 'usableWithWarnings',
26
+ validationStatus: 'warning',
27
+ confidence: 0.72,
28
+ summary: 'Mock trust run (AIFABRIX_AGENT_TRUST_MOCK=1)',
29
+ validatedAt: new Date().toISOString(),
30
+ inputHash: 'mock-input-hash',
31
+ contractVersion: '1.0.0',
32
+ cacheHit: false,
33
+ highLevelWarnings: ['MOCK_TRUST — set AIFABRIX_AGENT_TRUST_MOCK=0 for live dataplane validation'],
34
+ findings: [],
35
+ observedBusinessModel: null,
36
+ runId: 'mock-run-id',
37
+ mock: true
38
+ };
39
+ }
40
+
41
+ module.exports = {
42
+ isAgentTrustMockEnabled,
43
+ buildMockTrustRun
44
+ };
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @fileoverview Run dataplane agent metadata validation for one datasource (404.5 / plan 143).
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const chalk = require('chalk');
10
+ const logger = require('../utils/logger');
11
+ const { formatSuccessLine } = require('../utils/cli-test-layout-chalk');
12
+ const { getConfig } = require('../core/config');
13
+ const { setupIntegrationTestAuth } = require('../external-system/test-auth');
14
+ const { resolveAppKeyForDatasource } = require('./resolve-app');
15
+ const { getSystemKeyFromAppKey } = require('./integration-context');
16
+ const { requireBearerForDataplanePipeline } = require('../utils/token-manager');
17
+ const { fetchTrustRunFromDataplane } = require('./agent-trust-fetch');
18
+
19
+ async function maybeSyncBeforeTrust({ noSync, authConfig, systemKey }) {
20
+ if (noSync === true) return;
21
+ requireBearerForDataplanePipeline(authConfig);
22
+ logger.log(chalk.cyan('Syncing local config to dataplane…'));
23
+ const { uploadExternalSystem } = require('../commands/upload');
24
+ await uploadExternalSystem(systemKey, { minimal: true });
25
+ logger.log(formatSuccessLine('Sync complete'));
26
+ }
27
+
28
+ function buildTransportFailureTrustRun(datasourceKey, systemKey, err) {
29
+ return {
30
+ datasourceKey,
31
+ systemKey,
32
+ status: 'fail',
33
+ trustDecision: 'notTrusted',
34
+ validationStatus: 'failed',
35
+ confidence: 0,
36
+ summary: err && err.message ? String(err.message) : 'Request failed',
37
+ transportError: true
38
+ };
39
+ }
40
+
41
+ /**
42
+ * @async
43
+ * @param {string} datasourceKey
44
+ * @param {Object} options
45
+ * @returns {Promise<{ trustRun: Object, apiError: Object|null }>}
46
+ */
47
+ async function runDatasourceAgentTrust(datasourceKey, options = {}) {
48
+ if (!datasourceKey || typeof datasourceKey !== 'string') {
49
+ throw new Error('Datasource key is required');
50
+ }
51
+ const { appKey } = await resolveAppKeyForDatasource(datasourceKey, options.app);
52
+ const systemKey = await getSystemKeyFromAppKey(appKey);
53
+
54
+ let authConfig = options.authConfig;
55
+ let dataplaneUrl = options.dataplaneUrl || options.dataplane;
56
+ if (!authConfig || !dataplaneUrl) {
57
+ const configObj = await getConfig();
58
+ const auth = await setupIntegrationTestAuth(
59
+ appKey,
60
+ { environment: options.environment, dataplane: options.dataplane },
61
+ configObj
62
+ );
63
+ authConfig = auth.authConfig;
64
+ dataplaneUrl = auth.dataplaneUrl;
65
+ }
66
+
67
+ await maybeSyncBeforeTrust({
68
+ noSync: options.noSync === true,
69
+ authConfig,
70
+ systemKey
71
+ });
72
+
73
+ try {
74
+ const trustRun = await fetchTrustRunFromDataplane({
75
+ datasourceKey,
76
+ systemKey,
77
+ dataplaneUrl,
78
+ authConfig,
79
+ options
80
+ });
81
+ return { trustRun, apiError: null };
82
+ } catch (err) {
83
+ return {
84
+ trustRun: buildTransportFailureTrustRun(datasourceKey, systemKey, err),
85
+ apiError: err
86
+ };
87
+ }
88
+ }
89
+
90
+ module.exports = {
91
+ runDatasourceAgentTrust,
92
+ maybeSyncBeforeTrust
93
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * @fileoverview HTTP timeout parsing for agent trust CLI (plan 143).
3
+ */
4
+
5
+ 'use strict';
6
+
7
+ const DEFAULT_TRUST_TIMEOUT_MS = 120000;
8
+
9
+ /**
10
+ * @param {Object} [options]
11
+ * @returns {number}
12
+ */
13
+ function parseTrustTimeoutMs(options = {}) {
14
+ const raw = options.timeout;
15
+ if (raw !== undefined && raw !== null && raw !== '') {
16
+ const n = parseInt(String(raw), 10);
17
+ if (Number.isFinite(n) && n > 0) return n;
18
+ }
19
+ return DEFAULT_TRUST_TIMEOUT_MS;
20
+ }
21
+
22
+ module.exports = {
23
+ DEFAULT_TRUST_TIMEOUT_MS,
24
+ parseTrustTimeoutMs
25
+ };
@@ -0,0 +1,80 @@
1
+ /**
2
+ * @fileoverview TTY and JSON output for audit evidence verification (407.3)
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ const chalk = require('chalk');
10
+ const logger = require('../utils/logger');
11
+ const {
12
+ sectionTitle,
13
+ formatSuccessLine,
14
+ formatBlockingError,
15
+ successGlyph,
16
+ failureGlyph
17
+ } = require('../utils/cli-test-layout-chalk');
18
+
19
+ const SEP = '────────────────────────────────';
20
+
21
+ /**
22
+ * @param {'passed'|'failed'} status
23
+ * @returns {string}
24
+ */
25
+ function rowGlyph(status) {
26
+ return status === 'passed' ? successGlyph() : failureGlyph();
27
+ }
28
+
29
+ /**
30
+ * @param {import('../api/types/audit.types').AuditEvidenceVerification} result
31
+ * @param {boolean} [verbose]
32
+ */
33
+ function displayAuditEvidenceMatrixTTY(result, verbose = false) {
34
+ logger.log(SEP);
35
+ logger.log(sectionTitle('Audit evidence matrix'));
36
+ logger.log(chalk.gray(` Datasource: ${result.datasourceKey}`));
37
+ if (result.correlationId) {
38
+ logger.log(chalk.gray(` Correlation: ${result.correlationId}`));
39
+ }
40
+ if (verbose && result.executionIds.length) {
41
+ logger.log(chalk.gray(` Execution ids: ${result.executionIds.length}`));
42
+ }
43
+ logger.log('');
44
+ for (const row of result.matrix || []) {
45
+ logger.log(` ${rowGlyph(row.status)} Row ${row.row}: ${row.detail}`);
46
+ if (verbose && row.code) {
47
+ logger.log(chalk.gray(` code: ${row.code}`));
48
+ }
49
+ }
50
+ logger.log('');
51
+ if (result.status === 'passed') {
52
+ logger.log(formatSuccessLine('Audit evidence verification passed'));
53
+ } else {
54
+ const failed = (result.matrix || []).filter(r => r.status === 'failed').length;
55
+ logger.log(formatBlockingError(`Audit evidence verification failed (${failed} row(s))`));
56
+ }
57
+ logger.log(SEP);
58
+ }
59
+
60
+ /**
61
+ * @param {import('../api/types/audit.types').AuditEvidenceVerification} result
62
+ */
63
+ function printAuditEvidenceVerificationJson(result) {
64
+ logger.log(
65
+ JSON.stringify({
66
+ auditEvidenceVerification: {
67
+ status: result.status,
68
+ datasourceKey: result.datasourceKey,
69
+ correlationId: result.correlationId,
70
+ executionIds: result.executionIds,
71
+ matrix: result.matrix
72
+ }
73
+ })
74
+ );
75
+ }
76
+
77
+ module.exports = {
78
+ displayAuditEvidenceMatrixTTY,
79
+ printAuditEvidenceVerificationJson
80
+ };
@@ -0,0 +1,103 @@
1
+ /**
2
+ * @fileoverview Extract execution ids from DatasourceTestRun debug / async E2E payloads
3
+ * @author AI Fabrix Team
4
+ * @version 1.0.0
5
+ */
6
+
7
+ 'use strict';
8
+
9
+ /**
10
+ * @param {Array<*>} ids
11
+ * @returns {string[]}
12
+ */
13
+ function dedupeIds(ids) {
14
+ if (!Array.isArray(ids)) return [];
15
+ const out = [];
16
+ const seen = new Set();
17
+ for (const raw of ids) {
18
+ const id = raw !== null && raw !== undefined ? String(raw).trim() : '';
19
+ if (!id || seen.has(id)) continue;
20
+ seen.add(id);
21
+ out.push(id);
22
+ }
23
+ return out;
24
+ }
25
+
26
+ /**
27
+ * @param {*} node
28
+ * @param {string[]} out
29
+ */
30
+ function collectExecutionIdFields(node, out) {
31
+ if (!node || typeof node !== 'object') return;
32
+ if (typeof node.executionId === 'string' && node.executionId.trim()) {
33
+ out.push(node.executionId.trim());
34
+ }
35
+ if (Array.isArray(node.jobs)) {
36
+ for (const job of node.jobs) collectExecutionIdFields(job, out);
37
+ }
38
+ if (Array.isArray(node.datasources)) {
39
+ for (const ds of node.datasources) collectExecutionIdFields(ds, out);
40
+ }
41
+ if (node.audit && typeof node.audit === 'object') {
42
+ collectExecutionIdFields(node.audit, out);
43
+ }
44
+ if (node.evidence && typeof node.evidence === 'object') {
45
+ collectExecutionIdFields(node.evidence, out);
46
+ }
47
+ }
48
+
49
+ /**
50
+ * @param {Object|null|undefined} envelope
51
+ * @returns {string[]}
52
+ */
53
+ function executionIdsFromDebugEnvelope(envelope) {
54
+ const dbg = envelope && envelope.debug;
55
+ if (!dbg || typeof dbg !== 'object') return [];
56
+ const found = [];
57
+ if (dbg.executionIds) {
58
+ found.push(...(Array.isArray(dbg.executionIds) ? dbg.executionIds : [dbg.executionIds]));
59
+ }
60
+ const asyncDbg = dbg.e2eAsyncDebug;
61
+ if (asyncDbg && Array.isArray(asyncDbg.stepDebug)) {
62
+ for (const step of asyncDbg.stepDebug) {
63
+ if (step && step.evidence) collectExecutionIdFields(step.evidence, found);
64
+ }
65
+ }
66
+ return dedupeIds(found);
67
+ }
68
+
69
+ /**
70
+ * CIP operation names from capacity step (insert, update, list, …).
71
+ * @param {Object|null|undefined} envelope
72
+ * @returns {string[]}
73
+ */
74
+ function cipOperationsFromDebugEnvelope(envelope) {
75
+ const dbg = envelope && envelope.debug;
76
+ const asyncDbg = dbg && dbg.e2eAsyncDebug;
77
+ if (!asyncDbg || !Array.isArray(asyncDbg.stepDebug)) return [];
78
+ const capStep = asyncDbg.stepDebug.find(s => s && s.name === 'capacity');
79
+ if (!capStep || !capStep.evidence) return [];
80
+ const ops = new Set();
81
+ const details = capStep.evidence.datasources;
82
+ if (!Array.isArray(details)) return [];
83
+ for (const ds of details) {
84
+ if (!ds || !Array.isArray(ds.capabilityDetails)) continue;
85
+ for (const item of ds.capabilityDetails) {
86
+ const key = item && item.key ? String(item.key) : '';
87
+ const m = key.match(/^capacity:([a-zA-Z]+)/);
88
+ if (m && m[1]) {
89
+ let op = m[1] === 'updateBasic' ? 'updatebasic' : m[1].toLowerCase();
90
+ if (op === 'create') op = 'insert';
91
+ ops.add(op);
92
+ }
93
+ }
94
+ }
95
+ return [...ops];
96
+ }
97
+
98
+ module.exports = {
99
+ dedupeIds,
100
+ executionIdsFromDebugEnvelope,
101
+ cipOperationsFromDebugEnvelope,
102
+ collectExecutionIdFields
103
+ };