rosett-ai 1.3.3 → 1.5.10

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 (453) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +413 -22
  3. data/README.md +56 -42
  4. data/bin/raictl +13 -0
  5. data/conf/adopt_redactions.yml +2 -0
  6. data/conf/compliance/cra_rules.yml +2 -0
  7. data/conf/compliance/license_rules.yml +2 -0
  8. data/conf/mcp/server_defaults.yml +2 -0
  9. data/conf/mcp/trust.yml +1 -0
  10. data/conf/packaging/core.yml +2 -0
  11. data/conf/packaging/gtk4.yml +2 -0
  12. data/conf/packaging/qt6.yml +2 -0
  13. data/conf/policy/default_deny_list.yml +2 -0
  14. data/conf/review/cli-command-audit.yml +2 -0
  15. data/conf/review/design-docs.yml +2 -0
  16. data/conf/review/design-questionnaire.yml +2 -0
  17. data/conf/review/questionnaire.yml +2 -0
  18. data/conf/review/rosett-ai-core.yml +2 -0
  19. data/conf/schemas/ai_config_schema.json +14 -2
  20. data/conf/schemas/autoqueue.schema.json +153 -0
  21. data/conf/schemas/behaviour_schema.json +31 -7
  22. data/conf/schemas/compliance_rule_schema.json +17 -4
  23. data/conf/schemas/content_pack_manifest_schema.json +23 -4
  24. data/conf/schemas/design_schema.json +177 -42
  25. data/conf/schemas/engine_manifest_schema.json +22 -5
  26. data/conf/schemas/lockfile_schema.json +26 -4
  27. data/conf/schemas/mcp_server_schema.json +50 -9
  28. data/conf/schemas/packaging_schema.json +23 -5
  29. data/conf/schemas/policy_schema.json +35 -9
  30. data/conf/schemas/provenance_schema.json +33 -5
  31. data/conf/schemas/rai_config_schema.json +6 -2
  32. data/conf/schemas/rai_project_schema.json +8 -2
  33. data/conf/schemas/scope_hierarchy_schema.json +22 -5
  34. data/conf/schemas/target_schema.json +33 -6
  35. data/conf/schemas/tooling_schema.json +53 -12
  36. data/conf/schemas/workflow_schema.json +39 -9
  37. data/conf/targets/agents_md.yml +1 -0
  38. data/conf/targets/claude.yml +2 -0
  39. data/conf/tooling/tools.yml +2 -0
  40. data/lib/rosett_ai/adopter/local_analysis_collector.rb +5 -0
  41. data/lib/rosett_ai/adopter/rule_adopter.rb +40 -0
  42. data/lib/rosett_ai/ai_config/context_window.rb +3 -0
  43. data/lib/rosett_ai/ai_config/cost_controls.rb +1 -0
  44. data/lib/rosett_ai/ai_config/fallback_chain.rb +1 -0
  45. data/lib/rosett_ai/ai_config/model_router.rb +1 -0
  46. data/lib/rosett_ai/ai_config/validator.rb +2 -0
  47. data/lib/rosett_ai/authorship/attribution_compiler.rb +1 -0
  48. data/lib/rosett_ai/authorship/disclosure_policy.rb +2 -0
  49. data/lib/rosett_ai/authorship/review_validator.rb +1 -0
  50. data/lib/rosett_ai/authorship/trailer_generator.rb +1 -0
  51. data/lib/rosett_ai/backup/compressor.rb +3 -0
  52. data/lib/rosett_ai/backup/destination.rb +1 -0
  53. data/lib/rosett_ai/behaviour/manager.rb +1 -0
  54. data/lib/rosett_ai/compiler/backend.rb +3 -0
  55. data/lib/rosett_ai/compiler/backends/agents_md_backend.rb +1 -0
  56. data/lib/rosett_ai/compiler/backends/claude_backend.rb +1 -0
  57. data/lib/rosett_ai/compiler/behaviour_compiler.rb +1 -0
  58. data/lib/rosett_ai/compiler/compilation_pipeline.rb +1 -7
  59. data/lib/rosett_ai/compiler/locale_compiler.rb +2 -0
  60. data/lib/rosett_ai/compiler/target_profile.rb +11 -0
  61. data/lib/rosett_ai/completion/generator.rb +2 -0
  62. data/lib/rosett_ai/completion/shells/zsh_generator.rb +1 -0
  63. data/lib/rosett_ai/comply/checkers/cra_checker.rb +1 -0
  64. data/lib/rosett_ai/comply/checkers/license_checker.rb +2 -0
  65. data/lib/rosett_ai/comply/checkers/spdx_header_checker.rb +4 -0
  66. data/lib/rosett_ai/comply/runner.rb +2 -0
  67. data/lib/rosett_ai/composition/composer.rb +1 -0
  68. data/lib/rosett_ai/composition/lockfile.rb +1 -0
  69. data/lib/rosett_ai/composition/merge_strategy.rb +1 -0
  70. data/lib/rosett_ai/config/masking_secret_resolver.rb +9 -0
  71. data/lib/rosett_ai/config/secret_resolver.rb +4 -0
  72. data/lib/rosett_ai/configuration.rb +4 -0
  73. data/lib/rosett_ai/content/content_client.rb +15 -0
  74. data/lib/rosett_ai/content/pack_installer.rb +1 -0
  75. data/lib/rosett_ai/content/pack_manifest.rb +21 -0
  76. data/lib/rosett_ai/content_packs/manager.rb +1 -0
  77. data/lib/rosett_ai/dbus/compositor_detector.rb +2 -0
  78. data/lib/rosett_ai/dbus/focus_adapters/base.rb +1 -0
  79. data/lib/rosett_ai/dbus/focus_adapters/gnome_adapter.rb +5 -0
  80. data/lib/rosett_ai/dbus/focus_adapters/hyprland_adapter.rb +4 -0
  81. data/lib/rosett_ai/dbus/focus_adapters/i3_adapter.rb +4 -0
  82. data/lib/rosett_ai/dbus/focus_adapters/kwin_adapter.rb +4 -0
  83. data/lib/rosett_ai/dbus/focus_adapters/x11_adapter.rb +4 -0
  84. data/lib/rosett_ai/dbus/focus_monitor_interface.rb +1 -0
  85. data/lib/rosett_ai/dbus/manager_interface.rb +1 -0
  86. data/lib/rosett_ai/dbus/plugin_manager_interface.rb +2 -0
  87. data/lib/rosett_ai/dbus/rate_limiter.rb +1 -0
  88. data/lib/rosett_ai/dbus/service.rb +3 -0
  89. data/lib/rosett_ai/dbus/status_notifier_interface.rb +14 -0
  90. data/lib/rosett_ai/desktop/dbus_client.rb +6 -0
  91. data/lib/rosett_ai/desktop/gtk4_app.rb +3 -0
  92. data/lib/rosett_ai/desktop/gtk4_preferences.rb +1 -0
  93. data/lib/rosett_ai/desktop/gui_logger.rb +2 -0
  94. data/lib/rosett_ai/doctor/check.rb +1 -1
  95. data/lib/rosett_ai/doctor/checks/cache_health_check.rb +1 -0
  96. data/lib/rosett_ai/doctor.rb +1 -0
  97. data/lib/rosett_ai/documentation/reference_compiler.rb +9 -0
  98. data/lib/rosett_ai/documentation/translator.rb +8 -0
  99. data/lib/rosett_ai/engines/base_config_compiler.rb +71 -1
  100. data/lib/rosett_ai/engines/detector.rb +5 -0
  101. data/lib/rosett_ai/engines/registry.rb +7 -0
  102. data/lib/rosett_ai/exit_codes.rb +6 -0
  103. data/lib/rosett_ai/formatting.rb +1 -0
  104. data/lib/rosett_ai/gem_consistency_checker.rb +6 -0
  105. data/lib/rosett_ai/git_hooks/chain_detector.rb +1 -0
  106. data/lib/rosett_ai/git_hooks/installer.rb +4 -0
  107. data/lib/rosett_ai/git_hooks/script_generator.rb +2 -0
  108. data/lib/rosett_ai/gitlab/validators/supplementary_gitlab_ci_yaml_validator.rb +6 -0
  109. data/lib/rosett_ai/i18n/utf8_checker.rb +1 -0
  110. data/lib/rosett_ai/init/config_file_writer.rb +4 -0
  111. data/lib/rosett_ai/init/directory_builder.rb +15 -0
  112. data/lib/rosett_ai/init/file_copier.rb +51 -0
  113. data/lib/rosett_ai/init/mcp_registrar.rb +1 -0
  114. data/lib/rosett_ai/init/project_initializer.rb +1 -0
  115. data/lib/rosett_ai/licensing/license_key.rb +4 -0
  116. data/lib/rosett_ai/licensing/license_store.rb +11 -0
  117. data/lib/rosett_ai/licensing/tier.rb +9 -0
  118. data/lib/rosett_ai/mcp/admin/auditor.rb +1 -0
  119. data/lib/rosett_ai/mcp/admin/health_checker.rb +1 -0
  120. data/lib/rosett_ai/mcp/admin/registry.rb +1 -0
  121. data/lib/rosett_ai/mcp/enforcement/hook_generator.rb +27 -4
  122. data/lib/rosett_ai/mcp/enforcement/validator.rb +24 -3
  123. data/lib/rosett_ai/mcp/governance.rb +9 -0
  124. data/lib/rosett_ai/mcp/http_security_config.rb +22 -0
  125. data/lib/rosett_ai/mcp/key_hasher.rb +4 -2
  126. data/lib/rosett_ai/mcp/keyfile.rb +4 -0
  127. data/lib/rosett_ai/mcp/middleware/cors.rb +4 -0
  128. data/lib/rosett_ai/mcp/middleware/origin_validation.rb +1 -0
  129. data/lib/rosett_ai/mcp/middleware/rate_limit.rb +3 -0
  130. data/lib/rosett_ai/mcp/plugins.rb +1 -0
  131. data/lib/rosett_ai/mcp/prompts/compilation_prompt.rb +2 -0
  132. data/lib/rosett_ai/mcp/prompts/compliance_prompt.rb +3 -0
  133. data/lib/rosett_ai/mcp/prompts/diagnostics_prompt.rb +2 -0
  134. data/lib/rosett_ai/mcp/prompts/validation_prompt.rb +2 -0
  135. data/lib/rosett_ai/mcp/resources/behaviour_resource.rb +2 -0
  136. data/lib/rosett_ai/mcp/resources/config_resource.rb +2 -0
  137. data/lib/rosett_ai/mcp/resources/design_resource.rb +1 -0
  138. data/lib/rosett_ai/mcp/resources/hooks_resource.rb +3 -0
  139. data/lib/rosett_ai/mcp/resources/provenance_resource.rb +2 -0
  140. data/lib/rosett_ai/mcp/resources/rules_resource.rb +1 -0
  141. data/lib/rosett_ai/mcp/resources/schema_resource.rb +1 -0
  142. data/lib/rosett_ai/mcp/server.rb +7 -1
  143. data/lib/rosett_ai/mcp/settings/trust_manager.rb +3 -0
  144. data/lib/rosett_ai/mcp/tools/adopt_tool.rb +4 -0
  145. data/lib/rosett_ai/mcp/tools/backup_tool.rb +4 -0
  146. data/lib/rosett_ai/mcp/tools/behaviour_display_tool.rb +4 -0
  147. data/lib/rosett_ai/mcp/tools/behaviour_list_tool.rb +3 -0
  148. data/lib/rosett_ai/mcp/tools/behaviour_manage_tool.rb +5 -0
  149. data/lib/rosett_ai/mcp/tools/behaviour_show_tool.rb +4 -0
  150. data/lib/rosett_ai/mcp/tools/compile_status_tool.rb +4 -0
  151. data/lib/rosett_ai/mcp/tools/compile_tool.rb +4 -0
  152. data/lib/rosett_ai/mcp/tools/comply_tool.rb +4 -0
  153. data/lib/rosett_ai/mcp/tools/config_compile_tool.rb +4 -0
  154. data/lib/rosett_ai/mcp/tools/config_status_tool.rb +3 -0
  155. data/lib/rosett_ai/mcp/tools/content_tool.rb +5 -0
  156. data/lib/rosett_ai/mcp/tools/context_query_tool.rb +4 -0
  157. data/lib/rosett_ai/mcp/tools/design_list_tool.rb +3 -0
  158. data/lib/rosett_ai/mcp/tools/design_show_tool.rb +4 -0
  159. data/lib/rosett_ai/mcp/tools/doctor_tool.rb +4 -0
  160. data/lib/rosett_ai/mcp/tools/documentation_status_tool.rb +3 -0
  161. data/lib/rosett_ai/mcp/tools/engines_tool.rb +5 -0
  162. data/lib/rosett_ai/mcp/tools/hook_install_tool.rb +7 -0
  163. data/lib/rosett_ai/mcp/tools/hook_preview_tool.rb +33 -8
  164. data/lib/rosett_ai/mcp/tools/hooks_status_tool.rb +5 -0
  165. data/lib/rosett_ai/mcp/tools/init_tool.rb +5 -0
  166. data/lib/rosett_ai/mcp/tools/license_status_tool.rb +3 -0
  167. data/lib/rosett_ai/mcp/tools/project_tool.rb +5 -0
  168. data/lib/rosett_ai/mcp/tools/provenance_tool.rb +5 -0
  169. data/lib/rosett_ai/mcp/tools/provenance_write_tool.rb +3 -0
  170. data/lib/rosett_ai/mcp/tools/retrofit_tool.rb +5 -0
  171. data/lib/rosett_ai/mcp/tools/rule_search_tool.rb +4 -0
  172. data/lib/rosett_ai/mcp/tools/schema_get_tool.rb +5 -0
  173. data/lib/rosett_ai/mcp/tools/tooling_tool.rb +5 -0
  174. data/lib/rosett_ai/mcp/tools/validate_tool.rb +4 -0
  175. data/lib/rosett_ai/mcp/tools/workflow_execute_tool.rb +4 -0
  176. data/lib/rosett_ai/mcp/tools/workflow_tool.rb +5 -0
  177. data/lib/rosett_ai/migration/detector.rb +1 -0
  178. data/lib/rosett_ai/migration/nncc_config_migrator.rb +2 -0
  179. data/lib/rosett_ai/migration/xdg_migrator.rb +3 -1
  180. data/lib/rosett_ai/package_manager/apt.rb +5 -0
  181. data/lib/rosett_ai/package_manager/base.rb +1 -0
  182. data/lib/rosett_ai/package_manager/gem_backend.rb +1 -0
  183. data/lib/rosett_ai/packaging/variant_config.rb +12 -0
  184. data/lib/rosett_ai/plugins/contract.rb +1 -0
  185. data/lib/rosett_ai/plugins/engine_contract.rb +2 -0
  186. data/lib/rosett_ai/plugins/gui_contract.rb +2 -0
  187. data/lib/rosett_ai/plugins/mcp_contract.rb +2 -0
  188. data/lib/rosett_ai/plugins/registry.rb +10 -0
  189. data/lib/rosett_ai/policy/auditor.rb +1 -0
  190. data/lib/rosett_ai/policy/opt_out_scanner.rb +1 -0
  191. data/lib/rosett_ai/policy/tier_hierarchy.rb +2 -0
  192. data/lib/rosett_ai/policy/validator.rb +1 -0
  193. data/lib/rosett_ai/profiler.rb +7 -0
  194. data/lib/rosett_ai/project/drift_detector.rb +1 -0
  195. data/lib/rosett_ai/project/manager.rb +1 -0
  196. data/lib/rosett_ai/project/template_applier.rb +1 -0
  197. data/lib/rosett_ai/provenance/entry.rb +2 -0
  198. data/lib/rosett_ai/provenance/source.rb +1 -0
  199. data/lib/rosett_ai/provenance/store.rb +3 -0
  200. data/lib/rosett_ai/provenance/validator.rb +1 -0
  201. data/lib/rosett_ai/quorum/collector.rb +1 -0
  202. data/lib/rosett_ai/quorum/comparator.rb +2 -0
  203. data/lib/rosett_ai/quorum/strategies/adopt.rb +1 -0
  204. data/lib/rosett_ai/rai_config.rb +9 -0
  205. data/lib/rosett_ai/retrofit/engine.rb +2 -0
  206. data/lib/rosett_ai/retrofit/parsers/agents_md_parser.rb +8 -0
  207. data/lib/rosett_ai/retrofit/parsers/claude_parser.rb +10 -0
  208. data/lib/rosett_ai/retrofit/parsers/cursor_parser.rb +9 -0
  209. data/lib/rosett_ai/retrofit/secret_detector.rb +3 -0
  210. data/lib/rosett_ai/secrets_resolver.rb +1 -0
  211. data/lib/rosett_ai/session_hooks/installer.rb +130 -0
  212. data/lib/rosett_ai/smart_feedback/suggester.rb +4 -0
  213. data/lib/rosett_ai/smart_feedback/thor_middleware.rb +7 -0
  214. data/lib/rosett_ai/structured_logger.rb +1 -0
  215. data/lib/rosett_ai/telemetry/log_rotator.rb +1 -0
  216. data/lib/rosett_ai/telemetry.rb +1 -0
  217. data/lib/rosett_ai/thor/cli.rb +9 -0
  218. data/lib/rosett_ai/thor/tasks/adopt.rb +2 -0
  219. data/lib/rosett_ai/thor/tasks/backfill_user_yml.rb +207 -0
  220. data/lib/rosett_ai/thor/tasks/backup.rb +6 -0
  221. data/lib/rosett_ai/thor/tasks/behaviour.rb +12 -0
  222. data/lib/rosett_ai/thor/tasks/build.rb +106 -21
  223. data/lib/rosett_ai/thor/tasks/compile.rb +76 -32
  224. data/lib/rosett_ai/thor/tasks/completion.rb +9 -0
  225. data/lib/rosett_ai/thor/tasks/comply.rb +2 -0
  226. data/lib/rosett_ai/thor/tasks/config.rb +21 -5
  227. data/lib/rosett_ai/thor/tasks/content.rb +8 -0
  228. data/lib/rosett_ai/thor/tasks/dbus.rb +13 -0
  229. data/lib/rosett_ai/thor/tasks/design.rb +2 -0
  230. data/lib/rosett_ai/thor/tasks/desktop.rb +4 -0
  231. data/lib/rosett_ai/thor/tasks/doctor.rb +2 -0
  232. data/lib/rosett_ai/thor/tasks/documentation.rb +7 -0
  233. data/lib/rosett_ai/thor/tasks/engines.rb +8 -0
  234. data/lib/rosett_ai/thor/tasks/hooks.rb +8 -0
  235. data/lib/rosett_ai/thor/tasks/init.rb +1 -0
  236. data/lib/rosett_ai/thor/tasks/license.rb +8 -0
  237. data/lib/rosett_ai/thor/tasks/mcp.rb +40 -0
  238. data/lib/rosett_ai/thor/tasks/migrate.rb +2 -0
  239. data/lib/rosett_ai/thor/tasks/plugins.rb +15 -0
  240. data/lib/rosett_ai/thor/tasks/project.rb +8 -0
  241. data/lib/rosett_ai/thor/tasks/provenance.rb +8 -0
  242. data/lib/rosett_ai/thor/tasks/release.rb +8 -0
  243. data/lib/rosett_ai/thor/tasks/retrofit.rb +4 -0
  244. data/lib/rosett_ai/thor/tasks/validate.rb +1 -0
  245. data/lib/rosett_ai/thor/tasks/workflow.rb +14 -0
  246. data/lib/rosett_ai/tooling/version_checker.rb +1 -0
  247. data/lib/rosett_ai/ui/accessible_tui.rb +18 -0
  248. data/lib/rosett_ai/ui/base.rb +3 -0
  249. data/lib/rosett_ai/ui/gtk4.rb +19 -0
  250. data/lib/rosett_ai/ui/kde.rb +1 -0
  251. data/lib/rosett_ai/ui/qt6.rb +1 -0
  252. data/lib/rosett_ai/ui/registry.rb +15 -0
  253. data/lib/rosett_ai/ui/tui.rb +22 -0
  254. data/lib/rosett_ai/validators/behaviour_validator.rb +1 -0
  255. data/lib/rosett_ai/validators/design_validator.rb +2 -0
  256. data/lib/rosett_ai/validators/schema_validator.rb +4 -0
  257. data/lib/rosett_ai/validators/tooling_validator.rb +1 -0
  258. data/lib/rosett_ai/version.rb +2 -1
  259. data/lib/rosett_ai/version_consistency_checker.rb +6 -0
  260. data/lib/rosett_ai/workflow/engine.rb +1 -0
  261. data/lib/rosett_ai/workflow/manager.rb +1 -0
  262. data/lib/rosett_ai/workflow/schema_validator.rb +2 -0
  263. data/lib/rosett_ai/workflow/step_runner.rb +1 -0
  264. data/lib/rosett_ai/workflow/steps/rai_step.rb +1 -0
  265. data/lib/rosett_ai/yaml_loader.rb +2 -0
  266. data/lib/rosett_ai.rb +2 -0
  267. data/lib/scripts/generated/docker_hub_tags.rb +2 -0
  268. data/locales/ar.yml +2 -0
  269. data/locales/en.yml +5 -0
  270. data/locales/fr.yml +2 -0
  271. metadata +9 -189
  272. data/.ai-provenance.yml +0 -119
  273. data/.debride_whitelist +0 -186
  274. data/.fasterer.yml +0 -29
  275. data/.mdl_style.rb +0 -10
  276. data/.mdlrc +0 -3
  277. data/.mutant.yml +0 -49
  278. data/.namespace-allowlist +0 -42
  279. data/.reek.yml +0 -1040
  280. data/.rosett-ai/config.yml +0 -3
  281. data/.rspec +0 -5
  282. data/.rubocop.yml +0 -380
  283. data/.ruby-version +0 -1
  284. data/.yamllint +0 -51
  285. data/.yardopts +0 -12
  286. data/AI-DISCLOSURE.md +0 -48
  287. data/CLAUDE.md +0 -141
  288. data/CONTRIBUTING.md +0 -734
  289. data/INSTALL.md +0 -154
  290. data/LICENSE.md +0 -675
  291. data/QUICKSTART.md +0 -73
  292. data/Rakefile +0 -200
  293. data/SECURITY.md +0 -114
  294. data/cliff.toml +0 -52
  295. data/conf/behaviour/.gitkeep +0 -0
  296. data/conf/design/aaif_alignment.yml +0 -181
  297. data/conf/design/ab_testing.yml +0 -172
  298. data/conf/design/accessibility.yml +0 -84
  299. data/conf/design/ai_authorship.yml +0 -210
  300. data/conf/design/ai_provenance.yml +0 -224
  301. data/conf/design/ai_tool_configuration.yml +0 -207
  302. data/conf/design/architecture.yml +0 -139
  303. data/conf/design/autocompletion.yml +0 -115
  304. data/conf/design/backward_compatibility.yml +0 -112
  305. data/conf/design/behaviour_composition.yml +0 -246
  306. data/conf/design/build_rake_extraction.yml +0 -57
  307. data/conf/design/ci_pipeline.yml +0 -100
  308. data/conf/design/claude_code_configuration.yml +0 -157
  309. data/conf/design/compiler.yml +0 -128
  310. data/conf/design/comply.yml +0 -153
  311. data/conf/design/content_packs.yml +0 -84
  312. data/conf/design/desktop_integration.yml +0 -289
  313. data/conf/design/distribution.yml +0 -216
  314. data/conf/design/doctor.yml +0 -184
  315. data/conf/design/documentation.yml +0 -152
  316. data/conf/design/engine_architecture.yml +0 -257
  317. data/conf/design/error_handling.yml +0 -103
  318. data/conf/design/feature_flags.yml +0 -142
  319. data/conf/design/git_hooks.yml +0 -165
  320. data/conf/design/gui_plugins.yml +0 -475
  321. data/conf/design/i18n.yml +0 -84
  322. data/conf/design/integration_testing.yml +0 -56
  323. data/conf/design/licensing_system.yml +0 -88
  324. data/conf/design/lifecycle_management.yml +0 -208
  325. data/conf/design/mcp_integration.yml +0 -207
  326. data/conf/design/mcp_settings.yml +0 -126
  327. data/conf/design/migration.yml +0 -56
  328. data/conf/design/monitoring_observability.yml +0 -194
  329. data/conf/design/namespace_cleanup.yml +0 -145
  330. data/conf/design/plugin_test_segregation.yml +0 -145
  331. data/conf/design/policy_management.yml +0 -229
  332. data/conf/design/project_management.yml +0 -183
  333. data/conf/design/rai_mcp_asset_discovery.yml +0 -164
  334. data/conf/design/rai_mcp_server.yml +0 -605
  335. data/conf/design/release_management.yml +0 -117
  336. data/conf/design/retrofit.yml +0 -199
  337. data/conf/design/retrospective_analyzer.yml +0 -79
  338. data/conf/design/scope_hierarchy.yml +0 -352
  339. data/conf/design/security.yml +0 -115
  340. data/conf/design/session_retrospective.yml +0 -85
  341. data/conf/design/smart_ui_feedback.yml +0 -89
  342. data/conf/design/structured_logging.yml +0 -148
  343. data/conf/design/styles.yml +0 -123
  344. data/conf/design/test_peer_review.yml +0 -89
  345. data/conf/design/testing.yml +0 -136
  346. data/conf/design/threat_model.yml +0 -108
  347. data/conf/design/ui_framework.yml +0 -111
  348. data/conf/design/usage_optimization.yml +0 -122
  349. data/conf/design/version_management.yml +0 -60
  350. data/conf/design/workflow.yml +0 -227
  351. data/doc/AAIF_POSITIONING.md +0 -58
  352. data/doc/ADOPT.md +0 -224
  353. data/doc/AI_PROVENANCE.md +0 -139
  354. data/doc/ARCHITECTURE.md +0 -920
  355. data/doc/BEHAVIOUR.md +0 -409
  356. data/doc/BUILD.md +0 -138
  357. data/doc/CI_CD_RECIPES.md +0 -171
  358. data/doc/CLAUDE_SESSIONS_MOVED.md +0 -16
  359. data/doc/COMMAND_ANALYSIS.md +0 -229
  360. data/doc/CONFIGURATION.md +0 -281
  361. data/doc/DESIGN_AUDIT.md +0 -235
  362. data/doc/DESIGN_PEER_REVIEW.md +0 -771
  363. data/doc/DESKTOP.md +0 -447
  364. data/doc/ENGINES.md +0 -567
  365. data/doc/ENGINE_DEVELOPMENT_GUIDE.md +0 -417
  366. data/doc/FEATURE_AUDIT.md +0 -218
  367. data/doc/IMPLEMENTATION_PLAN.md +0 -669
  368. data/doc/INCIDENT_REPORT_2026-02-02.md +0 -251
  369. data/doc/MIGRATION_GUIDE.md +0 -88
  370. data/doc/PACKAGING.md +0 -232
  371. data/doc/PROJECT_DASHBOARD.md +0 -153
  372. data/doc/PULP_DEPLOYMENT.md +0 -164
  373. data/doc/QUALITY_FIX_SUMMARY.md +0 -110
  374. data/doc/QUICK_START.md +0 -162
  375. data/doc/REEK_CONFIGURATION.md +0 -166
  376. data/doc/REFERENCE.md +0 -253
  377. data/doc/REFERENCES.md +0 -324
  378. data/doc/SECURITY_REVIEW_CHECKLIST.md +0 -72
  379. data/doc/SESSION_2026-02-28_GTK4_HARDENING.md +0 -359
  380. data/doc/SETUP.md +0 -202
  381. data/doc/TEST_PEER_REVIEW.md +0 -152
  382. data/doc/THREAT_MODEL.md +0 -230
  383. data/doc/USAGE.md +0 -545
  384. data/doc/USER_MANUAL.md +0 -585
  385. data/doc/ai_test_review_checklist.md +0 -110
  386. data/doc/changes/2026-02-18-packaging-fpm.md +0 -155
  387. data/doc/changes/2026-02-19-testing-infrastructure.md +0 -221
  388. data/doc/changes/2026-02-20-security-implementation.md +0 -281
  389. data/doc/changes/2026-02-20-styles-implementation.md +0 -220
  390. data/doc/changes/2026-02-21-architecture-completion.md +0 -95
  391. data/doc/changes/2026-02-21-architecture-ui-layer.md +0 -253
  392. data/doc/changes/2026-02-21-cc-config-implementation.md +0 -108
  393. data/doc/changes/2026-02-21-ci-pipeline-implementation.md +0 -214
  394. data/doc/changes/2026-02-21-compiler-multi-target-pipeline.md +0 -241
  395. data/doc/changes/2026-02-21-config-design-show-commands.md +0 -61
  396. data/doc/changes/2026-02-21-design-implementation-overview.md +0 -455
  397. data/doc/changes/2026-02-21-lifecycle-management.md +0 -196
  398. data/doc/changes/2026-02-21-path-resolver.md +0 -128
  399. data/doc/changes/2026-02-24-ci-tmpdir-mutant-fetch.md +0 -45
  400. data/doc/changes/2026-03-01-ci-bundler-strategy.md +0 -120
  401. data/doc/changes/2026-03-20-security-hardening-phase2.md +0 -163
  402. data/doc/context/SESSION-HANDOFF.md +0 -69
  403. data/doc/context/ai-engine-usage-trends-2026.md +0 -80
  404. data/doc/context/plan-pluggable-engines.md +0 -590
  405. data/doc/decisions/001-flog-deferred.md +0 -32
  406. data/doc/decisions/002-path-resolution-strategy.md +0 -158
  407. data/doc/decisions/003-ui-adapter-selection.md +0 -193
  408. data/doc/decisions/004-design-document-validation.md +0 -179
  409. data/doc/decisions/005-package-splitting-strategy.md +0 -200
  410. data/doc/decisions/006-multi-engine-architecture.md +0 -147
  411. data/doc/decisions/007-engine-agnostic-pivot.md +0 -219
  412. data/doc/decisions/008-ci-bundler-strategy.md +0 -129
  413. data/doc/decisions/009-core-only-v1-release.md +0 -60
  414. data/doc/decisions/010-engine-debian-packaging.md +0 -66
  415. data/doc/decisions/011-context-aware-cli.md +0 -71
  416. data/doc/dependency_decisions.yml +0 -247
  417. data/doc/issues/001-wrapper-missing-environment-variables.md +0 -197
  418. data/doc/issues/002-embedded-ruby-wrong-prefix.md +0 -217
  419. data/doc/issues/003-smoke-test-false-positive.md +0 -127
  420. data/doc/issues/004-market-research-design-updates.md +0 -109
  421. data/doc/issues/005-compile-scope-coexistence.md +0 -161
  422. data/doc/locales/.gitkeep +0 -0
  423. data/doc/man/rai.1.ronn +0 -505
  424. data/doc/operations/packaging.md +0 -133
  425. data/doc/operations/rosett-ai-release.md +0 -65
  426. data/doc/reference/error-catalog.md +0 -107
  427. data/doc/reference/rosett-ai-technical-reference.pdf +0 -0
  428. data/doc/reference/src/Pictures/cover.jpg +0 -0
  429. data/doc/reference/src/Pictures/head1.jpg +0 -0
  430. data/doc/reference/src/Pictures/head2.jpg +0 -0
  431. data/doc/reference/src/Pictures/head3.jpg +0 -0
  432. data/doc/reference/src/Pictures/head4.jpg +0 -0
  433. data/doc/reference/src/Pictures/head5.jpg +0 -0
  434. data/doc/reference/src/Pictures/head6.jpg +0 -0
  435. data/doc/reference/src/Pictures/head7.jpg +0 -0
  436. data/doc/reference/src/Pictures/head8.jpg +0 -0
  437. data/doc/reference/src/StyleInd.ist +0 -4
  438. data/doc/reference/src/bibliography.bib +0 -79
  439. data/doc/reference/src/main.tex +0 -1288
  440. data/doc/reference/src/structure.tex +0 -303
  441. data/doc/rosett-ai-bookmarks.html +0 -301
  442. data/kitchen.yml +0 -46
  443. data/lib/rosett_ai/mcp/enforcement/.gitkeep +0 -0
  444. data/locales/.gitkeep +0 -0
  445. data/packaging/build-engine-deb.sh +0 -81
  446. data/packaging/scripts/postinst +0 -17
  447. data/packaging/scripts/postrm +0 -19
  448. data/packaging/scripts/prerm +0 -10
  449. data/packaging/wrapper.sh.template +0 -38
  450. data/rosett-ai.gemspec +0 -63
  451. data/rules/.gitkeep +0 -0
  452. data/scripts/publish/pulp_upload.sh +0 -123
  453. data/settings.json +0 -29
