@neurcode-ai/cli 0.9.64 → 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.
Files changed (323) hide show
  1. package/LICENSE +201 -0
  2. package/dist/commands/bootstrap-policy.d.ts +29 -0
  3. package/dist/commands/bootstrap-policy.d.ts.map +1 -0
  4. package/dist/commands/bootstrap-policy.js +334 -0
  5. package/dist/commands/bootstrap-policy.js.map +1 -0
  6. package/dist/commands/brain.d.ts.map +1 -1
  7. package/dist/commands/brain.js +273 -0
  8. package/dist/commands/brain.js.map +1 -1
  9. package/dist/commands/doctor.d.ts.map +1 -1
  10. package/dist/commands/doctor.js +82 -0
  11. package/dist/commands/doctor.js.map +1 -1
  12. package/dist/commands/pilot-report.d.ts +9 -0
  13. package/dist/commands/pilot-report.d.ts.map +1 -0
  14. package/dist/commands/pilot-report.js +176 -0
  15. package/dist/commands/pilot-report.js.map +1 -0
  16. package/dist/commands/quickstart.d.ts +21 -0
  17. package/dist/commands/quickstart.d.ts.map +1 -0
  18. package/dist/commands/quickstart.js +178 -0
  19. package/dist/commands/quickstart.js.map +1 -0
  20. package/dist/commands/remediate-export.d.ts +31 -0
  21. package/dist/commands/remediate-export.d.ts.map +1 -0
  22. package/dist/commands/remediate-export.js +283 -0
  23. package/dist/commands/remediate-export.js.map +1 -0
  24. package/dist/commands/remediate-governance.d.ts +54 -0
  25. package/dist/commands/remediate-governance.d.ts.map +1 -0
  26. package/dist/commands/remediate-governance.js +375 -0
  27. package/dist/commands/remediate-governance.js.map +1 -0
  28. package/dist/commands/remediate.d.ts.map +1 -1
  29. package/dist/commands/remediate.js.map +1 -1
  30. package/dist/commands/replay.d.ts.map +1 -1
  31. package/dist/commands/replay.js +30 -0
  32. package/dist/commands/replay.js.map +1 -1
  33. package/dist/commands/verify.d.ts.map +1 -1
  34. package/dist/commands/verify.js +409 -30
  35. package/dist/commands/verify.js.map +1 -1
  36. package/dist/daemon/server.d.ts.map +1 -1
  37. package/dist/daemon/server.js +1078 -0
  38. package/dist/daemon/server.js.map +1 -1
  39. package/dist/explainability/DeterminismClassifier.d.ts +34 -0
  40. package/dist/explainability/DeterminismClassifier.d.ts.map +1 -0
  41. package/dist/explainability/DeterminismClassifier.js +104 -0
  42. package/dist/explainability/DeterminismClassifier.js.map +1 -0
  43. package/dist/explainability/ViolationFormatter.d.ts +32 -0
  44. package/dist/explainability/ViolationFormatter.d.ts.map +1 -0
  45. package/dist/explainability/ViolationFormatter.js +252 -0
  46. package/dist/explainability/ViolationFormatter.js.map +1 -0
  47. package/dist/explainability/index.d.ts +15 -0
  48. package/dist/explainability/index.d.ts.map +1 -0
  49. package/dist/explainability/index.js +94 -0
  50. package/dist/explainability/index.js.map +1 -0
  51. package/dist/explainability/types.d.ts +37 -0
  52. package/dist/explainability/types.d.ts.map +1 -0
  53. package/dist/explainability/types.js +3 -0
  54. package/dist/explainability/types.js.map +1 -0
  55. package/dist/governance/canonical-invariants.d.ts +88 -0
  56. package/dist/governance/canonical-invariants.d.ts.map +1 -0
  57. package/dist/governance/canonical-invariants.js +197 -0
  58. package/dist/governance/canonical-invariants.js.map +1 -0
  59. package/dist/governance/canonical-ordering.d.ts +76 -0
  60. package/dist/governance/canonical-ordering.d.ts.map +1 -0
  61. package/dist/governance/canonical-ordering.js +189 -0
  62. package/dist/governance/canonical-ordering.js.map +1 -0
  63. package/dist/governance/canonical-pipeline.d.ts +45 -0
  64. package/dist/governance/canonical-pipeline.d.ts.map +1 -0
  65. package/dist/governance/canonical-pipeline.js +616 -0
  66. package/dist/governance/canonical-pipeline.js.map +1 -0
  67. package/dist/governance/diff-line-provenance.d.ts +59 -0
  68. package/dist/governance/diff-line-provenance.d.ts.map +1 -0
  69. package/dist/governance/diff-line-provenance.js +118 -0
  70. package/dist/governance/diff-line-provenance.js.map +1 -0
  71. package/dist/governance/pilot-readiness.d.ts +34 -0
  72. package/dist/governance/pilot-readiness.d.ts.map +1 -0
  73. package/dist/governance/pilot-readiness.js +226 -0
  74. package/dist/governance/pilot-readiness.js.map +1 -0
  75. package/dist/governance/policy-parity-validator.d.ts +62 -0
  76. package/dist/governance/policy-parity-validator.d.ts.map +1 -0
  77. package/dist/governance/policy-parity-validator.js +137 -0
  78. package/dist/governance/policy-parity-validator.js.map +1 -0
  79. package/dist/governance/remediation-boundary.d.ts +55 -0
  80. package/dist/governance/remediation-boundary.d.ts.map +1 -0
  81. package/dist/governance/remediation-boundary.js +120 -0
  82. package/dist/governance/remediation-boundary.js.map +1 -0
  83. package/dist/governance/structural-cache.d.ts +103 -0
  84. package/dist/governance/structural-cache.d.ts.map +1 -0
  85. package/dist/governance/structural-cache.js +240 -0
  86. package/dist/governance/structural-cache.js.map +1 -0
  87. package/dist/governance/structural-on-diff.d.ts +33 -0
  88. package/dist/governance/structural-on-diff.d.ts.map +1 -0
  89. package/dist/governance/structural-on-diff.js +67 -0
  90. package/dist/governance/structural-on-diff.js.map +1 -0
  91. package/dist/governance/structural-policy-merge.d.ts +22 -0
  92. package/dist/governance/structural-policy-merge.d.ts.map +1 -0
  93. package/dist/governance/structural-policy-merge.js +32 -0
  94. package/dist/governance/structural-policy-merge.js.map +1 -0
  95. package/dist/governance/verify-runtime-guard.d.ts +99 -0
  96. package/dist/governance/verify-runtime-guard.d.ts.map +1 -0
  97. package/dist/governance/verify-runtime-guard.js +129 -0
  98. package/dist/governance/verify-runtime-guard.js.map +1 -0
  99. package/dist/index.js +107 -0
  100. package/dist/index.js.map +1 -1
  101. package/dist/integrations/review-compression/index.d.ts +50 -0
  102. package/dist/integrations/review-compression/index.d.ts.map +1 -0
  103. package/dist/integrations/review-compression/index.js +158 -0
  104. package/dist/integrations/review-compression/index.js.map +1 -0
  105. package/dist/intent-engine/domain-taxonomy.d.ts +42 -0
  106. package/dist/intent-engine/domain-taxonomy.d.ts.map +1 -0
  107. package/dist/intent-engine/domain-taxonomy.js +534 -0
  108. package/dist/intent-engine/domain-taxonomy.js.map +1 -0
  109. package/dist/intent-engine/index.d.ts +1 -0
  110. package/dist/intent-engine/index.d.ts.map +1 -1
  111. package/dist/intent-engine/index.js +6 -1
  112. package/dist/intent-engine/index.js.map +1 -1
  113. package/dist/intent-engine/parser.d.ts.map +1 -1
  114. package/dist/intent-engine/parser.js +47 -0
  115. package/dist/intent-engine/parser.js.map +1 -1
  116. package/dist/intent-engine/repo-classifier.d.ts +64 -0
  117. package/dist/intent-engine/repo-classifier.d.ts.map +1 -0
  118. package/dist/intent-engine/repo-classifier.js +178 -0
  119. package/dist/intent-engine/repo-classifier.js.map +1 -0
  120. package/dist/intent-engine/semantic-expander.d.ts +104 -0
  121. package/dist/intent-engine/semantic-expander.d.ts.map +1 -0
  122. package/dist/intent-engine/semantic-expander.js +480 -0
  123. package/dist/intent-engine/semantic-expander.js.map +1 -0
  124. package/dist/patch-engine/patterns.d.ts.map +1 -1
  125. package/dist/patch-engine/patterns.js +8 -4
  126. package/dist/patch-engine/patterns.js.map +1 -1
  127. package/dist/semantic/index.d.ts +14 -0
  128. package/dist/semantic/index.d.ts.map +1 -0
  129. package/dist/semantic/index.js +30 -0
  130. package/dist/semantic/index.js.map +1 -0
  131. package/dist/semantic/tfidf-engine.d.ts +81 -0
  132. package/dist/semantic/tfidf-engine.d.ts.map +1 -0
  133. package/dist/semantic/tfidf-engine.js +278 -0
  134. package/dist/semantic/tfidf-engine.js.map +1 -0
  135. package/dist/semantic/vector-store.d.ts +108 -0
  136. package/dist/semantic/vector-store.d.ts.map +1 -0
  137. package/dist/semantic/vector-store.js +321 -0
  138. package/dist/semantic/vector-store.js.map +1 -0
  139. package/dist/structural-rules/context-severity.d.ts +46 -0
  140. package/dist/structural-rules/context-severity.d.ts.map +1 -0
  141. package/dist/structural-rules/context-severity.js +115 -0
  142. package/dist/structural-rules/context-severity.js.map +1 -0
  143. package/dist/structural-rules/distributed/DS001-saga-rollback-absence.d.ts +11 -0
  144. package/dist/structural-rules/distributed/DS001-saga-rollback-absence.d.ts.map +1 -0
  145. package/dist/structural-rules/distributed/DS001-saga-rollback-absence.js +212 -0
  146. package/dist/structural-rules/distributed/DS001-saga-rollback-absence.js.map +1 -0
  147. package/dist/structural-rules/distributed/DS002-missing-correlation-id.d.ts +11 -0
  148. package/dist/structural-rules/distributed/DS002-missing-correlation-id.d.ts.map +1 -0
  149. package/dist/structural-rules/distributed/DS002-missing-correlation-id.js +213 -0
  150. package/dist/structural-rules/distributed/DS002-missing-correlation-id.js.map +1 -0
  151. package/dist/structural-rules/distributed/index.d.ts +3 -0
  152. package/dist/structural-rules/distributed/index.d.ts.map +1 -0
  153. package/dist/structural-rules/distributed/index.js +8 -0
  154. package/dist/structural-rules/distributed/index.js.map +1 -0
  155. package/dist/structural-rules/engine.d.ts +25 -0
  156. package/dist/structural-rules/engine.d.ts.map +1 -0
  157. package/dist/structural-rules/engine.js +90 -0
  158. package/dist/structural-rules/engine.js.map +1 -0
  159. package/dist/structural-rules/index.d.ts +45 -0
  160. package/dist/structural-rules/index.d.ts.map +1 -0
  161. package/dist/structural-rules/index.js +158 -0
  162. package/dist/structural-rules/index.js.map +1 -0
  163. package/dist/structural-rules/python/PY001-asyncio-task-without-cancel.d.ts +11 -0
  164. package/dist/structural-rules/python/PY001-asyncio-task-without-cancel.d.ts.map +1 -0
  165. package/dist/structural-rules/python/PY001-asyncio-task-without-cancel.js +66 -0
  166. package/dist/structural-rules/python/PY001-asyncio-task-without-cancel.js.map +1 -0
  167. package/dist/structural-rules/python/PY002-unbounded-dict-singleton.d.ts +11 -0
  168. package/dist/structural-rules/python/PY002-unbounded-dict-singleton.d.ts.map +1 -0
  169. package/dist/structural-rules/python/PY002-unbounded-dict-singleton.js +135 -0
  170. package/dist/structural-rules/python/PY002-unbounded-dict-singleton.js.map +1 -0
  171. package/dist/structural-rules/python/PY003-broad-except-clause.d.ts +32 -0
  172. package/dist/structural-rules/python/PY003-broad-except-clause.d.ts.map +1 -0
  173. package/dist/structural-rules/python/PY003-broad-except-clause.js +277 -0
  174. package/dist/structural-rules/python/PY003-broad-except-clause.js.map +1 -0
  175. package/dist/structural-rules/python/PY004-swallowed-async-exception.d.ts +11 -0
  176. package/dist/structural-rules/python/PY004-swallowed-async-exception.d.ts.map +1 -0
  177. package/dist/structural-rules/python/PY004-swallowed-async-exception.js +167 -0
  178. package/dist/structural-rules/python/PY004-swallowed-async-exception.js.map +1 -0
  179. package/dist/structural-rules/python/PY005-fastapi-without-pydantic.d.ts +11 -0
  180. package/dist/structural-rules/python/PY005-fastapi-without-pydantic.d.ts.map +1 -0
  181. package/dist/structural-rules/python/PY005-fastapi-without-pydantic.js +154 -0
  182. package/dist/structural-rules/python/PY005-fastapi-without-pydantic.js.map +1 -0
  183. package/dist/structural-rules/python/PY006-blocking-io-in-async.d.ts +11 -0
  184. package/dist/structural-rules/python/PY006-blocking-io-in-async.d.ts.map +1 -0
  185. package/dist/structural-rules/python/PY006-blocking-io-in-async.js +130 -0
  186. package/dist/structural-rules/python/PY006-blocking-io-in-async.js.map +1 -0
  187. package/dist/structural-rules/python/PY007-sqlalchemy-session-leak.d.ts +11 -0
  188. package/dist/structural-rules/python/PY007-sqlalchemy-session-leak.d.ts.map +1 -0
  189. package/dist/structural-rules/python/PY007-sqlalchemy-session-leak.js +93 -0
  190. package/dist/structural-rules/python/PY007-sqlalchemy-session-leak.js.map +1 -0
  191. package/dist/structural-rules/python/PY008-celery-task-without-retry.d.ts +11 -0
  192. package/dist/structural-rules/python/PY008-celery-task-without-retry.d.ts.map +1 -0
  193. package/dist/structural-rules/python/PY008-celery-task-without-retry.js +154 -0
  194. package/dist/structural-rules/python/PY008-celery-task-without-retry.js.map +1 -0
  195. package/dist/structural-rules/python/PY009-unsafe-pickle-deserialization.d.ts +11 -0
  196. package/dist/structural-rules/python/PY009-unsafe-pickle-deserialization.d.ts.map +1 -0
  197. package/dist/structural-rules/python/PY009-unsafe-pickle-deserialization.js +133 -0
  198. package/dist/structural-rules/python/PY009-unsafe-pickle-deserialization.js.map +1 -0
  199. package/dist/structural-rules/python/PY010-leaked-aiohttp-session.d.ts +11 -0
  200. package/dist/structural-rules/python/PY010-leaked-aiohttp-session.d.ts.map +1 -0
  201. package/dist/structural-rules/python/PY010-leaked-aiohttp-session.js +80 -0
  202. package/dist/structural-rules/python/PY010-leaked-aiohttp-session.js.map +1 -0
  203. package/dist/structural-rules/python/PY011-thread-lifecycle.d.ts +11 -0
  204. package/dist/structural-rules/python/PY011-thread-lifecycle.d.ts.map +1 -0
  205. package/dist/structural-rules/python/PY011-thread-lifecycle.js +97 -0
  206. package/dist/structural-rules/python/PY011-thread-lifecycle.js.map +1 -0
  207. package/dist/structural-rules/python/PY012-asyncio-run-misuse.d.ts +11 -0
  208. package/dist/structural-rules/python/PY012-asyncio-run-misuse.d.ts.map +1 -0
  209. package/dist/structural-rules/python/PY012-asyncio-run-misuse.js +83 -0
  210. package/dist/structural-rules/python/PY012-asyncio-run-misuse.js.map +1 -0
  211. package/dist/structural-rules/python/PY013-mutable-default-arg.d.ts +11 -0
  212. package/dist/structural-rules/python/PY013-mutable-default-arg.d.ts.map +1 -0
  213. package/dist/structural-rules/python/PY013-mutable-default-arg.js +73 -0
  214. package/dist/structural-rules/python/PY013-mutable-default-arg.js.map +1 -0
  215. package/dist/structural-rules/python/PY014-fixed-sleep-retry.d.ts +11 -0
  216. package/dist/structural-rules/python/PY014-fixed-sleep-retry.d.ts.map +1 -0
  217. package/dist/structural-rules/python/PY014-fixed-sleep-retry.js +115 -0
  218. package/dist/structural-rules/python/PY014-fixed-sleep-retry.js.map +1 -0
  219. package/dist/structural-rules/rules/SR001-swallowed-async-rejection.d.ts +11 -0
  220. package/dist/structural-rules/rules/SR001-swallowed-async-rejection.d.ts.map +1 -0
  221. package/dist/structural-rules/rules/SR001-swallowed-async-rejection.js +145 -0
  222. package/dist/structural-rules/rules/SR001-swallowed-async-rejection.js.map +1 -0
  223. package/dist/structural-rules/rules/SR002-unbounded-collection.d.ts +11 -0
  224. package/dist/structural-rules/rules/SR002-unbounded-collection.d.ts.map +1 -0
  225. package/dist/structural-rules/rules/SR002-unbounded-collection.js +196 -0
  226. package/dist/structural-rules/rules/SR002-unbounded-collection.js.map +1 -0
  227. package/dist/structural-rules/rules/SR003-timer-without-cleanup.d.ts +11 -0
  228. package/dist/structural-rules/rules/SR003-timer-without-cleanup.d.ts.map +1 -0
  229. package/dist/structural-rules/rules/SR003-timer-without-cleanup.js +148 -0
  230. package/dist/structural-rules/rules/SR003-timer-without-cleanup.js.map +1 -0
  231. package/dist/structural-rules/rules/SR004-request-boundary-no-validation.d.ts +11 -0
  232. package/dist/structural-rules/rules/SR004-request-boundary-no-validation.d.ts.map +1 -0
  233. package/dist/structural-rules/rules/SR004-request-boundary-no-validation.js +162 -0
  234. package/dist/structural-rules/rules/SR004-request-boundary-no-validation.js.map +1 -0
  235. package/dist/structural-rules/rules/SR005-halfopen-probe-gate.d.ts +11 -0
  236. package/dist/structural-rules/rules/SR005-halfopen-probe-gate.d.ts.map +1 -0
  237. package/dist/structural-rules/rules/SR005-halfopen-probe-gate.js +150 -0
  238. package/dist/structural-rules/rules/SR005-halfopen-probe-gate.js.map +1 -0
  239. package/dist/structural-rules/rules/SR006-fanout-error-sanitization.d.ts +11 -0
  240. package/dist/structural-rules/rules/SR006-fanout-error-sanitization.d.ts.map +1 -0
  241. package/dist/structural-rules/rules/SR006-fanout-error-sanitization.js +161 -0
  242. package/dist/structural-rules/rules/SR006-fanout-error-sanitization.js.map +1 -0
  243. package/dist/structural-rules/rules/SR007-cross-request-error.d.ts +11 -0
  244. package/dist/structural-rules/rules/SR007-cross-request-error.d.ts.map +1 -0
  245. package/dist/structural-rules/rules/SR007-cross-request-error.js +175 -0
  246. package/dist/structural-rules/rules/SR007-cross-request-error.js.map +1 -0
  247. package/dist/structural-rules/rules/SR008-background-task-orphan.d.ts +11 -0
  248. package/dist/structural-rules/rules/SR008-background-task-orphan.d.ts.map +1 -0
  249. package/dist/structural-rules/rules/SR008-background-task-orphan.js +176 -0
  250. package/dist/structural-rules/rules/SR008-background-task-orphan.js.map +1 -0
  251. package/dist/structural-rules/rules/SR009-missing-retry-backoff.d.ts +11 -0
  252. package/dist/structural-rules/rules/SR009-missing-retry-backoff.d.ts.map +1 -0
  253. package/dist/structural-rules/rules/SR009-missing-retry-backoff.js +168 -0
  254. package/dist/structural-rules/rules/SR009-missing-retry-backoff.js.map +1 -0
  255. package/dist/structural-rules/rules/SR010-retry-storm.d.ts +11 -0
  256. package/dist/structural-rules/rules/SR010-retry-storm.d.ts.map +1 -0
  257. package/dist/structural-rules/rules/SR010-retry-storm.js +181 -0
  258. package/dist/structural-rules/rules/SR010-retry-storm.js.map +1 -0
  259. package/dist/structural-rules/rules/SR011-event-listener-leak.d.ts +11 -0
  260. package/dist/structural-rules/rules/SR011-event-listener-leak.d.ts.map +1 -0
  261. package/dist/structural-rules/rules/SR011-event-listener-leak.js +208 -0
  262. package/dist/structural-rules/rules/SR011-event-listener-leak.js.map +1 -0
  263. package/dist/structural-rules/rules/SR012-promise-race-leak.d.ts +11 -0
  264. package/dist/structural-rules/rules/SR012-promise-race-leak.d.ts.map +1 -0
  265. package/dist/structural-rules/rules/SR012-promise-race-leak.js +191 -0
  266. package/dist/structural-rules/rules/SR012-promise-race-leak.js.map +1 -0
  267. package/dist/structural-rules/rules/SR013-missing-idempotency-key.d.ts +11 -0
  268. package/dist/structural-rules/rules/SR013-missing-idempotency-key.d.ts.map +1 -0
  269. package/dist/structural-rules/rules/SR013-missing-idempotency-key.js +219 -0
  270. package/dist/structural-rules/rules/SR013-missing-idempotency-key.js.map +1 -0
  271. package/dist/structural-rules/rules/SR014-mutable-closure-async.d.ts +11 -0
  272. package/dist/structural-rules/rules/SR014-mutable-closure-async.d.ts.map +1 -0
  273. package/dist/structural-rules/rules/SR014-mutable-closure-async.js +208 -0
  274. package/dist/structural-rules/rules/SR014-mutable-closure-async.js.map +1 -0
  275. package/dist/structural-rules/rules/SR015-dangling-abort-controller.d.ts +11 -0
  276. package/dist/structural-rules/rules/SR015-dangling-abort-controller.d.ts.map +1 -0
  277. package/dist/structural-rules/rules/SR015-dangling-abort-controller.js +190 -0
  278. package/dist/structural-rules/rules/SR015-dangling-abort-controller.js.map +1 -0
  279. package/dist/structural-rules/rules/SR016-unsafe-json-parse.d.ts +11 -0
  280. package/dist/structural-rules/rules/SR016-unsafe-json-parse.d.ts.map +1 -0
  281. package/dist/structural-rules/rules/SR016-unsafe-json-parse.js +187 -0
  282. package/dist/structural-rules/rules/SR016-unsafe-json-parse.js.map +1 -0
  283. package/dist/structural-rules/suppressions.d.ts +43 -0
  284. package/dist/structural-rules/suppressions.d.ts.map +1 -0
  285. package/dist/structural-rules/suppressions.js +115 -0
  286. package/dist/structural-rules/suppressions.js.map +1 -0
  287. package/dist/structural-rules/types.d.ts +55 -0
  288. package/dist/structural-rules/types.d.ts.map +1 -0
  289. package/dist/structural-rules/types.js +3 -0
  290. package/dist/structural-rules/types.js.map +1 -0
  291. package/dist/utils/brain-cache.d.ts +100 -0
  292. package/dist/utils/brain-cache.d.ts.map +1 -0
  293. package/dist/utils/brain-cache.js +346 -0
  294. package/dist/utils/brain-cache.js.map +1 -0
  295. package/dist/utils/governance-provenance.d.ts +95 -0
  296. package/dist/utils/governance-provenance.d.ts.map +1 -0
  297. package/dist/utils/governance-provenance.js +187 -0
  298. package/dist/utils/governance-provenance.js.map +1 -0
  299. package/dist/utils/pilot-metrics.d.ts +46 -0
  300. package/dist/utils/pilot-metrics.d.ts.map +1 -0
  301. package/dist/utils/pilot-metrics.js +240 -0
  302. package/dist/utils/pilot-metrics.js.map +1 -0
  303. package/dist/utils/replay-runtime.d.ts +34 -0
  304. package/dist/utils/replay-runtime.d.ts.map +1 -1
  305. package/dist/utils/replay-runtime.js +207 -0
  306. package/dist/utils/replay-runtime.js.map +1 -1
  307. package/dist/utils/verify-runtime-stability.d.ts +142 -0
  308. package/dist/utils/verify-runtime-stability.d.ts.map +1 -0
  309. package/dist/utils/verify-runtime-stability.js +230 -0
  310. package/dist/utils/verify-runtime-stability.js.map +1 -0
  311. package/dist/workspace/cross-repo-graph.d.ts +111 -0
  312. package/dist/workspace/cross-repo-graph.d.ts.map +1 -0
  313. package/dist/workspace/cross-repo-graph.js +450 -0
  314. package/dist/workspace/cross-repo-graph.js.map +1 -0
  315. package/dist/workspace/federated-context.d.ts +144 -0
  316. package/dist/workspace/federated-context.d.ts.map +1 -0
  317. package/dist/workspace/federated-context.js +347 -0
  318. package/dist/workspace/federated-context.js.map +1 -0
  319. package/dist/workspace/index.d.ts +38 -0
  320. package/dist/workspace/index.d.ts.map +1 -0
  321. package/dist/workspace/index.js +48 -0
  322. package/dist/workspace/index.js.map +1 -0
  323. package/package.json +9 -9
