@neurcode-ai/cli 0.9.66 → 0.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.telemetry-bundle/dist/__tests__/harvest-verify.test.d.ts +1 -0
- package/.telemetry-bundle/dist/__tests__/harvest-verify.test.js +86 -0
- package/.telemetry-bundle/dist/contracts.d.ts +58 -0
- package/.telemetry-bundle/dist/contracts.js +8 -0
- package/.telemetry-bundle/dist/harvest-verify.d.ts +9 -0
- package/.telemetry-bundle/dist/harvest-verify.js +128 -0
- package/.telemetry-bundle/dist/index.d.ts +10 -0
- package/.telemetry-bundle/dist/index.js +22 -0
- package/.telemetry-bundle/dist/precision/leaderboards.d.ts +20 -0
- package/.telemetry-bundle/dist/precision/leaderboards.js +72 -0
- package/.telemetry-bundle/dist/reader.d.ts +5 -0
- package/.telemetry-bundle/dist/reader.js +46 -0
- package/.telemetry-bundle/dist/stable-json.d.ts +5 -0
- package/.telemetry-bundle/dist/stable-json.js +24 -0
- package/.telemetry-bundle/dist/store.d.ts +10 -0
- package/.telemetry-bundle/dist/store.js +52 -0
- package/.telemetry-bundle/dist/trust-scoring.d.ts +20 -0
- package/.telemetry-bundle/dist/trust-scoring.js +58 -0
- package/.telemetry-bundle/package.json +8 -0
- package/dist/commands/governance.d.ts +3 -0
- package/dist/commands/governance.d.ts.map +1 -0
- package/dist/commands/governance.js +390 -0
- package/dist/commands/governance.js.map +1 -0
- package/dist/commands/quickstart.js +3 -3
- package/dist/commands/quickstart.js.map +1 -1
- package/dist/commands/remediate-export.d.ts +5 -0
- package/dist/commands/remediate-export.d.ts.map +1 -1
- package/dist/commands/remediate-export.js +803 -14
- package/dist/commands/remediate-export.js.map +1 -1
- package/dist/commands/replay.d.ts.map +1 -1
- package/dist/commands/replay.js +14 -0
- package/dist/commands/replay.js.map +1 -1
- package/dist/commands/session.d.ts +7 -0
- package/dist/commands/session.d.ts.map +1 -1
- package/dist/commands/session.js +156 -0
- package/dist/commands/session.js.map +1 -1
- package/dist/commands/start-intent.d.ts.map +1 -1
- package/dist/commands/start-intent.js +61 -11
- package/dist/commands/start-intent.js.map +1 -1
- package/dist/commands/verify-guidance.d.ts +5 -0
- package/dist/commands/verify-guidance.d.ts.map +1 -0
- package/dist/commands/verify-guidance.js +49 -0
- package/dist/commands/verify-guidance.js.map +1 -0
- package/dist/commands/verify-output.d.ts +37 -0
- package/dist/commands/verify-output.d.ts.map +1 -0
- package/dist/commands/verify-output.js +572 -0
- package/dist/commands/verify-output.js.map +1 -0
- package/dist/commands/verify-render.d.ts +41 -0
- package/dist/commands/verify-render.d.ts.map +1 -0
- package/dist/commands/verify-render.js +457 -0
- package/dist/commands/verify-render.js.map +1 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +278 -1081
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/workspace.d.ts.map +1 -1
- package/dist/commands/workspace.js +3 -14
- package/dist/commands/workspace.js.map +1 -1
- package/dist/context-engine/graph.d.ts.map +1 -1
- package/dist/context-engine/graph.js +69 -7
- package/dist/context-engine/graph.js.map +1 -1
- package/dist/context-engine/scanner.d.ts.map +1 -1
- package/dist/context-engine/scanner.js +9 -2
- package/dist/context-engine/scanner.js.map +1 -1
- package/dist/daemon/compatibility/execution.d.ts +42 -0
- package/dist/daemon/compatibility/execution.d.ts.map +1 -0
- package/dist/daemon/compatibility/execution.js +183 -0
- package/dist/daemon/compatibility/execution.js.map +1 -0
- package/dist/daemon/compatibility/mutation.d.ts +24 -0
- package/dist/daemon/compatibility/mutation.d.ts.map +1 -0
- package/dist/daemon/compatibility/mutation.js +724 -0
- package/dist/daemon/compatibility/mutation.js.map +1 -0
- package/dist/daemon/routes.d.ts +19 -0
- package/dist/daemon/routes.d.ts.map +1 -0
- package/dist/daemon/routes.js +123 -0
- package/dist/daemon/routes.js.map +1 -0
- package/dist/daemon/runtime/execution-bus.d.ts +217 -0
- package/dist/daemon/runtime/execution-bus.d.ts.map +1 -0
- package/dist/daemon/runtime/execution-bus.js +1420 -0
- package/dist/daemon/runtime/execution-bus.js.map +1 -0
- package/dist/daemon/runtime/workspace-runtime.d.ts +280 -0
- package/dist/daemon/runtime/workspace-runtime.d.ts.map +1 -0
- package/dist/daemon/runtime/workspace-runtime.js +1473 -0
- package/dist/daemon/runtime/workspace-runtime.js.map +1 -0
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +171 -874
- package/dist/daemon/server.js.map +1 -1
- package/dist/daemon/shaping.d.ts +11 -0
- package/dist/daemon/shaping.d.ts.map +1 -0
- package/dist/daemon/shaping.js +240 -0
- package/dist/daemon/shaping.js.map +1 -0
- package/dist/governance/canonical-pipeline.d.ts +2 -1
- package/dist/governance/canonical-pipeline.d.ts.map +1 -1
- package/dist/governance/canonical-pipeline.js +259 -84
- package/dist/governance/canonical-pipeline.js.map +1 -1
- package/dist/governance/structural-cache.d.ts.map +1 -1
- package/dist/governance/structural-cache.js +2 -7
- package/dist/governance/structural-cache.js.map +1 -1
- package/dist/index.js +230 -66
- package/dist/index.js.map +1 -1
- package/dist/utils/active-engineering-context.d.ts +12 -0
- package/dist/utils/active-engineering-context.d.ts.map +1 -0
- package/dist/utils/active-engineering-context.js +67 -0
- package/dist/utils/active-engineering-context.js.map +1 -0
- package/dist/utils/artifact-io.d.ts +33 -0
- package/dist/utils/artifact-io.d.ts.map +1 -0
- package/dist/utils/artifact-io.js +183 -0
- package/dist/utils/artifact-io.js.map +1 -0
- package/dist/utils/change-contract.d.ts +6 -2
- package/dist/utils/change-contract.d.ts.map +1 -1
- package/dist/utils/change-contract.js +175 -0
- package/dist/utils/change-contract.js.map +1 -1
- package/dist/utils/context-pack.d.ts +12 -0
- package/dist/utils/context-pack.d.ts.map +1 -0
- package/dist/utils/context-pack.js +147 -0
- package/dist/utils/context-pack.js.map +1 -0
- package/dist/utils/control-plane.d.ts +18 -0
- package/dist/utils/control-plane.d.ts.map +1 -1
- package/dist/utils/control-plane.js +31 -4
- package/dist/utils/control-plane.js.map +1 -1
- package/dist/utils/drift-intelligence.d.ts +47 -0
- package/dist/utils/drift-intelligence.d.ts.map +1 -0
- package/dist/utils/drift-intelligence.js +2099 -0
- package/dist/utils/drift-intelligence.js.map +1 -0
- package/dist/utils/execution-actions.d.ts +22 -0
- package/dist/utils/execution-actions.d.ts.map +1 -0
- package/dist/utils/execution-actions.js +103 -0
- package/dist/utils/execution-actions.js.map +1 -0
- package/dist/utils/execution-bus.d.ts +1 -214
- package/dist/utils/execution-bus.d.ts.map +1 -1
- package/dist/utils/execution-bus.js +15 -1359
- package/dist/utils/execution-bus.js.map +1 -1
- package/dist/utils/git.d.ts +1 -0
- package/dist/utils/git.d.ts.map +1 -1
- package/dist/utils/git.js +13 -3
- package/dist/utils/git.js.map +1 -1
- package/dist/utils/governance-decisions.d.ts +75 -0
- package/dist/utils/governance-decisions.d.ts.map +1 -0
- package/dist/utils/governance-decisions.js +412 -0
- package/dist/utils/governance-decisions.js.map +1 -0
- package/dist/utils/governance-provenance.d.ts +1 -1
- package/dist/utils/governance-provenance.d.ts.map +1 -1
- package/dist/utils/governance-provenance.js +5 -7
- package/dist/utils/governance-provenance.js.map +1 -1
- package/dist/utils/governance.d.ts +108 -0
- package/dist/utils/governance.d.ts.map +1 -1
- package/dist/utils/governance.js +209 -7
- package/dist/utils/governance.js.map +1 -1
- package/dist/utils/intelligence-runtime-common.d.ts +30 -0
- package/dist/utils/intelligence-runtime-common.d.ts.map +1 -0
- package/dist/utils/intelligence-runtime-common.js +156 -0
- package/dist/utils/intelligence-runtime-common.js.map +1 -0
- package/dist/utils/intent-contract-diagnostics.d.ts +9 -0
- package/dist/utils/intent-contract-diagnostics.d.ts.map +1 -0
- package/dist/utils/intent-contract-diagnostics.js +322 -0
- package/dist/utils/intent-contract-diagnostics.js.map +1 -0
- package/dist/utils/intent-pack.d.ts +15 -0
- package/dist/utils/intent-pack.d.ts.map +1 -0
- package/dist/utils/intent-pack.js +196 -0
- package/dist/utils/intent-pack.js.map +1 -0
- package/dist/utils/plan-sync.d.ts +1 -0
- package/dist/utils/plan-sync.d.ts.map +1 -1
- package/dist/utils/plan-sync.js +23 -0
- package/dist/utils/plan-sync.js.map +1 -1
- package/dist/utils/policy-decision.d.ts +5 -0
- package/dist/utils/policy-decision.d.ts.map +1 -0
- package/dist/utils/policy-decision.js +17 -0
- package/dist/utils/policy-decision.js.map +1 -0
- package/dist/utils/replay-custody.d.ts +43 -0
- package/dist/utils/replay-custody.d.ts.map +1 -0
- package/dist/utils/replay-custody.js +168 -0
- package/dist/utils/replay-custody.js.map +1 -0
- package/dist/utils/replay-runtime.d.ts +13 -0
- package/dist/utils/replay-runtime.d.ts.map +1 -1
- package/dist/utils/replay-runtime.js +96 -9
- package/dist/utils/replay-runtime.js.map +1 -1
- package/dist/utils/repository-intelligence.d.ts +9 -0
- package/dist/utils/repository-intelligence.d.ts.map +1 -0
- package/dist/utils/repository-intelligence.js +372 -0
- package/dist/utils/repository-intelligence.js.map +1 -0
- package/dist/utils/runtime-events.d.ts.map +1 -1
- package/dist/utils/runtime-events.js +25 -6
- package/dist/utils/runtime-events.js.map +1 -1
- package/dist/utils/semantic-contract-intelligence.d.ts +20 -0
- package/dist/utils/semantic-contract-intelligence.d.ts.map +1 -0
- package/dist/utils/semantic-contract-intelligence.js +825 -0
- package/dist/utils/semantic-contract-intelligence.js.map +1 -0
- package/dist/utils/session-continuity.d.ts +56 -0
- package/dist/utils/session-continuity.d.ts.map +1 -0
- package/dist/utils/session-continuity.js +318 -0
- package/dist/utils/session-continuity.js.map +1 -0
- package/dist/utils/verification-evidence.d.ts.map +1 -1
- package/dist/utils/verification-evidence.js +4 -1
- package/dist/utils/verification-evidence.js.map +1 -1
- package/dist/utils/workspace-runtime.d.ts +1 -266
- package/dist/utils/workspace-runtime.d.ts.map +1 -1
- package/dist/utils/workspace-runtime.js +15 -1412
- package/dist/utils/workspace-runtime.js.map +1 -1
- package/package.json +13 -11
- package/LICENSE +0 -201
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* neurcode remediate-export --finding <id> --format mcp
|
|
18
18
|
* neurcode remediate-export --finding <id> --out ./payload.json
|
|
19
19
|
* neurcode remediate-export --finding <id> --copy
|
|
20
|
+
* neurcode remediate-export --verify-output-file ./verify.json --project-root ./repo
|
|
20
21
|
*/
|
|
21
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
23
|
exports.remediateExportCommand = remediateExportCommand;
|
|
@@ -53,6 +54,35 @@ const REMEDIATION_CATEGORY = {
|
|
|
53
54
|
DS001: 'distributed-consistency',
|
|
54
55
|
'potential-secret-default': 'security',
|
|
55
56
|
'potential-secret-high': 'security',
|
|
57
|
+
governance_decision_block: 'governance-boundary',
|
|
58
|
+
scope_guard: 'governance-boundary',
|
|
59
|
+
'drift_narrative:service-boundary-escape': 'governance-boundary',
|
|
60
|
+
'drift_narrative:dependency-expansion': 'governance-boundary',
|
|
61
|
+
'drift_narrative:forbidden-boundary-breach': 'governance-boundary',
|
|
62
|
+
'drift_narrative:semantic-coupling': 'governance-boundary',
|
|
63
|
+
'drift_narrative:blast-radius-expansion': 'governance-boundary',
|
|
64
|
+
'drift_narrative:localized-scope-drift': 'governance-boundary',
|
|
65
|
+
'drift_narrative:ownership-boundary-breach': 'governance-boundary',
|
|
66
|
+
'drift_narrative:architectural-invariant-erosion': 'governance-boundary',
|
|
67
|
+
'drift_narrative:runtime-behavior-shift': 'governance-boundary',
|
|
68
|
+
'drift_narrative:deployment-semantics-breach': 'governance-boundary',
|
|
69
|
+
'drift_narrative:state-ownership-erosion': 'governance-boundary',
|
|
70
|
+
'drift_intelligence:cross-service': 'governance-boundary',
|
|
71
|
+
'drift_intelligence:dependency-spread': 'governance-boundary',
|
|
72
|
+
'drift_intelligence:infra-leakage': 'governance-boundary',
|
|
73
|
+
'drift_intelligence:sensitive-boundary': 'governance-boundary',
|
|
74
|
+
'drift_intelligence:blast-radius': 'governance-boundary',
|
|
75
|
+
'drift_intelligence:rollout-risk': 'governance-boundary',
|
|
76
|
+
'drift_intelligence:runtime-coupling': 'governance-boundary',
|
|
77
|
+
'drift_intelligence:architectural-leakage': 'governance-boundary',
|
|
78
|
+
'drift_intelligence:layer-violation': 'governance-boundary',
|
|
79
|
+
'drift_intelligence:contract-misuse': 'governance-boundary',
|
|
80
|
+
'drift_intelligence:ownership-inversion': 'governance-boundary',
|
|
81
|
+
'drift_intelligence:responsibility-drift': 'governance-boundary',
|
|
82
|
+
'drift_intelligence:invariant-violation': 'governance-boundary',
|
|
83
|
+
'drift_intelligence:behavioral-drift': 'governance-boundary',
|
|
84
|
+
'drift_intelligence:deployment-coupling': 'governance-boundary',
|
|
85
|
+
'drift_intelligence:state-ownership-risk': 'governance-boundary',
|
|
56
86
|
};
|
|
57
87
|
// ── Suggested prompt hint per category — advisory, never prescriptive ─────────
|
|
58
88
|
const PROMPT_HINT = {
|
|
@@ -76,22 +106,27 @@ const PROMPT_HINT = {
|
|
|
76
106
|
'Remediation should add compensating logic, idempotency, or saga rollback.',
|
|
77
107
|
'data-flow': 'The finding identifies a data flow issue (unbounded collection, leaking state). ' +
|
|
78
108
|
'Remediation should add bounds or explicit cleanup.',
|
|
109
|
+
'governance-boundary': 'The finding identifies engineering drift outside the approved intent envelope. ' +
|
|
110
|
+
'Remediation should pull the change back inside the declared service, dependency, and rollout boundary before re-verification.',
|
|
79
111
|
};
|
|
80
112
|
async function remediateExportCommand(options) {
|
|
81
|
-
const projectRoot = process.cwd();
|
|
82
|
-
const
|
|
83
|
-
|
|
113
|
+
const projectRoot = options.projectRoot ? (0, path_1.resolve)(options.projectRoot) : process.cwd();
|
|
114
|
+
const verifyPath = options.verifyOutputFile
|
|
115
|
+
? (0, path_1.resolve)(options.verifyOutputFile)
|
|
116
|
+
: (0, path_1.join)(projectRoot, '.neurcode', 'last-verify-output.json');
|
|
117
|
+
if (!(0, fs_1.existsSync)(verifyPath)) {
|
|
84
118
|
console.error(chalk.red('✗ No verify output found.'));
|
|
119
|
+
console.error(chalk.dim(` Expected: ${verifyPath}`));
|
|
85
120
|
console.error(chalk.dim(' Run: neurcode verify --policy-only --json'));
|
|
86
|
-
console.error(chalk.dim('
|
|
121
|
+
console.error(chalk.dim(' Or pass: neurcode remediate-export --verify-output-file <path-to-verify.json>'));
|
|
87
122
|
process.exit(1);
|
|
88
123
|
}
|
|
89
124
|
let verifyOutput;
|
|
90
125
|
try {
|
|
91
|
-
verifyOutput = JSON.parse((0, fs_1.readFileSync)(
|
|
126
|
+
verifyOutput = JSON.parse((0, fs_1.readFileSync)(verifyPath, 'utf-8'));
|
|
92
127
|
}
|
|
93
128
|
catch {
|
|
94
|
-
console.error(chalk.red(
|
|
129
|
+
console.error(chalk.red(`✗ Could not parse verify output: ${verifyPath}`));
|
|
95
130
|
process.exit(1);
|
|
96
131
|
}
|
|
97
132
|
// Collect findings from verify output
|
|
@@ -130,8 +165,8 @@ async function remediateExportCommand(options) {
|
|
|
130
165
|
selected = [findings[0]];
|
|
131
166
|
}
|
|
132
167
|
const format = options.format ?? 'json';
|
|
133
|
-
const replayChecksum = verifyOutput
|
|
134
|
-
const replayMode = verifyOutput
|
|
168
|
+
const replayChecksum = resolveReplayChecksum(verifyOutput);
|
|
169
|
+
const replayMode = resolveReplayMode(verifyOutput);
|
|
135
170
|
const payloads = selected.map((finding) => buildPayload(finding, verifyOutput, projectRoot, replayChecksum, replayMode, format));
|
|
136
171
|
const output = payloads.length === 1
|
|
137
172
|
? JSON.stringify(format === 'mcp' ? payloads[0].mcpEnvelope : payloads[0], null, 2)
|
|
@@ -177,7 +212,7 @@ function collectFindings(verifyOutput) {
|
|
|
177
212
|
return [...violations, ...blockingItems, ...advisoryItems];
|
|
178
213
|
}
|
|
179
214
|
function buildPayload(finding, verifyOutput, projectRoot, replayChecksum, replayMode, format) {
|
|
180
|
-
const ruleId = finding
|
|
215
|
+
const ruleId = resolveFindingRuleId(finding);
|
|
181
216
|
const filePath = finding.filePath ?? finding.file ?? finding.evidence?.filePath ?? '';
|
|
182
217
|
const line = finding.line ?? finding.evidence?.line ?? null;
|
|
183
218
|
const column = finding.column ?? finding.evidence?.column ?? null;
|
|
@@ -200,16 +235,56 @@ function buildPayload(finding, verifyOutput, projectRoot, replayChecksum, replay
|
|
|
200
235
|
.slice(0, 16);
|
|
201
236
|
const remediationCategory = REMEDIATION_CATEGORY[ruleId] ?? 'general';
|
|
202
237
|
const suggestedPromptHint = PROMPT_HINT[remediationCategory] ?? PROMPT_HINT['correctness'];
|
|
238
|
+
const snapshotIds = Array.isArray(finding.replayMetadata?.snapshotIds)
|
|
239
|
+
? finding.replayMetadata.snapshotIds.filter((entry) => typeof entry === 'string' && entry.trim().length > 0)
|
|
240
|
+
: [];
|
|
241
|
+
const controlPlaneSnapshotId = typeof verifyOutput.controlPlaneSnapshotId === 'string'
|
|
242
|
+
? verifyOutput.controlPlaneSnapshotId
|
|
243
|
+
: snapshotIds.find((entry) => entry.startsWith('cps-')) ?? null;
|
|
244
|
+
const workspaceSnapshotId = typeof verifyOutput.workspaceSnapshotId === 'string'
|
|
245
|
+
? verifyOutput.workspaceSnapshotId
|
|
246
|
+
: snapshotIds.find((entry) => entry.startsWith('wss-')) ?? null;
|
|
203
247
|
const policyViolations = [];
|
|
204
248
|
if (finding.structuralMetadata?.policyRef)
|
|
205
249
|
policyViolations.push(finding.structuralMetadata.policyRef);
|
|
206
250
|
if (finding.policy)
|
|
207
251
|
policyViolations.push(finding.policy);
|
|
252
|
+
const blastRadiusRisk = typeof verifyOutput.blastRadius === 'object'
|
|
253
|
+
&& verifyOutput.blastRadius
|
|
254
|
+
&& typeof verifyOutput.blastRadius.riskScore === 'string'
|
|
255
|
+
? verifyOutput.blastRadius.riskScore
|
|
256
|
+
: null;
|
|
257
|
+
const scopeReason = typeof verifyOutput.suspiciousChange === 'object'
|
|
258
|
+
&& verifyOutput.suspiciousChange
|
|
259
|
+
&& typeof verifyOutput.suspiciousChange.reason === 'string'
|
|
260
|
+
? verifyOutput.suspiciousChange.reason
|
|
261
|
+
: null;
|
|
262
|
+
const scopeUnexpectedFiles = typeof verifyOutput.suspiciousChange === 'object'
|
|
263
|
+
&& verifyOutput.suspiciousChange
|
|
264
|
+
&& Array.isArray(verifyOutput.suspiciousChange.unexpectedFiles)
|
|
265
|
+
? verifyOutput.suspiciousChange.unexpectedFiles
|
|
266
|
+
.filter((entry) => typeof entry === 'string' && entry.trim().length > 0)
|
|
267
|
+
.slice(0, 12)
|
|
268
|
+
: [];
|
|
269
|
+
const contractViolationSummary = typeof verifyOutput.changeContract === 'object'
|
|
270
|
+
&& verifyOutput.changeContract
|
|
271
|
+
&& Array.isArray(verifyOutput.changeContract.violations)
|
|
272
|
+
? verifyOutput.changeContract.violations
|
|
273
|
+
.map((entry) => typeof entry.message === 'string' ? entry.message.trim() : '')
|
|
274
|
+
.filter((entry) => entry.length > 0)
|
|
275
|
+
.slice(0, 12)
|
|
276
|
+
: [];
|
|
277
|
+
const engineeringContext = extractEngineeringContext(verifyOutput);
|
|
278
|
+
const intentGovernance = extractIntentGovernance(verifyOutput);
|
|
279
|
+
const driftIntelligence = extractDriftIntelligence(verifyOutput);
|
|
280
|
+
const graphImpact = extractGraphImpact(verifyOutput);
|
|
281
|
+
const relevantNarratives = selectRelevantNarratives(driftIntelligence, filePath, ruleId);
|
|
282
|
+
const semanticInsights = deriveSemanticExportInsights(engineeringContext, driftIntelligence, relevantNarratives, filePath);
|
|
208
283
|
const payload = {
|
|
209
284
|
exportId,
|
|
210
285
|
exportedAt: new Date().toISOString(),
|
|
211
|
-
neurcodeVersion: '0.
|
|
212
|
-
schemaVersion: '2026-05-
|
|
286
|
+
neurcodeVersion: '0.10.1',
|
|
287
|
+
schemaVersion: '2026-05-14',
|
|
213
288
|
findingId,
|
|
214
289
|
ruleId,
|
|
215
290
|
ruleName,
|
|
@@ -223,12 +298,30 @@ function buildPayload(finding, verifyOutput, projectRoot, replayChecksum, replay
|
|
|
223
298
|
policyViolations,
|
|
224
299
|
operationalExplanation,
|
|
225
300
|
remediationCategory,
|
|
301
|
+
blastRadiusRisk,
|
|
302
|
+
scopeReason,
|
|
303
|
+
scopeUnexpectedFiles,
|
|
304
|
+
contractViolationSummary,
|
|
305
|
+
violatedContracts: semanticInsights.violatedContracts,
|
|
306
|
+
ownershipBoundaryCrossed: semanticInsights.ownershipBoundaryCrossed,
|
|
307
|
+
invariantSummaries: semanticInsights.invariantSummaries,
|
|
308
|
+
semanticRiskSummary: semanticInsights.semanticRiskSummary,
|
|
309
|
+
intentGovernance,
|
|
226
310
|
trustBoundaryStatement: TRUST_BOUNDARY_STATEMENT,
|
|
227
311
|
replayChecksum,
|
|
228
312
|
replayMode,
|
|
229
313
|
findingGraphHash,
|
|
230
|
-
provenanceRunId: finding.provenanceMetadata?.
|
|
231
|
-
provenanceAt: finding.provenanceMetadata?.generatedAt ?? null,
|
|
314
|
+
provenanceRunId: finding.provenanceMetadata?.runId ?? verifyOutput.provenanceRunId ?? null,
|
|
315
|
+
provenanceAt: finding.provenanceMetadata?.generatedAt ?? verifyOutput.provenanceRunAt ?? null,
|
|
316
|
+
planId: finding.provenanceMetadata?.planId ?? verifyOutput.planId ?? null,
|
|
317
|
+
policyLockFingerprint: finding.provenanceMetadata?.policyLockFingerprint ?? verifyOutput.policyLockFingerprint ?? null,
|
|
318
|
+
compiledPolicyFingerprint: finding.provenanceMetadata?.compiledPolicyFingerprint ?? verifyOutput.compiledPolicyFingerprint ?? null,
|
|
319
|
+
controlPlaneSnapshotId,
|
|
320
|
+
workspaceSnapshotId,
|
|
321
|
+
engineeringContext,
|
|
322
|
+
driftIntelligence,
|
|
323
|
+
graphImpact,
|
|
324
|
+
relevantNarratives,
|
|
232
325
|
suggestedPromptHint,
|
|
233
326
|
};
|
|
234
327
|
if (format === 'mcp') {
|
|
@@ -244,13 +337,709 @@ function buildPayload(finding, verifyOutput, projectRoot, replayChecksum, replay
|
|
|
244
337
|
line,
|
|
245
338
|
codeSpan,
|
|
246
339
|
},
|
|
247
|
-
context: surroundingContext,
|
|
340
|
+
context: buildMcpContext(surroundingContext, engineeringContext, driftIntelligence, graphImpact, relevantNarratives, semanticInsights, intentGovernance),
|
|
248
341
|
constraint: TRUST_BOUNDARY_STATEMENT,
|
|
249
342
|
promptHint: suggestedPromptHint,
|
|
250
343
|
};
|
|
251
344
|
}
|
|
252
345
|
return payload;
|
|
253
346
|
}
|
|
347
|
+
function resolveFindingRuleId(finding) {
|
|
348
|
+
const direct = finding.ruleId
|
|
349
|
+
?? finding.rule
|
|
350
|
+
?? finding.structuralMetadata?.ruleId
|
|
351
|
+
?? null;
|
|
352
|
+
if (typeof direct === 'string' && direct.trim().length > 0) {
|
|
353
|
+
return direct.trim();
|
|
354
|
+
}
|
|
355
|
+
const title = typeof finding.title === 'string' ? finding.title.trim() : '';
|
|
356
|
+
const titleMatch = title.match(/·\s*([A-Za-z0-9:_-]+)/);
|
|
357
|
+
if (titleMatch?.[1]) {
|
|
358
|
+
return titleMatch[1];
|
|
359
|
+
}
|
|
360
|
+
return 'UNKNOWN';
|
|
361
|
+
}
|
|
362
|
+
function asRecord(value) {
|
|
363
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
return value;
|
|
367
|
+
}
|
|
368
|
+
function asStringArray(value, limit = 12) {
|
|
369
|
+
if (!Array.isArray(value)) {
|
|
370
|
+
return [];
|
|
371
|
+
}
|
|
372
|
+
return value
|
|
373
|
+
.filter((entry) => typeof entry === 'string' && entry.trim().length > 0)
|
|
374
|
+
.slice(0, limit);
|
|
375
|
+
}
|
|
376
|
+
function extractGovernanceDecisionLineage(value) {
|
|
377
|
+
const record = asRecord(value);
|
|
378
|
+
if (!record)
|
|
379
|
+
return null;
|
|
380
|
+
return {
|
|
381
|
+
decisionId: typeof record.decisionId === 'string' ? record.decisionId : 'unknown',
|
|
382
|
+
state: typeof record.state === 'string' ? record.state : 'acknowledged',
|
|
383
|
+
findingId: typeof record.findingId === 'string' ? record.findingId : null,
|
|
384
|
+
category: typeof record.category === 'string' ? record.category : null,
|
|
385
|
+
reason: typeof record.reason === 'string' ? record.reason : 'Governance decision reason unavailable.',
|
|
386
|
+
actor: typeof record.actor === 'string' ? record.actor : 'unknown',
|
|
387
|
+
decidedAt: typeof record.decidedAt === 'string' ? record.decidedAt : '',
|
|
388
|
+
expiresAt: typeof record.expiresAt === 'string' ? record.expiresAt : null,
|
|
389
|
+
temporary: record.temporary === true,
|
|
390
|
+
expired: record.expired === true,
|
|
391
|
+
previousGate: typeof record.previousGate === 'string' ? record.previousGate : null,
|
|
392
|
+
resultingGate: typeof record.resultingGate === 'string' ? record.resultingGate : null,
|
|
393
|
+
previousRolloutTrust: typeof record.previousRolloutTrust === 'string' ? record.previousRolloutTrust : null,
|
|
394
|
+
resultingRolloutTrust: typeof record.resultingRolloutTrust === 'string' ? record.resultingRolloutTrust : null,
|
|
395
|
+
sourcePath: typeof record.sourcePath === 'string' ? record.sourcePath : null,
|
|
396
|
+
lineageHash: typeof record.lineageHash === 'string' ? record.lineageHash : 'unknown',
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
function asBoundaryArray(value) {
|
|
400
|
+
if (!Array.isArray(value)) {
|
|
401
|
+
return [];
|
|
402
|
+
}
|
|
403
|
+
return value
|
|
404
|
+
.map((entry) => asRecord(entry))
|
|
405
|
+
.filter((entry) => entry !== null)
|
|
406
|
+
.map((entry) => ({
|
|
407
|
+
type: typeof entry.type === 'string' ? entry.type : 'unknown',
|
|
408
|
+
path: typeof entry.path === 'string' ? entry.path : '',
|
|
409
|
+
policy: typeof entry.policy === 'string' ? entry.policy : 'review-required',
|
|
410
|
+
reason: typeof entry.reason === 'string' ? entry.reason : '',
|
|
411
|
+
}))
|
|
412
|
+
.filter((entry) => entry.path.trim().length > 0)
|
|
413
|
+
.slice(0, 12);
|
|
414
|
+
}
|
|
415
|
+
function extractEngineeringContext(verifyOutput) {
|
|
416
|
+
const context = asRecord(verifyOutput.engineeringContext);
|
|
417
|
+
if (!context) {
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
420
|
+
const approvedScope = asRecord(context.approvedScope);
|
|
421
|
+
const semanticExpectations = asRecord(context.semanticExpectations);
|
|
422
|
+
return {
|
|
423
|
+
source: typeof context.source === 'string' ? context.source : null,
|
|
424
|
+
sessionId: typeof context.sessionId === 'string' ? context.sessionId : null,
|
|
425
|
+
intentPackId: typeof context.intentPackId === 'string' ? context.intentPackId : null,
|
|
426
|
+
contextPackId: typeof context.contextPackId === 'string' ? context.contextPackId : null,
|
|
427
|
+
repositoryGraphId: typeof context.repositoryGraphId === 'string' ? context.repositoryGraphId : null,
|
|
428
|
+
intentSummary: typeof context.intentSummary === 'string' ? context.intentSummary : null,
|
|
429
|
+
approvedScope: {
|
|
430
|
+
files: asStringArray(approvedScope?.files, 20),
|
|
431
|
+
modules: asStringArray(approvedScope?.modules, 20),
|
|
432
|
+
services: asStringArray(approvedScope?.services, 20),
|
|
433
|
+
},
|
|
434
|
+
expectedDependencies: asStringArray(context.expectedDependencies, 20),
|
|
435
|
+
expectedInfrastructure: asStringArray(context.expectedInfrastructure, 20),
|
|
436
|
+
rolloutExpectations: asStringArray(context.rolloutExpectations, 12),
|
|
437
|
+
forbiddenBoundaries: asBoundaryArray(context.forbiddenBoundaries),
|
|
438
|
+
semanticExpectations: semanticExpectations
|
|
439
|
+
? {
|
|
440
|
+
ownershipBoundaries: asStringArray(semanticExpectations.ownershipBoundaries, 16),
|
|
441
|
+
contractIds: asStringArray(semanticExpectations.contractIds, 20),
|
|
442
|
+
invariantIds: asStringArray(semanticExpectations.invariantIds, 20),
|
|
443
|
+
expectedResponsibilities: asStringArray(semanticExpectations.expectedResponsibilities, 20),
|
|
444
|
+
expectedBehaviorKinds: asStringArray(semanticExpectations.expectedBehaviorKinds, 20),
|
|
445
|
+
expectedRuntimeFlows: asStringArray(semanticExpectations.expectedRuntimeFlows, 20),
|
|
446
|
+
expectedRolloutUnits: asStringArray(semanticExpectations.expectedRolloutUnits, 20),
|
|
447
|
+
}
|
|
448
|
+
: null,
|
|
449
|
+
contextFiles: Array.isArray(context.contextFiles)
|
|
450
|
+
? context.contextFiles
|
|
451
|
+
.map((entry) => asRecord(entry))
|
|
452
|
+
.filter((entry) => entry !== null)
|
|
453
|
+
.map((entry) => (typeof entry.path === 'string' ? entry.path : ''))
|
|
454
|
+
.filter((entry) => entry.length > 0)
|
|
455
|
+
.slice(0, 16)
|
|
456
|
+
: [],
|
|
457
|
+
relatedModules: asStringArray(context.relatedModules, 20),
|
|
458
|
+
serviceBoundaries: Array.isArray(context.serviceBoundaries)
|
|
459
|
+
? context.serviceBoundaries
|
|
460
|
+
.map((entry) => asRecord(entry))
|
|
461
|
+
.filter((entry) => entry !== null)
|
|
462
|
+
.map((entry) => `${typeof entry.name === 'string' ? entry.name : 'unknown'}:${typeof entry.path === 'string' ? entry.path : ''}`)
|
|
463
|
+
.filter((entry) => !entry.endsWith(':'))
|
|
464
|
+
.slice(0, 16)
|
|
465
|
+
: [],
|
|
466
|
+
ownershipBoundaries: Array.isArray(context.ownershipBoundaries)
|
|
467
|
+
? context.ownershipBoundaries
|
|
468
|
+
.map((entry) => asRecord(entry))
|
|
469
|
+
.filter((entry) => entry !== null)
|
|
470
|
+
.map((entry) => ({
|
|
471
|
+
name: typeof entry.name === 'string' ? entry.name : 'unknown',
|
|
472
|
+
domain: typeof entry.domain === 'string' ? entry.domain : 'unknown',
|
|
473
|
+
kind: typeof entry.kind === 'string' ? entry.kind : 'unknown',
|
|
474
|
+
primaryOwner: typeof entry.primaryOwner === 'string' ? entry.primaryOwner : 'unknown',
|
|
475
|
+
responsibilities: asStringArray(entry.responsibilities, 12),
|
|
476
|
+
forbiddenResponsibilities: asStringArray(entry.forbiddenResponsibilities, 12),
|
|
477
|
+
criticality: typeof entry.criticality === 'string' ? entry.criticality : 'standard',
|
|
478
|
+
}))
|
|
479
|
+
.slice(0, 16)
|
|
480
|
+
: [],
|
|
481
|
+
invariants: Array.isArray(context.invariants)
|
|
482
|
+
? context.invariants
|
|
483
|
+
.map((entry) => asRecord(entry))
|
|
484
|
+
.filter((entry) => entry !== null)
|
|
485
|
+
.map((entry) => ({
|
|
486
|
+
id: typeof entry.id === 'string' ? entry.id : 'unknown',
|
|
487
|
+
name: typeof entry.name === 'string' ? entry.name : 'Invariant',
|
|
488
|
+
category: typeof entry.category === 'string' ? entry.category : 'unknown',
|
|
489
|
+
expectation: typeof entry.expectation === 'string' ? entry.expectation : 'Expectation unavailable.',
|
|
490
|
+
impact: typeof entry.impact === 'string' ? entry.impact : 'unknown',
|
|
491
|
+
boundaryName: typeof entry.boundaryName === 'string' ? entry.boundaryName : null,
|
|
492
|
+
}))
|
|
493
|
+
.slice(0, 20)
|
|
494
|
+
: [],
|
|
495
|
+
invariantMemory: (() => {
|
|
496
|
+
const memory = asRecord(context.invariantMemory);
|
|
497
|
+
if (!memory)
|
|
498
|
+
return null;
|
|
499
|
+
return {
|
|
500
|
+
invariantMemoryId: typeof memory.invariantMemoryId === 'string' ? memory.invariantMemoryId : null,
|
|
501
|
+
historicalDriftPatterns: Array.isArray(memory.historicalDriftPatterns)
|
|
502
|
+
? memory.historicalDriftPatterns
|
|
503
|
+
.map((entry) => asRecord(entry))
|
|
504
|
+
.filter((entry) => entry !== null)
|
|
505
|
+
.map((entry) => ({
|
|
506
|
+
category: typeof entry.category === 'string' ? entry.category : 'unknown',
|
|
507
|
+
count: typeof entry.count === 'number' ? entry.count : 0,
|
|
508
|
+
latestSummary: typeof entry.latestSummary === 'string' ? entry.latestSummary : '',
|
|
509
|
+
}))
|
|
510
|
+
.slice(0, 12)
|
|
511
|
+
: [],
|
|
512
|
+
};
|
|
513
|
+
})(),
|
|
514
|
+
runtimeBehaviors: Array.isArray(context.runtimeBehaviors)
|
|
515
|
+
? context.runtimeBehaviors
|
|
516
|
+
.map((entry) => asRecord(entry))
|
|
517
|
+
.filter((entry) => entry !== null)
|
|
518
|
+
.map((entry) => ({
|
|
519
|
+
boundaryName: typeof entry.boundaryName === 'string' ? entry.boundaryName : 'unknown',
|
|
520
|
+
behaviorKinds: asStringArray(entry.behaviorKinds, 12),
|
|
521
|
+
sideEffectKinds: asStringArray(entry.sideEffectKinds, 12),
|
|
522
|
+
stateSurfaces: asStringArray(entry.stateSurfaces, 12),
|
|
523
|
+
rolloutUnits: asStringArray(entry.rolloutUnits, 12),
|
|
524
|
+
runtimeEnvironments: asStringArray(entry.runtimeEnvironments, 8),
|
|
525
|
+
criticalFlows: asStringArray(entry.criticalFlows, 12),
|
|
526
|
+
}))
|
|
527
|
+
.slice(0, 20)
|
|
528
|
+
: [],
|
|
529
|
+
runtimeInteractions: Array.isArray(context.runtimeInteractions)
|
|
530
|
+
? context.runtimeInteractions
|
|
531
|
+
.map((entry) => asRecord(entry))
|
|
532
|
+
.filter((entry) => entry !== null)
|
|
533
|
+
.map((entry) => ({
|
|
534
|
+
kind: typeof entry.kind === 'string' ? entry.kind : 'unknown',
|
|
535
|
+
fromBoundaryName: typeof entry.fromBoundaryName === 'string' ? entry.fromBoundaryName : 'unknown',
|
|
536
|
+
toBoundaryName: typeof entry.toBoundaryName === 'string' ? entry.toBoundaryName : null,
|
|
537
|
+
subject: typeof entry.subject === 'string' ? entry.subject : 'unknown',
|
|
538
|
+
rationale: typeof entry.rationale === 'string' ? entry.rationale : '',
|
|
539
|
+
}))
|
|
540
|
+
.slice(0, 24)
|
|
541
|
+
: [],
|
|
542
|
+
deploymentBoundaries: Array.isArray(context.deploymentBoundaries)
|
|
543
|
+
? context.deploymentBoundaries
|
|
544
|
+
.map((entry) => asRecord(entry))
|
|
545
|
+
.filter((entry) => entry !== null)
|
|
546
|
+
.map((entry) => ({
|
|
547
|
+
name: typeof entry.name === 'string' ? entry.name : 'unknown',
|
|
548
|
+
type: typeof entry.type === 'string' ? entry.type : 'unknown',
|
|
549
|
+
rolloutUnits: asStringArray(entry.rolloutUnits, 12),
|
|
550
|
+
runtimeEnvironments: asStringArray(entry.runtimeEnvironments, 8),
|
|
551
|
+
dependentBoundaryNames: asStringArray(entry.dependentBoundaryNames, 12),
|
|
552
|
+
}))
|
|
553
|
+
.slice(0, 16)
|
|
554
|
+
: [],
|
|
555
|
+
sessionLineage: asStringArray(context.sessionLineage, 12),
|
|
556
|
+
};
|
|
557
|
+
}
|
|
558
|
+
function extractDriftIntelligence(verifyOutput) {
|
|
559
|
+
const drift = asRecord(verifyOutput.driftIntelligence);
|
|
560
|
+
if (!drift) {
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
const findings = Array.isArray(drift.findings)
|
|
564
|
+
? drift.findings
|
|
565
|
+
.map((entry) => asRecord(entry))
|
|
566
|
+
.filter((entry) => entry !== null)
|
|
567
|
+
.map((entry) => {
|
|
568
|
+
const evidence = asRecord(entry.evidence);
|
|
569
|
+
const remediationGuidance = asRecord(entry.remediationGuidance);
|
|
570
|
+
return {
|
|
571
|
+
category: typeof entry.category === 'string' ? entry.category : 'unknown',
|
|
572
|
+
severity: typeof entry.severity === 'string' ? entry.severity : 'unknown',
|
|
573
|
+
message: typeof entry.message === 'string' ? entry.message : 'Drift signal detected.',
|
|
574
|
+
rationale: typeof entry.rationale === 'string' ? entry.rationale : null,
|
|
575
|
+
file: typeof entry.file === 'string' ? entry.file : null,
|
|
576
|
+
module: typeof entry.module === 'string' ? entry.module : null,
|
|
577
|
+
service: typeof entry.service === 'string' ? entry.service : null,
|
|
578
|
+
evidenceTier: typeof entry.evidenceTier === 'string' ? entry.evidenceTier : null,
|
|
579
|
+
actionability: typeof entry.actionability === 'string' ? entry.actionability : null,
|
|
580
|
+
priority: typeof entry.priority === 'string' ? entry.priority : null,
|
|
581
|
+
governanceGate: typeof entry.governanceGate === 'string' ? entry.governanceGate : null,
|
|
582
|
+
rolloutTrust: typeof entry.rolloutTrust === 'string' ? entry.rolloutTrust : null,
|
|
583
|
+
relationships: Array.isArray(entry.relationships)
|
|
584
|
+
? entry.relationships
|
|
585
|
+
.map((relationship) => asRecord(relationship))
|
|
586
|
+
.filter((relationship) => relationship !== null)
|
|
587
|
+
.map((relationship) => ({
|
|
588
|
+
type: typeof relationship.type === 'string' ? relationship.type : 'derived-from',
|
|
589
|
+
targetFindingId: typeof relationship.targetFindingId === 'string'
|
|
590
|
+
? relationship.targetFindingId
|
|
591
|
+
: '',
|
|
592
|
+
rationale: typeof relationship.rationale === 'string'
|
|
593
|
+
? relationship.rationale
|
|
594
|
+
: 'Finding relationship rationale unavailable.',
|
|
595
|
+
}))
|
|
596
|
+
.filter((relationship) => relationship.targetFindingId.length > 0)
|
|
597
|
+
.slice(0, 4)
|
|
598
|
+
: [],
|
|
599
|
+
governanceDecision: extractGovernanceDecisionLineage(entry.governanceDecision),
|
|
600
|
+
evidence: evidence
|
|
601
|
+
? {
|
|
602
|
+
tier: typeof evidence.tier === 'string' ? evidence.tier : null,
|
|
603
|
+
changedFiles: asStringArray(evidence.changedFiles, 8),
|
|
604
|
+
changedLines: Array.isArray(evidence.changedLines)
|
|
605
|
+
? evidence.changedLines
|
|
606
|
+
.map((line) => asRecord(line))
|
|
607
|
+
.filter((line) => line !== null)
|
|
608
|
+
.map((line) => ({
|
|
609
|
+
file: typeof line.file === 'string' ? line.file : 'unknown',
|
|
610
|
+
line: typeof line.line === 'number' ? line.line : 0,
|
|
611
|
+
text: typeof line.text === 'string' ? line.text : '',
|
|
612
|
+
}))
|
|
613
|
+
.filter((line) => line.line > 0 || line.text.length > 0)
|
|
614
|
+
.slice(0, 8)
|
|
615
|
+
: [],
|
|
616
|
+
dependencyEdges: asStringArray(evidence.dependencyEdges, 8),
|
|
617
|
+
boundary: typeof evidence.boundary === 'string' ? evidence.boundary : null,
|
|
618
|
+
explanation: typeof evidence.explanation === 'string' ? evidence.explanation : null,
|
|
619
|
+
}
|
|
620
|
+
: null,
|
|
621
|
+
remediationGuidance: remediationGuidance
|
|
622
|
+
? {
|
|
623
|
+
actionability: typeof remediationGuidance.actionability === 'string'
|
|
624
|
+
? remediationGuidance.actionability
|
|
625
|
+
: null,
|
|
626
|
+
evidenceTier: typeof remediationGuidance.evidenceTier === 'string'
|
|
627
|
+
? remediationGuidance.evidenceTier
|
|
628
|
+
: null,
|
|
629
|
+
minimalCorrection: typeof remediationGuidance.minimalCorrection === 'string'
|
|
630
|
+
? remediationGuidance.minimalCorrection
|
|
631
|
+
: null,
|
|
632
|
+
boundaryToPreserve: typeof remediationGuidance.boundaryToPreserve === 'string'
|
|
633
|
+
? remediationGuidance.boundaryToPreserve
|
|
634
|
+
: null,
|
|
635
|
+
verifyAfterRemediation: typeof remediationGuidance.verifyAfterRemediation === 'string'
|
|
636
|
+
? remediationGuidance.verifyAfterRemediation
|
|
637
|
+
: null,
|
|
638
|
+
uncertainty: asStringArray(remediationGuidance.uncertainty, 6),
|
|
639
|
+
}
|
|
640
|
+
: null,
|
|
641
|
+
};
|
|
642
|
+
})
|
|
643
|
+
.slice(0, 8)
|
|
644
|
+
: [];
|
|
645
|
+
const narratives = Array.isArray(drift.narratives)
|
|
646
|
+
? drift.narratives
|
|
647
|
+
.map((entry) => asRecord(entry))
|
|
648
|
+
.filter((entry) => entry !== null)
|
|
649
|
+
.map((entry) => ({
|
|
650
|
+
category: typeof entry.category === 'string' ? entry.category : 'unknown',
|
|
651
|
+
severity: typeof entry.severity === 'string' ? entry.severity : 'unknown',
|
|
652
|
+
summary: typeof entry.summary === 'string' ? entry.summary : 'Compressed governance narrative detected.',
|
|
653
|
+
rootCause: typeof entry.rootCause === 'string' ? entry.rootCause : 'Root cause unavailable.',
|
|
654
|
+
operationalRisk: typeof entry.operationalRisk === 'string' ? entry.operationalRisk : 'Operational risk unavailable.',
|
|
655
|
+
remediationBoundary: typeof entry.remediationBoundary === 'string' ? entry.remediationBoundary : 'Keep remediation inside the approved scope.',
|
|
656
|
+
causalChain: asStringArray(entry.causalChain, 8),
|
|
657
|
+
affectedFiles: asStringArray(entry.affectedFiles, 16),
|
|
658
|
+
affectedModules: asStringArray(entry.affectedModules, 16),
|
|
659
|
+
affectedServices: asStringArray(entry.affectedServices, 16),
|
|
660
|
+
}))
|
|
661
|
+
.slice(0, 6)
|
|
662
|
+
: [];
|
|
663
|
+
const riskSynthesisRecord = asRecord(drift.riskSynthesis);
|
|
664
|
+
const priorityCountsRecord = asRecord(riskSynthesisRecord?.priorityCounts);
|
|
665
|
+
const governancePostureRecord = asRecord(drift.governancePosture);
|
|
666
|
+
const posturePriorityCountsRecord = asRecord(governancePostureRecord?.priorityCounts);
|
|
667
|
+
const governanceDecisionsRecord = asRecord(drift.governanceDecisions);
|
|
668
|
+
return {
|
|
669
|
+
source: typeof drift.source === 'string' ? drift.source : null,
|
|
670
|
+
confidence: typeof drift.confidence === 'string' ? drift.confidence : null,
|
|
671
|
+
rolloutRisk: typeof drift.rolloutRisk === 'string' ? drift.rolloutRisk : null,
|
|
672
|
+
unexpectedFiles: asStringArray(drift.unexpectedFiles, 20),
|
|
673
|
+
unexpectedModules: asStringArray(drift.unexpectedModules, 20),
|
|
674
|
+
unexpectedServices: asStringArray(drift.unexpectedServices, 20),
|
|
675
|
+
impactedModules: asStringArray(drift.impactedModules, 20),
|
|
676
|
+
impactedServices: asStringArray(drift.impactedServices, 20),
|
|
677
|
+
impactedRuntimeFlows: asStringArray(drift.impactedRuntimeFlows, 20),
|
|
678
|
+
affectedRolloutUnits: asStringArray(drift.affectedRolloutUnits, 20),
|
|
679
|
+
findings,
|
|
680
|
+
narratives,
|
|
681
|
+
riskSynthesis: riskSynthesisRecord
|
|
682
|
+
? {
|
|
683
|
+
overallRisk: typeof riskSynthesisRecord.overallRisk === 'string' ? riskSynthesisRecord.overallRisk : null,
|
|
684
|
+
summary: typeof riskSynthesisRecord.summary === 'string' ? riskSynthesisRecord.summary : null,
|
|
685
|
+
primaryNarratives: asStringArray(riskSynthesisRecord.primaryNarratives, 6),
|
|
686
|
+
rawFindingCount: typeof riskSynthesisRecord.rawFindingCount === 'number' ? riskSynthesisRecord.rawFindingCount : null,
|
|
687
|
+
compressedNarrativeCount: typeof riskSynthesisRecord.compressedNarrativeCount === 'number'
|
|
688
|
+
? riskSynthesisRecord.compressedNarrativeCount
|
|
689
|
+
: null,
|
|
690
|
+
authExposure: riskSynthesisRecord.authExposure === true,
|
|
691
|
+
infraExposure: riskSynthesisRecord.infraExposure === true,
|
|
692
|
+
deploymentExposure: riskSynthesisRecord.deploymentExposure === true,
|
|
693
|
+
dependencyExposure: riskSynthesisRecord.dependencyExposure === true,
|
|
694
|
+
transitiveImpactCount: typeof riskSynthesisRecord.transitiveImpactCount === 'number'
|
|
695
|
+
? riskSynthesisRecord.transitiveImpactCount
|
|
696
|
+
: null,
|
|
697
|
+
runtimeFlowExposure: riskSynthesisRecord.runtimeFlowExposure === true,
|
|
698
|
+
externalSideEffectExposure: riskSynthesisRecord.externalSideEffectExposure === true,
|
|
699
|
+
stateOwnershipExposure: riskSynthesisRecord.stateOwnershipExposure === true,
|
|
700
|
+
affectedRolloutUnits: asStringArray(riskSynthesisRecord.affectedRolloutUnits, 12),
|
|
701
|
+
cascadingRisk: typeof riskSynthesisRecord.cascadingRisk === 'string'
|
|
702
|
+
? riskSynthesisRecord.cascadingRisk
|
|
703
|
+
: null,
|
|
704
|
+
rolloutTrust: typeof riskSynthesisRecord.rolloutTrust === 'string'
|
|
705
|
+
? riskSynthesisRecord.rolloutTrust
|
|
706
|
+
: null,
|
|
707
|
+
governanceGate: typeof riskSynthesisRecord.governanceGate === 'string'
|
|
708
|
+
? riskSynthesisRecord.governanceGate
|
|
709
|
+
: null,
|
|
710
|
+
postureSummary: typeof riskSynthesisRecord.postureSummary === 'string'
|
|
711
|
+
? riskSynthesisRecord.postureSummary
|
|
712
|
+
: null,
|
|
713
|
+
priorityCounts: priorityCountsRecord
|
|
714
|
+
? {
|
|
715
|
+
p0RolloutBlockers: typeof priorityCountsRecord.p0RolloutBlockers === 'number'
|
|
716
|
+
? priorityCountsRecord.p0RolloutBlockers
|
|
717
|
+
: 0,
|
|
718
|
+
p1ArchitectureBlockers: typeof priorityCountsRecord.p1ArchitectureBlockers === 'number'
|
|
719
|
+
? priorityCountsRecord.p1ArchitectureBlockers
|
|
720
|
+
: 0,
|
|
721
|
+
p2ReviewRequired: typeof priorityCountsRecord.p2ReviewRequired === 'number'
|
|
722
|
+
? priorityCountsRecord.p2ReviewRequired
|
|
723
|
+
: 0,
|
|
724
|
+
p3Advisory: typeof priorityCountsRecord.p3Advisory === 'number'
|
|
725
|
+
? priorityCountsRecord.p3Advisory
|
|
726
|
+
: 0,
|
|
727
|
+
}
|
|
728
|
+
: null,
|
|
729
|
+
remediationOrder: asStringArray(riskSynthesisRecord.remediationOrder, 12),
|
|
730
|
+
}
|
|
731
|
+
: null,
|
|
732
|
+
governancePosture: governancePostureRecord
|
|
733
|
+
? {
|
|
734
|
+
rolloutTrust: typeof governancePostureRecord.rolloutTrust === 'string'
|
|
735
|
+
? governancePostureRecord.rolloutTrust
|
|
736
|
+
: null,
|
|
737
|
+
governanceGate: typeof governancePostureRecord.governanceGate === 'string'
|
|
738
|
+
? governancePostureRecord.governanceGate
|
|
739
|
+
: null,
|
|
740
|
+
summary: typeof governancePostureRecord.summary === 'string'
|
|
741
|
+
? governancePostureRecord.summary
|
|
742
|
+
: null,
|
|
743
|
+
reasons: asStringArray(governancePostureRecord.reasons, 6),
|
|
744
|
+
priorityCounts: posturePriorityCountsRecord
|
|
745
|
+
? {
|
|
746
|
+
p0RolloutBlockers: typeof posturePriorityCountsRecord.p0RolloutBlockers === 'number'
|
|
747
|
+
? posturePriorityCountsRecord.p0RolloutBlockers
|
|
748
|
+
: 0,
|
|
749
|
+
p1ArchitectureBlockers: typeof posturePriorityCountsRecord.p1ArchitectureBlockers === 'number'
|
|
750
|
+
? posturePriorityCountsRecord.p1ArchitectureBlockers
|
|
751
|
+
: 0,
|
|
752
|
+
p2ReviewRequired: typeof posturePriorityCountsRecord.p2ReviewRequired === 'number'
|
|
753
|
+
? posturePriorityCountsRecord.p2ReviewRequired
|
|
754
|
+
: 0,
|
|
755
|
+
p3Advisory: typeof posturePriorityCountsRecord.p3Advisory === 'number'
|
|
756
|
+
? posturePriorityCountsRecord.p3Advisory
|
|
757
|
+
: 0,
|
|
758
|
+
}
|
|
759
|
+
: null,
|
|
760
|
+
remediationOrder: asStringArray(governancePostureRecord.remediationOrder, 12),
|
|
761
|
+
}
|
|
762
|
+
: null,
|
|
763
|
+
governanceDecisions: governanceDecisionsRecord
|
|
764
|
+
? {
|
|
765
|
+
sourcePath: typeof governanceDecisionsRecord.sourcePath === 'string'
|
|
766
|
+
? governanceDecisionsRecord.sourcePath
|
|
767
|
+
: null,
|
|
768
|
+
decisionsApplied: typeof governanceDecisionsRecord.decisionsApplied === 'number'
|
|
769
|
+
? governanceDecisionsRecord.decisionsApplied
|
|
770
|
+
: 0,
|
|
771
|
+
activeOverrides: typeof governanceDecisionsRecord.activeOverrides === 'number'
|
|
772
|
+
? governanceDecisionsRecord.activeOverrides
|
|
773
|
+
: 0,
|
|
774
|
+
expiredOverrides: typeof governanceDecisionsRecord.expiredOverrides === 'number'
|
|
775
|
+
? governanceDecisionsRecord.expiredOverrides
|
|
776
|
+
: 0,
|
|
777
|
+
findingsChanged: typeof governanceDecisionsRecord.findingsChanged === 'number'
|
|
778
|
+
? governanceDecisionsRecord.findingsChanged
|
|
779
|
+
: 0,
|
|
780
|
+
lineage: Array.isArray(governanceDecisionsRecord.lineage)
|
|
781
|
+
? governanceDecisionsRecord.lineage
|
|
782
|
+
.map((entry) => extractGovernanceDecisionLineage(entry))
|
|
783
|
+
.filter((entry) => entry !== null)
|
|
784
|
+
.slice(0, 12)
|
|
785
|
+
: [],
|
|
786
|
+
}
|
|
787
|
+
: null,
|
|
788
|
+
};
|
|
789
|
+
}
|
|
790
|
+
function extractIntentGovernance(verifyOutput) {
|
|
791
|
+
const intentGovernance = asRecord(verifyOutput.intentGovernance);
|
|
792
|
+
if (!intentGovernance) {
|
|
793
|
+
return null;
|
|
794
|
+
}
|
|
795
|
+
return {
|
|
796
|
+
source: typeof intentGovernance.source === 'string' ? intentGovernance.source : null,
|
|
797
|
+
deterministic: intentGovernance.deterministic === true,
|
|
798
|
+
flagged: intentGovernance.flagged === true,
|
|
799
|
+
confidence: typeof intentGovernance.confidence === 'string' ? intentGovernance.confidence : null,
|
|
800
|
+
rolloutRisk: typeof intentGovernance.rolloutRisk === 'string' ? intentGovernance.rolloutRisk : null,
|
|
801
|
+
canonicalFindingCount: typeof intentGovernance.canonicalFindingCount === 'number' ? intentGovernance.canonicalFindingCount : null,
|
|
802
|
+
blockingFindingCount: typeof intentGovernance.blockingFindingCount === 'number' ? intentGovernance.blockingFindingCount : null,
|
|
803
|
+
advisoryFindingCount: typeof intentGovernance.advisoryFindingCount === 'number' ? intentGovernance.advisoryFindingCount : null,
|
|
804
|
+
riskSummary: typeof intentGovernance.riskSummary === 'string' ? intentGovernance.riskSummary : null,
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
function extractGraphImpact(verifyOutput) {
|
|
808
|
+
const blastRadius = asRecord(verifyOutput.blastRadius);
|
|
809
|
+
if (!blastRadius) {
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
return {
|
|
813
|
+
affectedServices: asStringArray(blastRadius.affectedServices, 20),
|
|
814
|
+
impactedModules: asStringArray(blastRadius.impactedModules, 20),
|
|
815
|
+
impactedServices: asStringArray(blastRadius.impactedServices, 20),
|
|
816
|
+
transitiveImpactCount: typeof blastRadius.transitiveImpactCount === 'number' ? blastRadius.transitiveImpactCount : null,
|
|
817
|
+
rolloutComplexity: typeof blastRadius.rolloutComplexity === 'string' ? blastRadius.rolloutComplexity : null,
|
|
818
|
+
affectedRuntimeFlows: asStringArray(blastRadius.affectedRuntimeFlows, 20),
|
|
819
|
+
affectedRolloutUnits: asStringArray(blastRadius.affectedRolloutUnits, 20),
|
|
820
|
+
cascadingRisk: typeof blastRadius.cascadingRisk === 'string' ? blastRadius.cascadingRisk : null,
|
|
821
|
+
stateOwnershipExposure: blastRadius.stateOwnershipExposure === true,
|
|
822
|
+
externalSideEffectExposure: blastRadius.externalSideEffectExposure === true,
|
|
823
|
+
authTouched: blastRadius.authTouched === true,
|
|
824
|
+
apiTouched: blastRadius.apiTouched === true,
|
|
825
|
+
infraTouched: blastRadius.infraTouched === true,
|
|
826
|
+
deploymentTouched: blastRadius.deploymentTouched === true,
|
|
827
|
+
dependencyManifestTouched: blastRadius.dependencyManifestTouched === true,
|
|
828
|
+
};
|
|
829
|
+
}
|
|
830
|
+
function deriveModulePathForExport(filePath) {
|
|
831
|
+
const normalized = filePath.replace(/\\/g, '/').replace(/^\.\//, '').trim();
|
|
832
|
+
const parts = normalized.split('/').filter(Boolean);
|
|
833
|
+
if (parts.length <= 1)
|
|
834
|
+
return parts[0] || normalized;
|
|
835
|
+
if (['src', 'app', 'apps', 'services', 'packages', 'libs', 'lib', 'web'].includes(parts[0]) && parts.length >= 2) {
|
|
836
|
+
return `${parts[0]}/${parts[1]}`;
|
|
837
|
+
}
|
|
838
|
+
return parts[0];
|
|
839
|
+
}
|
|
840
|
+
function selectRelevantNarratives(driftIntelligence, filePath, ruleId) {
|
|
841
|
+
if (!driftIntelligence || driftIntelligence.narratives.length === 0) {
|
|
842
|
+
return [];
|
|
843
|
+
}
|
|
844
|
+
const moduleName = deriveModulePathForExport(filePath);
|
|
845
|
+
const driftRuleCategory = ruleId.startsWith('drift_') && ruleId.includes(':')
|
|
846
|
+
? ruleId.split(':').slice(1).join(':')
|
|
847
|
+
: null;
|
|
848
|
+
const matched = driftIntelligence.narratives.filter((entry) => entry.affectedFiles.includes(filePath)
|
|
849
|
+
|| entry.affectedModules.includes(moduleName)
|
|
850
|
+
|| (driftRuleCategory ? entry.category.includes(driftRuleCategory.replace('drift_intelligence:', '')) : false));
|
|
851
|
+
const selected = matched.length > 0 ? matched : driftIntelligence.narratives.slice(0, 3);
|
|
852
|
+
return selected.slice(0, 3).map((entry) => ({
|
|
853
|
+
category: entry.category,
|
|
854
|
+
severity: entry.severity,
|
|
855
|
+
summary: entry.summary,
|
|
856
|
+
rootCause: entry.rootCause,
|
|
857
|
+
operationalRisk: entry.operationalRisk,
|
|
858
|
+
remediationBoundary: entry.remediationBoundary,
|
|
859
|
+
causalChain: entry.causalChain.slice(0, 5),
|
|
860
|
+
}));
|
|
861
|
+
}
|
|
862
|
+
function dedupeStrings(values, limit = 12) {
|
|
863
|
+
return [...new Set(values.map((value) => value.trim()).filter(Boolean))].slice(0, limit);
|
|
864
|
+
}
|
|
865
|
+
function deriveSemanticExportInsights(engineeringContext, driftIntelligence, relevantNarratives, filePath) {
|
|
866
|
+
const moduleName = deriveModulePathForExport(filePath);
|
|
867
|
+
const touchedOwnership = engineeringContext?.ownershipBoundaries.filter((boundary) => boundary.name === moduleName
|
|
868
|
+
|| driftIntelligence?.unexpectedModules.includes(boundary.name)
|
|
869
|
+
|| driftIntelligence?.unexpectedServices.includes(boundary.name)
|
|
870
|
+
|| relevantNarratives.some((entry) => entry.summary.includes(boundary.name))) || [];
|
|
871
|
+
const violatedContracts = dedupeStrings([
|
|
872
|
+
...(engineeringContext?.semanticExpectations?.contractIds || []),
|
|
873
|
+
...touchedOwnership.flatMap((boundary) => boundary.forbiddenResponsibilities.map((item) => `${boundary.name}:${item}`)),
|
|
874
|
+
], 16);
|
|
875
|
+
const ownershipBoundaryCrossed = dedupeStrings(touchedOwnership.map((boundary) => `${boundary.name} (${boundary.primaryOwner})`), 12);
|
|
876
|
+
const invariantSummaries = dedupeStrings([
|
|
877
|
+
...(engineeringContext?.invariants
|
|
878
|
+
.filter((invariant) => !invariant.boundaryName
|
|
879
|
+
|| touchedOwnership.some((boundary) => boundary.name === invariant.boundaryName)
|
|
880
|
+
|| relevantNarratives.some((entry) => entry.summary.includes(invariant.boundaryName || ''))
|
|
881
|
+
|| invariant.expectation.includes(moduleName))
|
|
882
|
+
.map((invariant) => invariant.expectation) || []),
|
|
883
|
+
...relevantNarratives
|
|
884
|
+
.filter((entry) => entry.category === 'ownership-boundary-breach'
|
|
885
|
+
|| entry.category === 'architectural-invariant-erosion'
|
|
886
|
+
|| entry.category === 'semantic-coupling')
|
|
887
|
+
.map((entry) => entry.rootCause),
|
|
888
|
+
], 12);
|
|
889
|
+
const semanticRiskSummary = relevantNarratives[0]?.operationalRisk
|
|
890
|
+
|| driftIntelligence?.riskSynthesis?.summary
|
|
891
|
+
|| null;
|
|
892
|
+
return {
|
|
893
|
+
violatedContracts,
|
|
894
|
+
ownershipBoundaryCrossed,
|
|
895
|
+
invariantSummaries,
|
|
896
|
+
semanticRiskSummary,
|
|
897
|
+
};
|
|
898
|
+
}
|
|
899
|
+
function buildMcpContext(surroundingContext, engineeringContext, driftIntelligence, graphImpact, relevantNarratives, semanticInsights, intentGovernance) {
|
|
900
|
+
const lines = [];
|
|
901
|
+
if (engineeringContext?.intentSummary) {
|
|
902
|
+
lines.push(`Intent: ${engineeringContext.intentSummary}`);
|
|
903
|
+
}
|
|
904
|
+
if (engineeringContext) {
|
|
905
|
+
lines.push(`Approved scope: files=${engineeringContext.approvedScope.files.slice(0, 6).join(', ') || 'none'}; modules=${engineeringContext.approvedScope.modules.slice(0, 6).join(', ') || 'none'}; services=${engineeringContext.approvedScope.services.slice(0, 6).join(', ') || 'none'}`);
|
|
906
|
+
}
|
|
907
|
+
if (driftIntelligence?.riskSynthesis?.summary) {
|
|
908
|
+
lines.push(`Risk synthesis: ${driftIntelligence.riskSynthesis.summary}`);
|
|
909
|
+
}
|
|
910
|
+
if (driftIntelligence?.governancePosture?.summary) {
|
|
911
|
+
lines.push(`Governance posture: ${driftIntelligence.governancePosture.governanceGate || 'advisory'} / ${driftIntelligence.governancePosture.rolloutTrust || 'rollout-safe'} — ${driftIntelligence.governancePosture.summary}`);
|
|
912
|
+
}
|
|
913
|
+
if (driftIntelligence?.governanceDecisions && driftIntelligence.governanceDecisions.decisionsApplied > 0) {
|
|
914
|
+
lines.push(`Governance decisions: ${driftIntelligence.governanceDecisions.activeOverrides} active, ${driftIntelligence.governanceDecisions.expiredOverrides} expired/invalid, ${driftIntelligence.governanceDecisions.findingsChanged} changed finding posture.`);
|
|
915
|
+
}
|
|
916
|
+
if (driftIntelligence?.findings.length) {
|
|
917
|
+
driftIntelligence.findings.slice(0, 3).forEach((finding, index) => {
|
|
918
|
+
lines.push(`Drift evidence ${index + 1}: [${finding.priority || 'p2-review-required'} / ${finding.governanceGate || 'review-blocker'} / ${finding.actionability || 'review-required'} / ${finding.evidenceTier || 'unknown-evidence'}] ${finding.message}`);
|
|
919
|
+
if (finding.rolloutTrust) {
|
|
920
|
+
lines.push(`Rollout posture ${index + 1}: ${finding.rolloutTrust}`);
|
|
921
|
+
}
|
|
922
|
+
if (finding.evidence?.explanation) {
|
|
923
|
+
lines.push(`Evidence basis ${index + 1}: ${finding.evidence.explanation}`);
|
|
924
|
+
}
|
|
925
|
+
if (finding.evidence?.changedLines.length) {
|
|
926
|
+
const lineRefs = finding.evidence.changedLines
|
|
927
|
+
.slice(0, 3)
|
|
928
|
+
.map((line) => `${line.file}:${line.line}`)
|
|
929
|
+
.join(', ');
|
|
930
|
+
lines.push(`Changed-line evidence ${index + 1}: ${lineRefs}`);
|
|
931
|
+
}
|
|
932
|
+
if (finding.evidence?.dependencyEdges.length) {
|
|
933
|
+
lines.push(`Dependency edge evidence ${index + 1}: ${finding.evidence.dependencyEdges.slice(0, 4).join(' | ')}`);
|
|
934
|
+
}
|
|
935
|
+
if (finding.relationships.length) {
|
|
936
|
+
lines.push(`Finding relationship ${index + 1}: ${finding.relationships
|
|
937
|
+
.slice(0, 2)
|
|
938
|
+
.map((relationship) => `${relationship.type}->${relationship.targetFindingId}`)
|
|
939
|
+
.join(' | ')}`);
|
|
940
|
+
}
|
|
941
|
+
if (finding.governanceDecision) {
|
|
942
|
+
lines.push(`Governance decision ${index + 1}: ${finding.governanceDecision.state} by ${finding.governanceDecision.actor}; reason=${finding.governanceDecision.reason}; lineage=${finding.governanceDecision.lineageHash}`);
|
|
943
|
+
}
|
|
944
|
+
if (finding.remediationGuidance?.minimalCorrection) {
|
|
945
|
+
lines.push(`Bounded correction ${index + 1}: ${finding.remediationGuidance.minimalCorrection}`);
|
|
946
|
+
}
|
|
947
|
+
if (finding.remediationGuidance?.uncertainty.length) {
|
|
948
|
+
lines.push(`Uncertainty ${index + 1}: ${finding.remediationGuidance.uncertainty.slice(0, 2).join(' | ')}`);
|
|
949
|
+
}
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
if (intentGovernance) {
|
|
953
|
+
lines.push(`Intent governance: source=${intentGovernance.source || 'unknown'}; deterministic=${intentGovernance.deterministic ? 'yes' : 'no'}; findings=${intentGovernance.canonicalFindingCount ?? 0}; blocking=${intentGovernance.blockingFindingCount ?? 0}; rollout=${intentGovernance.rolloutRisk || 'unknown'}`);
|
|
954
|
+
}
|
|
955
|
+
if (semanticInsights.ownershipBoundaryCrossed.length > 0) {
|
|
956
|
+
lines.push(`Ownership boundary: ${semanticInsights.ownershipBoundaryCrossed.join(' | ')}`);
|
|
957
|
+
}
|
|
958
|
+
if (semanticInsights.violatedContracts.length > 0) {
|
|
959
|
+
lines.push(`Violated contracts: ${semanticInsights.violatedContracts.slice(0, 6).join(' | ')}`);
|
|
960
|
+
}
|
|
961
|
+
if (semanticInsights.invariantSummaries.length > 0) {
|
|
962
|
+
lines.push(`Invariant expectations: ${semanticInsights.invariantSummaries.slice(0, 3).join(' | ')}`);
|
|
963
|
+
}
|
|
964
|
+
if (semanticInsights.semanticRiskSummary) {
|
|
965
|
+
lines.push(`Semantic risk: ${semanticInsights.semanticRiskSummary}`);
|
|
966
|
+
}
|
|
967
|
+
if (engineeringContext?.semanticExpectations?.expectedBehaviorKinds.length) {
|
|
968
|
+
lines.push(`Expected runtime behaviors: ${engineeringContext.semanticExpectations.expectedBehaviorKinds.slice(0, 6).join(' | ')}`);
|
|
969
|
+
}
|
|
970
|
+
if (engineeringContext?.semanticExpectations?.expectedRuntimeFlows.length) {
|
|
971
|
+
lines.push(`Expected runtime flows: ${engineeringContext.semanticExpectations.expectedRuntimeFlows.slice(0, 6).join(' | ')}`);
|
|
972
|
+
}
|
|
973
|
+
if (engineeringContext?.semanticExpectations?.expectedRolloutUnits.length) {
|
|
974
|
+
lines.push(`Expected rollout units: ${engineeringContext.semanticExpectations.expectedRolloutUnits.slice(0, 6).join(' | ')}`);
|
|
975
|
+
}
|
|
976
|
+
if (engineeringContext?.runtimeBehaviors.length) {
|
|
977
|
+
const summaries = engineeringContext.runtimeBehaviors
|
|
978
|
+
.slice(0, 4)
|
|
979
|
+
.map((entry) => `${entry.boundaryName}:${entry.behaviorKinds.slice(0, 3).join('/') || 'unknown'}`);
|
|
980
|
+
lines.push(`Runtime behaviors: ${summaries.join(' | ')}`);
|
|
981
|
+
}
|
|
982
|
+
if (engineeringContext?.deploymentBoundaries.length) {
|
|
983
|
+
const summaries = engineeringContext.deploymentBoundaries
|
|
984
|
+
.slice(0, 4)
|
|
985
|
+
.map((entry) => `${entry.name}:${entry.type}:${entry.rolloutUnits.slice(0, 2).join('/') || 'default'}`);
|
|
986
|
+
lines.push(`Deployment boundaries: ${summaries.join(' | ')}`);
|
|
987
|
+
}
|
|
988
|
+
if (relevantNarratives.length > 0) {
|
|
989
|
+
relevantNarratives.forEach((narrative, index) => {
|
|
990
|
+
lines.push(`Narrative ${index + 1}: ${narrative.summary}`);
|
|
991
|
+
lines.push(`Root cause ${index + 1}: ${narrative.rootCause}`);
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
else if (driftIntelligence?.findings.length) {
|
|
995
|
+
lines.push(`Drift: ${driftIntelligence.findings.slice(0, 3).map((entry) => entry.message).join(' | ')}`);
|
|
996
|
+
}
|
|
997
|
+
if (graphImpact) {
|
|
998
|
+
lines.push(`Graph impact: services=${graphImpact.impactedServices.slice(0, 6).join(', ') || 'none'}; modules=${graphImpact.impactedModules.slice(0, 6).join(', ') || 'none'}; rollout=${graphImpact.rolloutComplexity || 'unknown'}`);
|
|
999
|
+
if (graphImpact.affectedRuntimeFlows.length > 0) {
|
|
1000
|
+
lines.push(`Runtime flows impacted: ${graphImpact.affectedRuntimeFlows.slice(0, 6).join(' | ')}`);
|
|
1001
|
+
}
|
|
1002
|
+
if (graphImpact.affectedRolloutUnits.length > 0) {
|
|
1003
|
+
lines.push(`Rollout units impacted: ${graphImpact.affectedRolloutUnits.slice(0, 6).join(' | ')}`);
|
|
1004
|
+
}
|
|
1005
|
+
if (graphImpact.cascadingRisk) {
|
|
1006
|
+
lines.push(`Cascading risk: ${graphImpact.cascadingRisk}`);
|
|
1007
|
+
}
|
|
1008
|
+
if (graphImpact.stateOwnershipExposure) {
|
|
1009
|
+
lines.push('State ownership risk: runtime state mutation spans multiple boundaries.');
|
|
1010
|
+
}
|
|
1011
|
+
if (graphImpact.externalSideEffectExposure) {
|
|
1012
|
+
lines.push('External side effects detected in the affected runtime path.');
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
1015
|
+
if (surroundingContext.trim().length > 0) {
|
|
1016
|
+
lines.push('Code context:');
|
|
1017
|
+
lines.push(surroundingContext);
|
|
1018
|
+
}
|
|
1019
|
+
return lines.join('\n');
|
|
1020
|
+
}
|
|
1021
|
+
function resolveReplayChecksum(verifyOutput) {
|
|
1022
|
+
const direct = typeof verifyOutput.replayChecksum === 'string' && verifyOutput.replayChecksum.trim().length > 0
|
|
1023
|
+
? verifyOutput.replayChecksum.trim()
|
|
1024
|
+
: null;
|
|
1025
|
+
if (direct)
|
|
1026
|
+
return direct;
|
|
1027
|
+
const nested = verifyOutput.governanceVerification?.replayChecksum;
|
|
1028
|
+
return typeof nested === 'string' && nested.trim().length > 0 ? nested.trim() : null;
|
|
1029
|
+
}
|
|
1030
|
+
function resolveReplayMode(verifyOutput) {
|
|
1031
|
+
const direct = typeof verifyOutput.replayMode === 'string' && verifyOutput.replayMode.trim().length > 0
|
|
1032
|
+
? verifyOutput.replayMode.trim()
|
|
1033
|
+
: null;
|
|
1034
|
+
if (direct)
|
|
1035
|
+
return direct;
|
|
1036
|
+
const policyOnly = verifyOutput.policyOnly === true;
|
|
1037
|
+
const mode = typeof verifyOutput.mode === 'string' ? verifyOutput.mode : '';
|
|
1038
|
+
if (policyOnly || mode === 'policy_only') {
|
|
1039
|
+
return 'local-structural';
|
|
1040
|
+
}
|
|
1041
|
+
return null;
|
|
1042
|
+
}
|
|
254
1043
|
function extractCodeSpan(projectRoot, filePath, line) {
|
|
255
1044
|
if (!filePath || line === null) {
|
|
256
1045
|
return { codeSpan: '(file or line not available)', surroundingContext: '' };
|