@@ -6,11 +6,16 @@
6
6
  require 'fileutils'
7
7
 
8
8
  module RosettAi
9
+ # Project and global directory initialization.
9
10
  module Init
10
11
  # Helper module for copying files during initialization
11
12
  module FileCopier
12
13
  module_function
13
14
 
15
+ # Copy global assets to the ~/.claude/ directory.
16
+ #
17
+ # @param base_dir [String] the target base directory
18
+ # @return [Array<String>] list of copied file names
14
19
  def copy_global_assets(base_dir)
15
20
  root = RosettAi.root
16
21
  copied = []
@@ -25,6 +30,10 @@ module RosettAi
25
30
  copied
26
31
  end
27
32
 
33
+ # Copy local assets to the project .claude/ directory.
34
+ #
35
+ # @param base_dir [String] the target base directory
36
+ # @return [Array<String>] list of copied file names
28
37
  def copy_local_assets(base_dir)
29
38
  copied = []
30
39
  # Local scope copies to .claude/conf/ (not XDG)
@@ -32,6 +41,12 @@ module RosettAi
32
41
  copied
33
42
  end
34
43
 
44
+ # Copy configuration assets (behaviours, schemas) to the target.
45
+ #
46
+ # @param source_root [Pathname] the source root directory
47
+ # @param conf_base [String] the target configuration directory
48
+ # @param copied [Array<String>] accumulator for copied file names
49
+ # @return [void]
35
50
  def copy_conf_assets(source_root, conf_base, copied)
