@neurcode-ai/cli 0.9.65 → 0.9.66
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/dist/commands/bootstrap-policy.d.ts +29 -0
- package/dist/commands/bootstrap-policy.d.ts.map +1 -0
- package/dist/commands/bootstrap-policy.js +334 -0
- package/dist/commands/bootstrap-policy.js.map +1 -0
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +82 -0
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/quickstart.d.ts +21 -0
- package/dist/commands/quickstart.d.ts.map +1 -0
- package/dist/commands/quickstart.js +178 -0
- package/dist/commands/quickstart.js.map +1 -0
- package/dist/commands/remediate-export.d.ts +31 -0
- package/dist/commands/remediate-export.d.ts.map +1 -0
- package/dist/commands/remediate-export.js +283 -0
- package/dist/commands/remediate-export.js.map +1 -0
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +106 -10
- package/dist/commands/verify.js.map +1 -1
- package/dist/governance/canonical-invariants.d.ts +88 -0
- package/dist/governance/canonical-invariants.d.ts.map +1 -0
- package/dist/governance/canonical-invariants.js +197 -0
- package/dist/governance/canonical-invariants.js.map +1 -0
- package/dist/governance/canonical-ordering.d.ts +76 -0
- package/dist/governance/canonical-ordering.d.ts.map +1 -0
- package/dist/governance/canonical-ordering.js +189 -0
- package/dist/governance/canonical-ordering.js.map +1 -0
- package/dist/governance/canonical-pipeline.d.ts +7 -0
- package/dist/governance/canonical-pipeline.d.ts.map +1 -1
- package/dist/governance/canonical-pipeline.js +184 -16
- package/dist/governance/canonical-pipeline.js.map +1 -1
- package/dist/governance/diff-line-provenance.d.ts +59 -0
- package/dist/governance/diff-line-provenance.d.ts.map +1 -0
- package/dist/governance/diff-line-provenance.js +118 -0
- package/dist/governance/diff-line-provenance.js.map +1 -0
- package/dist/governance/pilot-readiness.d.ts +34 -0
- package/dist/governance/pilot-readiness.d.ts.map +1 -0
- package/dist/governance/pilot-readiness.js +226 -0
- package/dist/governance/pilot-readiness.js.map +1 -0
- package/dist/governance/policy-parity-validator.d.ts +62 -0
- package/dist/governance/policy-parity-validator.d.ts.map +1 -0
- package/dist/governance/policy-parity-validator.js +137 -0
- package/dist/governance/policy-parity-validator.js.map +1 -0
- package/dist/governance/remediation-boundary.d.ts +55 -0
- package/dist/governance/remediation-boundary.d.ts.map +1 -0
- package/dist/governance/remediation-boundary.js +120 -0
- package/dist/governance/remediation-boundary.js.map +1 -0
- package/dist/governance/structural-cache.d.ts +103 -0
- package/dist/governance/structural-cache.d.ts.map +1 -0
- package/dist/governance/structural-cache.js +240 -0
- package/dist/governance/structural-cache.js.map +1 -0
- package/dist/governance/structural-on-diff.d.ts +22 -2
- package/dist/governance/structural-on-diff.d.ts.map +1 -1
- package/dist/governance/structural-on-diff.js +36 -4
- package/dist/governance/structural-on-diff.js.map +1 -1
- package/dist/governance/structural-policy-merge.d.ts +8 -0
- package/dist/governance/structural-policy-merge.d.ts.map +1 -1
- package/dist/governance/structural-policy-merge.js +7 -0
- package/dist/governance/structural-policy-merge.js.map +1 -1
- package/dist/governance/verify-runtime-guard.d.ts +99 -0
- package/dist/governance/verify-runtime-guard.d.ts.map +1 -0
- package/dist/governance/verify-runtime-guard.js +129 -0
- package/dist/governance/verify-runtime-guard.js.map +1 -0
- package/dist/index.js +50 -14
- package/dist/index.js.map +1 -1
- package/dist/intent-engine/repo-classifier.d.ts +64 -0
- package/dist/intent-engine/repo-classifier.d.ts.map +1 -0
- package/dist/intent-engine/repo-classifier.js +178 -0
- package/dist/intent-engine/repo-classifier.js.map +1 -0
- package/dist/structural-rules/index.d.ts +4 -0
- package/dist/structural-rules/index.d.ts.map +1 -1
- package/dist/structural-rules/index.js +18 -1
- package/dist/structural-rules/index.js.map +1 -1
- package/dist/structural-rules/python/PY003-broad-except-clause.d.ts +21 -0
- package/dist/structural-rules/python/PY003-broad-except-clause.d.ts.map +1 -1
- package/dist/structural-rules/python/PY003-broad-except-clause.js +212 -21
- package/dist/structural-rules/python/PY003-broad-except-clause.js.map +1 -1
- package/dist/structural-rules/python/PY011-thread-lifecycle.d.ts +11 -0
- package/dist/structural-rules/python/PY011-thread-lifecycle.d.ts.map +1 -0
- package/dist/structural-rules/python/PY011-thread-lifecycle.js +97 -0
- package/dist/structural-rules/python/PY011-thread-lifecycle.js.map +1 -0
- package/dist/structural-rules/python/PY012-asyncio-run-misuse.d.ts +11 -0
- package/dist/structural-rules/python/PY012-asyncio-run-misuse.d.ts.map +1 -0
- package/dist/structural-rules/python/PY012-asyncio-run-misuse.js +83 -0
- package/dist/structural-rules/python/PY012-asyncio-run-misuse.js.map +1 -0
- package/dist/structural-rules/python/PY013-mutable-default-arg.d.ts +11 -0
- package/dist/structural-rules/python/PY013-mutable-default-arg.d.ts.map +1 -0
- package/dist/structural-rules/python/PY013-mutable-default-arg.js +73 -0
- package/dist/structural-rules/python/PY013-mutable-default-arg.js.map +1 -0
- package/dist/structural-rules/python/PY014-fixed-sleep-retry.d.ts +11 -0
- package/dist/structural-rules/python/PY014-fixed-sleep-retry.d.ts.map +1 -0
- package/dist/structural-rules/python/PY014-fixed-sleep-retry.js +115 -0
- package/dist/structural-rules/python/PY014-fixed-sleep-retry.js.map +1 -0
- package/dist/structural-rules/types.d.ts +12 -0
- package/dist/structural-rules/types.d.ts.map +1 -1
- package/dist/utils/verify-runtime-stability.d.ts +142 -0
- package/dist/utils/verify-runtime-stability.d.ts.map +1 -0
- package/dist/utils/verify-runtime-stability.js +230 -0
- package/dist/utils/verify-runtime-stability.js.map +1 -0
- package/package.json +1 -1
package/dist/commands/verify.js
CHANGED
|
@@ -69,8 +69,12 @@ const diff_symbols_1 = require("../utils/diff-symbols");
|
|
|
69
69
|
const advisory_signals_1 = require("../utils/advisory-signals");
|
|
70
70
|
const structural_rules_1 = require("../structural-rules");
|
|
71
71
|
const canonical_pipeline_1 = require("../governance/canonical-pipeline");
|
|
72
|
+
const canonical_invariants_1 = require("../governance/canonical-invariants");
|
|
72
73
|
const structural_on_diff_1 = require("../governance/structural-on-diff");
|
|
73
|
-
|
|
74
|
+
// NOTE: mergeStructuralIntoPolicyViolations is intentionally NOT imported.
|
|
75
|
+
// Structural violations flow exclusively through payload.structuralViolations
|
|
76
|
+
// into the canonical pipeline. Merging them into policyViolations caused
|
|
77
|
+
// duplicate GovernanceFinding objects (fixed in Phase 1 canonical graph hardening).
|
|
74
78
|
const telemetry_1 = require("@neurcode-ai/telemetry");
|
|
75
79
|
const governance_provenance_1 = require("../utils/governance-provenance");
|
|
76
80
|
const pilot_metrics_1 = require("../utils/pilot-metrics");
|
|
@@ -80,6 +84,7 @@ const artifact_signature_1 = require("../utils/artifact-signature");
|
|
|
80
84
|
const policy_1 = require("@neurcode-ai/policy");
|
|
81
85
|
const ai_debt_budget_1 = require("../utils/ai-debt-budget");
|
|
82
86
|
const verification_evidence_1 = require("../utils/verification-evidence");
|
|
87
|
+
const verify_runtime_stability_1 = require("../utils/verify-runtime-stability");
|
|
83
88
|
// Import chalk with fallback
|
|
84
89
|
let chalk;
|
|
85
90
|
try {
|
|
@@ -100,6 +105,38 @@ catch {
|
|
|
100
105
|
white: (str) => str,
|
|
101
106
|
};
|
|
102
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Structured CI explainability for `neurcode verify --ci` / `--policy-only` human output.
|
|
110
|
+
* Keeps logs short — no JSON dumps — and separates merge-blocking vs advisory signals.
|
|
111
|
+
*/
|
|
112
|
+
function logCiPolicyOnlyOutcomeExplainability(params) {
|
|
113
|
+
if (!params.ciModeEnabled || params.json) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const modeLine = params.source === 'ci'
|
|
117
|
+
? '`verify --ci` uses deterministic local governance (compiled/custom policy + structural rules). Remote plan-verify API is not used.'
|
|
118
|
+
: '`--policy-only` — local policy + structural governance without plan adherence.';
|
|
119
|
+
const sev = (s) => String(s || '').toLowerCase();
|
|
120
|
+
const sBlock = params.structuralViolations.filter((v) => v.severity === 'BLOCKING').length;
|
|
121
|
+
const sAdv = params.structuralViolations.length - sBlock;
|
|
122
|
+
const pBlock = params.policyViolations.filter((v) => sev(v.severity) === 'block').length;
|
|
123
|
+
const pWarn = params.policyViolations.filter((v) => sev(v.severity) === 'warn').length;
|
|
124
|
+
if (params.verdict === 'PASS') {
|
|
125
|
+
console.log(chalk.dim('\n── CI verify contract ──'));
|
|
126
|
+
console.log(chalk.dim(` ${modeLine}`));
|
|
127
|
+
console.log(chalk.dim(' Exit 0: no blocking severities. Replay checksum (JSON) anchors structural findings for audit parity.'));
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
console.log(chalk.bold.red('\n── CI failure explainability ──'));
|
|
131
|
+
console.log(chalk.dim(` ${modeLine}`));
|
|
132
|
+
console.log(chalk.red(` Merge-blocking rows: structural BLOCKING ${sBlock}; policy/custom severity=block ${pBlock}`));
|
|
133
|
+
console.log(chalk.yellow(` Non-blocking (warn/advisory-class): structural advisory ${sAdv}; policy warn ${pWarn} — does not fail CI unless your gate maps warns to failure`));
|
|
134
|
+
console.log(chalk.dim(' Offline / structural-only: set NEURCODE_VERIFY_LOCAL_ONLY=1 or `--local-only` to skip API compatibility probes (AST gates still run).'));
|
|
135
|
+
if (params.replayChecksum) {
|
|
136
|
+
console.log(chalk.dim(` Structural replay checksum: ${params.replayChecksum.slice(0, 16)}… · mode ${params.replayMode ?? 'local-structural'}`));
|
|
137
|
+
}
|
|
138
|
+
console.log(chalk.dim(' Next: resolve BLOCKING first → `neurcode remediate-export` (optional) → re-run `neurcode verify --ci`.\n'));
|
|
139
|
+
}
|
|
103
140
|
;
|
|
104
141
|
function toArtifactSignatureSummary(status) {
|
|
105
142
|
return {
|
|
@@ -1932,7 +1969,9 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
|
|
|
1932
1969
|
});
|
|
1933
1970
|
}
|
|
1934
1971
|
const policyOnlyStructural = (0, structural_on_diff_1.runStructuralOnDiffFiles)(projectRoot, diffFilesForPolicy);
|
|
1935
|
-
|
|
1972
|
+
// Structural violations are passed to the canonical pipeline via payload.structuralViolations
|
|
1973
|
+
// (see line ~2584). Do NOT merge them into policyViolations — that would create structural:*
|
|
1974
|
+
// duplicates that contaminate the canonical finding graph.
|
|
1936
1975
|
policyDecision = resolvePolicyDecisionFromViolations(policyViolations);
|
|
1937
1976
|
const effectiveVerdict = policyDecision === 'block' ? 'FAIL' : policyDecision === 'warn' ? 'WARN' : 'PASS';
|
|
1938
1977
|
const grade = effectiveVerdict === 'PASS' ? 'A' : effectiveVerdict === 'WARN' ? 'C' : 'F';
|
|
@@ -1989,6 +2028,11 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
|
|
|
1989
2028
|
eventCount: auditIntegrity.count,
|
|
1990
2029
|
},
|
|
1991
2030
|
};
|
|
2031
|
+
// Phase 4: Compute replay checksum from structural findings so replayChecksum
|
|
2032
|
+
// is populated in --policy-only and --local-only CI/daemonless modes.
|
|
2033
|
+
// This closes the N/A gap identified in the Apache Airflow benchmark.
|
|
2034
|
+
const policyOnlyStructuralFindings = policyOnlyStructural.violations.map(canonical_pipeline_1.findingFromStructural);
|
|
2035
|
+
const policyOnlyReplayChecksum = (0, canonical_invariants_1.computeCanonicalFindingChecksum)(policyOnlyStructuralFindings);
|
|
1992
2036
|
const policyOnlyPayload = {
|
|
1993
2037
|
grade,
|
|
1994
2038
|
score,
|
|
@@ -2007,6 +2051,8 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
|
|
|
2007
2051
|
mode: 'policy_only',
|
|
2008
2052
|
policyOnly: true,
|
|
2009
2053
|
policyOnlySource: source,
|
|
2054
|
+
replayChecksum: policyOnlyReplayChecksum,
|
|
2055
|
+
replayMode: 'local-structural',
|
|
2010
2056
|
...governancePayload,
|
|
2011
2057
|
policyLock: {
|
|
2012
2058
|
enforced: policyLockEvaluation.enforced,
|
|
@@ -2057,6 +2103,16 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
|
|
|
2057
2103
|
}
|
|
2058
2104
|
displayGovernanceInsights(governanceAnalysis, { explain: options.explain });
|
|
2059
2105
|
console.log(chalk.dim(`\n${message}`));
|
|
2106
|
+
logCiPolicyOnlyOutcomeExplainability({
|
|
2107
|
+
ciModeEnabled,
|
|
2108
|
+
json: Boolean(options.json),
|
|
2109
|
+
verdict: effectiveVerdict,
|
|
2110
|
+
source,
|
|
2111
|
+
structuralViolations: policyOnlyStructural.violations,
|
|
2112
|
+
policyViolations,
|
|
2113
|
+
replayChecksum: policyOnlyReplayChecksum,
|
|
2114
|
+
replayMode: 'local-structural',
|
|
2115
|
+
});
|
|
2060
2116
|
}
|
|
2061
2117
|
await recordPolicyOnlyVerification({
|
|
2062
2118
|
grade,
|
|
@@ -2092,6 +2148,13 @@ async function verifyCommand(options) {
|
|
|
2092
2148
|
let lastCanonicalOutput = null;
|
|
2093
2149
|
let lastEvidenceFallbackOutput = null;
|
|
2094
2150
|
let evidenceFinalizeAttempted = false;
|
|
2151
|
+
// ── Phase 1 Runtime Stability: create context early so all subsystems share it ──
|
|
2152
|
+
// Structural governance is NEVER gated by this context — it always runs.
|
|
2153
|
+
const runtimeCtx = (0, verify_runtime_stability_1.createVerifyRuntimeContext)(ciModeEnabled);
|
|
2154
|
+
// Large repo detection: sets largeRepoMode and emits cache-build recommendation.
|
|
2155
|
+
(0, verify_runtime_stability_1.applyLargeRepoProtection)(runtimeCtx, projectRoot);
|
|
2156
|
+
// Initial memory pressure check at entry.
|
|
2157
|
+
(0, verify_runtime_stability_1.applyMemoryPressureDegradation)(runtimeCtx);
|
|
2095
2158
|
if (ciModeEnabled) {
|
|
2096
2159
|
options.policyOnly = true;
|
|
2097
2160
|
options.requirePlan = false;
|
|
@@ -2163,6 +2226,9 @@ async function verifyCommand(options) {
|
|
|
2163
2226
|
let structuralRulesApplied = [];
|
|
2164
2227
|
let structuralSuppressedCount = 0;
|
|
2165
2228
|
const emitVerifyJson = (payload) => {
|
|
2229
|
+
// Check memory pressure immediately before emission (may have changed during long verify)
|
|
2230
|
+
(0, verify_runtime_stability_1.applyMemoryPressureDegradation)(runtimeCtx);
|
|
2231
|
+
const runtimeStabilityReport = (0, verify_runtime_stability_1.buildVerifyRuntimeReport)(runtimeCtx);
|
|
2166
2232
|
const enrichedPayload = {
|
|
2167
2233
|
...payload,
|
|
2168
2234
|
ciMode: payload.ciMode ?? ciModeEnabled,
|
|
@@ -2178,6 +2244,8 @@ async function verifyCommand(options) {
|
|
|
2178
2244
|
structuralViolations: payload.structuralViolations ?? structuralViolations,
|
|
2179
2245
|
structuralRulesApplied: payload.structuralRulesApplied ?? structuralRulesApplied,
|
|
2180
2246
|
structuralSuppressedCount: payload.structuralSuppressedCount ?? structuralSuppressedCount,
|
|
2247
|
+
// Runtime stability transparency — always present
|
|
2248
|
+
runtimeStabilityReport,
|
|
2181
2249
|
};
|
|
2182
2250
|
lastEvidenceFallbackOutput = enrichedPayload;
|
|
2183
2251
|
emitCanonicalVerifyJson(enrichedPayload, (canonical) => {
|
|
@@ -2622,8 +2690,19 @@ async function verifyCommand(options) {
|
|
|
2622
2690
|
try {
|
|
2623
2691
|
let contextNote = note;
|
|
2624
2692
|
if (Array.isArray(changedFiles) && changedFiles.length > 0) {
|
|
2625
|
-
|
|
2626
|
-
|
|
2693
|
+
// Runtime stability: skip brain context refresh if semantic layer is degraded
|
|
2694
|
+
// (memory pressure or time pressure). Structural verification is unaffected.
|
|
2695
|
+
if ((0, verify_runtime_stability_1.shouldSkipSemanticLayer)(runtimeCtx)) {
|
|
2696
|
+
contextNote = `${contextNote};semantic_skipped=runtime_pressure`;
|
|
2697
|
+
if (!ciModeEnabled && runtimeCtx.degradationReasons.length > 0) {
|
|
2698
|
+
console.log(chalk.yellow(`\n⚠️ Brain context refresh skipped: ${runtimeCtx.degradationReasons[runtimeCtx.degradationReasons.length - 1]}`));
|
|
2699
|
+
console.log(chalk.dim(' Deterministic structural governance continues unaffected.\n'));
|
|
2700
|
+
}
|
|
2701
|
+
}
|
|
2702
|
+
else {
|
|
2703
|
+
const refreshed = (0, brain_context_1.refreshBrainContextForFiles)(projectRoot, brainScope, changedFiles);
|
|
2704
|
+
contextNote = `${contextNote};indexed=${refreshed.indexed};removed=${refreshed.removed};skipped=${refreshed.skipped}`;
|
|
2705
|
+
}
|
|
2627
2706
|
}
|
|
2628
2707
|
(0, brain_context_1.recordBrainProgressEvent)(projectRoot, brainScope, {
|
|
2629
2708
|
type: 'verify',
|
|
@@ -2818,7 +2897,9 @@ async function verifyCommand(options) {
|
|
|
2818
2897
|
});
|
|
2819
2898
|
}
|
|
2820
2899
|
console.log(chalk.dim(`\n[Local-only] ${localStructural.violations.length} finding(s), ${blockingViolations.length} blocking. ` +
|
|
2821
|
-
`
|
|
2900
|
+
`Structural analysis ran on this checkout only (no verify API).\n`));
|
|
2901
|
+
console.log(chalk.dim(' Replay: same commit + same flags → same structural findings.\n' +
|
|
2902
|
+
' Full plan/adherence + remote verify: drop --local-only when policy allows network/API.\n'));
|
|
2822
2903
|
}
|
|
2823
2904
|
recordVerifyEvent(localVerdict, `local_only;structural=${localStructural.violations.length}`, diffFiles.map((f) => f.path));
|
|
2824
2905
|
exitWithEvidence(blockingViolations.length > 0 ? 2 : 0);
|
|
@@ -3216,10 +3297,14 @@ async function verifyCommand(options) {
|
|
|
3216
3297
|
}
|
|
3217
3298
|
const message = 'No plan linked yet. Ran advisory verification for quick first-run experience. ' +
|
|
3218
3299
|
'Use `neurcode plan` and `neurcode contract import --auto-detect --write-change-contract` for full enforcement.';
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3300
|
+
// Runtime stability: skip advisory signals if advisory layer is degraded.
|
|
3301
|
+
// Structural rules always run regardless.
|
|
3302
|
+
const advisorySignals = (0, verify_runtime_stability_1.shouldSkipAdvisoryLayer)(runtimeCtx)
|
|
3303
|
+
? []
|
|
3304
|
+
: (0, advisory_signals_1.evaluateAdvisorySignals)({ diffFiles, summary });
|
|
3305
|
+
if ((0, verify_runtime_stability_1.shouldSkipAdvisoryLayer)(runtimeCtx) && !options.json) {
|
|
3306
|
+
console.log(chalk.dim(' Advisory signals skipped (runtime pressure — structural governance unaffected).'));
|
|
3307
|
+
}
|
|
3223
3308
|
const advisoryWarnCount = advisorySignals.filter((item) => item.severity === 'warn').length;
|
|
3224
3309
|
// ── Advisory-first: always run structural rules, downgrade scope issues to advisory ──
|
|
3225
3310
|
// Structural rules are deterministic and local — they MUST always run regardless of plan.
|
|
@@ -3971,7 +4056,9 @@ async function verifyCommand(options) {
|
|
|
3971
4056
|
message: `Policy audit chain is invalid: ${auditIntegrityStatus.issues.join('; ') || 'unknown issue'}`,
|
|
3972
4057
|
});
|
|
3973
4058
|
}
|
|
3974
|
-
|
|
4059
|
+
// Structural violations are passed to the canonical pipeline via payload.structuralViolations
|
|
4060
|
+
// (see line ~5281). Do NOT merge them into policyViolations — that would create structural:*
|
|
4061
|
+
// duplicates that contaminate the canonical finding graph.
|
|
3975
4062
|
policyDecision = resolvePolicyDecisionFromViolations(policyViolations);
|
|
3976
4063
|
const policyExceptionsSummary = {
|
|
3977
4064
|
sourceMode: policyExceptionResolution.mode,
|
|
@@ -4556,6 +4643,15 @@ async function verifyCommand(options) {
|
|
|
4556
4643
|
console.log(chalk.dim(' Intent proof repo scan reached configured file/byte limit (truncated).'));
|
|
4557
4644
|
}
|
|
4558
4645
|
}
|
|
4646
|
+
console.log(chalk.dim('\n── Verification contract (this run) ──'));
|
|
4647
|
+
console.log(chalk.dim(` Verify source: ${verifySource === 'local_fallback'
|
|
4648
|
+
? 'local deterministic fallback (verify API unavailable)'
|
|
4649
|
+
: 'verify API'}`));
|
|
4650
|
+
console.log(chalk.dim(` Structural findings: ${structuralViolations.length} ` +
|
|
4651
|
+
`(${structuralViolations.filter((v) => v.severity === 'BLOCKING').length} blocking, ` +
|
|
4652
|
+
`${structuralViolations.filter((v) => v.severity !== 'BLOCKING').length} advisory)`));
|
|
4653
|
+
console.log(chalk.dim(' Merge gates follow rule severity + policy: blocking structural findings are reproducible on this tree.'));
|
|
4654
|
+
console.log(chalk.dim(' Evidence trail: see `.neurcode/` on success (provenance, telemetry) — use `neurcode replay` / dashboard for audit parity.'));
|
|
4559
4655
|
}
|
|
4560
4656
|
// ── Governance Provenance Chain + Pilot Metrics ───────────────────────
|
|
4561
4657
|
// Best-effort: never throws, never changes the verification outcome.
|