rosett-ai 1.3.3

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 (527) hide show
  1. checksums.yaml +7 -0
  2. data/.ai-provenance.yml +119 -0
  3. data/.debride_whitelist +186 -0
  4. data/.fasterer.yml +29 -0
  5. data/.mdl_style.rb +10 -0
  6. data/.mdlrc +3 -0
  7. data/.mutant.yml +49 -0
  8. data/.namespace-allowlist +42 -0
  9. data/.reek.yml +1040 -0
  10. data/.rosett-ai/config.yml +3 -0
  11. data/.rspec +5 -0
  12. data/.rubocop.yml +380 -0
  13. data/.ruby-version +1 -0
  14. data/.yamllint +51 -0
  15. data/.yardopts +12 -0
  16. data/AI-DISCLOSURE.md +48 -0
  17. data/CHANGELOG.md +519 -0
  18. data/CLAUDE.md +141 -0
  19. data/CONTRIBUTING.md +734 -0
  20. data/INSTALL.md +154 -0
  21. data/LICENSE +674 -0
  22. data/LICENSE.md +675 -0
  23. data/QUICKSTART.md +73 -0
  24. data/README.md +366 -0
  25. data/Rakefile +200 -0
  26. data/SECURITY.md +114 -0
  27. data/bin/rai +1 -0
  28. data/cliff.toml +52 -0
  29. data/conf/adopt_redactions.yml +8 -0
  30. data/conf/behaviour/.gitkeep +0 -0
  31. data/conf/compliance/cra_rules.yml +25 -0
  32. data/conf/compliance/license_rules.yml +20 -0
  33. data/conf/design/aaif_alignment.yml +181 -0
  34. data/conf/design/ab_testing.yml +172 -0
  35. data/conf/design/accessibility.yml +84 -0
  36. data/conf/design/ai_authorship.yml +210 -0
  37. data/conf/design/ai_provenance.yml +224 -0
  38. data/conf/design/ai_tool_configuration.yml +207 -0
  39. data/conf/design/architecture.yml +139 -0
  40. data/conf/design/autocompletion.yml +115 -0
  41. data/conf/design/backward_compatibility.yml +112 -0
  42. data/conf/design/behaviour_composition.yml +246 -0
  43. data/conf/design/build_rake_extraction.yml +57 -0
  44. data/conf/design/ci_pipeline.yml +100 -0
  45. data/conf/design/claude_code_configuration.yml +157 -0
  46. data/conf/design/compiler.yml +128 -0
  47. data/conf/design/comply.yml +153 -0
  48. data/conf/design/content_packs.yml +84 -0
  49. data/conf/design/desktop_integration.yml +289 -0
  50. data/conf/design/distribution.yml +216 -0
  51. data/conf/design/doctor.yml +184 -0
  52. data/conf/design/documentation.yml +152 -0
  53. data/conf/design/engine_architecture.yml +257 -0
  54. data/conf/design/error_handling.yml +103 -0
  55. data/conf/design/feature_flags.yml +142 -0
  56. data/conf/design/git_hooks.yml +165 -0
  57. data/conf/design/gui_plugins.yml +475 -0
  58. data/conf/design/i18n.yml +84 -0
  59. data/conf/design/integration_testing.yml +56 -0
  60. data/conf/design/licensing_system.yml +88 -0
  61. data/conf/design/lifecycle_management.yml +208 -0
  62. data/conf/design/mcp_integration.yml +207 -0
  63. data/conf/design/mcp_settings.yml +126 -0
  64. data/conf/design/migration.yml +56 -0
  65. data/conf/design/monitoring_observability.yml +194 -0
  66. data/conf/design/namespace_cleanup.yml +145 -0
  67. data/conf/design/plugin_test_segregation.yml +145 -0
  68. data/conf/design/policy_management.yml +229 -0
  69. data/conf/design/project_management.yml +183 -0
  70. data/conf/design/rai_mcp_asset_discovery.yml +164 -0
  71. data/conf/design/rai_mcp_server.yml +605 -0
  72. data/conf/design/release_management.yml +117 -0
  73. data/conf/design/retrofit.yml +199 -0
  74. data/conf/design/retrospective_analyzer.yml +79 -0
  75. data/conf/design/scope_hierarchy.yml +352 -0
  76. data/conf/design/security.yml +115 -0
  77. data/conf/design/session_retrospective.yml +85 -0
  78. data/conf/design/smart_ui_feedback.yml +89 -0
  79. data/conf/design/structured_logging.yml +148 -0
  80. data/conf/design/styles.yml +123 -0
  81. data/conf/design/test_peer_review.yml +89 -0
  82. data/conf/design/testing.yml +136 -0
  83. data/conf/design/threat_model.yml +108 -0
  84. data/conf/design/ui_framework.yml +111 -0
  85. data/conf/design/usage_optimization.yml +122 -0
  86. data/conf/design/version_management.yml +60 -0
  87. data/conf/design/workflow.yml +227 -0
  88. data/conf/mcp/server_defaults.yml +42 -0
  89. data/conf/mcp/trust.yml +21 -0
  90. data/conf/packaging/core.yml +12 -0
  91. data/conf/packaging/gtk4.yml +11 -0
  92. data/conf/packaging/qt6.yml +11 -0
  93. data/conf/policy/default_deny_list.yml +197 -0
  94. data/conf/review/cli-command-audit.yml +857 -0
  95. data/conf/review/design-docs.yml +1064 -0
  96. data/conf/review/design-questionnaire.yml +153 -0
  97. data/conf/review/questionnaire.yml +146 -0
  98. data/conf/review/rosett-ai-core.yml +2919 -0
  99. data/conf/schemas/ai_config_schema.json +73 -0
  100. data/conf/schemas/behaviour_schema.json +132 -0
  101. data/conf/schemas/compliance_rule_schema.json +63 -0
  102. data/conf/schemas/content_pack_manifest_schema.json +51 -0
  103. data/conf/schemas/design_schema.json +210 -0
  104. data/conf/schemas/engine_manifest_schema.json +144 -0
  105. data/conf/schemas/lockfile_schema.json +74 -0
  106. data/conf/schemas/mcp_server_schema.json +48 -0
  107. data/conf/schemas/packaging_schema.json +70 -0
  108. data/conf/schemas/policy_schema.json +85 -0
  109. data/conf/schemas/provenance_schema.json +84 -0
  110. data/conf/schemas/rai_config_schema.json +56 -0
  111. data/conf/schemas/rai_project_schema.json +20 -0
  112. data/conf/schemas/scope_hierarchy_schema.json +49 -0
  113. data/conf/schemas/target_schema.json +67 -0
  114. data/conf/schemas/tooling_schema.json +65 -0
  115. data/conf/schemas/workflow_schema.json +112 -0
  116. data/conf/targets/agents_md.yml +17 -0
  117. data/conf/targets/claude.yml +12 -0
  118. data/conf/tooling/tools.yml +58 -0
  119. data/dist/rosett-ai-mcp.service +48 -0
  120. data/dist/rosett-ai-mcp.yml.default +45 -0
  121. data/doc/AAIF_POSITIONING.md +58 -0
  122. data/doc/ADOPT.md +224 -0
  123. data/doc/AI_PROVENANCE.md +139 -0
  124. data/doc/ARCHITECTURE.md +920 -0
  125. data/doc/BEHAVIOUR.md +409 -0
  126. data/doc/BUILD.md +138 -0
  127. data/doc/CI_CD_RECIPES.md +171 -0
  128. data/doc/CLAUDE_SESSIONS_MOVED.md +16 -0
  129. data/doc/COMMAND_ANALYSIS.md +229 -0
  130. data/doc/CONFIGURATION.md +281 -0
  131. data/doc/DESIGN_AUDIT.md +235 -0
  132. data/doc/DESIGN_PEER_REVIEW.md +771 -0
  133. data/doc/DESKTOP.md +447 -0
  134. data/doc/ENGINES.md +567 -0
  135. data/doc/ENGINE_DEVELOPMENT_GUIDE.md +417 -0
  136. data/doc/FEATURE_AUDIT.md +218 -0
  137. data/doc/IMPLEMENTATION_PLAN.md +669 -0
  138. data/doc/INCIDENT_REPORT_2026-02-02.md +251 -0
  139. data/doc/MIGRATION_GUIDE.md +88 -0
  140. data/doc/PACKAGING.md +232 -0
  141. data/doc/PROJECT_DASHBOARD.md +153 -0
  142. data/doc/PULP_DEPLOYMENT.md +164 -0
  143. data/doc/QUALITY_FIX_SUMMARY.md +110 -0
  144. data/doc/QUICK_START.md +162 -0
  145. data/doc/REEK_CONFIGURATION.md +166 -0
  146. data/doc/REFERENCE.md +253 -0
  147. data/doc/REFERENCES.md +324 -0
  148. data/doc/SECURITY_REVIEW_CHECKLIST.md +72 -0
  149. data/doc/SESSION_2026-02-28_GTK4_HARDENING.md +359 -0
  150. data/doc/SETUP.md +202 -0
  151. data/doc/TEST_PEER_REVIEW.md +152 -0
  152. data/doc/THREAT_MODEL.md +230 -0
  153. data/doc/USAGE.md +545 -0
  154. data/doc/USER_MANUAL.md +585 -0
  155. data/doc/ai_test_review_checklist.md +110 -0
  156. data/doc/changes/2026-02-18-packaging-fpm.md +155 -0
  157. data/doc/changes/2026-02-19-testing-infrastructure.md +221 -0
  158. data/doc/changes/2026-02-20-security-implementation.md +281 -0
  159. data/doc/changes/2026-02-20-styles-implementation.md +220 -0
  160. data/doc/changes/2026-02-21-architecture-completion.md +95 -0
  161. data/doc/changes/2026-02-21-architecture-ui-layer.md +253 -0
  162. data/doc/changes/2026-02-21-cc-config-implementation.md +108 -0
  163. data/doc/changes/2026-02-21-ci-pipeline-implementation.md +214 -0
  164. data/doc/changes/2026-02-21-compiler-multi-target-pipeline.md +241 -0
  165. data/doc/changes/2026-02-21-config-design-show-commands.md +61 -0
  166. data/doc/changes/2026-02-21-design-implementation-overview.md +455 -0
  167. data/doc/changes/2026-02-21-lifecycle-management.md +196 -0
  168. data/doc/changes/2026-02-21-path-resolver.md +128 -0
  169. data/doc/changes/2026-02-24-ci-tmpdir-mutant-fetch.md +45 -0
  170. data/doc/changes/2026-03-01-ci-bundler-strategy.md +120 -0
  171. data/doc/changes/2026-03-20-security-hardening-phase2.md +163 -0
  172. data/doc/context/SESSION-HANDOFF.md +69 -0
  173. data/doc/context/ai-engine-usage-trends-2026.md +80 -0
  174. data/doc/context/plan-pluggable-engines.md +590 -0
  175. data/doc/decisions/001-flog-deferred.md +32 -0
  176. data/doc/decisions/002-path-resolution-strategy.md +158 -0
  177. data/doc/decisions/003-ui-adapter-selection.md +193 -0
  178. data/doc/decisions/004-design-document-validation.md +179 -0
  179. data/doc/decisions/005-package-splitting-strategy.md +200 -0
  180. data/doc/decisions/006-multi-engine-architecture.md +147 -0
  181. data/doc/decisions/007-engine-agnostic-pivot.md +219 -0
  182. data/doc/decisions/008-ci-bundler-strategy.md +129 -0
  183. data/doc/decisions/009-core-only-v1-release.md +60 -0
  184. data/doc/decisions/010-engine-debian-packaging.md +66 -0
  185. data/doc/decisions/011-context-aware-cli.md +71 -0
  186. data/doc/dependency_decisions.yml +247 -0
  187. data/doc/issues/001-wrapper-missing-environment-variables.md +197 -0
  188. data/doc/issues/002-embedded-ruby-wrong-prefix.md +217 -0
  189. data/doc/issues/003-smoke-test-false-positive.md +127 -0
  190. data/doc/issues/004-market-research-design-updates.md +109 -0
  191. data/doc/issues/005-compile-scope-coexistence.md +161 -0
  192. data/doc/locales/.gitkeep +0 -0
  193. data/doc/man/rai.1.ronn +505 -0
  194. data/doc/operations/packaging.md +133 -0
  195. data/doc/operations/rosett-ai-release.md +65 -0
  196. data/doc/reference/error-catalog.md +107 -0
  197. data/doc/reference/rosett-ai-technical-reference.pdf +0 -0
  198. data/doc/reference/src/Pictures/cover.jpg +0 -0
  199. data/doc/reference/src/Pictures/head1.jpg +0 -0
  200. data/doc/reference/src/Pictures/head2.jpg +0 -0
  201. data/doc/reference/src/Pictures/head3.jpg +0 -0
  202. data/doc/reference/src/Pictures/head4.jpg +0 -0
  203. data/doc/reference/src/Pictures/head5.jpg +0 -0
  204. data/doc/reference/src/Pictures/head6.jpg +0 -0
  205. data/doc/reference/src/Pictures/head7.jpg +0 -0
  206. data/doc/reference/src/Pictures/head8.jpg +0 -0
  207. data/doc/reference/src/StyleInd.ist +4 -0
  208. data/doc/reference/src/bibliography.bib +79 -0
  209. data/doc/reference/src/main.tex +1288 -0
  210. data/doc/reference/src/structure.tex +303 -0
  211. data/doc/rosett-ai-bookmarks.html +301 -0
  212. data/kitchen.yml +46 -0
  213. data/lib/rosett_ai/adopter/executor_resolver.rb +77 -0
  214. data/lib/rosett_ai/adopter/local_analysis_collector.rb +154 -0
  215. data/lib/rosett_ai/adopter/rule_adopter.rb +254 -0
  216. data/lib/rosett_ai/ai_config/config_compiler.rb +111 -0
  217. data/lib/rosett_ai/ai_config/context_window.rb +55 -0
  218. data/lib/rosett_ai/ai_config/cost_controls.rb +44 -0
  219. data/lib/rosett_ai/ai_config/fallback_chain.rb +64 -0
  220. data/lib/rosett_ai/ai_config/model_router.rb +121 -0
  221. data/lib/rosett_ai/ai_config/validator.rb +45 -0
  222. data/lib/rosett_ai/authorship/attribution_compiler.rb +99 -0
  223. data/lib/rosett_ai/authorship/disclosure_policy.rb +81 -0
  224. data/lib/rosett_ai/authorship/review_validator.rb +39 -0
  225. data/lib/rosett_ai/authorship/trailer_generator.rb +88 -0
  226. data/lib/rosett_ai/backup/compressor.rb +180 -0
  227. data/lib/rosett_ai/backup/destination.rb +91 -0
  228. data/lib/rosett_ai/behaviour/manager.rb +156 -0
  229. data/lib/rosett_ai/compiler/backend.rb +86 -0
  230. data/lib/rosett_ai/compiler/backends/agents_md_backend.rb +80 -0
  231. data/lib/rosett_ai/compiler/backends/claude_backend.rb +88 -0
  232. data/lib/rosett_ai/compiler/backends/generic_backend.rb +15 -0
  233. data/lib/rosett_ai/compiler/behaviour_compiler.rb +40 -0
  234. data/lib/rosett_ai/compiler/capability_checker.rb +104 -0
  235. data/lib/rosett_ai/compiler/compilation_pipeline.rb +361 -0
  236. data/lib/rosett_ai/compiler/compiled_output.rb +39 -0
  237. data/lib/rosett_ai/compiler/locale_compiler.rb +250 -0
  238. data/lib/rosett_ai/compiler/target_profile.rb +112 -0
  239. data/lib/rosett_ai/completion/generator.rb +101 -0
  240. data/lib/rosett_ai/completion/shells/bash_generator.rb +126 -0
  241. data/lib/rosett_ai/completion/shells/fish_generator.rb +78 -0
  242. data/lib/rosett_ai/completion/shells/zsh_generator.rb +126 -0
  243. data/lib/rosett_ai/comply/checkers/cra_checker.rb +102 -0
  244. data/lib/rosett_ai/comply/checkers/license_checker.rb +85 -0
  245. data/lib/rosett_ai/comply/checkers/spdx_header_checker.rb +98 -0
  246. data/lib/rosett_ai/comply/reporter.rb +113 -0
  247. data/lib/rosett_ai/comply/runner.rb +50 -0
  248. data/lib/rosett_ai/composition/circular_dependency_detector.rb +56 -0
  249. data/lib/rosett_ai/composition/composer.rb +158 -0
  250. data/lib/rosett_ai/composition/composition_result.rb +64 -0
  251. data/lib/rosett_ai/composition/conflict_detector.rb +53 -0
  252. data/lib/rosett_ai/composition/lockfile.rb +103 -0
  253. data/lib/rosett_ai/composition/merge_strategy.rb +131 -0
  254. data/lib/rosett_ai/composition/priority_sorter.rb +29 -0
  255. data/lib/rosett_ai/composition/scope_resolver.rb +55 -0
  256. data/lib/rosett_ai/config/compile_result.rb +37 -0
  257. data/lib/rosett_ai/config/compiler.rb +13 -0
  258. data/lib/rosett_ai/config/domain_transformer.rb +13 -0
  259. data/lib/rosett_ai/config/key_map.rb +13 -0
  260. data/lib/rosett_ai/config/masking_secret_resolver.rb +40 -0
  261. data/lib/rosett_ai/config/scope_router.rb +13 -0
  262. data/lib/rosett_ai/config/secret_resolver.rb +125 -0
  263. data/lib/rosett_ai/configuration.rb +119 -0
  264. data/lib/rosett_ai/content/content_client.rb +60 -0
  265. data/lib/rosett_ai/content/pack_installer.rb +117 -0
  266. data/lib/rosett_ai/content/pack_manifest.rb +50 -0
  267. data/lib/rosett_ai/content/pack_registry.rb +68 -0
  268. data/lib/rosett_ai/content_packs/manager.rb +50 -0
  269. data/lib/rosett_ai/dbus/compositor_detector.rb +77 -0
  270. data/lib/rosett_ai/dbus/focus_adapters/base.rb +59 -0
  271. data/lib/rosett_ai/dbus/focus_adapters/gnome_adapter.rb +172 -0
  272. data/lib/rosett_ai/dbus/focus_adapters/hyprland_adapter.rb +77 -0
  273. data/lib/rosett_ai/dbus/focus_adapters/i3_adapter.rb +65 -0
  274. data/lib/rosett_ai/dbus/focus_adapters/kwin_adapter.rb +103 -0
  275. data/lib/rosett_ai/dbus/focus_adapters/x11_adapter.rb +105 -0
  276. data/lib/rosett_ai/dbus/focus_monitor_interface.rb +103 -0
  277. data/lib/rosett_ai/dbus/manager_interface.rb +213 -0
  278. data/lib/rosett_ai/dbus/plugin_manager_interface.rb +169 -0
  279. data/lib/rosett_ai/dbus/rate_limiter.rb +89 -0
  280. data/lib/rosett_ai/dbus/service.rb +121 -0
  281. data/lib/rosett_ai/dbus/status_notifier_interface.rb +79 -0
  282. data/lib/rosett_ai/deprecation.rb +79 -0
  283. data/lib/rosett_ai/desktop/dbus_client.rb +259 -0
  284. data/lib/rosett_ai/desktop/gtk4_app.rb +371 -0
  285. data/lib/rosett_ai/desktop/gtk4_preferences.rb +331 -0
  286. data/lib/rosett_ai/desktop/gui_logger.rb +236 -0
  287. data/lib/rosett_ai/doctor/check.rb +92 -0
  288. data/lib/rosett_ai/doctor/checks/cache_health_check.rb +50 -0
  289. data/lib/rosett_ai/doctor/checks/dbus_availability_check.rb +39 -0
  290. data/lib/rosett_ai/doctor/checks/engine_detection_check.rb +46 -0
  291. data/lib/rosett_ai/doctor/checks/file_permission_check.rb +44 -0
  292. data/lib/rosett_ai/doctor/checks/gem_dependency_check.rb +55 -0
  293. data/lib/rosett_ai/doctor/checks/ruby_version_check.rb +50 -0
  294. data/lib/rosett_ai/doctor/checks/stale_config_nncc_check.rb +57 -0
  295. data/lib/rosett_ai/doctor/checks/stale_home_nncc_check.rb +59 -0
  296. data/lib/rosett_ai/doctor.rb +81 -0
  297. data/lib/rosett_ai/documentation/reference_compiler.rb +122 -0
  298. data/lib/rosett_ai/documentation/translator.rb +62 -0
  299. data/lib/rosett_ai/engines/base_config_compiler.rb +203 -0
  300. data/lib/rosett_ai/engines/detector.rb +63 -0
  301. data/lib/rosett_ai/engines/registry.rb +50 -0
  302. data/lib/rosett_ai/error_handler.rb +139 -0
  303. data/lib/rosett_ai/exit_codes.rb +76 -0
  304. data/lib/rosett_ai/feature_flags.rb +102 -0
  305. data/lib/rosett_ai/formatting.rb +33 -0
  306. data/lib/rosett_ai/gem_consistency_checker.rb +199 -0
  307. data/lib/rosett_ai/git_hooks/chain_detector.rb +86 -0
  308. data/lib/rosett_ai/git_hooks/installer.rb +175 -0
  309. data/lib/rosett_ai/git_hooks/script_generator.rb +125 -0
  310. data/lib/rosett_ai/gitlab/validators/supplementary_gitlab_ci_yaml_validator.rb +79 -0
  311. data/lib/rosett_ai/i18n/locale_resolver.rb +46 -0
  312. data/lib/rosett_ai/i18n/utf8_checker.rb +32 -0
  313. data/lib/rosett_ai/init/config_file_writer.rb +24 -0
  314. data/lib/rosett_ai/init/directory_builder.rb +38 -0
  315. data/lib/rosett_ai/init/file_copier.rb +95 -0
  316. data/lib/rosett_ai/init/global_initializer.rb +28 -0
  317. data/lib/rosett_ai/init/local_initializer.rb +27 -0
  318. data/lib/rosett_ai/init/mcp_registrar.rb +109 -0
  319. data/lib/rosett_ai/init/project_initializer.rb +38 -0
  320. data/lib/rosett_ai/licensing/license_key.rb +139 -0
  321. data/lib/rosett_ai/licensing/license_store.rb +64 -0
  322. data/lib/rosett_ai/licensing/license_validator.rb +60 -0
  323. data/lib/rosett_ai/licensing/tier.rb +42 -0
  324. data/lib/rosett_ai/mcp/admin/auditor.rb +88 -0
  325. data/lib/rosett_ai/mcp/admin/health_checker.rb +81 -0
  326. data/lib/rosett_ai/mcp/admin/registry.rb +100 -0
  327. data/lib/rosett_ai/mcp/admin/schema_validator.rb +63 -0
  328. data/lib/rosett_ai/mcp/enforcement/.gitkeep +0 -0
  329. data/lib/rosett_ai/mcp/enforcement/hook_generator.rb +197 -0
  330. data/lib/rosett_ai/mcp/enforcement/validator.rb +215 -0
  331. data/lib/rosett_ai/mcp/governance.rb +160 -0
  332. data/lib/rosett_ai/mcp/http_security_config.rb +158 -0
  333. data/lib/rosett_ai/mcp/instructions.rb +266 -0
  334. data/lib/rosett_ai/mcp/key_hasher.rb +66 -0
  335. data/lib/rosett_ai/mcp/keyfile.rb +221 -0
  336. data/lib/rosett_ai/mcp/middleware/authentication.rb +146 -0
  337. data/lib/rosett_ai/mcp/middleware/content_type.rb +56 -0
  338. data/lib/rosett_ai/mcp/middleware/cors.rb +83 -0
  339. data/lib/rosett_ai/mcp/middleware/origin_validation.rb +73 -0
  340. data/lib/rosett_ai/mcp/middleware/rate_limit.rb +106 -0
  341. data/lib/rosett_ai/mcp/middleware/request_size.rb +51 -0
  342. data/lib/rosett_ai/mcp/plugins.rb +143 -0
  343. data/lib/rosett_ai/mcp/prompts/compilation_prompt.rb +40 -0
  344. data/lib/rosett_ai/mcp/prompts/compliance_prompt.rb +41 -0
  345. data/lib/rosett_ai/mcp/prompts/diagnostics_prompt.rb +41 -0
  346. data/lib/rosett_ai/mcp/prompts/validation_prompt.rb +41 -0
  347. data/lib/rosett_ai/mcp/resources/behaviour_resource.rb +127 -0
  348. data/lib/rosett_ai/mcp/resources/config_resource.rb +72 -0
  349. data/lib/rosett_ai/mcp/resources/design_resource.rb +58 -0
  350. data/lib/rosett_ai/mcp/resources/hooks_resource.rb +74 -0
  351. data/lib/rosett_ai/mcp/resources/provenance_resource.rb +51 -0
  352. data/lib/rosett_ai/mcp/resources/rules_resource.rb +60 -0
  353. data/lib/rosett_ai/mcp/resources/schema_resource.rb +72 -0
  354. data/lib/rosett_ai/mcp/response_helper.rb +46 -0
  355. data/lib/rosett_ai/mcp/security_logger.rb +60 -0
  356. data/lib/rosett_ai/mcp/server.rb +212 -0
  357. data/lib/rosett_ai/mcp/settings/server_installer.rb +112 -0
  358. data/lib/rosett_ai/mcp/settings/trust_manager.rb +142 -0
  359. data/lib/rosett_ai/mcp/tools/adopt_tool.rb +70 -0
  360. data/lib/rosett_ai/mcp/tools/backup_tool.rb +64 -0
  361. data/lib/rosett_ai/mcp/tools/behaviour_display_tool.rb +72 -0
  362. data/lib/rosett_ai/mcp/tools/behaviour_list_tool.rb +56 -0
  363. data/lib/rosett_ai/mcp/tools/behaviour_manage_tool.rb +114 -0
  364. data/lib/rosett_ai/mcp/tools/behaviour_show_tool.rb +62 -0
  365. data/lib/rosett_ai/mcp/tools/compile_status_tool.rb +122 -0
  366. data/lib/rosett_ai/mcp/tools/compile_tool.rb +191 -0
  367. data/lib/rosett_ai/mcp/tools/comply_tool.rb +79 -0
  368. data/lib/rosett_ai/mcp/tools/config_compile_tool.rb +71 -0
  369. data/lib/rosett_ai/mcp/tools/config_status_tool.rb +79 -0
  370. data/lib/rosett_ai/mcp/tools/content_tool.rb +78 -0
  371. data/lib/rosett_ai/mcp/tools/context_query_tool.rb +156 -0
  372. data/lib/rosett_ai/mcp/tools/design_list_tool.rb +57 -0
  373. data/lib/rosett_ai/mcp/tools/design_show_tool.rb +69 -0
  374. data/lib/rosett_ai/mcp/tools/doctor_tool.rb +62 -0
  375. data/lib/rosett_ai/mcp/tools/documentation_status_tool.rb +45 -0
  376. data/lib/rosett_ai/mcp/tools/engines_tool.rb +84 -0
  377. data/lib/rosett_ai/mcp/tools/hook_install_tool.rb +190 -0
  378. data/lib/rosett_ai/mcp/tools/hook_preview_tool.rb +173 -0
  379. data/lib/rosett_ai/mcp/tools/hooks_status_tool.rb +84 -0
  380. data/lib/rosett_ai/mcp/tools/init_tool.rb +87 -0
  381. data/lib/rosett_ai/mcp/tools/license_status_tool.rb +44 -0
  382. data/lib/rosett_ai/mcp/tools/project_tool.rb +117 -0
  383. data/lib/rosett_ai/mcp/tools/provenance_tool.rb +97 -0
  384. data/lib/rosett_ai/mcp/tools/provenance_write_tool.rb +40 -0
  385. data/lib/rosett_ai/mcp/tools/retrofit_tool.rb +81 -0
  386. data/lib/rosett_ai/mcp/tools/rule_search_tool.rb +163 -0
  387. data/lib/rosett_ai/mcp/tools/schema_get_tool.rb +94 -0
  388. data/lib/rosett_ai/mcp/tools/tooling_tool.rb +86 -0
  389. data/lib/rosett_ai/mcp/tools/validate_tool.rb +105 -0
  390. data/lib/rosett_ai/mcp/tools/workflow_execute_tool.rb +74 -0
  391. data/lib/rosett_ai/mcp/tools/workflow_tool.rb +78 -0
  392. data/lib/rosett_ai/migration/detector.rb +117 -0
  393. data/lib/rosett_ai/migration/nncc_config_migrator.rb +94 -0
  394. data/lib/rosett_ai/migration/nncc_project_migrator.rb +90 -0
  395. data/lib/rosett_ai/migration/xdg_migrator.rb +123 -0
  396. data/lib/rosett_ai/package_manager/apt.rb +108 -0
  397. data/lib/rosett_ai/package_manager/base.rb +68 -0
  398. data/lib/rosett_ai/package_manager/gem_backend.rb +90 -0
  399. data/lib/rosett_ai/packaging/variant_config.rb +92 -0
  400. data/lib/rosett_ai/path_resolver.rb +115 -0
  401. data/lib/rosett_ai/plugins/contract.rb +43 -0
  402. data/lib/rosett_ai/plugins/engine_contract.rb +60 -0
  403. data/lib/rosett_ai/plugins/gui_contract.rb +74 -0
  404. data/lib/rosett_ai/plugins/mcp_contract.rb +48 -0
  405. data/lib/rosett_ai/plugins/registry.rb +150 -0
  406. data/lib/rosett_ai/policy/auditor.rb +41 -0
  407. data/lib/rosett_ai/policy/deny_list.rb +71 -0
  408. data/lib/rosett_ai/policy/opt_out_scanner.rb +37 -0
  409. data/lib/rosett_ai/policy/policy_compiler.rb +84 -0
  410. data/lib/rosett_ai/policy/protected_files.rb +47 -0
  411. data/lib/rosett_ai/policy/tier_hierarchy.rb +48 -0
  412. data/lib/rosett_ai/policy/validator.rb +35 -0
  413. data/lib/rosett_ai/profiler.rb +79 -0
  414. data/lib/rosett_ai/project/drift_detector.rb +126 -0
  415. data/lib/rosett_ai/project/manager.rb +115 -0
  416. data/lib/rosett_ai/project/sync_manager.rb +138 -0
  417. data/lib/rosett_ai/project/template_applier.rb +105 -0
  418. data/lib/rosett_ai/project_context.rb +82 -0
  419. data/lib/rosett_ai/provenance/entry.rb +63 -0
  420. data/lib/rosett_ai/provenance/file_source.rb +32 -0
  421. data/lib/rosett_ai/provenance/source.rb +62 -0
  422. data/lib/rosett_ai/provenance/store.rb +153 -0
  423. data/lib/rosett_ai/provenance/tracker.rb +62 -0
  424. data/lib/rosett_ai/provenance/trailer_generator.rb +43 -0
  425. data/lib/rosett_ai/provenance/validator.rb +45 -0
  426. data/lib/rosett_ai/quorum/collector.rb +59 -0
  427. data/lib/rosett_ai/quorum/comparator.rb +81 -0
  428. data/lib/rosett_ai/quorum/dispatcher.rb +57 -0
  429. data/lib/rosett_ai/quorum/strategies/adopt.rb +56 -0
  430. data/lib/rosett_ai/rai_config.rb +107 -0
  431. data/lib/rosett_ai/retrofit/base_parser.rb +66 -0
  432. data/lib/rosett_ai/retrofit/engine.rb +171 -0
  433. data/lib/rosett_ai/retrofit/parsers/agents_md_parser.rb +50 -0
  434. data/lib/rosett_ai/retrofit/parsers/claude_parser.rb +69 -0
  435. data/lib/rosett_ai/retrofit/parsers/cursor_parser.rb +82 -0
  436. data/lib/rosett_ai/retrofit/round_trip_validator.rb +65 -0
  437. data/lib/rosett_ai/retrofit/scanner.rb +47 -0
  438. data/lib/rosett_ai/retrofit/secret_detector.rb +87 -0
  439. data/lib/rosett_ai/secrets_resolver.rb +71 -0
  440. data/lib/rosett_ai/smart_feedback/suggester.rb +83 -0
  441. data/lib/rosett_ai/smart_feedback/thor_middleware.rb +84 -0
  442. data/lib/rosett_ai/structured_logger.rb +110 -0
  443. data/lib/rosett_ai/telemetry/json_lines_writer.rb +50 -0
  444. data/lib/rosett_ai/telemetry/log_rotator.rb +67 -0
  445. data/lib/rosett_ai/telemetry/provider.rb +26 -0
  446. data/lib/rosett_ai/telemetry/reporter.rb +144 -0
  447. data/lib/rosett_ai/telemetry.rb +47 -0
  448. data/lib/rosett_ai/text_sanitizer.rb +62 -0
  449. data/lib/rosett_ai/thor/cli.rb +269 -0
  450. data/lib/rosett_ai/thor/tasks/adopt.rb +250 -0
  451. data/lib/rosett_ai/thor/tasks/backup.rb +420 -0
  452. data/lib/rosett_ai/thor/tasks/behaviour.rb +474 -0
  453. data/lib/rosett_ai/thor/tasks/build.rb +1162 -0
  454. data/lib/rosett_ai/thor/tasks/compile.rb +415 -0
  455. data/lib/rosett_ai/thor/tasks/completion.rb +123 -0
  456. data/lib/rosett_ai/thor/tasks/comply.rb +82 -0
  457. data/lib/rosett_ai/thor/tasks/config.rb +265 -0
  458. data/lib/rosett_ai/thor/tasks/content.rb +193 -0
  459. data/lib/rosett_ai/thor/tasks/dbus.rb +321 -0
  460. data/lib/rosett_ai/thor/tasks/design.rb +258 -0
  461. data/lib/rosett_ai/thor/tasks/desktop.rb +129 -0
  462. data/lib/rosett_ai/thor/tasks/doctor.rb +127 -0
  463. data/lib/rosett_ai/thor/tasks/documentation.rb +321 -0
  464. data/lib/rosett_ai/thor/tasks/engines.rb +167 -0
  465. data/lib/rosett_ai/thor/tasks/hooks.rb +219 -0
  466. data/lib/rosett_ai/thor/tasks/init.rb +259 -0
  467. data/lib/rosett_ai/thor/tasks/license.rb +120 -0
  468. data/lib/rosett_ai/thor/tasks/mcp.rb +535 -0
  469. data/lib/rosett_ai/thor/tasks/migrate.rb +121 -0
  470. data/lib/rosett_ai/thor/tasks/plugins.rb +157 -0
  471. data/lib/rosett_ai/thor/tasks/project.rb +260 -0
  472. data/lib/rosett_ai/thor/tasks/provenance.rb +195 -0
  473. data/lib/rosett_ai/thor/tasks/release.rb +314 -0
  474. data/lib/rosett_ai/thor/tasks/retrofit.rb +90 -0
  475. data/lib/rosett_ai/thor/tasks/tooling.rb +308 -0
  476. data/lib/rosett_ai/thor/tasks/validate.rb +108 -0
  477. data/lib/rosett_ai/thor/tasks/workflow.rb +196 -0
  478. data/lib/rosett_ai/tooling/ci_yaml_validator.rb +37 -0
  479. data/lib/rosett_ai/tooling/version_checker.rb +35 -0
  480. data/lib/rosett_ai/ui/accessible_tui.rb +61 -0
  481. data/lib/rosett_ai/ui/base.rb +46 -0
  482. data/lib/rosett_ai/ui/gtk4.rb +98 -0
  483. data/lib/rosett_ai/ui/kde.rb +40 -0
  484. data/lib/rosett_ai/ui/qt6.rb +40 -0
  485. data/lib/rosett_ai/ui/registry.rb +60 -0
  486. data/lib/rosett_ai/ui/tty_helper.rb +74 -0
  487. data/lib/rosett_ai/ui/tui.rb +59 -0
  488. data/lib/rosett_ai/validators/behaviour_validator.rb +20 -0
  489. data/lib/rosett_ai/validators/design_validator.rb +17 -0
  490. data/lib/rosett_ai/validators/schema_validator.rb +84 -0
  491. data/lib/rosett_ai/validators/tooling_validator.rb +17 -0
  492. data/lib/rosett_ai/version.rb +8 -0
  493. data/lib/rosett_ai/version_consistency_checker.rb +129 -0
  494. data/lib/rosett_ai/workflow/audit_log.rb +86 -0
  495. data/lib/rosett_ai/workflow/engine.rb +142 -0
  496. data/lib/rosett_ai/workflow/manager.rb +82 -0
  497. data/lib/rosett_ai/workflow/schema_validator.rb +71 -0
  498. data/lib/rosett_ai/workflow/step_runner.rb +61 -0
  499. data/lib/rosett_ai/workflow/steps/prompt_step.rb +62 -0
  500. data/lib/rosett_ai/workflow/steps/rai_step.rb +74 -0
  501. data/lib/rosett_ai/workflow/steps/shell_step.rb +53 -0
  502. data/lib/rosett_ai/yaml_loader.rb +78 -0
  503. data/lib/rosett_ai.rb +221 -0
  504. data/lib/rubocop/cop/rosett_ai/shell_interpolation.rb +54 -0
  505. data/lib/rubocop/cop/rosett_ai/unsafe_const_get.rb +60 -0
  506. data/lib/rubocop/cop/rosett_ai/unsafe_send.rb +50 -0
  507. data/lib/rubocop/cop/rosett_ai/unsafe_yaml_load.rb +40 -0
  508. data/lib/rubocop/rosett_ai.rb +9 -0
  509. data/lib/scripts/generated/docker_hub_tags.rb +126 -0
  510. data/locales/.gitkeep +0 -0
  511. data/locales/ar.yml +579 -0
  512. data/locales/en.yml +571 -0
  513. data/locales/fr.yml +567 -0
  514. data/packaging/build-engine-deb.sh +81 -0
  515. data/packaging/scripts/postinst +17 -0
  516. data/packaging/scripts/postrm +19 -0
  517. data/packaging/scripts/prerm +10 -0
  518. data/packaging/wrapper.sh.template +38 -0
  519. data/rosett-ai.gemspec +63 -0
  520. data/rules/.gitkeep +0 -0
  521. data/scripts/publish/pulp_upload.sh +123 -0
  522. data/settings.json +29 -0
  523. data/share/applications/be.neatnerds.rosettai.desktop +29 -0
  524. data/share/dbus-1/interfaces/be.neatnerds.rosettai.xml +103 -0
  525. data/share/dbus-1/services/be.neatnerds.rosettai.service +3 -0
  526. data/share/templates/behaviour/criticalthinking.yml +69 -0
  527. metadata +810 -0