36
51
  FileUtils.mkdir_p(File.join(conf_base, 'behaviour'))
37
52
  FileUtils.mkdir_p(File.join(conf_base, 'schemas'))
@@ -45,6 +60,13 @@ module RosettAi
45
60
  copied, 'conf/adopt_redactions.yml')
46
61
  end
47
62
 
63
+ # Copy a single file to the target path.
64
+ #
65
+ # @param source [Pathname, String] source file path
66
+ # @param target [String] target file path
67
+ # @param copied [Array<String>] accumulator for copied file names
68
+ # @param name [String] display name for the copied file
69
+ # @return [void]
48
70
  def copy_single_file(source, target, copied, name)
49
71
  return if File.exist?(target) || !File.exist?(source)
50
72
 
@@ -52,6 +74,13 @@ module RosettAi
52
74
  copied << name
53
75
  end
54
76
 
77
+ # Copy an executable file preserving permissions.
78
+ #
79
+ # @param source [Pathname, String] source file path
80
+ # @param target [String] target file path
81
+ # @param copied [Array<String>] accumulator for copied file names
82
+ # @param name [String] display name for the copied file
83
+ # @return [void]
55
84
  def copy_executable(source, target, copied, name)
56
85
  return unless File.exist?(source)
57
86
 
@@ -60,6 +89,13 @@ module RosettAi
60
89
  copied << name
