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,217 @@
1
+ # Issue 002: Embedded Ruby compiled with wrong --prefix
2
+
3
+ | Field | Value |
4
+ |-------------|-------------------------------------------------|
5
+ | Severity | **High** (makes Issue 001 workarounds necessary) |
6
+ | Status | **Resolved** |
7
+ | Component | CI pipeline, `lib/rosett_ai/thor/tasks/build.rb` |
8
+ | Affects | CI builds; local builds have a variant of this |
9
+ | Found in | v1.0.0 (`nncc_1.0.0-1_amd64.deb`) |
10
+ | Resolved in | v1.1.0 |
11
+
12
+ ## Resolution
13
+
14
+ Resolved via the wrapper template fix (see Issue 001). `ruby-build` does not
15
+ support separating `--prefix` from the install destination, so overriding
16
+ `--prefix` via `RUBY_CONFIGURE_OPTS` causes `make install` to write to the
17
+ system path (Permission denied). Instead:
18
+
19
+ 1. Ruby is compiled into the staging path (ruby-build's default behavior).
20
+ 2. The runtime wrapper (`packaging/wrapper.sh.template`) sets `LD_LIBRARY_PATH`,
21
+ `RUBYLIB`, and `GEM_HOME` to the correct `/opt/rosett-ai/embedded/` paths,
22
+ overriding the compiled-in prefix at runtime.
23
+ 3. Ruby's `rbconfig.rb` has a `TOPDIR` self-healing mechanism that computes the
24
+ real prefix from `File.dirname(__FILE__)` once `RUBYLIB` is set.
25
+ 4. CI pipeline no longer pre-seeds from the Docker image's `/usr/local/` Ruby.
26
+
27
+ ## Summary
28
+
29
+ The embedded Ruby binary at `/opt/rosett-ai/embedded/bin/ruby` was compiled with
30
+ `--prefix=/usr/local` instead of `--prefix=/opt/rosett-ai/embedded`. This causes
31
+ the binary's ELF `RUNPATH` and default `$LOAD_PATH` to reference
32
+ `/usr/local/lib/...` paths that do not exist on the target system.
33
+
34
+ ## Root Cause
35
+
36
+ ### CI builds: Docker image pre-seeding
37
+
38
+ The CI pipeline (`.gitlab-ci-files/build/package.yml`, lines 28-33)
39
+ pre-populates the staging directory with the Docker image's Ruby to skip the
40
+ 13-minute `ruby-build` compilation:
41
+
42
+ ```yaml
43
+ - mkdir -p tmp/staging/opt/rosett-ai/embedded
44
+ - |
45
+ if ! tmp/staging/opt/rosett-ai/embedded/bin/ruby --version 2>/dev/null; then
46
+ echo "Seeding embedded Ruby from Docker image..."
47
+ rsync -a /usr/local/ tmp/staging/opt/rosett-ai/embedded/
48
+ fi
49
+ ```
50
+
51
+ The Docker image (`ruby:3.3.10-bookworm`) installs Ruby at `/usr/local/` with
52
+ `--prefix=/usr/local`. Copying these files to `tmp/staging/opt/rosett-ai/embedded/`
53
+ does **not** change the compiled-in prefix. The binary retains:
54
+
55
+ - **ELF RUNPATH**: `/usr/local/lib` (where it searches for `libruby.so.3.3`)
56
+ - **Default `$LOAD_PATH`**: `/usr/local/lib/ruby/3.3.0`, etc.
57
+
58
+ The `compile_ruby!` method's `ruby_already_compiled?` check (build.rb:327-333)
59
+ only verifies `RUBY_VERSION` matches — it does not check the compiled prefix:
60
+
61
+ ```ruby
62
+ def ruby_already_compiled?
63
+ ruby_bin = staging_embedded.join('bin', 'ruby')
64
+ return false unless ruby_bin.exist?
65
+
66
+ installed = IO.popen([ruby_bin.to_s, '-e', 'puts RUBY_VERSION'], &:read).strip
67
+ installed == ruby_version.sub(/\A(\d+\.\d+\.\d+).*/, '\1')
68
+ end
69
+ ```
70
+
71
+ ### Local builds: staging absolute path as prefix
72
+
73
+ When `ruby-build` is invoked locally (build.rb:306-307):
74
+
75
+ ```ruby
76
+ run_clean_command('ruby-build', ruby_version, staging_embedded.to_s)
77
+ ```
78
+
79
+ `staging_embedded` resolves to an absolute path like:
80
+
81
+ ```text
82
+ /home/user/git/Neatnerds/NNCO/rosett-ai/tmp/staging/opt/rosett-ai/embedded
83
+ ```
84
+
85
+ `ruby-build` passes this as `--prefix` to Ruby's `./configure`. The resulting
86
+ binary has the full staging path compiled in, which won't exist on the target
87
+ system after `dpkg -i` installs the files to `/opt/rosett-ai/embedded/`.
88
+
89
+ ## Evidence
90
+
91
+ ```text
92
+ $ readelf -d /opt/rosett-ai/embedded/bin/ruby | grep RUNPATH
93
+ 0x000000000000001d (RUNPATH) Library runpath: [/usr/local/lib]
94
+
95
+ $ strings /opt/rosett-ai/embedded/bin/ruby | grep '/usr/local'
96
+ /usr/local/lib
97
+
98
+ $ LD_LIBRARY_PATH=/opt/rosett-ai/embedded/lib \
99
+ /opt/rosett-ai/embedded/bin/ruby -e 'puts $LOAD_PATH'
100
+ /usr/local/lib/ruby/site_ruby/3.3.0
101
+ /usr/local/lib/ruby/site_ruby/3.3.0/x86_64-linux
102
+ /usr/local/lib/ruby/site_ruby
103
+ /usr/local/lib/ruby/vendor_ruby/3.3.0
104
+ /usr/local/lib/ruby/vendor_ruby/3.3.0/x86_64-linux
105
+ /usr/local/lib/ruby/vendor_ruby
106
+ /usr/local/lib/ruby/3.3.0
107
+ /usr/local/lib/ruby/3.3.0/x86_64-linux
108
+ ```
109
+
110
+ Note: `rbconfig.rb` has a self-healing `TOPDIR` mechanism based on
111
+ `File.dirname(__FILE__)`, so `RbConfig::CONFIG["prefix"]` reports
112
+ `/opt/rosett-ai/embedded` when loaded via `RUBYLIB`. But the binary itself cannot
113
+ load `rbconfig.rb` because the default `$LOAD_PATH` points elsewhere.
114
+
115
+ ## Proposed Solutions
116
+
117
+ ### Option A: Compile Ruby with correct prefix in CI (recommended)
118
+
119
+ Replace the Docker pre-seeding with a dedicated compilation step that uses the
120
+ correct prefix. To preserve the CI speed optimization, compile Ruby once in a
121
+ separate CI job and cache the result.
122
+
123
+ **CI pipeline change:**
124
+
125
+ ```yaml
126
+ before_script:
127
+ - !reference [.ruby_base, before_script]
128
+ - apt-get install -y -qq fakeroot dpkg-dev rsync
129
+ - bundle exec fpm --version
130
+ # Compile Ruby with correct prefix if not cached
131
+ - mkdir -p tmp/staging/opt/rosett-ai/embedded
132
+ - |
133
+ RUBY_BIN=tmp/staging/opt/rosett-ai/embedded/bin/ruby
134
+ if [ -x "$RUBY_BIN" ] && \
135
+ "$RUBY_BIN" -e "exit(RbConfig::CONFIG['prefix'] == '/opt/rosett-ai/embedded' ? 0 : 1)" 2>/dev/null; then
136
+ echo "Cached Ruby has correct prefix — skipping compilation"
137
+ else
138
+ echo "Compiling Ruby with --prefix=/opt/rosett-ai/embedded..."
139
+ RUBY_CONFIGURE_OPTS="--prefix=/opt/rosett-ai/embedded" \
140
+ ruby-build 3.3.10 tmp/staging/opt/rosett-ai/embedded
141
+ fi
142
+ ```
143
+
144
+ **Build.rb change** — update `ruby_already_compiled?` to verify prefix:
145
+
146
+ ```ruby
147
+ def ruby_already_compiled?
148
+ ruby_bin = staging_embedded.join('bin', 'ruby')
149
+ return false unless ruby_bin.exist?
150
+
151
+ output = IO.popen(
152
+ [ruby_bin.to_s, '-e', 'puts RUBY_VERSION; puts RbConfig::CONFIG["prefix"]'],
153
+ &:read
154
+ ).strip
155
+ version, prefix = output.split("\n", 2)
156
+ version == ruby_version.sub(/\A(\d+\.\d+\.\d+).*/, '\1') &&
157
+ prefix == INSTALL_DIR + '/embedded'
158
+ rescue StandardError
159
+ false
160
+ end
161
+ ```
162
+
163
+ ### Option B: Fix prefix post-build with patchelf
164
+
165
+ After pre-seeding from Docker, use `patchelf` to update the `RUNPATH` and
166
+ rely on `RUBYLIB` in the wrapper for load path correction:
167
+
168
+ ```yaml
169
+ - rsync -a /usr/local/ tmp/staging/opt/rosett-ai/embedded/
170
+ - patchelf --set-rpath /opt/rosett-ai/embedded/lib tmp/staging/opt/rosett-ai/embedded/bin/ruby
171
+ ```
172
+
173
+ This is faster than recompiling but only fixes `RUNPATH`. The `$LOAD_PATH`
174
+ would still need `RUBYLIB` override in the wrapper (Issue 001 fix).
175
+
176
+ ### Option C: Use `RUBY_CONFIGURE_OPTS` for local builds
177
+
178
+ For local builds, override the prefix passed to `ruby-build`:
179
+
180
+ ```ruby
181
+ def compile_ruby!
182
+ # ... existing checks ...
183
+ env = clean_env.merge(
184
+ 'RUBY_CONFIGURE_OPTS' => "--prefix=#{INSTALL_DIR}/embedded"
185
+ )
186
+ success = system(env, 'ruby-build', ruby_version, staging_embedded.to_s)
187
+ # ...
188
+ end
189
+ ```
190
+
191
+ `ruby-build` supports `RUBY_CONFIGURE_OPTS` to pass additional flags to
192
+ Ruby's `./configure`. Setting `--prefix=/opt/rosett-ai/embedded` ensures the
193
+ compiled binary has the correct install path, even though it's initially
194
+ built into the staging directory.
195
+
196
+ ## Recommendation
197
+
198
+ Implement **Option A + C** together:
199
+
200
+ 1. CI compiles Ruby with `--prefix=/opt/rosett-ai/embedded` (via `RUBY_CONFIGURE_OPTS`)
201
+ 2. Local builds also set `RUBY_CONFIGURE_OPTS` in `compile_ruby!`
202
+ 3. `ruby_already_compiled?` validates both version AND prefix
203
+ 4. The wrapper script fix from Issue 001 provides defense-in-depth
204
+
205
+ Even with the correct prefix, the wrapper should still set `LD_LIBRARY_PATH`
206
+ and `RUBYLIB` as defense-in-depth — the system dynamic linker does not search
207
+ `/opt/rosett-ai/embedded/lib/` by default, and there is no `ldconfig` entry for it.
208
+
209
+ ## Affected Files
210
+
211
+ - `.gitlab-ci-files/build/package.yml` (CI pre-seeding logic)
212
+ - `lib/rosett_ai/thor/tasks/build.rb` (`compile_ruby!`, `ruby_already_compiled?`)
213
+
214
+ ## Related Issues
215
+
216
+ - [001 - Wrapper script missing environment variables](001-wrapper-missing-environment-variables.md)
217
+ - [003 - Smoke test installs system Ruby masking failures](003-smoke-test-false-positive.md)
@@ -0,0 +1,127 @@
1
+ # Issue 003: Smoke test may produce false positives
2
+
3
+ | Field | Value |
4
+ |-------------|--------------------------------------------------|
5
+ | Severity | **Medium** (test reliability) |
6
+ | Status | **Resolved** |
7
+ | Component | `.gitlab-ci-files/build/package.yml` |
8
+ | Affects | CI pipeline |
9
+ | Found in | v1.0.0 |
10
+ | Resolved in | v1.1.0 |
11
+
12
+ ## Resolution
13
+
14
+ Removed `apt-get install ... ruby` from the smoke test. The test now installs only
15
+ the built `.deb` and its declared APT dependencies. Added assertions to verify:
16
+
17
+ - CLI commands (`raictl version`, `rai validate`, `rai engines list`) work
18
+ - Embedded Ruby reports correct compiled prefix (`/opt/rosett-ai/embedded`)
19
+ - ELF RUNPATH points to `/opt/rosett-ai/embedded/lib`
20
+
21
+ ## Summary
22
+
23
+ The CI smoke test job (`build:package:smoke_test`) installs a system Ruby via
24
+ `apt-get` before installing the rosett-ai `.deb` package. This may mask the runtime
25
+ failures described in Issues 001 and 002, creating a false sense that the
26
+ package works correctly on a clean target system.
27
+
28
+ ## Current Smoke Test
29
+
30
+ ```yaml
31
+ build:package:smoke_test:
32
+ stage: build
33
+ image: debian:bookworm
34
+ script:
35
+ - apt-get update && apt-get install -y --no-install-recommends ruby
36
+ - dpkg -i pkg/*.deb || apt-get install -fy --no-install-recommends
37
+ - rosett-ai version
38
+ - rai validate
39
+ - rai engines list
40
+ ```
41
+
42
+ ## Analysis
43
+
44
+ ### Why `apt-get install ruby` is problematic
45
+
46
+ The `apt-get install ... ruby` line installs Debian bookworm's system Ruby
47
+ (3.1.x), which pulls in `libruby3.1`. This does **not** provide
48
+ `libruby.so.3.3` (needed by the embedded Ruby 3.3.10), so it would not
49
+ directly fix Failure 1 from Issue 001.
50
+
51
+ However, installing system Ruby may have indirect side effects:
52
+
53
+ - It places Ruby-related libraries in system library paths that `ld.so` scans
54
+ - It may trigger `ldconfig` runs that update the linker cache
55
+ - On certain Debian configurations it could install packages that satisfy
56
+ transitive dependencies
57
+
58
+ ### The test should validate the package in isolation
59
+
60
+ The smoke test's purpose is to verify that `dpkg -i rosett-ai.deb` produces a
61
+ working installation on a clean Debian system. Installing extra packages
62
+ before the test defeats this purpose — it cannot detect missing dependencies
63
+ or environment setup issues.
64
+
65
+ ### Current test outcome
66
+
67
+ Given the `RUNPATH` and `$LOAD_PATH` issues documented in Issues 001 and 002,
68
+ this smoke test should fail with the same errors the user observed. If it
69
+ passes in CI, it may be because:
70
+
71
+ 1. The CI cache retains state from previous runs
72
+ 2. The Docker environment has additional libraries in system paths
73
+ 3. The test has not actually run on a clean system recently
74
+
75
+ ## Proposed Fix
76
+
77
+ Remove the system Ruby installation and test the package in isolation:
78
+
79
+ ```yaml
80
+ build:package:smoke_test:
81
+ stage: build
82
+ image: debian:bookworm
83
+ tags:
84
+ - docker
85
+ needs:
86
+ - job: build:package:amd64
87
+ artifacts: true
88
+ script:
89
+ # Install the package and its declared dependencies only
90
+ - apt-get update
91
+ - dpkg -i pkg/*.deb || apt-get install -fy --no-install-recommends
92
+ # Verify the CLI works without any extra packages installed
93
+ - rosett-ai version
94
+ - rai validate
95
+ - rai engines list
96
+ # Verify the embedded Ruby reports correct prefix
97
+ - /opt/rosett-ai/embedded/bin/ruby -e 'puts RbConfig::CONFIG["prefix"]' | grep -q '/opt/rosett-ai/embedded'
98
+ rules:
99
+ - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
100
+ when: on_success
101
+ - if: $CI_COMMIT_TAG
102
+ when: on_success
103
+ ```
104
+
105
+ ### Additional verification steps
106
+
107
+ Consider adding these assertions to catch regressions:
108
+
109
+ ```bash
110
+ # Verify libruby.so is found without manual LD_LIBRARY_PATH
111
+ ldd /opt/rosett-ai/embedded/bin/ruby | grep -q 'libruby.so.3.3 => /opt/rosett-ai'
112
+
113
+ # Verify RubyGems loads
114
+ /opt/rosett-ai/bin/raictl version 2>&1 | grep -v 'were not loaded'
115
+
116
+ # Verify no stale prefix in RUNPATH
117
+ readelf -d /opt/rosett-ai/embedded/bin/ruby | grep RUNPATH | grep -q '/opt/rosett-ai/embedded/lib'
118
+ ```
119
+
120
+ ## Affected Files
121
+
122
+ - `.gitlab-ci-files/build/package.yml` (smoke test job definition)
123
+
124
+ ## Related Issues
125
+
126
+ - [001 - Wrapper script missing environment variables](001-wrapper-missing-environment-variables.md)
127
+ - [002 - Embedded Ruby compiled with wrong prefix](002-embedded-ruby-wrong-prefix.md)
@@ -0,0 +1,109 @@
1
+ # ISSUE-004: Update Design Documents with Market Research Findings
2
+
3
+ ## Status
4
+
5
+ Open (2026-03-22)
6
+
7
+ ## Context
8
+
9
+ Market research conducted during NLnet grant preparation (see
10
+ `doc/context/ai-engine-usage-trends-2026.md`) revealed industry data that validates
11
+ rosett-ai's architecture and identifies areas where design documents should be updated to
12
+ reflect the current landscape.
13
+
14
+ ## Research Summary
15
+
16
+ - 59% of developers use 3+ AI tools; 20% use 5+
17
+ - Engine switching is constant (Claude Code: 0 to #1 in 8 months)
18
+ - Configuration portability between engines does not exist
19
+ - Vendor lock-in in AI coding tools is now recognized as strategic risk
20
+ - AGENTS.md standardization effort emerged (OpenAI, Google, Cursor, Factory)
21
+ - Multi-agent coordination is a 2026 trend (Gartner: 1,445% inquiry surge)
22
+ - Developer confidence declines with tool count (28% at 6+ tools)
23
+
24
+ ## Required Actions
25
+
26
+ ### 1. Update ADR-006 and ADR-007
27
+
28
+ **Priority**: Medium
29
+ **Files**: `doc/decisions/006-multi-engine-architecture.md`,
30
+ `doc/decisions/007-engine-agnostic-pivot.md`
31
+
32
+ Add a "Market Validation" section to both ADRs referencing the research data. The
33
+ architectural decisions made in Feb 2026 are now backed by industry statistics. Key
34
+ points to add:
35
+
36
+ - The engine table in ADR-006 should be updated with current config locations (verify
37
+ Cursor uses `.cursor/rules/` not just `.cursor/`, verify Windsurf path)
38
+ - ADR-007's "why engine-agnostic" rationale should cite the 59% multi-tool statistic
39
+ and the Claude Code migration velocity
40
+ - Reference `doc/context/ai-engine-usage-trends-2026.md` as evidence
41
+
42
+ ### 2. AGENTS.md Positioning Document
43
+
44
+ **Priority**: Medium
45
+ **File**: `doc/AAIF_POSITIONING.md`
46
+
47
+ Update with current AGENTS.md adoption data:
48
+
49
+ - Which vendors have adopted AGENTS.md (OpenAI, Google, Cursor, Factory confirmed)
50
+ - Which have not (Claude Code, Copilot, Windsurf, Ollama — verify current status)
51
+ - rosett-ai's position: support AGENTS.md as ONE target among many, not as the only standard
52
+ - Differentiation: rai compiles to engines that will never adopt AGENTS.md
53
+
54
+ ### 3. Quorum Proofing Design Document
55
+
56
+ **Priority**: High (planned feature, grant-funded)
57
+ **File**: New — `doc/decisions/012-quorum-proofing.md` (or appropriate next number)
58
+
59
+ Create a new ADR for quorum proofing based on the multi-agent trend data:
60
+
61
+ - Problem: how to cross-validate AI outputs across engines
62
+ - Approach: parallel prompt execution, consensus detection
63
+ - Budget implication: requires paid subscriptions to multiple engines
64
+ - Reference Gartner multi-agent inquiry surge as market validation
65
+ - Reference GitHub Agent HQ and xAI Grok Build as comparable approaches
66
+ - Define what "agreement" means (exact match? semantic similarity? human review?)
67
+
68
+ ### 4. Deep Research Tasks
69
+
70
+ **Priority**: Low (post-grant-submission)
71
+
72
+ Conduct deeper research on:
73
+
74
+ a. **Engine config format evolution**: Are any engines converging on shared formats?
75
+ Track quarterly. If Cursor adopts AGENTS.md, document impact on rosett-ai's engine count.
76
+
77
+ b. **Developer governance pain points**: Survey or interview developers about their
78
+ actual workflow when switching engines. What do they lose? What do they wish they
79
+ could keep? This informs rosett-ai's feature priority.
80
+
81
+ c. **Enterprise AI governance**: How do organizations with 50+ developers manage AI
82
+ tool governance today? Manual policy documents? Per-engine configs? Nothing?
83
+ This informs the enterprise content pack strategy.
84
+
85
+ d. **Regulatory requirements for AI provenance**: Track EU AI Act implementation
86
+ details, especially re: disclosure requirements for AI-generated code in
87
+ regulated industries (finance, healthcare, government).
88
+
89
+ e. **Authorship attribution standards**: Research existing standards for attributing
90
+ sources in AI-generated output. Are there emerging conventions? Academic work?
91
+ Legal precedent?
92
+
93
+ ### 5. Update ENGINE_DEVELOPMENT_GUIDE.md
94
+
95
+ **Priority**: Low
96
+
97
+ Add a section on market context for new engine contributors:
98
+
99
+ - Why engine diversity matters (59% multi-tool, constant migration)
100
+ - How to identify config format for a new engine target
101
+ - How to verify compilation output against the engine's actual behaviour
102
+
103
+ ## References
104
+
105
+ - `doc/context/ai-engine-usage-trends-2026.md` — full research data with sources
106
+ - `doc/decisions/006-multi-engine-architecture.md` — original multi-engine ADR
107
+ - `doc/decisions/007-engine-agnostic-pivot.md` — engine-agnostic architecture
108
+ - `doc/AAIF_POSITIONING.md` — AGENTS.md positioning
109
+ - `applications/nlnet-2026-q1/research/ai-engine-usage-trends.md` — grant repo copy
@@ -0,0 +1,161 @@
1
+ # Issue 005: Compile Cannot Merge Project-Level and Global Behaviours
2
+
3
+ | Field | Value |
4
+ |-------------|--------------------------------------------------------------|
5
+ | Severity | **High** |
6
+ | Status | **Open** |
7
+ | Component | `lib/rosett_ai/thor/tasks/compile.rb`, `lib/rosett_ai/project_context.rb` |
8
+ | Affects | Any workspace with `.rosett-ai/conf/behaviour/` alongside global behaviours |
9
+ | Found in | v3.3.0 (packaged .deb, post WP#711/WP#712 fixes) |
10
+ | Resolved in | — |
11
+
12
+ ## Summary
13
+
14
+ When `rai compile` is run from a directory that has an `.rosett-ai/conf/behaviour/`
15
+ project structure (created by `rai init --project`), the compile discovers
16
+ **only** the project-level behaviours. All previously compiled global behaviours
17
+ are removed as "orphans". The reverse is also true: compiling from a non-project
18
+ directory restores globals but removes any project-level rules.
19
+
20
+ This means project-level and global behaviours are **mutually exclusive** after
21
+ any single compile run. Users cannot extend the global rule set with
22
+ project-specific behaviours.
23
+
24
+ ## Distinction from WP#711 / WP#712
25
+
26
+ WP#711 fixed `ProjectContext#nncc_internal?` so the rosett-ai source tree is
27
+ correctly identified. WP#712 added an `empty?` guard to `remove_orphans`.
28
+ Both are merged (2026-03-27). This issue is **not** a regression of those
29
+ fixes — it occurs in the normal case of a non-rai project directory with
30
+ `.rosett-ai/` initialised via `rai init --project`.
31
+
32
+ ## Symptoms
33
+
34
+ ### Reproduction steps
35
+
36
+ ```bash
37
+ # 1. Start with global behaviours compiled
38
+ cd /mnt/claude-scratch && rai compile --verbose
39
+ # Output: Unchanged: behaviour-criticalthinking.md, behaviour-operational_discipline.md,
40
+ # behaviour-session_retrospective.md
41
+ # Result: 3 rules in ~/.claude/rules/
42
+
43
+ # 2. Initialise a project with its own behaviour
44
+ cd ~/git
45
+ rai init --project --no-compile
46
+ # Creates .rosett-ai/conf/behaviour/ (empty)
47
+
48
+ # Place a behaviour file:
49
+ cp documentation_first.yml .rosett-ai/conf/behaviour/
50
+
51
+ # 3. Compile from the project directory
52
+ rai compile --verbose
53
+ ```
54
+
55
+ ### Actual output
56
+
57
+ ```text
58
+ Discovered categories:
59
+ behaviour
60
+ design
61
+
62
+ Created: behaviour-documentation_first.md (5f05146f)
63
+ Removed orphan: behaviour-criticalthinking.md
64
+ Removed orphan: behaviour-operational_discipline.md
65
+ Removed orphan: behaviour-session_retrospective.md
66
+
67
+ ╭─────────────────╮
68
+ │ Compile Summary │
69
+ ├─────────┬───────┤
70
+ │ Action │ Count │
71
+ ╞═════════╪═══════╡
72
+ │ Created │ 1 │
73
+ ╰─────────┴───────╯
74
+ ```
75
+
76
+ ### Expected output
77
+
78
+ ```text
79
+ Discovered categories:
80
+ behaviour (global: 3, project: 1)
81
+ design (project scope only)
82
+
83
+ Unchanged: behaviour-criticalthinking.md (d966e8ae)
84
+ Unchanged: behaviour-operational_discipline.md (da9c39a9)
85
+ Unchanged: behaviour-session_retrospective.md (deaee56c)
86
+ Created: behaviour-documentation_first.md (5f05146f)
87
+
88
+ ╭─────────────────╮
89
+ │ Compile Summary │
90
+ ├─────────┬───────┤
91
+ │ Action │ Count │
92
+ ╞═════════╪═══════╡
93
+ │ Unchanged │ 3 │
94
+ │ Created │ 1 │
95
+ ╰─────────┴───────╯
96
+ ```
97
+
98
+ ## Root Cause Analysis
99
+
100
+ ### Single-source discovery
101
+
102
+ `ProjectContext#conf_root` (line ~44 of `lib/rosett_ai/project_context.rb`) returns a
103
+ **single** path — either the global `/opt/rosett-ai/app/conf` or the project's
104
+ `.rosett-ai/conf`. This single path is passed as `source_dir:` to
105
+ `CompilationPipeline` via `build_compiler` (line ~116 of
106
+ `lib/rosett_ai/thor/tasks/compile.rb`).
107
+
108
+ `CompilationPipeline#compile` (line ~74 of
109
+ `lib/rosett_ai/compiler/compilation_pipeline.rb`) reads **only** from `@source_dir`.
110
+ There is no multi-source support.
111
+
112
+ ### Orphan removal sees only one scope
113
+
114
+ `remove_orphans` in `compile.rb` (line ~276) computes orphans as:
115
+ `managed_files - compiled_keys`. Since `compiled_keys` only contains
116
+ project-level results, all global rules are classified as orphans and deleted.
117
+
118
+ ### Design exists but is not wired
119
+
120
+ - `conf/design/scope_hierarchy.yml` (status: **draft**) defines a four-level
121
+ merge hierarchy: global → organisation → project → local
122
+ - `RosettAi::Composition::ScopeResolver` exists at
123
+ `lib/rosett_ai/composition/scope_resolver.rb` and understands the hierarchy
124
+ - Neither is connected to `CompilationPipeline` or `build_compiler`
125
+
126
+ ## Proposed Fix
127
+
128
+ ### Phase 1: Scope-aware compile (minimum viable)
129
+
130
+ 1. Modify `build_compiler` to collect **all active source directories** via
131
+ `ScopeResolver.resolve(working_dir)` instead of a single `conf_root`
132
+ 2. Pass multiple source dirs to `CompilationPipeline` (or run the pipeline
133
+ per-scope and merge results before orphan removal)
134
+ 3. `remove_orphans` receives the **union** of all compiled keys across scopes
135
+
136
+ ### Phase 2: CLI flags (from scope_hierarchy.yml design)
137
+
138
+ Add `--global`, `--project`, `--local` flags to `rai compile` so users can
139
+ target a single scope when needed (e.g. `rai compile --project` only
140
+ recompiles project-level without touching globals).
141
+
142
+ ### Phase 3: Priority resolution
143
+
144
+ When a project behaviour has the same `name` as a global behaviour, the
145
+ project-level version should win (override), following the existing
146
+ configuration hierarchy documented in CLAUDE.md.
147
+
148
+ ## Affected Files
149
+
150
+ - `lib/rosett_ai/project_context.rb` — `conf_root` must support multi-source
151
+ - `lib/rosett_ai/thor/tasks/compile.rb` — `build_compiler` and `remove_orphans`
152
+ - `lib/rosett_ai/compiler/compilation_pipeline.rb` — accept multiple source dirs
153
+ - `lib/rosett_ai/composition/scope_resolver.rb` — wire into compile flow
154
+ - `conf/design/scope_hierarchy.yml` — update status from draft to in-progress
155
+
156
+ ## Related Issues
157
+
158
+ - [Issue 001](001-wrapper-missing-environment-variables.md) — environment variable handling
159
+ - WP#711 — `fix/711-compile-reads-rosett-ai-conf-instead-of-source` (merged)
160
+ - WP#712 — `fix/712-compile-deletes-global-rules-as-orphans` (merged)
161
+ - `conf/design/scope_hierarchy.yml` — design document for scope merging
File without changes