@@ -67,11 +67,24 @@ const policy_compiler_1 = require("../utils/policy-compiler");
67
67
  const change_contract_1 = require("../utils/change-contract");
68
68
  const diff_symbols_1 = require("../utils/diff-symbols");
69
69
  const advisory_signals_1 = require("../utils/advisory-signals");
70
+ const structural_rules_1 = require("../structural-rules");
71
+ const canonical_pipeline_1 = require("../governance/canonical-pipeline");
72
+ const canonical_invariants_1 = require("../governance/canonical-invariants");
73
+ const structural_on_diff_1 = require("../governance/structural-on-diff");
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).
78
+ const telemetry_1 = require("@neurcode-ai/telemetry");
79
+ const governance_provenance_1 = require("../utils/governance-provenance");
80
+ const pilot_metrics_1 = require("../utils/pilot-metrics");
81
+ const explainability_1 = require("../explainability");
70
82
  const runtime_guard_1 = require("../utils/runtime-guard");
71
83
  const artifact_signature_1 = require("../utils/artifact-signature");
72
84
  const policy_1 = require("@neurcode-ai/policy");
73
85
  const ai_debt_budget_1 = require("../utils/ai-debt-budget");
74
86
  const verification_evidence_1 = require("../utils/verification-evidence");
87
+ const verify_runtime_stability_1 = require("../utils/verify-runtime-stability");
75
88
  // Import chalk with fallback