61
90
  end
62
91
 
92
+ # Recursively copy a directory tree to the target.
93
+ #
94
+ # @param source [Pathname, String] source directory path
95
+ # @param target [String] target directory path
96
+ # @param copied [Array<String>] accumulator for copied file names
97
+ # @param name [String] display name for the copied directory
98
+ # @return [void]
63
99
  def copy_directory(source, target, copied, name)
64
100
  return unless Dir.exist?(source)
65
101
 
@@ -67,6 +103,14 @@ module RosettAi
67
103
  copied << name
68
104
  end
69
105
 
106
+ # Copy files matching a glob pattern to the target directory.
107
+ #
108
+ # @param source_dir [Pathname, String] source directory to glob
109
+ # @param target_dir [String] target directory path
110
+ # @param pattern [String] glob pattern (e.g. '*.yml')
111
+ # @param prefix [String] display prefix for copied file names
112
+ # @param copied [Array<String>] accumulator for copied file names
113
+ # @return [void]
70
114
  def copy_glob_files(source_dir, target_dir, pattern, prefix, copied)
71
115
  return unless Dir.exist?(source_dir)
72
116
 
@@ -84,6 +128,13 @@ module RosettAi
84
128
  end
85
129
  end
86
130
 
131
+ # Copy a file only if the target does not already exist.
132
+ #
133
+ # @param source [Pathname, String] source file path
134
+ # @param target [String] target file path
135
+ # @param copied [Array<String>] accumulator for copied file names
136
+ # @param name [String] display name for the copied file
137
+ # @return [void]
87
138
  def copy_if_new(source, target, copied, name)
