0xray 3.1.1 → 3.3.0

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 (309) hide show
  1. package/.opencode/codex.codex +1 -1
  2. package/.opencode/commands/auto-format.md +3 -3
  3. package/.opencode/commands/auto-summary-capture.md +2 -2
  4. package/.opencode/commands/enforcer-daily-scan.md +3 -3
  5. package/.opencode/commands/framework-compliance-audit.md +4 -4
  6. package/.opencode/commands/interactive-validator.md +2 -2
  7. package/.opencode/commands/job-summary-logger.md +2 -2
  8. package/.opencode/commands/mode-switch.md +1 -1
  9. package/.opencode/commands/model-health-check.md +2 -2
  10. package/.opencode/commands/performance-analysis.md +2 -2
  11. package/.opencode/commands/pre-commit-introspection.md +3 -3
  12. package/.opencode/commands/security-scan.md +3 -3
  13. package/.opencode/commands/sisyphus-validation.md +3 -3
  14. package/.opencode/commands/summary-logger.md +2 -2
  15. package/AGENTS.md +3 -13
  16. package/README.md +3 -3
  17. package/dist/AGENTS.md +3 -13
  18. package/dist/CHANGELOG.md +55 -0
  19. package/dist/README.md +3 -3
  20. package/dist/analytics/consent-manager.js +0 -1
  21. package/dist/analytics/emerging-pattern-detector.js +0 -1
  22. package/dist/analytics/pattern-learning-engine.js +0 -1
  23. package/dist/analytics/pattern-performance-tracker.js +0 -1
  24. package/dist/analytics/predictive-analytics.js +0 -1
  25. package/dist/analytics/prompt-pattern-analyzer.js +0 -1
  26. package/dist/analytics/routing-performance-analyzer.js +0 -1
  27. package/dist/analytics/routing-refiner.js +0 -1
  28. package/dist/analytics/simple-pattern-analyzer.js +0 -1
  29. package/dist/cli/commands/archive-logs.js +0 -1
  30. package/dist/cli/commands/opencode-install.js +13 -0
  31. package/dist/cli/commands/plugin-commands.js +0 -1
  32. package/dist/cli/commands/status.js +11 -13
  33. package/dist/cli/index.js +2 -7
  34. package/dist/core/activity-logger.js +0 -1
  35. package/dist/core/adaptive-kernel.js +0 -1
  36. package/dist/core/boot-orchestrator.js +2 -12
  37. package/dist/core/bridge.mjs +0 -1
  38. package/dist/core/codex-formatter.js +0 -1
  39. package/dist/core/codex-injector.js +0 -1
  40. package/dist/core/config-loader.js +36 -28
  41. package/dist/core/context-loader.js +0 -1
  42. package/dist/core/context-validator.js +0 -1
  43. package/dist/core/features-config.js +40 -1
  44. package/dist/core/kernel-patterns.js +0 -1
  45. package/dist/core/model-router.js +23 -64
  46. package/dist/core/system-prompt-generator.js +0 -1
  47. package/dist/delegation/agent-delegator.js +0 -1
  48. package/dist/delegation/agent-expertise.js +0 -1
  49. package/dist/delegation/analytics/index.js +0 -1
  50. package/dist/delegation/analytics/learning-engine.js +0 -1
  51. package/dist/delegation/analytics/outcome-tracker.js +0 -1
  52. package/dist/delegation/analytics/routing-analytics.js +0 -1
  53. package/dist/delegation/ast-code-parser.js +0 -1
  54. package/dist/delegation/complexity-analyzer.js +0 -1
  55. package/dist/delegation/dependency-graph-builder.js +0 -1
  56. package/dist/delegation/index.js +0 -1
  57. package/dist/delegation/metrics-aggregator.js +0 -1
  58. package/dist/delegation/session-coordinator.js +0 -1
  59. package/dist/delegation/strategy-selector.js +0 -1
  60. package/dist/delegation/voting-coordinator.js +0 -1
  61. package/dist/delegation/voting-types.js +0 -1
  62. package/dist/delegation/weighted-voting-aggregator.js +0 -1
  63. package/dist/enforcement/core/index.js +0 -1
  64. package/dist/enforcement/core/rule-executor.js +0 -1
  65. package/dist/enforcement/core/rule-hierarchy.js +0 -1
  66. package/dist/enforcement/core/rule-registry.js +0 -1
  67. package/dist/enforcement/core/violation-fixer.js +0 -1
  68. package/dist/enforcement/index.js +0 -1
  69. package/dist/enforcement/loaders/agent-triage-loader.js +0 -1
  70. package/dist/enforcement/loaders/agents-md-validation-loader.js +0 -1
  71. package/dist/enforcement/loaders/base-loader.js +0 -1
  72. package/dist/enforcement/loaders/codex-loader.js +0 -1
  73. package/dist/enforcement/loaders/index.js +0 -1
  74. package/dist/enforcement/loaders/loader-orchestrator.js +0 -1
  75. package/dist/enforcement/loaders/processor-loader.js +0 -1
  76. package/dist/enforcement/types.js +0 -1
  77. package/dist/enforcement/validators/architecture-validators.js +0 -1
  78. package/dist/enforcement/validators/base-validator.js +0 -1
  79. package/dist/enforcement/validators/code-quality-validators.js +0 -1
  80. package/dist/enforcement/validators/index.js +0 -1
  81. package/dist/enforcement/validators/security-validators.js +0 -1
  82. package/dist/enforcement/validators/testing-validators.js +0 -1
  83. package/dist/enforcement/validators/validator-registry.js +0 -1
  84. package/dist/governance/codex-policy.service.js +0 -1
  85. package/dist/inference/inference-agent-invoker.js +67 -0
  86. package/dist/inference/inference-applier.js +178 -0
  87. package/dist/inference/inference-cycle.js +51 -827
  88. package/dist/inference/inference-proposal-generator.js +149 -0
  89. package/dist/infrastructure/iac-validator.js +465 -0
  90. package/dist/infrastructure/schemas/cloud-schemas.js +488 -0
  91. package/dist/integrations/base/ExampleIntegration.js +0 -1
  92. package/dist/integrations/base/Integration.js +0 -1
  93. package/dist/integrations/base/index.js +0 -1
  94. package/dist/integrations/base/registry.js +0 -1
  95. package/dist/integrations/base/types.js +0 -1
  96. package/dist/integrations/enforcement-gate.js +3 -3
  97. package/dist/integrations/governance/governance-client.js +0 -1
  98. package/dist/integrations/governance/index.js +11 -19
  99. package/dist/integrations/governance/types.js +0 -1
  100. package/dist/integrations/hermes-agent/__init__.py +4 -0
  101. package/dist/integrations/hermes-agent/bridge.mjs +37 -0
  102. package/dist/integrations/openclaw/api-server.js +0 -1
  103. package/dist/integrations/openclaw/client.js +0 -1
  104. package/dist/integrations/openclaw/config.js +0 -1
  105. package/dist/integrations/openclaw/hooks/xray-hooks.js +0 -1
  106. package/dist/integrations/openclaw/index.js +0 -1
  107. package/dist/integrations/openclaw/types.js +0 -1
  108. package/dist/integrations/plugins/index.js +0 -1
  109. package/dist/integrations/plugins/plugin-integration.js +0 -1
  110. package/dist/integrations/plugins/plugin-registry.js +0 -1
  111. package/dist/mcps/agent-resolver.js +0 -1
  112. package/dist/mcps/architect-tools.server.js +119 -185
  113. package/dist/mcps/auto-format.server.js +56 -74
  114. package/dist/mcps/boot-orchestrator.server.js +67 -85
  115. package/dist/mcps/config/config-loader.js +6 -0
  116. package/dist/mcps/config/plugin-server-registry.js +0 -1
  117. package/dist/mcps/enforcer-tools.server.js +207 -273
  118. package/dist/mcps/estimation.server.js +63 -107
  119. package/dist/mcps/framework-compliance-audit.server.js +52 -81
  120. package/dist/mcps/framework-help.server.js +71 -89
  121. package/dist/mcps/governance.server.js +97 -149
  122. package/dist/mcps/knowledge-skills/api-design.server.js +33 -65
  123. package/dist/mcps/knowledge-skills/architecture-patterns.server.js +33 -65
  124. package/dist/mcps/knowledge-skills/bug-triage-specialist.server.js +123 -163
  125. package/dist/mcps/knowledge-skills/code-analyzer.server.js +210 -237
  126. package/dist/mcps/knowledge-skills/code-review.server.js +108 -142
  127. package/dist/mcps/knowledge-skills/content-creator.server.js +203 -225
  128. package/dist/mcps/knowledge-skills/database-design.server.js +116 -150
  129. package/dist/mcps/knowledge-skills/devops-deployment.server.js +123 -157
  130. package/dist/mcps/knowledge-skills/git-workflow.server.js +34 -67
  131. package/dist/mcps/knowledge-skills/growth-strategist.server.js +301 -323
  132. package/dist/mcps/knowledge-skills/log-monitor.server.js +139 -159
  133. package/dist/mcps/knowledge-skills/mobile-development.server.js +170 -200
  134. package/dist/mcps/knowledge-skills/multimodal-looker.server.js +122 -158
  135. package/dist/mcps/knowledge-skills/performance-optimization.server.js +88 -138
  136. package/dist/mcps/knowledge-skills/project-analysis.server.js +131 -218
  137. package/dist/mcps/knowledge-skills/refactoring-strategies.server.js +115 -150
  138. package/dist/mcps/knowledge-skills/security-audit.server.js +16 -143
  139. package/dist/mcps/knowledge-skills/seo-consultant.server.js +20 -213
  140. package/dist/mcps/knowledge-skills/session-management.server.js +13 -90
  141. package/dist/mcps/knowledge-skills/skill-invocation.server.js +43 -421
  142. package/dist/mcps/knowledge-skills/strategist.server.js +10 -55
  143. package/dist/mcps/knowledge-skills/tech-writer.server.js +16 -191
  144. package/dist/mcps/knowledge-skills/testing-best-practices.server.js +18 -191
  145. package/dist/mcps/knowledge-skills/testing-strategy.server.js +18 -156
  146. package/dist/mcps/knowledge-skills/ui-ux-design.server.js +22 -296
  147. package/dist/mcps/lint.server.js +50 -91
  148. package/dist/mcps/model-health-check.server.js +32 -60
  149. package/dist/mcps/orchestrator/aside-context.js +207 -0
  150. package/dist/mcps/orchestrator/config/agent-capabilities.js +30 -11
  151. package/dist/mcps/orchestrator/config/memory-routing-bridge.js +70 -0
  152. package/dist/mcps/orchestrator/execution/execution-planner.js +25 -7
  153. package/dist/mcps/orchestrator/handlers/complexity-handler.js +5 -1
  154. package/dist/mcps/orchestrator/handlers/status-handler.js +8 -1
  155. package/dist/mcps/orchestrator/handlers/task-handler.js +59 -1
  156. package/dist/mcps/orchestrator/index.js +5 -0
  157. package/dist/mcps/orchestrator/server.js +63 -8
  158. package/dist/mcps/performance-analysis.server.js +56 -87
  159. package/dist/mcps/processor-pipeline.server.js +68 -99
  160. package/dist/mcps/researcher.server.js +80 -153
  161. package/dist/mcps/security-scan.server.js +56 -70
  162. package/dist/mcps/shared/knowledge-skill-base.js +11 -4
  163. package/dist/mcps/state-manager.server.js +124 -152
  164. package/dist/memory-routing/index.js +4 -0
  165. package/dist/memory-routing/null-provider.js +51 -0
  166. package/dist/memory-routing/provider-loader.js +91 -0
  167. package/dist/memory-routing/provider-registry.js +40 -0
  168. package/dist/memory-routing/types.js +7 -0
  169. package/dist/memory-routing/validate-config.js +32 -0
  170. package/dist/monitoring/nudge-watchdog.js +0 -1
  171. package/dist/nucleus/default-plugins.js +13 -19
  172. package/dist/nucleus/index.js +0 -1
  173. package/dist/nucleus/thin-dispatch.js +29 -1
  174. package/dist/orchestrator/agent-spawn-governor.js +0 -1
  175. package/dist/orchestrator/intelligent-commit-batcher.js +2 -10
  176. package/dist/orchestrator/multi-agent-orchestration-coordinator.js +0 -1
  177. package/dist/orchestrator/orchestrator.js +8 -18
  178. package/dist/orchestrator/self-direction-activation.js +0 -1
  179. package/dist/orchestrator/universal-registry-bridge.js +0 -1
  180. package/dist/performance/performance-budget-enforcer.js +0 -1
  181. package/dist/performance/performance-regression-tester.js +0 -1
  182. package/dist/plugin/plugin-codex-context.js +87 -0
  183. package/dist/plugin/plugin-helpers.js +155 -0
  184. package/dist/plugin/plugin-logger.js +46 -0
  185. package/dist/plugin/plugin-modules.js +144 -0
  186. package/dist/plugin/plugin-quality-gate.js +88 -0
  187. package/dist/plugin/plugin-types.js +1 -0
  188. package/dist/plugin/xray-codex-injection.js +338 -0
  189. package/dist/postprocessor/PostProcessor.js +3 -9
  190. package/dist/postprocessor/analysis/CodeChangeAnalyzer.js +50 -0
  191. package/dist/postprocessor/config/ProcessorConfigLoader.js +16 -0
  192. package/dist/postprocessor/integration.js +194 -0
  193. package/dist/postprocessor/metamorphosis/SelfProposalEngine.js +472 -0
  194. package/dist/postprocessor/metamorphosis/index.js +1 -0
  195. package/dist/postprocessor/redeploy/RetryHandler.js +118 -0
  196. package/dist/postprocessor/services/RegressionAnalysisService.js +0 -1
  197. package/dist/postprocessor/triggers/APITrigger.js +0 -1
  198. package/dist/postprocessor/triggers/WebhookTrigger.js +0 -1
  199. package/dist/processors/implementations/agents-md-validation-processor.js +0 -1
  200. package/dist/processors/implementations/async-pattern-processor.js +0 -1
  201. package/dist/processors/implementations/console-log-guard-processor.js +0 -1
  202. package/dist/processors/implementations/coverage-analysis-processor.js +0 -1
  203. package/dist/processors/implementations/inference-improvement-processor.js +2 -9
  204. package/dist/processors/implementations/log-protection-processor.js +0 -1
  205. package/dist/processors/implementations/nudge-processor.js +0 -1
  206. package/dist/processors/implementations/performance-budget-processor.js +0 -1
  207. package/dist/processors/implementations/postprocessor-chain-validator.js +0 -1
  208. package/dist/processors/implementations/publish-preflight-processor.js +4 -12
  209. package/dist/processors/implementations/session-summary-processor.js +8 -16
  210. package/dist/processors/implementations/spawn-governance-processor.js +0 -1
  211. package/dist/processors/implementations/storytelling-trigger-processor.js +3 -28
  212. package/dist/processors/implementations/test-auto-creation-processor.js +0 -1
  213. package/dist/processors/implementations/typescript-compilation-processor.js +0 -1
  214. package/dist/processors/implementations/version-compliance-processor.js +0 -1
  215. package/dist/processors/processor-interfaces.js +0 -1
  216. package/dist/processors/processor-types.js +0 -1
  217. package/dist/scripts/integration.js +0 -1
  218. package/dist/security/comprehensive-security-audit.js +0 -1
  219. package/dist/security/security-agent-coordinator.js +0 -1
  220. package/dist/security/security-auditor.js +0 -1
  221. package/dist/security/security-hardener.js +0 -1
  222. package/dist/security/security-hardening-system.js +0 -1
  223. package/dist/security/security-headers.js +0 -1
  224. package/dist/security/security-orchestration-layer.js +0 -1
  225. package/dist/services/inference-tuner.js +0 -1
  226. package/dist/session/session-cleanup-manager.js +0 -1
  227. package/dist/session/session-monitor.js +0 -1
  228. package/dist/session/session-state-manager.js +0 -1
  229. package/dist/skills/xray-orchestrator/index.js +0 -1
  230. package/dist/utils/codex-parser.js +0 -1
  231. package/dist/utils/language-detector.js +0 -1
  232. package/dist/utils/shutdown-handler.js +0 -1
  233. package/dist/validation/agent-config-validator.js +280 -0
  234. package/dist/validation/orchestration-flow-validator.js +606 -0
  235. package/package.json +1 -1
  236. package/scripts/node/release.mjs +2 -2
  237. package/scripts/node/setup.cjs +28 -0
  238. package/scripts/node/universal-version-manager.js +1 -1
  239. package/src/mcps/agent-resolver.ts +0 -1
  240. package/src/mcps/architect-tools.server.ts +129 -211
  241. package/src/mcps/auto-format.server.ts +74 -103
  242. package/src/mcps/boot-orchestrator.server.ts +71 -96
  243. package/src/mcps/config/__tests__/config-loader.test.ts +6 -6
  244. package/src/mcps/config/config-loader.ts +7 -0
  245. package/src/mcps/config/plugin-server-registry.ts +0 -1
  246. package/src/mcps/enforcer-tools.server.ts +217 -294
  247. package/src/mcps/estimation.server.ts +62 -122
  248. package/src/mcps/framework-compliance-audit.server.ts +53 -95
  249. package/src/mcps/framework-help.server.ts +74 -96
  250. package/src/mcps/governance.server.ts +97 -162
  251. package/src/mcps/knowledge-skills/api-design.server.ts +33 -72
  252. package/src/mcps/knowledge-skills/architecture-patterns.server.ts +33 -72
  253. package/src/mcps/knowledge-skills/bug-triage-specialist.server.ts +148 -193
  254. package/src/mcps/knowledge-skills/code-analyzer.server.ts +222 -254
  255. package/src/mcps/knowledge-skills/code-review.server.ts +115 -157
  256. package/src/mcps/knowledge-skills/content-creator.server.ts +219 -246
  257. package/src/mcps/knowledge-skills/database-design.server.ts +119 -160
  258. package/src/mcps/knowledge-skills/devops-deployment.server.ts +126 -167
  259. package/src/mcps/knowledge-skills/git-workflow.server.ts +32 -77
  260. package/src/mcps/knowledge-skills/growth-strategist.server.ts +322 -360
  261. package/src/mcps/knowledge-skills/log-monitor.server.ts +68 -95
  262. package/src/mcps/knowledge-skills/mobile-development.server.ts +16 -56
  263. package/src/mcps/knowledge-skills/multimodal-looker.server.ts +13 -59
  264. package/src/mcps/knowledge-skills/performance-optimization.server.ts +13 -74
  265. package/src/mcps/knowledge-skills/project-analysis.server.ts +13 -120
  266. package/src/mcps/knowledge-skills/refactoring-strategies.server.ts +13 -60
  267. package/src/mcps/knowledge-skills/security-audit.server.ts +19 -157
  268. package/src/mcps/knowledge-skills/seo-consultant.server.ts +23 -227
  269. package/src/mcps/knowledge-skills/session-management.server.ts +17 -106
  270. package/src/mcps/knowledge-skills/skill-invocation.server.ts +45 -446
  271. package/src/mcps/knowledge-skills/strategist.server.ts +13 -63
  272. package/src/mcps/knowledge-skills/tech-writer.server.ts +19 -204
  273. package/src/mcps/knowledge-skills/testing-best-practices.server.ts +21 -204
  274. package/src/mcps/knowledge-skills/testing-strategy.server.ts +21 -165
  275. package/src/mcps/knowledge-skills/ui-ux-design.server.ts +25 -342
  276. package/src/mcps/lint.server.ts +52 -105
  277. package/src/mcps/model-health-check.server.ts +34 -70
  278. package/src/mcps/orchestrator/aside-context.ts +245 -0
  279. package/src/mcps/orchestrator/config/agent-capabilities.ts +49 -14
  280. package/src/mcps/orchestrator/config/memory-routing-bridge.ts +80 -0
  281. package/src/mcps/orchestrator/execution/execution-planner.ts +36 -9
  282. package/src/mcps/orchestrator/handlers/complexity-handler.ts +9 -3
  283. package/src/mcps/orchestrator/handlers/status-handler.ts +11 -1
  284. package/src/mcps/orchestrator/handlers/task-handler.ts +78 -2
  285. package/src/mcps/orchestrator/index.ts +29 -0
  286. package/src/mcps/orchestrator/server.ts +79 -24
  287. package/src/mcps/orchestrator/types.ts +50 -0
  288. package/src/mcps/performance-analysis.server.ts +59 -102
  289. package/src/mcps/processor-pipeline.server.ts +70 -108
  290. package/src/mcps/researcher.server.ts +87 -175
  291. package/src/mcps/security-scan.server.ts +57 -76
  292. package/src/mcps/shared/knowledge-skill-base.ts +12 -4
  293. package/src/mcps/state-manager.server.ts +129 -169
  294. package/src/opencode/codex.codex +1 -1
  295. package/src/opencode/commands/auto-format.md +3 -3
  296. package/src/opencode/commands/auto-summary-capture.md +2 -2
  297. package/src/opencode/commands/enforcer-daily-scan.md +3 -3
  298. package/src/opencode/commands/framework-compliance-audit.md +4 -4
  299. package/src/opencode/commands/interactive-validator.md +2 -2
  300. package/src/opencode/commands/job-summary-logger.md +2 -2
  301. package/src/opencode/commands/mode-switch.md +1 -1
  302. package/src/opencode/commands/model-health-check.md +2 -2
  303. package/src/opencode/commands/performance-analysis.md +2 -2
  304. package/src/opencode/commands/pre-commit-introspection.md +3 -3
  305. package/src/opencode/commands/security-scan.md +3 -3
  306. package/src/opencode/commands/sisyphus-validation.md +3 -3
  307. package/src/opencode/commands/summary-logger.md +2 -2
  308. package/src/skills/xray-orchestrator/index.ts +0 -1
  309. package/dist/nucleus/orchestrator.js +0 -479