76
89
  let chalk;
77
90
  try {
@@ -92,6 +105,38 @@ catch {
92
105
  white: (str) => str,
93
106
  };
94
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
+ }
95
140
  ;
96
141
  function toArtifactSignatureSummary(status) {
97
142
  return {
@@ -1080,10 +1125,17 @@ function toCanonicalVerifyOutput(payload) {
1080
1125
  'policyDecision',
1081
1126
  'policyPack',
1082
1127
  'changeContractViolations',
1128
+ 'governanceVerification',
1129
+ 'governanceFindings',
1130
+ 'structuralViolations',
1131
+ 'structuralRulesApplied',
1132
+ 'structuralSuppressedCount',
1083
1133
  ];
1134
+ const canonicalMutable = canonical;
1084
1135
  for (const key of passthroughKeys) {
1085
- if (Object.prototype.hasOwnProperty.call(payload, key) && payload[key] !== undefined) {
1086
- canonical[key] = payload[key];
1136
+ const v = payload[key];
1137
+ if (Object.prototype.hasOwnProperty.call(payload, key) && v !== undefined && v !== null) {
1138
+ canonicalMutable[key] = v;
1087
1139
  }
1088
1140
  }
1089
1141
  // Backward-compatibility alias: older integrations and tests expect `rule`
@@ -1099,7 +1151,7 @@ function toCanonicalVerifyOutput(payload) {
1099
1151
  return canonical;
1100
1152
  }
1101
1153
  function emitCanonicalVerifyJson(payload, onEmit) {
1102
- const canonical = toCanonicalVerifyOutput(payload);
1154
+ const canonical = toCanonicalVerifyOutput((0, canonical_pipeline_1.attachCanonicalGovernance)(payload));
1103
1155
  onEmit?.(canonical);
1104
1156
  // Use sync stdout write so immediate process.exit paths do not truncate JSON.
1105
1157
  const serialized = Buffer.from(`${JSON.stringify(canonical, null, 2)}\n`, 'utf-8');
@@ -1916,6 +1968,10 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
1916
1968
  message: `Policy audit chain is invalid: ${auditIntegrityStatus.issues.join('; ') || 'unknown issue'}`,
1917
1969
  });
1918
1970
  }
1971
+ const policyOnlyStructural = (0, structural_on_diff_1.runStructuralOnDiffFiles)(projectRoot, diffFilesForPolicy);
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.
1919
1975
  policyDecision = resolvePolicyDecisionFromViolations(policyViolations);
1920
1976
  const effectiveVerdict = policyDecision === 'block' ? 'FAIL' : policyDecision === 'warn' ? 'WARN' : 'PASS';
1921
1977
  const grade = effectiveVerdict === 'PASS' ? 'A' : effectiveVerdict === 'WARN' ? 'C' : 'F';
@@ -1972,6 +2028,11 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
1972
2028
  eventCount: auditIntegrity.count,
1973
2029
  },
