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,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ui_framework
|
|
3
|
+
domain: ui
|
|
4
|
+
version: 1.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 3
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-02-18"
|
|
9
|
+
modified_at: "2026-03-17"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- architecture
|
|
13
|
+
- accessibility
|
|
14
|
+
- i18n
|
|
15
|
+
|
|
16
|
+
intent: |
|
|
17
|
+
Define the pluggable UI framework that allows rosett-ai to run as a TUI application
|
|
18
|
+
by default, with optional GUI frontends installed as separate Debian packages.
|
|
19
|
+
The abstract UI interface (lib/rosett_ai/ui/base.rb) defines the contract that all
|
|
20
|
+
implementations must fulfill, including accessibility methods and i18n support.
|
|
21
|
+
GUI layers must follow their platform's Human Interface Guidelines — rosett-ai does
|
|
22
|
+
not impose a uniform look across toolkits.
|
|
23
|
+
|
|
24
|
+
constraints:
|
|
25
|
+
- TUI is the default and must work on any terminal supporting UTF-8
|
|
26
|
+
- GUI packages are separate Debian packages with correct dependency declarations
|
|
27
|
+
- lib/rosett_ai/ui/base.rb defines the interface — all implementations must satisfy shared_examples
|
|
28
|
+
- GUI implementations must follow platform HIG (GNOME HIG for GTK4, KDE HIG for Qt6)
|
|
29
|
+
- All interactive elements must be keyboard-accessible in all UI variants
|
|
30
|
+
- Accessible mode (--accessible) provides linear, screen-reader-friendly output
|
|
31
|
+
- No business logic in UI layer — UI calls into lib/rosett_ai/ for all domain operations
|
|
32
|
+
- Qt 6 is the current major release (not Qt 5)
|
|
33
|
+
|
|
34
|
+
acceptance_criteria:
|
|
35
|
+
- lib/rosett_ai/ui/base.rb exists with documented abstract methods
|
|
36
|
+
- shared_examples "a UI implementation" passes for TUI implementation
|
|
37
|
+
- TUI mode works without X11/Wayland on a headless server
|
|
38
|
+
- Accessible mode (--accessible) produces linear text output
|
|
39
|
+
- Assistive tech auto-detection (ORCA_RUNNING, BRLTTY_TTY) defaults to accessible mode
|
|
40
|
+
- text_direction method returns correct direction based on current locale
|
|
41
|
+
- announce method is defined for screen reader live-region announcements
|
|
42
|
+
- All interactive elements have keyboard bindings documented
|
|
43
|
+
|
|
44
|
+
examples:
|
|
45
|
+
- scenario: "Blind user launches rosett-ai with Orca screen reader running"
|
|
46
|
+
expected: |
|
|
47
|
+
ORCA_RUNNING env var detected. Accessible mode auto-enabled.
|
|
48
|
+
Output is linear text with structured headings. No box drawing characters.
|
|
49
|
+
Screen reader announces navigation and state changes.
|
|
50
|
+
not: "ncurses-style box drawing confuses Orca. User must manually pass --accessible."
|
|
51
|
+
- scenario: "Developer creates new rosett-ai-gtk4 package"
|
|
52
|
+
expected: |
|
|
53
|
+
Implements all methods from RosettAi::UI::Base. Passes shared_examples
|
|
54
|
+
'a UI implementation'. Registers via RosettAi::UI::Registry. Uses
|
|
55
|
+
GtkAccessible for all widgets. Follows Adwaita styling.
|
|
56
|
+
not: "Skips accessibility methods. Reimplements business logic. Uses custom styling."
|
|
57
|
+
- scenario: "User switches from TUI to GTK4 mid-session"
|
|
58
|
+
expected: "bin/raictl --ui gtk4 launches fresh GTK4 session. State is read from config, not transferred."
|
|
59
|
+
not: "Hot-swapping UI while running. Shared mutable state between UI instances."
|
|
60
|
+
|
|
61
|
+
anti_patterns:
|
|
62
|
+
- Business logic in UI code
|
|
63
|
+
- GUI-specific code in core package
|
|
64
|
+
- Ignoring platform HIG to create uniform cross-toolkit appearance
|
|
65
|
+
- Hardcoding terminal escape codes instead of using tty-* gem abstractions
|
|
66
|
+
- Skipping accessibility contract methods in new UI implementations
|
|
67
|
+
- Using Qt 5 instead of Qt 6
|
|
68
|
+
|
|
69
|
+
accessibility:
|
|
70
|
+
roles:
|
|
71
|
+
- element: "config_form"
|
|
72
|
+
role: "form"
|
|
73
|
+
label: "Settings and configuration input areas"
|
|
74
|
+
- element: "main_menu"
|
|
75
|
+
role: "navigation"
|
|
76
|
+
label: "Menu and command navigation structures"
|
|
77
|
+
- element: "status_bar"
|
|
78
|
+
role: "status"
|
|
79
|
+
label: "Status indicators and progress feedback"
|
|
80
|
+
keyboard:
|
|
81
|
+
- key: "Tab"
|
|
82
|
+
action: "Move focus to next interactive element (handled by TTY gems)"
|
|
83
|
+
- key: "Enter"
|
|
84
|
+
action: "Activate focused element (handled by TTY gems)"
|
|
85
|
+
- key: "Escape"
|
|
86
|
+
action: "Cancel or close current dialog (handled by TTY gems)"
|
|
87
|
+
- key: "Arrow keys"
|
|
88
|
+
action: "Navigate within lists and menus (handled by TTY gems)"
|
|
89
|
+
announcements:
|
|
90
|
+
- event: "state_change"
|
|
91
|
+
announce: "State changes announced via announce() method"
|
|
92
|
+
priority: "polite"
|
|
93
|
+
- event: "error"
|
|
94
|
+
announce: "Error conditions announced with assertive priority"
|
|
95
|
+
priority: "assertive"
|
|
96
|
+
- event: "progress"
|
|
97
|
+
announce: "Progress updates announced with polite priority"
|
|
98
|
+
priority: "polite"
|
|
99
|
+
|
|
100
|
+
preferences:
|
|
101
|
+
language: ruby
|
|
102
|
+
gems:
|
|
103
|
+
- tty-prompt
|
|
104
|
+
- tty-table
|
|
105
|
+
- tty-spinner
|
|
106
|
+
- pastel
|
|
107
|
+
- gtk4 (rosett-ai-gtk4 package only)
|
|
108
|
+
patterns:
|
|
109
|
+
- abstract_interface_with_shared_examples
|
|
110
|
+
- plugin_registry_with_auto_discovery
|
|
111
|
+
- presenter_pattern
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: usage_optimization
|
|
3
|
+
domain: operations
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
status: draft
|
|
6
|
+
priority: 6
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-03-04"
|
|
9
|
+
modified_at: "2026-03-16"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- architecture
|
|
13
|
+
- compiler
|
|
14
|
+
- error_handling
|
|
15
|
+
|
|
16
|
+
intent: |
|
|
17
|
+
Ensure the Rosett-AI CLI remains fast, memory-efficient, and scalable as the
|
|
18
|
+
engine count and configuration corpus grow. Startup must feel instant
|
|
19
|
+
(<200ms), compile must skip unchanged files via content-addressed caching,
|
|
20
|
+
and RSS must stay bounded. These targets protect the developer experience
|
|
21
|
+
on modest hardware (CI runners, laptops, Raspberry Pi) and prevent
|
|
22
|
+
performance regressions from creeping in unnoticed. Profiling must be
|
|
23
|
+
trivially activatable so bottlenecks are caught before they ship.
|
|
24
|
+
|
|
25
|
+
A benchmark suite (spec/benchmarks/) provides per-command performance targets
|
|
26
|
+
and automated regression detection in CI. Each command has a documented
|
|
27
|
+
time budget (e.g., version <200ms, compile <500ms, validate <300ms). The
|
|
28
|
+
benchmark suite runs in CI on merge requests and fails if any command
|
|
29
|
+
exceeds its budget by more than 20%. This catches performance regressions
|
|
30
|
+
before they reach main.
|
|
31
|
+
|
|
32
|
+
constraints:
|
|
33
|
+
- CLI startup (from exec to first Thor dispatch) must complete in under 200ms on warm cache
|
|
34
|
+
- Compile caching uses SHA256 content checksums stored at ~/.cache/rosett-ai/compile/ (XDG_CACHE_HOME)
|
|
35
|
+
- Cache format is a single JSON manifest mapping source path to {sha256, output_path, compiled_at}
|
|
36
|
+
- Zeitwerk lazy loading is already in use — no eager_load calls outside of test/CI
|
|
37
|
+
- Peak RSS must stay below 100MB for a full compile of all engines
|
|
38
|
+
- Parallelism strategy is Ractor first, concurrent-ruby fallback (per future-parallelism.md)
|
|
39
|
+
- Parallelism is deferred until validation exceeds 2 seconds or 100 files
|
|
40
|
+
- No new runtime dependencies — caching and profiling use stdlib only
|
|
41
|
+
- Backward compatible — cached and uncached compiles produce identical output
|
|
42
|
+
- --no-cache flag bypasses the cache for a single invocation
|
|
43
|
+
- RAI_PROFILE=1 enables profiling output (command timing breakdown to stderr)
|
|
44
|
+
- Cache invalidation is automatic — changed source SHA256 triggers recompile
|
|
45
|
+
- Incremental compilation only recompiles files whose source or dependencies changed
|
|
46
|
+
- Benchmark suite must define per-command time budgets with a 20% tolerance margin
|
|
47
|
+
- Benchmark results must be comparable across runs (use monotonic clock, warm JIT)
|
|
48
|
+
- CI benchmark job must fail if any command exceeds its budget
|
|
49
|
+
|
|
50
|
+
acceptance_criteria:
|
|
51
|
+
- bin/raictl version completes in under 200ms (measured via time command)
|
|
52
|
+
- bin/raictl compile writes a cache manifest to $XDG_CACHE_HOME/rosett-ai/compile/manifest.json
|
|
53
|
+
- Second consecutive compile skips unchanged files and completes faster than first
|
|
54
|
+
- --no-cache flag forces full recompile regardless of cache state
|
|
55
|
+
- Cache manifest entries include source_sha256, output_path, compiled_at fields
|
|
56
|
+
- Stale cache entries (source file deleted) are pruned on next compile
|
|
57
|
+
- RAI_PROFILE=1 prints per-phase timing to stderr (load, validate, compile, write)
|
|
58
|
+
- Peak RSS during full compile of 10 engines stays below 100MB
|
|
59
|
+
- Zeitwerk loader.ignore prevents autoloading of unused engine modules
|
|
60
|
+
- No Ractor or thread code is introduced until the parallelism trigger is met
|
|
61
|
+
- Cache directory respects XDG_CACHE_HOME when set, defaults to ~/.cache/rosett-ai/
|
|
62
|
+
- spec/benchmarks/ contains per-command benchmark scripts with documented budgets
|
|
63
|
+
- CI runs benchmarks on merge requests and fails on budget violations
|
|
64
|
+
|
|
65
|
+
examples:
|
|
66
|
+
- scenario: First compile after clean cache
|
|
67
|
+
expected: |
|
|
68
|
+
All source files are compiled. Cache manifest is written with SHA256
|
|
69
|
+
for each source file. Output identical to pre-cache behaviour.
|
|
70
|
+
not: |
|
|
71
|
+
Cache is written but compile output differs from uncached compile.
|
|
72
|
+
Manifest contains absolute paths that break on different machines.
|
|
73
|
+
- scenario: Second compile with no source changes
|
|
74
|
+
expected: |
|
|
75
|
+
Compiler reads manifest, computes SHA256 of each source, finds all
|
|
76
|
+
match, skips compilation, exits quickly. "Nothing to compile" message
|
|
77
|
+
in verbose mode.
|
|
78
|
+
not: |
|
|
79
|
+
All files are recompiled despite no changes. Cache is ignored.
|
|
80
|
+
- scenario: One behaviour file is modified between compiles
|
|
81
|
+
expected: |
|
|
82
|
+
Only the modified file (and files depending on it) are recompiled.
|
|
83
|
+
Other cached outputs are reused. Manifest is updated with new SHA256.
|
|
84
|
+
not: |
|
|
85
|
+
All files are recompiled. Unchanged outputs are rewritten to disk.
|
|
86
|
+
- scenario: Developer runs with RAI_PROFILE=1
|
|
87
|
+
expected: |
|
|
88
|
+
Stderr shows timing breakdown:
|
|
89
|
+
[profile] load: 45ms | validate: 12ms | compile: 89ms | write: 8ms | total: 154ms
|
|
90
|
+
not: |
|
|
91
|
+
Profiling output goes to stdout and breaks piped commands.
|
|
92
|
+
Profiling adds more than 5ms of overhead.
|
|
93
|
+
|
|
94
|
+
- scenario: CI benchmark detects performance regression
|
|
95
|
+
expected: |
|
|
96
|
+
Benchmark suite runs version, compile, validate commands 5 times each.
|
|
97
|
+
Median time is compared against budget: version <200ms, compile <500ms,
|
|
98
|
+
validate <300ms. If compile takes 650ms (exceeds 500ms + 20% = 600ms),
|
|
99
|
+
CI job fails with: "FAIL: compile exceeded budget (650ms > 600ms limit)".
|
|
100
|
+
not: |
|
|
101
|
+
Performance regression merges to main undetected. Benchmarks only run
|
|
102
|
+
locally. Budget violations are warnings instead of failures.
|
|
103
|
+
|
|
104
|
+
anti_patterns:
|
|
105
|
+
- Caching compiled output without checksumming the source (stale cache risk)
|
|
106
|
+
- Using mtime instead of content hash for change detection (unreliable across git operations)
|
|
107
|
+
- Eager-loading all engine modules at startup (violates lazy loading)
|
|
108
|
+
- Introducing concurrent-ruby as a runtime dependency before parallelism is needed
|
|
109
|
+
- Storing cache in the project directory (pollutes git status)
|
|
110
|
+
- Caching without a --no-cache escape hatch (debugging nightmare)
|
|
111
|
+
- Memory-mapping large files without bounds (RSS explosion)
|
|
112
|
+
- Profiling always-on even when RAI_PROFILE is unset (overhead)
|
|
113
|
+
|
|
114
|
+
preferences:
|
|
115
|
+
language: ruby
|
|
116
|
+
patterns:
|
|
117
|
+
- content_addressed_caching
|
|
118
|
+
- sha256_checksums
|
|
119
|
+
- xdg_cache_paths
|
|
120
|
+
- lazy_loading_zeitwerk
|
|
121
|
+
- monotonic_clock_profiling
|
|
122
|
+
gems: []
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: version_management
|
|
3
|
+
domain: ci
|
|
4
|
+
version: 1.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 1
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-02-23"
|
|
9
|
+
modified_at: "2026-03-17"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- ci_pipeline
|
|
13
|
+
- lifecycle_management
|
|
14
|
+
|
|
15
|
+
intent: >-
|
|
16
|
+
Any software modification that touches version upgrades (Ruby, gems, or
|
|
17
|
+
other dependencies) must pass quality checks before merging. The primary
|
|
18
|
+
gate is `rai tooling check-versions`, which verifies that all version
|
|
19
|
+
references across the codebase are consistent with canonical sources
|
|
20
|
+
(.ruby-version, Gemfile.lock). This check is enforced in both CI and
|
|
21
|
+
pre-commit hooks to prevent stale version strings from reaching the
|
|
22
|
+
remote repository.
|
|
23
|
+
|
|
24
|
+
constraints:
|
|
25
|
+
- "`rai tooling check-versions` must pass in CI before merge"
|
|
26
|
+
- "`check-versions` must run as an overcommit pre-commit hook"
|
|
27
|
+
- "Ruby version consistency: all MAJOR.MINOR.PATCH references must match .ruby-version"
|
|
28
|
+
- "Gem version consistency: resolved versions in Gemfile.lock are the canonical source"
|
|
29
|
+
- "Inline suppression (`rai:no-version-check`) is the only way to exempt a line"
|
|
30
|
+
- "Historical version references in documentation must use inline suppression, not directory-level exclusions"
|
|
31
|
+
|
|
32
|
+
acceptance_criteria:
|
|
33
|
+
- "`rai tooling check-versions` detects stale Ruby version references"
|
|
34
|
+
- "`rai tooling check-versions --gems` detects stale gem version references"
|
|
35
|
+
- "Overcommit pre-commit hook blocks commits with version mismatches"
|
|
36
|
+
- "CI pipeline fails on version mismatches"
|
|
37
|
+
- "Lines with `rai:no-version-check` are skipped"
|
|
38
|
+
- "Constraint patterns (~>, >=, etc.) are not flagged as mismatches"
|
|
39
|
+
|
|
40
|
+
examples:
|
|
41
|
+
- scenario: "Developer upgrades Ruby from 3.3.10 to 3.3.12"
|
|
42
|
+
expected: "check-versions flags any remaining 3.3.10 references in docs/code"
|
|
43
|
+
not: "3.3.10 in CHANGELOG.md or conf/design/ triggers a false positive"
|
|
44
|
+
- scenario: "LaTeX document describes historical upgrade from 3.3.8 to 3.3.10"
|
|
45
|
+
expected: "Line has `% rai:no-version-check` and is skipped"
|
|
46
|
+
not: "Entire doc/reference/src/ is excluded from checks"
|
|
47
|
+
- scenario: "Gemfile.lock resolves thor at 1.5.0 but README says thor 1.4"
|
|
48
|
+
expected: "check-versions --gems flags the stale gem reference"
|
|
49
|
+
|
|
50
|
+
anti_patterns:
|
|
51
|
+
- "Excluding entire directories to silence version mismatches"
|
|
52
|
+
- "Using --no-verify to bypass pre-commit version checks"
|
|
53
|
+
- "Hardcoding gem versions in documentation instead of referencing Gemfile.lock"
|
|
54
|
+
|
|
55
|
+
preferences:
|
|
56
|
+
language: ruby
|
|
57
|
+
patterns:
|
|
58
|
+
- "Inline suppression for intentional exceptions"
|
|
59
|
+
- "Array-form system() for all shell commands"
|
|
60
|
+
testing: rspec
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: workflow
|
|
3
|
+
domain: core
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 3
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-03-15"
|
|
9
|
+
modified_at: "2026-03-16"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- architecture
|
|
13
|
+
- engine_architecture
|
|
14
|
+
- behaviour_composition
|
|
15
|
+
- security
|
|
16
|
+
- error_handling
|
|
17
|
+
- git_hooks
|
|
18
|
+
#
|
|
19
|
+
intent: |
|
|
20
|
+
Provide repeatable, composable AI-assisted workflows that can be shared
|
|
21
|
+
across projects and teams. Define and execute multi-step workflows (e.g.
|
|
22
|
+
"review-and-fix", "refactor-with-tests", "translate-locale") as declarative
|
|
23
|
+
YAML at three scopes: global (~/.config/rosett-ai/workflows/), local
|
|
24
|
+
(.rosett-ai/workflows/), and project (.rosett-ai/conf/workflows/). Compose behaviours,
|
|
25
|
+
engine capabilities, and typed steps (shell, rosett-ai, prompt) into auditable,
|
|
26
|
+
reproducible sequences — replacing ad-hoc prompt chaining with governed
|
|
27
|
+
automation.
|
|
28
|
+
|
|
29
|
+
Workflows complement git hooks (git_hooks.yml) but serve a distinct purpose:
|
|
30
|
+
git hooks automate reactions to git lifecycle events (pre-commit, post-merge),
|
|
31
|
+
while workflows orchestrate multi-step sequences that may or may not involve
|
|
32
|
+
git. A git hook may trigger a workflow (e.g. post-merge runs the "sync-config"
|
|
33
|
+
workflow), but workflows are independently invocable and not tied to git events.
|
|
34
|
+
#
|
|
35
|
+
constraints:
|
|
36
|
+
- "Workflow definitions must be declarative YAML — no embedded Ruby or shell
|
|
37
|
+
in the YAML. Shell execution occurs only in shell-type steps via array-form
|
|
38
|
+
commands"
|
|
39
|
+
- "Shell steps use array-form execution only — no string interpolation or
|
|
40
|
+
shell expansion"
|
|
41
|
+
- "Workflows must declare required engine capabilities upfront"
|
|
42
|
+
- "Each step must be independently skippable and resumable"
|
|
43
|
+
- "Workflow execution must produce an audit log (who, what, when, which engine)"
|
|
44
|
+
- "Local workflows override global workflows of the same name"
|
|
45
|
+
- "Project workflows override local workflows of the same name"
|
|
46
|
+
- "Workflows must not access network unless explicitly declared via
|
|
47
|
+
network_required: true at the workflow or step level"
|
|
48
|
+
- "Each workflow step must declare its type: shell (array-form command),
|
|
49
|
+
raictl (CLI subcommand), or prompt (AI query). Unrecognised step types
|
|
50
|
+
are rejected at validation time"
|
|
51
|
+
- "Workflows must have a configurable maximum step count (default 50) to
|
|
52
|
+
prevent runaway definitions. Validation rejects workflows exceeding the
|
|
53
|
+
limit"
|
|
54
|
+
- "Prompt-type steps must not contain literal secrets or API key references
|
|
55
|
+
— only ${secret:env:NAME} placeholders. Prompt content is subject to
|
|
56
|
+
injection review during validation"
|
|
57
|
+
- "Prompt-type steps produce an audit hash (SHA-256 of prompt content +
|
|
58
|
+
engine + timestamp) for reproducibility and provenance tracking"
|
|
59
|
+
- "Steps using remote engines must declare network_required: true — failure
|
|
60
|
+
to declare this produces a warning (error in --strict mode)"
|
|
61
|
+
- "This design governs workflow definition, execution, scoping, and audit.
|
|
62
|
+
Git hook integration (which git events trigger which commands) is governed
|
|
63
|
+
by git_hooks.yml. Workflows may be invoked by hooks but are independently
|
|
64
|
+
defined and not coupled to git lifecycle events"
|
|
65
|
+
- "Each step in a workflow may specify an engine override, allowing a single
|
|
66
|
+
workflow to use different engines for different steps (e.g. Ollama for
|
|
67
|
+
local analysis, Claude for generation)"
|
|
68
|
+
#
|
|
69
|
+
acceptance_criteria:
|
|
70
|
+
- "`rai workflow list` shows available workflows from all three scopes"
|
|
71
|
+
- "`rai workflow run NAME` executes a workflow with the default engine"
|
|
72
|
+
- "`rai workflow run NAME --engine claude` executes with a specific engine"
|
|
73
|
+
- "`rai workflow validate NAME` checks workflow YAML against schema"
|
|
74
|
+
- "`rai workflow create NAME` scaffolds a new workflow from template"
|
|
75
|
+
- "Workflow audit log records each step execution with timestamp and outcome"
|
|
76
|
+
- "Scope precedence is enforced: project > local > global"
|
|
77
|
+
- "`rai workflow run NAME --resume` continues from the first incomplete step,
|
|
78
|
+
skipping previously completed steps based on the audit log"
|
|
79
|
+
- "`rai workflow run NAME --simulate` performs a dry run showing which steps
|
|
80
|
+
would execute, their types, and engine assignments without side effects"
|
|
81
|
+
- "Exit code 0 on success, 1 on step execution failure, 2 on validation
|
|
82
|
+
error, 3 on missing workflow, 5 on missing engine dependency"
|
|
83
|
+
#
|
|
84
|
+
examples:
|
|
85
|
+
- scenario: "Team shares a 'code-review' workflow via project .rosett-ai/conf/workflows/"
|
|
86
|
+
expected: "All team members get the same review workflow; it appears in `rai workflow list`"
|
|
87
|
+
not: "Each developer defines their own version of the same workflow"
|
|
88
|
+
- scenario: "A workflow step requires capability 'code_generation' but the engine lacks it"
|
|
89
|
+
expected: "Clear error before execution starts, listing missing capabilities"
|
|
90
|
+
not: "Failure mid-workflow when the step actually runs"
|
|
91
|
+
- scenario: "Developer resumes a partially completed workflow"
|
|
92
|
+
expected: |
|
|
93
|
+
`rai workflow run translate-locale --resume` reads the audit log,
|
|
94
|
+
identifies steps 1-3 as completed, and continues from step 4.
|
|
95
|
+
--verbose shows: 'Skipping step 1 (completed 2026-03-15T10:00:00Z)'
|
|
96
|
+
not: "Entire workflow re-runs from scratch. No way to resume."
|
|
97
|
+
- scenario: "Workflow uses mixed step types"
|
|
98
|
+
expected: |
|
|
99
|
+
steps:
|
|
100
|
+
- name: lint
|
|
101
|
+
type: shell
|
|
102
|
+
command: ["bundle", "exec", "rubocop", "--autocorrect"]
|
|
103
|
+
- name: compile
|
|
104
|
+
type: rai
|
|
105
|
+
command: compile --verbose
|
|
106
|
+
- name: review
|
|
107
|
+
type: prompt
|
|
108
|
+
engine: claude
|
|
109
|
+
prompt: "Review the changes for security issues"
|
|
110
|
+
network_required: true
|
|
111
|
+
Each step type is validated differently: shell checks array-form,
|
|
112
|
+
raictl checks valid subcommand, prompt checks for secret leakage.
|
|
113
|
+
not: |
|
|
114
|
+
All steps are treated identically. Shell commands use string-form.
|
|
115
|
+
Prompt content is not validated for secrets.
|
|
116
|
+
- scenario: "Developer dry-runs a workflow before execution"
|
|
117
|
+
expected: |
|
|
118
|
+
`rai workflow run deploy-config --simulate` outputs:
|
|
119
|
+
Step 1/4: [shell] lint — bundle exec rubocop
|
|
120
|
+
Step 2/4: [rai] compile — compile --engine claude
|
|
121
|
+
Step 3/4: [prompt] review — (claude, network_required: true)
|
|
122
|
+
Step 4/4: [shell] commit — git commit -m "..."
|
|
123
|
+
No files are modified, no commands execute.
|
|
124
|
+
not: "Dry-run silently executes shell commands. No preview available."
|
|
125
|
+
- scenario: "A shell step fails mid-workflow"
|
|
126
|
+
expected: |
|
|
127
|
+
Workflow stops at the failed step. Audit log records the failure.
|
|
128
|
+
`rai workflow run NAME --resume` can be used after fixing the issue
|
|
129
|
+
to continue from the failed step.
|
|
130
|
+
not: |
|
|
131
|
+
Workflow continues after failure. No audit trail of the failure.
|
|
132
|
+
Developer must re-run the entire workflow from scratch.
|
|
133
|
+
- scenario: "Shell step uses string-form command"
|
|
134
|
+
expected: |
|
|
135
|
+
`rai workflow validate NAME` rejects the workflow: 'Step "deploy"
|
|
136
|
+
uses string-form shell command — must be array-form for security'.
|
|
137
|
+
not: "String-form command is accepted and executed with shell expansion."
|
|
138
|
+
- scenario: "Multi-engine workflow with per-step engine selection"
|
|
139
|
+
expected: |
|
|
140
|
+
steps:
|
|
141
|
+
- name: analyze
|
|
142
|
+
type: prompt
|
|
143
|
+
engine: ollama
|
|
144
|
+
prompt: "Analyze this file for patterns"
|
|
145
|
+
- name: generate
|
|
146
|
+
type: prompt
|
|
147
|
+
engine: claude
|
|
148
|
+
prompt: "Generate refactored version"
|
|
149
|
+
network_required: true
|
|
150
|
+
Each step uses its declared engine. Engine capability is validated
|
|
151
|
+
per-step, not just at the workflow level.
|
|
152
|
+
not: |
|
|
153
|
+
All steps must use the same engine. No way to mix local and remote
|
|
154
|
+
engines in a single workflow.
|
|
155
|
+
#
|
|
156
|
+
anti_patterns:
|
|
157
|
+
- "Embedding Ruby code in workflow YAML definitions"
|
|
158
|
+
- "Workflows that cannot be interrupted and resumed"
|
|
159
|
+
- "Implicit network access during workflow execution"
|
|
160
|
+
- "Monolithic workflows that cannot be composed from smaller units"
|
|
161
|
+
- "String-form shell commands that allow injection"
|
|
162
|
+
- "Prompt steps containing literal API keys or secrets"
|
|
163
|
+
- "Workflows that silently skip failed steps"
|
|
164
|
+
- "Coupling workflow definitions to specific git events instead of
|
|
165
|
+
keeping them independently invocable"
|
|
166
|
+
- "Assuming all workflow steps use the same engine — multi-engine
|
|
167
|
+
workflows are a first-class use case"
|
|
168
|
+
#
|
|
169
|
+
gui_notes: |
|
|
170
|
+
Document interactions (cross-references):
|
|
171
|
+
|
|
172
|
+
1. git_hooks.yml: hooks may trigger workflows but are independently
|
|
173
|
+
defined. Hooks automate git lifecycle; workflows orchestrate steps.
|
|
174
|
+
|
|
175
|
+
2. behaviour_composition.yml: workflows compose behaviours as inputs.
|
|
176
|
+
Scope precedence (project > local > global) is consistent between
|
|
177
|
+
workflows and behaviours.
|
|
178
|
+
|
|
179
|
+
3. engine_architecture.yml: workflow steps reference engine capabilities.
|
|
180
|
+
Per-step engine selection leverages the engine manifest contract.
|
|
181
|
+
|
|
182
|
+
4. security.yml: shell steps use array-form execution. Prompt steps
|
|
183
|
+
are validated for secret leakage and injection patterns.
|
|
184
|
+
|
|
185
|
+
5. error_handling.yml: workflow errors (step failure, missing engine,
|
|
186
|
+
validation) follow the structured error hierarchy (exit codes,
|
|
187
|
+
what/why/fix format).
|
|
188
|
+
|
|
189
|
+
6. compiler.yml: workflows may invoke compilation as an rai-type step.
|
|
190
|
+
Workflows are not part of the compilation pipeline themselves.
|
|
191
|
+
|
|
192
|
+
Workflow YAML schema outline:
|
|
193
|
+
name: string (unique identifier)
|
|
194
|
+
description: string
|
|
195
|
+
version: string (semver)
|
|
196
|
+
author: string
|
|
197
|
+
scope: global | local | project
|
|
198
|
+
network_required: boolean (default false)
|
|
199
|
+
engine: string (default engine, overridable per step)
|
|
200
|
+
required_capabilities: [string]
|
|
201
|
+
max_steps: integer (default 50)
|
|
202
|
+
steps:
|
|
203
|
+
- name: string
|
|
204
|
+
type: shell | rosett-ai | prompt
|
|
205
|
+
command: [string] (shell) | string (rai)
|
|
206
|
+
prompt: string (prompt type only)
|
|
207
|
+
engine: string (optional override)
|
|
208
|
+
network_required: boolean
|
|
209
|
+
skip_if: string (condition expression)
|
|
210
|
+
on_failure: stop | continue | retry(n)
|
|
211
|
+
audit:
|
|
212
|
+
log_path: string (default .rosett-ai/logs/workflows/)
|
|
213
|
+
retention_days: integer (default 90)
|
|
214
|
+
#
|
|
215
|
+
preferences:
|
|
216
|
+
language: ruby
|
|
217
|
+
patterns:
|
|
218
|
+
- "Step executor pattern with pluggable step types"
|
|
219
|
+
- "Scope resolution chain (project > local > global)"
|
|
220
|
+
- "Structured audit logging"
|
|
221
|
+
- "Per-step engine selection"
|
|
222
|
+
- "Resume from audit log"
|
|
223
|
+
testing: rspec with workflow fixture YAML files, step executor mocks,
|
|
224
|
+
resume/dry-run scenarios, and multi-engine workflow integration tests
|
|
225
|
+
gems:
|
|
226
|
+
- json_schemer
|
|
227
|
+
- thor
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# frozen_string_literal: false
|
|
2
|
+
# Default MCP server configuration for Rosett-AI.
|
|
3
|
+
#
|
|
4
|
+
# Override per-project via .rosett-ai-mcp.yml or per-user via
|
|
5
|
+
# ~/.config/rosett-ai/mcp/server.yml.
|
|
6
|
+
---
|
|
7
|
+
http:
|
|
8
|
+
port: 8484
|
|
9
|
+
host: localhost
|
|
10
|
+
authentication:
|
|
11
|
+
type: api_key
|
|
12
|
+
key_source: auto
|
|
13
|
+
keyfile_path: rosett-ai-mcp-keys.yml
|
|
14
|
+
api_key_env: RAI_MCP_API_KEY
|
|
15
|
+
origin:
|
|
16
|
+
allowed_origins:
|
|
17
|
+
- "http://localhost:*"
|
|
18
|
+
- "http://127.0.0.1:*"
|
|
19
|
+
strict_mode: false
|
|
20
|
+
rate_limiting:
|
|
21
|
+
enabled: true
|
|
22
|
+
unauthenticated_rpm: 60
|
|
23
|
+
authenticated_rpm: 300
|
|
24
|
+
cors:
|
|
25
|
+
enabled: false
|
|
26
|
+
origins: []
|
|
27
|
+
methods:
|
|
28
|
+
- POST
|
|
29
|
+
- GET
|
|
30
|
+
- DELETE
|
|
31
|
+
headers:
|
|
32
|
+
- Content-Type
|
|
33
|
+
- Authorization
|
|
34
|
+
- Accept
|
|
35
|
+
- Mcp-Session-Id
|
|
36
|
+
max_age: 86400
|
|
37
|
+
max_request_size: 1048576
|
|
38
|
+
content_type_enforcement: true
|
|
39
|
+
tls:
|
|
40
|
+
enabled: false
|
|
41
|
+
cert_path: null
|
|
42
|
+
key_path: null
|
data/conf/mcp/trust.yml
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# SPDX-License-Identifier: GPL-3.0-only
|
|
2
|
+
# Copyright (C) 2026 Hugo Antonio Sepulveda Manriquez / NeatNerds
|
|
3
|
+
#
|
|
4
|
+
# Default trust sources for MCP server installation.
|
|
5
|
+
# Users can add custom trusted domains via `rai mcp trust-sources add DOMAIN`.
|
|
6
|
+
---
|
|
7
|
+
trust_sources:
|
|
8
|
+
# NeatNerds Enterprise Manager (default trusted)
|
|
9
|
+
- domain: enterprise.neatnerds.be
|
|
10
|
+
type: enterprise
|
|
11
|
+
description: NeatNerds Enterprise Manager
|
|
12
|
+
|
|
13
|
+
# Goose project registry (community-vetted)
|
|
14
|
+
- domain: registry.block.xyz
|
|
15
|
+
type: registry
|
|
16
|
+
description: Goose MCP server registry
|
|
17
|
+
|
|
18
|
+
# Localhost is trusted by default for local development servers
|
|
19
|
+
- domain: localhost
|
|
20
|
+
type: local
|
|
21
|
+
description: Local development servers
|