88
139
  return unless File.exist?(source) && !File.exist?(target)
89
140
 
@@ -18,6 +18,7 @@ module RosettAi
18
18
  # @author hugo
19
19
  # @author claude
20
20
  class McpRegistrar
21
+ # @return [String] MCP server name used in Claude Code settings.
21
22
  MCP_SERVER_NAME = 'rosett-ai'
22
23
 
23
24
  # @param settings_path [String] path to Claude Code settings.json
@@ -14,6 +14,7 @@ module RosettAi
14
14
  # @author hugo
15
15
  # @author claude
16
16
  class ProjectInitializer
17
+ # @return [String] Default project directory name.
17
18
  PROJECT_DIR = '.rosett-ai'
18
19
 
19
20
  # Sets up the .rosett-ai/ project directory structure.
@@ -15,9 +15,13 @@ module RosettAi
15
15
  # only verify signatures, not forge them. The private signing key
16
16
  # is held server-side and NEVER distributed.
17
17
  class LicenseKey
18
+ # @return [String] Hex-encoded public key for license verification.
18
19
  PUBLIC_KEY_HEX = '91f54336c0d42a7c88642b8d7f8bacab3adba4a4d633a33002fc15f676bfd8f0'
20
+ # @return [String] Prefix for rosett-ai license key strings.
19
21
  RAI_PREFIX = 'NNCC-'
