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.
- checksums.yaml +7 -0
- data/.ai-provenance.yml +119 -0
- data/.debride_whitelist +186 -0
- data/.fasterer.yml +29 -0
- data/.mdl_style.rb +10 -0
- data/.mdlrc +3 -0
- data/.mutant.yml +49 -0
- data/.namespace-allowlist +42 -0
- data/.reek.yml +1040 -0
- data/.rosett-ai/config.yml +3 -0
- data/.rspec +5 -0
- data/.rubocop.yml +380 -0
- data/.ruby-version +1 -0
- data/.yamllint +51 -0
- data/.yardopts +12 -0
- data/AI-DISCLOSURE.md +48 -0
- data/CHANGELOG.md +519 -0
- data/CLAUDE.md +141 -0
- data/CONTRIBUTING.md +734 -0
- data/INSTALL.md +154 -0
- data/LICENSE +674 -0
- data/LICENSE.md +675 -0
- data/QUICKSTART.md +73 -0
- data/README.md +366 -0
- data/Rakefile +200 -0
- data/SECURITY.md +114 -0
- data/bin/rai +1 -0
- data/cliff.toml +52 -0
- data/conf/adopt_redactions.yml +8 -0
- data/conf/behaviour/.gitkeep +0 -0
- data/conf/compliance/cra_rules.yml +25 -0
- data/conf/compliance/license_rules.yml +20 -0
- data/conf/design/aaif_alignment.yml +181 -0
- data/conf/design/ab_testing.yml +172 -0
- data/conf/design/accessibility.yml +84 -0
- data/conf/design/ai_authorship.yml +210 -0
- data/conf/design/ai_provenance.yml +224 -0
- data/conf/design/ai_tool_configuration.yml +207 -0
- data/conf/design/architecture.yml +139 -0
- data/conf/design/autocompletion.yml +115 -0
- data/conf/design/backward_compatibility.yml +112 -0
- data/conf/design/behaviour_composition.yml +246 -0
- data/conf/design/build_rake_extraction.yml +57 -0
- data/conf/design/ci_pipeline.yml +100 -0
- data/conf/design/claude_code_configuration.yml +157 -0
- data/conf/design/compiler.yml +128 -0
- data/conf/design/comply.yml +153 -0
- data/conf/design/content_packs.yml +84 -0
- data/conf/design/desktop_integration.yml +289 -0
- data/conf/design/distribution.yml +216 -0
- data/conf/design/doctor.yml +184 -0
- data/conf/design/documentation.yml +152 -0
- data/conf/design/engine_architecture.yml +257 -0
- data/conf/design/error_handling.yml +103 -0
- data/conf/design/feature_flags.yml +142 -0
- data/conf/design/git_hooks.yml +165 -0
- data/conf/design/gui_plugins.yml +475 -0
- data/conf/design/i18n.yml +84 -0
- data/conf/design/integration_testing.yml +56 -0
- data/conf/design/licensing_system.yml +88 -0
- data/conf/design/lifecycle_management.yml +208 -0
- data/conf/design/mcp_integration.yml +207 -0
- data/conf/design/mcp_settings.yml +126 -0
- data/conf/design/migration.yml +56 -0
- data/conf/design/monitoring_observability.yml +194 -0
- data/conf/design/namespace_cleanup.yml +145 -0
- data/conf/design/plugin_test_segregation.yml +145 -0
- data/conf/design/policy_management.yml +229 -0
- data/conf/design/project_management.yml +183 -0
- data/conf/design/rai_mcp_asset_discovery.yml +164 -0
- data/conf/design/rai_mcp_server.yml +605 -0
- data/conf/design/release_management.yml +117 -0
- data/conf/design/retrofit.yml +199 -0
- data/conf/design/retrospective_analyzer.yml +79 -0
- data/conf/design/scope_hierarchy.yml +352 -0
- data/conf/design/security.yml +115 -0
- data/conf/design/session_retrospective.yml +85 -0
- data/conf/design/smart_ui_feedback.yml +89 -0
- data/conf/design/structured_logging.yml +148 -0
- data/conf/design/styles.yml +123 -0
- data/conf/design/test_peer_review.yml +89 -0
- data/conf/design/testing.yml +136 -0
- data/conf/design/threat_model.yml +108 -0
- data/conf/design/ui_framework.yml +111 -0
- data/conf/design/usage_optimization.yml +122 -0
- data/conf/design/version_management.yml +60 -0
- data/conf/design/workflow.yml +227 -0
- data/conf/mcp/server_defaults.yml +42 -0
- data/conf/mcp/trust.yml +21 -0
- data/conf/packaging/core.yml +12 -0
- data/conf/packaging/gtk4.yml +11 -0
- data/conf/packaging/qt6.yml +11 -0
- data/conf/policy/default_deny_list.yml +197 -0
- data/conf/review/cli-command-audit.yml +857 -0
- data/conf/review/design-docs.yml +1064 -0
- data/conf/review/design-questionnaire.yml +153 -0
- data/conf/review/questionnaire.yml +146 -0
- data/conf/review/rosett-ai-core.yml +2919 -0
- data/conf/schemas/ai_config_schema.json +73 -0
- data/conf/schemas/behaviour_schema.json +132 -0
- data/conf/schemas/compliance_rule_schema.json +63 -0
- data/conf/schemas/content_pack_manifest_schema.json +51 -0
- data/conf/schemas/design_schema.json +210 -0
- data/conf/schemas/engine_manifest_schema.json +144 -0
- data/conf/schemas/lockfile_schema.json +74 -0
- data/conf/schemas/mcp_server_schema.json +48 -0
- data/conf/schemas/packaging_schema.json +70 -0
- data/conf/schemas/policy_schema.json +85 -0
- data/conf/schemas/provenance_schema.json +84 -0
- data/conf/schemas/rai_config_schema.json +56 -0
- data/conf/schemas/rai_project_schema.json +20 -0
- data/conf/schemas/scope_hierarchy_schema.json +49 -0
- data/conf/schemas/target_schema.json +67 -0
- data/conf/schemas/tooling_schema.json +65 -0
- data/conf/schemas/workflow_schema.json +112 -0
- data/conf/targets/agents_md.yml +17 -0
- data/conf/targets/claude.yml +12 -0
- data/conf/tooling/tools.yml +58 -0
- data/dist/rosett-ai-mcp.service +48 -0
- data/dist/rosett-ai-mcp.yml.default +45 -0
- data/doc/AAIF_POSITIONING.md +58 -0
- data/doc/ADOPT.md +224 -0
- data/doc/AI_PROVENANCE.md +139 -0
- data/doc/ARCHITECTURE.md +920 -0
- data/doc/BEHAVIOUR.md +409 -0
- data/doc/BUILD.md +138 -0
- data/doc/CI_CD_RECIPES.md +171 -0
- data/doc/CLAUDE_SESSIONS_MOVED.md +16 -0
- data/doc/COMMAND_ANALYSIS.md +229 -0
- data/doc/CONFIGURATION.md +281 -0
- data/doc/DESIGN_AUDIT.md +235 -0
- data/doc/DESIGN_PEER_REVIEW.md +771 -0
- data/doc/DESKTOP.md +447 -0
- data/doc/ENGINES.md +567 -0
- data/doc/ENGINE_DEVELOPMENT_GUIDE.md +417 -0
- data/doc/FEATURE_AUDIT.md +218 -0
- data/doc/IMPLEMENTATION_PLAN.md +669 -0
- data/doc/INCIDENT_REPORT_2026-02-02.md +251 -0
- data/doc/MIGRATION_GUIDE.md +88 -0
- data/doc/PACKAGING.md +232 -0
- data/doc/PROJECT_DASHBOARD.md +153 -0
- data/doc/PULP_DEPLOYMENT.md +164 -0
- data/doc/QUALITY_FIX_SUMMARY.md +110 -0
- data/doc/QUICK_START.md +162 -0
- data/doc/REEK_CONFIGURATION.md +166 -0
- data/doc/REFERENCE.md +253 -0
- data/doc/REFERENCES.md +324 -0
- data/doc/SECURITY_REVIEW_CHECKLIST.md +72 -0
- data/doc/SESSION_2026-02-28_GTK4_HARDENING.md +359 -0
- data/doc/SETUP.md +202 -0
- data/doc/TEST_PEER_REVIEW.md +152 -0
- data/doc/THREAT_MODEL.md +230 -0
- data/doc/USAGE.md +545 -0
- data/doc/USER_MANUAL.md +585 -0
- data/doc/ai_test_review_checklist.md +110 -0
- data/doc/changes/2026-02-18-packaging-fpm.md +155 -0
- data/doc/changes/2026-02-19-testing-infrastructure.md +221 -0
- data/doc/changes/2026-02-20-security-implementation.md +281 -0
- data/doc/changes/2026-02-20-styles-implementation.md +220 -0
- data/doc/changes/2026-02-21-architecture-completion.md +95 -0
- data/doc/changes/2026-02-21-architecture-ui-layer.md +253 -0
- data/doc/changes/2026-02-21-cc-config-implementation.md +108 -0
- data/doc/changes/2026-02-21-ci-pipeline-implementation.md +214 -0
- data/doc/changes/2026-02-21-compiler-multi-target-pipeline.md +241 -0
- data/doc/changes/2026-02-21-config-design-show-commands.md +61 -0
- data/doc/changes/2026-02-21-design-implementation-overview.md +455 -0
- data/doc/changes/2026-02-21-lifecycle-management.md +196 -0
- data/doc/changes/2026-02-21-path-resolver.md +128 -0
- data/doc/changes/2026-02-24-ci-tmpdir-mutant-fetch.md +45 -0
- data/doc/changes/2026-03-01-ci-bundler-strategy.md +120 -0
- data/doc/changes/2026-03-20-security-hardening-phase2.md +163 -0
- data/doc/context/SESSION-HANDOFF.md +69 -0
- data/doc/context/ai-engine-usage-trends-2026.md +80 -0
- data/doc/context/plan-pluggable-engines.md +590 -0
- data/doc/decisions/001-flog-deferred.md +32 -0
- data/doc/decisions/002-path-resolution-strategy.md +158 -0
- data/doc/decisions/003-ui-adapter-selection.md +193 -0
- data/doc/decisions/004-design-document-validation.md +179 -0
- data/doc/decisions/005-package-splitting-strategy.md +200 -0
- data/doc/decisions/006-multi-engine-architecture.md +147 -0
- data/doc/decisions/007-engine-agnostic-pivot.md +219 -0
- data/doc/decisions/008-ci-bundler-strategy.md +129 -0
- data/doc/decisions/009-core-only-v1-release.md +60 -0
- data/doc/decisions/010-engine-debian-packaging.md +66 -0
- data/doc/decisions/011-context-aware-cli.md +71 -0
- data/doc/dependency_decisions.yml +247 -0
- data/doc/issues/001-wrapper-missing-environment-variables.md +197 -0
- data/doc/issues/002-embedded-ruby-wrong-prefix.md +217 -0
- data/doc/issues/003-smoke-test-false-positive.md +127 -0
- data/doc/issues/004-market-research-design-updates.md +109 -0
- data/doc/issues/005-compile-scope-coexistence.md +161 -0
- data/doc/locales/.gitkeep +0 -0
- data/doc/man/rai.1.ronn +505 -0
- data/doc/operations/packaging.md +133 -0
- data/doc/operations/rosett-ai-release.md +65 -0
- data/doc/reference/error-catalog.md +107 -0
- data/doc/reference/rosett-ai-technical-reference.pdf +0 -0
- data/doc/reference/src/Pictures/cover.jpg +0 -0
- data/doc/reference/src/Pictures/head1.jpg +0 -0
- data/doc/reference/src/Pictures/head2.jpg +0 -0
- data/doc/reference/src/Pictures/head3.jpg +0 -0
- data/doc/reference/src/Pictures/head4.jpg +0 -0
- data/doc/reference/src/Pictures/head5.jpg +0 -0
- data/doc/reference/src/Pictures/head6.jpg +0 -0
- data/doc/reference/src/Pictures/head7.jpg +0 -0
- data/doc/reference/src/Pictures/head8.jpg +0 -0
- data/doc/reference/src/StyleInd.ist +4 -0
- data/doc/reference/src/bibliography.bib +79 -0
- data/doc/reference/src/main.tex +1288 -0
- data/doc/reference/src/structure.tex +303 -0
- data/doc/rosett-ai-bookmarks.html +301 -0
- data/kitchen.yml +46 -0
- data/lib/rosett_ai/adopter/executor_resolver.rb +77 -0
- data/lib/rosett_ai/adopter/local_analysis_collector.rb +154 -0
- data/lib/rosett_ai/adopter/rule_adopter.rb +254 -0
- data/lib/rosett_ai/ai_config/config_compiler.rb +111 -0
- data/lib/rosett_ai/ai_config/context_window.rb +55 -0
- data/lib/rosett_ai/ai_config/cost_controls.rb +44 -0
- data/lib/rosett_ai/ai_config/fallback_chain.rb +64 -0
- data/lib/rosett_ai/ai_config/model_router.rb +121 -0
- data/lib/rosett_ai/ai_config/validator.rb +45 -0
- data/lib/rosett_ai/authorship/attribution_compiler.rb +99 -0
- data/lib/rosett_ai/authorship/disclosure_policy.rb +81 -0
- data/lib/rosett_ai/authorship/review_validator.rb +39 -0
- data/lib/rosett_ai/authorship/trailer_generator.rb +88 -0
- data/lib/rosett_ai/backup/compressor.rb +180 -0
- data/lib/rosett_ai/backup/destination.rb +91 -0
- data/lib/rosett_ai/behaviour/manager.rb +156 -0
- data/lib/rosett_ai/compiler/backend.rb +86 -0
- data/lib/rosett_ai/compiler/backends/agents_md_backend.rb +80 -0
- data/lib/rosett_ai/compiler/backends/claude_backend.rb +88 -0
- data/lib/rosett_ai/compiler/backends/generic_backend.rb +15 -0
- data/lib/rosett_ai/compiler/behaviour_compiler.rb +40 -0
- data/lib/rosett_ai/compiler/capability_checker.rb +104 -0
- data/lib/rosett_ai/compiler/compilation_pipeline.rb +361 -0
- data/lib/rosett_ai/compiler/compiled_output.rb +39 -0
- data/lib/rosett_ai/compiler/locale_compiler.rb +250 -0
- data/lib/rosett_ai/compiler/target_profile.rb +112 -0
- data/lib/rosett_ai/completion/generator.rb +101 -0
- data/lib/rosett_ai/completion/shells/bash_generator.rb +126 -0
- data/lib/rosett_ai/completion/shells/fish_generator.rb +78 -0
- data/lib/rosett_ai/completion/shells/zsh_generator.rb +126 -0
- data/lib/rosett_ai/comply/checkers/cra_checker.rb +102 -0
- data/lib/rosett_ai/comply/checkers/license_checker.rb +85 -0
- data/lib/rosett_ai/comply/checkers/spdx_header_checker.rb +98 -0
- data/lib/rosett_ai/comply/reporter.rb +113 -0
- data/lib/rosett_ai/comply/runner.rb +50 -0
- data/lib/rosett_ai/composition/circular_dependency_detector.rb +56 -0
- data/lib/rosett_ai/composition/composer.rb +158 -0
- data/lib/rosett_ai/composition/composition_result.rb +64 -0
- data/lib/rosett_ai/composition/conflict_detector.rb +53 -0
- data/lib/rosett_ai/composition/lockfile.rb +103 -0
- data/lib/rosett_ai/composition/merge_strategy.rb +131 -0
- data/lib/rosett_ai/composition/priority_sorter.rb +29 -0
- data/lib/rosett_ai/composition/scope_resolver.rb +55 -0
- data/lib/rosett_ai/config/compile_result.rb +37 -0
- data/lib/rosett_ai/config/compiler.rb +13 -0
- data/lib/rosett_ai/config/domain_transformer.rb +13 -0
- data/lib/rosett_ai/config/key_map.rb +13 -0
- data/lib/rosett_ai/config/masking_secret_resolver.rb +40 -0
- data/lib/rosett_ai/config/scope_router.rb +13 -0
- data/lib/rosett_ai/config/secret_resolver.rb +125 -0
- data/lib/rosett_ai/configuration.rb +119 -0
- data/lib/rosett_ai/content/content_client.rb +60 -0
- data/lib/rosett_ai/content/pack_installer.rb +117 -0
- data/lib/rosett_ai/content/pack_manifest.rb +50 -0
- data/lib/rosett_ai/content/pack_registry.rb +68 -0
- data/lib/rosett_ai/content_packs/manager.rb +50 -0
- data/lib/rosett_ai/dbus/compositor_detector.rb +77 -0
- data/lib/rosett_ai/dbus/focus_adapters/base.rb +59 -0
- data/lib/rosett_ai/dbus/focus_adapters/gnome_adapter.rb +172 -0
- data/lib/rosett_ai/dbus/focus_adapters/hyprland_adapter.rb +77 -0
- data/lib/rosett_ai/dbus/focus_adapters/i3_adapter.rb +65 -0
- data/lib/rosett_ai/dbus/focus_adapters/kwin_adapter.rb +103 -0
- data/lib/rosett_ai/dbus/focus_adapters/x11_adapter.rb +105 -0
- data/lib/rosett_ai/dbus/focus_monitor_interface.rb +103 -0
- data/lib/rosett_ai/dbus/manager_interface.rb +213 -0
- data/lib/rosett_ai/dbus/plugin_manager_interface.rb +169 -0
- data/lib/rosett_ai/dbus/rate_limiter.rb +89 -0
- data/lib/rosett_ai/dbus/service.rb +121 -0
- data/lib/rosett_ai/dbus/status_notifier_interface.rb +79 -0
- data/lib/rosett_ai/deprecation.rb +79 -0
- data/lib/rosett_ai/desktop/dbus_client.rb +259 -0
- data/lib/rosett_ai/desktop/gtk4_app.rb +371 -0
- data/lib/rosett_ai/desktop/gtk4_preferences.rb +331 -0
- data/lib/rosett_ai/desktop/gui_logger.rb +236 -0
- data/lib/rosett_ai/doctor/check.rb +92 -0
- data/lib/rosett_ai/doctor/checks/cache_health_check.rb +50 -0
- data/lib/rosett_ai/doctor/checks/dbus_availability_check.rb +39 -0
- data/lib/rosett_ai/doctor/checks/engine_detection_check.rb +46 -0
- data/lib/rosett_ai/doctor/checks/file_permission_check.rb +44 -0
- data/lib/rosett_ai/doctor/checks/gem_dependency_check.rb +55 -0
- data/lib/rosett_ai/doctor/checks/ruby_version_check.rb +50 -0
- data/lib/rosett_ai/doctor/checks/stale_config_nncc_check.rb +57 -0
- data/lib/rosett_ai/doctor/checks/stale_home_nncc_check.rb +59 -0
- data/lib/rosett_ai/doctor.rb +81 -0
- data/lib/rosett_ai/documentation/reference_compiler.rb +122 -0
- data/lib/rosett_ai/documentation/translator.rb +62 -0
- data/lib/rosett_ai/engines/base_config_compiler.rb +203 -0
- data/lib/rosett_ai/engines/detector.rb +63 -0
- data/lib/rosett_ai/engines/registry.rb +50 -0
- data/lib/rosett_ai/error_handler.rb +139 -0
- data/lib/rosett_ai/exit_codes.rb +76 -0
- data/lib/rosett_ai/feature_flags.rb +102 -0
- data/lib/rosett_ai/formatting.rb +33 -0
- data/lib/rosett_ai/gem_consistency_checker.rb +199 -0
- data/lib/rosett_ai/git_hooks/chain_detector.rb +86 -0
- data/lib/rosett_ai/git_hooks/installer.rb +175 -0
- data/lib/rosett_ai/git_hooks/script_generator.rb +125 -0
- data/lib/rosett_ai/gitlab/validators/supplementary_gitlab_ci_yaml_validator.rb +79 -0
- data/lib/rosett_ai/i18n/locale_resolver.rb +46 -0
- data/lib/rosett_ai/i18n/utf8_checker.rb +32 -0
- data/lib/rosett_ai/init/config_file_writer.rb +24 -0
- data/lib/rosett_ai/init/directory_builder.rb +38 -0
- data/lib/rosett_ai/init/file_copier.rb +95 -0
- data/lib/rosett_ai/init/global_initializer.rb +28 -0
- data/lib/rosett_ai/init/local_initializer.rb +27 -0
- data/lib/rosett_ai/init/mcp_registrar.rb +109 -0
- data/lib/rosett_ai/init/project_initializer.rb +38 -0
- data/lib/rosett_ai/licensing/license_key.rb +139 -0
- data/lib/rosett_ai/licensing/license_store.rb +64 -0
- data/lib/rosett_ai/licensing/license_validator.rb +60 -0
- data/lib/rosett_ai/licensing/tier.rb +42 -0
- data/lib/rosett_ai/mcp/admin/auditor.rb +88 -0
- data/lib/rosett_ai/mcp/admin/health_checker.rb +81 -0
- data/lib/rosett_ai/mcp/admin/registry.rb +100 -0
- data/lib/rosett_ai/mcp/admin/schema_validator.rb +63 -0
- data/lib/rosett_ai/mcp/enforcement/.gitkeep +0 -0
- data/lib/rosett_ai/mcp/enforcement/hook_generator.rb +197 -0
- data/lib/rosett_ai/mcp/enforcement/validator.rb +215 -0
- data/lib/rosett_ai/mcp/governance.rb +160 -0
- data/lib/rosett_ai/mcp/http_security_config.rb +158 -0
- data/lib/rosett_ai/mcp/instructions.rb +266 -0
- data/lib/rosett_ai/mcp/key_hasher.rb +66 -0
- data/lib/rosett_ai/mcp/keyfile.rb +221 -0
- data/lib/rosett_ai/mcp/middleware/authentication.rb +146 -0
- data/lib/rosett_ai/mcp/middleware/content_type.rb +56 -0
- data/lib/rosett_ai/mcp/middleware/cors.rb +83 -0
- data/lib/rosett_ai/mcp/middleware/origin_validation.rb +73 -0
- data/lib/rosett_ai/mcp/middleware/rate_limit.rb +106 -0
- data/lib/rosett_ai/mcp/middleware/request_size.rb +51 -0
- data/lib/rosett_ai/mcp/plugins.rb +143 -0
- data/lib/rosett_ai/mcp/prompts/compilation_prompt.rb +40 -0
- data/lib/rosett_ai/mcp/prompts/compliance_prompt.rb +41 -0
- data/lib/rosett_ai/mcp/prompts/diagnostics_prompt.rb +41 -0
- data/lib/rosett_ai/mcp/prompts/validation_prompt.rb +41 -0
- data/lib/rosett_ai/mcp/resources/behaviour_resource.rb +127 -0
- data/lib/rosett_ai/mcp/resources/config_resource.rb +72 -0
- data/lib/rosett_ai/mcp/resources/design_resource.rb +58 -0
- data/lib/rosett_ai/mcp/resources/hooks_resource.rb +74 -0
- data/lib/rosett_ai/mcp/resources/provenance_resource.rb +51 -0
- data/lib/rosett_ai/mcp/resources/rules_resource.rb +60 -0
- data/lib/rosett_ai/mcp/resources/schema_resource.rb +72 -0
- data/lib/rosett_ai/mcp/response_helper.rb +46 -0
- data/lib/rosett_ai/mcp/security_logger.rb +60 -0
- data/lib/rosett_ai/mcp/server.rb +212 -0
- data/lib/rosett_ai/mcp/settings/server_installer.rb +112 -0
- data/lib/rosett_ai/mcp/settings/trust_manager.rb +142 -0
- data/lib/rosett_ai/mcp/tools/adopt_tool.rb +70 -0
- data/lib/rosett_ai/mcp/tools/backup_tool.rb +64 -0
- data/lib/rosett_ai/mcp/tools/behaviour_display_tool.rb +72 -0
- data/lib/rosett_ai/mcp/tools/behaviour_list_tool.rb +56 -0
- data/lib/rosett_ai/mcp/tools/behaviour_manage_tool.rb +114 -0
- data/lib/rosett_ai/mcp/tools/behaviour_show_tool.rb +62 -0
- data/lib/rosett_ai/mcp/tools/compile_status_tool.rb +122 -0
- data/lib/rosett_ai/mcp/tools/compile_tool.rb +191 -0
- data/lib/rosett_ai/mcp/tools/comply_tool.rb +79 -0
- data/lib/rosett_ai/mcp/tools/config_compile_tool.rb +71 -0
- data/lib/rosett_ai/mcp/tools/config_status_tool.rb +79 -0
- data/lib/rosett_ai/mcp/tools/content_tool.rb +78 -0
- data/lib/rosett_ai/mcp/tools/context_query_tool.rb +156 -0
- data/lib/rosett_ai/mcp/tools/design_list_tool.rb +57 -0
- data/lib/rosett_ai/mcp/tools/design_show_tool.rb +69 -0
- data/lib/rosett_ai/mcp/tools/doctor_tool.rb +62 -0
- data/lib/rosett_ai/mcp/tools/documentation_status_tool.rb +45 -0
- data/lib/rosett_ai/mcp/tools/engines_tool.rb +84 -0
- data/lib/rosett_ai/mcp/tools/hook_install_tool.rb +190 -0
- data/lib/rosett_ai/mcp/tools/hook_preview_tool.rb +173 -0
- data/lib/rosett_ai/mcp/tools/hooks_status_tool.rb +84 -0
- data/lib/rosett_ai/mcp/tools/init_tool.rb +87 -0
- data/lib/rosett_ai/mcp/tools/license_status_tool.rb +44 -0
- data/lib/rosett_ai/mcp/tools/project_tool.rb +117 -0
- data/lib/rosett_ai/mcp/tools/provenance_tool.rb +97 -0
- data/lib/rosett_ai/mcp/tools/provenance_write_tool.rb +40 -0
- data/lib/rosett_ai/mcp/tools/retrofit_tool.rb +81 -0
- data/lib/rosett_ai/mcp/tools/rule_search_tool.rb +163 -0
- data/lib/rosett_ai/mcp/tools/schema_get_tool.rb +94 -0
- data/lib/rosett_ai/mcp/tools/tooling_tool.rb +86 -0
- data/lib/rosett_ai/mcp/tools/validate_tool.rb +105 -0
- data/lib/rosett_ai/mcp/tools/workflow_execute_tool.rb +74 -0
- data/lib/rosett_ai/mcp/tools/workflow_tool.rb +78 -0
- data/lib/rosett_ai/migration/detector.rb +117 -0
- data/lib/rosett_ai/migration/nncc_config_migrator.rb +94 -0
- data/lib/rosett_ai/migration/nncc_project_migrator.rb +90 -0
- data/lib/rosett_ai/migration/xdg_migrator.rb +123 -0
- data/lib/rosett_ai/package_manager/apt.rb +108 -0
- data/lib/rosett_ai/package_manager/base.rb +68 -0
- data/lib/rosett_ai/package_manager/gem_backend.rb +90 -0
- data/lib/rosett_ai/packaging/variant_config.rb +92 -0
- data/lib/rosett_ai/path_resolver.rb +115 -0
- data/lib/rosett_ai/plugins/contract.rb +43 -0
- data/lib/rosett_ai/plugins/engine_contract.rb +60 -0
- data/lib/rosett_ai/plugins/gui_contract.rb +74 -0
- data/lib/rosett_ai/plugins/mcp_contract.rb +48 -0
- data/lib/rosett_ai/plugins/registry.rb +150 -0
- data/lib/rosett_ai/policy/auditor.rb +41 -0
- data/lib/rosett_ai/policy/deny_list.rb +71 -0
- data/lib/rosett_ai/policy/opt_out_scanner.rb +37 -0
- data/lib/rosett_ai/policy/policy_compiler.rb +84 -0
- data/lib/rosett_ai/policy/protected_files.rb +47 -0
- data/lib/rosett_ai/policy/tier_hierarchy.rb +48 -0
- data/lib/rosett_ai/policy/validator.rb +35 -0
- data/lib/rosett_ai/profiler.rb +79 -0
- data/lib/rosett_ai/project/drift_detector.rb +126 -0
- data/lib/rosett_ai/project/manager.rb +115 -0
- data/lib/rosett_ai/project/sync_manager.rb +138 -0
- data/lib/rosett_ai/project/template_applier.rb +105 -0
- data/lib/rosett_ai/project_context.rb +82 -0
- data/lib/rosett_ai/provenance/entry.rb +63 -0
- data/lib/rosett_ai/provenance/file_source.rb +32 -0
- data/lib/rosett_ai/provenance/source.rb +62 -0
- data/lib/rosett_ai/provenance/store.rb +153 -0
- data/lib/rosett_ai/provenance/tracker.rb +62 -0
- data/lib/rosett_ai/provenance/trailer_generator.rb +43 -0
- data/lib/rosett_ai/provenance/validator.rb +45 -0
- data/lib/rosett_ai/quorum/collector.rb +59 -0
- data/lib/rosett_ai/quorum/comparator.rb +81 -0
- data/lib/rosett_ai/quorum/dispatcher.rb +57 -0
- data/lib/rosett_ai/quorum/strategies/adopt.rb +56 -0
- data/lib/rosett_ai/rai_config.rb +107 -0
- data/lib/rosett_ai/retrofit/base_parser.rb +66 -0
- data/lib/rosett_ai/retrofit/engine.rb +171 -0
- data/lib/rosett_ai/retrofit/parsers/agents_md_parser.rb +50 -0
- data/lib/rosett_ai/retrofit/parsers/claude_parser.rb +69 -0
- data/lib/rosett_ai/retrofit/parsers/cursor_parser.rb +82 -0
- data/lib/rosett_ai/retrofit/round_trip_validator.rb +65 -0
- data/lib/rosett_ai/retrofit/scanner.rb +47 -0
- data/lib/rosett_ai/retrofit/secret_detector.rb +87 -0
- data/lib/rosett_ai/secrets_resolver.rb +71 -0
- data/lib/rosett_ai/smart_feedback/suggester.rb +83 -0
- data/lib/rosett_ai/smart_feedback/thor_middleware.rb +84 -0
- data/lib/rosett_ai/structured_logger.rb +110 -0
- data/lib/rosett_ai/telemetry/json_lines_writer.rb +50 -0
- data/lib/rosett_ai/telemetry/log_rotator.rb +67 -0
- data/lib/rosett_ai/telemetry/provider.rb +26 -0
- data/lib/rosett_ai/telemetry/reporter.rb +144 -0
- data/lib/rosett_ai/telemetry.rb +47 -0
- data/lib/rosett_ai/text_sanitizer.rb +62 -0
- data/lib/rosett_ai/thor/cli.rb +269 -0
- data/lib/rosett_ai/thor/tasks/adopt.rb +250 -0
- data/lib/rosett_ai/thor/tasks/backup.rb +420 -0
- data/lib/rosett_ai/thor/tasks/behaviour.rb +474 -0
- data/lib/rosett_ai/thor/tasks/build.rb +1162 -0
- data/lib/rosett_ai/thor/tasks/compile.rb +415 -0
- data/lib/rosett_ai/thor/tasks/completion.rb +123 -0
- data/lib/rosett_ai/thor/tasks/comply.rb +82 -0
- data/lib/rosett_ai/thor/tasks/config.rb +265 -0
- data/lib/rosett_ai/thor/tasks/content.rb +193 -0
- data/lib/rosett_ai/thor/tasks/dbus.rb +321 -0
- data/lib/rosett_ai/thor/tasks/design.rb +258 -0
- data/lib/rosett_ai/thor/tasks/desktop.rb +129 -0
- data/lib/rosett_ai/thor/tasks/doctor.rb +127 -0
- data/lib/rosett_ai/thor/tasks/documentation.rb +321 -0
- data/lib/rosett_ai/thor/tasks/engines.rb +167 -0
- data/lib/rosett_ai/thor/tasks/hooks.rb +219 -0
- data/lib/rosett_ai/thor/tasks/init.rb +259 -0
- data/lib/rosett_ai/thor/tasks/license.rb +120 -0
- data/lib/rosett_ai/thor/tasks/mcp.rb +535 -0
- data/lib/rosett_ai/thor/tasks/migrate.rb +121 -0
- data/lib/rosett_ai/thor/tasks/plugins.rb +157 -0
- data/lib/rosett_ai/thor/tasks/project.rb +260 -0
- data/lib/rosett_ai/thor/tasks/provenance.rb +195 -0
- data/lib/rosett_ai/thor/tasks/release.rb +314 -0
- data/lib/rosett_ai/thor/tasks/retrofit.rb +90 -0
- data/lib/rosett_ai/thor/tasks/tooling.rb +308 -0
- data/lib/rosett_ai/thor/tasks/validate.rb +108 -0
- data/lib/rosett_ai/thor/tasks/workflow.rb +196 -0
- data/lib/rosett_ai/tooling/ci_yaml_validator.rb +37 -0
- data/lib/rosett_ai/tooling/version_checker.rb +35 -0
- data/lib/rosett_ai/ui/accessible_tui.rb +61 -0
- data/lib/rosett_ai/ui/base.rb +46 -0
- data/lib/rosett_ai/ui/gtk4.rb +98 -0
- data/lib/rosett_ai/ui/kde.rb +40 -0
- data/lib/rosett_ai/ui/qt6.rb +40 -0
- data/lib/rosett_ai/ui/registry.rb +60 -0
- data/lib/rosett_ai/ui/tty_helper.rb +74 -0
- data/lib/rosett_ai/ui/tui.rb +59 -0
- data/lib/rosett_ai/validators/behaviour_validator.rb +20 -0
- data/lib/rosett_ai/validators/design_validator.rb +17 -0
- data/lib/rosett_ai/validators/schema_validator.rb +84 -0
- data/lib/rosett_ai/validators/tooling_validator.rb +17 -0
- data/lib/rosett_ai/version.rb +8 -0
- data/lib/rosett_ai/version_consistency_checker.rb +129 -0
- data/lib/rosett_ai/workflow/audit_log.rb +86 -0
- data/lib/rosett_ai/workflow/engine.rb +142 -0
- data/lib/rosett_ai/workflow/manager.rb +82 -0
- data/lib/rosett_ai/workflow/schema_validator.rb +71 -0
- data/lib/rosett_ai/workflow/step_runner.rb +61 -0
- data/lib/rosett_ai/workflow/steps/prompt_step.rb +62 -0
- data/lib/rosett_ai/workflow/steps/rai_step.rb +74 -0
- data/lib/rosett_ai/workflow/steps/shell_step.rb +53 -0
- data/lib/rosett_ai/yaml_loader.rb +78 -0
- data/lib/rosett_ai.rb +221 -0
- data/lib/rubocop/cop/rosett_ai/shell_interpolation.rb +54 -0
- data/lib/rubocop/cop/rosett_ai/unsafe_const_get.rb +60 -0
- data/lib/rubocop/cop/rosett_ai/unsafe_send.rb +50 -0
- data/lib/rubocop/cop/rosett_ai/unsafe_yaml_load.rb +40 -0
- data/lib/rubocop/rosett_ai.rb +9 -0
- data/lib/scripts/generated/docker_hub_tags.rb +126 -0
- data/locales/.gitkeep +0 -0
- data/locales/ar.yml +579 -0
- data/locales/en.yml +571 -0
- data/locales/fr.yml +567 -0
- data/packaging/build-engine-deb.sh +81 -0
- data/packaging/scripts/postinst +17 -0
- data/packaging/scripts/postrm +19 -0
- data/packaging/scripts/prerm +10 -0
- data/packaging/wrapper.sh.template +38 -0
- data/rosett-ai.gemspec +63 -0
- data/rules/.gitkeep +0 -0
- data/scripts/publish/pulp_upload.sh +123 -0
- data/settings.json +29 -0
- data/share/applications/be.neatnerds.rosettai.desktop +29 -0
- data/share/dbus-1/interfaces/be.neatnerds.rosettai.xml +103 -0
- data/share/dbus-1/services/be.neatnerds.rosettai.service +3 -0
- data/share/templates/behaviour/criticalthinking.yml +69 -0
- metadata +810 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: architecture
|
|
3
|
+
domain: core
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
status: draft
|
|
6
|
+
priority: 2
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-02-18"
|
|
9
|
+
modified_at: "2026-03-23"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- security
|
|
13
|
+
- testing
|
|
14
|
+
- ci_pipeline
|
|
15
|
+
- scope_hierarchy
|
|
16
|
+
|
|
17
|
+
intent: |
|
|
18
|
+
Define the overall system architecture of Rosett-AI as a TUI-first, pluggable
|
|
19
|
+
application with optional GUI layers delivered as separate Debian packages.
|
|
20
|
+
The core must run on headless servers (CLI/TUI only) while desktop users
|
|
21
|
+
can install GUI packages for their environment. All UI variants share the
|
|
22
|
+
same backend logic. The architecture must support multi-target AI model
|
|
23
|
+
compilation, licensing, i18n, and accessibility from the ground up —
|
|
24
|
+
informed by the security constraints established in Priority 1.
|
|
25
|
+
|
|
26
|
+
A foundational architectural principle is scope-first: all commands resolve
|
|
27
|
+
their working context from the three-level scope hierarchy (global, local,
|
|
28
|
+
project) before operating. Configuration sources are discovered from the
|
|
29
|
+
user's working directory, merged according to configurable strategies, and
|
|
30
|
+
compiled to scope-appropriate output locations. See scope_hierarchy.yml for
|
|
31
|
+
the full scope specification.
|
|
32
|
+
|
|
33
|
+
constraints:
|
|
34
|
+
- Core package (rai) must be fully functional without any GUI package installed
|
|
35
|
+
- GUI packages must not introduce dependencies on TUI-specific libraries
|
|
36
|
+
- All UI variants share the same backend logic in lib/rosett_ai/
|
|
37
|
+
- Only Linux is supported; Debian is the target distribution
|
|
38
|
+
- Ruby is the implementation language; version managed via rbenv
|
|
39
|
+
- Thor is the CLI framework
|
|
40
|
+
- All configuration files are YAML (validated by JSON Schema)
|
|
41
|
+
- Abstract UI interface (lib/rosett_ai/ui/base.rb) defines the contract all GUI plugins implement
|
|
42
|
+
- GUI plugins are discovered at runtime via a registry pattern
|
|
43
|
+
- Security constraints from security.yml apply to all architectural layers
|
|
44
|
+
- "Scope-first: all commands resolve their working context from the
|
|
45
|
+
three-level scope hierarchy (global, local, project) before operating
|
|
46
|
+
(see scope_hierarchy.yml)"
|
|
47
|
+
- Commands must never assume a single fixed source directory — source
|
|
48
|
+
directories are resolved from the active scope
|
|
49
|
+
|
|
50
|
+
acceptance_criteria:
|
|
51
|
+
- bin/raictl runs without errors on a headless Debian server (no X11/Wayland)
|
|
52
|
+
- Installing rosett-ai-gtk4 adds GTK4 UI option without modifying core
|
|
53
|
+
- lib/rosett_ai/ui/base.rb defines the abstract interface with documented methods
|
|
54
|
+
- lib/rosett_ai/ui/registry.rb discovers installed UI plugins automatically
|
|
55
|
+
- All business logic is in lib/rosett_ai/ (not in TUI or GUI code)
|
|
56
|
+
- conf/design/ documents are validated against conf/schemas/design_schema.json
|
|
57
|
+
- conf/behaviour/ documents are validated against conf/schemas/behaviour_schema.json
|
|
58
|
+
- Package dependencies are correctly declared (rosett-ai-gtk4 depends on rosett-ai)
|
|
59
|
+
- "Configuration sources are resolved from the three-level scope hierarchy:
|
|
60
|
+
global (~/.config/rosett-ai/conf/), local (<group>/.rosett-ai/conf/), project
|
|
61
|
+
(<project>/.rosett-ai/conf/) — see scope_hierarchy.yml"
|
|
62
|
+
- All scope-aware commands (compile, validate, design, behaviour) resolve
|
|
63
|
+
source directories from the active scope before operating
|
|
64
|
+
|
|
65
|
+
examples:
|
|
66
|
+
- scenario: "User installs only the Rosett-AI core package on a server"
|
|
67
|
+
expected: "All CLI commands work. TUI mode is available. No GUI-related errors or warnings."
|
|
68
|
+
not: "Application crashes due to missing GTK4 or Qt6 libraries."
|
|
69
|
+
- scenario: "User installs rosett-ai-gtk4 alongside rosett-ai on a GNOME desktop"
|
|
70
|
+
expected: "bin/raictl --ui gtk4 launches GTK4 interface. bin/raictl (no flag) uses TUI as default."
|
|
71
|
+
not: "GTK4 becomes the default. TUI mode breaks. Core behaviour changes."
|
|
72
|
+
- scenario: "Developer adds a new feature to the compiler"
|
|
73
|
+
expected: "Feature is implemented in lib/rosett_ai/compiler/. Both TUI and GUI see the feature without changes."
|
|
74
|
+
not: "Feature requires separate implementation in TUI and GUI code."
|
|
75
|
+
- scenario: "New AI model (e.g. Gemma) needs to be supported as compilation target"
|
|
76
|
+
expected: "Add conf/targets/gemma.yml with model profile. No code changes needed."
|
|
77
|
+
not: "Requires modifying compiler source code or adding conditional logic."
|
|
78
|
+
|
|
79
|
+
anti_patterns:
|
|
80
|
+
- Business logic in UI layer (TUI or GUI code making domain decisions)
|
|
81
|
+
- GUI-specific dependencies in core package
|
|
82
|
+
- Hardcoded paths instead of XDG-compliant directory resolution
|
|
83
|
+
- Assuming a single fixed source directory for all commands regardless of
|
|
84
|
+
working directory (see scope_hierarchy.yml)
|
|
85
|
+
- Monolithic package that bundles all UI toolkits
|
|
86
|
+
- Plugin discovery that requires editing a config file instead of auto-detection
|
|
87
|
+
|
|
88
|
+
gui_notes: |
|
|
89
|
+
Implicit Assumptions (documented per DESIGN_AUDIT.md recommendation #6):
|
|
90
|
+
|
|
91
|
+
1. Linux-only: rosett-ai targets Linux exclusively. macOS and Windows are not
|
|
92
|
+
supported. This is stated in constraints but deserves explicit callout
|
|
93
|
+
as it affects all design documents.
|
|
94
|
+
|
|
95
|
+
2. Debian-first: Primary packaging is .deb for Debian/Ubuntu. RPM support
|
|
96
|
+
(Fedora/RHEL) is Phase 2 of the distribution design. Other packaging
|
|
97
|
+
formats (AppImage, Homebrew, Winget) are Phase 3+.
|
|
98
|
+
|
|
99
|
+
3. Single-user: XDG paths (~/.config/rosett-ai/, ~/.cache/rosett-ai/) assume a
|
|
100
|
+
single user per HOME directory. Multi-user installations with shared
|
|
101
|
+
system-wide config are not designed for. Root-level managed settings
|
|
102
|
+
(/etc/claude-code/) are the exception for enterprise deployment.
|
|
103
|
+
|
|
104
|
+
4. Ruby 3.3.10: The project targets Ruby 3.3.10 managed via rbenv. This
|
|
105
|
+
is scattered across design documents but should be understood as a
|
|
106
|
+
hard constraint. Version bumps require updating rbenv, CI, and the
|
|
107
|
+
.ruby-version file.
|
|
108
|
+
|
|
109
|
+
5. Zeitwerk lazy loading: All module autoloading uses Zeitwerk. No
|
|
110
|
+
eager_load calls outside of test/CI. This affects startup time and
|
|
111
|
+
memory usage (see usage_optimization.yml).
|
|
112
|
+
|
|
113
|
+
6. UTF-8 everywhere: All text processing assumes UTF-8 encoding. YAML
|
|
114
|
+
files, CLI output, log files, and configuration all use UTF-8. No
|
|
115
|
+
other encodings are supported for configuration files.
|
|
116
|
+
|
|
117
|
+
7. Three-level scope hierarchy: The architecture supports three distinct
|
|
118
|
+
configuration scopes resolved from the user's working directory:
|
|
119
|
+
- Global: ~/.config/rosett-ai/conf/ (XDG user config, applied everywhere)
|
|
120
|
+
- Local: <group-dir>/.rosett-ai/conf/ (workspace-level, multi-project groups)
|
|
121
|
+
- Project: <project-dir>/.rosett-ai/conf/ (project-specific overrides)
|
|
122
|
+
Each scope has its own conf/ subtree with the same structure as the
|
|
123
|
+
raictl source directory. Commands auto-detect the active scope from the
|
|
124
|
+
working directory. See scope_hierarchy.yml for the full specification.
|
|
125
|
+
|
|
126
|
+
preferences:
|
|
127
|
+
language: ruby
|
|
128
|
+
patterns:
|
|
129
|
+
- hexagonal_architecture
|
|
130
|
+
- plugin_registry
|
|
131
|
+
- dependency_injection
|
|
132
|
+
- interface_contracts_via_shared_examples
|
|
133
|
+
testing: rspec with shared examples for interface contracts
|
|
134
|
+
gems:
|
|
135
|
+
- thor
|
|
136
|
+
- json_schemer
|
|
137
|
+
- tty-prompt
|
|
138
|
+
- tty-table
|
|
139
|
+
- pastel
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: autocompletion
|
|
3
|
+
domain: ui
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 3
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-03-15"
|
|
9
|
+
modified_at: "2026-03-16"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- ui_framework
|
|
13
|
+
- architecture
|
|
14
|
+
- security
|
|
15
|
+
- error_handling
|
|
16
|
+
#
|
|
17
|
+
intent: |
|
|
18
|
+
Generate shell completion scripts for bash, zsh, and fish from the Thor
|
|
19
|
+
command registry to reduce friction, prevent typos, and improve
|
|
20
|
+
discoverability across rosett-ai's 17+ subcommands with nested sub-subcommands,
|
|
21
|
+
flags, and dynamic arguments (behaviour names, design doc names, engine
|
|
22
|
+
names). Integrate completion installation into the .deb postinst script
|
|
23
|
+
for zero-configuration setup.
|
|
24
|
+
|
|
25
|
+
This design governs shell-level tab completion for the Rosett-AI CLI. It does
|
|
26
|
+
not cover in-prompt AI completions (which would be an engine-specific
|
|
27
|
+
feature) or TUI input field autocompletion (which is governed by
|
|
28
|
+
ui_framework.yml).
|
|
29
|
+
#
|
|
30
|
+
constraints:
|
|
31
|
+
- "Must support bash (>= 4.0), zsh (>= 5.0), and fish (>= 3.0)"
|
|
32
|
+
- "Completion scripts must be generated from the Thor command registry —
|
|
33
|
+
not hand-maintained"
|
|
34
|
+
- "Dynamic completions (behaviour names, engine names) must use rosett-ai
|
|
35
|
+
subcommands, not file globbing"
|
|
36
|
+
- "Completion script installation must integrate with the .deb postinst
|
|
37
|
+
script"
|
|
38
|
+
- "Must not slow down shell startup — lazy-load where possible"
|
|
39
|
+
- "Completion data must reflect the currently installed version of Rosett-AI"
|
|
40
|
+
- "Generated completion scripts must not contain shell injection
|
|
41
|
+
vulnerabilities — all dynamic values must be properly escaped"
|
|
42
|
+
- "This design governs shell tab completion for the Rosett-AI CLI binary.
|
|
43
|
+
TUI input completions are governed by ui_framework.yml"
|
|
44
|
+
#
|
|
45
|
+
acceptance_criteria:
|
|
46
|
+
- "`rai completion bash` outputs a bash completion script to stdout"
|
|
47
|
+
- "`rai completion zsh` outputs a zsh completion script to stdout"
|
|
48
|
+
- "`rai completion fish` outputs a fish completion script to stdout"
|
|
49
|
+
- "`rai completion install` installs the script for the current shell"
|
|
50
|
+
- "Tab-completing `raictl b<TAB>` suggests `backup`, `behaviour`, `build`"
|
|
51
|
+
- "Tab-completing `rai behaviour show <TAB>` lists available behaviour
|
|
52
|
+
names"
|
|
53
|
+
- "Tab-completing `rai compile --engine <TAB>` lists installed engines"
|
|
54
|
+
- ".deb postinst installs completions automatically"
|
|
55
|
+
- "Exit code 0 on success, 1 on generation failure, 3 on unsupported
|
|
56
|
+
shell"
|
|
57
|
+
#
|
|
58
|
+
examples:
|
|
59
|
+
- scenario: "User types `raictl com<TAB>` in bash"
|
|
60
|
+
expected: |
|
|
61
|
+
Shell completes to `raictl comp` then offers `compile`, `comply`,
|
|
62
|
+
`content`.
|
|
63
|
+
not: "No completion offered; user must type the full command"
|
|
64
|
+
- scenario: "User installs rosett-ai via .deb package"
|
|
65
|
+
expected: |
|
|
66
|
+
Completion script installed to
|
|
67
|
+
/usr/share/bash-completion/completions/rosett-ai automatically.
|
|
68
|
+
not: "User must manually source the completion script"
|
|
69
|
+
- scenario: "New engine installed after rosett-ai"
|
|
70
|
+
expected: |
|
|
71
|
+
Engine appears in `--engine <TAB>` completions on next invocation.
|
|
72
|
+
not: "Completions are stale until rosett-ai is reinstalled."
|
|
73
|
+
- scenario: "User requests completion for an unsupported shell"
|
|
74
|
+
expected: |
|
|
75
|
+
`rai completion tcsh` exits with code 3 and message: 'Shell tcsh
|
|
76
|
+
is not supported — available: bash, zsh, fish'. Suggests using
|
|
77
|
+
`rai completion bash` as a starting point.
|
|
78
|
+
not: "Silent failure or crash with unhandled exception."
|
|
79
|
+
#
|
|
80
|
+
anti_patterns:
|
|
81
|
+
- "Hand-maintaining completion scripts separate from the Thor command
|
|
82
|
+
registry"
|
|
83
|
+
- "Completion scripts that call rosett-ai on every tab press (too slow)"
|
|
84
|
+
- "Hardcoding command lists instead of generating from Thor metadata"
|
|
85
|
+
- "Shell-specific hacks that break on version upgrades"
|
|
86
|
+
- "Unescaped dynamic values in generated completion scripts"
|
|
87
|
+
#
|
|
88
|
+
gui_notes: |
|
|
89
|
+
Document interactions (cross-references):
|
|
90
|
+
|
|
91
|
+
1. architecture.yml: completion installation integrates with the .deb
|
|
92
|
+
postinst script and the `rai init` setup flow.
|
|
93
|
+
|
|
94
|
+
2. ui_framework.yml: shell tab completion is distinct from TUI input
|
|
95
|
+
field completion. Both improve UX but at different layers.
|
|
96
|
+
|
|
97
|
+
3. engine_architecture.yml: dynamic engine name completion uses
|
|
98
|
+
`rai engines list` output, driven by engine manifests.
|
|
99
|
+
|
|
100
|
+
4. security.yml: generated completion scripts must escape dynamic values
|
|
101
|
+
to prevent shell injection.
|
|
102
|
+
|
|
103
|
+
5. error_handling.yml: exit codes follow the error hierarchy.
|
|
104
|
+
#
|
|
105
|
+
preferences:
|
|
106
|
+
language: ruby
|
|
107
|
+
patterns:
|
|
108
|
+
- "Thor command introspection for completion data"
|
|
109
|
+
- "Template-based script generation per shell"
|
|
110
|
+
- "Lazy evaluation for dynamic completions"
|
|
111
|
+
- "Shell-safe escaping for generated scripts"
|
|
112
|
+
testing: rspec with shell completion script generation tests, dynamic
|
|
113
|
+
argument scenarios, and .deb postinst integration tests
|
|
114
|
+
gems:
|
|
115
|
+
- thor
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: backward_compatibility
|
|
3
|
+
domain: core
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 2
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-03-15"
|
|
9
|
+
modified_at: "2026-03-16"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- architecture
|
|
13
|
+
- security
|
|
14
|
+
- compiler
|
|
15
|
+
- engine_architecture
|
|
16
|
+
- error_handling
|
|
17
|
+
#
|
|
18
|
+
intent: |
|
|
19
|
+
Define the deprecation policy, migration paths, and versioning contracts for
|
|
20
|
+
rosett-ai. Users and engine authors must know which interfaces are stable, how
|
|
21
|
+
breaking changes are communicated, and what migration steps are required when
|
|
22
|
+
upgrading. Without this document, breaking changes surprise users and engine
|
|
23
|
+
authors lose trust in the platform stability.
|
|
24
|
+
|
|
25
|
+
Per-version migration guides (doc/migration/) provide step-by-step upgrade
|
|
26
|
+
instructions for each major version boundary. Each guide documents what
|
|
27
|
+
changed, why, what user action is required, and where automated migration
|
|
28
|
+
tooling (`bin/raictl migrate`) handles the transition automatically. Migration
|
|
29
|
+
guides are published alongside the release and linked from CHANGELOG.md.
|
|
30
|
+
#
|
|
31
|
+
constraints:
|
|
32
|
+
- Public CLI commands must not change behaviour without a deprecation cycle of at least one minor version
|
|
33
|
+
- Deprecated CLI options must emit a warning on stderr with the replacement and removal version
|
|
34
|
+
- Design document schema changes must be backward-compatible within a major version (additive only)
|
|
35
|
+
- Behaviour YAML format changes must include a migration path or automated migration tool
|
|
36
|
+
- Engine API (RosettAiEngine::Base interface) changes require a deprecation notice in CHANGELOG.md
|
|
37
|
+
- SemVer must be strictly enforced — patch for fixes, minor for features, major for breaking changes
|
|
38
|
+
- Compiled output format changes (rules/) must not silently change semantics between versions
|
|
39
|
+
- Configuration file migrations must be automated where possible (bin/raictl init handles upgrades)
|
|
40
|
+
- Removal of a public method or CLI command requires major version bump
|
|
41
|
+
- Deprecation warnings must include the version where the feature was deprecated and the planned removal version
|
|
42
|
+
- Per-version migration guides must exist in doc/migration/ for each major version
|
|
43
|
+
- Migration guides must document what changed, why, required user action, and automated tooling
|
|
44
|
+
- "`bin/raictl migrate` must detect the current config version and apply required migrations"
|
|
45
|
+
#
|
|
46
|
+
acceptance_criteria:
|
|
47
|
+
- Deprecated CLI options produce a warning on stderr with replacement and removal version
|
|
48
|
+
- CHANGELOG.md documents all breaking changes under a "BREAKING CHANGES" section
|
|
49
|
+
- bin/raictl version --check reports if running config files need migration
|
|
50
|
+
- Design schema version is tracked and validated against document version
|
|
51
|
+
- Engine gems declare minimum rai version via gemspec dependency
|
|
52
|
+
- At least one minor release exists between deprecation warning and removal
|
|
53
|
+
- Automated migration exists for behaviour YAML format changes (bin/raictl migrate)
|
|
54
|
+
- SemVer compliance is enforced by CI (conventional commits parsed for version bumps)
|
|
55
|
+
- Public Ruby API methods removed without deprecation cycle cause CI failure
|
|
56
|
+
- Release notes include a migration guide for any breaking change
|
|
57
|
+
- doc/migration/v1-to-v2.md (and subsequent) exist for each major version boundary
|
|
58
|
+
- "`bin/raictl migrate` detects current config version and applies migrations automatically"
|
|
59
|
+
- "Migration guides are linked from CHANGELOG.md release entries"
|
|
60
|
+
#
|
|
61
|
+
examples:
|
|
62
|
+
- scenario: "A CLI option --target is renamed to --engine in v1.1.0"
|
|
63
|
+
expected: |
|
|
64
|
+
v1.1.0: --target still works but emits warning: "WARNING: --target is
|
|
65
|
+
deprecated (since v1.1.0), use --engine instead. Will be removed in v2.0.0."
|
|
66
|
+
v2.0.0: --target is removed. Error message suggests --engine.
|
|
67
|
+
not: |
|
|
68
|
+
v1.1.0: --target silently stops working. No warning, no migration path.
|
|
69
|
+
- scenario: "Behaviour YAML gains a new required field in schema v1.2.0"
|
|
70
|
+
expected: |
|
|
71
|
+
New field has a default value. Existing files without the field pass
|
|
72
|
+
validation with a deprecation warning. bin/raictl migrate adds the field
|
|
73
|
+
to existing files.
|
|
74
|
+
not: |
|
|
75
|
+
Existing behaviour files fail validation immediately. Users must
|
|
76
|
+
manually edit every file.
|
|
77
|
+
- scenario: "Engine API method compile_rules is renamed to compile"
|
|
78
|
+
expected: |
|
|
79
|
+
v1.x: Both compile_rules and compile work. compile_rules emits
|
|
80
|
+
deprecation warning. Engine compatibility test verifies both.
|
|
81
|
+
v2.0: compile_rules removed. Engine scaffold generates compile.
|
|
82
|
+
not: |
|
|
83
|
+
Engine gems break on upgrade. No compatibility shim provided.
|
|
84
|
+
- scenario: "User upgrades rosett-ai from 1.0 to 2.0"
|
|
85
|
+
expected: |
|
|
86
|
+
bin/raictl init --global detects v1.0 config and offers migration.
|
|
87
|
+
CHANGELOG.md 2.0.0 section lists all breaking changes with fixes.
|
|
88
|
+
Engine gems with rosett-ai >= 1.0 dependency show compatibility warning.
|
|
89
|
+
not: |
|
|
90
|
+
Silent breakage. User discovers issues at runtime.
|
|
91
|
+
#
|
|
92
|
+
anti_patterns:
|
|
93
|
+
- Removing public API methods without a deprecation cycle
|
|
94
|
+
- Changing CLI command behaviour silently between versions
|
|
95
|
+
- Breaking schema backward compatibility within a major version
|
|
96
|
+
- Relying on users reading CHANGELOG.md for migration (automate where possible)
|
|
97
|
+
- Adding required fields to YAML schemas without default values
|
|
98
|
+
- Using internal constants or methods in engine gems (no stability guarantee)
|
|
99
|
+
- Skipping SemVer rules for "small" breaking changes
|
|
100
|
+
- Deprecation warnings without specifying the removal version
|
|
101
|
+
#
|
|
102
|
+
preferences:
|
|
103
|
+
language: ruby
|
|
104
|
+
patterns:
|
|
105
|
+
- deprecation_warnings
|
|
106
|
+
- semver_enforcement
|
|
107
|
+
- automated_migration
|
|
108
|
+
- compatibility_shims
|
|
109
|
+
testing: rspec with version migration scenarios
|
|
110
|
+
gems:
|
|
111
|
+
- thor
|
|
112
|
+
- semantic
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: behaviour_composition
|
|
3
|
+
domain: core
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
status: draft
|
|
6
|
+
priority: 2
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-03-10"
|
|
9
|
+
modified_at: "2026-03-23"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- compiler
|
|
13
|
+
- architecture
|
|
14
|
+
- engine_architecture
|
|
15
|
+
- security
|
|
16
|
+
- error_handling
|
|
17
|
+
- scope_hierarchy
|
|
18
|
+
#
|
|
19
|
+
intent: |
|
|
20
|
+
Define how multiple behaviour YAML files are composed, layered, and
|
|
21
|
+
merged during compilation. As rai projects grow, users author dozens
|
|
22
|
+
of behaviour files across different scopes (global, local, project).
|
|
23
|
+
This design governs the composition rules: what happens when behaviours
|
|
24
|
+
conflict, how priorities resolve ties, how scopes layer, and how the
|
|
25
|
+
final compiled output is deterministic.
|
|
26
|
+
|
|
27
|
+
Without explicit composition rules, behaviour merging becomes
|
|
28
|
+
unpredictable — a behaviour at priority 50 in the global scope might
|
|
29
|
+
silently override a project-specific rule at the same priority. This
|
|
30
|
+
design makes composition explicit, debuggable, and auditable.
|
|
31
|
+
|
|
32
|
+
Key capabilities:
|
|
33
|
+
- Scope hierarchy: global > local > project (each successive scope
|
|
34
|
+
overrides the previous at equal priority). The three-level scope
|
|
35
|
+
model is defined in scope_hierarchy.yml — this document defers to
|
|
36
|
+
that specification for scope definitions and detection algorithm
|
|
37
|
+
- Priority-based ordering within each scope (1-100, lower = higher priority)
|
|
38
|
+
- Conflict detection: when two rules with the same ID exist at the
|
|
39
|
+
same scope and priority, compilation emits a warning
|
|
40
|
+
- Composition modes: merge (combine rules), override (replace entire
|
|
41
|
+
behaviour), exclude (skip specific rules by ID)
|
|
42
|
+
- Hiera-like configurable merge strategies: first-found (highest
|
|
43
|
+
priority wins), deep-merge (recursive hash merge), array-union
|
|
44
|
+
(combine array values from all scopes)
|
|
45
|
+
- Dry-run composition: bin/raictl compile --simulate shows which rules
|
|
46
|
+
win, which are overridden, and why
|
|
47
|
+
- Lockfile: bin/raictl compile --vendor writes a lockfile capturing
|
|
48
|
+
the exact composition result for reproducible builds
|
|
49
|
+
#
|
|
50
|
+
constraints:
|
|
51
|
+
- This design governs composition rules (ordering, merging, conflict
|
|
52
|
+
resolution). The compilation pipeline (YAML-to-native transformation,
|
|
53
|
+
file I/O, target selection) is governed by compiler.yml
|
|
54
|
+
- Composition must be deterministic — same inputs always produce same output
|
|
55
|
+
- Merge strategy must be configurable per behaviour key — supported
|
|
56
|
+
strategies are first-found (highest priority wins), deep-merge
|
|
57
|
+
(recursive hash merge), and array-union (combine array values)
|
|
58
|
+
- When two rules have equal scope and priority, alphabetical behaviour
|
|
59
|
+
name breaks the tie
|
|
60
|
+
- Behaviour names must be NFC-normalized before alphabetical comparison
|
|
61
|
+
(per security.yml Unicode normalization constraint)
|
|
62
|
+
- Security-domain behaviours can never be overridden by non-security behaviours
|
|
63
|
+
- Behaviours marked as sensitive are excluded from non-internal compilation targets
|
|
64
|
+
- Composition order must be documented in the lockfile for auditability
|
|
65
|
+
- The lockfile must capture the active merge strategy configuration
|
|
66
|
+
alongside composition results — without it, determinism is not guaranteed
|
|
67
|
+
- Rule IDs must be unique within a single behaviour file
|
|
68
|
+
- Cross-behaviour rule ID collisions produce warnings (errors in --strict mode)
|
|
69
|
+
- Excluded rules must be explicitly listed — no wildcard exclusions
|
|
70
|
+
- Composition must handle circular depends_on with a clear error
|
|
71
|
+
- The lockfile must be a human-readable YAML file, not a binary format
|
|
72
|
+
- Lockfile parsing must use YAML.safe_load (same constraint as all
|
|
73
|
+
other YAML in the system)
|
|
74
|
+
- Compiled output must have snapshot baselines in spec/fixtures/snapshots/
|
|
75
|
+
for regression testing — baselines are committed to git and reviewed in MRs
|
|
76
|
+
- Property-based tests (Rantly) must verify composition determinism across
|
|
77
|
+
random priority/scope combinations
|
|
78
|
+
- Composed output must not exceed 50 MB total (configurable). Per-file
|
|
79
|
+
YAML limits (1 MB, 10 nesting, 1000 keys) from security.yml remain
|
|
80
|
+
unchanged
|
|
81
|
+
#
|
|
82
|
+
acceptance_criteria:
|
|
83
|
+
- bin/raictl compile merges all behaviour files respecting scope hierarchy and priority
|
|
84
|
+
- "Scope hierarchy (global > local > project) is applied correctly in
|
|
85
|
+
all cases — see scope_hierarchy.yml for scope definitions"
|
|
86
|
+
- Equal-priority rules within the same scope are ordered by behaviour name (alphabetical)
|
|
87
|
+
- Security-domain behaviours cannot be overridden by lower-domain behaviours
|
|
88
|
+
- bin/raictl compile --verbose shows composition trace (which rule wins, why)
|
|
89
|
+
- bin/raictl compile --simulate --verbose shows full composition without writing files
|
|
90
|
+
- bin/raictl compile --vendor writes a lockfile with exact composition result
|
|
91
|
+
- Lockfile can be used to reproduce exact compilation (bin/raictl compile --frozen)
|
|
92
|
+
- Cross-behaviour rule ID collisions produce warnings (or errors with --strict)
|
|
93
|
+
- Circular depends_on is detected and reported with the cycle path
|
|
94
|
+
- Behaviours with the sensitive flag are excluded when compiling for external targets
|
|
95
|
+
- Composition result is identical across Ruby versions (no hash ordering dependency)
|
|
96
|
+
- bin/raictl behaviour conflicts lists all detected rule ID collisions
|
|
97
|
+
- First-found merge strategy selects the value from the highest-priority scope only
|
|
98
|
+
- Deep-merge strategy recursively merges hash values from all scopes
|
|
99
|
+
- Array-union strategy combines array values from all scopes, deduplicating entries
|
|
100
|
+
- bin/raictl behaviour conflicts uses TTY-aware output (table when
|
|
101
|
+
interactive, plain text when piped)
|
|
102
|
+
#
|
|
103
|
+
examples:
|
|
104
|
+
- scenario: "Global behaviour sets Ruby style at priority 50, project overrides at priority 50"
|
|
105
|
+
expected: |
|
|
106
|
+
Project scope wins because later scopes override earlier at equal
|
|
107
|
+
priority. --verbose output shows: 'Rule ruby_style_001: project
|
|
108
|
+
scope overrides global scope (equal priority, scope wins)'.
|
|
109
|
+
not: "Undefined behaviour. Sometimes global wins, sometimes project."
|
|
110
|
+
- scenario: "Two project behaviours both define rule ID security_001"
|
|
111
|
+
expected: |
|
|
112
|
+
Warning: 'Rule ID collision: security_001 defined in both
|
|
113
|
+
code_security.yml and api_security.yml. Alphabetical tie-break:
|
|
114
|
+
api_security.yml wins'. In --strict mode, this is an error.
|
|
115
|
+
not: "Silent override. No indication which rule was used."
|
|
116
|
+
- scenario: "Local-scope behaviour marks rules as sensitive, compiled for external AGENTS.md"
|
|
117
|
+
expected: |
|
|
118
|
+
Sensitive rules are excluded from AGENTS.md compilation. --verbose
|
|
119
|
+
shows: 'Excluding 3 sensitive rules from agents_md target'.
|
|
120
|
+
Non-sensitive rules compile normally.
|
|
121
|
+
not: "Sensitive internal rules appear in public AGENTS.md."
|
|
122
|
+
- scenario: "Developer runs bin/raictl compile --frozen with a lockfile"
|
|
123
|
+
expected: |
|
|
124
|
+
Compilation uses exactly the composition recorded in the lockfile.
|
|
125
|
+
If behaviour files have changed since the lockfile was created,
|
|
126
|
+
a warning is emitted: 'Behaviour files changed since lockfile —
|
|
127
|
+
run bin/raictl compile --vendor to update'.
|
|
128
|
+
not: "Lockfile silently ignored. Compilation uses current files."
|
|
129
|
+
- scenario: "Behaviour A depends_on B, B depends_on A"
|
|
130
|
+
expected: |
|
|
131
|
+
bin/raictl compile detects circular dependency and fails with error:
|
|
132
|
+
'Circular dependency detected: A -> B -> A'. No output written.
|
|
133
|
+
not: "Infinite loop. Stack overflow. Silent incorrect output."
|
|
134
|
+
- scenario: "Project excludes specific global rules by ID"
|
|
135
|
+
expected: |
|
|
136
|
+
Project config contains 'exclude: [global_rule_001, global_rule_003]'.
|
|
137
|
+
Those rules are skipped during composition. --verbose shows:
|
|
138
|
+
'Rule global_rule_001: excluded by project scope'.
|
|
139
|
+
not: |
|
|
140
|
+
Exclude is silently ignored. Excluded rules still appear in output.
|
|
141
|
+
Wildcard 'exclude: [*]' is accepted (must be rejected).
|
|
142
|
+
- scenario: "Developer runs bin/raictl behaviour conflicts"
|
|
143
|
+
expected: |
|
|
144
|
+
TTY-aware output lists all rule ID collisions across scopes:
|
|
145
|
+
┌─────────────────┬───────────────┬───────────────┬────────┐
|
|
146
|
+
│ Rule ID │ File A │ File B │ Winner │
|
|
147
|
+
├─────────────────┼───────────────┼───────────────┼────────┤
|
|
148
|
+
│ security_001 │ code_sec.yml │ api_sec.yml │ A │
|
|
149
|
+
└─────────────────┴───────────────┴───────────────┴────────┘
|
|
150
|
+
Piped output: 'security_001\tcode_sec.yml\tapi_sec.yml\tA'
|
|
151
|
+
not: "No output. Developer must read compile --verbose logs to find collisions."
|
|
152
|
+
- scenario: "Deep-merge strategy combines settings from global and project scopes"
|
|
153
|
+
expected: |
|
|
154
|
+
Global defines { editor: { theme: dark } }. Project defines
|
|
155
|
+
{ editor: { font_size: 14 } }. Deep-merge produces
|
|
156
|
+
{ editor: { theme: dark, font_size: 14 } }.
|
|
157
|
+
not: "Project replaces entire editor hash. Global theme is lost."
|
|
158
|
+
- scenario: "Developer incorrectly uses a wildcard exclusion"
|
|
159
|
+
expected: |
|
|
160
|
+
bin/raictl compile rejects 'exclude: ["*"]' with error: 'Wildcard
|
|
161
|
+
exclusions are not permitted — list specific rule IDs to exclude'.
|
|
162
|
+
not: "All rules are excluded. Empty output is silently produced."
|
|
163
|
+
- scenario: "Lockfile schema example"
|
|
164
|
+
expected: |
|
|
165
|
+
The lockfile (rosett-ai-compose.lock.yml) contains:
|
|
166
|
+
rai_version: 1.0.0
|
|
167
|
+
composed_at: '2026-03-16T10:00:00Z'
|
|
168
|
+
merge_strategy:
|
|
169
|
+
default: first_found
|
|
170
|
+
overrides:
|
|
171
|
+
editor_settings: deep_merge
|
|
172
|
+
allowed_tools: array_union
|
|
173
|
+
composition:
|
|
174
|
+
- rule_id: ruby_style_001
|
|
175
|
+
source: project/code_quality.yml
|
|
176
|
+
scope: project
|
|
177
|
+
priority: 50
|
|
178
|
+
action: included
|
|
179
|
+
- rule_id: global_rule_003
|
|
180
|
+
source: global/defaults.yml
|
|
181
|
+
scope: global
|
|
182
|
+
priority: 80
|
|
183
|
+
action: excluded_by_project
|
|
184
|
+
scope_resolution:
|
|
185
|
+
global: ~/.config/rosett-ai/conf/
|
|
186
|
+
local: ~/projects/.rosett-ai/conf/
|
|
187
|
+
project: ~/projects/acme-api/.rosett-ai/conf/
|
|
188
|
+
not: "Lockfile is a binary blob or lacks merge strategy configuration."
|
|
189
|
+
#
|
|
190
|
+
anti_patterns:
|
|
191
|
+
- Non-deterministic composition (relying on hash iteration order)
|
|
192
|
+
- Implicit conflict resolution without user visibility
|
|
193
|
+
- Allowing non-security behaviours to override security constraints
|
|
194
|
+
- Wildcard exclusions that could accidentally suppress critical rules
|
|
195
|
+
- Binary lockfile formats that cannot be reviewed in pull requests
|
|
196
|
+
- Ignoring sensitive flags during cross-target compilation
|
|
197
|
+
- Circular dependency detection only at runtime (must be compile-time)
|
|
198
|
+
- Comparing behaviour names without Unicode NFC normalization
|
|
199
|
+
- Omitting merge strategy from lockfile (breaks reproducibility)
|
|
200
|
+
#
|
|
201
|
+
gui_notes: |
|
|
202
|
+
Document interactions (cross-references):
|
|
203
|
+
|
|
204
|
+
1. compiler.yml: composition feeds into the compilation pipeline as a
|
|
205
|
+
pre-processing phase. Compiler invokes composition, not vice versa.
|
|
206
|
+
|
|
207
|
+
2. security.yml: security-domain override protection and YAML.safe_load
|
|
208
|
+
constraints apply to all composition operations.
|
|
209
|
+
|
|
210
|
+
3. error_handling.yml: composition errors (circular deps, ID collisions)
|
|
211
|
+
follow the structured error hierarchy (exit code 2, what/why/fix format).
|
|
212
|
+
|
|
213
|
+
4. engine_architecture.yml: engines may express merge strategy preferences
|
|
214
|
+
via their capability manifests, but composition itself is engine-agnostic.
|
|
215
|
+
|
|
216
|
+
5. backward_compatibility.yml: composition rules are a public API surface —
|
|
217
|
+
changes to scope hierarchy or merge behaviour are breaking changes.
|
|
218
|
+
|
|
219
|
+
6. scope_hierarchy.yml: authoritative specification for the three-level
|
|
220
|
+
scope model (global > local > project). This document defines
|
|
221
|
+
composition rules within that model; scope_hierarchy.yml defines
|
|
222
|
+
scope detection, merge strategies, and directory resolution.
|
|
223
|
+
|
|
224
|
+
ScopeResolver specification:
|
|
225
|
+
SCOPE_ORDER = ['global', 'local', 'project']
|
|
226
|
+
# Each successive scope overrides the previous at equal priority.
|
|
227
|
+
# See scope_hierarchy.yml for detection algorithm and merge semantics.
|
|
228
|
+
#
|
|
229
|
+
preferences:
|
|
230
|
+
language: ruby
|
|
231
|
+
patterns:
|
|
232
|
+
- hiera_like_hierarchical_lookup
|
|
233
|
+
- configurable_merge_strategies
|
|
234
|
+
- deterministic_composition
|
|
235
|
+
- scope_hierarchy_with_priority
|
|
236
|
+
- explicit_conflict_resolution
|
|
237
|
+
- lockfile_for_reproducibility
|
|
238
|
+
- compile_time_cycle_detection
|
|
239
|
+
testing: rspec with multi-scope fixtures, conflict scenarios, merge strategy
|
|
240
|
+
tests, lockfile round-trip tests, snapshot baselines in spec/fixtures/snapshots/
|
|
241
|
+
for compiled output regression, and Rantly property-based tests for composition
|
|
242
|
+
determinism and priority ordering edge cases
|
|
243
|
+
gems:
|
|
244
|
+
- json_schemer
|
|
245
|
+
- thor
|
|
246
|
+
- rantly
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: build_rake_extraction
|
|
3
|
+
domain: core
|
|
4
|
+
version: "1.0.0"
|
|
5
|
+
status: implemented
|
|
6
|
+
intent: |
|
|
7
|
+
Extract build, release, and documentation Thor tasks from the raictl CLI
|
|
8
|
+
into a Rakefile-based development toolchain. The Thor CLI serves the
|
|
9
|
+
application's end-user commands exclusively. Developer-facing tasks
|
|
10
|
+
(package building, engine .deb compilation, release preparation, version
|
|
11
|
+
tagging, documentation generation) belong in Rake, which is the standard
|
|
12
|
+
Ruby tool for project-internal automation.
|
|
13
|
+
|
|
14
|
+
Implemented in v1.2.0: build and release commands added to INTERNAL_COMMANDS
|
|
15
|
+
in cli.rb (hidden from raictl --help), Rake tasks delegate to existing
|
|
16
|
+
Thor task classes. The Thor classes remain in lib/ as the implementation;
|
|
17
|
+
Rake is the developer-facing entry point.
|
|
18
|
+
|
|
19
|
+
constraints:
|
|
20
|
+
- "Thor CLI must only expose end-user commands (compile, validate, behaviour, design, etc.)"
|
|
21
|
+
- "Rake tasks must be invocable via `bundle exec rake <task>` from the source tree"
|
|
22
|
+
- "Rake tasks must NOT be shipped in the .deb package"
|
|
23
|
+
- "build and release are in INTERNAL_COMMANDS (hidden from non-internal contexts)"
|
|
24
|
+
- "Existing fpm integration, variant configs, and wrapper template must be preserved"
|
|
25
|
+
- "No regression in .deb quality — same postinst/prerm/postrm scripts"
|
|
26
|
+
|
|
27
|
+
acceptance_criteria:
|
|
28
|
+
- "`rake build:package` builds the same .deb as the Thor task"
|
|
29
|
+
- "`rake build:engine` builds an engine .deb"
|
|
30
|
+
- "`rake release:prepare[minor]` bumps version and generates CHANGELOG"
|
|
31
|
+
- "`rake release:tag` creates an annotated git tag"
|
|
32
|
+
- "`rake readme:update` updates README version, test count, engine count"
|
|
33
|
+
- "`raictl help` does not show build or release commands"
|
|
34
|
+
- "InSpec integration tests pass"
|
|
35
|
+
|
|
36
|
+
examples:
|
|
37
|
+
- scenario: "Developer builds core .deb package"
|
|
38
|
+
expected: "`bundle exec rake build:package` produces pkg/rosett-ai_*.deb"
|
|
39
|
+
- scenario: "Developer builds GTK4 variant"
|
|
40
|
+
expected: "`bundle exec rake build:package[gtk4]` produces GTK4 variant .deb"
|
|
41
|
+
- scenario: "Developer prepares a minor release"
|
|
42
|
+
expected: "`bundle exec rake release:prepare[minor]` bumps version and generates CHANGELOG"
|
|
43
|
+
|
|
44
|
+
preferences:
|
|
45
|
+
language: ruby
|
|
46
|
+
patterns:
|
|
47
|
+
- "Namespace Rake tasks: build:package, build:engine, release:prepare, release:tag, readme:update"
|
|
48
|
+
- "Rake tasks delegate to Thor task classes via .new.invoke(:method)"
|
|
49
|
+
- "Keep variant_config.rb and packaging/ directory structure unchanged"
|
|
50
|
+
gems:
|
|
51
|
+
- rake
|
|
52
|
+
- fpm
|
|
53
|
+
|
|
54
|
+
anti_patterns:
|
|
55
|
+
- "Do not create a separate build tool or script — use Rake"
|
|
56
|
+
- "Do not duplicate logic — Rake delegates to Thor task classes"
|
|
57
|
+
- "Do not ship Rakefile in the .deb package"
|