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,214 @@
|
|
|
1
|
+
# Implement ci_pipeline.yml design document (P1)
|
|
2
|
+
|
|
3
|
+
**Branch**: `design_implementation`
|
|
4
|
+
**Date**: 2026-02-21
|
|
5
|
+
**Design doc**: `conf/design/ci_pipeline.yml` v1.0.0
|
|
6
|
+
**Commits**: bf9f15e (primary), 5f352e6 (mutant job)
|
|
7
|
+
|
|
8
|
+
## Motivation
|
|
9
|
+
|
|
10
|
+
Without enforcement gates, security rules are suggestions, not constraints.
|
|
11
|
+
The CI pipeline turns the security, testing, and styles design documents into
|
|
12
|
+
merge-blocking reality. No code merges to main without passing all stages.
|
|
13
|
+
|
|
14
|
+
This is the fourth and final P1 domain. It depends on security (audit tools),
|
|
15
|
+
testing (test harness), and styles (linting tools) all being in place first.
|
|
16
|
+
|
|
17
|
+
## Acceptance criteria
|
|
18
|
+
|
|
19
|
+
11 of 12 acceptance criteria from `ci_pipeline.yml` are satisfied. One is
|
|
20
|
+
deferred with documented rationale:
|
|
21
|
+
|
|
22
|
+
| # | Criterion | Status | Evidence |
|
|
23
|
+
|---|-----------|--------|----------|
|
|
24
|
+
| 1 | GitLab CI YAML is valid and passes rai validate-ci-yaml | Met | `validate:ci_yaml` job runs `bin/raictl tooling validate-ci-yaml` |
|
|
25
|
+
| 2 | Pipeline has distinct stages in order | Met | validate > code_quality > security_scan > test > build |
|
|
26
|
+
| 3 | bundler-audit check exits non-zero on known CVEs | Met | Pre-existing `security:bundler_audit` job |
|
|
27
|
+
| 4 | ruby_audit check exits non-zero on Ruby stdlib CVEs | Met | New `security:ruby_audit` job |
|
|
28
|
+
| 5 | rubocop exits non-zero on any violation | Met | Pre-existing `quality:rubocop` job |
|
|
29
|
+
| 6 | reek exits non-zero on any code smell above threshold | Met | `quality:reek` job (exit code fix applied) |
|
|
30
|
+
| 7 | flay exits non-zero on structural duplication above threshold | Met | Enforced via overcommit pre-commit hook (mass 16) |
|
|
31
|
+
| 8 | flog exits non-zero on complexity above threshold | Deferred | ADR-001: covered by RuboCop Metrics cops |
|
|
32
|
+
| 9 | rspec produces JUnit XML report and coverage/ artifacts | Met | Pre-existing `test:rspec` job with artifacts |
|
|
33
|
+
| 10 | mutant runs only on merge_request_event and blocks merge | Met | `.gitlab-ci-files/test/mutant.yml` (`allow_failure: false`) |
|
|
34
|
+
| 11 | Build stage produces .deb package artifact | Met | Pre-existing `build:package` job |
|
|
35
|
+
| 12 | Pipeline duration under 15 minutes for push events | Met | Mutation testing excluded from push events |
|
|
36
|
+
|
|
37
|
+
### Flog deferral (ADR-001)
|
|
38
|
+
|
|
39
|
+
Flog measures method complexity using an ABC-based scoring algorithm. RuboCop
|
|
40
|
+
already enforces the same concern through `Metrics/CyclomaticComplexity`
|
|
41
|
+
(max: 7) and `Metrics/PerceivedComplexity` (max: 8). Adding Flog would
|
|
42
|
+
duplicate enforcement. Decision recorded in `doc/decisions/001-flog-deferred.md`.
|
|
43
|
+
|
|
44
|
+
## Changes by area
|
|
45
|
+
|
|
46
|
+
### CI YAML validation job
|
|
47
|
+
|
|
48
|
+
**New file**: `.gitlab-ci-files/validate/ci-yaml.yml`
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
validate:ci_yaml:
|
|
52
|
+
stage: validate
|
|
53
|
+
extends:
|
|
54
|
+
- .ruby_base
|
|
55
|
+
- .resource_limits_small
|
|
56
|
+
script:
|
|
57
|
+
- bundle exec bin/raictl tooling validate-ci-yaml
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Validates all `.gitlab-ci-files/**/*.yml` files using the rosett-ai CLI's
|
|
61
|
+
`SupplementaryGitlabCiYamlValidator`. This catches YAML syntax errors in CI
|
|
62
|
+
configuration before they reach GitLab's own validator.
|
|
63
|
+
|
|
64
|
+
### Version consistency job
|
|
65
|
+
|
|
66
|
+
**New file**: `.gitlab-ci-files/validate/version-consistency.yml`
|
|
67
|
+
|
|
68
|
+
```yaml
|
|
69
|
+
validate:version_consistency:
|
|
70
|
+
stage: validate
|
|
71
|
+
extends:
|
|
72
|
+
- .ruby_base
|
|
73
|
+
- .resource_limits_small
|
|
74
|
+
script:
|
|
75
|
+
- bundle exec bin/raictl tooling check-versions
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Runs `VersionConsistencyChecker` to verify all Ruby version references in the
|
|
79
|
+
codebase match `.ruby-version`. Catches partial version updates that leave
|
|
80
|
+
stale references.
|
|
81
|
+
|
|
82
|
+
### Reek exit code fix
|
|
83
|
+
|
|
84
|
+
**Commit**: bf9f15e
|
|
85
|
+
|
|
86
|
+
The `quality:reek` job previously discarded reek's exit code because the JSON
|
|
87
|
+
report redirection masked it:
|
|
88
|
+
|
|
89
|
+
```diff
|
|
90
|
+
script:
|
|
91
|
+
- gem install reek --no-document
|
|
92
|
+
- |
|
|
93
|
+
- bundle exec reek --config .reek.yml --format json lib > reek-report.json || true
|
|
94
|
+
- bundle exec reek --config .reek.yml lib
|
|
95
|
+
+ bundle exec reek --config .reek.yml --format json lib > reek-report.json
|
|
96
|
+
+ REEK_EXIT=$?
|
|
97
|
+
+ bundle exec reek --config .reek.yml lib
|
|
98
|
+
+ exit $REEK_EXIT
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Now the JSON report is captured for artifacts AND the exit code is preserved
|
|
102
|
+
so smells actually block the pipeline.
|
|
103
|
+
|
|
104
|
+
### Security scan jobs
|
|
105
|
+
|
|
106
|
+
**New file**: `.gitlab-ci-files/security_scan/ruby-audit.yml`
|
|
107
|
+
|
|
108
|
+
```yaml
|
|
109
|
+
security:ruby_audit:
|
|
110
|
+
stage: security_scan
|
|
111
|
+
extends:
|
|
112
|
+
- .ruby_base
|
|
113
|
+
- .resource_limits_small
|
|
114
|
+
script:
|
|
115
|
+
- gem install bundler --no-document
|
|
116
|
+
- bundle exec ruby-audit check
|
|
117
|
+
artifacts:
|
|
118
|
+
when: on_failure
|
|
119
|
+
expire_in: 1 week
|
|
120
|
+
paths:
|
|
121
|
+
- ruby-audit-report.txt
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Scans Ruby's stdlib for known CVEs. Complements bundler-audit (which scans
|
|
125
|
+
gem dependencies). Together they cover the full Ruby dependency surface.
|
|
126
|
+
|
|
127
|
+
### Stage ordering
|
|
128
|
+
|
|
129
|
+
The `.gitlab-ci.yml` includes are organized by stage:
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
validate: yaml.yml, json.yml, ruby-syntax.yml, version-consistency.yml, ci-yaml.yml
|
|
133
|
+
code_quality: rubocop.yml, reek.yml
|
|
134
|
+
security_scan: bundler-audit.yml, ruby-audit.yml, trivy.yml
|
|
135
|
+
test: rspec.yml, mutant.yml
|
|
136
|
+
build: package.yml
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
This ordering ensures fast validation checks run first (catching YAML/JSON
|
|
140
|
+
errors in seconds), followed by increasingly expensive stages. Security scans
|
|
141
|
+
run before tests so CVE-affected code is caught even if tests pass.
|
|
142
|
+
|
|
143
|
+
## CI pipeline stage flow
|
|
144
|
+
|
|
145
|
+
```mermaid
|
|
146
|
+
flowchart TB
|
|
147
|
+
subgraph VALIDATE["validate"]
|
|
148
|
+
V1[yaml syntax]
|
|
149
|
+
V2[json syntax]
|
|
150
|
+
V3[ruby syntax]
|
|
151
|
+
V4[version consistency]
|
|
152
|
+
V5[ci-yaml validation]
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
subgraph CODE_QUALITY["code_quality"]
|
|
156
|
+
CQ1[rubocop]
|
|
157
|
+
CQ2[reek]
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
subgraph SECURITY["security_scan"]
|
|
161
|
+
S1[bundler-audit]
|
|
162
|
+
S2[ruby-audit]
|
|
163
|
+
S3[trivy]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
subgraph TEST["test"]
|
|
167
|
+
T1[rspec + SimpleCov]
|
|
168
|
+
T2[mutant<br/>MR only]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
subgraph BUILD["build"]
|
|
172
|
+
B1[.deb package]
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
VALIDATE --> CODE_QUALITY --> SECURITY --> TEST --> BUILD
|
|
176
|
+
|
|
177
|
+
VALIDATE -->|any fail| STOP1[Pipeline stops]
|
|
178
|
+
CODE_QUALITY -->|any fail| STOP2[Pipeline stops]
|
|
179
|
+
SECURITY -->|any fail| STOP3[Pipeline stops]
|
|
180
|
+
TEST -->|any fail| STOP4[Pipeline stops]
|
|
181
|
+
|
|
182
|
+
style STOP1 fill:#8b0000,color:#fff
|
|
183
|
+
style STOP2 fill:#8b0000,color:#fff
|
|
184
|
+
style STOP3 fill:#8b0000,color:#fff
|
|
185
|
+
style STOP4 fill:#8b0000,color:#fff
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Files created
|
|
189
|
+
|
|
190
|
+
| File | Purpose |
|
|
191
|
+
|------|---------|
|
|
192
|
+
| `.gitlab-ci-files/validate/ci-yaml.yml` | CI YAML validation job |
|
|
193
|
+
| `.gitlab-ci-files/validate/version-consistency.yml` | Version consistency check job |
|
|
194
|
+
| `.gitlab-ci-files/security_scan/ruby-audit.yml` | Ruby stdlib CVE scanning job |
|
|
195
|
+
| `doc/decisions/001-flog-deferred.md` | ADR: Flog deferred, covered by RuboCop Metrics |
|
|
196
|
+
|
|
197
|
+
## Files modified
|
|
198
|
+
|
|
199
|
+
| File | Change |
|
|
200
|
+
|------|--------|
|
|
201
|
+
| `.gitlab-ci.yml` | Added 3 new include entries (ci-yaml, version-consistency, ruby-audit) |
|
|
202
|
+
| `.gitlab-ci-files/code_quality/reek.yml` | Fixed exit code handling (was silently swallowing failures) |
|
|
203
|
+
| `conf/design/ci_pipeline.yml` | Updated flog criterion with deferral annotation |
|
|
204
|
+
|
|
205
|
+
## Verification
|
|
206
|
+
|
|
207
|
+
- [x] `bundle exec bin/raictl tooling validate-ci-yaml` — all CI YAML files valid
|
|
208
|
+
- [x] `bundle exec bin/raictl tooling check-versions` — all version references consistent
|
|
209
|
+
- [x] `bundle exec bundler-audit check` — 0 vulnerabilities
|
|
210
|
+
- [x] `bundle exec ruby-audit check` — 0 vulnerabilities
|
|
211
|
+
- [x] `bundle exec rubocop` — 0 offenses
|
|
212
|
+
- [x] `bundle exec reek lib/` — 0 warnings
|
|
213
|
+
- [x] `bundle exec rspec` — 437 examples, 0 failures
|
|
214
|
+
- [x] ADR-001 documents flog deferral rationale
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
# Compiler Multi-Target Pipeline (P2)
|
|
2
|
+
|
|
3
|
+
**Branch**: `design_implementation`
|
|
4
|
+
**Date**: 2026-02-21
|
|
5
|
+
**Design doc**: `conf/design/compiler.yml` v1.0.0 (draft -> approved)
|
|
6
|
+
**Depends on**: security, architecture
|
|
7
|
+
|
|
8
|
+
## Motivation
|
|
9
|
+
|
|
10
|
+
The rai compiler is the core product capability: author configuration once
|
|
11
|
+
in a rich YAML format, compile down to target-specific output for different
|
|
12
|
+
AI assistants. Until this phase, the compiler was a monolithic
|
|
13
|
+
`BehaviourCompiler` class that hardcoded Claude Code's markdown format —
|
|
14
|
+
every method from discovery to rendering to orphan management lived in one
|
|
15
|
+
219-line class.
|
|
16
|
+
|
|
17
|
+
This made it impossible to compile for non-Claude targets without forking
|
|
18
|
+
the entire compilation pipeline. The compiler.yml design document specifies
|
|
19
|
+
9 acceptance criteria requiring pluggable backends, target profiles that
|
|
20
|
+
require no code changes, locale compilation, and sub-5-second performance
|
|
21
|
+
at scale.
|
|
22
|
+
|
|
23
|
+
This phase refactors the compiler into a strategy-pattern pipeline with
|
|
24
|
+
data-driven target profiles, extracts two concrete backends (Claude and
|
|
25
|
+
Generic), adds a locale compiler producing gettext and Qt Linguist output,
|
|
26
|
+
and wires `--target` and `--locales` flags into the CLI — all while
|
|
27
|
+
maintaining 100% backward compatibility with existing tests.
|
|
28
|
+
|
|
29
|
+
## Acceptance criteria
|
|
30
|
+
|
|
31
|
+
| # | Criterion | Status | Evidence |
|
|
32
|
+
|---|-----------|--------|----------|
|
|
33
|
+
| 1 | `bin/raictl compile` produces output in ~/.claude/rules/ | Met (preserved) | Existing compile specs pass unchanged |
|
|
34
|
+
| 2 | `--target claude` produces CLAUDE.md-compatible markdown | Met | ClaudeBackend renders HTML metadata + priority annotations |
|
|
35
|
+
| 3 | `--target generic` produces lowest-common-denominator markdown | Met | GenericBackend renders plain markdown, no Claude specifics |
|
|
36
|
+
| 4 | `--simulate --verbose` shows diffs without writing | Met (preserved) | Existing simulate specs pass unchanged |
|
|
37
|
+
| 5 | `--vendor` writes lockfile | Met (preserved) | Existing vendor specs pass unchanged |
|
|
38
|
+
| 6 | `--locales` compiles i18n YAML to gettext and Qt formats | Met | LocaleCompiler produces .pot/.po and .ts files |
|
|
39
|
+
| 7 | New target profile in conf/targets/ requires no code changes | Met | TargetProfile.load + Backend.for factory; data-driven |
|
|
40
|
+
| 8 | Invalid source documents produce clear error messages | Met (preserved) | CompileError with file path and field details |
|
|
41
|
+
| 9 | 100 behaviour files compile in under 5 seconds | Met | Benchmark spec: 100 files in ~0.4s |
|
|
42
|
+
|
|
43
|
+
## Architecture
|
|
44
|
+
|
|
45
|
+
### Class hierarchy
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
RosettAi::Compiler::Backend (abstract base + .for() factory)
|
|
49
|
+
├── RosettAi::Compiler::Backends::ClaudeBackend (extracted from BehaviourCompiler)
|
|
50
|
+
└── RosettAi::Compiler::Backends::GenericBackend (new, plain markdown)
|
|
51
|
+
|
|
52
|
+
RosettAi::Compiler::CompilationPipeline (shared pipeline, accepts backend:)
|
|
53
|
+
└── RosettAi::Compiler::BehaviourCompiler (backward-compat wrapper, defaults claude)
|
|
54
|
+
|
|
55
|
+
RosettAi::Compiler::CompiledOutput (Struct value object)
|
|
56
|
+
RosettAi::Compiler::TargetProfile (loads conf/targets/<name>.yml)
|
|
57
|
+
RosettAi::Compiler::LocaleCompiler (YAML -> gettext .po + Qt .ts)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Pipeline flow
|
|
61
|
+
|
|
62
|
+
```mermaid
|
|
63
|
+
flowchart LR
|
|
64
|
+
subgraph INPUT["Source"]
|
|
65
|
+
YAML["conf/behaviour/*.yml<br/>conf/design/*.yml<br/>conf/tooling/*.yml"]
|
|
66
|
+
LOCALE["locales/*.yml"]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
subgraph PIPELINE["CompilationPipeline"]
|
|
70
|
+
DISC[discover_categories]
|
|
71
|
+
VAL[validate!]
|
|
72
|
+
RENDER[backend.render]
|
|
73
|
+
CHECK[checksum]
|
|
74
|
+
DIFF[diff]
|
|
75
|
+
LOCK[lockfile_data]
|
|
76
|
+
ORPHAN[orphaned_files]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
subgraph BACKEND["Backend (strategy)"]
|
|
80
|
+
CLAUDE[ClaudeBackend<br/>HTML metadata<br/>priority annotations]
|
|
81
|
+
GENERIC[GenericBackend<br/>plain markdown<br/>no annotations]
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
subgraph PROFILE["Target Profile"]
|
|
85
|
+
TP["conf/targets/claude.yml<br/>conf/targets/generic.yml"]
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
subgraph OUTPUT["Output"]
|
|
89
|
+
RULES["~/.claude/rules/*.md"]
|
|
90
|
+
POT[".pot / .po"]
|
|
91
|
+
TS[".ts (Qt)"]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
YAML --> DISC --> VAL --> RENDER --> CHECK
|
|
95
|
+
TP --> BACKEND
|
|
96
|
+
BACKEND --> RENDER
|
|
97
|
+
CHECK --> DIFF --> LOCK
|
|
98
|
+
CHECK --> ORPHAN
|
|
99
|
+
RENDER --> RULES
|
|
100
|
+
|
|
101
|
+
LOCALE --> POT
|
|
102
|
+
LOCALE --> TS
|
|
103
|
+
|
|
104
|
+
style CLAUDE fill:#2d6a2d,color:#fff
|
|
105
|
+
style GENERIC fill:#2d6a2d,color:#fff
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Changes by area
|
|
109
|
+
|
|
110
|
+
### Backend abstraction (Steps 1-2)
|
|
111
|
+
|
|
112
|
+
Introduced `RosettAi::Compiler::Backend` as an abstract base class with a
|
|
113
|
+
`.for(target_name)` factory method, following the `Compressor.for()` pattern
|
|
114
|
+
from `RosettAi::Backup`. The factory loads a `TargetProfile`, resolves the
|
|
115
|
+
backend class from a constant map, and returns an instantiated backend.
|
|
116
|
+
|
|
117
|
+
`ClaudeBackend` was extracted directly from the original
|
|
118
|
+
`BehaviourCompiler#render` method — identical output, now isolated behind
|
|
119
|
+
the strategy interface. `GenericBackend` produces lowest-common-denominator
|
|
120
|
+
markdown: no HTML comment metadata, no priority annotations, just headings
|
|
121
|
+
and rule descriptions.
|
|
122
|
+
|
|
123
|
+
Both backends share the `managed_file?` implementation from the base class,
|
|
124
|
+
using their distinct `generated_marker` prefixes to identify which files
|
|
125
|
+
they manage. This ensures orphan detection works correctly across backends.
|
|
126
|
+
|
|
127
|
+
### CompiledOutput value object (Step 3)
|
|
128
|
+
|
|
129
|
+
Replaced the raw `Hash` returned by `compile()` with a frozen `Struct`.
|
|
130
|
+
Ruby `Struct` supports both `.field` and `[:field]` access, so all existing
|
|
131
|
+
callers that use `info[:content]` continue to work without modification.
|
|
132
|
+
|
|
133
|
+
### Target profile system (Step 4)
|
|
134
|
+
|
|
135
|
+
Created `conf/targets/claude.yml` and `conf/targets/generic.yml` as
|
|
136
|
+
declarative profiles validated against `conf/schemas/target_schema.json`.
|
|
137
|
+
The `TargetProfile` loader validates profiles at load time and exposes
|
|
138
|
+
field accessors. Adding a new target (e.g., Mistral) requires only a new
|
|
139
|
+
YAML file — no code changes.
|
|
140
|
+
|
|
141
|
+
The JSON Schema enforces a strict enum for `backend` (`claude`, `generic`)
|
|
142
|
+
and `output_format` (`markdown`, `json`, `yaml`), with optional fields for
|
|
143
|
+
`engine_version`, `output_dir`, `max_context_window`, and `rendering` flags.
|
|
144
|
+
|
|
145
|
+
### Pipeline extraction (Step 5)
|
|
146
|
+
|
|
147
|
+
`BehaviourCompiler` was split into:
|
|
148
|
+
|
|
149
|
+
- **`CompilationPipeline`** — owns all pipeline mechanics (discover, validate,
|
|
150
|
+
compile, checksum, diff, lockfile, orphans). Delegates `render()` and
|
|
151
|
+
`managed_file?()` to the injected backend.
|
|
152
|
+
- **`BehaviourCompiler`** — thin subclass that preserves the original 3-argument
|
|
153
|
+
constructor (`source_dir:`, `target_dir:`, `schema_dir:`) and defaults the
|
|
154
|
+
backend to `ClaudeBackend`.
|
|
155
|
+
|
|
156
|
+
**Backward compatibility gate**: all 26 existing `BehaviourCompiler` specs
|
|
157
|
+
and all 11 existing compile task specs passed without modification at this
|
|
158
|
+
step.
|
|
159
|
+
|
|
160
|
+
### CLI extensions (Step 6)
|
|
161
|
+
|
|
162
|
+
Added `--target` (string, default `claude`) and `--locales` (boolean) options
|
|
163
|
+
to the compile Thor task. The `build_compiler` method now instantiates
|
|
164
|
+
`CompilationPipeline` with the target-specific backend instead of hardcoding
|
|
165
|
+
`BehaviourCompiler`.
|
|
166
|
+
|
|
167
|
+
### Locale compiler (Step 7)
|
|
168
|
+
|
|
169
|
+
`LocaleCompiler` reads `locales/*.yml` files, flattens nested YAML keys
|
|
170
|
+
into dotted paths, and generates:
|
|
171
|
+
|
|
172
|
+
- **Gettext**: `.pot` template (English source, empty `msgstr`) and
|
|
173
|
+
per-locale `.po` files (populated `msgstr`). Standard PO format with
|
|
174
|
+
project headers.
|
|
175
|
+
- **Qt Linguist**: `.ts` XML files following the TS 2.1 DTD. Messages are
|
|
176
|
+
grouped by context (derived from key path hierarchy).
|
|
177
|
+
|
|
178
|
+
Output structure:
|
|
179
|
+
|
|
180
|
+
```text
|
|
181
|
+
locales/compiled/
|
|
182
|
+
├── gettext/
|
|
183
|
+
│ ├── rosett-ai.pot
|
|
184
|
+
│ └── en/LC_MESSAGES/rosett-ai.po
|
|
185
|
+
└── qt/
|
|
186
|
+
└── nncc_en.ts
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Performance (Step 8)
|
|
190
|
+
|
|
191
|
+
Benchmark spec generates 100 behaviour fixture files and asserts compilation
|
|
192
|
+
completes in under 5 seconds. Actual measured time: ~0.4 seconds.
|
|
193
|
+
|
|
194
|
+
## Files created (19)
|
|
195
|
+
|
|
196
|
+
| File | Purpose |
|
|
197
|
+
|------|---------|
|
|
198
|
+
| `lib/rosett_ai/compiler/backend.rb` | Abstract backend base with .for() factory |
|
|
199
|
+
| `lib/rosett_ai/compiler/backends/claude_backend.rb` | Claude Code markdown renderer |
|
|
200
|
+
| `lib/rosett_ai/compiler/backends/generic_backend.rb` | Generic plain markdown renderer |
|
|
201
|
+
| `lib/rosett_ai/compiler/compilation_pipeline.rb` | Shared compilation pipeline |
|
|
202
|
+
| `lib/rosett_ai/compiler/compiled_output.rb` | CompiledOutput Struct value object |
|
|
203
|
+
| `lib/rosett_ai/compiler/target_profile.rb` | Target profile loader and validator |
|
|
204
|
+
| `lib/rosett_ai/compiler/locale_compiler.rb` | YAML to gettext + Qt compiler |
|
|
205
|
+
| `conf/targets/claude.yml` | Claude Code target profile |
|
|
206
|
+
| `conf/targets/generic.yml` | Generic AI target profile |
|
|
207
|
+
| `conf/schemas/target_schema.json` | JSON Schema for target profiles |
|
|
208
|
+
| `locales/en.yml` | English locale source file |
|
|
209
|
+
| `spec/rosett_ai/compiler/backend_spec.rb` | Backend abstract base tests |
|
|
210
|
+
| `spec/rosett_ai/compiler/backends/claude_backend_spec.rb` | ClaudeBackend tests |
|
|
211
|
+
| `spec/rosett_ai/compiler/backends/generic_backend_spec.rb` | GenericBackend tests |
|
|
212
|
+
| `spec/rosett_ai/compiler/compilation_pipeline_spec.rb` | Pipeline tests + benchmark |
|
|
213
|
+
| `spec/rosett_ai/compiler/compiled_output_spec.rb` | CompiledOutput tests |
|
|
214
|
+
| `spec/rosett_ai/compiler/target_profile_spec.rb` | TargetProfile tests |
|
|
215
|
+
| `spec/rosett_ai/compiler/locale_compiler_spec.rb` | LocaleCompiler tests |
|
|
216
|
+
| `spec/support/shared_examples/compiler_backend.rb` | Backend interface contract |
|
|
217
|
+
|
|
218
|
+
## Files modified (8)
|
|
219
|
+
|
|
220
|
+
| File | Change |
|
|
221
|
+
|------|--------|
|
|
222
|
+
| `lib/rosett_ai/compiler/behaviour_compiler.rb` | Refactored to thin wrapper around CompilationPipeline |
|
|
223
|
+
| `lib/rosett_ai/thor/tasks/compile.rb` | Added --target and --locales options, uses CompilationPipeline |
|
|
224
|
+
| `spec/rosett_ai/compiler/behaviour_compiler_spec.rb` | Unchanged (backward compatibility preserved) |
|
|
225
|
+
| `spec/rosett_ai/thor/tasks/compile_spec.rb` | Updated stub from rules_target_dir to resolve_target_dir, added --target generic test |
|
|
226
|
+
| `spec/rosett_ai/thor/tasks/validate_spec.rb` | Excluded internal target_schema from category coverage assertion |
|
|
227
|
+
| `spec/spec_helper.rb` | Added target_schema copy, targets dir, create_target_profile helper |
|
|
228
|
+
| `.reek.yml` | Added exclusions for new pipeline, backend, and locale classes |
|
|
229
|
+
| `conf/design/compiler.yml` | Status: draft -> approved |
|
|
230
|
+
|
|
231
|
+
## Verification
|
|
232
|
+
|
|
233
|
+
- [x] `bundle exec rspec` — 579 examples, 0 failures
|
|
234
|
+
- [x] `bundle exec rubocop` — 96 files, 0 offenses
|
|
235
|
+
- [x] `bundle exec reek lib/rosett_ai/compiler/` — 0 warnings
|
|
236
|
+
- [x] `bin/raictl compile --simulate --verbose` — correct output
|
|
237
|
+
- [x] `bin/raictl compile --target generic --simulate --verbose` — generic markers, no Claude metadata
|
|
238
|
+
- [x] `bin/raictl compile --locales --simulate --verbose` — locale paths reported
|
|
239
|
+
- [x] Performance benchmark: 100 files in ~0.4s (< 5s threshold)
|
|
240
|
+
- [x] All 26 original BehaviourCompiler specs pass unchanged
|
|
241
|
+
- [x] All 11 original compile task specs pass unchanged
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Add `config show` and `design show` / `design list` subcommands
|
|
2
|
+
|
|
3
|
+
**Date**: 2026-02-21
|
|
4
|
+
**Branch**: `design_implementation`
|
|
5
|
+
**Design doc**: `conf/design/claude_code_configuration.yml` (criterion 18 added)
|
|
6
|
+
|
|
7
|
+
## Summary
|
|
8
|
+
|
|
9
|
+
Adds `config show SCOPE` and `design show NAME` / `design list` subcommands
|
|
10
|
+
to close feature gaps identified after completing the CC config compiler (P2).
|
|
11
|
+
These provide read-only inspection of compiled configuration and design
|
|
12
|
+
documents without modifying any files.
|
|
13
|
+
|
|
14
|
+
## New commands
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bin/raictl config show user # Compiled JSON with secrets masked
|
|
18
|
+
bin/raictl config show user --raw # YAML source, sanitized
|
|
19
|
+
bin/raictl design show security # Summary: header, intent, constraints, criteria
|
|
20
|
+
bin/raictl design show security --full # All sections including examples, preferences
|
|
21
|
+
bin/raictl design list # Table of all design documents
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## New files (2)
|
|
25
|
+
|
|
26
|
+
| File | Purpose |
|
|
27
|
+
|------|---------|
|
|
28
|
+
| `lib/rosett_ai/config/masking_secret_resolver.rb` | Drop-in SecretResolver replacement returning `"***"` for all `${secret:...}` values |
|
|
29
|
+
| `spec/rosett_ai/config/masking_secret_resolver_spec.rb` | 15 tests: resolve/resolve_all for all backends, pass-through, nested structures |
|
|
30
|
+
|
|
31
|
+
## Modified files (7)
|
|
32
|
+
|
|
33
|
+
| File | Change |
|
|
34
|
+
|------|--------|
|
|
35
|
+
| `lib/rosett_ai/config/compiler.rb` | Accept optional `secret_resolver:` keyword in `initialize` |
|
|
36
|
+
| `lib/rosett_ai/thor/tasks/config.rb` | Add `show SCOPE` with `--raw` flag, 3 private helpers |
|
|
37
|
+
| `lib/rosett_ai/thor/tasks/design.rb` | Add `show NAME` with `--full`, `list`, 9 private helpers |
|
|
38
|
+
| `spec/rosett_ai/thor/tasks/config_spec.rb` | 5 new tests for config show |
|
|
39
|
+
| `spec/rosett_ai/thor/tasks/design_spec.rb` | 15 new tests for design show + list |
|
|
40
|
+
| `conf/design/claude_code_configuration.yml` | Add acceptance criterion 18 |
|
|
41
|
+
| `.reek.yml` | Exclusions for new methods |
|
|
42
|
+
|
|
43
|
+
## Key design decisions
|
|
44
|
+
|
|
45
|
+
1. **MaskingSecretResolver over flag** — injecting a resolver that returns
|
|
46
|
+
`"***"` is safer than adding a `mask:` flag to SecretResolver. The real
|
|
47
|
+
resolver never sees show-mode traffic, so there is no risk of accidentally
|
|
48
|
+
leaking secrets.
|
|
49
|
+
|
|
50
|
+
2. **Compile in simulate mode** — `config show` compiles in-memory with
|
|
51
|
+
`simulate: true` so no files are written, ever.
|
|
52
|
+
|
|
53
|
+
3. **Design show: summary by default, --full for complete** — mirrors how
|
|
54
|
+
users typically inspect documents. Constraints and acceptance criteria are
|
|
55
|
+
always shown; examples and anti-patterns require `--full`.
|
|
56
|
+
|
|
57
|
+
## Verification
|
|
58
|
+
|
|
59
|
+
- 764 tests, 0 failures, 92.52% line coverage
|
|
60
|
+
- RuboCop: 0 offenses (113 files)
|
|
61
|
+
- Reek: 0 warnings
|