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,214 @@
1
+ # Implement ci_pipeline.yml design document (P1)
2
+
3
+ **Branch**: `design_implementation`
4
+ **Date**: 2026-02-21
5
+ **Design doc**: `conf/design/ci_pipeline.yml` v1.0.0
6
+ **Commits**: bf9f15e (primary), 5f352e6 (mutant job)
7
+
8
+ ## Motivation
9
+
10
+ Without enforcement gates, security rules are suggestions, not constraints.
11
+ The CI pipeline turns the security, testing, and styles design documents into
12
+ merge-blocking reality. No code merges to main without passing all stages.
13
+
14
+ This is the fourth and final P1 domain. It depends on security (audit tools),
15
+ testing (test harness), and styles (linting tools) all being in place first.
16
+
17
+ ## Acceptance criteria
18
+
19
+ 11 of 12 acceptance criteria from `ci_pipeline.yml` are satisfied. One is
20
+ deferred with documented rationale:
21
+
22
+ | # | Criterion | Status | Evidence |
23
+ |---|-----------|--------|----------|
24
+ | 1 | GitLab CI YAML is valid and passes rai validate-ci-yaml | Met | `validate:ci_yaml` job runs `bin/raictl tooling validate-ci-yaml` |
25
+ | 2 | Pipeline has distinct stages in order | Met | validate > code_quality > security_scan > test > build |
26
+ | 3 | bundler-audit check exits non-zero on known CVEs | Met | Pre-existing `security:bundler_audit` job |
27
+ | 4 | ruby_audit check exits non-zero on Ruby stdlib CVEs | Met | New `security:ruby_audit` job |
28
+ | 5 | rubocop exits non-zero on any violation | Met | Pre-existing `quality:rubocop` job |
29
+ | 6 | reek exits non-zero on any code smell above threshold | Met | `quality:reek` job (exit code fix applied) |
30
+ | 7 | flay exits non-zero on structural duplication above threshold | Met | Enforced via overcommit pre-commit hook (mass 16) |
31
+ | 8 | flog exits non-zero on complexity above threshold | Deferred | ADR-001: covered by RuboCop Metrics cops |
32
+ | 9 | rspec produces JUnit XML report and coverage/ artifacts | Met | Pre-existing `test:rspec` job with artifacts |
33
+ | 10 | mutant runs only on merge_request_event and blocks merge | Met | `.gitlab-ci-files/test/mutant.yml` (`allow_failure: false`) |
34
+ | 11 | Build stage produces .deb package artifact | Met | Pre-existing `build:package` job |
35
+ | 12 | Pipeline duration under 15 minutes for push events | Met | Mutation testing excluded from push events |
36
+
37
+ ### Flog deferral (ADR-001)
38
+
39
+ Flog measures method complexity using an ABC-based scoring algorithm. RuboCop
40
+ already enforces the same concern through `Metrics/CyclomaticComplexity`
41
+ (max: 7) and `Metrics/PerceivedComplexity` (max: 8). Adding Flog would
42
+ duplicate enforcement. Decision recorded in `doc/decisions/001-flog-deferred.md`.
43
+
44
+ ## Changes by area
45
+
46
+ ### CI YAML validation job
47
+
48
+ **New file**: `.gitlab-ci-files/validate/ci-yaml.yml`
49
+
50
+ ```yaml
51
+ validate:ci_yaml:
52
+ stage: validate
53
+ extends:
54
+ - .ruby_base
55
+ - .resource_limits_small
56
+ script:
57
+ - bundle exec bin/raictl tooling validate-ci-yaml
58
+ ```
59
+
60
+ Validates all `.gitlab-ci-files/**/*.yml` files using the rosett-ai CLI's
61
+ `SupplementaryGitlabCiYamlValidator`. This catches YAML syntax errors in CI
62
+ configuration before they reach GitLab's own validator.
63
+
64
+ ### Version consistency job
65
+
66
+ **New file**: `.gitlab-ci-files/validate/version-consistency.yml`
67
+
68
+ ```yaml
69
+ validate:version_consistency:
70
+ stage: validate
71
+ extends:
72
+ - .ruby_base
73
+ - .resource_limits_small
74
+ script:
75
+ - bundle exec bin/raictl tooling check-versions
76
+ ```
77
+
78
+ Runs `VersionConsistencyChecker` to verify all Ruby version references in the
79
+ codebase match `.ruby-version`. Catches partial version updates that leave
80
+ stale references.
81
+
82
+ ### Reek exit code fix
83
+
84
+ **Commit**: bf9f15e
85
+
86
+ The `quality:reek` job previously discarded reek's exit code because the JSON
87
+ report redirection masked it:
88
+
89
+ ```diff
90
+ script:
91
+ - gem install reek --no-document
92
+ - |
93
+ - bundle exec reek --config .reek.yml --format json lib > reek-report.json || true
94
+ - bundle exec reek --config .reek.yml lib
95
+ + bundle exec reek --config .reek.yml --format json lib > reek-report.json
96
+ + REEK_EXIT=$?
97
+ + bundle exec reek --config .reek.yml lib
98
+ + exit $REEK_EXIT
99
+ ```
100
+
101
+ Now the JSON report is captured for artifacts AND the exit code is preserved
102
+ so smells actually block the pipeline.
103
+
104
+ ### Security scan jobs
105
+
106
+ **New file**: `.gitlab-ci-files/security_scan/ruby-audit.yml`
107
+
108
+ ```yaml
109
+ security:ruby_audit:
110
+ stage: security_scan
111
+ extends:
112
+ - .ruby_base
113
+ - .resource_limits_small
114
+ script:
115
+ - gem install bundler --no-document
116
+ - bundle exec ruby-audit check
117
+ artifacts:
118
+ when: on_failure
119
+ expire_in: 1 week
120
+ paths:
121
+ - ruby-audit-report.txt
122
+ ```
123
+
124
+ Scans Ruby's stdlib for known CVEs. Complements bundler-audit (which scans
125
+ gem dependencies). Together they cover the full Ruby dependency surface.
126
+
127
+ ### Stage ordering
128
+
129
+ The `.gitlab-ci.yml` includes are organized by stage:
130
+
131
+ ```text
132
+ validate: yaml.yml, json.yml, ruby-syntax.yml, version-consistency.yml, ci-yaml.yml
133
+ code_quality: rubocop.yml, reek.yml
134
+ security_scan: bundler-audit.yml, ruby-audit.yml, trivy.yml
135
+ test: rspec.yml, mutant.yml
136
+ build: package.yml
137
+ ```
138
+
139
+ This ordering ensures fast validation checks run first (catching YAML/JSON
140
+ errors in seconds), followed by increasingly expensive stages. Security scans
141
+ run before tests so CVE-affected code is caught even if tests pass.
142
+
143
+ ## CI pipeline stage flow
144
+
145
+ ```mermaid
146
+ flowchart TB
147
+ subgraph VALIDATE["validate"]
148
+ V1[yaml syntax]
149
+ V2[json syntax]
150
+ V3[ruby syntax]
151
+ V4[version consistency]
152
+ V5[ci-yaml validation]
153
+ end
154
+
155
+ subgraph CODE_QUALITY["code_quality"]
156
+ CQ1[rubocop]
157
+ CQ2[reek]
158
+ end
159
+
160
+ subgraph SECURITY["security_scan"]
161
+ S1[bundler-audit]
162
+ S2[ruby-audit]
163
+ S3[trivy]
164
+ end
165
+
166
+ subgraph TEST["test"]
167
+ T1[rspec + SimpleCov]
168
+ T2[mutant<br/>MR only]
169
+ end
170
+
171
+ subgraph BUILD["build"]
172
+ B1[.deb package]
173
+ end
174
+
175
+ VALIDATE --> CODE_QUALITY --> SECURITY --> TEST --> BUILD
176
+
177
+ VALIDATE -->|any fail| STOP1[Pipeline stops]
178
+ CODE_QUALITY -->|any fail| STOP2[Pipeline stops]
179
+ SECURITY -->|any fail| STOP3[Pipeline stops]
180
+ TEST -->|any fail| STOP4[Pipeline stops]
181
+
182
+ style STOP1 fill:#8b0000,color:#fff
183
+ style STOP2 fill:#8b0000,color:#fff
184
+ style STOP3 fill:#8b0000,color:#fff
185
+ style STOP4 fill:#8b0000,color:#fff
186
+ ```
187
+
188
+ ## Files created
189
+
190
+ | File | Purpose |
191
+ |------|---------|
192
+ | `.gitlab-ci-files/validate/ci-yaml.yml` | CI YAML validation job |
193
+ | `.gitlab-ci-files/validate/version-consistency.yml` | Version consistency check job |
194
+ | `.gitlab-ci-files/security_scan/ruby-audit.yml` | Ruby stdlib CVE scanning job |
195
+ | `doc/decisions/001-flog-deferred.md` | ADR: Flog deferred, covered by RuboCop Metrics |
196
+
197
+ ## Files modified
198
+
199
+ | File | Change |
200
+ |------|--------|
201
+ | `.gitlab-ci.yml` | Added 3 new include entries (ci-yaml, version-consistency, ruby-audit) |
202
+ | `.gitlab-ci-files/code_quality/reek.yml` | Fixed exit code handling (was silently swallowing failures) |
203
+ | `conf/design/ci_pipeline.yml` | Updated flog criterion with deferral annotation |
204
+
205
+ ## Verification
206
+
207
+ - [x] `bundle exec bin/raictl tooling validate-ci-yaml` — all CI YAML files valid
208
+ - [x] `bundle exec bin/raictl tooling check-versions` — all version references consistent
209
+ - [x] `bundle exec bundler-audit check` — 0 vulnerabilities
210
+ - [x] `bundle exec ruby-audit check` — 0 vulnerabilities
211
+ - [x] `bundle exec rubocop` — 0 offenses
212
+ - [x] `bundle exec reek lib/` — 0 warnings
213
+ - [x] `bundle exec rspec` — 437 examples, 0 failures
214
+ - [x] ADR-001 documents flog deferral rationale
@@ -0,0 +1,241 @@
1
+ # Compiler Multi-Target Pipeline (P2)
2
+
3
+ **Branch**: `design_implementation`
4
+ **Date**: 2026-02-21
5
+ **Design doc**: `conf/design/compiler.yml` v1.0.0 (draft -> approved)
6
+ **Depends on**: security, architecture
7
+
8
+ ## Motivation
9
+
10
+ The rai compiler is the core product capability: author configuration once
11
+ in a rich YAML format, compile down to target-specific output for different
12
+ AI assistants. Until this phase, the compiler was a monolithic
13
+ `BehaviourCompiler` class that hardcoded Claude Code's markdown format —
14
+ every method from discovery to rendering to orphan management lived in one
15
+ 219-line class.
16
+
17
+ This made it impossible to compile for non-Claude targets without forking
18
+ the entire compilation pipeline. The compiler.yml design document specifies
19
+ 9 acceptance criteria requiring pluggable backends, target profiles that
20
+ require no code changes, locale compilation, and sub-5-second performance
21
+ at scale.
22
+
23
+ This phase refactors the compiler into a strategy-pattern pipeline with
24
+ data-driven target profiles, extracts two concrete backends (Claude and
25
+ Generic), adds a locale compiler producing gettext and Qt Linguist output,
26
+ and wires `--target` and `--locales` flags into the CLI — all while
27
+ maintaining 100% backward compatibility with existing tests.
28
+
29
+ ## Acceptance criteria
30
+
31
+ | # | Criterion | Status | Evidence |
32
+ |---|-----------|--------|----------|
33
+ | 1 | `bin/raictl compile` produces output in ~/.claude/rules/ | Met (preserved) | Existing compile specs pass unchanged |
34
+ | 2 | `--target claude` produces CLAUDE.md-compatible markdown | Met | ClaudeBackend renders HTML metadata + priority annotations |
35
+ | 3 | `--target generic` produces lowest-common-denominator markdown | Met | GenericBackend renders plain markdown, no Claude specifics |
36
+ | 4 | `--simulate --verbose` shows diffs without writing | Met (preserved) | Existing simulate specs pass unchanged |
37
+ | 5 | `--vendor` writes lockfile | Met (preserved) | Existing vendor specs pass unchanged |
38
+ | 6 | `--locales` compiles i18n YAML to gettext and Qt formats | Met | LocaleCompiler produces .pot/.po and .ts files |
39
+ | 7 | New target profile in conf/targets/ requires no code changes | Met | TargetProfile.load + Backend.for factory; data-driven |
40
+ | 8 | Invalid source documents produce clear error messages | Met (preserved) | CompileError with file path and field details |
41
+ | 9 | 100 behaviour files compile in under 5 seconds | Met | Benchmark spec: 100 files in ~0.4s |
42
+
43
+ ## Architecture
44
+
45
+ ### Class hierarchy
46
+
47
+ ```text
48
+ RosettAi::Compiler::Backend (abstract base + .for() factory)
49
+ ├── RosettAi::Compiler::Backends::ClaudeBackend (extracted from BehaviourCompiler)
50
+ └── RosettAi::Compiler::Backends::GenericBackend (new, plain markdown)
51
+
52
+ RosettAi::Compiler::CompilationPipeline (shared pipeline, accepts backend:)
53
+ └── RosettAi::Compiler::BehaviourCompiler (backward-compat wrapper, defaults claude)
54
+
55
+ RosettAi::Compiler::CompiledOutput (Struct value object)
56
+ RosettAi::Compiler::TargetProfile (loads conf/targets/<name>.yml)
57
+ RosettAi::Compiler::LocaleCompiler (YAML -> gettext .po + Qt .ts)
58
+ ```
59
+
60
+ ### Pipeline flow
61
+
62
+ ```mermaid
63
+ flowchart LR
64
+ subgraph INPUT["Source"]
65
+ YAML["conf/behaviour/*.yml<br/>conf/design/*.yml<br/>conf/tooling/*.yml"]
66
+ LOCALE["locales/*.yml"]
67
+ end
68
+
69
+ subgraph PIPELINE["CompilationPipeline"]
70
+ DISC[discover_categories]
71
+ VAL[validate!]
72
+ RENDER[backend.render]
73
+ CHECK[checksum]
74
+ DIFF[diff]
75
+ LOCK[lockfile_data]
76
+ ORPHAN[orphaned_files]
77
+ end
78
+
79
+ subgraph BACKEND["Backend (strategy)"]
80
+ CLAUDE[ClaudeBackend<br/>HTML metadata<br/>priority annotations]
81
+ GENERIC[GenericBackend<br/>plain markdown<br/>no annotations]
82
+ end
83
+
84
+ subgraph PROFILE["Target Profile"]
85
+ TP["conf/targets/claude.yml<br/>conf/targets/generic.yml"]
86
+ end
87
+
88
+ subgraph OUTPUT["Output"]
89
+ RULES["~/.claude/rules/*.md"]
90
+ POT[".pot / .po"]
91
+ TS[".ts (Qt)"]
92
+ end
93
+
94
+ YAML --> DISC --> VAL --> RENDER --> CHECK
95
+ TP --> BACKEND
96
+ BACKEND --> RENDER
97
+ CHECK --> DIFF --> LOCK
98
+ CHECK --> ORPHAN
99
+ RENDER --> RULES
100
+
101
+ LOCALE --> POT
102
+ LOCALE --> TS
103
+
104
+ style CLAUDE fill:#2d6a2d,color:#fff
105
+ style GENERIC fill:#2d6a2d,color:#fff
106
+ ```
107
+
108
+ ## Changes by area
109
+
110
+ ### Backend abstraction (Steps 1-2)
111
+
112
+ Introduced `RosettAi::Compiler::Backend` as an abstract base class with a
113
+ `.for(target_name)` factory method, following the `Compressor.for()` pattern
114
+ from `RosettAi::Backup`. The factory loads a `TargetProfile`, resolves the
115
+ backend class from a constant map, and returns an instantiated backend.
116
+
117
+ `ClaudeBackend` was extracted directly from the original
118
+ `BehaviourCompiler#render` method — identical output, now isolated behind
119
+ the strategy interface. `GenericBackend` produces lowest-common-denominator
120
+ markdown: no HTML comment metadata, no priority annotations, just headings
121
+ and rule descriptions.
122
+
123
+ Both backends share the `managed_file?` implementation from the base class,
124
+ using their distinct `generated_marker` prefixes to identify which files
125
+ they manage. This ensures orphan detection works correctly across backends.
126
+
127
+ ### CompiledOutput value object (Step 3)
128
+
129
+ Replaced the raw `Hash` returned by `compile()` with a frozen `Struct`.
130
+ Ruby `Struct` supports both `.field` and `[:field]` access, so all existing
131
+ callers that use `info[:content]` continue to work without modification.
132
+
133
+ ### Target profile system (Step 4)
134
+
135
+ Created `conf/targets/claude.yml` and `conf/targets/generic.yml` as
136
+ declarative profiles validated against `conf/schemas/target_schema.json`.
137
+ The `TargetProfile` loader validates profiles at load time and exposes
138
+ field accessors. Adding a new target (e.g., Mistral) requires only a new
139
+ YAML file — no code changes.
140
+
141
+ The JSON Schema enforces a strict enum for `backend` (`claude`, `generic`)
142
+ and `output_format` (`markdown`, `json`, `yaml`), with optional fields for
143
+ `engine_version`, `output_dir`, `max_context_window`, and `rendering` flags.
144
+
145
+ ### Pipeline extraction (Step 5)
146
+
147
+ `BehaviourCompiler` was split into:
148
+
149
+ - **`CompilationPipeline`** — owns all pipeline mechanics (discover, validate,
150
+ compile, checksum, diff, lockfile, orphans). Delegates `render()` and
151
+ `managed_file?()` to the injected backend.
152
+ - **`BehaviourCompiler`** — thin subclass that preserves the original 3-argument
153
+ constructor (`source_dir:`, `target_dir:`, `schema_dir:`) and defaults the
154
+ backend to `ClaudeBackend`.
155
+
156
+ **Backward compatibility gate**: all 26 existing `BehaviourCompiler` specs
157
+ and all 11 existing compile task specs passed without modification at this
158
+ step.
159
+
160
+ ### CLI extensions (Step 6)
161
+
162
+ Added `--target` (string, default `claude`) and `--locales` (boolean) options
163
+ to the compile Thor task. The `build_compiler` method now instantiates
164
+ `CompilationPipeline` with the target-specific backend instead of hardcoding
165
+ `BehaviourCompiler`.
166
+
167
+ ### Locale compiler (Step 7)
168
+
169
+ `LocaleCompiler` reads `locales/*.yml` files, flattens nested YAML keys
170
+ into dotted paths, and generates:
171
+
172
+ - **Gettext**: `.pot` template (English source, empty `msgstr`) and
173
+ per-locale `.po` files (populated `msgstr`). Standard PO format with
174
+ project headers.
175
+ - **Qt Linguist**: `.ts` XML files following the TS 2.1 DTD. Messages are
176
+ grouped by context (derived from key path hierarchy).
177
+
178
+ Output structure:
179
+
180
+ ```text
181
+ locales/compiled/
182
+ ├── gettext/
183
+ │ ├── rosett-ai.pot
184
+ │ └── en/LC_MESSAGES/rosett-ai.po
185
+ └── qt/
186
+ └── nncc_en.ts
187
+ ```
188
+
189
+ ### Performance (Step 8)
190
+
191
+ Benchmark spec generates 100 behaviour fixture files and asserts compilation
192
+ completes in under 5 seconds. Actual measured time: ~0.4 seconds.
193
+
194
+ ## Files created (19)
195
+
196
+ | File | Purpose |
197
+ |------|---------|
198
+ | `lib/rosett_ai/compiler/backend.rb` | Abstract backend base with .for() factory |
199
+ | `lib/rosett_ai/compiler/backends/claude_backend.rb` | Claude Code markdown renderer |
200
+ | `lib/rosett_ai/compiler/backends/generic_backend.rb` | Generic plain markdown renderer |
201
+ | `lib/rosett_ai/compiler/compilation_pipeline.rb` | Shared compilation pipeline |
202
+ | `lib/rosett_ai/compiler/compiled_output.rb` | CompiledOutput Struct value object |
203
+ | `lib/rosett_ai/compiler/target_profile.rb` | Target profile loader and validator |
204
+ | `lib/rosett_ai/compiler/locale_compiler.rb` | YAML to gettext + Qt compiler |
205
+ | `conf/targets/claude.yml` | Claude Code target profile |
206
+ | `conf/targets/generic.yml` | Generic AI target profile |
207
+ | `conf/schemas/target_schema.json` | JSON Schema for target profiles |
208
+ | `locales/en.yml` | English locale source file |
209
+ | `spec/rosett_ai/compiler/backend_spec.rb` | Backend abstract base tests |
210
+ | `spec/rosett_ai/compiler/backends/claude_backend_spec.rb` | ClaudeBackend tests |
211
+ | `spec/rosett_ai/compiler/backends/generic_backend_spec.rb` | GenericBackend tests |
212
+ | `spec/rosett_ai/compiler/compilation_pipeline_spec.rb` | Pipeline tests + benchmark |
213
+ | `spec/rosett_ai/compiler/compiled_output_spec.rb` | CompiledOutput tests |
214
+ | `spec/rosett_ai/compiler/target_profile_spec.rb` | TargetProfile tests |
215
+ | `spec/rosett_ai/compiler/locale_compiler_spec.rb` | LocaleCompiler tests |
216
+ | `spec/support/shared_examples/compiler_backend.rb` | Backend interface contract |
217
+
218
+ ## Files modified (8)
219
+
220
+ | File | Change |
221
+ |------|--------|
222
+ | `lib/rosett_ai/compiler/behaviour_compiler.rb` | Refactored to thin wrapper around CompilationPipeline |
223
+ | `lib/rosett_ai/thor/tasks/compile.rb` | Added --target and --locales options, uses CompilationPipeline |
224
+ | `spec/rosett_ai/compiler/behaviour_compiler_spec.rb` | Unchanged (backward compatibility preserved) |
225
+ | `spec/rosett_ai/thor/tasks/compile_spec.rb` | Updated stub from rules_target_dir to resolve_target_dir, added --target generic test |
226
+ | `spec/rosett_ai/thor/tasks/validate_spec.rb` | Excluded internal target_schema from category coverage assertion |
227
+ | `spec/spec_helper.rb` | Added target_schema copy, targets dir, create_target_profile helper |
228
+ | `.reek.yml` | Added exclusions for new pipeline, backend, and locale classes |
229
+ | `conf/design/compiler.yml` | Status: draft -> approved |
230
+
231
+ ## Verification
232
+
233
+ - [x] `bundle exec rspec` — 579 examples, 0 failures
234
+ - [x] `bundle exec rubocop` — 96 files, 0 offenses
235
+ - [x] `bundle exec reek lib/rosett_ai/compiler/` — 0 warnings
236
+ - [x] `bin/raictl compile --simulate --verbose` — correct output
237
+ - [x] `bin/raictl compile --target generic --simulate --verbose` — generic markers, no Claude metadata
238
+ - [x] `bin/raictl compile --locales --simulate --verbose` — locale paths reported
239
+ - [x] Performance benchmark: 100 files in ~0.4s (< 5s threshold)
240
+ - [x] All 26 original BehaviourCompiler specs pass unchanged
241
+ - [x] All 11 original compile task specs pass unchanged
@@ -0,0 +1,61 @@
1
+ # Add `config show` and `design show` / `design list` subcommands
2
+
3
+ **Date**: 2026-02-21
4
+ **Branch**: `design_implementation`
5
+ **Design doc**: `conf/design/claude_code_configuration.yml` (criterion 18 added)
6
+
7
+ ## Summary
8
+
9
+ Adds `config show SCOPE` and `design show NAME` / `design list` subcommands
10
+ to close feature gaps identified after completing the CC config compiler (P2).
11
+ These provide read-only inspection of compiled configuration and design
12
+ documents without modifying any files.
13
+
14
+ ## New commands
15
+
16
+ ```bash
17
+ bin/raictl config show user # Compiled JSON with secrets masked
18
+ bin/raictl config show user --raw # YAML source, sanitized
19
+ bin/raictl design show security # Summary: header, intent, constraints, criteria
20
+ bin/raictl design show security --full # All sections including examples, preferences
21
+ bin/raictl design list # Table of all design documents
22
+ ```
23
+
24
+ ## New files (2)
25
+
26
+ | File | Purpose |
27
+ |------|---------|
28
+ | `lib/rosett_ai/config/masking_secret_resolver.rb` | Drop-in SecretResolver replacement returning `"***"` for all `${secret:...}` values |
29
+ | `spec/rosett_ai/config/masking_secret_resolver_spec.rb` | 15 tests: resolve/resolve_all for all backends, pass-through, nested structures |
30
+
31
+ ## Modified files (7)
32
+
33
+ | File | Change |
34
+ |------|--------|
35
+ | `lib/rosett_ai/config/compiler.rb` | Accept optional `secret_resolver:` keyword in `initialize` |
36
+ | `lib/rosett_ai/thor/tasks/config.rb` | Add `show SCOPE` with `--raw` flag, 3 private helpers |
37
+ | `lib/rosett_ai/thor/tasks/design.rb` | Add `show NAME` with `--full`, `list`, 9 private helpers |
38
+ | `spec/rosett_ai/thor/tasks/config_spec.rb` | 5 new tests for config show |
39
+ | `spec/rosett_ai/thor/tasks/design_spec.rb` | 15 new tests for design show + list |
40
+ | `conf/design/claude_code_configuration.yml` | Add acceptance criterion 18 |
41
+ | `.reek.yml` | Exclusions for new methods |
42
+
43
+ ## Key design decisions
44
+
45
+ 1. **MaskingSecretResolver over flag** — injecting a resolver that returns
46
+ `"***"` is safer than adding a `mask:` flag to SecretResolver. The real
47
+ resolver never sees show-mode traffic, so there is no risk of accidentally
48
+ leaking secrets.
49
+
50
+ 2. **Compile in simulate mode** — `config show` compiles in-memory with
51
+ `simulate: true` so no files are written, ever.
52
+
53
+ 3. **Design show: summary by default, --full for complete** — mirrors how
54
+ users typically inspect documents. Constraints and acceptance criteria are
55
+ always shown; examples and anti-patterns require `--full`.
56
+
57
+ ## Verification
58
+
59
+ - 764 tests, 0 failures, 92.52% line coverage
60
+ - RuboCop: 0 offenses (113 files)
61
+ - Reek: 0 warnings