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,184 @@
1
+ ---
2
+ name: doctor
3
+ domain: core
4
+ version: 0.2.0
5
+ status: implemented
6
+ priority: 2
7
+ author: hugo
8
+ created_at: "2026-03-16"
9
+ modified_at: "2026-04-14"
10
+ modified_by: claude opus-4.6
11
+ depends_on:
12
+ - architecture
13
+ - security
14
+ - error_handling
15
+ - engine_architecture
16
+ - monitoring_observability
17
+ #
18
+ intent: |
19
+ Provide a single diagnostic command (`rai doctor`) that checks all runtime
20
+ prerequisites and reports actionable fixes for any issues found. Users
21
+ installing rosett-ai on a new machine, upgrading Ruby, or troubleshooting engine
22
+ failures need a one-stop health check that verifies Ruby version, gem
23
+ dependencies, file permissions, D-Bus availability, engine detection, and
24
+ cache integrity — without requiring them to know which subsystem is failing.
25
+
26
+ Without this command, users troubleshoot by trial and error: "Is it a Ruby
27
+ version mismatch? Missing gems? Wrong permissions?" This design replaces
28
+ guesswork with structured diagnostics that produce a pass/warn/fail report
29
+ per check, with specific remediation steps for each failure.
30
+
31
+ Doctor is the diagnostic layer — it inspects the runtime environment and
32
+ reports readiness. It does not modify state (no auto-fix). Monitoring
33
+ (monitoring_observability.yml) captures runtime telemetry during command
34
+ execution. Error handling (error_handling.yml) governs how errors are
35
+ displayed. Engine detection (engine_architecture.yml) provides the probe
36
+ logic that doctor invokes.
37
+ #
38
+ constraints:
39
+ - "Doctor must be read-only — it inspects and reports but never modifies
40
+ files, installs gems, or changes configuration"
41
+ - "Each check must be independently testable with a clear pass/warn/fail
42
+ verdict and a human-readable remediation message"
43
+ - "Doctor must work without any engine installed — it reports 'no engines
44
+ detected' as a warning, not an error"
45
+ - "Checks must complete within 5 seconds total on a standard system (no
46
+ network calls, no heavy computation)"
47
+ - "Output must be TTY-aware: formatted table with colour when interactive,
48
+ plain text with status codes when piped"
49
+ - "Doctor must not require elevated privileges — all checks operate within
50
+ the user's permission scope"
51
+ - "Exit code 0 when all checks pass, 1 when any check warns, 2 when any
52
+ check fails"
53
+ - "Each check class implements a common interface: #name, #run, #status,
54
+ #message, #remediation"
55
+ - "Checks are registered declaratively and executed in registration order"
56
+ - "Doctor must report the rai version and Ruby version at the top of output"
57
+ - "All remediation messages must be translatable via i18n keys"
58
+ - "This design governs environment diagnostics (checking readiness). Runtime
59
+ telemetry is governed by monitoring_observability.yml. Error display is
60
+ governed by error_handling.yml. Engine probing is governed by
61
+ engine_architecture.yml"
62
+ #
63
+ acceptance_criteria:
64
+ - "`rai doctor` runs all registered checks and displays a summary table"
65
+ - "Ruby version check verifies .ruby-version matches running Ruby"
66
+ - "Gem dependency check verifies all Gemfile.lock gems are installed"
67
+ - "File permission check verifies ~/.claude/ and ~/.config/rosett-ai/ are writable"
68
+ - "D-Bus availability check verifies session bus is accessible (warn if not)"
69
+ - "Engine detection check lists detected engines (warn if none found)"
70
+ - "Cache health check verifies cache directory exists and is writable"
71
+ - "Exit code 0 on all pass, 1 on any warn, 2 on any fail"
72
+ - "TTY-aware output: colour table when interactive, plain lines when piped"
73
+ - "Each check can be run individually via `rai doctor --check ruby_version`"
74
+ - "Output includes rai version and Ruby version header"
75
+ - "All remediation messages use i18n keys from locales/ directory"
76
+ - "`rai doctor --format json` outputs machine-readable results for CI"
77
+ #
78
+ examples:
79
+ - scenario: "User runs `rai doctor` on a correctly configured system"
80
+ expected: |
81
+ raictl 0.9.0 | Ruby 3.3.10 | Linux x86_64
82
+
83
+ ┌──────────────────────┬────────┬─────────────────────────────┐
84
+ │ Check │ Status │ Details │
85
+ ├──────────────────────┼────────┼─────────────────────────────┤
86
+ │ Ruby version │ PASS │ 3.3.10 matches .ruby-version│
87
+ │ Gem dependencies │ PASS │ All 42 gems installed │
88
+ │ File permissions │ PASS │ ~/.claude/ writable │
89
+ │ D-Bus session bus │ PASS │ be.neatnerds.rosettai reachable │
90
+ │ Engine detection │ PASS │ claude (default), generic │
91
+ │ Cache health │ PASS │ ~/.cache/rosett-ai/ writable │
92
+ └──────────────────────┴────────┴─────────────────────────────┘
93
+
94
+ All 6 checks passed.
95
+ not: |
96
+ Raw exception output. Missing remediation for failures. Exit code 1
97
+ when everything is healthy.
98
+ - scenario: "User runs `rai doctor` with wrong Ruby version installed"
99
+ expected: |
100
+ Ruby version check fails with:
101
+ "FAIL: Ruby 3.2.3 detected, but .ruby-version requires 3.3.10.
102
+ Fix: rbenv install 3.3.10 && rbenv local 3.3.10"
103
+ Exit code 2. Other checks still run and report their status.
104
+ not: |
105
+ Doctor stops at first failure. No remediation suggestion.
106
+ Exit code 1 (should be 2 for failure).
107
+ - scenario: "User runs `rai doctor` on a headless server without D-Bus"
108
+ expected: |
109
+ D-Bus check warns: "WARN: D-Bus session bus not available. Desktop
110
+ integration features will be unavailable.
111
+ Fix: Install dbus and ensure DBUS_SESSION_BUS_ADDRESS is set."
112
+ Exit code 1 (warn). All other checks still run.
113
+ not: |
114
+ Doctor crashes because D-Bus is missing. D-Bus check reports FAIL
115
+ instead of WARN (D-Bus is optional).
116
+ - scenario: "CI pipeline runs `rai doctor --format json`"
117
+ expected: |
118
+ {"rai_version":"0.9.0","ruby_version":"3.3.10","checks":[
119
+ {"name":"ruby_version","status":"pass","message":"3.3.10 matches .ruby-version"},
120
+ {"name":"gem_dependencies","status":"pass","message":"All 42 gems installed"},
121
+ ...
122
+ ],"summary":{"pass":6,"warn":0,"fail":0}}
123
+ not: "Human-readable table output that CI cannot parse."
124
+ - scenario: "User runs a single check via `rai doctor --check cache_health`"
125
+ expected: |
126
+ Only the cache health check runs. Output shows single check result.
127
+ Exit code reflects that check's status only.
128
+ not: "All checks run despite --check filter. Unknown check name silently ignored."
129
+ #
130
+ anti_patterns:
131
+ - "Auto-fixing problems without user consent (doctor is read-only)"
132
+ - "Requiring network access for any check (all checks must be local)"
133
+ - "Stopping at the first failed check (always run all checks)"
134
+ - "Using raw Ruby exception output instead of structured remediation"
135
+ - "Hardcoding remediation messages instead of using i18n keys"
136
+ - "Treating optional features (D-Bus) as required (warn, not fail)"
137
+ - "Running checks that require elevated privileges"
138
+ - "Dynamic check discovery via ObjectSpace (register checks explicitly)"
139
+ #
140
+ gui_notes: |
141
+ Document interactions (cross-references):
142
+
143
+ 1. error_handling.yml: exit codes follow the structured error hierarchy.
144
+ Doctor exit codes (0/1/2) align with the error code mapping.
145
+
146
+ 2. engine_architecture.yml: engine detection check invokes the engine
147
+ detector to find installed AI tools.
148
+
149
+ 3. monitoring_observability.yml: doctor itself emits telemetry events
150
+ (command_start, command_end) when telemetry is enabled.
151
+
152
+ 4. security.yml: file permission checks verify security-relevant paths
153
+ (~/.claude/, ~/.config/rosett-ai/) have correct permissions.
154
+
155
+ 5. architecture.yml: check registration follows the pluggable provider
156
+ pattern used throughout rosett-ai.
157
+
158
+ Module structure:
159
+
160
+ lib/rosett_ai/doctor.rb — Diagnostic runner (orchestrates checks)
161
+ lib/rosett_ai/doctor/check.rb — Base check interface
162
+ lib/rosett_ai/doctor/checks/ruby_version_check.rb
163
+ lib/rosett_ai/doctor/checks/gem_dependency_check.rb
164
+ lib/rosett_ai/doctor/checks/file_permission_check.rb
165
+ lib/rosett_ai/doctor/checks/dbus_availability_check.rb
166
+ lib/rosett_ai/doctor/checks/engine_detection_check.rb
167
+ lib/rosett_ai/doctor/checks/cache_health_check.rb
168
+ lib/rosett_ai/thor/tasks/doctor.rb — CLI integration
169
+ #
170
+ preferences:
171
+ language: ruby
172
+ patterns:
173
+ - "Check interface pattern (#name, #run, #status, #message, #remediation)"
174
+ - "Declarative check registration"
175
+ - "TTY-aware output (TtyHelper)"
176
+ - "i18n remediation messages"
177
+ - "JSON output for CI integration"
178
+ testing: rspec with check pass/fail/warn scenarios, TTY vs pipe output,
179
+ exit code verification, JSON output format, and individual check filtering
180
+ gems:
181
+ - thor
182
+ - pastel
183
+ - tty-table
184
+ - i18n
@@ -0,0 +1,152 @@
1
+ ---
2
+ name: documentation
3
+ domain: documentation
4
+ version: 0.2.0
5
+ status: implemented
6
+ priority: 5
7
+ author: claude
8
+ created_at: "2026-02-22"
9
+ modified_at: "2026-03-17"
10
+ modified_by: claude
11
+ depends_on:
12
+ - architecture
13
+ - compiler
14
+ - error_handling
15
+
16
+ intent: |
17
+ Provide end users with complete documentation for installing, configuring,
18
+ and using rosett-ai. The project currently has developer-facing docs (SETUP.md,
19
+ USAGE.md, CONFIGURATION.md) but lacks production-facing artifacts: man pages
20
+ for terminal discovery, installation guides for .deb users, and generated
21
+ API documentation for contributors.
22
+
23
+ Man pages are the Unix standard for command documentation. Users expect
24
+ 'ma rai' to work after installing a .deb package. Without this, the tool
25
+ feels incomplete and forces users to find docs online.
26
+
27
+ API documentation via YARD enables contributors to understand the codebase
28
+ without reading every file. This is especially important for an open-source
29
+ GPL-3.0 project that invites community contributions.
30
+
31
+ An installation guide bridges the gap between "here is a .deb file" and
32
+ "here is a working rosett-ai setup". Without it, users must reverse-engineer
33
+ the setup process from developer docs.
34
+
35
+ A quick start guide (doc/QUICK_START.md) provides first-time users with a
36
+ 5-minute path from installation to first successful compile. Unlike INSTALL.md
37
+ (which covers all installation methods) or the man page (which is a reference),
38
+ the quick start guide is a tutorial that walks through a single happy-path
39
+ scenario: install, init, author a behaviour, compile, verify. It targets users
40
+ who want to see rosett-ai produce output before reading comprehensive documentation.
41
+
42
+ constraints:
43
+ - Man pages are authored in ronn-ng markdown format (doc/man/*.ronn)
44
+ - Man page build produces roff output at man/man1/rai.1
45
+ - The .deb package ships man pages at /usr/share/man/man1/rai.1.gz
46
+ - "YARD documentation generates without errors; minimum 40% of lib files have YARD tags (target 100%)"
47
+ - All user-facing documentation must be consistent with the current version (no stale version references)
48
+ - Documentation source files are versioned in git alongside code
49
+ - INSTALL.md covers .deb installation, APT repository setup, and post-install verification
50
+ - No documentation references features that don't exist yet (no aspirational docs)
51
+ - ronn-ng is a development dependency only (not runtime)
52
+ - Quick start guide must be completable in under 5 minutes by a new user
53
+ - "Quick start guide covers exactly one path: install, init, author, compile, verify"
54
+ - "Documentation generation processes trusted source files only — no external input accepted"
55
+
56
+ acceptance_criteria:
57
+ - ma rai displays a well-formatted man page after .deb installation
58
+ - doc/man/rai.1.ronn exists with NAME, SYNOPSIS, DESCRIPTION, COMMANDS, OPTIONS, FILES, EXIT STATUS, and SEE ALSO sections
59
+ - A Rake task rake man generates man/man1/rai.1 from ronn source
60
+ - The .deb build process includes man page generation and installs to /usr/share/man/man1/
61
+ - .yardopts configuration exists with project-appropriate settings
62
+ - "yard doc generates HTML documentation; spec/yard_coverage_spec.rb enforces minimum 40% YARD tag coverage (target 100%)"
63
+ - INSTALL.md exists with sections for .deb install, APT repo config, manual install, and verification
64
+ - bin/raictl release prepare verifies documentation consistency (no stale version refs)
65
+ - All subcommands documented in man page match actual CLI help output
66
+ - doc/SETUP.md Ruby version matches .ruby-version (verified by CI)
67
+ - doc/QUICK_START.md exists with install, init, author, compile, verify sections
68
+ - Quick start guide uses only stable commands (no experimental features)
69
+
70
+ examples:
71
+ - scenario: "User installs rosett-ai .deb and wants to learn available commands"
72
+ expected: |
73
+ $ ma rai
74
+ RAICTL(1) NeatNerds Manual RAICTL(1)
75
+
76
+ NAME
77
+ raictl - Rosett-AI
78
+
79
+ SYNOPSIS
80
+ raictl [--accessible] [--locale LOCALE] [--ui ADAPTER] COMMAND [ARGS]
81
+
82
+ DESCRIPTION
83
+ Configuration management tool for Claude Code workflows...
84
+
85
+ COMMANDS
86
+ version Display rosett-ai version
87
+ compile Compile YAML configurations into rule files
88
+ behaviour Behaviour configuration management
89
+ ...
90
+ not: |
91
+ 'ma rai' returns "No manual entry for Rosett-AI". Man page lists
92
+ commands that don't exist in the CLI. Man page version differs from
93
+ raictl version.
94
+
95
+ - scenario: "Contributor wants to understand the PathResolver API"
96
+ expected: |
97
+ $ yard doc
98
+ Files: 66
99
+ Modules: 15
100
+ Classes: 42
101
+ Methods: 180
102
+ YARD coverage spec enforces >= 40% (target 100%)
103
+
104
+ Open doc/api/index.html in browser → navigate to RosettAi::PathResolver
105
+ → see all public methods with param types and return values.
106
+ not: |
107
+ YARD coverage drops below 40% threshold. Generated docs reference
108
+ private implementation details.
109
+
110
+ - scenario: "New user wants to install rosett-ai on Debian Bookworm"
111
+ expected: |
112
+ User opens INSTALL.md, finds clear steps:
113
+ 1. Add NeatNerds APT repository
114
+ 2. Import GPG signing key
115
+ 3. apt update && apt install rosett-ai
116
+ 4. rai version (verify installation)
117
+ 5. rai init --global (first-time setup)
118
+ not: |
119
+ INSTALL.md says "run bundle install" (that's developer setup, not user install).
120
+ INSTALL.md references features not yet available. Steps are out of order.
121
+
122
+ - scenario: "First-time user wants to see rosett-ai produce output immediately"
123
+ expected: |
124
+ User opens doc/QUICK_START.md, follows 5 steps:
125
+ 1. apt install rosett-ai (or gem install)
126
+ 2. rai init --global
127
+ 3. rai behaviour manage add my_first_rule (creates a template)
128
+ 4. rai compile --verbose (compiles to ~/.claude/rules/)
129
+ 5. cat ~/.claude/rules/my_first_rule.md (sees compiled output)
130
+ Total time: under 5 minutes. User has a working rosett-ai setup.
131
+ not: |
132
+ Quick start requires reading 3 other documents first. Quick start
133
+ uses experimental commands. Quick start assumes prior knowledge of
134
+ YAML schemas or engine architecture.
135
+
136
+ anti_patterns:
137
+ - Writing man pages in raw roff format (unreadable, unmaintainable)
138
+ - Generating documentation that references undocumented or private methods
139
+ - Shipping documentation with stale version numbers
140
+ - Duplicating CLI help text in man pages (generate from single source where possible)
141
+ - Creating documentation for features that don't exist yet (aspirational docs mislead users)
142
+ - Skipping man page from .deb package (users expect Unix conventions)
143
+
144
+ preferences:
145
+ language: ruby
146
+ gems:
147
+ - ronn-ng
148
+ - yard
149
+ patterns:
150
+ - single_source_of_truth
151
+ - version_consistency_verification
152
+ testing: rspec for doc generation tasks, CI linting for version consistency
@@ -0,0 +1,257 @@
1
+ ---
2
+ name: engine_architecture
3
+ domain: core
4
+ version: 1.0.0
5
+ status: implemented
6
+ priority: 2
7
+ author: hugo
8
+ created_at: "2026-02-26"
9
+ modified_at: "2026-04-14"
10
+ modified_by: claude opus-4.6
11
+ depends_on:
12
+ - architecture
13
+ - security
14
+ - testing
15
+ - compiler
16
+ - error_handling
17
+ - scope_hierarchy
18
+
19
+ intent: |
20
+ Establish a pluggable engine architecture that enables rosett-ai to manage
21
+ configuration for multiple AI coding tools from a single set of
22
+ human-authored YAML source files. Each AI tool (Claude Code, Cursor,
23
+ Goose, AGENTS.md, Ollama, GPT-NeoX, etc.) is represented by an
24
+ independent engine — a self-contained gem with optional components.
25
+
26
+ The generic layer (conf/behaviour/, conf/design/) captures human intent:
27
+ behaviour rules, ethics, workflows, coding standards. This layer is
28
+ AI-tool-agnostic. Each engine translates the generic layer into its
29
+ tool's native format and writes to the tool's native filesystem location.
30
+
31
+ Engines are independently installable. Core rosett-ai has no LLM API
32
+ dependencies. The Claude engine brings the anthropic gem. The Ollama
33
+ engine brings an HTTP client for localhost. A minimal installation
34
+ with only the Generic engine produces plain markdown — no AI tool needed.
35
+
36
+ Engine authors need a comprehensive development guide (doc/ENGINE_DEVELOPMENT_GUIDE.md)
37
+ that covers manifest schema, component interfaces, testing patterns, and
38
+ packaging requirements. Without this guide, third-party engine development
39
+ requires reading Rosett-AI core source code — which is fragile and undocumented.
40
+ The guide serves as the Plugin SDK documentation for the engine architecture.
41
+
42
+ Engines are autodetectable. At init time or via bin/raictl engines detect,
43
+ raictl probes the system for installed AI tools and suggests a default
44
+ engine. Engines that support programmatic invocation (API or CLI) can
45
+ participate in quorum analysis via the separate quorum module.
46
+
47
+ This design supersedes the implicit Claude-only assumption and implements
48
+ the direction accepted as ADR-007.
49
+
50
+ constraints:
51
+ - Each engine is a self-contained directory — no cross-engine dependencies
52
+ - Generic layer (behaviour, design YAML) contains only human intent — no engine-specific keys
53
+ - Engine-specific configuration lives in conf/engines/<name>/ — not in generic config
54
+ - Core rosett-ai has zero LLM API dependencies — API gems are engine-specific
55
+ - Existing Claude Code workflows must not break during incremental migration
56
+ - Engine components are optional — only implement what applies to the tool
57
+ - No forced common interface across engines — each implements relevant components only
58
+ - Autodetection is data-driven from manifest.yml — custom Ruby only when needed
59
+ - Quorum is a separate module (lib/rosett_ai/quorum/) — not part of engine interface
60
+ - Security constraints from security.yml apply to all engine code
61
+ - No ERB or eval-based templating for machine-parsed output (per ADR-006)
62
+ - Engine manifest schema must be documented and validated via JSON Schema
63
+ - doc/ENGINE_DEVELOPMENT_GUIDE.md must exist with manifest schema, component
64
+ interfaces, testing patterns, and packaging requirements
65
+ - "Engine target profiles must declare per-scope output directories: an
66
+ absolute path for global output and a relative path for scoped (local/
67
+ project) output resolved against the scope directory — see scope_hierarchy.yml"
68
+ - Engine detection must work at any scope level (global, local, project)
69
+
70
+ acceptance_criteria:
71
+ - lib/rosett_ai/engines/claude/ directory contains backend, config_adapter, detector, and manifest
72
+ - lib/rosett_ai/engines/generic/ directory contains backend and manifest
73
+ - bin/raictl compile --engine claude produces identical output to current bin/raictl compile
74
+ - bin/raictl compile --engine generic produces identical output to current bin/raictl compile --target generic
75
+ - bin/raictl engines list shows all known engines with installed/detected status
76
+ - bin/raictl engines detect probes system and reports which AI tools are present
77
+ - bin/raictl init suggests default engine based on autodetection
78
+ - Compiling for an engine that does not support a generic feature emits a warning
79
+ - bin/raictl compile --engine cursor --strict fails if any unsupported features are present
80
+ - anthropic gem is not in rosett-ai.gemspec runtime dependencies
81
+ - bin/raictl adopt runs local structural checks without any engine or API configured
82
+ - bin/raictl adopt --api --engine claude invokes Claude API for analysis
83
+ - All 251+ existing tests pass after engine restructure with zero behavioural change
84
+ - conf/engines/claude/manifest.yml declares capabilities, detection, and execution metadata
85
+ - conf/schemas/engine_manifest_schema.json validates all engine manifests
86
+ - doc/ENGINE_DEVELOPMENT_GUIDE.md covers manifest schema, component interfaces,
87
+ testing patterns, gem packaging, and CI setup for third-party engines
88
+ - "Engine TargetProfile includes output_dirs hash with global (absolute)
89
+ and scoped (relative) paths"
90
+ - Engine detection works correctly at any scope level — an engine configured
91
+ at global scope is available to all local and project scopes
92
+
93
+ examples:
94
+ - scenario: "User has only Claude Code installed, runs bin/raictl compile"
95
+ expected: |
96
+ Autodetected default engine is claude. Compiles behaviour YAML to
97
+ ~/.claude/rules/ in Claude markdown format. Output identical to
98
+ pre-restructure behaviour. No warnings.
99
+ not: "Compilation fails because no --engine flag provided. Output differs from before."
100
+ - scenario: "User installs Cursor alongside Claude, runs bin/raictl compile --engine cursor"
101
+ expected: |
102
+ Compiles behaviour YAML to .cursorrules in project root. Warns about
103
+ unsupported features (priority annotations, sensitive filtering).
104
+ Claude rules in ~/.claude/rules/ are unaffected.
105
+ not: "Cursor compilation modifies Claude rules. Unsupported features silently dropped."
106
+ - scenario: "CI pipeline runs bin/raictl compile --engine agents_md --strict"
107
+ expected: |
108
+ Compiles to AGENTS.md. If any behaviour uses features unsupported by
109
+ AGENTS.md engine, build fails with clear error listing unsupported features.
110
+ not: "Silently produces incomplete AGENTS.md. Build passes despite gaps."
111
+ - scenario: "Air-gapped government server with GPT-NeoX on vLLM, no internet"
112
+ expected: |
113
+ bin/raictl engines detect finds gpt_neox engine (vLLM endpoint configured).
114
+ bin/raictl adopt --api --engine gpt_neox analyses rules via local LLM.
115
+ No network calls to external services. Ollama not required.
116
+ not: "Adopt fails because no Anthropic API key. GPT-NeoX requires Ollama."
117
+ - scenario: "Claude engine declares per-scope output directories"
118
+ expected: |
119
+ Claude engine target profile contains:
120
+ output_dirs:
121
+ global: ~/.claude/rules/
122
+ scoped: .claude/rules/
123
+ bin/raictl compile --project resolves scoped path against project dir:
124
+ ~/projects/acme-api/.claude/rules/
125
+ bin/raictl compile --global writes to the absolute path: ~/.claude/rules/.
126
+ not: "All compiled output goes to ~/.claude/rules/ regardless of scope."
127
+
128
+ anti_patterns:
129
+ - Engine B depending on Engine A (e.g. GPT-NeoX requiring Ollama)
130
+ - Generic layer containing engine-specific keys or extensions
131
+ - LLM API gems in core rosett-ai dependencies
132
+ - Assuming any specific engine is installed or configured
133
+ - Forced common interface that all engines must implement
134
+ - Config compilation logic outside the engine that owns the format
135
+ - Hardcoded engine paths instead of manifest-driven detection
136
+ - Hardcoded output directories instead of scope-aware output_dirs
137
+ (global absolute + scoped relative) from engine target profiles
138
+
139
+ gui_notes: |
140
+ Engine directory structure:
141
+
142
+ lib/rosett_ai/engines/<name>/
143
+ backend.rb — Compiler backend (renders YAML → tool-native format)
144
+ config_adapter.rb — Settings compilation (tool-specific config files)
145
+ path_resolver.rb — Output path resolution (where to write)
146
+ scaffolder.rb — Init/scaffold (create tool directory structure)
147
+ detector.rb — Autodetection (is this tool installed?)
148
+ executor.rb — API/CLI invocation (for quorum, adopt --api)
149
+ validator.rb — Output validation (is compiled output correct?)
150
+ manifest.yml — Capability declaration, detection rules, execution metadata
151
+
152
+ All components are optional. Minimal engine (e.g. Cursor):
153
+ backend.rb + detector.rb + manifest.yml
154
+
155
+ Full engine (e.g. Claude):
156
+ All 8 files
157
+
158
+ Manifest structure:
159
+
160
+ name: claude
161
+ display_name: Claude Code
162
+ detection:
163
+ binaries: [claude]
164
+ config_dirs: [~/.claude]
165
+ env_vars: [ANTHROPIC_API_KEY]
166
+ capabilities:
167
+ behaviour_rules: true
168
+ design_constraints: true
169
+ priority_annotations: true
170
+ sensitive_filtering: true
171
+ source_metadata: true
172
+ execution:
173
+ invocable: true
174
+ methods: [api, cli]
175
+ api_gem: anthropic
176
+ cli_binary: claude
177
+ structured_output: true
178
+ output_dirs:
179
+ global: ~/.claude/rules/
180
+ scoped: .claude/rules/
181
+ supported_assets:
182
+ skills: { target: ".claude/skills/", format: "markdown" }
183
+ hooks: { target: ".claude/settings.json#hooks", format: "json" }
184
+ memory: { target: ".claude/memory/", format: "markdown" }
185
+ required_config:
186
+ - mcp_servers
187
+ - permissions
188
+ - api_settings
189
+
190
+ Quorum module (separate from engines):
191
+
192
+ lib/rosett_ai/quorum/
193
+ dispatcher.rb — Send analysis to N engines in parallel
194
+ collector.rb — Gather responses, handle timeouts
195
+ comparator.rb — Determine consensus/disagreements
196
+ strategies/
197
+ adopt.rb — Compare structured adopt findings
198
+ majority.rb — Simple majority vote
199
+ unanimous.rb — All must agree
200
+
201
+ interactions:
202
+ - action: "Compile rules for a specific engine"
203
+ tui: "bin/raictl compile --engine claude"
204
+ - action: "List available engines"
205
+ tui: "bin/raictl engines list"
206
+ - action: "Detect installed AI tools"
207
+ tui: "bin/raictl engines detect"
208
+ - action: "Show engine status"
209
+ tui: "bin/raictl engines status"
210
+ - action: "Run local-only adopt"
211
+ tui: "bin/raictl adopt"
212
+ - action: "Run API-based adopt via specific engine"
213
+ tui: "bin/raictl adopt --api --engine claude"
214
+ - action: "Run quorum adopt"
215
+ tui: "bin/raictl adopt --api --quorum"
216
+
217
+ preferences:
218
+ language: ruby
219
+ patterns:
220
+ - "Engine as namespace directory (lib/rosett_ai/engines/<name>/)"
221
+ - "Capability manifest with asset type contracts"
222
+ - "Data-driven detection from manifest.yml"
223
+ - "Optional components (only implement what applies)"
224
+ - "Strategy pattern for compiler backends"
225
+ - "No forced common interface across engines"
226
+ testing: rspec with per-engine specs, capability gap tests, manifest
227
+ validation, autodetection scenarios, and asset contract verification
228
+ gems:
229
+ - thor
230
+ - json_schemer
231
+ - zeitwerk
232
+
233
+ implementation_notes: |
234
+ v1.2.0 implementation diverged from the original design in key areas:
235
+
236
+ 1. Engine code lives in separate gems (rosett-ai-engine-claude,
237
+ rosett-ai-engine-agents-md) discovered via the plugin registry,
238
+ not in lib/rosett_ai/engines/<name>/ directories within core.
239
+
240
+ 2. Core provides: base_config_compiler.rb, detector.rb, registry.rb
241
+ as abstract base infrastructure. Engine gems implement the
242
+ concrete backends.
243
+
244
+ 3. Compiler backends (claude_backend, agents_md_backend, generic_backend)
245
+ live in lib/rosett_ai/compiler/backends/ as fallback implementations
246
+ for when engine gems are not installed.
247
+
248
+ 4. Quorum module not yet implemented — deferred to post-v1.2.0.
249
+
250
+ 5. Per-scope output_dirs (global absolute + scoped relative) not yet
251
+ in TargetProfile — uses a single output_dir field.
252
+
253
+ 6. doc/ENGINE_DEVELOPMENT_GUIDE.md exists and covers manifest schema,
254
+ component interfaces, and gem packaging.
255
+
256
+ These divergences are intentional: the external-gem model proved
257
+ cleaner for distribution and versioning than embedded directories.