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,590 @@
|
|
|
1
|
+
# Pluggable Engine Architecture + Config Adapters
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
raictl currently hardcodes 10 engines in two maps (`Registry.ENGINES` + `Backend.BACKENDS`). Every new engine or engine change requires modifying rosett-ai core. This is fragile — AI tools evolve rapidly and new ones emerge constantly.
|
|
6
|
+
|
|
7
|
+
This plan extracts engines into **separate repositories** as individual gems (`rosett-ai-engine-<name>`) with a pluggable discovery system. Each engine gem owns its backend, detector, executor, config compiler, manifests, schemas, and specs. rosett-ai core provides the CLI, compilation pipeline, registry, and base classes.
|
|
8
|
+
|
|
9
|
+
The pluggable architecture applies to **all plugin types** — not just engines. GUIs (desktop environments), MCP servers, and future plugin categories each get their own contract module, discovery mechanism, and separate repository. The naming convention `rosett-ai-<plugin-type>-<name>` covers:
|
|
10
|
+
- `rosett-ai-engine-<name>` — AI engine plugins (claude, goose, aider, cursor, etc.)
|
|
11
|
+
- `rosett-ai-gui-<name>` — Desktop GUI plugins (gtk4, qt6, etc.)
|
|
12
|
+
- `rosett-ai-mcp-<name>` — MCP server plugins
|
|
13
|
+
- Other future plugin types as needed
|
|
14
|
+
|
|
15
|
+
Config adapters for Goose, Aider, Cursor, Ollama, GPT-NeoX, and a new Mistral engine are built using this pluggable pattern.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Plan A: Pluggable Architecture + Engine Extraction
|
|
20
|
+
|
|
21
|
+
**Branch**: `feature/pluggable-engines`
|
|
22
|
+
|
|
23
|
+
### Phase 1: Plugin contracts + dynamic registry
|
|
24
|
+
|
|
25
|
+
#### 1a. Plugin contract modules
|
|
26
|
+
|
|
27
|
+
Create contract modules for each plugin type. Each contract defines the interface that plugin gems must implement.
|
|
28
|
+
|
|
29
|
+
**Engine contract** — `lib/rosett_ai/plugins/engine_contract.rb`:
|
|
30
|
+
|
|
31
|
+
```ruby
|
|
32
|
+
module RosettAi::Plugins::EngineContract
|
|
33
|
+
def self.included(base)
|
|
34
|
+
base.extend(ClassMethods)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
module ClassMethods
|
|
38
|
+
def plugin_type = :engine
|
|
39
|
+
def engine_name = raise NotImplementedError
|
|
40
|
+
def display_name = raise NotImplementedError
|
|
41
|
+
def backend_class = raise NotImplementedError
|
|
42
|
+
def detector_class = nil # optional
|
|
43
|
+
def executor_class = nil # optional
|
|
44
|
+
def config_compiler_class = nil # optional
|
|
45
|
+
def manifest_path = raise NotImplementedError
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
**GUI contract** — `lib/rosett_ai/plugins/gui_contract.rb`:
|
|
51
|
+
|
|
52
|
+
```ruby
|
|
53
|
+
module RosettAi::Plugins::GuiContract
|
|
54
|
+
def self.included(base)
|
|
55
|
+
base.extend(ClassMethods)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
module ClassMethods
|
|
59
|
+
def plugin_type = :gui
|
|
60
|
+
def gui_name = raise NotImplementedError
|
|
61
|
+
def display_name = raise NotImplementedError
|
|
62
|
+
def toolkit = raise NotImplementedError # :gtk4, :qt6, etc.
|
|
63
|
+
def application_class = raise NotImplementedError
|
|
64
|
+
def dbus_interface_class = nil # optional D-Bus integration
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**MCP contract** — `lib/rosett_ai/plugins/mcp_contract.rb`:
|
|
70
|
+
|
|
71
|
+
```ruby
|
|
72
|
+
module RosettAi::Plugins::McpContract
|
|
73
|
+
def self.included(base)
|
|
74
|
+
base.extend(ClassMethods)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
module ClassMethods
|
|
78
|
+
def plugin_type = :mcp
|
|
79
|
+
def mcp_name = raise NotImplementedError
|
|
80
|
+
def display_name = raise NotImplementedError
|
|
81
|
+
def server_class = raise NotImplementedError
|
|
82
|
+
def tool_definitions = raise NotImplementedError # MCP tool schema
|
|
83
|
+
def resource_definitions = [] # optional MCP resources
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
**Base contract** — `lib/rosett_ai/plugins/contract.rb` (shared interface for all plugin types):
|
|
89
|
+
|
|
90
|
+
```ruby
|
|
91
|
+
module RosettAi::Plugins::Contract
|
|
92
|
+
def self.included(base)
|
|
93
|
+
base.extend(ClassMethods)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
module ClassMethods
|
|
97
|
+
def plugin_type = raise NotImplementedError
|
|
98
|
+
def plugin_name = raise NotImplementedError
|
|
99
|
+
def display_name = raise NotImplementedError
|
|
100
|
+
def version = raise NotImplementedError
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
#### 1b. Dynamic registry (multi-type)
|
|
106
|
+
|
|
107
|
+
Replace hardcoded `ENGINES` and `BACKENDS` maps with a multi-type registry supporting engines, GUIs, and MCPs:
|
|
108
|
+
|
|
109
|
+
```ruby
|
|
110
|
+
module RosettAi::Plugins
|
|
111
|
+
class Registry
|
|
112
|
+
PLUGIN_TYPES = %i[engine gui mcp].freeze
|
|
113
|
+
@plugins = Hash.new { |h, k| h[k] = {} }
|
|
114
|
+
|
|
115
|
+
def self.register(type, name, plugin_module)
|
|
116
|
+
raise ArgumentError unless PLUGIN_TYPES.include?(type)
|
|
117
|
+
@plugins[type][name.to_s] = plugin_module
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def self.available(type) = @plugins[type].keys
|
|
121
|
+
def self.plugin_module(type, name) = @plugins[type].fetch(name.to_s) { raise ... }
|
|
122
|
+
|
|
123
|
+
# Convenience aliases
|
|
124
|
+
def self.engines = @plugins[:engine]
|
|
125
|
+
def self.guis = @plugins[:gui]
|
|
126
|
+
def self.mcps = @plugins[:mcp]
|
|
127
|
+
|
|
128
|
+
# Discovery: find and load all installed plugin gems
|
|
129
|
+
def self.discover!
|
|
130
|
+
Gem.find_files('rosett_ai_engine/*/register.rb').each { |f| require f }
|
|
131
|
+
Gem.find_files('rosett_ai_gui/*/register.rb').each { |f| require f }
|
|
132
|
+
Gem.find_files('rosett_ai_mcp/*/register.rb').each { |f| require f }
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Refactor `Backend.for` to delegate to `Registry.plugin_module(:engine, name).backend_class` instead of the hardcoded `BACKENDS` map.
|
|
139
|
+
|
|
140
|
+
#### 1c. Base config compiler
|
|
141
|
+
|
|
142
|
+
Extract shared compilation pipeline from `RosettAi::Engines::Claude::ConfigCompiler` into `lib/rosett_ai/engines/base_config_compiler.rb`:
|
|
143
|
+
- `discover_scope_files`, `compile`, `compile_scope`, `write_results`
|
|
144
|
+
- Schema validation via json_schemer
|
|
145
|
+
- Secret resolution via shared `RosettAi::Config::SecretResolver`
|
|
146
|
+
- `CompileResult` return type (already shared)
|
|
147
|
+
|
|
148
|
+
Each engine overrides: `transform(data, scope)`, `output_format`, `scope_routes`, `schema_path`.
|
|
149
|
+
|
|
150
|
+
#### 1d. Engine-aware CLI
|
|
151
|
+
|
|
152
|
+
Update `lib/rosett_ai/thor/tasks/config.rb`:
|
|
153
|
+
- Add `--engine` option with cascade lookup: config → autodetect → prompt
|
|
154
|
+
- Cascade: configured default → autodetect (Claude preferred, then alphabetical) → ask user for binary/endpoint
|
|
155
|
+
- Resolve to engine's `config_compiler_class` via Registry
|
|
156
|
+
- Remove hardcoded `RosettAi::Config::Compiler` (Claude alias)
|
|
157
|
+
|
|
158
|
+
Update `bin/raictl config show` to also display **plugged engines** — list all registered engine gems with version, capabilities, and detection status.
|
|
159
|
+
|
|
160
|
+
**Files to create:**
|
|
161
|
+
- `lib/rosett_ai/plugins/contract.rb` (base contract)
|
|
162
|
+
- `lib/rosett_ai/plugins/engine_contract.rb`
|
|
163
|
+
- `lib/rosett_ai/plugins/gui_contract.rb`
|
|
164
|
+
- `lib/rosett_ai/plugins/mcp_contract.rb`
|
|
165
|
+
- `lib/rosett_ai/plugins/registry.rb`
|
|
166
|
+
- `lib/rosett_ai/engines/base_config_compiler.rb`
|
|
167
|
+
- `spec/rosett_ai/plugins/contract_spec.rb`
|
|
168
|
+
- `spec/rosett_ai/plugins/engine_contract_spec.rb`
|
|
169
|
+
- `spec/rosett_ai/plugins/gui_contract_spec.rb`
|
|
170
|
+
- `spec/rosett_ai/plugins/mcp_contract_spec.rb`
|
|
171
|
+
- `spec/rosett_ai/plugins/registry_spec.rb`
|
|
172
|
+
- `spec/rosett_ai/engines/base_config_compiler_spec.rb`
|
|
173
|
+
|
|
174
|
+
**Files to modify:**
|
|
175
|
+
- `lib/rosett_ai/engines/registry.rb` — delegate to `Plugins::Registry`, deprecation alias
|
|
176
|
+
- `lib/rosett_ai/compiler/backend.rb` — delegate to `Plugins::Registry`, remove `BACKENDS`
|
|
177
|
+
- `lib/rosett_ai/thor/tasks/config.rb` — `--engine` flag, cascade lookup, plugged engines display
|
|
178
|
+
- `lib/rosett_ai/thor/tasks/compile.rb` — use Registry for engine resolution
|
|
179
|
+
- `lib/rosett_ai/thor/tasks/engines.rb` — use dynamic Registry
|
|
180
|
+
- `spec/rosett_ai/engines/registry_spec.rb` — update
|
|
181
|
+
- `spec/rosett_ai/compiler/backend_spec.rb` — update
|
|
182
|
+
- `spec/rosett_ai/thor/tasks/config_spec.rb` — update
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### Phase 2: Engine extraction to separate repositories
|
|
187
|
+
|
|
188
|
+
#### 2a. Repository structure
|
|
189
|
+
|
|
190
|
+
Each engine is a **separate git repository** at:
|
|
191
|
+
```
|
|
192
|
+
~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-engine-<name>/
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Plugin naming convention for all rosett-ai plugin types:
|
|
196
|
+
```text
|
|
197
|
+
~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-<plugin-type>-<name>/
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Examples:
|
|
201
|
+
```text
|
|
202
|
+
~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-engine-claude/
|
|
203
|
+
~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-engine-goose/
|
|
204
|
+
~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-gui-gtk4/
|
|
205
|
+
~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-gui-qt6/
|
|
206
|
+
~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-mcp-server/
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
#### 2b. Per-engine repository layout
|
|
210
|
+
|
|
211
|
+
```text
|
|
212
|
+
rosett-ai-engine-claude/
|
|
213
|
+
├── rosett-ai-engine-claude.gemspec
|
|
214
|
+
├── .gitlab-ci.yml # Same quality gates as core
|
|
215
|
+
├── .rubocop.yml
|
|
216
|
+
├── .reek.yml
|
|
217
|
+
├── .license_finder.yml # License compliance config
|
|
218
|
+
├── .mutant.yml # Mutation testing config
|
|
219
|
+
├── Gemfile
|
|
220
|
+
├── CHANGELOG.md
|
|
221
|
+
├── LICENSE # GPL-3.0-only (MANDATORY)
|
|
222
|
+
├── lib/
|
|
223
|
+
│ └── rosett_ai_engine/
|
|
224
|
+
│ └── claude/
|
|
225
|
+
│ ├── register.rb # self-registration entry point
|
|
226
|
+
│ ├── engine.rb # includes EngineContract, declares components
|
|
227
|
+
│ ├── backend.rb
|
|
228
|
+
│ ├── detector.rb
|
|
229
|
+
│ ├── executor.rb
|
|
230
|
+
│ ├── config_compiler.rb
|
|
231
|
+
│ ├── key_map.rb
|
|
232
|
+
│ ├── scope_router.rb
|
|
233
|
+
│ └── domain_transformer.rb
|
|
234
|
+
├── conf/
|
|
235
|
+
│ ├── manifest.yml
|
|
236
|
+
│ ├── target.yml
|
|
237
|
+
│ ├── config/
|
|
238
|
+
│ │ ├── managed.yml
|
|
239
|
+
│ │ ├── user.yml
|
|
240
|
+
│ │ ├── project.yml
|
|
241
|
+
│ │ └── local.yml
|
|
242
|
+
│ └── schemas/
|
|
243
|
+
│ └── config_schema.json
|
|
244
|
+
└── spec/
|
|
245
|
+
├── spec_helper.rb
|
|
246
|
+
├── backend_spec.rb
|
|
247
|
+
├── config_compiler_spec.rb
|
|
248
|
+
├── key_map_spec.rb
|
|
249
|
+
└── ...
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
#### 2c. Quality gates per plugin repository
|
|
253
|
+
|
|
254
|
+
Each plugin repo MUST have the same CI quality gates as rosett-ai core:
|
|
255
|
+
- RSpec (all specs pass, SimpleCov coverage)
|
|
256
|
+
- RuboCop (zero offenses)
|
|
257
|
+
- Reek (zero smells)
|
|
258
|
+
- **Mutant** (mutation testing on critical subjects)
|
|
259
|
+
- bundler-audit + ruby-audit
|
|
260
|
+
- **license_finder** (license compliance — all deps must be GPL-3.0-compatible)
|
|
261
|
+
- Schema validation (manifest, config schemas)
|
|
262
|
+
- **GPL-3.0-only** license file in every repository
|
|
263
|
+
|
|
264
|
+
Generated `.gitlab-ci.yml` per plugin repo, reusing CI templates where possible.
|
|
265
|
+
|
|
266
|
+
#### 2d. Claude extraction first
|
|
267
|
+
|
|
268
|
+
Extract Claude engine first — this is the most complex engine (7 components) and must work flawlessly before extracting others. Steps:
|
|
269
|
+
|
|
270
|
+
1. Create `~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-engine-claude/`
|
|
271
|
+
2. Move `lib/rosett_ai/engines/claude/*.rb` → `lib/rosett_ai_engine/claude/`
|
|
272
|
+
3. Move `conf/engines/claude/` → `conf/`
|
|
273
|
+
4. Move `spec/rosett_ai/engines/claude/` → `spec/`
|
|
274
|
+
5. Create gemspec, register.rb, engine.rb
|
|
275
|
+
6. Set up CI pipeline with quality gates
|
|
276
|
+
7. Verify all specs pass independently
|
|
277
|
+
8. Update rosett-ai core Gemfile to reference via `path:` or git URL
|
|
278
|
+
9. Verify full rosett-ai suite still passes
|
|
279
|
+
|
|
280
|
+
Then extract remaining engines in order: generic, agents_md, goose, aider, cursor, copilot, windsurf, ollama, gpt_neox.
|
|
281
|
+
|
|
282
|
+
#### 2e. GUI + MCP extraction
|
|
283
|
+
|
|
284
|
+
After engine extraction is validated, extract GUI and MCP plugins:
|
|
285
|
+
|
|
286
|
+
1. `rosett-ai-gui-gtk4/` — extract `lib/rosett_ai/desktop/gtk4/` + D-Bus adapters into `lib/rosett_ai_gui/gtk4/`
|
|
287
|
+
2. `rosett-ai-gui-qt6/` — placeholder for future KDE/Qt6 desktop (currently deferred)
|
|
288
|
+
3. `rosett-ai-mcp-server/` — extract `lib/rosett_ai/mcp/` into `lib/rosett_ai_mcp/server/`
|
|
289
|
+
|
|
290
|
+
Each follows the same pattern: own repo, own gemspec, own CI, GPL-3.0-only, contract module inclusion, self-registration via `register.rb`.
|
|
291
|
+
|
|
292
|
+
#### 2f. Core cleanup
|
|
293
|
+
|
|
294
|
+
Remove from rosett-ai core after all extractions:
|
|
295
|
+
- `lib/rosett_ai/engines/` (except `registry.rb`, `detector.rb`, `base_config_compiler.rb`)
|
|
296
|
+
- `lib/rosett_ai/desktop/` (moved to gui plugins)
|
|
297
|
+
- `lib/rosett_ai/mcp/` (moved to mcp plugins)
|
|
298
|
+
- `conf/engines/` (except `conf/schemas/engine_manifest_schema.json`)
|
|
299
|
+
- Engine/GUI/MCP-specific specs
|
|
300
|
+
|
|
301
|
+
Retain in core:
|
|
302
|
+
- `lib/rosett_ai/plugins/` (contract modules + registry)
|
|
303
|
+
- `lib/rosett_ai/engines/base_config_compiler.rb`
|
|
304
|
+
- Shared modules: `CompileResult`, `SecretResolver`, `CapabilityChecker`
|
|
305
|
+
|
|
306
|
+
Update rosett-ai core Gemfile to reference all plugin gems.
|
|
307
|
+
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### Phase 3: Example dummy plugins (ACME)
|
|
311
|
+
|
|
312
|
+
A true pluggable architecture must include example plugins so end users can understand the contract between core and plugin. ACME examples cover **all plugin types** to demonstrate each contract.
|
|
313
|
+
|
|
314
|
+
#### 3a. ACME example engine
|
|
315
|
+
|
|
316
|
+
Create `rosett-ai-engine-acme` — an inert example engine plugin:
|
|
317
|
+
|
|
318
|
+
**Placeholder organization**: ACME Corp (`acme-corp.tld`)
|
|
319
|
+
- Example users: alice, bob, goku, Haru Urara, Momonga
|
|
320
|
+
- Example roles: admin, developer, manager, analyst, hr, creator, student
|
|
321
|
+
|
|
322
|
+
The ACME engine:
|
|
323
|
+
- Includes `EngineContract` with all required methods
|
|
324
|
+
- Backend renders a no-op output (e.g., `# ACME engine — no output`)
|
|
325
|
+
- Detector always returns `detected: false`
|
|
326
|
+
- Config compiler demonstrates the full pipeline with example settings
|
|
327
|
+
- Has example config YAML with ACME-specific settings (using ACME users/roles)
|
|
328
|
+
- Has example manifest declaring capabilities
|
|
329
|
+
- **Tests exist and achieve minimal code coverage** (even though the engine is inert)
|
|
330
|
+
- Extensive inline comments explaining each contract method and what it does
|
|
331
|
+
- GPL-3.0-only license, mutant config, license_finder config
|
|
332
|
+
|
|
333
|
+
#### 3b. ACME example GUI (optional, deferred until GUI extraction)
|
|
334
|
+
|
|
335
|
+
Create `rosett-ai-gui-acme` — an inert example GUI plugin:
|
|
336
|
+
- Includes `GuiContract` with all required methods
|
|
337
|
+
- Application class returns immediately (no actual window)
|
|
338
|
+
- Demonstrates how a GUI plugin registers and interfaces with core
|
|
339
|
+
|
|
340
|
+
#### 3c. ACME example MCP (optional, deferred until MCP extraction)
|
|
341
|
+
|
|
342
|
+
Create `rosett-ai-mcp-acme` — an inert example MCP plugin:
|
|
343
|
+
- Includes `McpContract` with all required methods
|
|
344
|
+
- Server class responds with dummy tool definitions
|
|
345
|
+
- Demonstrates how an MCP plugin registers and interfaces with core
|
|
346
|
+
|
|
347
|
+
#### 3d. ACME documentation focus
|
|
348
|
+
|
|
349
|
+
The ACME plugins are **declarative and educational**:
|
|
350
|
+
- Every file has comments explaining why it exists and what it fulfills
|
|
351
|
+
- `README.md` walks through creating a plugin from scratch
|
|
352
|
+
- Shows how to register, how discovery works, how manifests are validated
|
|
353
|
+
- References the contract module and base classes in rosett-ai core
|
|
354
|
+
- Documents the differences between engine, GUI, and MCP contracts
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
358
|
+
### Phase 4: Config adapters (using pluggable pattern)
|
|
359
|
+
|
|
360
|
+
Each adapter follows the same pattern — engine gem adds `config_compiler.rb`, `key_map.rb`, scope YAML, and schema.
|
|
361
|
+
|
|
362
|
+
#### 4a. Goose config adapter
|
|
363
|
+
|
|
364
|
+
- **Output**: `~/.config/goose/config.yaml` (YAML)
|
|
365
|
+
- **Settings**: provider, model, temperature, max_tokens, mode, max_turns, security, planner
|
|
366
|
+
- **Scopes**: user only
|
|
367
|
+
|
|
368
|
+
#### 4b. Aider config adapter
|
|
369
|
+
|
|
370
|
+
- **Output**: `~/.aider.conf.yml` (user) + `./.aider.conf.yml` (project)
|
|
371
|
+
- **Settings**: model, weak-model, editor-model, edit-format, API keys (secret refs), auto-commits, lint-cmd, test-cmd, dark-mode, stream, cache-prompts, reasoning-effort
|
|
372
|
+
- **Scopes**: user + project
|
|
373
|
+
|
|
374
|
+
#### 4c. Cursor config adapter
|
|
375
|
+
|
|
376
|
+
- **Output**: `.cursor/settings.json` (JSON)
|
|
377
|
+
- **Settings**: API keys (secret refs), model selection, custom endpoints, MCP servers
|
|
378
|
+
- **Scopes**: project only
|
|
379
|
+
|
|
380
|
+
#### 4d. Ollama config adapter
|
|
381
|
+
|
|
382
|
+
- **Output**: Modelfile (text) + env var config
|
|
383
|
+
- **Settings**: FROM (model), PARAMETER temperature/top_k/top_p, SYSTEM prompt, OLLAMA_HOST
|
|
384
|
+
- **Scopes**: user only
|
|
385
|
+
|
|
386
|
+
#### 4e. GPT-NeoX (vLLM) config adapter
|
|
387
|
+
|
|
388
|
+
- **Output**: `config.yaml` for `vllm serve --config`
|
|
389
|
+
- **Settings**: model, host, port, gpu-memory-utilization, max-model-len
|
|
390
|
+
- **Scopes**: user only
|
|
391
|
+
|
|
392
|
+
#### 4f. Mistral engine (new)
|
|
393
|
+
|
|
394
|
+
Entirely new engine gem `rosett-ai-engine-mistral`:
|
|
395
|
+
- Backend: compile behaviour YAML to Mistral instruction format
|
|
396
|
+
- Detector: check `mistral` CLI binary or `MISTRAL_API_KEY` env var
|
|
397
|
+
- Config adapter: API key (secret ref), model, endpoint, temperature
|
|
398
|
+
- Manifest + target profile
|
|
399
|
+
- Scopes: user only
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
### Phase 5: Design document updates
|
|
404
|
+
|
|
405
|
+
#### 5a. Update existing design documents
|
|
406
|
+
|
|
407
|
+
All existing design documents in `conf/design/` must be updated to reflect the pluggable architecture:
|
|
408
|
+
- `engine_architecture.yml` — pluggable discovery, contract modules (engine + GUI + MCP), gem-based plugins
|
|
409
|
+
- `compiler.yml` — base config compiler, engine-aware pipeline
|
|
410
|
+
- `testing.yml` — per-plugin gem testing strategy (including mutant)
|
|
411
|
+
- `distribution.yml` — per-plugin gem packaging, license_finder requirement
|
|
412
|
+
- `architecture.yml` — updated system overview with multi-type plugin system
|
|
413
|
+
- `desktop_integration.yml` — GUI contract module, gui plugin extraction
|
|
414
|
+
- `mcp_integration.yml` — MCP contract module, mcp plugin extraction
|
|
415
|
+
- Others as applicable
|
|
416
|
+
|
|
417
|
+
#### 5b. Categorize design documents
|
|
418
|
+
|
|
419
|
+
Design documents should be categorized by topic and purpose:
|
|
420
|
+
- **Core architecture**: architecture, compiler, engine_architecture
|
|
421
|
+
- **Security & quality**: security, testing, ci_pipeline
|
|
422
|
+
- **Distribution**: distribution, release_management, version_management, lifecycle_management
|
|
423
|
+
- **User interface**: ui_framework, accessibility, desktop_integration, styles
|
|
424
|
+
- **Integrations**: mcp_integration, aaif_alignment, content_packs
|
|
425
|
+
- **Operations**: monitoring_observability, usage_optimization
|
|
426
|
+
- **Configuration**: claude_code_configuration, i18n
|
|
427
|
+
- **Business**: licensing_system, documentation
|
|
428
|
+
|
|
429
|
+
---
|
|
430
|
+
|
|
431
|
+
### Phase 6: Documentation
|
|
432
|
+
|
|
433
|
+
Documentation about the pluggable architecture is of **extreme importance**.
|
|
434
|
+
|
|
435
|
+
- Update `doc/ARCHITECTURE.md` — pluggable engine diagrams, gem discovery flow
|
|
436
|
+
- Update `doc/ENGINES.md` — per-engine config adapter docs, how plugins work
|
|
437
|
+
- Update `doc/man/rai.1.ronn` — `config compile --engine`, `config show` plugged engines
|
|
438
|
+
- Update `CONTRIBUTING.md` — "How to create an engine gem" guide (reference ACME example)
|
|
439
|
+
- Update `INSTALL.md` — how to install engine gems
|
|
440
|
+
- Update `CHANGELOG.md`
|
|
441
|
+
- Update `doc/IMPLEMENTATION_PLAN.md` — new phases, engine delivery matrix
|
|
442
|
+
- Full quality gate
|
|
443
|
+
|
|
444
|
+
---
|
|
445
|
+
|
|
446
|
+
## Key design decisions
|
|
447
|
+
|
|
448
|
+
| Decision | Rationale |
|
|
449
|
+
|----------|-----------|
|
|
450
|
+
| Separate git repositories per plugin | Engines, GUIs, MCPs, and future plugin types each get full independence, own CI, own versioning |
|
|
451
|
+
| `Gem.find_files('nncc_{engine,gui,mcp}/*/register.rb')` discovery | No config needed; install gem = available |
|
|
452
|
+
| Namespaced dirs (`rosett_ai_engine/`, `rosett_ai_gui/`, `rosett_ai_mcp/`) | **Default approach** — avoids Zeitwerk root dir overlap with core gem |
|
|
453
|
+
| Contract modules per plugin type | Engine, GUI, and MCP contracts define type-specific interfaces |
|
|
454
|
+
| Base contract shared across all types | Common `plugin_type`, `plugin_name`, `display_name`, `version` |
|
|
455
|
+
| Plugin gemspec `metadata['nncc_plugin_type']` | Enables `gem search` filtering by type |
|
|
456
|
+
| Base config compiler in core | Shared pipeline logic, engines only override transforms |
|
|
457
|
+
| `CompileResult` + `SecretResolver` stay in core | Shared across all plugins |
|
|
458
|
+
| ACME example plugin | Teaches the contract without requiring real AI tool knowledge |
|
|
459
|
+
| Claude extracted first | Most complex engine; validates the pattern |
|
|
460
|
+
| GPL-3.0-only on ALL repositories | Uniform licensing across core and all plugin repos |
|
|
461
|
+
| Mutant in every repo's CI | Mutation testing ensures real test coverage quality |
|
|
462
|
+
| license_finder in every repo | Ensures all dependencies are GPL-3.0-compatible |
|
|
463
|
+
|
|
464
|
+
## Risk areas
|
|
465
|
+
|
|
466
|
+
| Risk | Mitigation |
|
|
467
|
+
|------|-----------|
|
|
468
|
+
| Zeitwerk root dir conflicts | **Namespacing is the default**: `rosett_ai_engine/`, `rosett_ai_gui/`, `rosett_ai_mcp/` — never overlap with core's `rosett-ai/` autoload root |
|
|
469
|
+
| Gem discovery order | Registry sorts alphabetically; Claude preferred via config default |
|
|
470
|
+
| Breaking existing specs | Claude extraction must be flawless before others |
|
|
471
|
+
| Deprecation aliases | Keep `RosettAi::Config::Compiler` etc. for one release cycle |
|
|
472
|
+
| CI complexity | Each plugin repo has own CI; core CI tests with all plugins installed |
|
|
473
|
+
| License compatibility | license_finder enforced in CI — blocks merges with incompatible deps |
|
|
474
|
+
| Contract drift across types | Base contract module ensures common interface; type-specific contracts extend it |
|
|
475
|
+
| GUI/MCP contracts not yet battle-tested | Engine contract validated first via Claude extraction; GUI/MCP contracts refined during extraction |
|
|
476
|
+
|
|
477
|
+
---
|
|
478
|
+
|
|
479
|
+
## Plan B: Building/Packaging Fixes (separate plan, after Plan A)
|
|
480
|
+
|
|
481
|
+
**Branch**: `fix/packaging-v1`
|
|
482
|
+
|
|
483
|
+
Addresses three documented issues at `doc/issues/`:
|
|
484
|
+
|
|
485
|
+
### Issue 001: Wrapper script missing LD_LIBRARY_PATH and RUBYLIB
|
|
486
|
+
|
|
487
|
+
- **Severity**: Critical (application fails to launch)
|
|
488
|
+
- **Fix**: Update `packaging/wrapper.sh` to set `LD_LIBRARY_PATH`, `RUBYLIB`, and hardcode `GEM_HOME` (or use ERB template at build time to avoid chicken-and-egg `ruby -e` call)
|
|
489
|
+
- **Files**: `packaging/wrapper.sh` (or new `packaging/wrapper.sh.erb`), `lib/rosett_ai/thor/tasks/build.rb`
|
|
490
|
+
|
|
491
|
+
### Issue 002: Embedded Ruby compiled with wrong --prefix
|
|
492
|
+
|
|
493
|
+
- **Severity**: High (makes Issue 001 workarounds necessary)
|
|
494
|
+
- **Root cause**: CI Docker pre-seeding copies `/usr/local/` Ruby (prefix `/usr/local`) to `/opt/rosett-ai/embedded/`; local builds use staging absolute path as prefix
|
|
495
|
+
- **Fix**: Option A+C — compile Ruby with `RUBY_CONFIGURE_OPTS="--prefix=/opt/rosett-ai/embedded"` in both CI and local builds; update `ruby_already_compiled?` to verify prefix
|
|
496
|
+
- **Files**: `.gitlab-ci-files/build/package.yml`, `lib/rosett_ai/thor/tasks/build.rb`
|
|
497
|
+
|
|
498
|
+
### Issue 003: Smoke test may produce false positives
|
|
499
|
+
|
|
500
|
+
- **Severity**: Medium (test reliability)
|
|
501
|
+
- **Root cause**: Smoke test installs system Ruby (`apt-get install ruby`) before testing the package, masking missing deps
|
|
502
|
+
- **Fix**: Remove `apt-get install ruby` from smoke test; test package in isolation on clean `debian:bookworm`; add `readelf` and `RbConfig::CONFIG["prefix"]` assertions
|
|
503
|
+
- **Files**: `.gitlab-ci-files/build/package.yml`
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Plan C: Test Kitchen Integration (separate plan, after Plan A)
|
|
508
|
+
|
|
509
|
+
**Branch**: `feature/test-kitchen`
|
|
510
|
+
|
|
511
|
+
Imperative for fully testing the pluggable architecture in realistic deployment scenarios.
|
|
512
|
+
|
|
513
|
+
### Overview
|
|
514
|
+
|
|
515
|
+
Implement test-kitchen for integration testing of rosett-ai packages and plugin architecture.
|
|
516
|
+
|
|
517
|
+
### InSpec via neatspec
|
|
518
|
+
|
|
519
|
+
For compliance/verification profiles, use the **neatspec** project:
|
|
520
|
+
- Location: `~/git/Neatnerds/NNSD/InSpec/neatspec`
|
|
521
|
+
- Wraps `cinc-auditor` gem
|
|
522
|
+
- Provides reusable profiles, role-based compliance, hierarchical data management
|
|
523
|
+
|
|
524
|
+
### Scope
|
|
525
|
+
|
|
526
|
+
- Kitchen configuration for testing .deb package installation on clean Debian
|
|
527
|
+
- Verify wrapper script, embedded Ruby prefix, and `$LOAD_PATH`
|
|
528
|
+
- Verify plugin discovery works with installed engine gems
|
|
529
|
+
- Verify `bin/raictl` commands work after package install
|
|
530
|
+
- neatspec profiles for rosett-ai compliance (file permissions, paths, service health)
|
|
531
|
+
- Design document for test-kitchen exists or will be created in `conf/design/`
|
|
532
|
+
|
|
533
|
+
---
|
|
534
|
+
|
|
535
|
+
## Verification (Plan A)
|
|
536
|
+
|
|
537
|
+
After Phase 1:
|
|
538
|
+
```bash
|
|
539
|
+
bundle exec rspec spec/rosett_ai/plugins/registry_spec.rb
|
|
540
|
+
bundle exec rspec spec/rosett_ai/plugins/contract_spec.rb
|
|
541
|
+
bundle exec rspec spec/rosett_ai/plugins/engine_contract_spec.rb
|
|
542
|
+
bundle exec rspec spec/rosett_ai/plugins/gui_contract_spec.rb
|
|
543
|
+
bundle exec rspec spec/rosett_ai/plugins/mcp_contract_spec.rb
|
|
544
|
+
bundle exec rspec spec/rosett_ai/engines/base_config_compiler_spec.rb
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
After Phase 2 (per engine repo):
|
|
548
|
+
```bash
|
|
549
|
+
cd ~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-engine-claude && bundle exec rspec
|
|
550
|
+
# ... repeat for each engine
|
|
551
|
+
bundle exec rspec # full suite from rosett-ai core
|
|
552
|
+
```
|
|
553
|
+
|
|
554
|
+
After Phase 3:
|
|
555
|
+
```bash
|
|
556
|
+
cd ~/git/Neatnerds/NNSD/NeatNerds-ai/rosett-ai-engine-acme && bundle exec rspec
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
After Phase 4:
|
|
560
|
+
```bash
|
|
561
|
+
bin/raictl config compile --engine goose --simulate --verbose
|
|
562
|
+
bin/raictl config compile --engine aider --simulate --verbose
|
|
563
|
+
bin/raictl config compile --engine cursor --simulate --verbose
|
|
564
|
+
bin/raictl config compile --engine ollama --simulate --verbose
|
|
565
|
+
bin/raictl config compile --engine gpt_neox --simulate --verbose
|
|
566
|
+
bin/raictl config compile --engine mistral --simulate --verbose
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
Final (per-repo):
|
|
570
|
+
```bash
|
|
571
|
+
bundle exec rspec # All specs pass
|
|
572
|
+
bundle exec rubocop # Clean
|
|
573
|
+
bundle exec reek # Clean
|
|
574
|
+
bundle exec mutant run # Mutation score tracked
|
|
575
|
+
bundle exec bundler-audit check # No vulns
|
|
576
|
+
bundle exec license_finder # All deps GPL-3.0-compatible
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
Final (rosett-ai core with all plugins):
|
|
580
|
+
```bash
|
|
581
|
+
bundle exec rspec # All specs pass (including plugin integration)
|
|
582
|
+
bundle exec rubocop # Clean
|
|
583
|
+
bundle exec reek # Clean
|
|
584
|
+
bundle exec mutant run # Mutation score tracked
|
|
585
|
+
bundle exec bundler-audit check # No vulns
|
|
586
|
+
bundle exec license_finder # All deps GPL-3.0-compatible
|
|
587
|
+
bin/raictl validate # All config valid
|
|
588
|
+
bin/raictl engines list # 12 engines (10 real + acme + mistral)
|
|
589
|
+
bin/raictl config show # Shows plugged engines + GUIs + MCPs
|
|
590
|
+
```
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# ADR-001: Flog Deferred from Lifecycle Verification Suite
|
|
2
|
+
|
|
3
|
+
## Status
|
|
4
|
+
|
|
5
|
+
Accepted (2026-02-20)
|
|
6
|
+
|
|
7
|
+
## Context
|
|
8
|
+
|
|
9
|
+
The lifecycle_management.yml design document (criterion 4) originally required
|
|
10
|
+
RuboCop, Reek, Flay, **and Flog** to run without regressions after every upgrade.
|
|
11
|
+
|
|
12
|
+
Flog measures method complexity using an ABC-based scoring algorithm. However,
|
|
13
|
+
RuboCop already enforces method complexity through two Metrics cops:
|
|
14
|
+
|
|
15
|
+
- `Metrics/CyclomaticComplexity` (default max: 7)
|
|
16
|
+
- `Metrics/PerceivedComplexity` (default max: 8)
|
|
17
|
+
|
|
18
|
+
These cops cover the same concern as Flog (identifying overly complex methods)
|
|
19
|
+
and are already enforced in CI and pre-commit hooks.
|
|
20
|
+
|
|
21
|
+
## Decision
|
|
22
|
+
|
|
23
|
+
Defer Flog from the lifecycle verification suite. The complexity concern it
|
|
24
|
+
addresses is already covered by RuboCop Metrics cops that are active in the
|
|
25
|
+
project's CI pipeline and pre-commit configuration.
|
|
26
|
+
|
|
27
|
+
## Consequences
|
|
28
|
+
|
|
29
|
+
- One fewer tool to install and run in the verification pipeline
|
|
30
|
+
- Complexity enforcement remains via RuboCop (already mandatory)
|
|
31
|
+
- If RuboCop Metrics cops are ever disabled or relaxed, revisit this decision
|
|
32
|
+
and consider re-introducing Flog as a standalone check
|