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,229 @@
1
+ ---
2
+ name: policy_management
3
+ domain: security
4
+ version: 0.1.0
5
+ status: implemented
6
+ priority: 2
7
+ author: hugo
8
+ created_at: "2026-03-10"
9
+ modified_at: "2026-03-16"
10
+ modified_by: claude
11
+ depends_on:
12
+ - security
13
+ - ai_provenance
14
+ - ai_authorship
15
+ - engine_architecture
16
+ - compiler
17
+ - error_handling
18
+ #
19
+ intent: |
20
+ Provide a structured framework for organisations to define, enforce, and
21
+ audit AI usage policies across their development teams. While rosett-ai's
22
+ behaviour rules govern how AI tools behave, policies govern what AI tools
23
+ are allowed to do — the organisational, legal, and compliance layer.
24
+
25
+ This bridges the gap between rosett-ai's technical configuration and the
26
+ real-world requirements of regulated industries (finance, healthcare,
27
+ government, defence) and compliance frameworks (EU AI Act, SOC 2,
28
+ ISO 27001, NIST AI RMF).
29
+
30
+ Policy is the governance layer in the provenance–authorship–policy triad:
31
+ ai_provenance.yml records what each AI tool did (audit trail),
32
+ ai_authorship.yml governs how that involvement is attributed (disclosure),
33
+ and this design governs the requirements — which projects require
34
+ provenance, at what level, what disclosure is mandated, and what
35
+ file access restrictions apply.
36
+
37
+ Inspired by openvox-mcp's nine policy areas (A-I), adapted for Rosett-AI's
38
+ compilation model. Policies are authored as YAML, validated against a
39
+ schema, and compiled into engine-specific enforcement rules.
40
+
41
+ Key capabilities:
42
+ - Policy tiers (mandatory, advisory, informational) with per-project override
43
+ - Deny lists for sensitive file patterns (keys, credentials, secrets)
44
+ - Protected files list (files AI may read but not modify)
45
+ - License allowlist/rejectlist for dependency auditing
46
+ - Rate limiting configuration for AI-assisted contributions
47
+ - Opt-out markers for files and directories
48
+ - Policy versioning with no retroactive enforcement
49
+ - Tiered enforcement: strict for org-critical, advisory for team projects
50
+ #
51
+ constraints:
52
+ - "Policies must never weaken security constraints from security.yml"
53
+ - "Policy files use YAML.safe_load only, validated against a policy schema"
54
+ - "Policy file content must be validated for ANSI escape sequences and
55
+ control characters — deny-list patterns and protected file paths are
56
+ stripped of control characters before compilation"
57
+ - "Deny-list patterns must be validated for path traversal — patterns
58
+ containing '..' or symlink resolution outside the project root are
59
+ rejected"
60
+ - "Deny-list patterns must be tested (no untested glob patterns) — a
61
+ dry-run mode shows which files each pattern would match"
62
+ - "Policy tiers can be tightened by child projects but never loosened"
63
+ - "Protected files are read-only for AI — human override requires explicit
64
+ waiver"
65
+ - "Rate limiting is advisory by default, enforceable only with explicit
66
+ configuration"
67
+ - "Policy changes must be auditable (git history is the audit trail)"
68
+ - "No policy enforcement requires network access (offline-first)"
69
+ - "Policy compilation must produce engine-specific output (e.g. Claude
70
+ denied paths, Cursor ignore patterns). Engines declare policy-compatible
71
+ features in their capability manifests"
72
+ - "Opt-out markers must be respected across all engines"
73
+ - "Policy files are subject to the same size limits as other YAML files
74
+ (1 MB per file, 10 nesting levels, 1000 keys per security.yml)"
75
+ - "This design governs compile-time policy governance — policies are
76
+ evaluated and compiled into engine-specific rules before AI tools run.
77
+ raictl does not enforce policies at runtime. Runtime behaviour of AI
78
+ tools is governed by the compiled output, not by Rosett-AI itself"
79
+ #
80
+ acceptance_criteria:
81
+ - "bin/raictl policy init creates .rosett-ai/conf/policies/ with default policy
82
+ template"
83
+ - "bin/raictl policy validate checks all policy files against the policy
84
+ schema"
85
+ - "bin/raictl policy show displays active policies with tier and enforcement
86
+ level using TTY-aware output (table when interactive, plain text when
87
+ piped)"
88
+ - "Deny-list patterns from policy compile to Claude Code denied paths in
89
+ settings.json"
90
+ - "Deny-list patterns from policy compile to Cursor ignore patterns in
91
+ .cursorrules"
92
+ - "Protected files from policy compile to read-only annotations in
93
+ AGENTS.md"
94
+ - "License allowlist integrates with bundler-audit and dependency checking"
95
+ - "Policy tier hierarchy is enforced (org > team > project, can only
96
+ tighten)"
97
+ - "Opt-out markers (AI-MODIFICATION disabled) are honoured during
98
+ compilation"
99
+ - "bin/raictl policy audit generates a compliance report for the current
100
+ project using TTY-aware output"
101
+ - "Rate limiting configuration is parsed and included in compiled output
102
+ where engines support it"
103
+ - "bin/raictl policy audit --framework 'EU AI Act' maps policies to
104
+ specific compliance requirements"
105
+ - "Exit code 0 on success, 1 on policy violation, 2 on validation error,
106
+ 3 on tier weakening attempt, 5 on missing policy schema"
107
+ #
108
+ examples:
109
+ - scenario: "Financial services company mandates no AI access to PCI-DSS scoped files"
110
+ expected: |
111
+ Organisation policy defines deny-list patterns for card data files,
112
+ PCI-scoped directories. bin/raictl compile generates Claude Code
113
+ settings.json with denied paths. Cursor gets ignore patterns.
114
+ AGENTS.md gets "DO NOT ACCESS" annotations.
115
+ not: "Deny list only works for one engine. Other engines silently ignore restrictions."
116
+ - scenario: "Open-source project opts out specific files from AI modification"
117
+ expected: |
118
+ Files marked with # AI-MODIFICATION: disabled are included in
119
+ protected files list during compilation. AI tools can read but
120
+ not modify these files. Policy validation confirms markers are
121
+ consistent with .rosett-ai/conf/policies/protected_files.yml.
122
+ not: "Opt-out markers are ignored by some engines."
123
+ - scenario: "Team project wants to allow AI but cap contributions"
124
+ expected: |
125
+ Policy sets rate_limit: 5 AI-assisted PRs per week per contributor.
126
+ Compiled output includes advisory note in AGENTS.md and CLAUDE.md.
127
+ CI integration (if configured) flags exceeding the limit.
128
+ not: "Rate limiting silently blocks contributions without explanation."
129
+ - scenario: "Child project tries to loosen parent organisation's deny list"
130
+ expected: |
131
+ bin/raictl policy validate rejects the override with error:
132
+ 'Cannot remove deny-list pattern from parent policy — tighten only'.
133
+ Exit code 3.
134
+ not: "Child project successfully removes security-critical deny patterns."
135
+ - scenario: "Running a compliance audit report"
136
+ expected: |
137
+ `rai policy audit` generates:
138
+ ┌───────────────────┬──────────┬─────────────┬─────────┐
139
+ │ Policy │ Tier │ Enforcement │ Status │
140
+ ├───────────────────┼──────────┼─────────────┼─────────┤
141
+ │ deny_pci_files │ mandatory│ strict │ active │
142
+ │ rate_limit │ advisory │ advisory │ active │
143
+ │ ai_disclosure │ mandatory│ standard │ active │
144
+ └───────────────────┴──────────┴─────────────┴─────────┘
145
+ Piped output: tab-separated, no box drawing.
146
+ not: "No audit capability. Must manually review policy files."
147
+ - scenario: "Deny-list pattern contains path traversal attempt"
148
+ expected: |
149
+ `rai policy validate` rejects: 'Deny-list pattern "../../etc/passwd"
150
+ contains path traversal — patterns must be relative to project root'.
151
+ not: "Path traversal pattern is accepted and compiled into engine config."
152
+ #
153
+ anti_patterns:
154
+ - "Policies that require API calls to validate (must work offline)"
155
+ - "Using behaviour YAML for policy concerns (separate policy from behaviour)"
156
+ - "Retroactive policy enforcement (evaluate against policy at submission time)"
157
+ - "Binary enforcement (allow/block) without advisory middle ground"
158
+ - "Hardcoding policy patterns instead of making them configurable"
159
+ - "Policy that cannot be audited (must be in version control)"
160
+ - "Rate limiting that blocks instead of flags (advisory by default)"
161
+ - "Policy tier weakening (child can only tighten, never loosen)"
162
+ - "Deny-list patterns without dry-run testing (untested patterns may
163
+ match unintended files)"
164
+ - "Runtime policy enforcement by Rosett-AI (rai compiles, it does not enforce)"
165
+ #
166
+ gui_notes: |
167
+ Document interactions (cross-references):
168
+
169
+ 1. ai_provenance.yml: policy governs provenance requirements — which
170
+ projects must record provenance, at what granularity.
171
+
172
+ 2. ai_authorship.yml: policy governs disclosure requirements — which
173
+ projects must disclose AI involvement, at what level.
174
+
175
+ 3. security.yml: policies must never weaken security constraints.
176
+ Deny-list patterns are subject to path validation and content
177
+ stripping from security.yml.
178
+
179
+ 4. engine_architecture.yml: engines declare policy-compatible features
180
+ (deny paths, ignore patterns, read-only annotations) in manifests.
181
+
182
+ 5. compiler.yml: policy is a compilation target — YAML policies compile
183
+ to engine-specific enforcement rules.
184
+
185
+ 6. error_handling.yml: exit codes and structured error messages follow
186
+ the error hierarchy (what/why/fix format).
187
+
188
+ 7. behaviour_composition.yml: policies govern what AI may do; behaviours
189
+ govern how AI behaves. Both compile to engine-native formats but
190
+ serve different purposes.
191
+
192
+ Policy schema outline:
193
+ version: string (schema version)
194
+ policies:
195
+ - name: string
196
+ tier: mandatory | advisory | informational
197
+ enforcement: strict | standard | advisory
198
+ scope: org | team | project
199
+ deny_list:
200
+ - pattern: string (glob)
201
+ reason: string
202
+ protected_files:
203
+ - pattern: string (glob)
204
+ access: read_only
205
+ waiver: string (conditions for override)
206
+ license_allowlist: [string (SPDX identifiers)]
207
+ license_rejectlist: [string (SPDX identifiers)]
208
+ rate_limit:
209
+ max_ai_prs: integer
210
+ period: string (e.g. "7d")
211
+ enforcement: advisory | blocking
212
+ disclosure_level: none | minimal | standard | full
213
+ provenance_required: boolean
214
+ #
215
+ preferences:
216
+ language: ruby
217
+ patterns:
218
+ - "Tiered enforcement (mandatory/advisory/informational)"
219
+ - "Deny-list with schema validation and dry-run testing"
220
+ - "Protected files compilation to engine-native formats"
221
+ - "Hierarchical policy inheritance (tighten-only)"
222
+ - "Offline-first validation"
223
+ - "TTY-aware output (TtyHelper)"
224
+ testing: rspec with policy hierarchy fixtures, deny-list glob tests,
225
+ path traversal rejection, cross-engine compilation, tier weakening
226
+ prevention, and compliance audit report scenarios
227
+ gems:
228
+ - json_schemer
229
+ - thor
@@ -0,0 +1,183 @@
1
+ ---
2
+ name: project_management
3
+ domain: core
4
+ version: 0.2.0
5
+ status: draft
6
+ priority: 3
7
+ author: hugo
8
+ created_at: "2026-03-15"
9
+ modified_at: "2026-03-23"
10
+ modified_by: claude
11
+ depends_on:
12
+ - architecture
13
+ - engine_architecture
14
+ - security
15
+ - compiler
16
+ - error_handling
17
+ - backward_compatibility
18
+ - scope_hierarchy
19
+ #
20
+ intent: |
21
+ Provide project lifecycle management beyond initial scaffolding — adding
22
+ behaviours, configuring engines, managing design documents, and
23
+ synchronising with upstream rosett-ai updates. Centralise project-specific
24
+ operations that currently require manual file manipulation or multiple
25
+ unrelated commands into the `rai project` command, covering template
26
+ application, configuration drift detection, and project health reporting.
27
+
28
+ Project management complements two adjacent commands in the Rosett-AI lifecycle:
29
+ `rai init` creates the initial .rosett-ai/ directory structure (scaffolding),
30
+ and `rai retrofit` imports existing native AI tool configs into Rosett-AI YAML.
31
+ Once a project is initialised and optionally retrofitted, `rai project`
32
+ manages its ongoing lifecycle — applying templates, detecting drift,
33
+ syncing with upstream, and reporting health. The lifecycle flow is:
34
+ init (scaffold) → retrofit (import) → project (manage) → compile (deploy).
35
+ #
36
+ constraints:
37
+ - "All project operations must work within the .rosett-ai/ directory scope.
38
+ Project scope (.rosett-ai/conf/) is distinct from local scope (parent
39
+ .rosett-ai/conf/) — see scope_hierarchy.yml for the full specification"
40
+ - "Template application must never overwrite user-modified files without
41
+ confirmation or --force flag"
42
+ - "Forward drift detection compares source YAML against compiled native
43
+ config (source → compiled). Template drift detection compares project
44
+ config against the template baseline that generated it (config → template)"
45
+ - "Must support both interactive and non-interactive (CI) modes"
46
+ - "Project configuration changes must be logged to a structured audit log
47
+ (JSON Lines format in .rosett-ai/logs/project.jsonl)"
48
+ - "Templates must be engine-agnostic — engine-specific content is added by
49
+ engines during compilation, not by templates during application"
50
+ - "All template YAML files must be parsed with YAML.safe_load only"
51
+ - "Template content must be validated for security — imported behaviour
52
+ rules are subject to the same content validation as authored behaviours
53
+ (ANSI stripping, control character removal, no secret references)"
54
+ - "`rai project sync` must verify upstream source integrity before applying
55
+ changes. Sync sources must be explicitly configured in .rosett-ai/config.yml
56
+ — no implicit network access or unsigned content"
57
+ - "`rai project sync` must warn when upstream changes include breaking
58
+ modifications (removed keys, changed semantics) and require --force or
59
+ explicit confirmation to apply"
60
+ - "This design governs project lifecycle management (templates, drift,
61
+ sync, status). Initial scaffolding is governed by architecture.yml
62
+ (rai init). Config import is governed by retrofit.yml. Source-to-native
63
+ compilation is governed by compiler.yml. Per-engine drift at the native
64
+ config level is handled by compile, not project_management"
65
+ - "`rai init --project` creates a project-level .rosett-ai/ marker and
66
+ conf/ subtree. `rai init --local` creates a local-level (workspace)
67
+ .rosett-ai/ marker. The scope type (local vs project) is determined by
68
+ the presence of child .rosett-ai/ markers — see scope_hierarchy.yml"
69
+ #
70
+ acceptance_criteria:
71
+ - "`rai project status` shows current project configuration and health
72
+ using TTY-aware output (table when interactive, plain text when piped)"
73
+ - "`rai project apply-template NAME` applies a project template with
74
+ conflict resolution (skip, overwrite, merge)"
75
+ - "`rai project drift` detects both forward drift (source → compiled)
76
+ and template drift (config → template baseline), reporting each type
77
+ separately"
78
+ - "`rai project drift --type forward` shows only source-to-compiled drift"
79
+ - "`rai project drift --type template` shows only config-to-template drift"
80
+ - "`rai project sync` updates project configs from upstream rosett-ai changes
81
+ with breaking-change detection"
82
+ - "`rai project info` shows project metadata (name, engine, behaviours,
83
+ template origin)"
84
+ - "Non-interactive mode uses safe defaults (skip conflicts, report only)"
85
+ - "Exit code 0 on success, 1 on operation failure, 2 on validation error,
86
+ 3 on missing project config, 4 on drift detected, 5 on sync conflict"
87
+ - "`rai init --project` creates project-level .rosett-ai/ with config.yml
88
+ and conf/ subtree. `rai init --local` creates local-level .rosett-ai/ for
89
+ workspace grouping"
90
+ - "`rai project status` shows which scope is active (global, local,
91
+ project) and the resolved source and output directories"
92
+ #
93
+ examples:
94
+ - scenario: "Developer applies the 'ruby-gem' template to a new project"
95
+ expected: |
96
+ Template populates .rosett-ai/conf/behaviour/ with Ruby-specific behaviours.
97
+ Existing files are not overwritten. --verbose shows each file applied.
98
+ not: "Template overwrites existing custom behaviours without asking"
99
+ - scenario: "rosett-ai was upgraded and project configs are outdated"
100
+ expected: |
101
+ `rai project drift --type template` lists specific files that differ
102
+ from the new baseline: 'conf/behaviour/security.yml: 3 keys changed
103
+ (added: cve_scanning, removed: none, modified: audit_level)'.
104
+ not: "Silent acceptance of outdated configs"
105
+ - scenario: "Running `rai project status` in CI"
106
+ expected: |
107
+ Clean machine-readable output with exit code indicating health.
108
+ Non-interactive mode: no prompts, no colour, tab-separated values.
109
+ not: "Interactive prompts that block CI pipeline"
110
+ - scenario: "Sync finds breaking changes in upstream"
111
+ expected: |
112
+ `rai project sync` warns: 'Upstream v1.2.0 removes key
113
+ behaviour.max_priority (breaking change). Use --force to apply or
114
+ review changes with --simulate.' Exit code 5.
115
+ not: "Breaking changes applied silently. Existing config corrupted."
116
+ - scenario: "Forward drift detected — compiled config differs from source YAML"
117
+ expected: |
118
+ `rai project drift --type forward` shows: 'Forward drift detected:
119
+ .claude/settings.json differs from compiled output of conf/claude_code/.
120
+ Run `rai compile` to sync, or `rai retrofit --simulate` to review.'
121
+ not: "No way to detect that native config was hand-edited after compile."
122
+ - scenario: "Template contains a behaviour file with suspicious content"
123
+ expected: |
124
+ Template validation detects ANSI escape sequences or shell metacharacters
125
+ in a behaviour rule. Warning: 'Template behaviour security_001 contains
126
+ suspicious content — review before applying'. --strict mode rejects.
127
+ not: "Malicious content in template is applied without any validation."
128
+ #
129
+ anti_patterns:
130
+ - "Modifying files outside the .rosett-ai/ directory scope"
131
+ - "Requiring interactive input in CI environments"
132
+ - "Templates that embed engine-specific configuration"
133
+ - "Drift detection that flags cosmetic differences (comments, whitespace)"
134
+ - "Sync that silently downgrades or removes configuration keys"
135
+ - "Drift detection that requires network access to compute"
136
+ #
137
+ gui_notes: |
138
+ Document interactions (cross-references):
139
+
140
+ 1. architecture.yml: `rai init` creates the .rosett-ai/ structure that
141
+ project_management operates within. Init is scaffolding;
142
+ project is lifecycle.
143
+
144
+ 2. retrofit.yml: retrofit imports existing native configs into Rosett-AI YAML.
145
+ Project management manages the ongoing lifecycle after import.
146
+ The flow is: init → retrofit → project → compile.
147
+
148
+ 3. compiler.yml: forward drift detection compares source YAML against
149
+ compiled native config. Per-engine drift at the native level is
150
+ handled by compile, not project_management.
151
+
152
+ 4. backward_compatibility.yml: `rai project sync` must handle upstream
153
+ breaking changes according to the deprecation policy.
154
+
155
+ 5. security.yml: template content validation, YAML.safe_load, sync
156
+ source trust verification.
157
+
158
+ 6. error_handling.yml: exit codes and structured error messages follow
159
+ the error hierarchy (what/why/fix format).
160
+
161
+ 7. engine_architecture.yml: templates are engine-agnostic. Engine-specific
162
+ content is added during compilation via engine manifests.
163
+
164
+ 8. scope_hierarchy.yml: defines the three-level scope model (global,
165
+ local, project). Project management commands operate within the
166
+ scope hierarchy. `rai init` creates scope markers; `rai project
167
+ status` reports the active scope.
168
+ #
169
+ preferences:
170
+ language: ruby
171
+ patterns:
172
+ - "Template pattern with conflict resolution strategy"
173
+ - "Baseline comparison for drift detection (forward and template)"
174
+ - "Command pattern for project operations"
175
+ - "TTY-aware output (TtyHelper)"
176
+ - "Structured audit logging (JSON Lines)"
177
+ testing: rspec with project fixture directories, drift detection scenarios
178
+ (forward and template), template conflict resolution tests, sync
179
+ breaking-change handling, and CI non-interactive mode tests
180
+ gems:
181
+ - json_schemer
182
+ - thor
183
+ - diffy
@@ -0,0 +1,164 @@
1
+ ---
2
+ name: rai_mcp_asset_discovery
3
+ domain: core
4
+ version: 0.1.0
5
+ status: draft
6
+ priority: 3
7
+ author: hugo
8
+ created_at: "2026-04-16"
9
+ modified_at: "2026-04-16"
10
+ modified_by: claude
11
+ depends_on:
12
+ - mcp_integration
13
+ - compiler
14
+ - architecture
15
+ - scope_hierarchy
16
+ #
17
+ intent: |
18
+ Expose rosett-ai's behaviour files, compiled rules, and schemas as discoverable
19
+ MCP tools. This solves a concrete problem identified in W5-01 post-retrospective:
20
+ sessions outside the rosett-ai dev directory cannot find behaviour files because
21
+ they lack bundle context and don't know the XDG/packaged/project path hierarchy.
22
+
23
+ By exposing asset discovery via MCP, any AI session with the rosett-ai MCP server
24
+ configured can query behaviour files, search rules, and check compilation status
25
+ without knowing filesystem paths. This eliminates the root cause of the
26
+ retrospective skill path failure and enables other tools (skills, hooks, external
27
+ scripts) to discover rosett-ai assets programmatically.
28
+
29
+ The tools defined here are read-only discovery operations. Write operations
30
+ (compilation, behaviour management) are covered by the parent mcp_integration
31
+ design. This design focuses exclusively on the 5 asset discovery tools.
32
+ #
33
+ constraints:
34
+ - "All 5 tools must be read-only (readOnlyHint=true, destructiveHint=false)"
35
+ - "Tools must use the 3-tier lookup: project > XDG user > packaged defaults"
36
+ - "Tools must work without bundle context — no require of dev dependencies"
37
+ - "Tool responses must be structured JSON, not formatted text"
38
+ - "File paths in responses must use display paths (~/ prefix), never absolute /home/ paths"
39
+ - "rai_behaviour_get must not return sensitive behaviours unless explicitly requested"
40
+ - "rai_rule_search must search compiled output, not raw YAML source"
41
+ - "All tools must respect the scope field introduced in behaviour schema v1.2.0"
42
+ - "Tools must not expose file contents that match deny-list patterns (credentials, keys)"
43
+ - "Response payloads must be bounded — rai_behaviour_list returns metadata not full content"
44
+ #
45
+ acceptance_criteria:
46
+ - "rai_behaviour_list returns all discoverable behaviours with name, path, scope, rule count, and source tier (project/xdg/packaged)"
47
+ - "rai_behaviour_get returns the full YAML content of a named behaviour file"
48
+ - "rai_behaviour_get returns an error for non-existent or sensitive behaviours"
49
+ - "rai_rule_search accepts a keyword and returns matching rules with behaviour name, rule ID, priority, and matching text"
50
+ - "rai_rule_search supports optional filters: priority_min, scope, enabled_only"
51
+ - "rai_schema_get returns the behaviour YAML schema (behaviour_schema.json)"
52
+ - "rai_schema_get accepts an optional schema_name parameter to retrieve other schemas (design, tooling)"
53
+ - "rai_compile_status returns per-file staleness: source checksum vs compiled checksum"
54
+ - "rai_compile_status reports orphaned compiled files (no source) and uncompiled sources (no output)"
55
+ - "All 5 tools are registered in the MCP server tool manifest with accurate annotations"
56
+ - "Integration test verifies each tool via MCP JSON-RPC protocol handshake"
57
+ - "Tools work from any working directory, not just the rosett-ai source tree"
58
+ #
59
+ examples:
60
+ - scenario: "AI session needs to find behaviour files to propose a new rule"
61
+ expected: |
62
+ Tool call: { name: "rai_behaviour_list", arguments: {} }
63
+ Response:
64
+ {
65
+ "behaviours": [
66
+ {
67
+ "name": "operational_discipline",
68
+ "scope": "global",
69
+ "source_tier": "xdg",
70
+ "path": "~/.config/rosett-ai/conf/behaviour/operational_discipline.yml",
71
+ "version": "1.0.0",
72
+ "rules_count": 76,
73
+ "enabled_rules_count": 76
74
+ },
75
+ ...
76
+ ],
77
+ "total": 8,
78
+ "source_dirs": {
79
+ "project": null,
80
+ "xdg": "~/.config/rosett-ai/conf/behaviour/",
81
+ "packaged": "/opt/rosett-ai/app/conf/behaviour/"
82
+ }
83
+ }
84
+ not: "Tool returns empty list or crashes when run outside rosett-ai directory"
85
+ - scenario: "AI session searches for rules about git hooks"
86
+ expected: |
87
+ Tool call: { name: "rai_rule_search", arguments: { keyword: "git hook" } }
88
+ Response:
89
+ {
90
+ "matches": [
91
+ {
92
+ "behaviour": "operational_discipline",
93
+ "rule_id": "rule_022",
94
+ "priority": 90,
95
+ "scope": "global",
96
+ "snippet": "Never use OVERCOMMIT_DISABLE, --no-verify, or any mechanism to bypass git hooks..."
97
+ },
98
+ ...
99
+ ],
100
+ "total": 3
101
+ }
102
+ not: "Search returns raw YAML or requires knowledge of file paths"
103
+ - scenario: "AI session checks if compiled rules are up to date"
104
+ expected: |
105
+ Tool call: { name: "rai_compile_status", arguments: {} }
106
+ Response:
107
+ {
108
+ "status": "stale",
109
+ "files": [
110
+ {
111
+ "name": "behaviour-operational_discipline",
112
+ "source_checksum": "sha256:abc123...",
113
+ "compiled_checksum": "sha256:def456...",
114
+ "stale": true,
115
+ "compiled_at": "2026-04-15T10:30:00Z"
116
+ },
117
+ ...
118
+ ],
119
+ "orphaned": [],
120
+ "uncompiled": ["behaviour-new_feature"]
121
+ }
122
+ not: "Status check triggers recompilation or modifies files"
123
+ - scenario: "AI session retrieves a specific behaviour to read its rules"
124
+ expected: |
125
+ Tool call: { name: "rai_behaviour_get", arguments: { name: "criticalthinking" } }
126
+ Response:
127
+ {
128
+ "name": "criticalthinking",
129
+ "path": "~/.config/rosett-ai/conf/behaviour/criticalthinking.yml",
130
+ "source_tier": "xdg",
131
+ "content": { ... full parsed YAML ... }
132
+ }
133
+ not: "Returns raw file content as string instead of parsed structure"
134
+ - scenario: "AI session needs the schema to validate a behaviour before writing"
135
+ expected: |
136
+ Tool call: { name: "rai_schema_get", arguments: {} }
137
+ Response:
138
+ {
139
+ "schema_name": "behaviour_schema",
140
+ "version": "1.2.0",
141
+ "content": { ... full JSON Schema ... }
142
+ }
143
+ not: "Returns a file path instead of the schema content"
144
+ #
145
+ anti_patterns:
146
+ - "Returning absolute /home/user/ paths in tool responses — use display paths"
147
+ - "Loading the full compilation pipeline just to list behaviours"
148
+ - "Caching tool responses across MCP sessions — always read fresh from disk"
149
+ - "Implementing search by loading all YAML into memory — search compiled .md files"
150
+ - "Exposing raw file system operations (read, write, delete) as MCP tools"
151
+ - "Making rai_compile_status trigger compilation as a side effect"
152
+ - "Returning unstructured text — all responses must be parseable JSON objects"
153
+ #
154
+ preferences:
155
+ language: ruby
156
+ patterns:
157
+ - "Service object per tool (RosettAi::Mcp::Tools::BehaviourList, etc.)"
158
+ - "PathResolver for all path discovery — never hardcode paths in tools"
159
+ - "Struct or Data for response objects — not raw hashes"
160
+ testing: rspec with MCP protocol integration tests, tool response schema
161
+ validation, edge cases for missing dirs and empty results
162
+ gems:
163
+ - mcp
164
+ - json_schemer