@@ -0,0 +1,605 @@
1
+ ---
2
+ name: rai_mcp_server
3
+ domain: core
4
+ version: 0.1.0
5
+ status: draft
6
+ priority: 2
7
+ author: hugo
8
+ created_at: "2026-04-17"
9
+ modified_at: "2026-04-17"
10
+ modified_by: claude
11
+ depends_on:
12
+ - mcp_integration
13
+ - mcp_settings
14
+ - rai_mcp_asset_discovery
15
+ - compiler
16
+ - architecture
17
+ - scope_hierarchy
18
+ - security
19
+ - error_handling
20
+ #
21
+ intent: |
22
+ DES-RAI-MCP-002: Concrete implementation specification for the rai-mcp server
23
+ invoked via `raictl mcp serve`. This refines three prior design documents
24
+ (mcp_integration, mcp_settings, rai_mcp_asset_discovery) into a single
25
+ actionable spec with tool catalog, resource catalog, enforcement pipeline,
26
+ and phased implementation plan.
27
+
28
+ rai-mcp is the first step of the Bootstrap Loop: it enables enforcement that
29
+ improves every subsequent AI-assisted session. The server:
30
+
31
+ 1. Serves rosett-ai assets (behaviours, rules, schemas) to any MCP-compliant
32
+ AI client via the instructions field for auto-discovery.
33
+ 2. Provides decision-support tools ("what rules apply here?", "is this
34
+ file compliant?") that make AI clients rule-aware.
35
+ 3. Generates and installs PreToolUse enforcement hooks from behaviour rules,
36
+ transforming declarative YAML into runtime enforcement.
37
+ 4. Implements mutation safety: confirmation-by-default, auto-backup before
38
+ writes, configurable enforcement levels.
39
+
40
+ The server infrastructure (transport, middleware, governance, plugins) already
41
+ exists. This design focuses on closing gaps: the instructions field, the
42
+ enforcement pipeline, decision-support tools, asset discovery tools, and
43
+ fixing 6 partial tools + 1 stub.
44
+
45
+ Key principle: documentation-tool parity. Every tool documented here must
46
+ exist and behave as described. Every tool that exists must be documented.
47
+ The design doc is the acceptance test.
48
+
49
+ Session: W6-01-RAIMCP-DESIGN | WP#1557
50
+ #
51
+ constraints:
52
+ - "Must use the official MCP Ruby SDK (mcp gem >= 0.9.2) — no custom protocol implementation"
53
+ - "MCP spec version: 2025-03-26"
54
+ - "All MCP tools must validate input against JSON Schema before execution"
55
+ - "MCP server must run via stdio transport by default (subprocess model)"
56
+ - "Streamable HTTP transport is optional and requires explicit opt-in"
57
+ - "No MCP tool may perform destructive operations without user confirmation (default)"
58
+ - "MCP tool annotations must accurately reflect behaviour (readOnlyHint, destructiveHint)"
59
+ - "Server-side secrets must never be exposed via MCP resources"
60
+ - "MCP server must declare capabilities honestly — no overclaiming"
61
+ - "Array-form system() for any subprocess spawning within MCP tools"
62
+ - "YAML.safe_load only for all YAML processing within MCP tools"
63
+ - "Instructions field is MANDATORY — AI clients must auto-discover tools at launch"
64
+ - "Documentation-tool parity: every documented tool must work, every working tool must be documented"
65
+ - "Both manual and AI-assisted authoring paths must pass through EnforcementValidator — no bypass"
66
+ - "All new MCP code must have YARD documentation"
67
+ - "Enforcement pipeline (hook preview/install) is separate from compilation (raictl compile)"
68
+ - "Resolution strategy configurable: global, hybrid (default), per_request"
69
+ - "Mutation tools require auto-backup before execution (configurable, default on)"
70
+ #
71
+ acceptance_criteria:
72
+ # Instructions field
73
+ - "MCP server passes instructions field to MCP::Server.new on startup"
74
+ - "Instructions markdown contains tool inventory grouped by category"
75
+ - "Instructions markdown contains resource URI patterns with examples"
76
+ - "Instructions markdown contains scope hierarchy explanation"
77
+ - "Instructions markdown contains common workflow guides"
78
+ - "Instructions markdown contains mutation safety rules"
79
+ - "AI client auto-discovers all rosett-ai tools on session start via instructions"
80
+ # Tool catalog — shipping tools
81
+ - "All 19 SHIPPING tools registered and functional via MCP protocol"
82
+ - "All 19 SHIPPING tools documented in instructions with accurate annotations"
83
+ - "raictl mcp tools output matches design doc tool catalog exactly"
84
+ # Tool catalog — fixed tools
85
+ - "rai_compile delegates to real compiler (stub eliminated)"
86
+ - "rai_validate performs JSON Schema validation, not just YAML syntax check"
87
+ - "rai_project reads from gemspec/config, not hardcoded values"
88
+ - "rai_hooks_status filter handles all overcommit hook phases"
89
+ - "rosett_ai_engines surfaces errors instead of swallowing them"
90
+ - "rai_config_status surfaces errors instead of swallowing them"
91
+ # Tool catalog — new tools
92
+ - "rai_rule_search accepts keyword and returns matching rules with behaviour, rule_id, priority, snippet"
93
+ - "rai_rule_search supports optional filters: priority_min, scope, enabled_only"
94
+ - "rai_schema_get returns JSON Schema content for behaviour/design/tooling schemas"
95
+ - "rai_compile_status returns per-file staleness with source vs compiled checksums"
96
+ - "rai_hook_preview returns generated hook script for inspection without side effects"
97
+ - "rai_hook_install generates hook + writes to disk + registers in settings.json (mutation, confirmation required)"
98
+ - "rai_context_query returns applicable rules for a given file path, tool name, or action"
99
+ # Resources
100
+ - "rosett-ai://behaviour/{name} resolves via 3-tier lookup with configurable merge strategy"
101
+ - "rosett-ai://behaviour/{name}?tier=xdg returns content from specific tier"
102
+ - "rosett-ai://design/{name} returns design document YAML content"
103
+ - "rosett-ai://provenance/ returns AI provenance entries"
104
+ - "rosett-ai://config/{scope} returns settings for all scopes including user (bug fixed)"
105
+ - "rosett-ai://schema/{name} returns JSON Schema content"
106
+ - "rosett-ai://rules/{name} returns compiled rule markdown content"
107
+ - "rosett-ai://hooks/{scope} returns installed hook script content"
108
+ # Enforcement pipeline
109
+ - "Behaviour schema v1.3.0 adds optional enforcement block (type, pattern, applies_to, action)"
110
+ - "EnforcementValidator checks: pattern present, pattern compiles, pattern not degenerate, applies_to present, action valid"
111
+ - "EnforcementValidator downgrades invalid enforceable rules to advisory with warning"
112
+ - "EnforcementValidator runs on both manual and AI-assisted authoring paths"
113
+ - "rai_hook_install auto-backups affected scope before writing"
114
+ - "Generated hook scripts include YARD documentation, human-readable header, AI client instructions"
115
+ - "Hook scripts are traceable: source behaviour, rule ID, version, generator version, initiator identity"
116
+ # Mutation safety
117
+ - "Mutation confirmation default is required (configurable: required, optional, disabled)"
118
+ - "Auto-backup before mutation default is on (configurable)"
119
+ - "Instructions field directs AI clients to request user confirmation for mutation tools"
120
+ # Resolution
121
+ - "Resolution mode configurable: global, hybrid (default), per_request"
122
+ - "Hybrid mode: server config for mutations, per-request override on read-only tools"
123
+ - "Default merge strategy: first_wins (configurable: first_wins, deep_merge, array_union)"
124
+ # Integration
125
+ - "raictl init --global auto-registers MCP server in ~/.claude/settings.json"
126
+ - "raictl init --global documents MCP registration in output"
127
+ - "raictl init --local and --project do NOT modify global settings.json"
128
+ # Packaging
129
+ - "raictl mcp serve starts from .deb installation (kitchen VM verified)"
130
+ - "BUNDLE_WITHOUT does not exclude mcp group in .deb wrapper"
131
+ - "Build process reproducible: documented minimal dependencies, kitchen test builds .deb from source in clean VM"
132
+ - "Developer documentation enables independent reproducible builds"
133
+ # Quality
134
+ - "Integration tests verify MCP protocol handshake and tool execution"
135
+ - "All new code has YARD documentation"
136
+ - "MCP server gracefully handles malformed JSON-RPC messages"
137
+ #
138
+ examples:
139
+ - scenario: "AI client starts a session and discovers rosett-ai tools"
140
+ expected: |
141
+ Claude Code reads the MCP server's instructions field on session start.
142
+ The instructions list all available tools by category:
143
+
144
+ DISCOVERY: rai_behaviour_list, rai_behaviour_show, rai_rule_search,
145
+ rai_schema_get, rai_compile_status, rai_design_list, rai_design_show
146
+ ENFORCEMENT: rai_hook_preview, rai_hook_install, rai_context_query
147
+ MANAGEMENT: rai_behaviour_manage, rai_compile, rai_config_compile, rai_validate
148
+ COMPLIANCE: rai_comply, rai_provenance, rai_provenance_init
149
+ OPERATIONS: rai_doctor, rai_backup, rai_init, rai_project, rosett_ai_engines
150
+
151
+ The AI client knows which tool to use for each task without manual lookup.
152
+ not: "AI client must guess tool names or read documentation files manually"
153
+ - scenario: "AI client queries applicable rules before editing a file"
154
+ expected: |
155
+ Tool call: { name: "rai_context_query", arguments: { tool_name: "Bash" } }
156
+ Response:
157
+ {
158
+ "applicable_rules": [
159
+ {
160
+ "rule_id": "rule_022",
161
+ "behaviour": "operational_discipline",
162
+ "priority": 90,
163
+ "enforcement": "enforceable",
164
+ "action": "block",
165
+ "description": "Never bypass git hooks with --no-verify"
166
+ },
167
+ ...
168
+ ],
169
+ "total": 5,
170
+ "scope": "global"
171
+ }
172
+ not: "AI client has no way to know which rules apply before acting"
173
+ - scenario: "User wants to install enforcement hooks"
174
+ expected: |
175
+ 1. AI calls rai_hook_preview to show what would be generated
176
+ 2. User reviews the preview output
177
+ 3. AI calls rai_hook_install with confirmed: true
178
+ 4. rai_hook_install auto-backups ~/.claude/hooks/ before writing
179
+ 5. Hook script written to ~/.claude/hooks/rai-enforce-global.rb
180
+ 6. settings.json updated with PreToolUse hook entry
181
+ 7. Response includes: hook path, backup path, rules count, behaviours included
182
+ not: "Hook installed without preview, without confirmation, or without backup"
183
+ - scenario: "User manually writes a rule marked enforceable with an invalid pattern"
184
+ expected: |
185
+ User saves behaviour YAML with enforcement.type: enforceable but
186
+ enforcement.pattern: ".*" (degenerate).
187
+
188
+ EnforcementValidator detects degenerate pattern, downgrades to advisory:
189
+ "Rule rule_005 declares enforceable but pattern is degenerate (matches
190
+ everything). Downgraded to advisory. Fix the pattern to enable hook
191
+ generation."
192
+
193
+ The rule is saved as advisory. No hook is generated for this rule.
194
+ Warning appears in rai_validate, rai_compile, and rai_hook_preview output.
195
+ not: "Degenerate pattern silently generates a hook that blocks all tool calls"
196
+ - scenario: "AI-assisted rule creation"
197
+ expected: |
198
+ User describes intent: "Block any attempt to write to /etc/passwd"
199
+ AI client calls rai_behaviour_manage with:
200
+ {
201
+ "action": "modify",
202
+ "name": "security_custom",
203
+ "rule": {
204
+ "id": "rule_010",
205
+ "description": "Block writes to system password file",
206
+ "priority": 95,
207
+ "enforcement": {
208
+ "type": "enforceable",
209
+ "pattern": "/etc/passwd",
210
+ "applies_to": ["Edit", "Write", "Bash"],
211
+ "action": "block"
212
+ }
213
+ }
214
+ }
215
+
216
+ EnforcementValidator runs on the AI-generated enforcement block
217
+ (same validator as manual path). Pattern is valid, non-degenerate,
218
+ applies_to and action present. Rule saved as enforceable.
219
+ not: "AI-generated rules bypass validation or use a different code path"
220
+ - scenario: "Reading a behaviour resource with specific tier and strategy"
221
+ expected: |
222
+ Resource read: rosett-ai://behaviour/criticalthinking?tier=xdg
223
+ Returns the XDG user copy, ignoring project and packaged tiers.
224
+
225
+ Resource read: rosett-ai://behaviour/criticalthinking?strategy=deep_merge
226
+ Returns the deep-merged result across all tiers (only in hybrid/per_request mode).
227
+ not: "Tier parameter ignored, or strategy override works in global-only mode"
228
+ - scenario: "raictl init --global sets up MCP auto-discovery"
229
+ expected: |
230
+ $ raictl init --global
231
+ Setting up global rosett-ai structure...
232
+ Created ~/.config/rosett-ai/conf/behaviour/
233
+ Created ~/.config/rosett-ai/mcp/
234
+ Registered rosett-ai MCP server in ~/.claude/settings.json
235
+ -> AI clients will auto-discover rosett-ai tools on next session start
236
+ not: "User must manually edit settings.json to register the MCP server"
237
+ - scenario: "Mutation tool requires confirmation and backup"
238
+ expected: |
239
+ AI client calls rai_compile with simulate: false.
240
+ Instructions field has told the AI client: "Present the action to the
241
+ user and ask for confirmation before executing mutation tools."
242
+ AI asks user: "Compile will write 12 rule files to ~/.claude/rules/. Proceed?"
243
+ User confirms.
244
+ Auto-backup snapshots ~/.claude/rules/ before compilation.
245
+ Compilation proceeds. Response includes backup path for rollback.
246
+ not: "Mutation executes without user awareness, or backup is skipped"
247
+ #
248
+ anti_patterns:
249
+ - "Implementing custom JSON-RPC handling instead of using the mcp gem"
250
+ - "Exposing file system paths outside whitelisted directories as MCP resources"
251
+ - "Making MCP tools that perform side effects without accurate annotations"
252
+ - "Running MCP server over HTTP without explicit user opt-in"
253
+ - "Storing MCP server credentials in plaintext configuration files"
254
+ - "Coupling MCP tool implementation to Claude Code specific features"
255
+ - "Using MCP sampling (server-initiated LLM calls) without explicit user consent"
256
+ - "Generating enforcement hooks for rules that fail EnforcementValidator"
257
+ - "Allowing AI-assisted rule creation to bypass EnforcementValidator"
258
+ - "Documenting tools that do not exist or do not work as described"
259
+ - "Shipping PARTIAL or STUB tools as Supported without fixing them first"
260
+ - "Skipping auto-backup before mutation tool execution"
261
+ - "Per-request strategy override on mutation tools in hybrid mode"
262
+ - "Hardcoding paths in MCP tools instead of using PathResolver"
263
+ - "Caching tool responses across MCP sessions — always read fresh from disk"
264
+ - "Loading the full compilation pipeline just to list behaviours"
265
+ #
266
+ gui_notes: |
267
+ ## Tool Catalog
268
+
269
+ ### Category: Discovery (read-only)
270
+
271
+ | Tool | Description | Status | Annotations |
272
+ |------|-------------|--------|-------------|
273
+ | rai_behaviour_list | List behaviours with metadata, scope, source tier | SHIPPING | readOnly=true |
274
+ | rai_behaviour_show | Return full content of a named behaviour | SHIPPING | readOnly=true |
275
+ | rai_behaviour_display | Display behaviour configuration table | SHIPPING | readOnly=true |
276
+ | rai_design_list | List design documents with metadata | SHIPPING | readOnly=true |
277
+ | rai_design_show | Return full content of a design document | SHIPPING | readOnly=true |
278
+ | rai_rule_search | Keyword search across rules with filters | PLANNED (W6-03) | readOnly=true |
279
+ | rai_schema_get | Return JSON Schema content | PLANNED (W6-03) | readOnly=true |
280
+ | rai_compile_status | Per-file staleness check | PLANNED (W6-03) | readOnly=true |
281
+
282
+ ### Category: Enforcement (new)
283
+
284
+ | Tool | Description | Status | Annotations |
285
+ |------|-------------|--------|-------------|
286
+ | rai_hook_preview | Show generated hook script for inspection | PLANNED (W6-03) | readOnly=true |
287
+ | rai_hook_install | Generate + write + register enforcement hook | PLANNED (W6-03) | readOnly=false, destructive=false |
288
+ | rai_context_query | Return applicable rules for a context | PLANNED (W6-03) | readOnly=true |
289
+
290
+ ### Category: Management (mutation)
291
+
292
+ | Tool | Description | Status | Annotations |
293
+ |------|-------------|--------|-------------|
294
+ | rai_behaviour_manage | Add/modify/delete behaviours | SHIPPING | readOnly=false |
295
+ | rai_compile | Compile rules to target format | FIX REQUIRED (W6-02) | readOnly=false |
296
+ | rai_config_compile | Compile YAML scopes to JSON settings | SHIPPING | readOnly=false |
297
+ | rai_validate | Validate config files with schema check | FIX REQUIRED (W6-02) | readOnly=true |
298
+ | rai_init | Set up global/local/project structure | SHIPPING | readOnly=false |
299
+ | rai_backup | Back up configuration scopes | SHIPPING | readOnly=false |
300
+
301
+ ### Category: Compliance
302
+
303
+ | Tool | Description | Status | Annotations |
304
+ |------|-------------|--------|-------------|
305
+ | rai_comply | Run compliance checks (CRA, license, SPDX) | SHIPPING | readOnly=true |
306
+ | rai_provenance | Show provenance entries (log, show) | SHIPPING | readOnly=true |
307
+ | rai_provenance_init | Create .ai-provenance.yml | SHIPPING | readOnly=false |
308
+
309
+ ### Category: Operations
310
+
311
+ | Tool | Description | Status | Annotations |
312
+ |------|-------------|--------|-------------|
313
+ | rai_doctor | Run diagnostic checks | SHIPPING | readOnly=true |
314
+ | rai_project | Show project status and info | FIX REQUIRED (W6-02) | readOnly=true |
315
+ | rosett_ai_engines | List/detect/status of engines | FIX REQUIRED (W6-02) | readOnly=true |
316
+ | rai_hooks_status | Show git hook installation status | FIX REQUIRED (W6-02) | readOnly=true |
317
+ | rai_config_status | Show config scope status | FIX REQUIRED (W6-02) | readOnly=true |
318
+ | rai_documentation_status | Show documentation file status | SHIPPING | readOnly=true |
319
+ | rai_license_status | Show license status | SHIPPING | readOnly=true |
320
+ | rai_adopt | Analyze rules for adoption | SHIPPING | readOnly=true |
321
+ | rai_content | List/install/update content packs | SHIPPING | readOnly=false (install/update) |
322
+ | rai_retrofit | Scan/convert native configs | SHIPPING | readOnly=true (scan), readOnly=false (convert) |
323
+ | rai_tooling | Validate CI YAML, check versions | SHIPPING | readOnly=true |
324
+ | rai_workflow | List/validate/simulate workflows | SHIPPING | readOnly=true |
325
+ | rai_workflow_execute | Execute a named workflow | SHIPPING | readOnly=false |
326
+
327
+ ## Resource Catalog
328
+
329
+ | URI Pattern | Content Type | Description | Status |
330
+ |-------------|-------------|-------------|--------|
331
+ | rosett-ai://behaviour/{name} | application/x-yaml | Behaviour YAML via 3-tier lookup | SHIPPING |
332
+ | rosett-ai://design/{name} | application/x-yaml | Design document YAML | SHIPPING |
333
+ | rosett-ai://provenance/ | application/x-yaml | AI provenance entries | SHIPPING |
334
+ | rosett-ai://config/{scope} | application/json | Settings for a scope | FIX (W6-02) |
335
+ | rosett-ai://schema/{name} | application/json | JSON Schema content | PLANNED (W6-03) |
336
+ | rosett-ai://rules/{name} | text/markdown | Compiled rule content | PLANNED (W6-03) |
337
+ | rosett-ai://hooks/{scope} | text/x-ruby | Installed hook script | PLANNED (W6-03) |
338
+
339
+ Resource query parameters:
340
+ - ?tier=project|xdg|packaged — request specific tier (bypasses merge)
341
+ - ?strategy=first_wins|deep_merge|array_union — override merge strategy
342
+ (honoured only in hybrid/per_request resolution modes, read-only only)
343
+
344
+ ## Enforcement Pipeline
345
+
346
+ ### Behaviour Schema v1.3.0 — enforcement block (optional, backward-compatible)
347
+
348
+ ```yaml
349
+ rules:
350
+ - id: rule_022
351
+ description: "Never bypass git hooks"
352
+ priority: 90
353
+ enabled: true
354
+ enforcement: # NEW — optional
355
+ type: enforceable # enforceable | advisory | informational
356
+ pattern: "--no-verify|OVERCOMMIT_DISABLE"
357
+ applies_to: ["Bash"]
358
+ action: block # block | warn | inform
359
+ ```
360
+
361
+ If enforcement block is absent, the rule defaults to informational.
362
+
363
+ ### EnforcementValidator
364
+
365
+ Runs on ALL authoring paths (manual YAML editing and AI-assisted creation).
366
+ Checks when enforcement.type == enforceable:
367
+ 1. pattern is present and non-empty
368
+ 2. pattern compiles as valid Ruby Regexp
369
+ 3. pattern is not degenerate (rejects .*, .+, \s*, etc.)
370
+ 4. applies_to is present and non-empty
371
+ 5. action is one of: block, warn, inform
372
+
373
+ On failure: downgrade to advisory with warning. Never silently generate
374
+ a broken hook. Warning surfaces in rai_validate, rai_compile,
375
+ rai_hook_preview output.
376
+
377
+ ### Hook Generation Flow
378
+
379
+ 1. rai_hook_preview (read-only):
380
+ - Reads behaviours via Composer with configured merge strategy
381
+ - Filters to enforceable rules that pass EnforcementValidator
382
+ - Generates Ruby hook script with YARD docs and human header
383
+ - Returns script content as text — no side effects
384
+
385
+ 2. rai_hook_install (mutation, confirmation required):
386
+ - Runs rai_hook_preview internally
387
+ - Auto-backups target directory (configurable, default on)
388
+ - Writes hook script to scope-appropriate location:
389
+ - global: ~/.claude/hooks/rai-enforce-global.rb
390
+ - project: .claude/hooks/rai-enforce-project.rb
391
+ - personal: ~/.claude/hooks/rai-enforce-personal.rb
392
+ - Registers hook in settings.json PreToolUse section
393
+ - Returns: hook path, backup path, rules count, behaviours included
394
+
395
+ ### Hook Script Format
396
+
397
+ Generated Ruby script includes:
398
+ - PURPOSE: what the hook does
399
+ - INTENTION: user/auto-generated protection description
400
+ - TRIGGERED BY: source behaviours with version and rule counts
401
+ - GENERATED: timestamp, generator version, merge strategy, initiator (name + email)
402
+ - AI CLIENT INSTRUCTIONS: how AI should respond to blocks
403
+ - YARD @author, @since, @see tags
404
+ - Full YARD documentation on every constant, variable, and code block
405
+ - DO NOT EDIT MANUALLY warning with regeneration command
406
+ - Rules sorted by priority with full traceability (behaviour, rule_id, version)
407
+ - Exit codes: 0 = allow/warn, 1 = block
408
+
409
+ ### Hook Scope Merge (runtime)
410
+
411
+ When multiple scope hooks exist, they merge:
412
+ - project overrides global on same rule ID
413
+ - personal overrides both on same rule ID
414
+ - priority field is tiebreaker for different rule IDs
415
+
416
+ ## Mutation Safety Architecture
417
+
418
+ ### Confirmation
419
+
420
+ Default: required. Configurable in behaviour YAML:
421
+ ```yaml
422
+ mutation_confirmation: required # required | optional | disabled
423
+ ```
424
+
425
+ When required: instructions field tells AI clients to present the action
426
+ and ask user before executing. Hard enforcement possible via PreToolUse
427
+ hook that blocks mutation tool calls without confirmed: true parameter.
428
+
429
+ ### Auto-Backup
430
+
431
+ Default: on. Configurable. Before any mutation tool executes,
432
+ RosettAi::Backup::Manager snapshots the affected scope. Response includes
433
+ backup path for rollback.
434
+
435
+ ## Resolution Strategy
436
+
437
+ Configured in ~/.config/rosett-ai/mcp/server.yml:
438
+ ```yaml
439
+ resolution:
440
+ strategy: first_wins # first_wins | deep_merge | array_union
441
+ mode: hybrid # global | hybrid | per_request
442
+ ```
443
+
444
+ | Mode | Behaviour |
445
+ |------|-----------|
446
+ | global | Server config strategy everywhere, per-request ?strategy= ignored |
447
+ | hybrid (DEFAULT) | Server config for mutations, per-request override on read-only |
448
+ | per_request | Every call can specify strategy, server config is default |
449
+
450
+ Strategies mirror Hiera resolution:
451
+ - first_wins: highest-priority scope wins (Hiera first)
452
+ - deep_merge: recursive hash merge across scopes (Hiera deep)
453
+ - array_union: combine arrays, deduplicate (Hiera unique)
454
+
455
+ Implemented by existing Composition::MergeStrategy module.
456
+
457
+ ## File Layout
458
+
459
+ ```
460
+ lib/rosett_ai/mcp/
461
+ ├── server.rb # MCP server (EXISTING — add instructions:)
462
+ ├── governance.rb # Tool/resource registration (EXISTING)
463
+ ├── plugins.rb # Plugin discovery (EXISTING)
464
+ ├── instructions.md # Server instructions for auto-discovery (NEW)
465
+ ├── tools/
466
+ │ ├── [19 existing shipping tools]
467
+ │ ├── [6 existing tools to fix]
468
+ │ ├── rule_search_tool.rb # NEW — keyword search across rules
469
+ │ ├── schema_get_tool.rb # NEW — return JSON Schema content
470
+ │ ├── compile_status_tool.rb # NEW — per-file staleness
471
+ │ ├── hook_preview_tool.rb # NEW — preview generated hook
472
+ │ ├── hook_install_tool.rb # NEW — generate + install hook
473
+ │ └── context_query_tool.rb # NEW — applicable rules for context
474
+ ├── resources/
475
+ │ ├── behaviour_resource.rb # EXISTING — update to use PathResolver
476
+ │ ├── config_resource.rb # EXISTING — fix user scope bug
477
+ │ ├── design_resource.rb # EXISTING
478
+ │ ├── provenance_resource.rb # EXISTING
479
+ │ ├── schema_resource.rb # NEW
480
+ │ ├── rules_resource.rb # NEW
481
+ │ └── hooks_resource.rb # NEW
482
+ ├── enforcement/
483
+ │ ├── enforcement_validator.rb # NEW — validate enforcement blocks
484
+ │ ├── hook_generator.rb # NEW — YAML rules -> Ruby hook script
485
+ │ ├── hook_installer.rb # NEW — write + register hooks
486
+ │ └── pattern_denylist.rb # NEW — degenerate pattern detection
487
+ ├── middleware/ # EXISTING — HTTP security stack
488
+ │ ├── authentication.rb
489
+ │ ├── content_type.rb
490
+ │ ├── cors.rb
491
+ │ ├── origin_validation.rb
492
+ │ ├── rate_limit.rb
493
+ │ └── request_size.rb
494
+ ├── admin/ # EXISTING
495
+ │ ├── registry.rb
496
+ │ ├── health_checker.rb
497
+ │ ├── schema_validator.rb
498
+ │ └── auditor.rb
499
+ ├── keyfile.rb # EXISTING
500
+ ├── key_hasher.rb # EXISTING
501
+ └── http_security_config.rb # EXISTING
502
+ ```
503
+
504
+ ## Integration Points
505
+
506
+ | Component | Integration |
507
+ |-----------|-------------|
508
+ | PathResolver | All tools/resources use PathResolver for 3-tier file discovery |
509
+ | Composition::Composer | Resource handler uses Composer for merge strategy |
510
+ | Composition::MergeStrategy | Configurable: first_wins, deep_merge, array_union |
511
+ | Composition::ScopeResolver | Scope classification for rules |
512
+ | Behaviour::Manager | behaviour_manage tool delegates to Manager |
513
+ | Compiler::CompilationPipeline | rai_compile tool delegates to pipeline (after fix) |
514
+ | Backup::Manager | Auto-backup before mutation tools |
515
+ | Validators::BehaviourValidator | Schema validation in rai_validate (after fix) |
516
+ | Validators::EnforcementValidator | NEW — validates enforcement blocks |
517
+ | Init::GlobalInitializer | Auto-registers MCP server in settings.json |
518
+
519
+ ## Test Strategy
520
+
521
+ Unit tests:
522
+ - EnforcementValidator: valid patterns, degenerate patterns, missing fields, downgrade
523
+ - HookGenerator: template rendering, rule sorting, YARD output, header fields
524
+ - HookInstaller: backup creation, file write, settings.json registration
525
+ - PatternDenylist: degenerate pattern detection
526
+ - Each new tool: input validation, delegation, error handling, response structure
527
+
528
+ Integration tests:
529
+ - MCP protocol handshake (stdio transport)
530
+ - Tool execution via JSON-RPC (all 25+ tools)
531
+ - Resource retrieval via JSON-RPC (all 7 URI patterns)
532
+ - Instructions field present in server capabilities
533
+ - Enforcement round-trip: create rule -> preview hook -> install hook -> trigger block
534
+ - Resolution mode: verify hybrid blocks strategy override on mutations
535
+ - Mutation safety: verify backup created before write
536
+
537
+ Kitchen (packaging):
538
+ - Build .deb from source in clean VM with documented minimal dependencies
539
+ - Install .deb, verify raictl mcp serve starts
540
+ - Verify raictl mcp tools lists all expected tools
541
+ - Verify tool execution from installed package
542
+ - Atomic build: build succeeds or fails completely
543
+
544
+ ## Implementation Phases
545
+
546
+ ### W6-02: Fix + Instructions (prerequisites)
547
+ - Fix rai_compile stub (delegate to CompilationPipeline)
548
+ - Fix rai_validate (add JSON Schema validation)
549
+ - Fix rai_project (read from gemspec/config)
550
+ - Fix rai_hooks_status (fix phase filter)
551
+ - Fix rosett_ai_engines (surface errors)
552
+ - Fix rai_config_status (surface errors)
553
+ - Fix config_resource.rb user scope bug
554
+ - Implement instructions field in server.rb build_server
555
+ - Write lib/rosett_ai/mcp/instructions.md
556
+ - Update raictl init --global to auto-register MCP server
557
+ - All fixed tools pass integration tests
558
+
559
+ ### W6-03: Asset Discovery + Enforcement Pipeline
560
+ - Build rai_rule_search tool
561
+ - Build rai_schema_get tool
562
+ - Build rai_compile_status tool
563
+ - Build EnforcementValidator
564
+ - Build HookGenerator
565
+ - Build rai_hook_preview tool
566
+ - Build rai_hook_install tool (with backup integration)
567
+ - Build rai_context_query tool
568
+ - Update behaviour_resource.rb to use PathResolver + Composer
569
+ - Build schema_resource.rb, rules_resource.rb, hooks_resource.rb
570
+ - Update behaviour schema to v1.3.0 (add enforcement block)
571
+ - PatternDenylist for degenerate pattern detection
572
+
573
+ ### W6-04: Resolution + Mutation Safety
574
+ - Implement resolution mode config (global/hybrid/per_request)
575
+ - Wire resolution mode into resource handlers and mutation tools
576
+ - Implement mutation confirmation flow (instructions + optional hard enforcement)
577
+ - Implement auto-backup before mutation
578
+ - Integration tests for resolution modes
579
+ - Integration tests for mutation safety
580
+
581
+ ### W6-05: Packaging + Documentation
582
+ - Verify BUNDLE_WITHOUT does not exclude mcp group
583
+ - Kitchen test: build .deb from source in clean VM
584
+ - Kitchen test: raictl mcp serve from installed package
585
+ - Developer build documentation (minimal dependencies, reproducible build)
586
+ - YARD documentation audit on all new MCP code
587
+ - End-to-end enforcement round-trip test (kitchen)
588
+ #
589
+ preferences:
590
+ language: ruby
591
+ patterns:
592
+ - "Service object per tool (RosettAi::Mcp::Tools::RuleSearchTool, etc.)"
593
+ - "PathResolver for all path discovery — never hardcode paths in tools"
594
+ - "Struct or Data for response objects — not raw hashes"
595
+ - "Composition::Composer for all multi-tier resolution"
596
+ - "EnforcementValidator as single validation gate for both authoring paths"
597
+ - "YARD documentation on all new public methods and classes"
598
+ testing: rspec with MCP protocol integration tests, tool response schema
599
+ validation, enforcement round-trip tests, resolution mode verification,
600
+ mutation safety tests, kitchen packaging tests
601
+ gems:
602
+ - mcp
603
+ - json_schemer
604
+ - thor
605
+ - zeitwerk