22
+ # @return [Integer] Days of grace period after license expiry.
20
23
  GRACE_PERIOD_DAYS = 14
24
+ # @return [Integer] Days of offline operation before license revalidation.
21
25
  OFFLINE_GRACE_DAYS = 30
22
26
 
23
27
  attr_reader :claims
@@ -8,15 +8,23 @@ module RosettAi
8
8
  # Persists the license key at ~/.config/rosett-ai/license.key with
9
9
  # strict file permissions (0600, owned by current uid).
10
10
  class LicenseStore
11
+ # @return [Object] File permission mode for secure files.
11
12
  SAFE_FILE_MODE = 0o600
13
+ # @return [Object] Directory permission mode for secure directories.
12
14
  SAFE_DIR_MODE = 0o700
13
15
 
16
+ # Save the license key to persistent storage.
17
+ #
18
+ # @param raw_key [Object] the raw key
19
+ # @return [void]
14
20
  def save(raw_key)
15
21
  ensure_parent_directory!
16
22
  File.write(license_path.to_s, raw_key, mode: 'w', perm: SAFE_FILE_MODE)
17
23
  validate_permissions!
18
24
  end
19
25
 
26
+ # Load the license key from persistent storage.
27
+ # @return [LicenseKey, nil]
20
28
  def load
21
29
  return nil unless exists?
22
30
 
@@ -24,6 +32,9 @@ module RosettAi
24
32
  File.read(license_path.to_s).chomp
25
33
  end
26
34
 
35
+ # Remove the stored license key file.
36
+ #
37
+ # @return [void]
27
38
  def remove!
28
39
  File.delete(license_path.to_s) if exists?
29
40
  end
@@ -4,6 +4,7 @@
4
4
  # Copyright (C) 2026 Hugo Antonio Sepulveda Manriquez / NeatNerds
5
5
 
6
6
  module RosettAi
7
+ # License key management and tier enforcement.
7
8
  module Licensing
8
9
  # Represents a license tier with comparable ordering.
9
10
  #
@@ -12,7 +13,9 @@ module RosettAi
12
13
  class Tier
13
14
  include Comparable
14
15
 
16
+ # @return [Hash] Ordered tier hierarchy from lowest to highest.
15
17
  HIERARCHY = { community: 0, supporter: 1, subscriber: 2, enterprise: 3 }.freeze
18
+ # @return [Object] Human-readable names for each tier.
16
19
  NAMES = HIERARCHY.keys.freeze
17
20
 
18
21
  attr_reader :name, :level
@@ -25,6 +28,10 @@ module RosettAi
25
28
  @level = HIERARCHY[sym]
26
29
  end
27
30
 
31
+ # Compare tier levels for sorting.
32
+ #
33
+ # @param other [Tier] the other tier to compare
34
+ # @return [Integer] -1, 0, or 1
28
35
  def <=>(other)
29
36
  level <=> other.level
30
37
  end
@@ -34,6 +41,8 @@ module RosettAi
34
41
  self >= other
35
42
  end
36
43
 
44
+ # Return the human-readable tier name.
45
+ # @return [String]
37
46
  def to_s
38
47
  name.to_s.capitalize
39
48
  end
@@ -5,6 +5,7 @@
5
5
 
6
6
  module RosettAi
7
7
  module Mcp
8
+ # MCP server administration: audit, health, registry.
8
9
  module Admin
9
10
  # Compliance auditor for MCP server configurations.
10
11
  #
@@ -14,6 +14,7 @@ module RosettAi
14
14
  # @author hugo
15
15
  # @author claude
16
16
  class HealthChecker
17
+ # @return [Integer] Default timeout in seconds.
17
18
  DEFAULT_TIMEOUT = 5
18
19
 
19
20
  # @param timeout [Integer] maximum seconds per health check
@@ -14,6 +14,7 @@ module RosettAi
14
14
  # @author hugo
15
15
  # @author claude
16
16
  class Registry
17
+ # @return [String] Configuration directory path.
17
18
  CONFIG_DIR = '.config/rosett-ai/mcp/servers'
18
19
 
19
20
  # @param config_dir [Pathname, nil] override config directory
@@ -34,13 +34,16 @@ module RosettAi
34
34
  # :priority, :description
35
35
  # @param behaviour_name [String] source behaviour name
36
36
  # @param behaviour_version [String] source behaviour version
37
+ # @param contextual_rules [Array<Hash>] rules without extractable regex patterns;
38
+ # listed in header for visibility but not enforced at hook time
37
39
  # @return [String] complete Ruby hook script
38
- def generate(rules, behaviour_name:, behaviour_version:)
40
+ def generate(rules, behaviour_name:, behaviour_version:, contextual_rules: [])
39
41
  timestamp = Time.now.utc.iso8601
40
42
  parts = []
41
43
  parts << shebang_and_magic
42
44
  parts << yard_documentation(rules)
43
- parts << traceability_header(behaviour_name, behaviour_version, rules, timestamp)
45
+ parts << traceability_header(behaviour_name, behaviour_version, rules, timestamp,
46
+ contextual_rules)
44
47
  parts << ai_client_instructions
45
48
  parts << rule_constant(rules)
46
49
  parts << enforcement_body
@@ -83,9 +86,11 @@ module RosettAi
83
86
  # @param behaviour_version [String]
84
87
  # @param rules [Array<Hash>]
85
88
  # @param timestamp [String]
89
+ # @param contextual_rules [Array<Hash>]
86
90
  # @return [String]
87
- def traceability_header(behaviour_name, behaviour_version, rules, timestamp)
88
- <<~RUBY
91
+ def traceability_header(behaviour_name, behaviour_version, rules, timestamp,
92
+ contextual_rules = [])
93
+ header = <<~RUBY
89
94
  # --- Traceability ---
90
95
  # Source behaviour: #{behaviour_name}
91
96
  # Behaviour version: #{behaviour_version}
@@ -94,6 +99,24 @@ module RosettAi
94
99
  # Rule count: #{rules.size}
95
100
  # Rule IDs: #{rules.map { |r| r[:rule_id] }.join(', ')}
96
101
  RUBY
102
+ header + contextual_warning(contextual_rules)
103
+ end
104
+
105
+ # Generates a contextual rules warning section for rules that cannot be
106
+ # regex-enforced. Listed for visibility; not enforced at hook time.
107
+ #
108
+ # @param contextual_rules [Array<Hash>]
109
+ # @return [String]
110
+ def contextual_warning(contextual_rules)
111
+ return '' if contextual_rules.empty?
112
+
113
+ lines = contextual_rules.map do |r|
114
+ "# #{r[:behaviour]}/#{r[:rule_id]} (P#{r[:priority]})"
115
+ end
116
+ <<~RUBY
117
+ # Contextual rules (no regex pattern — human-reviewed only):
118
+ #{lines.join("\n")}
119
+ RUBY
97
120
  end
98
121
 
99
122
  # @return [String]
@@ -5,6 +5,7 @@
5
5
 
6
6
  module RosettAi
7
7
  module Mcp
8
+ # Rule enforcement pipeline for MCP operations.
8
9
  module Enforcement
9
10
  # Validates enforcement blocks in behaviour rules.
10
11
  #
@@ -27,7 +28,9 @@ module RosettAi
27
28
  # @author hugo
28
29
  # @author claude
29
30
  class Validator
31
+ # @return [Array] Set of permitted type values.
30
32
  VALID_TYPES = ['enforceable', 'advisory', 'informational'].freeze