1974
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);
1975
2036
  const policyOnlyPayload = {
1976
2037
  grade,
1977
2038
  score,
@@ -1984,9 +2045,14 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
1984
2045
  plannedFilesModified: 0,
1985
2046
  totalPlannedFiles: 0,
1986
2047
  adherenceScore: score,
2048
+ structuralViolations: policyOnlyStructural.violations,
2049
+ structuralRulesApplied: policyOnlyStructural.rulesApplied,
2050
+ structuralSuppressedCount: policyOnlyStructural.suppressedCount,
1987
2051
  mode: 'policy_only',
1988
2052
  policyOnly: true,
1989
2053
  policyOnlySource: source,
2054
+ replayChecksum: policyOnlyReplayChecksum,
2055
+ replayMode: 'local-structural',
1990
2056
  ...governancePayload,
1991
2057
  policyLock: {
1992
2058
  enforced: policyLockEvaluation.enforced,
@@ -2037,6 +2103,16 @@ async function executePolicyOnlyMode(options, diffFiles, ignoreFilter, projectRo
2037
2103
  }
2038
2104
  displayGovernanceInsights(governanceAnalysis, { explain: options.explain });
2039
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
+ });
2040
2116
  }
2041
2117
  await recordPolicyOnlyVerification({
2042
2118
  grade,
@@ -2067,9 +2143,18 @@ async function verifyCommand(options) {
2067
2143
  const evidenceEnabled = options.evidence === true || isEnabledFlag(process.env.NEURCODE_VERIFY_EVIDENCE);
2068
2144
  const verifyStartedAtMs = Date.now();
2069
2145
  const evidenceCiContext = collectCIContext();
2146
+ /** Set when provenance is written (human path); JSON early-exit may leave null. */
2147
+ let lastProvenanceRunId = null;
2070
2148
  let lastCanonicalOutput = null;
2071
2149
  let lastEvidenceFallbackOutput = null;
2072
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);
2073
2158
  if (ciModeEnabled) {
2074
2159
  options.policyOnly = true;
2075
2160
  options.requirePlan = false;
@@ -2120,6 +2205,12 @@ async function verifyCommand(options) {
2120
2205
  };
2121
2206
  const exitWithEvidence = (exitCode) => {
2122
2207
  finalizeEvidence(exitCode);
2208
+ try {
2209
+ (0, telemetry_1.appendVerifyCompletedFromCanonical)(projectRoot, lastCanonicalOutput, lastProvenanceRunId);
2210
+ }
2211
+ catch {
2212
+ // calibration must never affect exit
2213
+ }
2123
2214
  process.exit(exitCode);
2124
2215
  };
2125
2216
  exitWithEvidenceFromTry = exitWithEvidence;
@@ -2130,7 +2221,14 @@ async function verifyCommand(options) {
2130
2221
  let intentEngineSummary = null;
2131
2222
  let intentEngineFlowIssues = [];
2132
2223
  let intentEngineRegressions = [];
2224
+ // Structural rule engine results — AST-level deterministic violations
2225
+ let structuralViolations = [];
2226
+ let structuralRulesApplied = [];
2227
+ let structuralSuppressedCount = 0;
2133
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);
2134
2232
  const enrichedPayload = {
2135
2233
  ...payload,
2136
2234
  ciMode: payload.ciMode ?? ciModeEnabled,
@@ -2143,6 +2241,11 @@ async function verifyCommand(options) {
2143
2241
  flowIssues: payload.flowIssues ?? intentEngineFlowIssues,
2144
2242
  // V6: regressions always injected
2145
2243
  regressions: payload.regressions ?? intentEngineRegressions,
2244
+ structuralViolations: payload.structuralViolations ?? structuralViolations,
2245
+ structuralRulesApplied: payload.structuralRulesApplied ?? structuralRulesApplied,
2246
+ structuralSuppressedCount: payload.structuralSuppressedCount ?? structuralSuppressedCount,
2247
+ // Runtime stability transparency — always present
2248
+ runtimeStabilityReport,
2146
2249
  };
2147
2250
  lastEvidenceFallbackOutput = enrichedPayload;
2148
2251
  emitCanonicalVerifyJson(enrichedPayload, (canonical) => {
@@ -2461,10 +2564,14 @@ async function verifyCommand(options) {
2461
2564
  console.log(chalk.dim(' CI mode: deterministic local verification enabled (policy-only, non-interactive).'));
2462
2565
  }
2463
2566
  }
2464
- const enforceCompatibilityHandshake = isEnabledFlag(process.env.NEURCODE_VERIFY_ENFORCE_COMPAT_HANDSHAKE)
2465
- || strictArtifactMode
2466
- || (process.env.CI === 'true' && Boolean(config.apiKey));
2467
- if (config.apiKey && config.apiUrl) {
2567
+ // NEURCODE_VERIFY_LOCAL_ONLY=1 or --local-only: skip API entirely, run structural-only
2568
+ const localOnlyMode = isEnabledFlag(process.env.NEURCODE_VERIFY_LOCAL_ONLY)
2569
+ || options.localOnly === true;
2570
+ const enforceCompatibilityHandshake = !localOnlyMode
2571
+ && (isEnabledFlag(process.env.NEURCODE_VERIFY_ENFORCE_COMPAT_HANDSHAKE)
2572
+ || strictArtifactMode
2573
+ || (process.env.CI === 'true' && Boolean(config.apiKey)));
2574
+ if (!localOnlyMode && config.apiKey && config.apiUrl) {
2468
2575
  const compatibilityProbe = await probeApiRuntimeCompatibility(config.apiUrl);
2469
2576
  if (compatibilityProbe.status !== 'ok' && enforceCompatibilityHandshake) {
2470
2577
  const failureMessages = compatibilityProbe.messages.length > 0
@@ -2493,6 +2600,7 @@ async function verifyCommand(options) {
2493
2600
  mode: 'runtime_compatibility_failed',
2494
2601
  policyOnly: options.policyOnly === true,
2495
2602
  changeContract: changeContractSummary,
2603
+ offlineFallbackHint: 'Run with NEURCODE_VERIFY_LOCAL_ONLY=1 or --local-only for offline structural verification.',
2496
2604
  ...(compiledPolicyMetadata ? { policyCompilation: compiledPolicyMetadata } : {}),
2497
2605
  });
2498
2606
  }
@@ -2507,6 +2615,7 @@ async function verifyCommand(options) {
2507
2615
  }
2508
2616
  console.log(chalk.dim(` CLI version: ${CLI_COMPONENT_VERSION}`));
2509
2617
  console.log(chalk.dim(' Upgrade/downgrade CLI, Action, or API to satisfy the runtime compatibility contract before running verify.\n'));
2618
+ console.log(chalk.dim(' Tip: Use --local-only to run offline deterministic structural verification without the API.\n'));
2510
2619
  }
2511
2620
  exitWithEvidence(2);
2512
2621
  }
@@ -2581,8 +2690,19 @@ async function verifyCommand(options) {
2581
2690
  try {
2582
2691
  let contextNote = note;
2583
2692
  if (Array.isArray(changedFiles) && changedFiles.length > 0) {
2584
- const refreshed = (0, brain_context_1.refreshBrainContextForFiles)(projectRoot, brainScope, changedFiles);
2585
- contextNote = `${contextNote};indexed=${refreshed.indexed};removed=${refreshed.removed};skipped=${refreshed.skipped}`;
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
+ }
2586
2706
  }
2587
2707
  (0, brain_context_1.recordBrainProgressEvent)(projectRoot, brainScope, {
2588
2708
  type: 'verify',
@@ -2726,6 +2846,64 @@ async function verifyCommand(options) {
2726
2846
  const excludeOldPath = file.oldPath ? isExcludedFile(file.oldPath) : false;
2727
2847
  return !excludePath && !excludeOldPath;
2728
2848
  });
2849
+ // ── Local-only mode (Part 8): run structural analysis and exit, no API calls ──
2850
+ // Triggered by NEURCODE_VERIFY_LOCAL_ONLY=1 or --local-only.
2851
+ // Deterministic structural governance MUST work offline, with zero API dependency.
2852
+ if (localOnlyMode) {
2853
+ if (!options.json) {
2854
+ console.log(chalk.cyan('\n🔍 Local-only mode: deterministic structural verification (no API required)...'));
2855
+ }
2856
+ const localStructural = (0, structural_on_diff_1.runStructuralOnDiffFiles)(projectRoot, diffFiles);
2857
+ const blockingViolations = localStructural.violations.filter((v) => v.severity === 'BLOCKING');
2858
+ const localVerdict = blockingViolations.length > 0 ? 'FAIL' : 'PASS';
2859
+ const localGrade = blockingViolations.length > 0 ? 'F' : 'B';
2860
+ const localScore = blockingViolations.length > 0 ? 0 : 70;
2861
+ if (options.json) {
2862
+ emitVerifyJson({
2863
+ grade: localGrade,
2864
+ score: localScore,
2865
+ verdict: localVerdict,
2866
+ violations: localStructural.violations.map((v) => ({
2867
+ file: v.filePath,
2868
+ rule: v.ruleId,
2869
+ severity: v.severity === 'BLOCKING' ? 'block' : 'warn',
2870
+ message: `${v.ruleName}: ${v.evidence.slice(0, 120)}`,
2871
+ })),
2872
+ adherenceScore: localScore,
2873
+ bloatCount: 0,
2874
+ bloatFiles: [],
2875
+ plannedFilesModified: 0,
2876
+ totalPlannedFiles: 0,
2877
+ message: `Local-only structural verification: ${localStructural.violations.length} finding(s), ${blockingViolations.length} blocking.`,
2878
+ scopeGuardPassed: true,
2879
+ mode: 'local_only_structural',
2880
+ policyOnly: true,
2881
+ structuralViolations: localStructural.violations,
2882
+ structuralBlockingCount: blockingViolations.length,
2883
+ structuralRulesApplied: localStructural.rulesApplied,
2884
+ changeContract: changeContractSummary,
2885
+ });
2886
+ }
2887
+ else {
2888
+ if (localStructural.violations.length === 0) {
2889
+ console.log(chalk.green('\n✅ No structural violations found (local-only mode).'));
2890
+ }
2891
+ else {
2892
+ localStructural.violations.forEach((v) => {
2893
+ const prefix = v.severity === 'BLOCKING' ? chalk.red(' ⛔ BLOCKING') : chalk.yellow(' ⚠ ADVISORY');
2894
+ console.log(`${prefix} ${v.ruleId} — ${v.filePath}:${v.line}`);
2895
+ console.log(chalk.dim(` ${v.ruleName}`));
2896
+ console.log(chalk.dim(` ${v.evidence.slice(0, 100)}`));
2897
+ });
2898
+ }
2899
+ console.log(chalk.dim(`\n[Local-only] ${localStructural.violations.length} finding(s), ${blockingViolations.length} blocking. ` +
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'));
2903
+ }
2904
+ recordVerifyEvent(localVerdict, `local_only;structural=${localStructural.violations.length}`, diffFiles.map((f) => f.path));
2905
+ exitWithEvidence(blockingViolations.length > 0 ? 2 : 0);
2906
+ }
2729
2907
  const summary = (0, diff_parser_1.getDiffSummary)(diffFiles);
2730
2908
  if (diffFiles.length === 0) {
2731
2909
  if (!options.json) {
@@ -3119,20 +3297,59 @@ async function verifyCommand(options) {
3119
3297
  }
3120
3298
  const message = 'No plan linked yet. Ran advisory verification for quick first-run experience. ' +
3121
3299
  'Use `neurcode plan` and `neurcode contract import --auto-detect --write-change-contract` for full enforcement.';
3122
- const advisorySignals = (0, advisory_signals_1.evaluateAdvisorySignals)({
3123
- diffFiles,
3124
- summary,
3125
- });
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
+ }
3126
3308
  const advisoryWarnCount = advisorySignals.filter((item) => item.severity === 'warn').length;
3127
- const advisoryVerdict = advisoryWarnCount > 0 ? 'WARN' : 'PASS';
3128
- const advisoryGrade = advisoryWarnCount > 0 ? 'C' : 'B';
3129
- const advisoryScore = advisoryWarnCount > 0 ? 60 : 70;
3130
- const advisoryViolations = advisorySignals.map((item) => ({
3131
- file: item.files[0] || '.',
3132
- rule: `advisory:${item.code.toLowerCase()}`,
3133
- severity: item.severity === 'warn' ? 'warn' : 'allow',
3134
- message: `${item.title}: ${item.detail}`,
3135
- }));
3309
+ // ── Advisory-first: always run structural rules, downgrade scope issues to advisory ──
3310
+ // Structural rules are deterministic and local they MUST always run regardless of plan.
3311
+ let advisoryStructuralViolations = [];
3312
+ let advisoryStructuralBlockingCount = 0;
3313
+ try {
3314
+ if (!options.json) {
3315
+ console.log(chalk.cyan('🔍 Running deterministic structural analysis (advisory mode — no plan)...'));
3316
+ }
3317
+ const structuralResult = (0, structural_on_diff_1.runStructuralOnDiffFiles)(projectRoot, diffFiles);
3318
+ advisoryStructuralViolations = structuralResult.violations;
3319
+ // In advisory mode (no plan), BLOCKING structural violations are downgraded to advisory warnings.
3320
+ // They are still surfaced — engineers must review them — but they do not block the verify exit.
3321
+ advisoryStructuralBlockingCount = structuralResult.violations.filter((v) => v.severity === 'BLOCKING').length;
3322
+ if (!options.json && advisoryStructuralViolations.length > 0) {
3323
+ console.log(chalk.yellow(`\n⚠ Structural findings (advisory — link a plan to enable enforcement):`));
3324
+ advisoryStructuralViolations.forEach((v) => {
3325
+ const prefix = v.severity === 'BLOCKING' ? chalk.yellow(' ⚠ BLOCKING (advisory)') : chalk.dim(' ℹ ADVISORY');
3326
+ console.log(`${prefix} ${v.ruleId} — ${v.filePath}:${v.line}`);
3327
+ console.log(chalk.dim(` ${v.ruleName}`));
3328
+ console.log(chalk.dim(` ${v.evidence.slice(0, 100)}`));
3329
+ });
3330
+ console.log(chalk.dim(`\n To enforce these findings: run \`neurcode plan "<intent>"\` to link a plan.\n`));
3331
+ }
3332
+ }
3333
+ catch {
3334
+ // Structural engine failure must never block advisory verify
3335
+ }
3336
+ const advisoryVerdict = advisoryWarnCount > 0 || advisoryStructuralBlockingCount > 0 ? 'WARN' : 'PASS';
3337
+ const advisoryGrade = advisoryWarnCount > 0 || advisoryStructuralBlockingCount > 0 ? 'C' : 'B';
3338
+ const advisoryScore = advisoryWarnCount > 0 || advisoryStructuralBlockingCount > 0 ? 60 : 70;
3339
+ const advisoryViolations = [
3340
+ ...advisorySignals.map((item) => ({
3341
+ file: item.files[0] || '.',
3342
+ rule: `advisory:${item.code.toLowerCase()}`,
3343
+ severity: item.severity === 'warn' ? 'warn' : 'allow',
3344
+ message: `${item.title}: ${item.detail}`,
3345
+ })),
3346
+ ...advisoryStructuralViolations.map((v) => ({
3347
+ file: v.filePath,
3348
+ rule: `structural-advisory:${v.ruleId.toLowerCase()}`,
3349
+ severity: 'warn',
3350
+ message: `${v.ruleId} ${v.ruleName}: ${v.evidence.slice(0, 100)} (advisory — link plan to enforce)`,
3351
+ })),
3352
+ ];
3136
3353
  recordVerifyEvent(advisoryVerdict, `advisory_missing_plan;signals=${advisorySignals.length};warn=${advisoryWarnCount}`, diffFiles.map((f) => f.path));
3137
3354
  if (options.json) {
3138
3355
  emitVerifyJson({
@@ -3150,6 +3367,11 @@ async function verifyCommand(options) {
3150
3367
  mode: 'advisory_missing_plan',
3151
3368
  advisoryMode: true,
3152
3369
  advisorySignals,
3370
+ structuralViolations: advisoryStructuralViolations,
3371
+ structuralBlockingCount: advisoryStructuralBlockingCount,
3372
+ structuralNote: advisoryStructuralBlockingCount > 0
3373
+ ? `${advisoryStructuralBlockingCount} structural finding(s) surfaced in advisory mode. Link a plan to enforce.`
3374
+ : undefined,
3153
3375
  policyOnly: true,
3154
3376
  policyOnlySource: 'fallback_missing_plan',
3155
3377
  ...(autoContractPath
@@ -3255,6 +3477,36 @@ async function verifyCommand(options) {
3255
3477
  // Non-fatal: intent engine errors must never break verification
3256
3478
  }
3257
3479
  }
3480
+ // ── Structural Rule Engine ──────────────────────────────────────────────
3481
+ // AST-level deterministic analysis against changed files.
3482
+ // Reads file contents from disk; never throws — errors are isolated per file.
3483
+ if (diffFiles.length > 0) {
3484
+ try {
3485
+ const structuralEngine = (0, structural_rules_1.createDefaultStructuralRuleEngine)();
3486
+ const filesToAnalyze = [];
3487
+ for (const df of diffFiles) {
3488
+ const absPath = (0, path_1.join)(projectRoot, df.path);
3489
+ if ((0, fs_1.existsSync)(absPath)) {
3490
+ try {
3491
+ const sourceText = (0, fs_1.readFileSync)(absPath, 'utf-8');
3492
+ filesToAnalyze.push({ filePath: df.path, sourceText });
3493
+ }
3494
+ catch {
3495
+ // Skip unreadable files
3496
+ }
3497
+ }
3498
+ }
3499
+ if (filesToAnalyze.length > 0) {
3500
+ const structuralResult = structuralEngine.analyze(filesToAnalyze);
3501
+ structuralViolations = structuralResult.violations;
3502
+ structuralRulesApplied = structuralResult.rulesApplied;
3503
+ structuralSuppressedCount = structuralResult.suppressedCount;
3504
+ }
3505
+ }
3506
+ catch {
3507
+ // Non-fatal: structural engine errors must never break verification
3508
+ }
3509
+ }
3258
3510
  governanceResult = (0, governance_1.evaluateGovernance)({
3259
3511
  projectRoot,
3260
3512
  task: governanceTask,
@@ -3804,6 +4056,9 @@ async function verifyCommand(options) {
3804
4056
  message: `Policy audit chain is invalid: ${auditIntegrityStatus.issues.join('; ') || 'unknown issue'}`,
3805
4057
  });
3806
4058
  }
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.
3807
4062
  policyDecision = resolvePolicyDecisionFromViolations(policyViolations);
3808
4063
  const policyExceptionsSummary = {
3809
4064
  sourceMode: policyExceptionResolution.mode,
@@ -4251,6 +4506,9 @@ async function verifyCommand(options) {
4251
4506
  plannedFilesModified: verifyResult.plannedFilesModified,
4252
4507
  totalPlannedFiles: verifyResult.totalPlannedFiles,
4253
4508
  verificationSource: verifySource,
4509
+ structuralViolations,
4510
+ structuralRulesApplied,
4511
+ structuralSuppressedCount,
4254
4512
  mode: 'plan_enforced',
4255
4513
  policyOnly: false,
4256
4514
  aiDebt: aiDebtSummary,
@@ -4322,7 +4580,7 @@ async function verifyCommand(options) {
4322
4580
  message: effectiveMessage,
4323
4581
  bloatFiles: displayBloatFiles,
4324
4582
  bloatCount: displayBloatFiles.length,
4325
- }, policyViolations, expediteModeEnabled, intentEngineIssues, intentEngineSummary, intentEngineFlowIssues, intentEngineRegressions);
4583
+ }, policyViolations, expediteModeEnabled, intentEngineIssues, intentEngineSummary, intentEngineFlowIssues, intentEngineRegressions, structuralViolations);
4326
4584
  if (governanceResult) {
4327
4585
  displayGovernanceInsights(governanceResult, { explain: options.explain });
4328
4586
  }
@@ -4385,6 +4643,67 @@ async function verifyCommand(options) {
4385
4643
  console.log(chalk.dim(' Intent proof repo scan reached configured file/byte limit (truncated).'));
4386
4644
  }
4387
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.'));
4655
+ }
4656
+ // ── Governance Provenance Chain + Pilot Metrics ───────────────────────
4657
+ // Best-effort: never throws, never changes the verification outcome.
4658
+ try {
4659
+ const structuralBlocking = structuralViolations.filter(v => v.severity === 'BLOCKING').length;
4660
+ const structuralAdvisory = structuralViolations.filter(v => v.severity === 'ADVISORY').length;
4661
+ const deterministicSigs = structuralViolations.filter(v => v.determinism === 'deterministic-structural').length;
4662
+ const heuristicSigs = structuralViolations.filter(v => v.determinism === 'heuristic-advisory').length;
4663
+ const trustScore = structuralViolations.length > 0
4664
+ ? Math.round((deterministicSigs / structuralViolations.length) * 100)
4665
+ : 100;
4666
+ const prov = (0, governance_provenance_1.buildProvenanceRecord)({
4667
+ repoRoot: projectRoot,
4668
+ filesAnalyzed: diffFiles.length,
4669
+ diffContext: `${options.base || 'HEAD'} vs working tree`,
4670
+ planId: finalPlanId || null,
4671
+ intentHash: null,
4672
+ policyHash: null,
4673
+ ruleIds: structuralRulesApplied,
4674
+ blockingCount: policyViolations.filter((v) => v.severity === 'block').length + structuralBlocking,
4675
+ advisoryCount: policyViolations.filter((v) => v.severity !== 'block').length + structuralAdvisory,
4676
+ suppressedCount: structuralSuppressedCount,
4677
+ structuralBlockingCount: structuralBlocking,
4678
+ structuralAdvisoryCount: structuralAdvisory,
4679
+ deterministicSignals: deterministicSigs,
4680
+ heuristicSignals: heuristicSigs,
4681
+ overallTrustScore: trustScore,
4682
+ verdict: effectiveVerdict,
4683
+ governanceDecision: governanceResult?.governanceDecision?.summary || 'automatic',
4684
+ });
4685
+ (0, governance_provenance_1.saveProvenanceRecord)(projectRoot, prov);
4686
+ lastProvenanceRunId = prov.runId;
4687
+ // Tally per-rule counts for pilot metrics
4688
+ const ruleCounts = {};
4689
+ for (const v of structuralViolations) {
4690
+ ruleCounts[v.ruleId] = (ruleCounts[v.ruleId] ?? 0) + 1;
4691
+ }
4692
+ (0, pilot_metrics_1.recordVerifyRun)(projectRoot, {
4693
+ planCount: 0,
4694
+ verifyCount: 1,
4695
+ passCount: effectiveVerdict === 'PASS' ? 1 : 0,
4696
+ failCount: effectiveVerdict === 'FAIL' ? 1 : 0,
4697
+ blockingCaught: prov.blockingCount,
4698
+ advisoryCaught: prov.advisoryCount,
4699
+ suppressions: structuralSuppressedCount,
4700
+ structuralCaught: structuralViolations.length,
4701
+ aiDebtDelta: aiDebtSummary?.score ?? 0,
4702
+ ruleCounts,
4703
+ });
4704
+ }
4705
+ catch {
4706
+ // Never break verification
4388
4707
  }
4389
4708
  // Report to Neurcode Cloud if --record flag is set
4390
4709
  const filteredBloatForReport = (verifyResult.bloatFiles || []).filter((f) => !shouldIgnore(f));
@@ -4855,7 +5174,7 @@ function displayChangeContractDrift(summary, options = { advisory: false }) {
4855
5174
  /**
4856
5175
  * Display verification results in a formatted report card
4857
5176
  */
4858
- function displayVerifyResults(result, policyViolations, expediteModeUsed = false, intentIssuesForDisplay = [], intentSummaryForDisplay = null, flowIssuesForDisplay = [], regressionsForDisplay = []) {
5177
+ function displayVerifyResults(result, policyViolations, expediteModeUsed = false, intentIssuesForDisplay = [], intentSummaryForDisplay = null, flowIssuesForDisplay = [], regressionsForDisplay = [], structuralViolationsForDisplay = []) {
4859
5178
  // ── Header ────────────────────────────────────────────────────────────────
4860
5179
  const headerLabel = result.verdict === 'PASS'
4861
5180
  ? chalk.bold.green('\n✅ VERIFICATION PASSED')
@@ -4937,6 +5256,19 @@ function displayVerifyResults(result, policyViolations, expediteModeUsed = false
4937
5256
  policy: item.rule || 'policy_violation',
4938
5257
  severity: item.severity,
4939
5258
  }));
5259
+ // Structural rule violations — split by severity
5260
+ const structuralBlocking = structuralViolationsForDisplay
5261
+ .filter((v) => v.severity === 'BLOCKING')
5262
+ .map((v) => ({
5263
+ file: v.filePath,
5264
+ message: `${v.ruleId} · ${v.ruleName} (line ${v.line}) — ${v.operationalRisk}`,
5265
+ }));
5266
+ const structuralAdvisory = structuralViolationsForDisplay
5267
+ .filter((v) => v.severity === 'ADVISORY')
5268
+ .map((v) => ({
5269
+ file: v.filePath,
5270
+ message: `${v.ruleId} · ${v.ruleName} (line ${v.line}) — ${v.operationalRisk}`,
5271
+ }));
4940
5272
  let blockingItems = [
4941
5273
  ...scopeItems.map((item) => ({
4942
5274
  file: item.file,
@@ -4948,13 +5280,17 @@ function displayVerifyResults(result, policyViolations, expediteModeUsed = false
4948
5280
  file: item.file,
4949
5281
  message: item.message,
4950
5282
  })),
5283
+ ...structuralBlocking,
5284
+ ];
5285
+ let advisoryItems = [
5286
+ ...policyTriageItems
5287
+ .filter((item) => !isBlockingSeverity(item.severity))
5288
+ .map((item) => ({
5289
+ file: item.file,
5290
+ message: item.message,
5291
+ })),
5292
+ ...structuralAdvisory,
4951
5293
  ];
4952
- let advisoryItems = policyTriageItems
4953
- .filter((item) => !isBlockingSeverity(item.severity))
4954
- .map((item) => ({
4955
- file: item.file,
4956
- message: item.message,
4957
- }));
4958
5294
  let expediteItems = [];
4959
5295
  if (expediteModeUsed) {
4960
5296
  blockingItems = [
@@ -5066,6 +5402,49 @@ function displayVerifyResults(result, policyViolations, expediteModeUsed = false
5066
5402
  });
5067
5403
  console.log(chalk.bold.red('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
5068
5404
  }
5405
+ // ── Structural Rule Engine ─────────────────────────────────────────────────
5406
+ // Display detailed structural violations with AST evidence and determinism labels.
5407
+ if (structuralViolationsForDisplay.length > 0) {
5408
+ try {
5409
+ const report = (0, explainability_1.buildViolationReport)(structuralViolationsForDisplay, '');
5410
+ const formatter = new explainability_1.ViolationFormatter();
5411
+ const blocking = report.blocking;
5412
+ const advisory = report.advisory;
5413
+ if (blocking.length > 0 || advisory.length > 0) {
5414
+ console.log(chalk.bold('\n━━━ STRUCTURAL ANALYSIS ━━━━━━━━━━━━━━━━━'));
5415
+ blocking.slice(0, 5).forEach((v) => {
5416
+ const detLabel = v.determinism === 'deterministic-structural'
5417
+ ? chalk.cyan('⚙ AST-verified')
5418
+ : chalk.yellow('⚡ heuristic');
5419
+ console.log(chalk.red(`\n ● ${v.ruleId} [BLOCKING] ${detLabel} · confidence ${Math.round(v.confidence * 100)}%`));
5420
+ console.log(chalk.bold(` ${v.filePath}:${v.line}`));
5421
+ console.log(chalk.dim(` Pattern: ${v.evidence.matchReason}`));
5422
+ if (v.evidence.codeSnippet) {
5423
+ console.log(chalk.dim(` Code: ${v.evidence.codeSnippet.slice(0, 100)}`));
5424
+ }
5425
+ console.log(chalk.yellow(` Risk: ${v.operationalRisk}`));
5426
+ console.log(chalk.green(` Fix: ${v.remediation}`));
5427
+ });
5428
+ if (blocking.length > 5) {
5429
+ console.log(chalk.dim(`\n ... ${blocking.length - 5} more blocking structural violations`));
5430
+ }
5431
+ advisory.slice(0, 3).forEach((v) => {
5432
+ console.log(chalk.yellow(`\n ○ ${v.ruleId} [ADVISORY] ⚡ heuristic · confidence ${Math.round(v.confidence * 100)}%`));
5433
+ console.log(chalk.dim(` ${v.filePath}:${v.line} — ${v.operationalRisk}`));
5434
+ });
5435
+ if (advisory.length > 3) {
5436
+ console.log(chalk.dim(` ... ${advisory.length - 3} more advisory structural violations`));
5437
+ }
5438
+ const deterministicCount = report.deterministicCount;
5439
+ const heuristicCount = report.heuristicCount;
5440
+ console.log(chalk.dim(`\n Determinism: ${deterministicCount} AST-verified · ${heuristicCount} heuristic`));
5441
+ console.log(chalk.bold('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
5442
+ }
5443
+ }
5444
+ catch {
5445
+ // Non-fatal: explainability rendering must never break verification display
5446
+ }
5447
+ }
5069
5448
  const hasAnyIssue = blockingItems.length > 0 ||
5070
5449
  advisoryItems.length > 0 ||
5071
5450
  expediteItems.length > 0 ||