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,148 @@
1
+ ---
2
+ name: structured_logging
3
+ domain: operations
4
+ version: 0.1.0
5
+ status: implemented
6
+ priority: 3
7
+ author: hugo
8
+ created_at: "2026-03-16"
9
+ modified_at: "2026-03-16"
10
+ modified_by: claude
11
+ depends_on:
12
+ - architecture
13
+ - security
14
+ - error_handling
15
+ - monitoring_observability
16
+ #
17
+ intent: |
18
+ Enhance the existing rosett-ai logger with correlation IDs and structured JSON
19
+ output for cross-command tracing and debugging. When a user reports a problem,
20
+ the support workflow requires correlating log entries from a single CLI
21
+ invocation — which is impossible with unstructured text logs that lack a
22
+ shared identifier. This design adds a per-invocation correlation ID (UUID v4)
23
+ to every log entry, enables JSON-formatted output for machine parsing, and
24
+ provides configurable log levels that align with the telemetry system.
25
+
26
+ Structured logging complements telemetry (monitoring_observability.yml):
27
+ telemetry captures high-level command events (start, end, duration) for
28
+ operational metrics, while structured logging captures detailed diagnostic
29
+ messages (debug, info, warn, error) for troubleshooting. Both share the
30
+ correlation ID so that telemetry events and log entries from the same
31
+ invocation can be joined. Error handling (error_handling.yml) governs
32
+ user-facing error display; structured logging governs developer-facing
33
+ diagnostic output.
34
+ #
35
+ constraints:
36
+ - "Each CLI invocation generates a unique correlation ID (UUID v4) at startup"
37
+ - "The correlation ID is included in every log entry and every telemetry event"
38
+ - "Log format is controlled via RAI_LOG_FORMAT={text,json} (default text)"
39
+ - "JSON log format produces one JSON object per line (JSON Lines compatible)"
40
+ - "Text log format produces human-readable output: [LEVEL] [correlation_id] message"
41
+ - "Log level is controlled via RAI_LOG_LEVEL={DEBUG,INFO,WARN,ERROR}
42
+ (default WARN)"
43
+ - "Log output goes to stderr — never stdout (stdout is for command output)"
44
+ - "Structured logger must be a drop-in replacement for the existing
45
+ Ruby Logger interface (respond_to debug, info, warn, error, fatal)"
46
+ - "No new runtime dependencies — uses stdlib Logger, JSON, SecureRandom"
47
+ - "Log entries must never contain secrets, API keys, or file contents
48
+ (same constraint as telemetry)"
49
+ - "Correlation ID is accessible via RosettAi::StructuredLogger.correlation_id
50
+ for passing to telemetry and error handlers"
51
+ - "Logger must be thread-safe (Mutex-protected writes)"
52
+ - "This design governs diagnostic logging (developer-facing debug output).
53
+ Runtime telemetry is governed by monitoring_observability.yml. User-facing
54
+ error display is governed by error_handling.yml"
55
+ #
56
+ acceptance_criteria:
57
+ - "RosettAi::StructuredLogger class exists and implements Ruby Logger interface"
58
+ - "Every log entry includes a correlation_id field (UUID v4)"
59
+ - "RAI_LOG_FORMAT=json produces JSON Lines output on stderr"
60
+ - "RAI_LOG_FORMAT=text produces [LEVEL] [correlation_id] message on stderr"
61
+ - "RAI_LOG_LEVEL filters entries below the configured severity"
62
+ - "Correlation ID is generated once per CLI invocation and reused for all
63
+ log entries"
64
+ - "RosettAi::StructuredLogger.correlation_id returns the current correlation ID"
65
+ - "Telemetry events include the same correlation_id as log entries"
66
+ - "Structured logger is wired as the default logger in RosettAi module"
67
+ - "Log entries include timestamp (ISO 8601), level, correlation_id, message"
68
+ - "JSON log entries additionally include pid, command (when available)"
69
+ - "No secrets or file contents appear in log output"
70
+ - "Logger is thread-safe under concurrent writes"
71
+ #
72
+ examples:
73
+ - scenario: "Developer debugs a compile failure with JSON logs"
74
+ expected: |
75
+ RAI_LOG_LEVEL=DEBUG RAI_LOG_FORMAT=json bin/raictl compile
76
+ stderr output (one JSON object per line):
77
+ {"timestamp":"2026-03-16T10:00:00.123Z","level":"debug","correlation_id":"a1b2c3d4-...","pid":12345,"command":"compile","message":"Loading behaviour files from conf/behaviour/"}
78
+ {"timestamp":"2026-03-16T10:00:00.145Z","level":"debug","correlation_id":"a1b2c3d4-...","pid":12345,"command":"compile","message":"Validating 8 behaviour files"}
79
+ {"timestamp":"2026-03-16T10:00:00.189Z","level":"error","correlation_id":"a1b2c3d4-...","pid":12345,"command":"compile","message":"Validation failed: conf/behaviour/broken.yml:14 — missing required field 'rules'"}
80
+ not: |
81
+ Log entries lack correlation_id. JSON output goes to stdout and
82
+ corrupts piped command output. Debug messages appear at default log level.
83
+ - scenario: "User runs rosett-ai with default settings (no log env vars)"
84
+ expected: |
85
+ Only WARN and ERROR messages appear on stderr in text format.
86
+ No DEBUG or INFO noise. Correlation ID is still generated internally
87
+ but not visible unless log level is lowered.
88
+ not: |
89
+ DEBUG output floods stderr by default. No log output at all even
90
+ for warnings.
91
+ - scenario: "Support request includes correlation ID for cross-referencing"
92
+ expected: |
93
+ User provides correlation_id from error output. Developer searches
94
+ telemetry logs and structured logs using that ID to find all events
95
+ from the same CLI invocation.
96
+ not: |
97
+ Correlation ID is different between log entries and telemetry events
98
+ from the same invocation.
99
+ - scenario: "Multiple CLI invocations run in parallel (e.g., CI)"
100
+ expected: |
101
+ Each invocation has a unique correlation ID. Log entries from
102
+ different invocations can be separated by filtering on correlation_id.
103
+ Thread-safe writes prevent interleaved JSON objects.
104
+ not: |
105
+ Same correlation ID used across invocations. JSON objects are
106
+ interleaved mid-line due to race conditions.
107
+ #
108
+ anti_patterns:
109
+ - "Using puts or $stderr.puts instead of the structured logger"
110
+ - "Logging file contents or secrets (even at DEBUG level)"
111
+ - "Generating a new correlation ID per log entry instead of per invocation"
112
+ - "Sending logs to stdout (reserved for command output)"
113
+ - "Different correlation IDs for log entries and telemetry events"
114
+ - "Requiring an external logging gem (use stdlib Logger)"
115
+ - "Eagerly formatting log messages when the level is filtered out"
116
+ - "Making log format or level configurable via config files (env vars only)"
117
+ #
118
+ gui_notes: |
119
+ Document interactions (cross-references):
120
+
121
+ 1. monitoring_observability.yml: telemetry events include the same
122
+ correlation_id as log entries for cross-referencing.
123
+
124
+ 2. error_handling.yml: error handler can include correlation_id in
125
+ user-facing error output for support reference.
126
+
127
+ 3. security.yml: log entries must never contain secrets, API keys, or PII.
128
+
129
+ 4. architecture.yml: structured logger replaces the simple logger in
130
+ RosettAi module as a drop-in compatible upgrade.
131
+
132
+ Module structure:
133
+
134
+ lib/rosett_ai/structured_logger.rb — Logger subclass with correlation ID,
135
+ JSON/text formatters, level filtering
136
+ #
137
+ preferences:
138
+ language: ruby
139
+ patterns:
140
+ - "Ruby Logger interface compatibility"
141
+ - "Per-invocation correlation ID (UUID v4)"
142
+ - "JSON Lines structured output"
143
+ - "Mutex thread-safety for writes"
144
+ - "Lazy message formatting (block form)"
145
+ testing: rspec with correlation ID propagation, JSON output parsing,
146
+ level filtering, thread-safety under concurrent writes, and
147
+ telemetry integration
148
+ gems: []
@@ -0,0 +1,123 @@
1
+ ---
2
+ name: styles
3
+ domain: styles
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
+
15
+ intent: |
16
+ Codify all code conventions, linting rules, YAML formatting, documentation
17
+ structure, and commit message standards into a single authoritative design
18
+ document. Style enforcement eliminates bikeshedding, ensures consistency
19
+ across human and AI contributors, and makes code review focus on logic
20
+ rather than formatting. This depends on testing because the enforcement
21
+ tools (rubocop, yamllint, reek, mdl, overcommit) must be present and
22
+ configured before style gates can be enforced. Style rules are enforced
23
+ automatically via pre-commit hooks (overcommit) and CI pipeline — they
24
+ are not optional guidelines.
25
+
26
+ constraints:
27
+ - All Ruby code must pass RuboCop with zero violations (no rubocop:disable without justification)
28
+ - All YAML files must pass yamllint with the project .yamllint configuration
29
+ - All Ruby code must pass Reek with zero violations above configured thresholds
30
+ - All JSON files must be syntactically valid (validated by overcommit JsonSyntax hook)
31
+ - All Markdown documentation must pass mdl (markdownlint) with project rules
32
+ - "Commit messages must follow Conventional Commits format: type(scope): description"
33
+ - Frozen string literal comment is required on every Ruby file
34
+ - Single quotes for strings unless interpolation is needed
35
+ - 2-space indentation for Ruby, YAML, and JSON — no tabs except Makefiles
36
+ - Maximum line length is 120 characters for Ruby, 240 for YAML (warning)
37
+ - RSpec examples follow behaviour-driven descriptions (what it does, not how)
38
+ - No trailing whitespace (except Markdown where it may be intentional)
39
+ - Structural duplication detected by Flay must stay below threshold (mass >= 16)
40
+ - Cyclomatic complexity enforced by RuboCop Metrics cops (AbcSize <= 25, CyclomaticComplexity <= 10, PerceivedComplexity <= 10)
41
+
42
+ acceptance_criteria:
43
+ - .rubocop.yml exists with all project conventions and zero violations on main
44
+ - .yamllint exists with project YAML formatting rules
45
+ - .reek.yml exists with code smell detection thresholds
46
+ - .overcommit.yml enforces rubocop, yamllint, reek, json, bundler-audit, and trailing whitespace on pre-commit
47
+ - Commit message format is enforced by overcommit CommitMsg hooks (Conventional Commits pattern)
48
+ - mdl (markdownlint) is configured and enforced for all .md files in doc/
49
+ - bundle exec rubocop exits zero on the entire codebase
50
+ - bundle exec reek exits zero on the entire codebase
51
+ - yamllint exits zero on all YAML files outside vendor/ and tmp/
52
+ - Flay is configured with mass threshold 16 and enforced via overcommit pre-commit hook; cyclomatic complexity enforced by RuboCop Metrics cops (AbcSize <= 25, CyclomaticComplexity <= 10, PerceivedComplexity <= 10)
53
+
54
+ examples:
55
+ - scenario: "AI generates a new Ruby class with double-quoted strings"
56
+ expected: |
57
+ Pre-commit hook catches the violation: RuboCop Style/StringLiterals
58
+ flags double quotes. Developer (or AI) fixes to single quotes. Commit
59
+ proceeds after fix.
60
+ not: "Code merges with inconsistent quoting style."
61
+ - scenario: "Developer writes a commit message 'fixed the bug'"
62
+ expected: |
63
+ Overcommit CommitMsg hook rejects: 'Commit message must follow
64
+ Conventional Commits format: <type>(<scope>): <description>'.
65
+ Developer rewrites as 'fix(compiler): handle nil input in validate method'.
66
+ not: "Freeform commit messages merge without convention."
67
+ - scenario: "New YAML configuration file uses 4-space indentation"
68
+ expected: |
69
+ yamllint flags indentation violation. Pre-commit hook blocks commit.
70
+ Developer fixes to 2-space indentation per project convention.
71
+ not: "Mixed indentation styles across YAML files."
72
+ - scenario: "New method has cyclomatic complexity of 15"
73
+ expected: |
74
+ RuboCop Metrics/CyclomaticComplexity flags the method above threshold
75
+ (max 10). Reek flags complexity smells. Developer refactors into smaller
76
+ methods. If threshold exception is truly justified, it is added to
77
+ .reek.yml or .rubocop.yml with a comment explaining why.
78
+ not: "Complex code merges without review. Thresholds silently increased."
79
+ - scenario: "Documentation in doc/ uses inconsistent heading styles"
80
+ expected: |
81
+ mdl flags heading style violation (e.g., mixed ATX and setext headings).
82
+ CI lint stage blocks merge. Author fixes to consistent ATX style (# headings).
83
+ not: "Documentation has mixed formatting that degrades readability."
84
+
85
+ anti_patterns:
86
+ - Disabling linting rules inline without a justification comment
87
+ - Blanket rubocop:disable at file level instead of fixing the issue
88
+ - Excluding entire directories from style checks without justification
89
+ - Treating style warnings as non-blocking (all style violations block in this project)
90
+ - Inconsistent configuration between local hooks and CI (they must match)
91
+ - Skipping pre-commit hooks with --no-verify
92
+ - Adding Reek exclusions without first attempting to refactor the code smell
93
+ - Commit messages that bypass Conventional Commits format
94
+
95
+ preferences:
96
+ language: ruby
97
+ gems:
98
+ - rubocop
99
+ - rubocop-performance
100
+ - rubocop-rspec
101
+ - rubocop-rake
102
+ - reek
103
+ - flay
104
+ - overcommit
105
+ tools:
106
+ - yamllint
107
+ - mdl
108
+ patterns:
109
+ - convention_over_configuration
110
+ - automated_enforcement_over_manual_review
111
+ - zero_tolerance_for_style_violations
112
+ conventions:
113
+ string_literals: single_quotes
114
+ frozen_string_literal: always
115
+ indentation: 2_spaces
116
+ line_length_ruby: 120
117
+ line_length_yaml: 240
118
+ hash_syntax: ruby19
119
+ array_style: brackets
120
+ symbol_array_style: brackets
121
+ trailing_comma: no_comma
122
+ class_children: nested
123
+ commit_format: conventional_commits
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: test_peer_review
3
+ domain: testing
4
+ version: 0.1.0
5
+ status: implemented
6
+ priority: 1
7
+ author: hugo
8
+ created_at: "2026-03-14"
9
+ modified_at: "2026-03-15"
10
+ modified_by: claude
11
+ depends_on:
12
+ - testing
13
+ - security
14
+
15
+ intent: |
16
+ Establish a structured, questionnaire-based peer review process for all
17
+ test suites across the Rosett-AI ecosystem (core + 11 engine plugins). This
18
+ addresses the fundamental trust problem: when AI generates both code and
19
+ tests, a human must independently verify that tests reflect actual
20
+ requirements, not just mirror implementation details.
21
+
22
+ The process produces a signed-off test registry where every spec file has
23
+ been reviewed, its intent documented, and its correctness confirmed by the
24
+ human maintainer. This creates an auditable trail of test quality that is
25
+ independent of the AI that wrote the tests.
26
+
27
+ The review follows a questionnaire format (similar to the Q1-Q5 design
28
+ review process) where each test file is examined through structured
29
+ questions that expose gaps, redundancy, incorrect assumptions, and
30
+ missing edge cases. The human reviewer signs off on each file, creating
31
+ a permanent record.
32
+
33
+ constraints:
34
+ - Every spec file must be reviewed before v1.0.0 release
35
+ - Each review must be signed off by the human maintainer (hugo)
36
+ - The review questionnaire must be reproducible and version-controlled
37
+ - Reviews must cover intent, correctness, completeness, and independence
38
+ - AI cannot sign off on its own tests — only the human reviewer can
39
+ - Review findings that require code changes must be tracked as issues
40
+ - The review registry must be machine-readable (YAML) for automation
41
+ - Reviews are per-file, not per-example, to keep the process practical
42
+
43
+ acceptance_criteria:
44
+ - A review questionnaire template exists with numbered questions (Q1-Qn)
45
+ - A review registry YAML file tracks status per spec file per repo
46
+ - Each registry entry includes reviewer, date, verdict, and notes
47
+ - The questionnaire covers at minimum these dimensions — intent clarity, assertion quality, edge case coverage, mock appropriateness, independence from implementation, mutation resilience, naming quality, fixture quality
48
+ - A CLI command or script can report review progress across all repos
49
+ - All 174 spec files (141 core + 33 engine) have been reviewed
50
+ - All critical findings have been resolved before sign-off
51
+ - The review process is documented in doc/TEST_PEER_REVIEW.md
52
+
53
+ examples:
54
+ - scenario: "Reviewing spec/rosett_ai/compiler/behaviour_compiler_spec.rb"
55
+ expected: |
56
+ Reviewer reads the file, answers each questionnaire question,
57
+ records findings in the registry. If Q3 (edge cases) reveals
58
+ missing nil input handling, this is recorded as a finding with
59
+ severity. The file is not signed off until the finding is resolved.
60
+ Once all questions are answered satisfactorily, the reviewer signs
61
+ off with date and verdict.
62
+
63
+ - scenario: "Reviewing spec/rosett_ai_engine/acme/backend_spec.rb"
64
+ expected: |
65
+ Reviewer examines engine contract tests. Q5 (implementation
66
+ independence) reveals that a test checks internal hash structure
67
+ rather than observable behaviour. This is flagged as a finding.
68
+ After the test is rewritten to check only the public interface,
69
+ the reviewer re-examines and signs off.
70
+
71
+ - scenario: "Generating progress report"
72
+ expected: |
73
+ CLI command reads all registry files and outputs a summary table:
74
+ Total files: 174, Reviewed: 87, Signed off: 72, Pending fixes: 15,
75
+ Not started: 87. Per-repo breakdown shows completion percentage.
76
+
77
+ anti_patterns:
78
+ - AI signing off on its own tests (only human reviewer can sign off)
79
+ - Reviewing tests without reading the implementation under test
80
+ - Batch sign-off without individual file assessment
81
+ - Skipping edge case review for seemingly simple specs
82
+ - Using test count as a proxy for test quality
83
+ - Approving tests that mirror implementation details
84
+
85
+ preferences:
86
+ questionnaire_format: "Numbered Q1-Q10 with verdict per question (pass/concern/fail)"
87
+ registry_format: "One YAML file per repo in conf/review/, keyed by spec file path"
88
+ review_workflow: "AI summary → human Q&A → registry → fix → sign-off"
89
+ batch_order: "Foundation → compiler → security → CLI → modules → UI → utils → engines"
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: testing
3
+ domain: testing
4
+ version: 0.3.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
+
14
+ intent: |
15
+ Establish a testing strategy that validates both code correctness AND test
16
+ quality, specifically addressing the circular trust problem of AI-generated
17
+ tests. When AI writes both code and tests, the test suite can be perfectly
18
+ consistent yet meaningless. Mutation testing (Mutant) acts as an independent
19
+ third-party validator that mechanically verifies tests catch real bugs,
20
+ regardless of who wrote them. This must be in place before feature development
21
+ begins so all future code is validated from day one.
22
+
23
+ constraints:
24
+ - Mutation testing (mutant-rspec) must be integrated before feature development begins
25
+ - All AI-generated tests must pass the 11-point review checklist before acceptance
26
+ - Unit tests must use concrete expected values, never computed expectations that mirror implementation
27
+ - Mocking is only permitted at boundaries (file system, network, shell commands)
28
+ - The unit under test must never be mocked
29
+ - Every public method must have tests for happy path, edge cases (empty, nil, boundary), negative cases, and error cases
30
+ - Test descriptions must be behaviour-focused, not implementation-focused
31
+ - "SimpleCov minimum line coverage is 88% overall and 25% per file (target: 90% line, 80% per-file)"
32
+ - Mutation score must meet threshold before code can merge (70% initial, 85% established, 95% critical paths)
33
+ - CI must run rspec on every push and mutant on merge requests
34
+ - Property-based testing must be used for cryptographic/security-critical code (licensing validation)
35
+ - Snapshot testing must be used for compiled output regression — baseline snapshots stored in spec/fixtures/snapshots/
36
+ - Snapshot files must be committed to git and reviewed in merge requests (not auto-updated)
37
+ - Property-based testing uses Rantly gem for random input generation
38
+ - Rantly generators for domain objects are defined in spec/support/rantly_generators.rb
39
+
40
+ acceptance_criteria:
41
+ - mutant-rspec is installed and configured with .mutant.yml
42
+ - SimpleCov is configured with minimum thresholds that block CI on violation
43
+ - RSpec runs on every CI push and produces JUnit XML report
44
+ - Mutant runs on every merge request for changed code and blocks merge if score drops
45
+ - spec/support/factories/ contains factory_bot factories for core domain objects
46
+ - spec/support/shared_examples/ contains interface contract tests for UI base
47
+ - spec/fixtures/ contains valid, invalid, malicious, and unicode test fixtures
48
+ - AI-generated test review checklist is documented and enforced in review process
49
+ - At least one property-based test exists for licensing key validation
50
+ - spec/fixtures/snapshots/ contains baseline compiled output for each engine backend
51
+ - Snapshot tests compare compiled output against committed baselines (exact match)
52
+ - spec/support/rantly_generators.rb contains Rantly generators for behaviour rules, design documents, and policy objects
53
+ - Property-based tests exist for composition edge cases (priority ordering, merge strategies)
54
+
55
+ examples:
56
+ - scenario: "AI generates tests for RosettAi::Compiler::BehaviourCompiler"
57
+ expected: |
58
+ Tests use concrete values (eq(3), not input.select(&:enabled?).count).
59
+ Tests cover enabled rules included, disabled rules excluded, empty input,
60
+ nil input, and invalid rule format. Mutant score >= 85%.
61
+ not: |
62
+ Tests reimplement the code logic in expectations. Tests only cover
63
+ happy path. Mocks replace the compiler itself. Descriptions say
64
+ 'calls select then map' instead of 'includes only enabled rules'.
65
+ - scenario: "Mutant reports a surviving mutation: select changed to reject"
66
+ expected: |
67
+ Developer (or AI) writes a new test that explicitly asserts disabled
68
+ rules are NOT in the output. Mutant is re-run to confirm the mutation
69
+ is now killed. New commit created (not amending).
70
+ not: |
71
+ Surviving mutation is ignored. Mutant threshold is lowered to accommodate.
72
+ Test is marked as pending.
73
+ - scenario: "AI generates tests and mutant score is 60%"
74
+ expected: |
75
+ Surviving mutations are fed back to AI with prompt: 'These mutations
76
+ survived, write tests to kill them: [list]'. AI generates targeted
77
+ tests. Mutant re-run. Repeat until >= 85%.
78
+ not: "Tests are accepted at 60%. Mutant is skipped."
79
+ - scenario: "New code adds a security-critical licensing validator"
80
+ expected: |
81
+ Unit tests with concrete values. Property-based tests with random
82
+ payloads verifying forged keys always rejected. Mutant score >= 95%.
83
+ Fixtures include valid, expired, forged, and tampered keys.
84
+ - scenario: "Compiled output changes unexpectedly after a refactor"
85
+ expected: |
86
+ Snapshot test compares compiled output against spec/fixtures/snapshots/
87
+ baseline. Test fails with a diff showing exactly what changed. Developer
88
+ reviews the diff and either fixes the regression or updates the snapshot.
89
+ not: |
90
+ Compiled output changes go undetected. Snapshots auto-update without
91
+ human review. No baseline exists for regression comparison.
92
+ - scenario: "Composition with random priority and scope combinations"
93
+ expected: |
94
+ Rantly generates 100 random behaviour rule sets with varying priorities,
95
+ scopes, and merge strategies. Property: output is always deterministic
96
+ (same input → same output). Property: security-domain rules are never
97
+ overridden by non-security rules.
98
+ not: |
99
+ Only hand-crafted examples are tested. Edge cases in priority ordering
100
+ are missed because the test space is too small.
101
+ - scenario: "Developer refactors compile method from select+map to filter_map"
102
+ expected: "All tests continue to pass because they test outcomes, not method calls"
103
+ not: "Tests break because they asserted select was called"
104
+
105
+ anti_patterns:
106
+ - Tautological tests (expectation reimplements the code logic)
107
+ - Over-mocking (mocking the unit under test, mocking everything)
108
+ - Weak assertions (not_to be_nil, to be_a(Array) without content checks)
109
+ - Happy path only (no edge cases, no error paths, no boundary values)
110
+ - Implementation coupling (testing call sequences instead of outcomes)
111
+ - Missing negative tests (no assertions about what should NOT be in output)
112
+ - Computed expectations (expect(x).to eq(input.select(&:foo?).count))
113
+ - Lowering mutation score thresholds to accommodate weak tests
114
+ - Skipping mutant on merge requests to save time
115
+ - Accepting AI-generated tests without review checklist verification
116
+ - Auto-updating snapshot baselines without human review
117
+ - Using only hand-crafted examples when property-based testing would catch more edge cases
118
+ - Defining Rantly generators outside spec/support/ (scattered generator definitions)
119
+
120
+ preferences:
121
+ language: ruby
122
+ testing: rspec with factory_bot and mutant-rspec
123
+ gems:
124
+ - rspec
125
+ - factory_bot
126
+ - mutant-rspec
127
+ - simplecov
128
+ - rspec-junit-formatter
129
+ - rantly
130
+ patterns:
131
+ - behaviour_driven_test_descriptions
132
+ - concrete_value_assertions
133
+ - boundary_only_mocking
134
+ - context_blocks_for_scenarios
135
+ - shared_examples_for_interfaces
136
+ - named_subjects_and_let_blocks
@@ -0,0 +1,108 @@
1
+ ---
2
+ name: threat_model
3
+ domain: security
4
+ version: 0.1.0
5
+ status: implemented
6
+ priority: 1
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
+ - architecture
14
+ - engine_architecture
15
+ - content_packs
16
+ - licensing_system
17
+ #
18
+ intent: |
19
+ Define the adversary model, trust boundaries, and threat scenarios for Rosett-AI.
20
+ Security.yml establishes coding rules; this document maps the attack surface —
21
+ who might attack, what they target, and which mitigations apply. Without a
22
+ threat model, security constraints are disconnected from real-world risks.
23
+ This document ensures every security decision traces back to a concrete threat.
24
+ #
25
+ constraints:
26
+ - Trust boundaries must be defined for every external input channel (CLI args, YAML files, content packs, engine gems, environment variables, D-Bus messages)
27
+ - Each identified threat must map to at least one mitigation in security.yml or this document
28
+ - Content packs from untrusted sources must be treated as hostile input (sandboxed parsing, no code execution)
29
+ - Engine gems are trusted only if installed via system package manager or bundler with locked checksums
30
+ - YAML files from external sources must pass schema validation before any processing
31
+ - D-Bus messages must be validated against expected method signatures before dispatch
32
+ - Supply chain attacks on dependencies must be mitigated by lockfile pinning and bundler-audit
33
+ - The threat model must be reviewed whenever a new input channel or external integration is added
34
+ - File path traversal attacks must be prevented by canonicalisation and whitelist checks
35
+ - No design document may introduce a new trust boundary without updating this threat model
36
+ #
37
+ acceptance_criteria:
38
+ - Trust boundary diagram exists (ASCII art or structured YAML) covering all input channels
39
+ - Each trust boundary has documented validation rules
40
+ - Content pack installation validates integrity (checksum verification) before extraction
41
+ - Engine gem loading validates gemspec metadata against expected patterns
42
+ - D-Bus method handlers reject messages with unexpected argument types or counts
43
+ - bin/raictl compile rejects YAML files containing path traversal sequences (../, symlinks to outside whitelist)
44
+ - bundler-audit and gitleaks run in CI and block merge on any finding
45
+ - Supply chain risk assessment exists for each runtime dependency (Gemfile.lock pinned)
46
+ - RSpec tests exist for each trust boundary validation (at least one positive and one negative test)
47
+ - Threat model review checklist is referenced in the design document template
48
+ #
49
+ examples:
50
+ - scenario: "User installs a content pack from an untrusted community repository"
51
+ expected: |
52
+ Content pack is downloaded to a temporary directory. Checksum is verified
53
+ against manifest. YAML files are validated against schemas. No Ruby code
54
+ in content packs is executed. Pack is installed only after all checks pass.
55
+ not: |
56
+ Content pack is extracted directly into ~/.config/rosett-ai/. Ruby files in
57
+ the pack are loaded via require. No checksum verification.
58
+ - scenario: "A malicious YAML behaviour file contains a path traversal in a rule's output path"
59
+ expected: |
60
+ Path is canonicalised with File.expand_path. Resulting path is checked
61
+ against whitelist (~/. claude/rules/, project .claude/). Traversal
62
+ detected: "Validation failed: output path escapes allowed directory."
63
+ not: |
64
+ Path traversal succeeds. File is written to /etc/cron.d/ or ~/.ssh/.
65
+ - scenario: "A compromised RubyGem is pushed as a dependency update"
66
+ expected: |
67
+ bundler-audit detects known CVE in CI. Merge is blocked. Developer
68
+ reviews advisory and pins to safe version in Gemfile.lock.
69
+ not: |
70
+ Compromised gem is installed. Malicious code executes at require time.
71
+ - scenario: "A D-Bus client sends an unexpected method call to be.neatnerds.rosettai"
72
+ expected: |
73
+ Method signature is validated. Unknown methods return D-Bus error
74
+ org.freedesktop.DBus.Error.UnknownMethod. Arguments are type-checked.
75
+ not: |
76
+ Arbitrary method calls are dispatched to internal handlers.
77
+ - scenario: "An engine gem's gemspec declares a dependency on a gem that executes native code"
78
+ expected: |
79
+ Engine loader checks gemspec dependencies against an allowlist.
80
+ Unknown native extensions trigger a warning. User must explicitly
81
+ approve gems with native extensions.
82
+ not: |
83
+ Native extension compiles and executes arbitrary C code without notice.
84
+ #
85
+ anti_patterns:
86
+ - Trusting input from any external channel without validation
87
+ - Assuming content packs are safe because they are YAML (YAML deserialization attacks)
88
+ - Loading engine gems via require without validating source or integrity
89
+ - Processing D-Bus messages without type-checking arguments
90
+ - Relying solely on file permissions for security (defence in depth needed)
91
+ - Hardcoding trust assumptions instead of documenting them in the threat model
92
+ - Treating all RubyGems as equally trusted regardless of source
93
+ - Skipping threat model review when adding new external integrations
94
+ - Using string comparison for paths instead of canonicalised path comparison
95
+ #
96
+ preferences:
97
+ language: ruby
98
+ patterns:
99
+ - defence_in_depth
100
+ - trust_boundary_validation
101
+ - input_sanitisation_at_boundaries
102
+ - least_privilege
103
+ - fail_secure
104
+ testing: rspec with adversarial input fixtures
105
+ gems:
106
+ - bundler-audit
107
+ - gitleaks
108
+ - json_schemer