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,100 @@
1
+ ---
2
+ name: ci_pipeline
3
+ domain: ci
4
+ version: 1.1.0
5
+ status: implemented
6
+ priority: 1
7
+ author: hugo
8
+ created_at: "2026-02-18"
9
+ modified_at: "2026-03-17"
10
+ modified_by: claude
11
+ depends_on:
12
+ - security
13
+ - testing
14
+ - styles
15
+
16
+ intent: |
17
+ Define the CI/CD pipeline that enforces security and testing constraints on
18
+ every code change. Without enforcement gates, security rules are suggestions,
19
+ not constraints. This pipeline must be in place before feature development
20
+ begins. It is the mechanism that ensures the security and testing design
21
+ documents are not just documentation but are actively enforced on every
22
+ commit and merge request.
23
+
24
+ constraints:
25
+ - No code merges to main without passing all CI stages
26
+ - Security audit stage (bundler-audit, ruby_audit) must run first and block on any finding
27
+ - Static analysis (rubocop, reek) must block on any violation — no warnings-only mode
28
+ - Test stage must produce JUnit XML artifacts for GitLab integration
29
+ - Mutation testing runs on merge requests only (too slow for every push)
30
+ - Mutation testing must block merge if score drops below threshold
31
+ - Mutation testing timeout is 30 minutes maximum
32
+ - Coverage reports must be preserved as CI artifacts
33
+ - Pipeline must complete in under 15 minutes for push events (excluding mutation testing)
34
+ - No allow_failure on security or test stages
35
+
36
+ acceptance_criteria:
37
+ - GitLab CI YAML is valid and passes rai validate-ci-yaml
38
+ - Pipeline has distinct stages in order — audit, lint, test, mutation, build
39
+ - bundler-audit check exits non-zero on known CVEs
40
+ - ruby_audit check exits non-zero on Ruby stdlib CVEs
41
+ - rubocop exits non-zero on any violation
42
+ - reek exits non-zero on any code smell above configured threshold
43
+ - flay exits non-zero on structural duplication above threshold
44
+ - flog exits non-zero on complexity above threshold (deferred — see ADR-001, covered by RuboCop Metrics cops)
45
+ - rspec produces JUnit XML report and coverage/ artifacts
46
+ - mutant runs only on merge_request_event and blocks merge on score drop
47
+ - Build stage produces .deb package artifact
48
+ - Pipeline duration is under 15 minutes for push events
49
+
50
+ examples:
51
+ - scenario: "Developer pushes a commit with YAML.load in new code"
52
+ expected: |
53
+ Lint stage fails: RuboCop flags YAML.load as security violation.
54
+ Pipeline stops. Developer must fix to YAML.safe_load before re-pushing.
55
+ not: "Pipeline passes with a warning. Code merges with unsafe YAML parsing."
56
+ - scenario: "A gem dependency has a new CVE published"
57
+ expected: |
58
+ Next CI run fails at audit stage. bundler-audit reports the CVE with
59
+ advisory URL. Pipeline blocks. Developer updates gem or adds justified
60
+ exception to .bundler-audit.yml.
61
+ not: "CVE is silently ignored. Pipeline passes with vulnerable dependency."
62
+ - scenario: "Merge request adds new Compiler class with AI-generated tests"
63
+ expected: |
64
+ Push stages pass (audit, lint, unit test). Mutation stage runs on changed
65
+ files. If mutant score >= 85%, MR is mergeable. If score < 85%, MR is
66
+ blocked with mutation report showing surviving mutations.
67
+ not: "Mutation testing is skipped. MR merges without test quality validation."
68
+ - scenario: "Developer adds a new feature but forgets to write tests"
69
+ expected: |
70
+ SimpleCov minimum_coverage_by_file (80%) fails for the new file.
71
+ Pipeline blocks at test stage.
72
+ not: "Untested code merges. Coverage drops silently."
73
+
74
+ anti_patterns:
75
+ - Using allow_failure on security or test stages
76
+ - Skipping stages with CI variables or manual overrides
77
+ - Running mutation testing on every push (too slow, blocks development)
78
+ - Not preserving test artifacts (coverage reports, JUnit XML)
79
+ - Hardcoding credentials or tokens in CI configuration
80
+ - Using --no-verify or equivalent to bypass pre-commit hooks
81
+ - Ignoring bundler-audit advisories without documented justification
82
+
83
+ preferences:
84
+ language: ruby
85
+ patterns:
86
+ - fail_fast_pipeline
87
+ - artifacts_for_debugging
88
+ - merge_request_gates
89
+ gems:
90
+ - bundler-audit
91
+ - ruby_audit
92
+ - rubocop
93
+ - rubocop-performance
94
+ - rubocop-rspec
95
+ - reek
96
+ - flay
97
+ - rspec
98
+ - simplecov
99
+ - mutant-rspec
100
+ - rspec-junit-formatter
@@ -0,0 +1,157 @@
1
+ ---
2
+ name: claude_code_configuration
3
+ domain: core
4
+ version: 2.0.0
5
+ status: implemented
6
+ priority: 2
7
+ author: hugo
8
+ created_at: "2026-02-20"
9
+ modified_at: "2026-03-17"
10
+ modified_by: claude
11
+ depends_on:
12
+ - security
13
+ - architecture
14
+ - compiler
15
+ - engine_architecture
16
+
17
+ intent: |
18
+ Define a YAML-based authoritative configuration format for AI tool
19
+ settings that compiles to native format via the engine-plugin pattern.
20
+ Core provides the compilation framework (BaseConfigCompiler, SecretResolver,
21
+ MaskingSecretResolver, CompileResult) and CLI commands (rai config compile,
22
+ raictl config show). Each engine provides the domain-specific transformation
23
+ logic: scope routing, key mapping, version compatibility checks, and
24
+ format-specific output.
25
+
26
+ For Claude Code, the rosett-ai-engine-claude gem implements ConfigCompiler,
27
+ DomainTransformer, ScopeRouter, and KeyMap to compile scope YAML files
28
+ into Claude Code's native JSON settings across all four scopes (managed,
29
+ user, project, local). Other engines may implement config_compiler_class
30
+ to compile their own tool-specific settings.
31
+
32
+ The goal is a single source of truth (scope-specific YAML files maintained
33
+ by the engine) that eliminates manual JSON editing, enforces schema
34
+ validation, supports version compatibility assertions, and handles
35
+ secrets resolution without exposing sensitive values in source.
36
+
37
+ constraints:
38
+ - All YAML files MUST be parseable with YAML.safe_load — no custom tags,
39
+ no permitted_classes, no extensions to the safe deserialisation surface
40
+ - Secret references use string convention "${secret:backend:key}" resolved
41
+ by deterministic string parser — never regex — to eliminate ReDoS vectors
42
+ - Secret resolution is single-pass only — resolved values are never
43
+ re-scanned for further references (prevents recursive injection)
44
+ - The secrets resolver MUST fail loudly (raise, never return nil) when a
45
+ referenced secret is missing or inaccessible
46
+ - File-backend secrets MUST validate 0600 permissions and reject files
47
+ owned by other users (prevent symlink/race attacks)
48
+ - File-backend secrets MUST enforce a size cap (64 KiB) to prevent
49
+ resource exhaustion from reading device files or oversized inputs
50
+ - Path-backend secrets MUST reject path traversal (no ".." components)
51
+ and validate against a whitelist of allowed directories
52
+ - Each YAML scope file compiles to exactly one native target — the
53
+ mapping is 1:1, never 1:many or many:1
54
+ - Configuration compilation follows the engine-plugin pattern — core
55
+ provides the abstract framework (BaseConfigCompiler), the engine
56
+ provides domain-specific transformation via config_compiler_class
57
+ - Core MUST NOT contain any engine-specific key mappings, scope routes,
58
+ or domain transformation logic — these belong in the engine gem
59
+ - No design or implementation in this document may contradict the security
60
+ design document (conf/design/security.yml)
61
+
62
+ acceptance_criteria:
63
+ # Core framework criteria
64
+ - rai config compile delegates to the active engine's config_compiler_class
65
+ via the plugin registry (RosettAi::Plugins::Registry)
66
+ - BaseConfigCompiler provides schema validation, SHA256 diffing, file I/O,
67
+ and compile result tracking that all engines inherit
68
+ - SecretResolver resolves ${secret:env:*}, ${secret:file:*}, and
69
+ ${secret:path:*} references using deterministic string parsing (no regex)
70
+ - MaskingSecretResolver replaces all ${secret:*} values with "***" without
71
+ resolving actual secrets, used by rai config show
72
+ - The --simulate flag shows a diff of what would change in each target
73
+ file without writing anything
74
+ - The --verbose flag shows processing details during compilation
75
+ - CompileResult struct tracks scope, paths, json_data, warnings, action,
76
+ and diff for each compiled file
77
+ - Missing secrets cause compilation to abort with a clear error message
78
+ naming the missing reference and the file where it was declared
79
+ - No regex is used anywhere in the secrets resolution path
80
+ # Engine-side criteria (satisfied by rosett-ai-engine-claude)
81
+ - Engine provides ConfigCompiler, DomainTransformer, ScopeRouter, and
82
+ KeyMap classes that handle Claude Code-specific compilation
83
+ - Engine's ScopeRouter maps scope names to target file paths (managed,
84
+ user, project, local)
85
+ - Engine's DomainTransformer converts YAML domains to JSON using an
86
+ explicit KeyMap (snake_case to camelCase, not algorithmic)
87
+ - Engine checks version compatibility constraints against the installed
88
+ Claude Code version at compile time (warnings, not errors)
89
+ - RSpec tests exist for the compiler, schema validation, and secrets
90
+ resolver with mutant-verified kill rates
91
+
92
+ examples:
93
+ - scenario: User compiles their personal configuration
94
+ expected: >
95
+ "bin/raictl config compile" resolves the active engine via the plugin
96
+ registry, delegates to the engine's ConfigCompiler, resolves any
97
+ secret references, and writes the native settings file.
98
+ not: >
99
+ The compiler silently overwrites settings without showing what
100
+ changed, or leaves secret reference strings unresolved in the output
101
+
102
+ - scenario: A secret reference points to an unset environment variable
103
+ expected: >
104
+ Compilation aborts with "Error: secret 'env:ANTHROPIC_API_KEY'
105
+ could not be resolved — environment variable ANTHROPIC_API_KEY
106
+ is not set"
107
+ not: >
108
+ The compiler writes a file containing the literal string
109
+ "${secret:env:ANTHROPIC_API_KEY}" or a null/empty value
110
+
111
+ - scenario: No engine provides a config_compiler_class
112
+ expected: >
113
+ "bin/raictl config compile" raises an error explaining that the
114
+ active engine does not support configuration compilation
115
+ not: >
116
+ The command silently does nothing or crashes with a NoMethodError
117
+
118
+ - scenario: A crafted input attempts ReDoS via nested secret patterns
119
+ expected: >
120
+ The deterministic string parser processes it in O(n) time.
121
+ "${secret:env:${secret:env:NESTED}}" is treated as a literal string
122
+ because it does not match the exact prefix/suffix pattern
123
+ not: >
124
+ The parser enters catastrophic backtracking or hangs
125
+
126
+ - scenario: User runs config compile --simulate
127
+ expected: >
128
+ A diff is shown for each target file (additions in green, removals
129
+ in red) without writing any files to disk
130
+ not: >
131
+ Files are modified during simulation, or no output is shown
132
+
133
+ anti_patterns:
134
+ - Using regex for secret reference detection or resolution — use
135
+ deterministic string parsing (start_with?/end_with?/split) only
136
+ - Storing actual secret values in YAML source files, even temporarily
137
+ - Using YAML custom tags (!secret, !vault, etc.) which require
138
+ permitted_classes and widen the safe_load deserialisation surface
139
+ - Putting engine-specific key mappings or scope routes in core — these
140
+ belong in the engine gem
141
+ - Recursively resolving secret references (resolved values must never
142
+ be re-scanned for further ${secret:...} patterns)
143
+ - Silently ignoring missing secrets (returning nil or empty string)
144
+ - Writing compiled files when the source YAML has not changed
145
+ (wasteful I/O and misleading timestamps)
146
+
147
+ preferences:
148
+ language: ruby
149
+ testing: rspec with factory_bot and mutant-rspec
150
+ gems:
151
+ - psych
152
+ - json_schemer
153
+ - diffy
154
+ patterns:
155
+ - compiler_pattern
156
+ - resolver_pattern
157
+ - engine_plugin_delegation
@@ -0,0 +1,128 @@
1
+ ---
2
+ name: compiler
3
+ domain: compiler
4
+ version: 2.0.0
5
+ status: draft
6
+ priority: 2
7
+ author: hugo
8
+ created_at: "2026-02-18"
9
+ modified_at: "2026-03-23"
10
+ modified_by: claude
11
+ depends_on:
12
+ - security
13
+ - architecture
14
+ - scope_hierarchy
15
+
16
+ intent: |
17
+ Define the compilation pipeline that transforms source documents (behaviours,
18
+ design specs, locale files) into target-specific output formats. This is the
19
+ core product capability of Rosett-AI: author once in the richest format, compile
20
+ down per AI target. The compiler must be pluggable to support new AI models
21
+ without code changes, and must enforce security constraints during all file
22
+ operations (safe YAML parsing, path validation, permission setting).
23
+
24
+ Compilation is scope-aware: the compiler resolves source directories from the
25
+ active scope hierarchy (global, local, project) before operating. Source files
26
+ are discovered from scope-appropriate directories, merged according to the
27
+ configured merge strategies, and written to scope-appropriate output locations
28
+ as declared by each engine's target profile. CLI flags (--global, --local,
29
+ --project) allow users to force a specific scope; without flags, the scope is
30
+ auto-detected from the user's working directory. See scope_hierarchy.yml for
31
+ the full scope specification.
32
+
33
+ constraints:
34
+ - All YAML parsing must use YAML.safe_load with explicit permitted_classes
35
+ - All output file writes must validate target path is within allowed directories
36
+ - All output files must be written with explicit permissions (0644)
37
+ - Compiler backends are pluggable via conf/targets/ profiles
38
+ - Source documents (conf/behaviour/, conf/design/) are never modified by compilation —
39
+ the sole exception is `rai retrofit`, which writes to source directories as a
40
+ controlled reverse-compilation operation (see retrofit.yml)
41
+ - Compilation must be idempotent (running twice produces identical output)
42
+ - Dry-run mode (--simulate) must never write to disk
43
+ - Verbose mode must never expose secrets or API keys in output
44
+ - Compilation errors must identify the source file and line/field that caused the error
45
+ - Locale compilation must produce platform-native formats (gettext, Qt Linguist)
46
+ - Compilation is scope-aware — source directories are resolved from the active
47
+ scope hierarchy (see scope_hierarchy.yml)
48
+ - CLI flags --global, --local, --project select a specific scope; without flags,
49
+ scope is auto-detected from the working directory
50
+ - "Each engine's target profile declares output directories: an absolute path
51
+ for global output and a relative path for scoped (local/project) output.
52
+ The compiler resolves the relative path against the active scope directory"
53
+ - Output target directory is never hardcoded — it is resolved from the engine's
54
+ target profile and the active scope
55
+
56
+ acceptance_criteria:
57
+ - bin/raictl compile produces output files in scope-resolved output directories
58
+ (e.g. ~/.claude/rules/ for global scope, <project>/.claude/rules/ for project scope)
59
+ - bin/raictl compile --engine claude produces CLAUDE.md-compatible markdown rules
60
+ - bin/raictl compile --engine generic produces lowest-common-denominator markdown
61
+ - bin/raictl compile --simulate --verbose shows scope-resolved source directories,
62
+ target output paths, and diffs — without writing any files
63
+ - bin/raictl compile --vendor writes a lockfile recording compiled state
64
+ - bin/raictl compile --locales compiles ruby-i18n YAML to gettext and Qt formats
65
+ - Adding a new target profile in conf/targets/ requires no code changes
66
+ - Invalid source documents produce clear error messages identifying the problem
67
+ - Compilation of 100 behaviour files completes in under 5 seconds
68
+ - bin/raictl compile --global compiles only global-scope sources to global output
69
+ - bin/raictl compile --local compiles merged global+local sources to local output
70
+ - bin/raictl compile --project compiles merged global+local+project sources to project output
71
+ - bin/raictl compile (no flag) auto-detects scope from working directory
72
+ - Compiler resolves source directory from the active scope before reading any files
73
+ - "Each engine's target profile declares output directories (global absolute,
74
+ scoped relative) — see scope_hierarchy.yml and engine_architecture.yml"
75
+
76
+ examples:
77
+ - scenario: "User runs bin/raictl compile from a project directory"
78
+ expected: |
79
+ Resolves scope from working directory: discovers project, local (if present),
80
+ and global source directories. Merges sources per scope hierarchy. Compiles
81
+ to project-scope output directory (e.g. <project>/.claude/rules/).
82
+ Sets 0644 permissions. Reports count of compiled rules and active scope.
83
+ not: "Ignores working directory. Always compiles from rosett-ai's own conf/."
84
+ - scenario: "User runs bin/raictl compile --engine mistral"
85
+ expected: |
86
+ Reads conf/targets/mistral.yml for model capabilities. Compiles behaviours
87
+ to flat markdown format (no YAML in prompt). Truncates or chunks if output
88
+ exceeds max_context. Writes to configured output location.
89
+ not: "Uses Claude-specific formatting for Mistral. Ignores context window limits."
90
+ - scenario: "A behaviour file has invalid YAML syntax"
91
+ expected: |
92
+ Compilation stops for that file. Error message includes filename and
93
+ parse error details. Other valid files still compile. Exit code is non-zero.
94
+ not: "YAML.load is used and succeeds despite syntax issues. Error is swallowed."
95
+ - scenario: "User runs bin/raictl compile --simulate --verbose"
96
+ expected: |
97
+ Shows scope resolution: 'Scope: project (~/projects/acme-api/.rosett-ai/)'.
98
+ Shows source directories per scope. Shows diff of what would change
99
+ on disk at scope-resolved output paths. Zero files written. Exit code 0.
100
+ not: "Actually writes files despite --simulate flag. Omits scope information."
101
+ - scenario: "User runs bin/raictl compile --global"
102
+ expected: |
103
+ Compiles only global-scope sources (~/.config/rosett-ai/conf/) to global
104
+ output directories. Local and project scopes are ignored even if
105
+ .rosett-ai/ markers exist in the current directory tree.
106
+ not: "Merges all scopes. Project-specific rules appear in global output."
107
+
108
+ anti_patterns:
109
+ - Using YAML.load instead of YAML.safe_load during compilation
110
+ - Writing output to arbitrary paths without validation
111
+ - Modifying source documents during compilation
112
+ - Hardcoding AI model assumptions instead of reading target profiles
113
+ - Silently skipping invalid source documents without error reporting
114
+ - Non-idempotent compilation (different output on repeated runs with same input)
115
+ - Hardcoding output directory (e.g. ~/.claude/rules/) instead of resolving from scope
116
+ - Assuming a single fixed source directory for all invocations
117
+ - Ignoring --global/--local/--project flags
118
+
119
+ preferences:
120
+ language: ruby
121
+ patterns:
122
+ - strategy_pattern_for_target_backends
123
+ - pipeline_pattern_for_compilation_stages
124
+ - value_objects_for_compiled_output
125
+ testing: rspec with file-based fixtures for input/output validation
126
+ gems:
127
+ - json_schemer
128
+ - diffy
@@ -0,0 +1,153 @@
1
+ ---
2
+ name: comply
3
+ domain: security
4
+ version: 0.1.0
5
+ status: implemented
6
+ priority: 2
7
+ author: hugo
8
+ created_at: "2026-03-15"
9
+ modified_at: "2026-03-16"
10
+ modified_by: claude
11
+ depends_on:
12
+ - security
13
+ - licensing_system
14
+ - policy_management
15
+ - error_handling
16
+ - engine_architecture
17
+ #
18
+ intent: |
19
+ Automate compliance checks for EU CRA and NIS2 directives, GPL-3.0
20
+ licensing requirements, and organisational policy adherence. Surface
21
+ compliance gaps before release rather than after deployment by providing
22
+ CRA vulnerability disclosure verification, SBOM generation, SPDX header
23
+ checks, and dependency license auditing through a single `rai comply`
24
+ command with machine-readable output for CI integration.
25
+
26
+ SBOM generation is a core capability: `rai comply --sbom` produces a
27
+ CycloneDX JSON document from Gemfile.lock and system metadata using the
28
+ syft CLI (when available) or a built-in Ruby fallback that parses
29
+ Gemfile.lock directly. The SBOM includes component name, version, PURL,
30
+ license SPDX identifier, and supplier. SPDX-format output is also
31
+ supported via `--sbom-format spdx` for organisations that mandate SPDX
32
+ over CycloneDX. SBOM output is written to a configurable path (default
33
+ `sbom.cdx.json` or `sbom.spdx.json` in the project root).
34
+
35
+ Comply is the compliance verification layer. It runs checks against
36
+ declarative rules. Policy management (policy_management.yml) defines
37
+ what policies apply to a project. Comply verifies that the project
38
+ meets those policies and produces an auditable report.
39
+ #
40
+ constraints:
41
+ - "CRA checks must not require network access by default — offline SBOM
42
+ analysis"
43
+ - "License audit must detect GPL-incompatible dependencies in the full
44
+ dependency tree"
45
+ - "SPDX header verification must support Ruby, YAML, JSON, Bash, and
46
+ Markdown files"
47
+ - "Output must be machine-readable (JSON/YAML) for CI integration and
48
+ TTY-aware (formatted table when interactive, structured data when piped)"
49
+ - "Must not store or transmit any proprietary compliance data"
50
+ - "Compliance rules must be declarative YAML, not hardcoded"
51
+ - "SBOM generation must work offline using Gemfile.lock as primary source —
52
+ syft CLI is optional (used when available for richer metadata)"
53
+ - "SBOM output must conform to CycloneDX 1.5 JSON schema or SPDX 2.3 JSON
54
+ schema depending on --sbom-format flag"
55
+ - "SBOM must include PURL (Package URL) identifiers for all components"
56
+ - "Exit code must distinguish pass (0), warning (1), and failure (2)
57
+ for CI pipelines"
58
+ - "This design governs compliance verification (checking adherence).
59
+ Policy definition and governance is handled by policy_management.yml.
60
+ Licensing system mechanics are handled by licensing_system.yml"
61
+ #
62
+ acceptance_criteria:
63
+ - "`rai comply` runs all compliance checks and produces a summary report"
64
+ - "`rai comply --cra` checks CRA-specific requirements (SBOM, vulnerability
65
+ policy)"
66
+ - "`rai comply --license` audits dependency licenses against GPL-3.0
67
+ compatibility"
68
+ - "`rai comply --headers` verifies SPDX headers on all source files"
69
+ - "`rai comply --format json` outputs machine-readable results"
70
+ - "CI pipeline can gate releases on compliance check exit code"
71
+ - "Compliance rules are loaded from conf/compliance/*.yml"
72
+ - "`rai comply --sbom` generates a CycloneDX 1.5 JSON SBOM from Gemfile.lock"
73
+ - "`rai comply --sbom --sbom-format spdx` generates an SPDX 2.3 JSON SBOM"
74
+ - "SBOM includes component name, version, PURL, license SPDX ID, and supplier"
75
+ - "SBOM generation works offline without syft (Ruby fallback parser)"
76
+ - "TTY-aware summary shows pass/warn/fail counts in colour when
77
+ interactive, plain counts when piped"
78
+ - "Exit code 0 on all pass, 1 on warnings only, 2 on any failure"
79
+ #
80
+ examples:
81
+ - scenario: "Developer runs `rai comply` before tagging a release"
82
+ expected: |
83
+ All checks pass; SBOM is current; all files have SPDX headers.
84
+ Summary: 12 checks passed, 0 warnings, 0 failures.
85
+ not: "Missing headers silently ignored or only warned about"
86
+ - scenario: "A new gem dependency has an AGPL-3.0 license"
87
+ expected: |
88
+ License audit flags it as potentially GPL-incompatible and explains
89
+ why: 'AGPL-3.0 imposes network copyleft obligations that may conflict
90
+ with GPL-3.0-only. Review and add to allowlist or replace dependency.'
91
+ not: "Silent acceptance of incompatible licenses"
92
+ - scenario: "Running in CI without internet access"
93
+ expected: |
94
+ Offline checks complete successfully using cached SBOM data.
95
+ Network-dependent checks (e.g. NVD lookup) are skipped with warning.
96
+ not: "Failure because NVD or other remote service is unreachable"
97
+ - scenario: "Developer generates SBOM for CRA compliance"
98
+ expected: |
99
+ `rai comply --sbom` produces sbom.cdx.json in CycloneDX 1.5 format.
100
+ Each component includes name, version, PURL, and license. Output
101
+ validates against the CycloneDX JSON schema.
102
+ not: |
103
+ SBOM generation requires internet access. Missing gems are silently
104
+ omitted. Output is an invalid CycloneDX document.
105
+ - scenario: "Compliance report in CI pipeline"
106
+ expected: |
107
+ `rai comply --format json` outputs structured results parseable by
108
+ CI tools. Exit code 2 triggers pipeline failure. Report includes
109
+ each check's name, status, and resolution guidance.
110
+ not: "Human-readable text output that CI cannot parse."
111
+ #
112
+ anti_patterns:
113
+ - "Hardcoding compliance rules in Ruby — use declarative YAML configs"
114
+ - "Requiring internet access for basic compliance checks"
115
+ - "Treating warnings as informational-only — they must have a clear
116
+ resolution path"
117
+ - "Mixing legal advice into tool output — report facts, not interpretations"
118
+ - "Coupling compliance checks to a specific engine's config format"
119
+ #
120
+ gui_notes: |
121
+ Document interactions (cross-references):
122
+
123
+ 1. policy_management.yml: policies define what applies; comply verifies
124
+ adherence and produces reports.
125
+
126
+ 2. licensing_system.yml: licensing mechanics (key management, activation).
127
+ Comply checks license compatibility of dependencies.
128
+
129
+ 3. security.yml: comply enforces security-adjacent requirements (SPDX
130
+ headers, vulnerability disclosure).
131
+
132
+ 4. error_handling.yml: exit codes and structured error messages follow
133
+ the error hierarchy.
134
+
135
+ 5. engine_architecture.yml: compliance rules may reference engine
136
+ capabilities or engine-specific outputs.
137
+
138
+ 6. distribution.yml: comply gates release publishing — CI runs comply
139
+ before deploy:publish.
140
+ #
141
+ preferences:
142
+ language: ruby
143
+ patterns:
144
+ - "Command pattern for individual check types"
145
+ - "Declarative YAML for compliance rule definitions"
146
+ - "Array-form system() for any shell-out to SBOM tools"
147
+ - "TTY-aware output (TtyHelper)"
148
+ testing: rspec with compliance rule fixtures, license compatibility
149
+ scenarios, SPDX header detection, and CI output format tests
150
+ gems:
151
+ - license_finder
152
+ - json_schemer
153
+ - thor
@@ -0,0 +1,84 @@
1
+ ---
2
+ name: content_packs
3
+ domain: licensing
4
+ version: 1.1.0
5
+ status: implemented
6
+ priority: 4
7
+ author: hugo
8
+ created_at: "2026-02-18"
9
+ modified_at: "2026-03-17"
10
+ modified_by: claude
11
+ depends_on:
12
+ - security
13
+ - licensing_system
14
+ - compiler
15
+
16
+ intent: |
17
+ Define the premium content pack system that delivers curated behaviours,
18
+ design patterns, and AI target profiles to licensed users. Content packs
19
+ are signed tarballs of YAML files with manifests, downloaded from a content
20
+ server and cached locally. The system must work offline after initial
21
+ download. Content packs are licensed under the NeatNerds Content License
22
+ (separate from GPL-3.0), and are data consumed by the software, not
23
+ derivative works of it.
24
+
25
+ constraints:
26
+ - Content packs are signed with the same Ed25519 key pair used for license keys
27
+ - Content pack signatures must be verified before installation
28
+ - Content is stored locally in ~/.config/rosett-ai/premium/ after download
29
+ - Content packs must work offline after initial download
30
+ - Content pack manifests are YAML validated against schema
31
+ - Tier entitlement is checked before download (not after)
32
+ - Content packs are YAML files — no executable code in packs
33
+ - Content pack installation must not modify core rosett-ai files or configuration
34
+ - All content pack YAML must be parsed with YAML.safe_load
35
+
36
+ acceptance_criteria:
37
+ - bin/raictl content list shows available packs for current license tier
38
+ - bin/raictl content list --available shows packs at all tiers (with tier labels)
39
+ - bin/raictl content install security_pack downloads, verifies, and installs pack
40
+ - bin/raictl content update re-downloads all installed packs (subscriber tier)
41
+ - Signature verification rejects tampered content packs
42
+ - Installed packs work without internet after download
43
+ - Content pack manifest schema exists in conf/schemas/
44
+ - bin/raictl compile integrates premium behaviours alongside core behaviours
45
+
46
+ examples:
47
+ - scenario: "Supporter installs the security_behaviours content pack"
48
+ expected: |
49
+ License tier verified (supporter >= supporter). Pack downloaded from
50
+ content server. Ed25519 signature verified. Tarball extracted to
51
+ ~/.config/rosett-ai/premium/security_behaviours/. Manifest validated.
52
+ 'Installed security_behaviours v2.1.0 (4 behaviours, 2 designs).'
53
+ not: "Pack installed without signature check. Arbitrary code executed from pack."
54
+ - scenario: "Community user tries to install a supporter-tier pack"
55
+ expected: |
56
+ 'security_behaviours requires Supporter tier. Your tier: Community.
57
+ Visit https://neatnerds.be/rosett-ai/pricing for upgrade options.'
58
+ not: "Pack downloads but fails silently. Error message is unclear about tier."
59
+ - scenario: "Content pack tarball has been tampered with"
60
+ expected: "Ed25519 signature verification fails. 'Content pack signature invalid. Pack not installed.'"
61
+ not: "Tampered pack is installed. YAML with unexpected content is loaded."
62
+ - scenario: "Subscriber runs bin/raictl content update while offline"
63
+ expected: "Graceful failure: 'Cannot reach content server. Existing content packs unchanged.'"
64
+ not: "Crash. Existing content deleted. Error without explanation."
65
+
66
+ anti_patterns:
67
+ - Including executable code (Ruby, shell) in content packs
68
+ - Installing packs without signature verification
69
+ - Requiring internet on every rosett-ai run to validate content
70
+ - Deleting local content when server is unreachable
71
+ - Mixing premium content with core rosett-ai files
72
+ - Using YAML.load to parse content pack files
73
+
74
+ preferences:
75
+ language: ruby
76
+ gems:
77
+ - faraday
78
+ - ed25519
79
+ - minitar
80
+ patterns:
81
+ - offline_first_caching
82
+ - signed_content_distribution
83
+ - schema_validated_manifests
84
+ testing: rspec with fixtures for valid, tampered, and unsigned packs