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,117 @@
1
+ ---
2
+ name: release_management
3
+ domain: release
4
+ version: 0.2.0
5
+ status: implemented
6
+ priority: 5
7
+ author: claude
8
+ created_at: "2026-02-22"
9
+ modified_at: "2026-03-17"
10
+ modified_by: claude
11
+ depends_on:
12
+ - ci_pipeline
13
+ - lifecycle_management
14
+ - testing
15
+
16
+ intent: |
17
+ Define a repeatable, automated process for releasing rosett-ai versions. Every
18
+ release today requires manual version edits, manual CHANGELOG writing, manual
19
+ tag creation, and manual CI coordination. This creates inconsistency risk
20
+ (version drift across files), omission risk (forgetting CHANGELOG entries),
21
+ and human error (wrong tag format, missed verification step).
22
+
23
+ With release management:
24
+ - Version bumping is atomic — all files updated in one operation
25
+ - CHANGELOG entries are generated from conventional commit history
26
+ - Tags are annotated with release notes
27
+ - The verification suite is mandatory before any release commit
28
+ - CI creates GitLab releases automatically on tag push
29
+
30
+ Without release management:
31
+ - Manual edits to lib/rosett_ai/version.rb, CHANGELOG.md, gemspec
32
+ - Version references drift (SETUP.md said 4.0.0 while .ruby-version said 3.3.10)
33
+ - Release timing is ad-hoc with no checklist
34
+ - No auditable trail connecting a tag to its verification results
35
+
36
+ constraints:
37
+ - Version follows Semantic Versioning 2.0.0 (semver.org) — MAJOR.MINOR.PATCH
38
+ - CHANGELOG follows Keep a Changelog 1.1.0 format (keepachangelog.com)
39
+ - Every release MUST pass the full verification suite before the release commit (rspec, rubocop, reek, bundler-audit, ruby-audit)
40
+ - Version references MUST be updated atomically — reuse lifecycle_management's atomic version update principle
41
+ - "Git tags MUST be annotated (not lightweight) and follow the pattern v{MAJOR}.{MINOR}.{PATCH}"
42
+ - "Release commits use the conventional commit format chore(release): prefix"
43
+ - No release may skip the pre-commit hooks — the release process calls git commit normally
44
+ - The release process MUST NOT push automatically — push is a separate explicit step (safety)
45
+ - CHANGELOG generation uses git-cliff with conventional commit parsing
46
+ - The version source of truth is lib/rosett_ai/version.rb — all other references derive from it
47
+
48
+ acceptance_criteria:
49
+ - "A Thor task bin/raictl release prepare LEVEL (major|minor|patch) bumps version and updates CHANGELOG"
50
+ - The prepare task updates version in lib/rosett_ai/version.rb, CHANGELOG.md (moves Unreleased to versioned section), and creates a release commit
51
+ - bin/raictl release tag creates an annotated git tag vX.Y.Z from the current VERSION constant
52
+ - bin/raictl release status shows current version, unreleased changes count, and last tag
53
+ - All files containing version references are updated atomically (grepped and verified — lifecycle_management pattern)
54
+ - CHANGELOG entries are generated from conventional commits between the last tag and HEAD
55
+ - CI job release:publish triggers on tag push and creates a GitLab release with CHANGELOG excerpt
56
+ - Running bin/raictl release prepare with uncommitted changes aborts with a clear error
57
+ - Running bin/raictl release prepare with failing verification suite aborts before version bump
58
+ - git-cliff configuration file (cliff.toml) exists with conventional commit type mapping
59
+
60
+ examples:
61
+ - scenario: "Releasing version 0.2.0 after adding P5 features"
62
+ expected: |
63
+ 1. Developer runs: bin/raictl release prepare minor
64
+ 2. Tool verifies working tree is clean (no uncommitted changes)
65
+ 3. Tool runs full verification suite (rspec, rubocop, reek, audits)
66
+ 4. Tool bumps version: 0.1.0 → 0.2.0 in lib/rosett_ai/version.rb
67
+ 5. Tool generates CHANGELOG section from conventional commits since v0.1.0
68
+ 6. Tool moves [Unreleased] content to [0.2.0] section with date
69
+ 7. Tool creates commit: 'chore(release): prepare v0.2.0'
70
+ 8. Developer reviews commit, then runs: bin/raictl release tag
71
+ 9. Tool creates annotated tag v0.2.0 with CHANGELOG excerpt as message
72
+ 10. Developer pushes: git push origin design_implementation --tags
73
+ 11. CI detects tag, creates GitLab release with notes
74
+ not: |
75
+ Tool auto-pushes to remote. Tool creates tag before commit.
76
+ Tool skips verification. Tool uses lightweight tag.
77
+ CHANGELOG section is empty or missing date.
78
+
79
+ - scenario: "Attempting release with uncommitted changes"
80
+ expected: |
81
+ bin/raictl release prepare patch
82
+ → Error: "Working tree has uncommitted changes. Commit or stash before releasing."
83
+ No files are modified. Exit code 1.
84
+ not: |
85
+ Silently proceed with dirty working tree. Offer to auto-commit changes.
86
+
87
+ - scenario: "Attempting release when rspec has failures"
88
+ expected: |
89
+ bin/raictl release prepare minor
90
+ → Runs rspec, detects 2 failures
91
+ → Error: "Verification suite failed (rspec: 2 failures). Fix issues before releasing."
92
+ No version bump occurs. Exit code 1.
93
+ not: |
94
+ Bump version anyway with a warning. Skip verification.
95
+
96
+ anti_patterns:
97
+ - Auto-pushing to remote as part of the release process (push must be explicit)
98
+ - Editing CHANGELOG manually when automation exists (defeats the purpose)
99
+ - Using lightweight git tags (cannot store release notes, unsigned)
100
+ - Skipping verification with --force or --no-verify flags
101
+ - Bumping version in some files but not others (atomic or nothing)
102
+ - Creating a release from a dirty working tree
103
+ - Releasing from a branch other than the designated release branch without explicit intent
104
+ - Coupling version bump and tag creation into one command (review step between them is valuable)
105
+
106
+ preferences:
107
+ language: ruby
108
+ gems:
109
+ - thor
110
+ patterns:
111
+ - conventional_commits
112
+ - atomic_version_updates
113
+ - fail_fast_on_invalid_state
114
+ testing: rspec for release task unit tests with filesystem mocking
115
+ tools:
116
+ changelog: git-cliff
117
+ tag_format: "v%M.%m.%p"
@@ -0,0 +1,199 @@
1
+ ---
2
+ name: retrofit
3
+ domain: core
4
+ version: 0.1.0
5
+ status: implemented
6
+ priority: 2
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
+ - compiler
14
+ - security
15
+ - engine_architecture
16
+ - claude_code_configuration
17
+ - error_handling
18
+ #
19
+ intent: |
20
+ Provide a reverse-compilation command (`rai retrofit`) that reads existing
21
+ AI tool configuration files from the local filesystem and generates
22
+ rosett-ai-managed YAML source files. Where `rai compile` transforms authored
23
+ YAML into native formats, retrofit transforms native formats back into
24
+ authored YAML — making ad-hoc, hand-edited configurations reproducible,
25
+ version-controllable, and shareable across projects and teams. Each engine
26
+ provides a retrofit adapter that knows how to parse its native config
27
+ format into the Rosett-AI schema.
28
+
29
+ Retrofit complements two adjacent commands: `rai init` creates the empty
30
+ .rosett-ai/ project structure, and `rai compile` transforms source YAML into
31
+ native formats. Retrofit closes the loop by importing existing native
32
+ configs back into source YAML. The lifecycle is:
33
+ init (scaffold) → retrofit (import) → edit → compile (deploy).
34
+ `rai project drift` (project_management.yml) detects when compiled output
35
+ diverges from source; `rai retrofit --simulate` detects the reverse —
36
+ when native configs diverge from what source YAML would produce.
37
+ #
38
+ constraints:
39
+ - "Retrofit is the only rosett-ai tool permitted to write to source YAML
40
+ directories — compiler.yml's 'source documents are never modified by
41
+ compilation' constraint explicitly exempts retrofit as a controlled
42
+ reverse-compilation operation"
43
+ - "Retrofit must never modify existing native config files — it is
44
+ read-only against them"
45
+ - "Generated YAML must pass `bin/raictl validate` without errors"
46
+ - "Generated YAML must round-trip — `rai compile` on retrofit output
47
+ must produce semantically equivalent native config (idempotent cycle)"
48
+ - "Retrofit must use engine-specific adapters — each engine gem provides
49
+ its own parser for native config discovery and extraction"
50
+ - "When no engine is specified, retrofit must auto-detect installed tools
51
+ by probing standard config paths (e.g. ~/.claude/, .cursor/, .github/)"
52
+ - "Retrofit must not silently overwrite existing Rosett-AI YAML files — prompt
53
+ for confirmation or require --force flag"
54
+ - "All file reads must validate paths against allowed directories (no
55
+ symlink traversal, no reads outside HOME)"
56
+ - "Sensitive values (API keys, tokens) detected in native configs must be
57
+ replaced with ${secret:env:NAME} references, never written as plaintext"
58
+ - "Retrofit output must include provenance metadata (source_file,
59
+ retrofit_date, engine, rai_version) as YAML comments"
60
+ - "YAML parsing of native files must use YAML.safe_load only"
61
+ - "Retrofit must work without network access — purely local file analysis"
62
+ - "Multiple engines can be retrofitted in a single invocation"
63
+ - "Unknown keys preserved as YAML comments must be sanitized — strip ANSI
64
+ escape sequences and control characters before writing (per security.yml)"
65
+ - "Retrofit complements `rai init` — init creates empty project structure,
66
+ retrofit populates it from existing native configs (init first, then
67
+ retrofit to import existing settings)"
68
+ - "This design governs reverse-compilation (native → source YAML). Forward
69
+ compilation (source → native) is governed by compiler.yml. Project
70
+ lifecycle management (drift, sync, templates) is governed by
71
+ project_management.yml"
72
+ #
73
+ acceptance_criteria:
74
+ - "`rai retrofit` auto-detects Claude Code config at ~/.claude/settings.json
75
+ and generates conf/claude_code/user.yml"
76
+ - "`rai retrofit --engine claude` targets Claude Code files specifically"
77
+ - "`rai retrofit --engine cursor` targets Cursor config files specifically"
78
+ - "Generated YAML files include all non-default settings from the source
79
+ config"
80
+ - "API keys and tokens in source configs are replaced with
81
+ ${secret:env:*} references"
82
+ - "Existing Rosett-AI YAML files are not overwritten without --force or
83
+ confirmation"
84
+ - "`rai retrofit --simulate` shows what files would be generated without
85
+ writing, using TTY-aware diff output (colour when interactive, plain
86
+ when piped)"
87
+ - "Round-trip test: retrofit then compile produces semantically equivalent
88
+ config"
89
+ - "Unknown or unsupported config keys are preserved as comments in the
90
+ generated YAML"
91
+ - "Retrofit generates a manifest (conf/retrofit_manifest.yml) listing
92
+ source files, extraction date, and engine versions"
93
+ - "Exit code 0 on success, 3 on config parse failure, 5 on missing
94
+ engine adapter"
95
+ #
96
+ examples:
97
+ - scenario: "Developer joins a project that already has .claude/settings.json hand-edited"
98
+ expected: |
99
+ `rai retrofit` reads .claude/settings.json, generates
100
+ conf/claude_code/project.yml with all settings expressed as
101
+ snake_case YAML. Developer commits the YAML and the team can
102
+ now reproduce the config via `rai compile`.
103
+ not: |
104
+ Developer manually transcribes JSON keys to YAML. Settings are
105
+ lost or mistyped. Team members have inconsistent configs.
106
+ - scenario: "Native config contains an ANTHROPIC_API_KEY in plaintext"
107
+ expected: |
108
+ Generated YAML contains `api_key: "${secret:env:ANTHROPIC_API_KEY}"`.
109
+ A warning is emitted: "Sensitive value detected in source — replaced
110
+ with secret reference. Set ANTHROPIC_API_KEY in your environment."
111
+ not: |
112
+ API key is written to the YAML file in plaintext. Secret is silently
113
+ dropped or the field is omitted.
114
+ - scenario: "User runs retrofit but conf/claude_code/user.yml already exists"
115
+ expected: |
116
+ Retrofit shows a diff of what would change and prompts for
117
+ confirmation. --force skips the prompt. --simulate shows the diff
118
+ without writing.
119
+ not: |
120
+ Existing YAML is silently overwritten. User loses their authored
121
+ config.
122
+ - scenario: "Team migrates from Cursor to Claude Code"
123
+ expected: |
124
+ `rai retrofit --engine cursor` imports Cursor config as Rosett-AI YAML.
125
+ `rai compile --engine claude` writes Claude Code native config.
126
+ Team commits the YAML — any member can compile for their preferred
127
+ engine.
128
+ not: |
129
+ Developer manually translates Cursor JSON to Claude JSON. Settings
130
+ are lost or mistyped. No version control.
131
+ - scenario: "Detecting reverse drift — native config was hand-edited after compile"
132
+ expected: |
133
+ `rai retrofit --simulate` shows a diff between current native
134
+ config and what the source YAML would generate. Effectively reverse
135
+ drift detection. See also: `rai project drift` for forward drift
136
+ (source → native).
137
+ not: |
138
+ No way to detect that someone hand-edited the native config after
139
+ compile.
140
+ - scenario: "Source config contains keys that rosett-ai does not recognise"
141
+ expected: |
142
+ Unknown keys are included in the generated YAML with a comment:
143
+ "# Unknown key — not in rosett-ai schema, preserved for compatibility".
144
+ A warning lists all unknown keys.
145
+ not: |
146
+ Unknown keys are silently dropped. Compiled output differs from
147
+ original.
148
+ #
149
+ anti_patterns:
150
+ - "Hardcoding config file paths instead of using engine adapter discovery"
151
+ - "Writing sensitive values to generated YAML without secret references"
152
+ - "Modifying native config files during the retrofit process"
153
+ - "Requiring network access to determine config structure"
154
+ - "Losing config values during the retrofit-compile round-trip"
155
+ - "Generating YAML that fails rosett-ai schema validation"
156
+ - "Silent overwrite of existing rosett-ai-managed YAML files"
157
+ - "Coupling retrofit logic to a single engine instead of using adapters"
158
+ #
159
+ gui_notes: |
160
+ Document interactions (cross-references):
161
+
162
+ 1. compiler.yml: compile transforms source → native; retrofit transforms
163
+ native → source. Retrofit is explicitly exempted from the compiler's
164
+ "source documents are never modified" constraint.
165
+
166
+ 2. project_management.yml: `rai project drift` detects forward drift
167
+ (source → compiled). `rai retrofit --simulate` detects reverse drift
168
+ (native → source).
169
+
170
+ 3. engine_architecture.yml: each engine provides a retrofit adapter via
171
+ its manifest. Adapters parse native config formats into rosett-ai schema.
172
+
173
+ 4. security.yml: YAML.safe_load, path validation, secret redaction,
174
+ ANSI/control character stripping for unknown keys.
175
+
176
+ 5. claude_code_configuration.yml: the Claude engine's retrofit adapter
177
+ parses settings.json, skills, hooks, and memory files.
178
+
179
+ 6. error_handling.yml: exit codes and structured error messages follow
180
+ the error hierarchy (what/why/fix format).
181
+
182
+ 7. architecture.yml: `rai init` creates the .rosett-ai/ structure that
183
+ retrofit populates. The lifecycle is: init → retrofit → edit → compile.
184
+ #
185
+ preferences:
186
+ language: ruby
187
+ patterns:
188
+ - "Adapter pattern for engine-specific parsers"
189
+ - "Reverse compiler pipeline (native → source)"
190
+ - "Secret detection and redaction"
191
+ - "Round-trip validation (retrofit → compile → compare)"
192
+ - "TTY-aware diff output"
193
+ testing: rspec with fixture-based round-trip tests, secret detection
194
+ scenarios, multi-engine retrofit, overwrite protection, and unknown
195
+ key preservation tests
196
+ gems:
197
+ - json_schemer
198
+ - diffy
199
+ - thor
@@ -0,0 +1,79 @@
1
+ ---
2
+ name: retrospective_analyzer
3
+ domain: operations
4
+ version: 0.1.0
5
+ status: draft
6
+ priority: 6
7
+ author: hugo
8
+ created_at: "2026-03-26"
9
+ modified_at: "2026-03-26"
10
+ modified_by: claude
11
+ depends_on:
12
+ - compiler
13
+ intent: |
14
+ Close the feedback loop between session retrospectives and rai behaviour
15
+ rules. Currently, retrospectives produce markdown files with Process Changes
16
+ (checkbox lists) and Failure Preventive Actions, but these remain as
17
+ unchecked items unless manually converted to rules.
18
+
19
+ This design adds a `bin/raictl retrospective` subcommand that parses
20
+ retrospective files, classifies findings into categories (behavioural,
21
+ tooling, process, mcp, memory), proposes rosett-ai resources, and tracks which
22
+ findings have been acted on.
23
+
24
+ CLI interface:
25
+ bin/raictl retrospective analyze [--path FILE] [--all] [--dry-run] [--verbose]
26
+ bin/raictl retrospective list
27
+ bin/raictl retrospective status
28
+
29
+ Ruby modules (lib/rosett_ai/retrospective/):
30
+ finding_parser.rb - Extracts Process Changes and Preventive Actions
31
+ finding_classifier.rb - Keyword-based classification (offline, no API)
32
+ proposal_builder.rb - Generates candidate behaviour rule YAML
33
+ proposal_presenter.rb - Renders approval prompt via tty-prompt
34
+
35
+ Thor task: lib/rosett_ai/thor/tasks/retrospective.rb (follows adopt.rb pattern)
36
+
37
+ State tracking via conf/retrospective.cache.yml (gitignored) recording
38
+ which findings have been converted to rules, with finding hash, category,
39
+ target behaviour, and acted-at timestamp.
40
+
41
+ Estimation: 5-6 hours (4 modules + Thor task + RSpec coverage).
42
+ constraints:
43
+ - Must work offline with keyword-based classification (no API calls by default)
44
+ - Must not break existing compile workflow
45
+ - User must approve all proposed changes (staged execution with approval gates)
46
+ - Must follow the adopt.rb Thor task pattern (spinner, verbose flags, result printing)
47
+ - Ruby only, GPL-3.0-only
48
+ - Must conform to behaviour schema v1.1.0 when generating rule proposals
49
+ acceptance_criteria:
50
+ - bin/raictl retrospective list discovers all retrospective-YYYY-MM-DD.md files across ~/.claude/projects/*/memory/
51
+ - bin/raictl retrospective analyze --dry-run parses findings and shows classified proposals without modifying any files
52
+ - bin/raictl retrospective analyze creates valid behaviour rules that pass bin/raictl behaviour validate
53
+ - bin/raictl retrospective status shows the backlog of unacted findings
54
+ - FindingParser extracts both Process Change checkboxes and Preventive Action lines
55
+ - FindingClassifier correctly categorizes at least 80% of findings from the existing 3 retrospectives
56
+ - No rule ID collisions with existing behaviour rules
57
+ - RSpec coverage for all 4 modules in spec/rosett_ai/retrospective/
58
+ examples:
59
+ - scenario: User runs analyze on a retrospective with 5 process changes
60
+ expected: 5 findings extracted, classified, and presented as proposals grouped by category
61
+ - scenario: User approves a behavioural proposal
62
+ expected: Rule added to operational_discipline.yml, validated, compiled to ~/.claude/rules/
63
+ - scenario: User runs status after acting on 3 of 5 findings
64
+ expected: Shows 2 pending findings with source retrospective and date
65
+ anti_patterns:
66
+ - Auto-executing behaviour modifications without user approval
67
+ - Using API calls for classification when offline heuristics suffice
68
+ - Generating duplicate rules that overlap with existing session_retrospective.yml
69
+ - Merging the retrospective cache with the adopt cache (different concerns)
70
+ preferences:
71
+ language: ruby
72
+ patterns:
73
+ - Thor subcommand (thin task delegating to domain modules)
74
+ - Keyword-based heuristic classification
75
+ - SHA256 finding hash for deduplication
76
+ testing: rspec
77
+ gems:
78
+ - tty-prompt (approval prompts)
79
+ - tty-spinner (progress indication)