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,56 @@
1
+ ---
2
+ name: migration
3
+ domain: core
4
+ version: 1.0.0
5
+ status: approved
6
+ priority: 1
7
+ author: hugo
8
+ created_at: "2026-03-31"
9
+ modified_at: "2026-03-31"
10
+ modified_by: claude
11
+ depends_on:
12
+ - init_command
13
+ - scope_hierarchy
14
+ - backward_compatibility
15
+
16
+ intent: |
17
+ Provide a safe, automated migration path when rai configuration paths
18
+ change between versions. The v1.0.0 -> v1.1.0 migration moves behaviours
19
+ from ~/.claude/conf/behaviour/ to ~/.config/rosett-ai/conf/behaviour/ (XDG).
20
+
21
+ Users must NEVER lose data or have silent behaviour changes. Every migration
22
+ must: detect the old layout, warn the user, offer automatic migration,
23
+ preserve originals as backups, and verify the migration succeeded.
24
+
25
+ constraints:
26
+ - "Migration must be automatic on first compile or init after package upgrade"
27
+ - "User must be warned before any file move with a clear explanation"
28
+ - "Original files must be preserved as .backup until user explicitly deletes"
29
+ - "Migration must be idempotent — running twice produces no additional changes"
30
+ - "rai doctor must detect pending migrations and report them"
31
+ - "Compilation must work during migration (read from both old and new paths)"
32
+ - "BREAKING CHANGES section in CHANGELOG.md for every path change"
33
+
34
+ acceptance_criteria:
35
+ - "User with ~/.claude/conf/behaviour/ files sees migration warning on first compile"
36
+ - "Migration copies (not moves) files to ~/.config/rosett-ai/conf/behaviour/"
37
+ - "After migration, compile reads from XDG path"
38
+ - "Original ~/.claude/conf/behaviour/ files renamed to .migrated-to-xdg"
39
+ - "rai doctor reports 'migration pending' if old path has files but new path is empty"
40
+ - "rai doctor reports 'migration complete' after successful migration"
41
+ - "CHANGELOG.md documents the path change with migration instructions"
42
+
43
+ anti_patterns:
44
+ - "Moving files without backup"
45
+ - "Silent path changes between versions"
46
+ - "Deleting old config files during migration"
47
+ - "Requiring manual user action for migration to work"
48
+ - "Breaking compile because old path is no longer read"
49
+
50
+ examples:
51
+ - scenario: "v1.0.0 to v1.1.0 XDG migration on first compile"
52
+ expected: >-
53
+ User with behaviours at ~/.claude/conf/behaviour/ runs rai compile.
54
+ Migration warning is shown. Files are copied to ~/.config/rosett-ai/conf/behaviour/.
55
+ Legacy directory renamed to ~/.claude/conf.migrated-to-xdg/.
56
+ Compile proceeds reading from XDG path.
@@ -0,0 +1,194 @@
1
+ ---
2
+ name: monitoring_observability
3
+ domain: operations
4
+ version: 0.1.0
5
+ status: implemented
6
+ priority: 6
7
+ author: hugo
8
+ created_at: "2026-03-04"
9
+ modified_at: "2026-03-16"
10
+ modified_by: claude
11
+ depends_on:
12
+ - security
13
+ - architecture
14
+ - error_handling
15
+ - workflow
16
+ - structured_logging
17
+ #
18
+ intent: |
19
+ Provide structured runtime telemetry for the Rosett-AI CLI so developers and
20
+ operators can diagnose errors, measure compile performance, and audit
21
+ command execution — all without sending any data externally. Every CLI
22
+ invocation should be observable after the fact via JSON Lines logs that
23
+ capture timing, outcome, and contextual metadata. The telemetry system
24
+ must be opt-in, impose negligible overhead when disabled, and follow the
25
+ same pluggable provider pattern used elsewhere in rosett-ai so that desktop
26
+ (D-Bus health), compile metrics, and engine probes can plug in later
27
+ without changing the core interface.
28
+
29
+ Telemetry is the observability layer — it captures runtime metrics and
30
+ events for diagnostic purposes. Related but distinct: workflow audit logs
31
+ (workflow.yml) record step-by-step execution history for reproducibility,
32
+ provenance logs (ai_provenance.yml) record AI involvement per commit for
33
+ attribution, error handling (error_handling.yml) governs structured
34
+ error display, and structured logging (structured_logging.yml) provides
35
+ per-invocation correlation IDs and detailed diagnostic messages. Telemetry
36
+ and structured logging share the same correlation ID so that high-level
37
+ events (command_start, command_end) and detailed log entries (debug, info,
38
+ warn, error) from the same invocation can be correlated.
39
+
40
+ Telemetry events and structured log entries are complementary: telemetry
41
+ captures what happened (event, duration, outcome), while structured logging
42
+ captures why it happened (debug traces, validation details, error context).
43
+ Together they provide full observability for a single CLI invocation.
44
+ #
45
+ constraints:
46
+ - "All telemetry is local-only — no external endpoints, no phone-home,
47
+ GDPR-safe by design"
48
+ - "Telemetry is disabled by default; enabled via RAI_TELEMETRY=1
49
+ environment variable"
50
+ - "Overhead must be less than 5ms per CLI invocation when telemetry is
51
+ disabled"
52
+ - "Output format is JSON Lines (one JSON object per line) for streaming
53
+ and tooling compatibility — telemetry output is raw structured data,
54
+ not TTY-formatted"
55
+ - "Log destination is stderr by default; RAI_TELEMETRY_FILE=<path>
56
+ redirects to a file"
57
+ - "Log level controlled via RAI_TELEMETRY_LEVEL={debug,info,warn,error}
58
+ (default info)"
59
+ - "Must use Mutex for thread-safe I/O (same pattern as Desktop::GuiLogger)"
60
+ - "No new runtime dependencies — uses only stdlib JSON, Time, Process"
61
+ - "Provider interface is a Ruby module (RosettAi::Telemetry::Provider) with
62
+ a single #report method"
63
+ - "Providers are registered at boot, not discovered dynamically, to keep
64
+ startup cost zero"
65
+ - "Never log secrets, API keys, file contents, or user-identifiable data"
66
+ - "Structured fields include timestamp (ISO 8601), level, event, pid,
67
+ duration_ms, command, engine, correlation_id"
68
+ - "Telemetry events must include the correlation_id from structured_logging
69
+ for cross-referencing with diagnostic log entries"
70
+ - "Telemetry log files must have a configurable rotation policy (default
71
+ 10 MB max, 5 rotated files) to prevent unbounded disk growth"
72
+ - "This design governs runtime observability (metrics, timing, diagnostics).
73
+ Workflow audit logs (step execution history) are governed by workflow.yml.
74
+ Provenance logs (AI involvement per commit) are governed by
75
+ ai_provenance.yml. Structured error display is governed by
76
+ error_handling.yml"
77
+ #
78
+ acceptance_criteria:
79
+ - "RosettAi::Telemetry::Reporter class exists with write_event, command_start,
80
+ command_end methods"
81
+ - "RosettAi::Telemetry::Provider module defines the #report(event_hash)
82
+ interface contract"
83
+ - "RAI_TELEMETRY=1 enables telemetry; unset or any other value disables it"
84
+ - "RAI_TELEMETRY_FILE writes JSON Lines to the specified path (append mode,
85
+ sync flush)"
86
+ - "RAI_TELEMETRY_LEVEL filters events below the configured severity"
87
+ - "CLI commands (compile, validate, adopt, engines) emit command_start and
88
+ command_end events"
89
+ - "command_end events include duration_ms measured via Process::CLOCK_MONOTONIC"
90
+ - "Error events include error class, message, and truncated backtrace
91
+ (first 5 frames)"
92
+ - "Debug/verbose output standards are documented: --verbose maps to info,
93
+ --debug to debug"
94
+ - "Reporter.instance returns a singleton; Reporter.enabled? returns boolean"
95
+ - "No telemetry code executes (beyond the enabled? check) when
96
+ RAI_TELEMETRY is unset"
97
+ - "Provider#report receives a frozen Hash and must not mutate it"
98
+ - "Telemetry events include correlation_id matching structured logging entries"
99
+ - "Exit code 0 on success, 1 on telemetry write failure (non-blocking),
100
+ 2 on invalid telemetry configuration"
101
+ #
102
+ examples:
103
+ - scenario: "Developer runs compile with telemetry enabled"
104
+ expected: |
105
+ RAI_TELEMETRY=1 bin/raictl compile emits two JSON Lines to stderr:
106
+ {"timestamp":"...","level":"info","event":"command_start","command":"compile","engine":"claude","pid":12345}
107
+ {"timestamp":"...","level":"info","event":"command_end","command":"compile","duration_ms":142.3,"status":"success","pid":12345}
108
+ not: |
109
+ Telemetry output is mixed with normal CLI output on stdout.
110
+ File paths or rule content appear in telemetry events.
111
+ - scenario: "Developer runs compile without RAI_TELEMETRY"
112
+ expected: |
113
+ No JSON Lines output. The only cost is a single ENV fetch and boolean
114
+ check at Reporter initialization. Measured overhead < 1ms.
115
+ not: |
116
+ Reporter allocates objects, opens file handles, or registers at_exit hooks.
117
+ - scenario: "A D-Bus health provider is added later"
118
+ expected: |
119
+ Provider implements RosettAi::Telemetry::Provider, is registered via
120
+ Reporter.register_provider(provider), and receives #report calls for
121
+ each event. No changes to Reporter or existing providers needed.
122
+ not: |
123
+ D-Bus health logic is added directly into Reporter. Conditional
124
+ require blocks litter the telemetry module.
125
+ - scenario: "Telemetry log file is unwritable"
126
+ expected: |
127
+ Reporter swallows the I/O error and continues CLI execution normally.
128
+ A single warning is emitted to stderr: 'rosett-ai: telemetry file
129
+ /path/to/log unwritable — telemetry disabled for this invocation'.
130
+ Exit code is not affected (telemetry failures are non-blocking).
131
+ not: |
132
+ CLI crashes because telemetry file cannot be written. User's compile
133
+ or validate operation fails due to a telemetry issue.
134
+ - scenario: "Telemetry log file exceeds rotation threshold"
135
+ expected: |
136
+ When the log file exceeds 10 MB, it is rotated to
137
+ telemetry.jsonl.1 (up to 5 files). Oldest rotated file is deleted.
138
+ Rotation happens atomically before writing the next event.
139
+ not: "Log file grows unbounded. Disk fills up over months of use."
140
+ #
141
+ anti_patterns:
142
+ - "Sending telemetry data to any external service or network endpoint"
143
+ - "Enabling telemetry by default (must be explicit opt-in)"
144
+ - "Logging file contents, secrets, API keys, or personally identifiable
145
+ information"
146
+ - "Using puts or print instead of structured JSON Lines"
147
+ - "Dynamic provider discovery via ObjectSpace or const_get (register
148
+ explicitly)"
149
+ - "Allocating telemetry objects when telemetry is disabled"
150
+ - "Blocking CLI execution on telemetry I/O failures (swallow and continue)"
151
+ - "Using global variables or class variables for telemetry state (use
152
+ singleton instance)"
153
+ - "Unbounded log file growth without rotation"
154
+ #
155
+ gui_notes: |
156
+ Document interactions (cross-references):
157
+
158
+ 1. workflow.yml: workflow audit logs record step execution history for
159
+ reproducibility. Telemetry observes workflow execution at the timing/
160
+ metrics level.
161
+
162
+ 2. ai_provenance.yml: provenance logs record AI involvement per commit.
163
+ Telemetry captures the timing of provenance operations.
164
+
165
+ 3. error_handling.yml: structured error display follows the error
166
+ hierarchy. Telemetry captures error events with class, message,
167
+ and truncated backtrace.
168
+
169
+ 4. security.yml: telemetry must never log secrets, API keys, or PII.
170
+ Local-only constraint is absolute.
171
+
172
+ 5. architecture.yml: the pluggable provider pattern follows rosett-ai's
173
+ extension architecture (register at boot, not discover dynamically).
174
+
175
+ 6. desktop_integration.yml: D-Bus health provider is a future telemetry
176
+ provider that exposes rosett-ai health on the session bus.
177
+
178
+ 7. structured_logging.yml: structured logging provides correlation IDs
179
+ and detailed diagnostic messages. Telemetry events include the same
180
+ correlation_id for cross-referencing.
181
+ #
182
+ preferences:
183
+ language: ruby
184
+ patterns:
185
+ - "Singleton instance pattern for Reporter"
186
+ - "Provider interface module (RosettAi::Telemetry::Provider)"
187
+ - "JSON Lines structured logging"
188
+ - "Mutex thread-safety for I/O"
189
+ - "Monotonic clock timing (Process::CLOCK_MONOTONIC)"
190
+ - "Log rotation with configurable threshold"
191
+ testing: rspec with telemetry event capture, provider registration,
192
+ disabled-mode overhead benchmarks, I/O failure handling, and log
193
+ rotation scenarios
194
+ gems: []
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: namespace_cleanup
3
+ domain: core
4
+ version: 1.0.0
5
+ status: implemented
6
+ priority: 1
7
+ author: hugo
8
+ created_at: '2026-04-14'
9
+ modified_at: '2026-04-14'
10
+ modified_by: claude opus-4.6
11
+ depends_on:
12
+ - migration
13
+ - doctor
14
+ - architecture
15
+ - ci_pipeline
16
+ intent: |
17
+ Eliminate all remaining references to the legacy "nncc" namespace from the
18
+ rosett-ai codebase, configuration, and project ecosystem. The project was
19
+ renamed from NeatNerds Code Companion (nncc) to Rosett-AI in v1.0.0, but
20
+ residual nncc references persist in method names, test modules, design docs,
21
+ schema filenames, code comments, and the user's filesystem. These stale
22
+ references create confusion for contributors, break the naming contract
23
+ established by the rename, and will appear unprofessional in a published
24
+ release.
25
+
26
+ This design document records the decisions for each cleanup area. A separate
27
+ implementation session will execute the changes based on these decisions.
28
+
29
+ Pre-flight findings (2026-04-14):
30
+ - ~/.config/nncc/ contains 6 behaviour files, schemas, and config.yml
31
+ - 12 projects across ~/git have .nncc/ directories (+ ~/git/.nncc)
32
+ - Zero .rosett-ai/ project directories exist on disk
33
+ - RAI_MARKER and MARKER_PREFIX already use rosett-ai naming
34
+ - nncc_managed? method persists in installer.rb and chain_detector.rb
35
+ - NnccTestStubs module in spec/support/stub_engines.rb
36
+ - 5 design docs reference nncc
37
+ - Schema files: nncc_config_schema.json, nncc_project_schema.json
38
+ - CLAUDE.md is missing from the project root
39
+ constraints:
40
+ - No data loss — user files in ~/.config/nncc/ and .nncc/ must be preserved or migrated,
41
+ never silently deleted
42
+ - Rename operations must not break the test suite — run rspec after each atomic rename
43
+ - CI lint job must distinguish intentional nncc references (migration code, doctor
44
+ checks) from stale ones
45
+ - The CLAUDE.md must reflect the current rosett-ai identity, not the nncc identity
46
+ from the parent CLAUDE.md
47
+ - Schema file renames must be accompanied by updates to all $ref pointers
48
+ - Design doc updates must preserve git blame utility — use targeted edits, not wholesale
49
+ rewrites
50
+ acceptance_criteria:
51
+ - grep -r 'Nncc::' lib/ returns zero matches
52
+ - grep -r 'nncc_managed?' lib/ returns zero matches
53
+ - grep -r 'NnccTestStubs' spec/ returns zero matches
54
+ - grep -r 'nncc' conf/design/ returns only namespace_cleanup.yml itself and migration.yml
55
+ (which documents the nncc->rosett-ai migration)
56
+ - ls conf/schemas/nncc_*.json returns zero matches
57
+ - CLAUDE.md exists at project root with raictl CLI reference
58
+ - CI lint job catches future nncc regressions
59
+ - raictl doctor detects ~/.config/nncc/ and .nncc/ directories
60
+ - Full test suite passes after all renames
61
+ anti_patterns:
62
+ - Bulk search-replace without context analysis — nncc in paths uses hyphens, in Ruby
63
+ identifiers uses underscores, in module names uses CamelCase
64
+ - Renaming migration/doctor code that intentionally references nncc
65
+ - Deleting ~/.config/nncc/ or .nncc/ directories without migration
66
+ - Writing CLAUDE.md by copying the parent CLAUDE.md and editing
67
+ examples:
68
+ - scenario: Developer greps for stale nncc references after cleanup
69
+ expected: |
70
+ $ grep -rn 'nncc' lib/ --include='*.rb'
71
+ lib/rosett_ai/doctor/checks/stale_home_nncc_check.rb:18: check_name 'stale_home_nncc'
72
+ lib/rosett_ai/doctor/checks/stale_config_nncc_check.rb:18: check_name 'stale_config_nncc'
73
+
74
+ Only doctor checks that detect legacy nncc artifacts appear.
75
+ No Nncc:: modules, no nncc_managed? methods, no NnccTestStubs.
76
+ not: |
77
+ Hundreds of nncc references across lib/, spec/, conf/.
78
+ Doctor checks renamed to remove nncc from their name (they describe
79
+ what they detect — the nncc artifacts).
80
+ preferences:
81
+ language: ruby
82
+ patterns:
83
+ - Targeted search-replace with context awareness
84
+ - Atomic commits per rename area (method, module, schema, docs)
85
+ - Test suite validation between each rename
86
+ testing: rspec full suite after each atomic rename, CI lint job as final gate
87
+ gui_notes: |
88
+ Decisions, schema renames, and action list archived below.
89
+
90
+ DECISIONS:
91
+ q01_project_marker_directory:
92
+ Q: What should the project-level marker directory be named?
93
+ A: Option A — keep .rosett-ai/
94
+
95
+ q02_xdg_global_config_path:
96
+ Q: What should the XDG global config path be?
97
+ A: Option A — keep ~/.config/rosett-ai/
98
+
99
+ q03_legacy_config_nncc_migration:
100
+ Q: How to handle the stale ~/.config/nncc/ directory?
101
+ A: Option C — raictl migrate command
102
+
103
+ q04_legacy_nncc_project_markers:
104
+ Q: How to handle .nncc/ directories in projects?
105
+ A: Option B — raictl migrate renames .nncc/ to .rosett-ai/
106
+
107
+ q05_method_name_nncc_managed:
108
+ Q: What should the nncc_managed? method be renamed to?
109
+ A: Option B — rename to rai_managed?
110
+
111
+ q06_test_stub_module:
112
+ Q: What should the NnccTestStubs module be renamed to?
113
+ A: Option B — rename to RaiTestStubs
114
+
115
+ q07_design_doc_nncc_references:
116
+ Q: How to handle nncc references in design docs?
117
+ A: Option A — search-replace nncc references
118
+
119
+ q08_claude_backend_stale_comment:
120
+ Q: Is nncc-claude-managed in compiled output or just a comment?
121
+ A: Code comment only — fix the comment
122
+
123
+ q09_ci_lint_job:
124
+ Q: What should the CI namespace regression lint check?
125
+ A: Grep-based lint job with allowlist
126
+
127
+ q10_claude_md_rewrite:
128
+ Q: What should the CLAUDE.md contain?
129
+ A: Complete rewrite for rosett-ai identity
130
+
131
+
132
+ SCHEMA FILE RENAMES:
133
+ conf/schemas/nncc_config_schema.json -> conf/schemas/rosett_ai_config_schema.json
134
+ conf/schemas/nncc_project_schema.json -> conf/schemas/rosett_ai_project_schema.json
135
+
136
+ PRIORITIZED ACTIONS (all completed):
137
+ 1. Write CLAUDE.md (Q10) — release blocker, no code dependencies
138
+ 2. Rename nncc_managed? to rai_managed? (Q5) — code change, test after
139
+ 3. Rename NnccTestStubs to RaiTestStubs (Q6) — test infra, test after
140
+ 4. Fix claude_backend.rb comment (Q8) — trivial, no test impact
141
+ 5. Rename schema files (supplementary) — update refs, test after
142
+ 6. Update design doc references (Q7) — 5 files, no code impact
143
+ 7. Add stale_config_nncc doctor check (Q3) — new code, test after
144
+ 8. Extend raictl migrate for .nncc/ and ~/.config/nncc/ (Q3, Q4)
145
+ 9. Add CI lint job (Q9) — must run after all renames complete
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: plugin_test_segregation
3
+ domain: testing
4
+ version: 0.1.0
5
+ status: draft
6
+ priority: 3
7
+ author: hugo
8
+ created_at: "2026-04-17"
9
+ modified_at: "2026-04-17"
10
+ modified_by: claude
11
+ depends_on:
12
+ - testing
13
+ - engine_architecture
14
+ - gui_plugins
15
+ - desktop_integration
16
+ - mcp_integration
17
+ intent: |
18
+ Decouple plugin test suites from the core rosett-ai test suite so that
19
+ (a) the core suite runs fast and deterministically without optional gems,
20
+ (b) each plugin gem owns its own specs and CI, and (c) the contract
21
+ boundary between core and plugins is explicit and testable from both sides.
22
+
23
+ Currently 25 spec files (dbus/13, desktop/4, ui/8) live in the core repo
24
+ but depend on optional gems (ruby-dbus, gtk4, libadwaita). The PrePush
25
+ hook already excludes them via --exclude-pattern, proving they are not
26
+ core tests. Thor task specs (dbus_spec.rb, desktop_spec.rb) and doctor
27
+ checks (dbus_availability_check_spec.rb) add further coupling. This
28
+ design formalises the decoupling.
29
+
30
+ constraints:
31
+ - Core test suite (bundle exec rspec) must pass with ZERO optional gems installed
32
+ - Plugin gems must be independently testable (bundle exec rspec in plugin repo)
33
+ - Contract specs must exist on BOTH sides — core verifies the contract interface, plugin verifies it satisfies the contract
34
+ - Shared examples ('a UI implementation', 'a compiler backend') must live in a shared gem or be duplicated in each plugin that uses them
35
+ - No spec file in the core repo may require ruby-dbus, gtk4, gi, or any optional gem at load time
36
+ - The PrePush --exclude-pattern hack must be eliminated — if specs live in the right repo, no exclusion is needed
37
+ - stub_engines.rb must remain in core — engine stubs test the compilation pipeline, not engine plugins
38
+ - Plugin CI must pull the core gem as a dependency (not git submodule) to test integration
39
+ - Mutation testing (mutant) must run per-repo — core mutant tests core, plugin mutant tests plugin
40
+ - Packaging specs (variant_config_spec.rb) that reference GTK4 must use stubs, not real GTK4
41
+
42
+ acceptance_criteria:
43
+ - Core rspec suite passes without --exclude-pattern and without optional gems
44
+ - No spec file under spec/ requires ruby-dbus, gtk4, gi, or qt5 gems
45
+ - rosett-ai-gtk4 gem has its own spec/ directory with desktop, dbus, and ui/gtk4 specs
46
+ - rosett-ai-gtk4 spec suite passes independently with bundle exec rspec
47
+ - Shared example 'a UI implementation' is available to plugin specs via rosett-ai core gem or shared spec gem
48
+ - Shared example 'a compiler backend' remains in core (engines are core infrastructure)
49
+ - Thor task specs for dbus and desktop commands use stub doubles, not real D-Bus/GTK classes
50
+ - Doctor dbus_availability_check_spec tests the check logic with stubs, not real D-Bus probing
51
+ - Plugin registry specs (gui_contract_spec.rb) test the contract interface, not a real GTK4 implementation
52
+ - PrePush RspecCore hook no longer needs --exclude-pattern for desktop/dbus/ui paths
53
+ - packaging/variant_config_spec.rb uses config stubs for gtk4 variant, not real GTK4 detection
54
+ - CI pipeline for core repo has no gtk4/dbus stage or dependency
55
+ - CI pipeline for rosett-ai-gtk4 installs ruby-dbus + gtk4 introspection in its own job
56
+ - Integration test exists that installs core .deb + gtk4 .deb and verifies plugin discovery
57
+
58
+ examples:
59
+ - scenario: Developer runs core test suite on a server with no desktop environment
60
+ expected: |
61
+ $ bundle exec rspec
62
+ 4200 examples, 0 failures
63
+
64
+ No --exclude-pattern needed. All 25 desktop/dbus/ui specs have been
65
+ moved to the rosett-ai-gtk4 plugin gem. Core specs that previously
66
+ tested D-Bus/GTK behaviour now use contract doubles.
67
+ not: Test suite fails with LoadError for ruby-dbus or gi gem
68
+
69
+ - scenario: Plugin developer adds a new D-Bus interface to rosett-ai-gtk4
70
+ expected: |
71
+ 1. Write spec in rosett-ai-gtk4/spec/dbus/new_interface_spec.rb
72
+ 2. Implement in rosett-ai-gtk4/lib/rosett_ai_gtk4/dbus/new_interface.rb
73
+ 3. Run: cd rosett-ai-gtk4 && bundle exec rspec — passes
74
+ 4. Core repo unchanged — no new spec, no new exclude pattern
75
+ not: Developer must add spec to core repo and update --exclude-pattern
76
+
77
+ - scenario: Core contract changes — UI implementation interface adds a new required method
78
+ expected: |
79
+ 1. Update shared example 'a UI implementation' in core
80
+ 2. Core specs pass (TUI and AccessibleTUI satisfy new contract)
81
+ 3. rosett-ai-gtk4 CI fails — GTK4 UI adapter missing new method
82
+ 4. Plugin developer adds method to GTK4 adapter
83
+ 5. Both repos green
84
+ not: Contract change is invisible to plugin authors until runtime
85
+
86
+ - scenario: Stubbing strategy for Thor desktop task spec in core
87
+ expected: |
88
+ The desktop_spec.rb in core tests the Thor task routing, not GTK4.
89
+ It stubs RosettAi::Plugins::Registry.available(:gui) to return
90
+ a contract double that responds_to launch, available?, gui_name.
91
+ No real GTK4 classes are loaded.
92
+
93
+ The rosett-ai-gtk4 repo has its own desktop_integration_spec.rb
94
+ that tests the real GTK4App class with the real D-Bus client.
95
+ not: Core desktop_spec.rb loads GTK4 classes or requires ruby-dbus
96
+
97
+ anti_patterns:
98
+ - Moving specs but keeping require lines that pull in optional gems — the LoadError just moves to a different location
99
+ - Using allow_any_instance_of to stub optional gem constants — fragile and hides real coupling
100
+ - Sharing spec helpers via git submodule — version drift, merge conflicts, CI complexity
101
+ - Conditionally skipping specs with pending/skip based on gem availability — this is the current anti-pattern, it hides failures
102
+ - Mocking the Zeitwerk loader instead of fixing the actual dependency graph
103
+ - Keeping shared examples in core gem spec/support/ — creates coupling between plugin test setup and core internals
104
+
105
+ preferences:
106
+ language: ruby
107
+ patterns:
108
+ - Contract doubles (not instance_double) for cross-gem boundaries — mocked via RSpec double() with method stubs
109
+ - Shared examples in a separate rosett-ai-test-support gem for cross-repo reuse
110
+ - RSpec tag filtering (:plugin => true) as a transitional measure before full extraction
111
+ testing: Core specs runnable with core Gemfile only (no optional groups). Plugin specs use own Gemfile with rosett-ai + rosett-ai-test-support as dependencies. Integration tests live in plugin repo.
112
+ gems:
113
+ - rosett-ai-test-support (new) — shared examples and contract double factories
114
+ - rosett-ai-gtk4 — separate GitLab repo (private until mature), owns all GTK4/D-Bus specs
115
+
116
+ gui_notes: |
117
+ DECISIONS (2026-04-17, approved by hugo):
118
+
119
+ 1. SEPARATE REPO: rosett-ai-gtk4 is a separate GitLab repository,
120
+ private until maturity. Not a monorepo subdirectory. This gives
121
+ clean CI isolation and independent release cycle. Harmonisation
122
+ (namespace alignment, contract stabilisation) is a prerequisite
123
+ before the full extraction starts.
124
+
125
+ 2. SEPARATE TEST SUPPORT GEM: rosett-ai-test-support gem ships shared
126
+ examples ('a UI implementation', 'a compiler backend') and contract
127
+ double factories. Both core and plugin repos depend on it for testing.
128
+ TUI implementation stays in core. Some duplication across repos is
129
+ accepted — the cost of tight coupling is greater.
130
+
131
+ 3. CONTRACT DOUBLES WITH MOCKING: Use RSpec double()/class_double()
132
+ for cross-gem boundaries. No instance_double (requires the real
133
+ class). Contract doubles mock the interface defined by GuiContract,
134
+ EngineContract, McpContract. The contract classes themselves remain
135
+ in core and define the expected method signatures.
136
+
137
+ 4. PHASED APPROACH: First move away the problematic test code from
138
+ core (Phase 1). Then create the plugin repo and stabilise the
139
+ contract boundary (Phase 2). The harmonisation work is a
140
+ prerequisite before Phase 2 starts.
141
+
142
+ Extraction targets: lib/rosett_ai/desktop/, lib/rosett_ai/dbus/
143
+ (except rate_limiter.rb which has no optional deps),
144
+ lib/rosett_ai/ui/gtk4.rb, lib/rosett_ai/ui/kde.rb,
145
+ lib/rosett_ai/ui/qt6.rb, and all corresponding specs.