33
+ # @return [Array] Set of permitted action values.
31
34
  VALID_ACTIONS = ['block', 'warn', 'log'].freeze
32
35
 
33
36
  # Patterns that match everything or nearly everything — unsafe for hooks.
@@ -44,6 +47,8 @@ module RosettAi
44
47
  /\A\(\.\+\)\z/ # (.+)
45
48
  ].freeze
46
49
 
50
+ # Struct holding rule context for enforcement validation.
51
+ #
47
52
  # @!attribute [r] behaviour
48
53
  # @return [String] behaviour name for error messages
49
54
  # @!attribute [r] rule_id
@@ -148,7 +153,7 @@ module RosettAi
148
153
  # @param prefix [String] error message prefix
149
154
  # @return [Array<String>]
150
155
  def check_pattern(pattern, prefix)
151
- return ["#{prefix}: pattern missing or empty"] if pattern.nil? || blank?(pattern)
156
+ return ["#{prefix}: pattern missing or empty"] if blank?(pattern.to_s)
152
157
 
153
158
  Regexp.new(pattern)
154
159
  return ["#{prefix}: pattern '#{pattern}' is degenerate (matches everything)"] if degenerate?(pattern)
@@ -170,17 +175,32 @@ module RosettAi
170
175
  end
171
176
 
172
177
  # Validates the action field.
178
+ # A nil/absent action is allowed — priority-based default applies.
173
179
  #
174
180
  # @param action [String, nil]
175
181
  # @param prefix [String] error message prefix
176
182
  # @return [Array<String>]
177
183
  def check_action(action, prefix)
184
+ return [] if action.to_s.strip.empty?
178
185
  return [] if VALID_ACTIONS.include?(action)
179
186
 
180
187
  allowed = VALID_ACTIONS.join(', ')
181
188
  ["#{prefix}: action '#{action}' invalid (must be one of: #{allowed})"]
182
189
  end
183
190
 
191
+ # Derives action from priority when none is explicitly set.
192
+ # Priority >= 80 → block; priority < 80 → warn.
193
+ #
194
+ # @param enforcement [Hash]
195
+ # @param priority [Integer]
196
+ # @return [String]
197
+ def derive_action(enforcement, priority)
198
+ action = enforcement['action'].to_s.strip
199
+ return action unless action.empty?
200
+
201
+ priority.to_i >= 80 ? 'block' : 'warn'
202
+ end
203
+
184
204
  # Tests whether a string is blank (nil, empty, or whitespace-only).
185
205
  #
186
206
  # @param value [String]
@@ -204,10 +224,11 @@ module RosettAi
204
224
  # @param ctx [RuleContext]
205
225
  # @return [Hash]
206
226
  def build_valid_entry(rule, enforcement, ctx)
227
+ priority = rule['priority'] || 0
207
228
  { rule_id: ctx.rule_id, behaviour: ctx.behaviour, type: 'enforceable',
208
229
  pattern: enforcement['pattern'], applies_to: enforcement['applies_to'],
209
- action: enforcement['action'], message: enforcement['message'],
210
- priority: rule['priority'] || 0, description: rule['description'].to_s.strip }
230
+ action: derive_action(enforcement, priority), message: enforcement['message'],
231
+ priority: priority, description: rule['description'].to_s.strip }
211
232
  end
212
233
  end
213
234
  end
@@ -13,6 +13,7 @@ module RosettAi
13
13
  # @author hugo
14
14
  # @author claude
15
15
  module Governance
16
+ # @return [Array] Registered MCP tool implementation classes.
16
17
  TOOL_CLASSES = [
17
18
  Tools::ValidateTool,
18
19
  Tools::CompileTool,
@@ -49,6 +50,7 @@ module RosettAi
49
50
  Tools::SchemaGetTool
50
51
  ].freeze
51
52
 
53
+ # @return [Array] Registered MCP resource implementation classes.
52
54
  RESOURCE_CLASSES = [
53
55
  Resources::BehaviourResource,
54
56
  Resources::DesignResource,
@@ -59,6 +61,7 @@ module RosettAi
59
61
  Resources::HooksResource
60
62
  ].freeze
61
63
 
64
+ # @return [Array] Registered MCP prompt implementation classes.
62
65
  PROMPT_CLASSES = [
63
66
  Prompts::ValidationPrompt,
64
67
  Prompts::CompilationPrompt,
@@ -66,6 +69,7 @@ module RosettAi
66
69
  Prompts::DiagnosticsPrompt
67
70
  ].freeze
68
71
 
72
+ # @return [Array] Parameter types passed as keyword arguments.
69
73
  KEYWORD_PARAM_TYPES = [:keyreq, :key].freeze
70
74
 
71
75
  module_function
@@ -125,6 +129,11 @@ module RosettAi
125
129
  end
126
130
  end
127
131
 
132
+ # Look up the MCP resource handler for a URI.
133
+ #
134
+ # @param resources [Array] registered resource instances
135
+ # @param uri [String] the resource URI to match
136
+ # @return [Object, nil] the matching resource, or nil
128
137
  def find_resource_for_uri(resources, uri)
129
138
  resources.find { |r| resource_matches_uri?(r, uri) }
130
139
  end
@@ -46,6 +46,7 @@ module RosettAi
46
46
  class AuthConfig
47
47
  attr_accessor :type, :key_source, :keyfile_path, :api_key_env
48
48
 
49
+ # @return [String] Default keyfile name constant.
49
50
  DEFAULT_KEYFILE_NAME = 'rosett-ai-mcp-keys.yml'
50
51
 
51
52
  def initialize
@@ -64,6 +65,10 @@ module RosettAi
64
65
  File.exist?(File.expand_path(@keyfile_path)) ? 'keyfile' : 'env'
65
66
  end
66
67
 
68
+ # Apply authentication configuration from a hash.
69
+ #
70
+ # @param hash [Hash] configuration values
71
+ # @return [void]
67
72
  def apply(hash)
68
73
  return unless hash.is_a?(Hash)
69
74
 
@@ -84,6 +89,10 @@ module RosettAi
84
89
  @key_path = nil
85
90
  end
86
91
 
92
+ # Apply TLS configuration from a hash.
93
+ #
94
+ # @param hash [Hash] configuration values
95
+ # @return [void]
87
96
  def apply(hash)
88
97
  return unless hash.is_a?(Hash)
89
98
 
@@ -95,6 +104,7 @@ module RosettAi
95
104
 
96
105
  # Origin validation sub-configuration.
97
106
  class OriginConfig
107
+ # @return [Array] Default allowed origins for origin validation.
98
108
  DEFAULT_ORIGINS = ['http://localhost:*', 'http://127.0.0.1:*'].freeze
99
109
 
100
110
  attr_accessor :allowed_origins, :strict_mode
@@ -104,6 +114,10 @@ module RosettAi
104
114
  @strict_mode = false
105
115
  end
106
116
 
117
+ # Apply origin validation configuration from a hash.
118
+ #
119
+ # @param hash [Hash] configuration values
120
+ # @return [void]
107
121
  def apply(hash)
108
122
  return unless hash.is_a?(Hash)
109
123
 
@@ -122,6 +136,10 @@ module RosettAi
122
136
  @authenticated_rpm = 300
123
137
  end
124
138
 
139
+ # Apply rate limit configuration from a hash.
140
+ #
141
+ # @param hash [Hash] configuration values
142
+ # @return [void]
125
143
  def apply(hash)
126
144
  return unless hash.is_a?(Hash)
127
145
 
@@ -143,6 +161,10 @@ module RosettAi
143
161
  @max_age = 86_400
144
162
  end
145
163
 
164
+ # Apply CORS configuration from a hash.
165
+ #
166
+ # @param hash [Hash] configuration values
167
+ # @return [void]
146
168
  def apply(hash)
