@neurcode-ai/cli 0.9.60 → 0.9.62
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/LICENSE +201 -0
- package/dist/commands/control-plane.d.ts +3 -0
- package/dist/commands/control-plane.d.ts.map +1 -0
- package/dist/commands/control-plane.js +163 -0
- package/dist/commands/control-plane.js.map +1 -0
- package/dist/commands/export.d.ts +7 -0
- package/dist/commands/export.d.ts.map +1 -0
- package/dist/commands/export.js +72 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/fix.d.ts +1 -0
- package/dist/commands/fix.d.ts.map +1 -1
- package/dist/commands/fix.js +3 -0
- package/dist/commands/fix.js.map +1 -1
- package/dist/commands/generate.d.ts +1 -0
- package/dist/commands/generate.d.ts.map +1 -1
- package/dist/commands/generate.js +63 -48
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/patch-apply.d.ts.map +1 -1
- package/dist/commands/patch-apply.js +1 -0
- package/dist/commands/patch-apply.js.map +1 -1
- package/dist/commands/replay.d.ts +3 -0
- package/dist/commands/replay.d.ts.map +1 -0
- package/dist/commands/replay.js +267 -0
- package/dist/commands/replay.js.map +1 -0
- package/dist/commands/verify.d.ts +7 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +281 -149
- package/dist/commands/verify.js.map +1 -1
- package/dist/commands/workspace.d.ts +3 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/commands/workspace.js +407 -0
- package/dist/commands/workspace.js.map +1 -0
- package/dist/daemon/server.d.ts +0 -17
- package/dist/daemon/server.d.ts.map +1 -1
- package/dist/daemon/server.js +1043 -58
- package/dist/daemon/server.js.map +1 -1
- package/dist/index.js +296 -12
- package/dist/index.js.map +1 -1
- package/dist/utils/cli-json.d.ts +1 -0
- package/dist/utils/cli-json.d.ts.map +1 -1
- package/dist/utils/cli-json.js +1 -0
- package/dist/utils/cli-json.js.map +1 -1
- package/dist/utils/control-plane.d.ts +171 -0
- package/dist/utils/control-plane.d.ts.map +1 -0
- package/dist/utils/control-plane.js +684 -0
- package/dist/utils/control-plane.js.map +1 -0
- package/dist/utils/execution-bus.d.ts +205 -0
- package/dist/utils/execution-bus.d.ts.map +1 -0
- package/dist/utils/execution-bus.js +1346 -0
- package/dist/utils/execution-bus.js.map +1 -0
- package/dist/utils/gitignore.d.ts +2 -2
- package/dist/utils/gitignore.d.ts.map +1 -1
- package/dist/utils/gitignore.js +27 -14
- package/dist/utils/gitignore.js.map +1 -1
- package/dist/utils/replay-runtime.d.ts +295 -0
- package/dist/utils/replay-runtime.d.ts.map +1 -0
- package/dist/utils/replay-runtime.js +1080 -0
- package/dist/utils/replay-runtime.js.map +1 -0
- package/dist/utils/runtime-events.d.ts +44 -0
- package/dist/utils/runtime-events.d.ts.map +1 -0
- package/dist/utils/runtime-events.js +213 -0
- package/dist/utils/runtime-events.js.map +1 -0
- package/dist/utils/verification-evidence.d.ts +22 -0
- package/dist/utils/verification-evidence.d.ts.map +1 -0
- package/dist/utils/verification-evidence.js +233 -0
- package/dist/utils/verification-evidence.js.map +1 -0
- package/dist/utils/workspace-runtime.d.ts +267 -0
- package/dist/utils/workspace-runtime.d.ts.map +1 -0
- package/dist/utils/workspace-runtime.js +1415 -0
- package/dist/utils/workspace-runtime.js.map +1 -0
- package/package.json +7 -8
package/dist/commands/verify.js
CHANGED
|
@@ -71,6 +71,7 @@ const runtime_guard_1 = require("../utils/runtime-guard");
|
|
|
71
71
|
const artifact_signature_1 = require("../utils/artifact-signature");
|
|
72
72
|
const policy_1 = require("@neurcode-ai/policy");
|
|
73
73
|
const ai_debt_budget_1 = require("../utils/ai-debt-budget");
|
|
74
|
+
const verification_evidence_1 = require("../utils/verification-evidence");
|
|
74
75
|
// Import chalk with fallback
|
|
75
76
|
let chalk;
|
|
76
77
|
try {
|
|
@@ -1023,7 +1024,7 @@ function toCanonicalVerifyOutput(payload) {
|
|
|
1023
1024
|
blockingItems = dedupeTriageItems([...regressionBlockingTriageItems, ...blockingItems]);
|
|
1024
1025
|
}
|
|
1025
1026
|
const grade = verdict === 'PASS' ? 'A' : verdict === 'WARN' ? 'C' : 'F';
|
|
1026
|
-
|
|
1027
|
+
const canonical = {
|
|
1027
1028
|
grade,
|
|
1028
1029
|
score: violations.length === 0 && warnings.length === 0 && scopeIssues.length === 0 ? 100 : 0,
|
|
1029
1030
|
verdict,
|
|
@@ -1052,9 +1053,55 @@ function toCanonicalVerifyOutput(payload) {
|
|
|
1052
1053
|
...(expediteModeUsed ? { expediteNote: 'Expedite Mode used' } : {}),
|
|
1053
1054
|
...(typeof driftScore === 'number' ? { driftScore } : {}),
|
|
1054
1055
|
};
|
|
1056
|
+
// Preserve actionable metadata from rich verify payloads so downstream
|
|
1057
|
+
// consumers (Action, CI contracts, dashboards) keep structured context.
|
|
1058
|
+
const passthroughKeys = [
|
|
1059
|
+
'message',
|
|
1060
|
+
'mode',
|
|
1061
|
+
'ciMode',
|
|
1062
|
+
'policyOnly',
|
|
1063
|
+
'policyOnlySource',
|
|
1064
|
+
'policySources',
|
|
1065
|
+
'scopeGuardPassed',
|
|
1066
|
+
'policyLock',
|
|
1067
|
+
'policyCompilation',
|
|
1068
|
+
'policyExceptions',
|
|
1069
|
+
'policyGovernance',
|
|
1070
|
+
'changeContract',
|
|
1071
|
+
'runtimeGuard',
|
|
1072
|
+
'governanceDecision',
|
|
1073
|
+
'orgGovernance',
|
|
1074
|
+
'aiChangeLog',
|
|
1075
|
+
'verificationSource',
|
|
1076
|
+
'tier',
|
|
1077
|
+
'aiDebt',
|
|
1078
|
+
'blastRadius',
|
|
1079
|
+
'suspiciousChange',
|
|
1080
|
+
'policyDecision',
|
|
1081
|
+
'policyPack',
|
|
1082
|
+
'changeContractViolations',
|
|
1083
|
+
];
|
|
1084
|
+
for (const key of passthroughKeys) {
|
|
1085
|
+
if (Object.prototype.hasOwnProperty.call(payload, key) && payload[key] !== undefined) {
|
|
1086
|
+
canonical[key] = payload[key];
|
|
1087
|
+
}
|
|
1088
|
+
}
|
|
1089
|
+
// Backward-compatibility alias: older integrations and tests expect `rule`
|
|
1090
|
+
// while canonical contract uses `policy`.
|
|
1091
|
+
canonical.violations = canonical.violations.map((item) => ({
|
|
1092
|
+
...item,
|
|
1093
|
+
rule: item.policy,
|
|
1094
|
+
}));
|
|
1095
|
+
canonical.warnings = canonical.warnings.map((item) => ({
|
|
1096
|
+
...item,
|
|
1097
|
+
rule: item.policy,
|
|
1098
|
+
}));
|
|
1099
|
+
return canonical;
|
|
1055
1100
|
}
|
|
1056
|
-
function emitCanonicalVerifyJson(payload) {
|
|
1057
|
-
|
|
1101
|
+
function emitCanonicalVerifyJson(payload, onEmit) {
|
|
1102
|
+
const canonical = toCanonicalVerifyOutput(payload);
|
|
1103
|
+
onEmit?.(canonical);
|
|
1104
|
+
console.log(JSON.stringify(canonical, null, 2));
|
|
1058
1105
|
}
|
|
1059
1106
|
function buildDeterministicLayerSummary(payload) {
|
|
1060
1107
|
const verdict = asStringValue(payload.verdict) || 'UNKNOWN';
|
|
@@ -1415,12 +1462,13 @@ async function recordVerificationIfRequested(options, config, payload) {
|
|
|
1415
1462
|
* Execute policy-only verification (General Governance mode)
|
|
1416
1463
|
* Returns the exit code to use
|
|
1417
1464
|
*/
|
|
1418
|
-
async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRoot, config, client, source, scopeTelemetry, projectId, orgGovernanceSettings, aiLogSigningKey, aiLogSigningKeyId, aiLogSigningKeys, aiLogSigner, expediteModeEnabled, compiledPolicyArtifact, compiledPolicyMetadata, changeContractSummary) {
|
|
1465
|
+
async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRoot, config, client, source, ciModeEnabled, scopeTelemetry, projectId, orgGovernanceSettings, aiLogSigningKey, aiLogSigningKeyId, aiLogSigningKeys, aiLogSigner, expediteModeEnabled, compiledPolicyArtifact, compiledPolicyMetadata, changeContractSummary, onCanonicalEmit) {
|
|
1419
1466
|
const emitPolicyOnlyJson = (payload) => {
|
|
1420
1467
|
emitCanonicalVerifyJson({
|
|
1421
1468
|
...payload,
|
|
1469
|
+
ciMode: payload.ciMode ?? ciModeEnabled,
|
|
1422
1470
|
expediteMode: expediteModeEnabled,
|
|
1423
|
-
});
|
|
1471
|
+
}, onCanonicalEmit);
|
|
1424
1472
|
};
|
|
1425
1473
|
const policyOnlyVerificationSource = 'policy_only';
|
|
1426
1474
|
const recordPolicyOnlyVerification = async (payload) => recordVerificationIfRequested(options, config, {
|
|
@@ -1902,44 +1950,50 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
|
|
|
1902
1950
|
eventCount: auditIntegrity.count,
|
|
1903
1951
|
},
|
|
1904
1952
|
};
|
|
1953
|
+
const policyOnlyPayload = {
|
|
1954
|
+
grade,
|
|
1955
|
+
score,
|
|
1956
|
+
verdict: effectiveVerdict,
|
|
1957
|
+
violations: violationsOutput,
|
|
1958
|
+
message,
|
|
1959
|
+
scopeGuardPassed: true, // N/A in policy-only mode
|
|
1960
|
+
bloatCount: 0,
|
|
1961
|
+
bloatFiles: [],
|
|
1962
|
+
plannedFilesModified: 0,
|
|
1963
|
+
totalPlannedFiles: 0,
|
|
1964
|
+
adherenceScore: score,
|
|
1965
|
+
mode: 'policy_only',
|
|
1966
|
+
policyOnly: true,
|
|
1967
|
+
policyOnlySource: source,
|
|
1968
|
+
...governancePayload,
|
|
1969
|
+
policyLock: {
|
|
1970
|
+
enforced: policyLockEvaluation.enforced,
|
|
1971
|
+
matched: policyLockEvaluation.matched,
|
|
1972
|
+
path: policyLockEvaluation.lockPath,
|
|
1973
|
+
mismatches: policyLockEvaluation.mismatches,
|
|
1974
|
+
},
|
|
1975
|
+
policyExceptions: policyExceptionsSummary,
|
|
1976
|
+
policyGovernance: policyGovernanceSummary,
|
|
1977
|
+
...(effectiveRules.policyPack
|
|
1978
|
+
? {
|
|
1979
|
+
policyPack: {
|
|
1980
|
+
id: effectiveRules.policyPack.packId,
|
|
1981
|
+
name: effectiveRules.policyPack.packName,
|
|
1982
|
+
version: effectiveRules.policyPack.version,
|
|
1983
|
+
ruleCount: effectiveRules.policyPackRules.length,
|
|
1984
|
+
},
|
|
1985
|
+
}
|
|
1986
|
+
: {}),
|
|
1987
|
+
};
|
|
1905
1988
|
if (options.json) {
|
|
1906
|
-
emitPolicyOnlyJson(
|
|
1907
|
-
grade,
|
|
1908
|
-
score,
|
|
1909
|
-
verdict: effectiveVerdict,
|
|
1910
|
-
violations: violationsOutput,
|
|
1911
|
-
message,
|
|
1912
|
-
scopeGuardPassed: true, // N/A in policy-only mode
|
|
1913
|
-
bloatCount: 0,
|
|
1914
|
-
bloatFiles: [],
|
|
1915
|
-
plannedFilesModified: 0,
|
|
1916
|
-
totalPlannedFiles: 0,
|
|
1917
|
-
adherenceScore: score,
|
|
1918
|
-
mode: 'policy_only',
|
|
1919
|
-
policyOnly: true,
|
|
1920
|
-
policyOnlySource: source,
|
|
1921
|
-
...governancePayload,
|
|
1922
|
-
policyLock: {
|
|
1923
|
-
enforced: policyLockEvaluation.enforced,
|
|
1924
|
-
matched: policyLockEvaluation.matched,
|
|
1925
|
-
path: policyLockEvaluation.lockPath,
|
|
1926
|
-
mismatches: policyLockEvaluation.mismatches,
|
|
1927
|
-
},
|
|
1928
|
-
policyExceptions: policyExceptionsSummary,
|
|
1929
|
-
policyGovernance: policyGovernanceSummary,
|
|
1930
|
-
...(effectiveRules.policyPack
|
|
1931
|
-
? {
|
|
1932
|
-
policyPack: {
|
|
1933
|
-
id: effectiveRules.policyPack.packId,
|
|
1934
|
-
name: effectiveRules.policyPack.packName,
|
|
1935
|
-
version: effectiveRules.policyPack.version,
|
|
1936
|
-
ruleCount: effectiveRules.policyPackRules.length,
|
|
1937
|
-
},
|
|
1938
|
-
}
|
|
1939
|
-
: {}),
|
|
1940
|
-
});
|
|
1989
|
+
emitPolicyOnlyJson(policyOnlyPayload);
|
|
1941
1990
|
}
|
|
1942
1991
|
else {
|
|
1992
|
+
onCanonicalEmit?.(toCanonicalVerifyOutput({
|
|
1993
|
+
...policyOnlyPayload,
|
|
1994
|
+
ciMode: ciModeEnabled,
|
|
1995
|
+
expediteMode: expediteModeEnabled,
|
|
1996
|
+
}));
|
|
1943
1997
|
if (effectiveVerdict === 'PASS') {
|
|
1944
1998
|
console.log(chalk.green('✅ Policy check passed'));
|
|
1945
1999
|
}
|
|
@@ -1979,6 +2033,7 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
|
|
|
1979
2033
|
return effectiveVerdict === 'FAIL' ? 2 : effectiveVerdict === 'WARN' ? 1 : 0;
|
|
1980
2034
|
}
|
|
1981
2035
|
async function verifyCommand(options) {
|
|
2036
|
+
let exitWithEvidenceFromTry = null;
|
|
1982
2037
|
try {
|
|
1983
2038
|
const rootResolution = (0, project_root_1.resolveNeurcodeProjectRootWithTrace)(process.cwd());
|
|
1984
2039
|
const projectRoot = rootResolution.projectRoot;
|
|
@@ -1986,9 +2041,77 @@ async function verifyCommand(options) {
|
|
|
1986
2041
|
const localPlanExpectedFiles = [...localPlanSync.expectedFiles];
|
|
1987
2042
|
const expediteModeEnabled = resolveVerifyExpediteMode(projectRoot);
|
|
1988
2043
|
const scopeTelemetry = (0, scope_telemetry_1.buildScopeTelemetryPayload)(rootResolution);
|
|
2044
|
+
const ciModeEnabled = options.ci === true || isEnabledFlag(process.env.NEURCODE_VERIFY_CI);
|
|
2045
|
+
const evidenceEnabled = options.evidence === true || isEnabledFlag(process.env.NEURCODE_VERIFY_EVIDENCE);
|
|
2046
|
+
const verifyStartedAtMs = Date.now();
|
|
2047
|
+
const evidenceCiContext = collectCIContext();
|
|
2048
|
+
let lastCanonicalOutput = null;
|
|
2049
|
+
let lastEvidenceFallbackOutput = null;
|
|
2050
|
+
let evidenceFinalizeAttempted = false;
|
|
2051
|
+
if (ciModeEnabled) {
|
|
2052
|
+
options.policyOnly = true;
|
|
2053
|
+
options.requirePlan = false;
|
|
2054
|
+
options.record = false;
|
|
2055
|
+
options.asyncMode = false;
|
|
2056
|
+
}
|
|
2057
|
+
const captureEvidencePayload = (payload) => {
|
|
2058
|
+
lastEvidenceFallbackOutput = payload;
|
|
2059
|
+
lastCanonicalOutput = toCanonicalVerifyOutput(payload);
|
|
2060
|
+
};
|
|
2061
|
+
const finalizeEvidence = (exitCode) => {
|
|
2062
|
+
if (!evidenceEnabled || evidenceFinalizeAttempted) {
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
evidenceFinalizeAttempted = true;
|
|
2066
|
+
try {
|
|
2067
|
+
const artifactPath = (0, verification_evidence_1.writeVerificationEvidence)({
|
|
2068
|
+
enabled: evidenceEnabled,
|
|
2069
|
+
projectRoot,
|
|
2070
|
+
startedAtMs: verifyStartedAtMs,
|
|
2071
|
+
exitCode,
|
|
2072
|
+
ciMode: ciModeEnabled,
|
|
2073
|
+
deterministicMode: ciModeEnabled || options.policyOnly === true,
|
|
2074
|
+
evidenceDir: options.evidenceDir,
|
|
2075
|
+
canonicalOutput: lastCanonicalOutput,
|
|
2076
|
+
fallbackOutput: lastEvidenceFallbackOutput,
|
|
2077
|
+
ciContext: evidenceCiContext,
|
|
2078
|
+
runtimeMetadata: {
|
|
2079
|
+
cliJsonContractVersion: contracts_1.CLI_JSON_CONTRACT_VERSION,
|
|
2080
|
+
runtimeCompatibilityContractVersion: contracts_1.RUNTIME_COMPATIBILITY_CONTRACT_VERSION,
|
|
2081
|
+
componentVersion: CLI_COMPONENT_VERSION,
|
|
2082
|
+
nodeVersion: process.version,
|
|
2083
|
+
platform: process.platform,
|
|
2084
|
+
arch: process.arch,
|
|
2085
|
+
command: 'verify',
|
|
2086
|
+
},
|
|
2087
|
+
});
|
|
2088
|
+
if (artifactPath && !options.json) {
|
|
2089
|
+
console.log(chalk.dim(`\n Verification evidence: ${artifactPath}`));
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
catch (error) {
|
|
2093
|
+
if (!options.json) {
|
|
2094
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2095
|
+
console.log(chalk.yellow(`\n⚠️ Failed to write verification evidence artifact: ${message}`));
|
|
2096
|
+
}
|
|
2097
|
+
}
|
|
2098
|
+
};
|
|
2099
|
+
const exitWithEvidence = (exitCode) => {
|
|
2100
|
+
finalizeEvidence(exitCode);
|
|
2101
|
+
process.exit(exitCode);
|
|
2102
|
+
};
|
|
2103
|
+
exitWithEvidenceFromTry = exitWithEvidence;
|
|
2104
|
+
// Hoisted so emitVerifyJson (called on every early-exit path) can reference
|
|
2105
|
+
// these via closure without hitting the temporal dead zone.
|
|
2106
|
+
let intentEngineIssues = [];
|
|
2107
|
+
let intentEngineDomains = [];
|
|
2108
|
+
let intentEngineSummary = null;
|
|
2109
|
+
let intentEngineFlowIssues = [];
|
|
2110
|
+
let intentEngineRegressions = [];
|
|
1989
2111
|
const emitVerifyJson = (payload) => {
|
|
1990
|
-
|
|
2112
|
+
const enrichedPayload = {
|
|
1991
2113
|
...payload,
|
|
2114
|
+
ciMode: payload.ciMode ?? ciModeEnabled,
|
|
1992
2115
|
expediteMode: expediteModeEnabled,
|
|
1993
2116
|
// Intent engine results injected so every code-path gets them.
|
|
1994
2117
|
intentIssues: payload.intentIssues ?? intentEngineIssues,
|
|
@@ -1998,6 +2121,10 @@ async function verifyCommand(options) {
|
|
|
1998
2121
|
flowIssues: payload.flowIssues ?? intentEngineFlowIssues,
|
|
1999
2122
|
// V6: regressions always injected
|
|
2000
2123
|
regressions: payload.regressions ?? intentEngineRegressions,
|
|
2124
|
+
};
|
|
2125
|
+
lastEvidenceFallbackOutput = enrichedPayload;
|
|
2126
|
+
emitCanonicalVerifyJson(enrichedPayload, (canonical) => {
|
|
2127
|
+
lastCanonicalOutput = canonical;
|
|
2001
2128
|
});
|
|
2002
2129
|
};
|
|
2003
2130
|
if (!isGitRepository(projectRoot)) {
|
|
@@ -2032,7 +2159,7 @@ async function verifyCommand(options) {
|
|
|
2032
2159
|
console.log(chalk.dim(` Current path: ${projectRoot}`));
|
|
2033
2160
|
console.log(chalk.dim(' Next step: git init && git add . && git commit -m "chore: baseline"\n'));
|
|
2034
2161
|
}
|
|
2035
|
-
|
|
2162
|
+
exitWithEvidence(1);
|
|
2036
2163
|
}
|
|
2037
2164
|
const enforceChangeContract = options.enforceChangeContract === true ||
|
|
2038
2165
|
isEnabledFlag(process.env.NEURCODE_VERIFY_ENFORCE_CHANGE_CONTRACT);
|
|
@@ -2183,7 +2310,7 @@ async function verifyCommand(options) {
|
|
|
2183
2310
|
});
|
|
2184
2311
|
console.log(chalk.dim('\nRegenerate artifacts with valid signing keys: NEURCODE_GOVERNANCE_SIGNING_KEY or NEURCODE_GOVERNANCE_SIGNING_KEYS.\n'));
|
|
2185
2312
|
}
|
|
2186
|
-
|
|
2313
|
+
exitWithEvidence(2);
|
|
2187
2314
|
}
|
|
2188
2315
|
// Advisory notice when artifact has a signature but signing is not required in this context.
|
|
2189
2316
|
if (!options.json) {
|
|
@@ -2236,7 +2363,7 @@ async function verifyCommand(options) {
|
|
|
2236
2363
|
signatureErrors.forEach((entry) => console.log(chalk.red(` • ${entry}`)));
|
|
2237
2364
|
console.log(chalk.dim('\nEnable signing keys via NEURCODE_GOVERNANCE_SIGNING_KEY or NEURCODE_GOVERNANCE_SIGNING_KEYS and regenerate artifacts.\n'));
|
|
2238
2365
|
}
|
|
2239
|
-
|
|
2366
|
+
exitWithEvidence(2);
|
|
2240
2367
|
}
|
|
2241
2368
|
}
|
|
2242
2369
|
if (!options.json) {
|
|
@@ -2304,6 +2431,14 @@ async function verifyCommand(options) {
|
|
|
2304
2431
|
// Ensure no trailing slash
|
|
2305
2432
|
config.apiUrl = config.apiUrl.replace(/\/$/, '');
|
|
2306
2433
|
}
|
|
2434
|
+
if (ciModeEnabled) {
|
|
2435
|
+
// CI mode enforces deterministic local verification and must not depend on
|
|
2436
|
+
// runtime compatibility handshakes or org-level remote settings.
|
|
2437
|
+
config.apiKey = undefined;
|
|
2438
|
+
if (!options.json) {
|
|
2439
|
+
console.log(chalk.dim(' CI mode: deterministic local verification enabled (policy-only, non-interactive).'));
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2307
2442
|
const enforceCompatibilityHandshake = isEnabledFlag(process.env.NEURCODE_VERIFY_ENFORCE_COMPAT_HANDSHAKE)
|
|
2308
2443
|
|| strictArtifactMode
|
|
2309
2444
|
|| (process.env.CI === 'true' && Boolean(config.apiKey));
|
|
@@ -2351,7 +2486,7 @@ async function verifyCommand(options) {
|
|
|
2351
2486
|
console.log(chalk.dim(` CLI version: ${CLI_COMPONENT_VERSION}`));
|
|
2352
2487
|
console.log(chalk.dim(' Upgrade/downgrade CLI, Action, or API to satisfy the runtime compatibility contract before running verify.\n'));
|
|
2353
2488
|
}
|
|
2354
|
-
|
|
2489
|
+
exitWithEvidence(2);
|
|
2355
2490
|
}
|
|
2356
2491
|
if (compatibilityProbe.status === 'error' && !options.json) {
|
|
2357
2492
|
console.log(chalk.yellow('\n⚠️ Runtime compatibility mismatch detected (advisory mode).'));
|
|
@@ -2490,7 +2625,7 @@ async function verifyCommand(options) {
|
|
|
2490
2625
|
projectId: projectId || undefined,
|
|
2491
2626
|
jsonMode: Boolean(options.json),
|
|
2492
2627
|
});
|
|
2493
|
-
|
|
2628
|
+
exitWithEvidence(2);
|
|
2494
2629
|
}
|
|
2495
2630
|
// Determine which diff to capture.
|
|
2496
2631
|
let diffText;
|
|
@@ -2547,7 +2682,7 @@ async function verifyCommand(options) {
|
|
|
2547
2682
|
});
|
|
2548
2683
|
}
|
|
2549
2684
|
recordVerifyEvent('NO_CHANGES', 'diff=empty');
|
|
2550
|
-
|
|
2685
|
+
exitWithEvidence(0);
|
|
2551
2686
|
}
|
|
2552
2687
|
// Parse tracked/staged diff and merge untracked files so plan adherence
|
|
2553
2688
|
// correctly counts newly created files before they are git-added.
|
|
@@ -2591,7 +2726,7 @@ async function verifyCommand(options) {
|
|
|
2591
2726
|
});
|
|
2592
2727
|
}
|
|
2593
2728
|
recordVerifyEvent('NO_CHANGES', 'diff_files=0');
|
|
2594
|
-
|
|
2729
|
+
exitWithEvidence(0);
|
|
2595
2730
|
}
|
|
2596
2731
|
const ignoreFilter = (0, ignore_1.loadIgnore)(projectRoot);
|
|
2597
2732
|
const runtimeIgnoreSet = getRuntimeIgnoreSetFromEnv();
|
|
@@ -2661,12 +2796,13 @@ async function verifyCommand(options) {
|
|
|
2661
2796
|
projectId: projectId || undefined,
|
|
2662
2797
|
jsonMode: Boolean(options.json),
|
|
2663
2798
|
});
|
|
2664
|
-
|
|
2799
|
+
return exitWithEvidence(2);
|
|
2665
2800
|
}
|
|
2666
|
-
const
|
|
2801
|
+
const runtimeGuardArtifact = guardRead.artifact;
|
|
2802
|
+
const runtimeGuardEvaluation = (0, runtime_guard_1.evaluateRuntimeGuardArtifact)(runtimeGuardArtifact, diffFiles.filter((file) => !shouldIgnore(file.path)));
|
|
2667
2803
|
runtimeGuardSummary = {
|
|
2668
2804
|
...runtimeGuardSummary,
|
|
2669
|
-
active:
|
|
2805
|
+
active: runtimeGuardArtifact.active,
|
|
2670
2806
|
pass: runtimeGuardEvaluation.pass,
|
|
2671
2807
|
changedFiles: runtimeGuardEvaluation.changedFiles.length,
|
|
2672
2808
|
outOfScopeFiles: runtimeGuardEvaluation.outOfScopeFiles,
|
|
@@ -2677,7 +2813,7 @@ async function verifyCommand(options) {
|
|
|
2677
2813
|
...(item.file ? { file: item.file } : {}),
|
|
2678
2814
|
})),
|
|
2679
2815
|
};
|
|
2680
|
-
const runtimeGuardUpdated = (0, runtime_guard_1.withRuntimeGuardCheckStats)(
|
|
2816
|
+
const runtimeGuardUpdated = (0, runtime_guard_1.withRuntimeGuardCheckStats)(runtimeGuardArtifact, {
|
|
2681
2817
|
blocked: !runtimeGuardEvaluation.pass,
|
|
2682
2818
|
});
|
|
2683
2819
|
(0, runtime_guard_1.writeRuntimeGuardArtifact)(projectRoot, runtimeGuardUpdated, options.runtimeGuard);
|
|
@@ -2726,7 +2862,7 @@ async function verifyCommand(options) {
|
|
|
2726
2862
|
projectId: projectId || undefined,
|
|
2727
2863
|
jsonMode: Boolean(options.json),
|
|
2728
2864
|
});
|
|
2729
|
-
|
|
2865
|
+
exitWithEvidence(2);
|
|
2730
2866
|
}
|
|
2731
2867
|
if (!options.json) {
|
|
2732
2868
|
console.log(chalk.dim(` Runtime guard passed (${runtimeGuardSummary.changedFiles} changed file(s), ` +
|
|
@@ -2805,7 +2941,7 @@ async function verifyCommand(options) {
|
|
|
2805
2941
|
jsonMode: Boolean(options.json),
|
|
2806
2942
|
governance: baselineGovernancePayload,
|
|
2807
2943
|
});
|
|
2808
|
-
|
|
2944
|
+
exitWithEvidence(2);
|
|
2809
2945
|
}
|
|
2810
2946
|
if (!options.json) {
|
|
2811
2947
|
console.log(chalk.cyan('\n📊 Analyzing change set...'));
|
|
@@ -2816,17 +2952,19 @@ async function verifyCommand(options) {
|
|
|
2816
2952
|
}
|
|
2817
2953
|
}
|
|
2818
2954
|
const runPolicyOnlyModeAndExit = async (source) => {
|
|
2819
|
-
const exitCode = await executePolicyOnlyMode(options, diffFiles, shouldIgnore, projectRoot, config, client, source, scopeTelemetry, projectId || undefined, orgGovernanceSettings, aiLogSigningKey, aiLogSigningKeyId, aiLogSigningKeys, aiLogSigner, expediteModeEnabled, compiledPolicyRead.artifact, compiledPolicyMetadata, changeContractSummary)
|
|
2955
|
+
const exitCode = await executePolicyOnlyMode(options, diffFiles, shouldIgnore, projectRoot, config, client, source, ciModeEnabled, scopeTelemetry, projectId || undefined, orgGovernanceSettings, aiLogSigningKey, aiLogSigningKeyId, aiLogSigningKeys, aiLogSigner, expediteModeEnabled, compiledPolicyRead.artifact, compiledPolicyMetadata, changeContractSummary, (canonical) => {
|
|
2956
|
+
lastCanonicalOutput = canonical;
|
|
2957
|
+
});
|
|
2820
2958
|
const changedFiles = diffFiles.map((f) => f.path);
|
|
2821
2959
|
const verdict = exitCode === 2 ? 'FAIL' : exitCode === 1 ? 'WARN' : 'PASS';
|
|
2822
2960
|
recordVerifyEvent(verdict, `policy_only_source=${source};exit=${exitCode}`, changedFiles);
|
|
2823
|
-
|
|
2961
|
+
exitWithEvidence(exitCode);
|
|
2824
2962
|
};
|
|
2825
2963
|
// ============================================
|
|
2826
2964
|
// --policy-only: General Governance (policy only, no plan enforcement)
|
|
2827
2965
|
// ============================================
|
|
2828
2966
|
if (options.policyOnly) {
|
|
2829
|
-
await runPolicyOnlyModeAndExit('explicit');
|
|
2967
|
+
await runPolicyOnlyModeAndExit(ciModeEnabled ? 'ci' : 'explicit');
|
|
2830
2968
|
}
|
|
2831
2969
|
const requirePlan = options.requirePlan === true
|
|
2832
2970
|
|| process.env.NEURCODE_VERIFY_REQUIRE_PLAN === '1'
|
|
@@ -2918,7 +3056,7 @@ async function verifyCommand(options) {
|
|
|
2918
3056
|
projectId: projectId || undefined,
|
|
2919
3057
|
jsonMode: Boolean(options.json),
|
|
2920
3058
|
});
|
|
2921
|
-
|
|
3059
|
+
exitWithEvidence(1);
|
|
2922
3060
|
}
|
|
2923
3061
|
let autoContractPath = null;
|
|
2924
3062
|
if (!changeContractRead.contract && !strictArtifactMode) {
|
|
@@ -3017,7 +3155,7 @@ async function verifyCommand(options) {
|
|
|
3017
3155
|
console.log(chalk.dim(' neurcode contract import --auto-detect --write-change-contract'));
|
|
3018
3156
|
console.log(chalk.dim(`\nSummary: ${message}\n`));
|
|
3019
3157
|
}
|
|
3020
|
-
|
|
3158
|
+
exitWithEvidence(0);
|
|
3021
3159
|
}
|
|
3022
3160
|
if (!planId) {
|
|
3023
3161
|
throw new Error('Plan ID resolution failed unexpectedly');
|
|
@@ -3035,11 +3173,6 @@ async function verifyCommand(options) {
|
|
|
3035
3173
|
let governanceResult = null;
|
|
3036
3174
|
let planFilesForVerification = [];
|
|
3037
3175
|
let intentConstraintsForVerification;
|
|
3038
|
-
let intentEngineIssues = [];
|
|
3039
|
-
let intentEngineDomains = [];
|
|
3040
|
-
let intentEngineSummary = null;
|
|
3041
|
-
let intentEngineFlowIssues = [];
|
|
3042
|
-
let intentEngineRegressions = [];
|
|
3043
3176
|
try {
|
|
3044
3177
|
// Step A: Get Modified Files (already have from diffFiles)
|
|
3045
3178
|
const modifiedFiles = diffFiles.map(f => f.path);
|
|
@@ -3237,7 +3370,7 @@ async function verifyCommand(options) {
|
|
|
3237
3370
|
})
|
|
3238
3371
|
: undefined,
|
|
3239
3372
|
});
|
|
3240
|
-
|
|
3373
|
+
exitWithEvidence(1);
|
|
3241
3374
|
}
|
|
3242
3375
|
else if (shouldBlockForScope) {
|
|
3243
3376
|
// Human-readable output only when NOT in json mode
|
|
@@ -3338,7 +3471,7 @@ async function verifyCommand(options) {
|
|
|
3338
3471
|
})
|
|
3339
3472
|
: undefined,
|
|
3340
3473
|
});
|
|
3341
|
-
|
|
3474
|
+
exitWithEvidence(1);
|
|
3342
3475
|
}
|
|
3343
3476
|
else {
|
|
3344
3477
|
scopeGuardExpediteBypass = true;
|
|
@@ -3504,7 +3637,7 @@ async function verifyCommand(options) {
|
|
|
3504
3637
|
})
|
|
3505
3638
|
: undefined,
|
|
3506
3639
|
});
|
|
3507
|
-
|
|
3640
|
+
exitWithEvidence(2);
|
|
3508
3641
|
}
|
|
3509
3642
|
}
|
|
3510
3643
|
let effectiveCompiledPolicy = compiledPolicyRead.artifact;
|
|
@@ -3596,7 +3729,7 @@ async function verifyCommand(options) {
|
|
|
3596
3729
|
},
|
|
3597
3730
|
});
|
|
3598
3731
|
}
|
|
3599
|
-
|
|
3732
|
+
exitWithEvidence(0);
|
|
3600
3733
|
}
|
|
3601
3734
|
let policyViolations = [];
|
|
3602
3735
|
let policyDecision = 'allow';
|
|
@@ -3891,7 +4024,7 @@ async function verifyCommand(options) {
|
|
|
3891
4024
|
})
|
|
3892
4025
|
: undefined,
|
|
3893
4026
|
});
|
|
3894
|
-
|
|
4027
|
+
exitWithEvidence(2);
|
|
3895
4028
|
}
|
|
3896
4029
|
else if (!changeContractEvaluation.valid && !options.json) {
|
|
3897
4030
|
displayChangeContractDrift(changeContractSummary, { advisory: true });
|
|
@@ -4060,72 +4193,74 @@ async function verifyCommand(options) {
|
|
|
4060
4193
|
((verifyResult.verdict === 'FAIL' || verifyResult.verdict === 'WARN') &&
|
|
4061
4194
|
policyViolations.length === 0 &&
|
|
4062
4195
|
verifyResult.bloatCount > 0));
|
|
4196
|
+
const filteredBloatFiles = (verifyResult.bloatFiles || []).filter((f) => !shouldIgnore(f));
|
|
4197
|
+
const scopeViolations = filteredBloatFiles.map((file) => ({
|
|
4198
|
+
file,
|
|
4199
|
+
rule: 'scope_guard',
|
|
4200
|
+
severity: 'block',
|
|
4201
|
+
message: 'File modified outside the plan',
|
|
4202
|
+
}));
|
|
4203
|
+
const policyViolationItems = policyViolations.map((v) => ({
|
|
4204
|
+
file: v.file,
|
|
4205
|
+
rule: v.rule,
|
|
4206
|
+
severity: v.severity,
|
|
4207
|
+
message: v.message,
|
|
4208
|
+
...(v.line != null ? { startLine: v.line } : {}),
|
|
4209
|
+
}));
|
|
4210
|
+
const aiDebtViolationItems = toAiDebtReportViolations(aiDebtSummary);
|
|
4211
|
+
const violations = [...scopeViolations, ...policyViolationItems, ...aiDebtViolationItems];
|
|
4212
|
+
const governancePayload = governanceResult
|
|
4213
|
+
? buildGovernancePayload(governanceResult, orgGovernanceSettings, {
|
|
4214
|
+
changeContract: changeContractSummary,
|
|
4215
|
+
compiledPolicy: compiledPolicyMetadata,
|
|
4216
|
+
aiDebt: aiDebtSummary,
|
|
4217
|
+
})
|
|
4218
|
+
: undefined;
|
|
4219
|
+
const verifyEvidencePayload = {
|
|
4220
|
+
grade,
|
|
4221
|
+
score: verifyResult.adherenceScore,
|
|
4222
|
+
verdict: effectiveVerdict,
|
|
4223
|
+
violations,
|
|
4224
|
+
message: effectiveMessage,
|
|
4225
|
+
adherenceScore: verifyResult.adherenceScore,
|
|
4226
|
+
scopeGuardPassed,
|
|
4227
|
+
bloatCount: filteredBloatFiles.length,
|
|
4228
|
+
bloatFiles: filteredBloatFiles,
|
|
4229
|
+
plannedFilesModified: verifyResult.plannedFilesModified,
|
|
4230
|
+
totalPlannedFiles: verifyResult.totalPlannedFiles,
|
|
4231
|
+
verificationSource: verifySource,
|
|
4232
|
+
mode: 'plan_enforced',
|
|
4233
|
+
policyOnly: false,
|
|
4234
|
+
aiDebt: aiDebtSummary,
|
|
4235
|
+
changeContract: changeContractSummary,
|
|
4236
|
+
...(compiledPolicyMetadata ? { policyCompilation: compiledPolicyMetadata } : {}),
|
|
4237
|
+
...(governancePayload || {}),
|
|
4238
|
+
policyLock: {
|
|
4239
|
+
enforced: policyLockEvaluation.enforced,
|
|
4240
|
+
matched: policyLockEvaluation.matched,
|
|
4241
|
+
path: policyLockEvaluation.lockPath,
|
|
4242
|
+
mismatches: policyLockEvaluation.mismatches,
|
|
4243
|
+
},
|
|
4244
|
+
policyExceptions: policyExceptionsSummary,
|
|
4245
|
+
policyGovernance: policyGovernanceSummary,
|
|
4246
|
+
intentProof: intentProofSummary,
|
|
4247
|
+
...(runtimeGuardSummary.required ? { runtimeGuard: runtimeGuardSummary } : {}),
|
|
4248
|
+
...(policyViolations.length > 0 && { policyDecision }),
|
|
4249
|
+
...(effectiveRules.policyPack
|
|
4250
|
+
? {
|
|
4251
|
+
policyPack: {
|
|
4252
|
+
id: effectiveRules.policyPack.packId,
|
|
4253
|
+
name: effectiveRules.policyPack.packName,
|
|
4254
|
+
version: effectiveRules.policyPack.version,
|
|
4255
|
+
ruleCount: effectiveRules.policyPackRules.length,
|
|
4256
|
+
},
|
|
4257
|
+
}
|
|
4258
|
+
: {}),
|
|
4259
|
+
};
|
|
4260
|
+
captureEvidencePayload(verifyEvidencePayload);
|
|
4063
4261
|
// If JSON output requested, output JSON and exit
|
|
4064
4262
|
if (options.json) {
|
|
4065
|
-
|
|
4066
|
-
const scopeViolations = filteredBloatFiles.map((file) => ({
|
|
4067
|
-
file,
|
|
4068
|
-
rule: 'scope_guard',
|
|
4069
|
-
severity: 'block',
|
|
4070
|
-
message: 'File modified outside the plan',
|
|
4071
|
-
}));
|
|
4072
|
-
const policyViolationItems = policyViolations.map((v) => ({
|
|
4073
|
-
file: v.file,
|
|
4074
|
-
rule: v.rule,
|
|
4075
|
-
severity: v.severity,
|
|
4076
|
-
message: v.message,
|
|
4077
|
-
...(v.line != null ? { startLine: v.line } : {}),
|
|
4078
|
-
}));
|
|
4079
|
-
const aiDebtViolationItems = toAiDebtReportViolations(aiDebtSummary);
|
|
4080
|
-
const violations = [...scopeViolations, ...policyViolationItems, ...aiDebtViolationItems];
|
|
4081
|
-
const jsonOutput = {
|
|
4082
|
-
grade,
|
|
4083
|
-
score: verifyResult.adherenceScore,
|
|
4084
|
-
verdict: effectiveVerdict,
|
|
4085
|
-
violations,
|
|
4086
|
-
message: effectiveMessage,
|
|
4087
|
-
adherenceScore: verifyResult.adherenceScore,
|
|
4088
|
-
scopeGuardPassed,
|
|
4089
|
-
bloatCount: filteredBloatFiles.length,
|
|
4090
|
-
bloatFiles: filteredBloatFiles,
|
|
4091
|
-
plannedFilesModified: verifyResult.plannedFilesModified,
|
|
4092
|
-
totalPlannedFiles: verifyResult.totalPlannedFiles,
|
|
4093
|
-
verificationSource: verifySource,
|
|
4094
|
-
mode: 'plan_enforced',
|
|
4095
|
-
policyOnly: false,
|
|
4096
|
-
aiDebt: aiDebtSummary,
|
|
4097
|
-
changeContract: changeContractSummary,
|
|
4098
|
-
...(compiledPolicyMetadata ? { policyCompilation: compiledPolicyMetadata } : {}),
|
|
4099
|
-
...(governanceResult
|
|
4100
|
-
? buildGovernancePayload(governanceResult, orgGovernanceSettings, {
|
|
4101
|
-
changeContract: changeContractSummary,
|
|
4102
|
-
compiledPolicy: compiledPolicyMetadata,
|
|
4103
|
-
aiDebt: aiDebtSummary,
|
|
4104
|
-
})
|
|
4105
|
-
: {}),
|
|
4106
|
-
policyLock: {
|
|
4107
|
-
enforced: policyLockEvaluation.enforced,
|
|
4108
|
-
matched: policyLockEvaluation.matched,
|
|
4109
|
-
path: policyLockEvaluation.lockPath,
|
|
4110
|
-
mismatches: policyLockEvaluation.mismatches,
|
|
4111
|
-
},
|
|
4112
|
-
policyExceptions: policyExceptionsSummary,
|
|
4113
|
-
policyGovernance: policyGovernanceSummary,
|
|
4114
|
-
intentProof: intentProofSummary,
|
|
4115
|
-
...(runtimeGuardSummary.required ? { runtimeGuard: runtimeGuardSummary } : {}),
|
|
4116
|
-
...(policyViolations.length > 0 && { policyDecision }),
|
|
4117
|
-
...(effectiveRules.policyPack
|
|
4118
|
-
? {
|
|
4119
|
-
policyPack: {
|
|
4120
|
-
id: effectiveRules.policyPack.packId,
|
|
4121
|
-
name: effectiveRules.policyPack.packName,
|
|
4122
|
-
version: effectiveRules.policyPack.version,
|
|
4123
|
-
ruleCount: effectiveRules.policyPackRules.length,
|
|
4124
|
-
},
|
|
4125
|
-
}
|
|
4126
|
-
: {}),
|
|
4127
|
-
};
|
|
4128
|
-
emitVerifyJson(jsonOutput);
|
|
4263
|
+
emitVerifyJson(verifyEvidencePayload);
|
|
4129
4264
|
await recordVerificationIfRequested(options, config, {
|
|
4130
4265
|
grade,
|
|
4131
4266
|
violations: violations,
|
|
@@ -4140,26 +4275,20 @@ async function verifyCommand(options) {
|
|
|
4140
4275
|
projectId: projectId || undefined,
|
|
4141
4276
|
jsonMode: true,
|
|
4142
4277
|
verificationSource: verifySource,
|
|
4143
|
-
governance:
|
|
4144
|
-
? buildGovernancePayload(governanceResult, orgGovernanceSettings, {
|
|
4145
|
-
changeContract: changeContractSummary,
|
|
4146
|
-
compiledPolicy: compiledPolicyMetadata,
|
|
4147
|
-
aiDebt: aiDebtSummary,
|
|
4148
|
-
})
|
|
4149
|
-
: undefined,
|
|
4278
|
+
governance: governancePayload,
|
|
4150
4279
|
});
|
|
4151
4280
|
// Exit based on effective verdict (same logic as below)
|
|
4152
4281
|
if (shouldForceGovernancePass) {
|
|
4153
|
-
|
|
4282
|
+
exitWithEvidence(0);
|
|
4154
4283
|
}
|
|
4155
4284
|
if (effectiveVerdict === 'FAIL') {
|
|
4156
|
-
|
|
4285
|
+
exitWithEvidence(2);
|
|
4157
4286
|
}
|
|
4158
4287
|
else if (effectiveVerdict === 'WARN') {
|
|
4159
|
-
|
|
4288
|
+
exitWithEvidence(1);
|
|
4160
4289
|
}
|
|
4161
4290
|
else {
|
|
4162
|
-
|
|
4291
|
+
exitWithEvidence(0);
|
|
4163
4292
|
}
|
|
4164
4293
|
}
|
|
4165
4294
|
// Display results (only if not in json mode; exclude ignored paths from bloat)
|
|
@@ -4287,18 +4416,18 @@ async function verifyCommand(options) {
|
|
|
4287
4416
|
if (!options.json && policyExceptionsSummary.suppressed > 0) {
|
|
4288
4417
|
console.log(chalk.yellow(` Policy exceptions applied: ${policyExceptionsSummary.suppressed}`));
|
|
4289
4418
|
}
|
|
4290
|
-
|
|
4419
|
+
exitWithEvidence(0);
|
|
4291
4420
|
}
|
|
4292
4421
|
// If scope guard didn't pass (or failed to check) or policy blocked, use effective verdict
|
|
4293
4422
|
// Exit with appropriate code based on AI verification and custom policies
|
|
4294
4423
|
if (effectiveVerdict === 'FAIL') {
|
|
4295
|
-
|
|
4424
|
+
exitWithEvidence(2);
|
|
4296
4425
|
}
|
|
4297
4426
|
else if (effectiveVerdict === 'WARN') {
|
|
4298
|
-
|
|
4427
|
+
exitWithEvidence(1);
|
|
4299
4428
|
}
|
|
4300
4429
|
else {
|
|
4301
|
-
|
|
4430
|
+
exitWithEvidence(0);
|
|
4302
4431
|
}
|
|
4303
4432
|
}
|
|
4304
4433
|
catch (error) {
|
|
@@ -4341,7 +4470,7 @@ async function verifyCommand(options) {
|
|
|
4341
4470
|
console.error(chalk.red('❌ Error:', error));
|
|
4342
4471
|
}
|
|
4343
4472
|
}
|
|
4344
|
-
|
|
4473
|
+
exitWithEvidence(1);
|
|
4345
4474
|
}
|
|
4346
4475
|
}
|
|
4347
4476
|
catch (error) {
|
|
@@ -4378,6 +4507,9 @@ async function verifyCommand(options) {
|
|
|
4378
4507
|
console.error(error);
|
|
4379
4508
|
}
|
|
4380
4509
|
}
|
|
4510
|
+
if (exitWithEvidenceFromTry) {
|
|
4511
|
+
exitWithEvidenceFromTry(1);
|
|
4512
|
+
}
|
|
4381
4513
|
process.exit(1);
|
|
4382
4514
|
}
|
|
4383
4515
|
}
|