@@ -0,0 +1,194 @@
1
+ /**
2
+ * 0xRay Integration Layer
3
+ *
4
+ * Provides generic connectors for integrating 0xRay's PostProcessor
5
+ * with external applications and frameworks.
6
+ *
7
+ * This is framework-agnostic - works with Express, Fastify, Koa, etc.
8
+ *
9
+ * @since 2026-03-08
10
+ */
11
+ export { WebhookTrigger } from './triggers/WebhookTrigger.js';
12
+ export { APITrigger } from './triggers/APITrigger.js';
13
+ /**
14
+ * Generic 0xRay integration for any external application
15
+ *
16
+ * Provides:
17
+ * - Webhook receivers (GitHub, GitLab, Bitbucket, Stripe)
18
+ * - REST API triggers (manual trigger, retry, status)
19
+ * - Framework-agnostic (works with Express, Fastify, Koa, etc.)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { createXrayIntegration } from '0xray/integration';
24
+ *
25
+ * const postProcessor = new PostProcessor(stateManager);
26
+ * const integration = createXrayIntegration(postProcessor);
27
+ *
28
+ * // Get Express app for mounting
29
+ * app.use('/webhooks', integration.getWebhookApp());
30
+ * app.use('/api/post-process', integration.getAPIApp());
31
+ *
32
+ * // Or get raw routers for Fastify/Koa
33
+ * const webhookRouter = integration.getWebhookRouter();
34
+ * const apiRouter = integration.getAPIRouter();
35
+ * ```
36
+ */
37
+ export class XrayIntegration {
38
+ postProcessor;
39
+ webhookTrigger = null;
40
+ apiTrigger = null;
41
+ constructor(postProcessor) {
42
+ this.postProcessor = postProcessor;
43
+ }
44
+ /**
45
+ * Initialize all triggers with default configuration
46
+ *
47
+ * @param config - Optional configuration for triggers
48
+ */
49
+ async initialize(config) {
50
+ const { WebhookTrigger } = await import('./triggers/WebhookTrigger.js');
51
+ const { APITrigger } = await import('./triggers/APITrigger.js');
52
+ // Initialize webhook trigger with default GitHub config
53
+ this.webhookTrigger = new WebhookTrigger(this.postProcessor, {
54
+ provider: 'github',
55
+ events: ['push', 'pull_request'],
56
+ path: '/webhooks/github',
57
+ verifySignature: true,
58
+ ...config?.webhook
59
+ });
60
+ await this.webhookTrigger.initialize();
61
+ // Initialize API trigger with default config
62
+ this.apiTrigger = new APITrigger(this.postProcessor, {
63
+ enabled: true,
64
+ path: '/api/post-process',
65
+ ...config?.api
66
+ });
67
+ await this.apiTrigger.initialize();
68
+ }
69
+ /**
70
+ * Get webhook app for framework-specific mounting
71
+ *
72
+ * Returns an Express Application. For other frameworks,
73
+ * use getWebhookRouter() to get the router instance.
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * // Express
78
+ * app.use('/webhooks', integration.getWebhookApp());
79
+ *
80
+ * // Fastify
81
+ * await fastify.register(integration.getWebhookRouter(), { prefix: '/webhooks' });
82
+ *
83
+ * // Koa
84
+ * app.use(integration.getWebhookRouter().routes());
85
+ * ```
86
+ */
87
+ getWebhookApp() {
88
+ return this.webhookTrigger?.getApp() ?? null;
89
+ }
90
+ /**
91
+ * Get webhook router (raw Express router)
92
+ *
93
+ * Useful for frameworks that need the router instance directly
94
+ * rather than the full Express app.
95
+ */
96
+ getWebhookRouter() {
97
+ return this.webhookTrigger?.getApp() ?? null;
98
+ }
99
+ /**
100
+ * Get API trigger app for framework-specific mounting
101
+ *
102
+ * @example
103
+ * ```typescript
104
+ * // Express
105
+ * app.use('/api/post-process', integration.getAPIApp());
106
+ *
107
+ * // Fastify
108
+ * await fastify.register(integration.getAPIRouter(), { prefix: '/api/post-process' });
109
+ * ```
110
+ */
111
+ getAPIApp() {
112
+ return this.apiTrigger?.getApp() ?? null;
113
+ }
114
+ /**
115
+ * Get API trigger router (raw Express router)
116
+ *
117
+ * Useful for frameworks that need the router instance directly.
118
+ */
119
+ getAPIRouter() {
120
+ return this.apiTrigger?.getApp() ?? null;
121
+ }
122
+ /**
123
+ * Manually trigger PostProcessor via API
124
+ *
125
+ * Convenience method for programmatic triggering without
126
+ * going through the HTTP endpoint.
127
+ *
128
+ * @example
129
+ * ```typescript
130
+ * await integration.trigger({
131
+ * tool: 'test',
132
+ * operation: 'run',
133
+ * reason: 'Manual test trigger'
134
+ * });
135
+ * ```
136
+ */
137
+ async trigger(options) {
138
+ const context = {
139
+ commitSha: `manual-${Date.now()}`,
140
+ repository: '',
141
+ branch: '',
142
+ author: 'manual',
143
+ files: [],
144
+ trigger: 'manual',
145
+ tool: options.tool,
146
+ operation: options.operation,
147
+ ...(options.filePath !== undefined ? { filePath: options.filePath } : {}),
148
+ ...(options.directory !== undefined ? { directory: options.directory } : {}),
149
+ };
150
+ await this.postProcessor.executePostProcessorLoop(context);
151
+ }
152
+ /**
153
+ * Shutdown all triggers
154
+ */
155
+ async shutdown() {
156
+ if (this.webhookTrigger) {
157
+ this.webhookTrigger.shutdown();
158
+ }
159
+ if (this.apiTrigger) {
160
+ this.apiTrigger.shutdown();
161
+ }
162
+ }
163
+ }
164
+ /**
165
+ * Factory function for easy integration setup
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * import { createXrayIntegration } from '0xray/integration';
170
+ *
171
+ * // With default configuration
172
+ * const integration = createXrayIntegration(postProcessor);
173
+ * await integration.initialize();
174
+ *
175
+ * // With custom configuration
176
+ * const integration = createXrayIntegration(postProcessor);
177
+ * await integration.initialize({
178
+ * webhook: {
179
+ * provider: 'gitlab',
180
+ * secret: process.env.GITLAB_WEBHOOK_SECRET,
181
+ * events: ['push', 'merge_request'],
182
+ * path: '/webhooks/gitlab'
183
+ * },
184
+ * api: {
185
+ * path: '/api/stray-trigger',
186
+ * apiKey: process.env.API_KEY
187
+ * }
188
+ * });
189
+ * ```
190
+ */
191
+ export function createXrayIntegration(postProcessor) {
192
+ return new XrayIntegration(postProcessor);
193
+ }
194
+ // Backward compat aliases
@@ -0,0 +1,472 @@
1
+ /**
2
+ * SelfProposalEngine — Phase 2.2
3
+ *
4
+ * Concrete MetamorphosisEngine that reads activity.log, parses structured
5
+ * log entries, detects semantic patterns, generates governance proposals
6
+ * (type: 'metamorphosis'), and submits them through the full 3-agent +
7
+ * Dynamo governance pipeline.
8
+ *
9
+ * Safety constraints:
10
+ * - Max proposals per hour (default 1, configurable)
11
+ * - Circuit breaker: after N consecutive failures, halt for cooldown (default 3/24h)
12
+ * - Only proposes changes to whitelisted targets
13
+ * - All proposals go through full governance with metamorphosisThreshold (default 0.7)
14
+ * - Detection thresholds are configurable (not hard-coded)
15
+ *
16
+ * Coupling note: currently triggered by PostProcessor.onPhase(). A future
17
+ * refactor should extract log-reading into a dedicated LogReader that can
18
+ * run on its own schedule or fs.watch, decoupling from PostProcessor lifecycle.
19
+ */
20
+ import { promises as fs, existsSync } from 'fs';
21
+ import { join } from 'path';
22
+ import { frameworkLogger } from '../../core/framework-logger.js';
23
+ import { handleGovernRequest } from '../../nucleus/govern-http.js';
24
+ const DEFAULT_CONFIG = {
25
+ maxProposalsPerHour: 1,
26
+ circuitBreakerThreshold: 3,
27
+ circuitBreakerCooldownHours: 24,
28
+ activityLogPath: 'logs/framework/activity.log',
29
+ whitelistedTargets: ['config/', 'features.json', 'src/processors/'],
30
+ maxLogLines: 100,
31
+ errorThreshold: 5,
32
+ warningThreshold: 10,
33
+ governanceRejectionThreshold: 3,
34
+ proposalConfidence: 0.7,
35
+ metamorphosisThreshold: 0.7,
36
+ projectRoot: process.cwd(),
37
+ };
38
+ const LOG_LINE_PATTERN = /^(\d{4}-\d{2}-\d{2}T[^ ]+)\s+(?:\[([^\]]*)\]\s+)?(?:\[([^\]]*)\]\s+)?\[([^\]]*)\]\s+(\S+)\s+-\s+(\w+)(?:\s+\|(.+))?$/;
39
+ function parseLogEntry(line) {
40
+ const match = line.match(LOG_LINE_PATTERN);
41
+ if (!match) {
42
+ // Fallback: try JSON parse for entangled log entries
43
+ try {
44
+ const json = JSON.parse(line);
45
+ if (json && typeof json === 'object' && json.action) {
46
+ return {
47
+ timestamp: json.timestamp ? new Date(json.timestamp).toISOString() : new Date().toISOString(),
48
+ component: json.component || 'unknown',
49
+ action: json.action,
50
+ status: (json.status || json.level || 'info').toLowerCase(),
51
+ details: json.details || json,
52
+ raw: line,
53
+ };
54
+ }
55
+ }
56
+ catch { }
57
+ return null;
58
+ }
59
+ const [, timestamp, , , component, action, status, detailsStr] = match;
60
+ let details;
61
+ if (detailsStr) {
62
+ try {
63
+ details = JSON.parse(detailsStr.trim());
64
+ }
65
+ catch {
66
+ details = { rawDetails: detailsStr.trim() };
67
+ }
68
+ }
69
+ const entry = {
70
+ timestamp: timestamp ?? new Date().toISOString(),
71
+ component: component || 'unknown',
72
+ action: action ?? 'unknown',
73
+ status: (status ?? 'info').toLowerCase(),
74
+ raw: line,
75
+ };
76
+ if (details !== undefined) {
77
+ entry.details = details;
78
+ }
79
+ return entry;
80
+ }
81
+ export class SelfProposalEngine {
82
+ name = 'self-proposal';
83
+ config;
84
+ proposalHistory = [];
85
+ consecutiveFailures = 0;
86
+ circuitBreakerUntil = 0;
87
+ constructor(config) {
88
+ this.config = { ...DEFAULT_CONFIG, ...config };
89
+ }
90
+ async onPhase(phase, context) {
91
+ if (phase !== 'monitoring-complete' && phase !== 'post-process-complete') {
92
+ return;
93
+ }
94
+ await frameworkLogger.log('self-proposal', 'phase-hook', 'info', {
95
+ phase,
96
+ message: 'Self-proposal engine triggered by phase',
97
+ });
98
+ if (this.isCircuitBreakerActive()) {
99
+ await frameworkLogger.log('self-proposal', 'circuit-breaker-active', 'warning', {
100
+ message: `Circuit breaker active until ${new Date(this.circuitBreakerUntil).toISOString()}`,
101
+ consecutiveFailures: this.consecutiveFailures,
102
+ });
103
+ return;
104
+ }
105
+ if (this.isRateLimited()) {
106
+ await frameworkLogger.log('self-proposal', 'rate-limited', 'info', {
107
+ message: 'Max proposals per hour reached',
108
+ });
109
+ return;
110
+ }
111
+ await this.evaluateAndPropose();
112
+ }
113
+ async onProposal(proposal) {
114
+ await frameworkLogger.log('self-proposal', 'external-proposal', 'info', {
115
+ proposalId: proposal.id,
116
+ type: proposal.type,
117
+ target: proposal.target,
118
+ impact: proposal.impact,
119
+ });
120
+ }
121
+ isCircuitBreakerActive() {
122
+ if (this.consecutiveFailures >= this.config.circuitBreakerThreshold) {
123
+ if (Date.now() < this.circuitBreakerUntil) {
124
+ return true;
125
+ }
126
+ this.consecutiveFailures = 0;
127
+ this.circuitBreakerUntil = 0;
128
+ }
129
+ return false;
130
+ }
131
+ isRateLimited() {
132
+ const oneHourAgo = Date.now() - 60 * 60 * 1000;
133
+ const recentProposals = this.proposalHistory.filter(a => a.timestamp > oneHourAgo);
134
+ return recentProposals.length >= this.config.maxProposalsPerHour;
135
+ }
136
+ getMetrics() {
137
+ const oneHourAgo = Date.now() - 60 * 60 * 1000;
138
+ const recentProposals = this.proposalHistory.filter(a => a.timestamp > oneHourAgo);
139
+ return {
140
+ totalProposals: this.proposalHistory.length,
141
+ recentProposals: recentProposals.length,
142
+ consecutiveFailures: this.consecutiveFailures,
143
+ circuitBreakerActive: this.isCircuitBreakerActive(),
144
+ circuitBreakerUntil: this.circuitBreakerUntil,
145
+ successRate: this.proposalHistory.length > 0
146
+ ? this.proposalHistory.filter(a => a.result === 'approved').length / this.proposalHistory.length
147
+ : 0,
148
+ };
149
+ }
150
+ async evaluateAndPropose() {
151
+ let logEntries = [];
152
+ try {
153
+ const logContent = await fs.readFile(this.config.activityLogPath, 'utf-8');
154
+ const lines = logContent.trim().split('\n');
155
+ logEntries = lines.slice(-this.config.maxLogLines).filter(line => line.trim().length > 0);
156
+ }
157
+ catch {
158
+ await frameworkLogger.log('self-proposal', 'log-read-error', 'warning', {
159
+ path: this.config.activityLogPath,
160
+ message: 'Activity log not found or unreadable — skipping self-proposal',
161
+ });
162
+ return;
163
+ }
164
+ const patterns = this.detectPatterns(logEntries);
165
+ if (patterns.length === 0) {
166
+ await frameworkLogger.log('self-proposal', 'no-patterns', 'info', {
167
+ message: 'No actionable patterns detected in activity log',
168
+ });
169
+ return;
170
+ }
171
+ for (const pattern of patterns) {
172
+ await this.submitProposal(pattern);
173
+ }
174
+ }
175
+ /**
176
+ * Detect actionable patterns from parsed activity log entries.
177
+ * Uses structured parsing instead of raw string matching to handle
178
+ * the actual xray log format:
179
+ * ISO_TIMESTAMP [jobId] [traceId.spanId] [component] action - STATUS | {details}
180
+ */
181
+ detectPatterns(entries) {
182
+ const parsed = entries.map(parseLogEntry).filter((e) => e !== null);
183
+ const proposals = [];
184
+ const errorEntries = parsed.filter(e => e.status === 'error');
185
+ const warningEntries = parsed.filter(e => e.status === 'warning');
186
+ const rejectedEntries = parsed.filter(e => e.component === 'governance' && (e.status === 'rejected' || e.details?.decision === 'reject'));
187
+ if (errorEntries.length >= this.config.errorThreshold) {
188
+ const components = [...new Set(errorEntries.map(e => e.component))];
189
+ proposals.push({
190
+ id: `meta-errors-${Date.now()}`,
191
+ type: 'modify',
192
+ target: 'config/error-handling',
193
+ description: `Elevated error rate: ${errorEntries.length} errors in last ${this.config.maxLogLines} entries. Components: ${components.join(', ')}. Propose adjusting error handling thresholds.`,
194
+ rationale: `High error count (${errorEntries.length}) across ${components.length} component(s) indicates a systemic issue. Affected components: ${components.join(', ')}. Governance review recommended for self-optimization.`,
195
+ impact: 'medium',
196
+ });
197
+ }
198
+ if (warningEntries.length >= this.config.warningThreshold) {
199
+ const components = [...new Set(warningEntries.map(e => e.component))];
200
+ proposals.push({
201
+ id: `meta-warnings-${Date.now()}`,
202
+ type: 'modify',
203
+ target: 'config/monitoring',
204
+ description: `Elevated warning rate: ${warningEntries.length} warnings in last ${this.config.maxLogLines} entries. Components: ${components.join(', ')}. Propose adjusting monitoring sensitivity.`,
205
+ rationale: `Frequent warnings (${warningEntries.length}) across ${components.length} component(s) may indicate configuration drift. Affected: ${components.join(', ')}.`,
206
+ impact: 'low',
207
+ });
208
+ }
209
+ if (rejectedEntries.length >= this.config.governanceRejectionThreshold) {
210
+ proposals.push({
211
+ id: `meta-governance-rejections-${Date.now()}`,
212
+ type: 'modify',
213
+ target: 'config/governance',
214
+ description: `Repeated governance rejections: ${rejectedEntries.length} in last ${this.config.maxLogLines} entries. Propose reviewing governance thresholds or submission patterns.`,
215
+ rationale: `${rejectedEntries.length} governance rejections suggest a pattern mismatch between proposals and governance criteria. Review recommended.`,
216
+ impact: 'medium',
217
+ });
218
+ }
219
+ return proposals.filter(p => this.config.whitelistedTargets.some(t => p.target.startsWith(t)));
220
+ }
221
+ /**
222
+ * Apply an approved self-evolution proposal by recording the change
223
+ * in a state file within the first matching whitelisted target directory.
224
+ * Returns true if the change was written and verified, false otherwise.
225
+ */
226
+ async applySelfProposal(pattern, score, decision) {
227
+ const matchedTarget = this.config.whitelistedTargets.find(t => pattern.target.startsWith(t));
228
+ if (!matchedTarget) {
229
+ await frameworkLogger.log('self-proposal', 'apply-no-matching-target', 'warning', {
230
+ proposalId: pattern.id,
231
+ target: pattern.target,
232
+ message: 'No whitelisted target matches this proposal — skipping apply',
233
+ });
234
+ return false;
235
+ }
236
+ const root = this.config.projectRoot;
237
+ const stateDir = join(root, matchedTarget);
238
+ const statePath = join(stateDir, 'self-evolution-state.json');
239
+ let applied = [];
240
+ try {
241
+ const content = await fs.readFile(statePath, 'utf-8');
242
+ const parsed = JSON.parse(content);
243
+ if (Array.isArray(parsed.applied))
244
+ applied = parsed.applied;
245
+ }
246
+ catch { }
247
+ applied.push({
248
+ proposalId: pattern.id,
249
+ target: pattern.target,
250
+ type: pattern.type,
251
+ description: pattern.description,
252
+ rationale: pattern.rationale,
253
+ impact: pattern.impact,
254
+ metamorphosisScore: score,
255
+ decision: decision,
256
+ appliedAt: new Date().toISOString(),
257
+ });
258
+ try {
259
+ await fs.mkdir(stateDir, { recursive: true });
260
+ // Backup existing state file before overwriting
261
+ const backupDir = join(root, '.xray', 'metamorphosis', 'backups');
262
+ let backupPath = null;
263
+ if (existsSync(statePath)) {
264
+ await fs.mkdir(backupDir, { recursive: true });
265
+ backupPath = join(backupDir, `self-evolution-state-${Date.now()}.json`);
266
+ await fs.copyFile(statePath, backupPath);
267
+ await frameworkLogger.log('self-proposal', 'backup-created', 'info', {
268
+ proposalId: pattern.id,
269
+ backupPath,
270
+ });
271
+ }
272
+ try {
273
+ await fs.writeFile(statePath, JSON.stringify({ applied }, null, 2), 'utf-8');
274
+ }
275
+ catch (writeError) {
276
+ // Restore from backup on write failure
277
+ if (backupPath && existsSync(backupPath)) {
278
+ await fs.copyFile(backupPath, statePath);
279
+ await frameworkLogger.log('self-proposal', 'restored-from-backup', 'warning', {
280
+ proposalId: pattern.id,
281
+ backupPath,
282
+ error: writeError instanceof Error ? writeError.message : String(writeError),
283
+ });
284
+ }
285
+ await frameworkLogger.log('self-proposal', 'apply-write-error', 'error', {
286
+ proposalId: pattern.id,
287
+ path: statePath,
288
+ error: writeError instanceof Error ? writeError.message : String(writeError),
289
+ });
290
+ return false;
291
+ }
292
+ }
293
+ catch (writeError) {
294
+ await frameworkLogger.log('self-proposal', 'apply-mkdir-error', 'error', {
295
+ proposalId: pattern.id,
296
+ error: writeError instanceof Error ? writeError.message : String(writeError),
297
+ });
298
+ return false;
299
+ }
300
+ try {
301
+ const verify = await fs.readFile(statePath, 'utf-8');
302
+ const parsed = JSON.parse(verify);
303
+ const found = Array.isArray(parsed.applied) && parsed.applied.some((a) => a.proposalId === pattern.id);
304
+ if (!found) {
305
+ await frameworkLogger.log('self-proposal', 'apply-verify-failed', 'error', {
306
+ proposalId: pattern.id,
307
+ message: 'Applied change not found in state file after write — verification failed',
308
+ });
309
+ }
310
+ return found;
311
+ }
312
+ catch (verifyError) {
313
+ await frameworkLogger.log('self-proposal', 'apply-verify-error', 'error', {
314
+ proposalId: pattern.id,
315
+ error: verifyError instanceof Error ? verifyError.message : String(verifyError),
316
+ });
317
+ return false;
318
+ }
319
+ }
320
+ async submitProposal(pattern) {
321
+ const governanceRequest = {
322
+ proposals: [{
323
+ id: pattern.id,
324
+ type: 'metamorphosis',
325
+ title: `Self-proposal: ${pattern.description.slice(0, 80)}`,
326
+ description: pattern.description,
327
+ evidence: [pattern.rationale],
328
+ source: 'metamorphosis',
329
+ confidence: this.config.proposalConfidence,
330
+ tags: ['0xray'],
331
+ }],
332
+ context: {
333
+ project: 'xray-self',
334
+ phase: 'self-evolution',
335
+ source: 'self-proposal-engine',
336
+ tags: ['0xray'],
337
+ },
338
+ options: {
339
+ requireExternalDynamo: true,
340
+ metamorphosisThreshold: this.config.metamorphosisThreshold,
341
+ },
342
+ };
343
+ await frameworkLogger.log('self-proposal', 'submitting', 'info', {
344
+ proposalId: pattern.id,
345
+ target: pattern.target,
346
+ impact: pattern.impact,
347
+ });
348
+ try {
349
+ const response = await handleGovernRequest(governanceRequest);
350
+ const result = response.results[0];
351
+ if (!result) {
352
+ await frameworkLogger.log('self-proposal', 'no-result', 'warning', {
353
+ proposalId: pattern.id,
354
+ message: 'Governance returned no results',
355
+ });
356
+ return;
357
+ }
358
+ const decision = result.finalDecision;
359
+ const attempt = {
360
+ timestamp: Date.now(),
361
+ result: decision === 'approve' ? 'approved' : decision === 'reject' ? 'rejected' : 'needs_revision',
362
+ };
363
+ if (result.metamorphosisScore !== undefined) {
364
+ attempt.metamorphosisScore = result.metamorphosisScore;
365
+ }
366
+ this.proposalHistory.push(attempt);
367
+ if (decision === 'approve' && (result.metamorphosisScore ?? 0) >= this.config.metamorphosisThreshold) {
368
+ this.consecutiveFailures = 0;
369
+ await frameworkLogger.log('self-proposal', 'approved', 'success', {
370
+ proposalId: pattern.id,
371
+ metamorphosisScore: result.metamorphosisScore,
372
+ finalDecision: decision,
373
+ averageConfidence: result.averageConfidence,
374
+ voteSummary: result.votes ? result.votes.map((v) => ({ server: v.server, decision: v.decision })) : undefined,
375
+ message: 'Self-evolution proposal approved by governance — applying change',
376
+ tags: ['0xray'],
377
+ });
378
+ const applied = await this.applySelfProposal(pattern, result.metamorphosisScore, decision);
379
+ if (applied) {
380
+ await frameworkLogger.log('self-proposal', 'applied', 'success', {
381
+ proposalId: pattern.id,
382
+ target: pattern.target,
383
+ metamorphosisScore: result.metamorphosisScore,
384
+ decision,
385
+ message: 'Self-evolution change applied and verified',
386
+ tags: ['0xray'],
387
+ });
388
+ await this.audit0xrayProposalTraceability(pattern.id, decision, result.metamorphosisScore);
389
+ }
390
+ else {
391
+ this.consecutiveFailures++;
392
+ if (this.consecutiveFailures >= this.config.circuitBreakerThreshold) {
393
+ this.circuitBreakerUntil = Date.now() + this.config.circuitBreakerCooldownHours * 60 * 60 * 1000;
394
+ }
395
+ await frameworkLogger.log('self-proposal', 'apply-failed', 'error', {
396
+ proposalId: pattern.id,
397
+ target: pattern.target,
398
+ consecutiveFailures: this.consecutiveFailures,
399
+ message: 'Self-evolution change apply failed — circuit breaker may activate',
400
+ });
401
+ }
402
+ }
403
+ else {
404
+ this.consecutiveFailures++;
405
+ if (this.consecutiveFailures >= this.config.circuitBreakerThreshold) {
406
+ this.circuitBreakerUntil = Date.now() + this.config.circuitBreakerCooldownHours * 60 * 60 * 1000;
407
+ }
408
+ await frameworkLogger.log('self-proposal', 'not-approved', 'warning', {
409
+ proposalId: pattern.id,
410
+ decision: decision,
411
+ metamorphosisScore: result.metamorphosisScore,
412
+ consecutiveFailures: this.consecutiveFailures,
413
+ circuitBreakerUntil: this.circuitBreakerUntil || 'not active',
414
+ });
415
+ }
416
+ }
417
+ catch (error) {
418
+ this.consecutiveFailures++;
419
+ await frameworkLogger.log('self-proposal', 'submission-error', 'error', {
420
+ proposalId: pattern.id,
421
+ error: error instanceof Error ? error.message : String(error),
422
+ });
423
+ }
424
+ }
425
+ /**
426
+ * Post-apply audit for Term 72 (Self-Evolution Traceability).
427
+ * For 0xray-tagged proposals (framework self-evolution), asserts that
428
+ * frameworkLogger entries exist with full provenance:
429
+ * - source proposal ID
430
+ * - governance vote results / finalDecision / averageConfidence
431
+ * - metamorphosisScore
432
+ * Logs the audit outcome via frameworkLogger.
433
+ */
434
+ async audit0xrayProposalTraceability(proposalId, decision, score) {
435
+ if (!proposalId) {
436
+ return;
437
+ }
438
+ try {
439
+ const logContent = await fs.readFile(this.config.activityLogPath, 'utf-8');
440
+ const lines = logContent.trim().split('\n').filter(l => l.trim().length > 0);
441
+ const recentLines = lines.slice(-this.config.maxLogLines);
442
+ // Look for entries tied to this proposalId that carry the required provenance.
443
+ // We expect 'approved' (with vote info) and 'applied' (with score/decision) for 0xray self-proposals.
444
+ const relevant = recentLines.filter(line => line.includes(proposalId) &&
445
+ (line.includes('approved') || line.includes('applied') || line.includes('submitting')));
446
+ const hasProposalId = relevant.length > 0;
447
+ const hasGovernanceVote = relevant.some(l => l.includes('finalDecision') || l.includes('averageConfidence') || l.includes('voteSummary'));
448
+ const hasMetamorphosisScore = relevant.some(l => l.includes('metamorphosisScore'));
449
+ const has0xrayTag = relevant.some(l => l.includes('0xray') || l.includes('"tags"') && l.includes('0xray'));
450
+ const auditPassed = hasProposalId && hasGovernanceVote && hasMetamorphosisScore && has0xrayTag;
451
+ await frameworkLogger.log('self-proposal', 'post-apply-audit', auditPassed ? 'success' : 'warning', {
452
+ proposalId,
453
+ decision,
454
+ metamorphosisScore: score,
455
+ hasProposalId,
456
+ hasGovernanceVote,
457
+ hasMetamorphosisScore,
458
+ has0xrayTag,
459
+ relevantEntryCount: relevant.length,
460
+ message: auditPassed
461
+ ? 'Term 72 traceability audit passed: frameworkLogger entries with full provenance (proposalId, governance votes, metamorphosisScore, 0xray tag) verified for self-evolution proposal.'
462
+ : 'Term 72 traceability audit warning: missing or incomplete frameworkLogger provenance for 0xray-tagged self-evolution proposal.',
463
+ });
464
+ }
465
+ catch (auditError) {
466
+ await frameworkLogger.log('self-proposal', 'post-apply-audit-error', 'error', {
467
+ proposalId,
468
+ error: auditError instanceof Error ? auditError.message : String(auditError),
469
+ });
470
+ }
471
+ }
472
+ }
@@ -0,0 +1 @@
1
+ export { SelfProposalEngine } from './SelfProposalEngine.js';