147
169
  return unless hash.is_a?(Hash)
148
170
 
@@ -16,7 +16,9 @@ module RosettAi
16
16
  # @author hugo
17
17
  # @author claude
18
18
  module KeyHasher
19
+ # @return [Integer] Number of random bytes used for key salting.
19
20
  SALT_BYTES = 16
21
+ # @return [String] Prefix for hashed API key identifiers.
20
22
  KEY_PREFIX = 'nncc_'
21
23
 
22
24
  module_function
@@ -53,8 +55,8 @@ module RosettAi
53
55
 
54
56
  # Constant-time string comparison to prevent timing attacks.
55
57
  #
56
- # @param a [String] first string
57
- # @param b [String] second string
58
+ # @param a_str [String] first string
59
+ # @param b_str [String] second string
58
60
  # @return [Boolean] true if strings match
59
61
  def secure_compare(a_str, b_str)
60
62
  return false unless a_str.bytesize == b_str.bytesize
@@ -14,9 +14,13 @@ module RosettAi
14
14
  # @author hugo
15
15
  # @author claude
16
16
  class Keyfile
17
+ # @return [String] Current version of the rosett-ai gem.
17
18
  VERSION = '1.0'
19
+ # @return [Object] Maximum number of permissions per key.
18
20
  MAX_PERMISSIONS = 0o600
21
+ # @return [String] Default filename for the MCP keyfile.
19
22
  DEFAULT_FILENAME = 'rosett-ai-mcp-keys.yml'
23
+ # @return [Integer] Days before expiry to show warnings.
20
24
  EXPIRY_WARNING_DAYS = 7
21
25
 
22
26
  # @param path [String] path to the keyfile
@@ -5,6 +5,7 @@
5
5
 
6
6
  module RosettAi
7
7
  module Mcp
8
+ # HTTP middleware: CORS, rate limiting, origin validation.
8
9
  module Middleware
9
10
  # Rack middleware for CORS header handling and preflight.
10
11
  #
@@ -17,8 +18,11 @@ module RosettAi
17
18
  # @param app [#call] the next Rack application
18
19
  # @param config [#origins, #methods, #headers, #max_age] CORS config
19
20
  DEFAULT_METHODS = ['POST', 'GET', 'DELETE'].freeze
21
+ # @return [Array] Default CORS headers.
20
22
  DEFAULT_HEADERS = ['Content-Type', 'Authorization', 'Accept', 'Mcp-Session-Id'].freeze
23
+ # @return [Object] Default CORS preflight cache duration in seconds.
21
24
  DEFAULT_MAX_AGE = 86_400
25
+ # @return [Array] Configuration field names for CORS middleware.
22
26
  CONFIG_FIELDS = [:origins, :methods, :headers, :max_age].freeze
23
27
 
24
28
  def initialize(app, config: nil)
@@ -15,6 +15,7 @@ module RosettAi
15
15
  # @author hugo
16
16
  # @author claude
17
17
  class OriginValidation
18
+ # @return [Array] Default allowed origins for origin validation.
18
19
  DEFAULT_ORIGINS = ['http://localhost:*', 'http://127.0.0.1:*'].freeze
19
20
 
20
21
  # @param app [#call] the next Rack application
@@ -15,9 +15,12 @@ module RosettAi
15
15
  # @author hugo
16
16
  # @author claude
17
17
  class RateLimit
18
+ # @return [Integer] Default rate limit for unauthenticated requests per minute.
18
19
  DEFAULT_UNAUTH_RPM = 60
20
+ # @return [Integer] Default rate limit for authenticated requests per minute.
19
21
  DEFAULT_AUTH_RPM = 300
20
22
  BUCKET_WINDOW = 60 # seconds
23
+ # @return [Integer] Interval between rate limit bucket cleanup sweeps.
21
24
  CLEANUP_INTERVAL = 100
22
25
 
23
26
  # @param app [#call] the next Rack application
@@ -16,6 +16,7 @@ module RosettAi
16
16
  # @author hugo
17
17
  # @author claude
18
18
  module Plugins
19
+ # @return [Mutex] Mutex for thread-safe plugin registration.
19
20
  PLUGIN_MUTEX = Mutex.new
20
21
 
21
22
  module_function
@@ -14,7 +14,9 @@ module RosettAi
14
14
  # @author hugo
15
15
  # @author claude
16
16
  class CompilationPrompt
17
+ # @return [String] MCP prompt identifier string.
17
18
  PROMPT_NAME = 'rai_compilation_workflow'
19
+ # @return [String] Human-readable description of this tool.
18
20
  DESCRIPTION = 'Compile rai behaviours and review output'
19
21
 
20
22
  # Generates the compilation prompt messages.
@@ -5,6 +5,7 @@
5
5
 
6
6
  module RosettAi
7
7
  module Mcp
8
+ # MCP prompt implementations for guided workflows.
8
9
  module Prompts
9
10
  # MCP prompt: compliance workflow.
10
11
  #
@@ -14,7 +15,9 @@ module RosettAi
14
15
  # @author hugo
15
16
  # @author claude
16
17
  class CompliancePrompt
18
+ # @return [String] MCP prompt identifier string.
17
19
  PROMPT_NAME = 'rai_compliance_workflow'
20
+ # @return [String] Human-readable description of this tool.
18
21
  DESCRIPTION = 'Run compliance checks and interpret results'
19
22
 
20
23
  # Generates the compliance prompt messages.
@@ -14,7 +14,9 @@ module RosettAi
14
14
  # @author hugo
15
15
  # @author claude
16
16
  class DiagnosticsPrompt
17
+ # @return [String] MCP prompt identifier string.
17
18
  PROMPT_NAME = 'rai_diagnostics_workflow'
19
+ # @return [String] Human-readable description of this tool.
18
20
  DESCRIPTION = 'Run diagnostics and troubleshoot issues'
19
21
 
20
22
  # Generates the diagnostics prompt messages.
@@ -14,7 +14,9 @@ module RosettAi
14
14
  # @author hugo
15
15
  # @author claude
16
16
  class ValidationPrompt
17
+ # @return [String] MCP prompt identifier string.
17
18
  PROMPT_NAME = 'rai_validation_workflow'
19
+ # @return [String] Human-readable description of this tool.
18
20
  DESCRIPTION = 'Validate rai configuration and suggest fixes'
19
21
 
20
22
  # Generates the validation prompt messages.
@@ -18,8 +18,10 @@ module RosettAi
18
18
  # @author hugo
19
19
  # @author claude
20
20
  class BehaviourResource
21
+ # @return [String] URI prefix for MCP resource discovery.
21
22
  URI_PREFIX = 'rosett-ai://behaviour/'
22
23
 
24
+ # @return [Hash] Directory names for each configuration tier.
23
25
  TIER_DIRS = {
24
26
  'project' => -> { RosettAi.conf_root.join('conf', 'behaviour') },
25
27
  'xdg' => -> { RosettAi.paths.rai_conf_dir.join('behaviour') },
@@ -13,7 +13,9 @@ module RosettAi
13
13
  # @author hugo
14
14
  # @author claude
15
15
  class ConfigResource
16
+ # @return [String] URI prefix for MCP resource discovery.
16
17
  URI_PREFIX = 'rosett-ai://config/'
18
+ # @return [Array] Supported configuration scope names.
17
19
  SCOPES = ['managed', 'user', 'project', 'local'].freeze
18
20
 
19
21
  # Lists available config resources.
@@ -14,6 +14,7 @@ module RosettAi
14
14
  # @author hugo
15
15
  # @author claude
16
16
  class DesignResource
17
+ # @return [String] URI prefix for MCP resource discovery.
17
18
  URI_PREFIX = 'rosett-ai://design/'
18
19
 
19
20
  # Lists all available design resources.