rosett-ai 1.3.3 → 1.5.9
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 +4 -4
- data/CHANGELOG.md +398 -22
- data/README.md +56 -42
- data/bin/raictl +13 -0
- data/conf/adopt_redactions.yml +2 -0
- data/conf/compliance/cra_rules.yml +2 -0
- data/conf/compliance/license_rules.yml +2 -0
- data/conf/mcp/server_defaults.yml +2 -0
- data/conf/mcp/trust.yml +1 -0
- data/conf/packaging/core.yml +2 -0
- data/conf/packaging/gtk4.yml +2 -0
- data/conf/packaging/qt6.yml +2 -0
- data/conf/policy/default_deny_list.yml +2 -0
- data/conf/review/cli-command-audit.yml +2 -0
- data/conf/review/design-docs.yml +2 -0
- data/conf/review/design-questionnaire.yml +2 -0
- data/conf/review/questionnaire.yml +2 -0
- data/conf/review/rosett-ai-core.yml +2 -0
- data/conf/schemas/ai_config_schema.json +14 -2
- data/conf/schemas/autoqueue.schema.json +153 -0
- data/conf/schemas/behaviour_schema.json +31 -7
- data/conf/schemas/compliance_rule_schema.json +17 -4
- data/conf/schemas/content_pack_manifest_schema.json +23 -4
- data/conf/schemas/design_schema.json +177 -42
- data/conf/schemas/engine_manifest_schema.json +22 -5
- data/conf/schemas/lockfile_schema.json +26 -4
- data/conf/schemas/mcp_server_schema.json +50 -9
- data/conf/schemas/packaging_schema.json +23 -5
- data/conf/schemas/policy_schema.json +35 -9
- data/conf/schemas/provenance_schema.json +33 -5
- data/conf/schemas/rai_config_schema.json +6 -2
- data/conf/schemas/rai_project_schema.json +8 -2
- data/conf/schemas/scope_hierarchy_schema.json +22 -5
- data/conf/schemas/target_schema.json +33 -6
- data/conf/schemas/tooling_schema.json +53 -12
- data/conf/schemas/workflow_schema.json +39 -9
- data/conf/targets/agents_md.yml +1 -0
- data/conf/targets/claude.yml +2 -0
- data/conf/tooling/tools.yml +2 -0
- data/lib/rosett_ai/adopter/local_analysis_collector.rb +5 -0
- data/lib/rosett_ai/adopter/rule_adopter.rb +40 -0
- data/lib/rosett_ai/ai_config/context_window.rb +3 -0
- data/lib/rosett_ai/ai_config/cost_controls.rb +1 -0
- data/lib/rosett_ai/ai_config/fallback_chain.rb +1 -0
- data/lib/rosett_ai/ai_config/model_router.rb +1 -0
- data/lib/rosett_ai/ai_config/validator.rb +2 -0
- data/lib/rosett_ai/authorship/attribution_compiler.rb +1 -0
- data/lib/rosett_ai/authorship/disclosure_policy.rb +2 -0
- data/lib/rosett_ai/authorship/review_validator.rb +1 -0
- data/lib/rosett_ai/authorship/trailer_generator.rb +1 -0
- data/lib/rosett_ai/backup/compressor.rb +3 -0
- data/lib/rosett_ai/backup/destination.rb +1 -0
- data/lib/rosett_ai/behaviour/manager.rb +1 -0
- data/lib/rosett_ai/compiler/backend.rb +3 -0
- data/lib/rosett_ai/compiler/backends/agents_md_backend.rb +1 -0
- data/lib/rosett_ai/compiler/backends/claude_backend.rb +1 -0
- data/lib/rosett_ai/compiler/behaviour_compiler.rb +1 -0
- data/lib/rosett_ai/compiler/compilation_pipeline.rb +1 -7
- data/lib/rosett_ai/compiler/locale_compiler.rb +2 -0
- data/lib/rosett_ai/compiler/target_profile.rb +11 -0
- data/lib/rosett_ai/completion/generator.rb +2 -0
- data/lib/rosett_ai/completion/shells/zsh_generator.rb +1 -0
- data/lib/rosett_ai/comply/checkers/cra_checker.rb +1 -0
- data/lib/rosett_ai/comply/checkers/license_checker.rb +2 -0
- data/lib/rosett_ai/comply/checkers/spdx_header_checker.rb +4 -0
- data/lib/rosett_ai/comply/runner.rb +2 -0
- data/lib/rosett_ai/composition/composer.rb +1 -0
- data/lib/rosett_ai/composition/lockfile.rb +1 -0
- data/lib/rosett_ai/composition/merge_strategy.rb +1 -0
- data/lib/rosett_ai/config/masking_secret_resolver.rb +9 -0
- data/lib/rosett_ai/config/secret_resolver.rb +4 -0
- data/lib/rosett_ai/configuration.rb +4 -0
- data/lib/rosett_ai/content/content_client.rb +15 -0
- data/lib/rosett_ai/content/pack_installer.rb +1 -0
- data/lib/rosett_ai/content/pack_manifest.rb +21 -0
- data/lib/rosett_ai/content_packs/manager.rb +1 -0
- data/lib/rosett_ai/dbus/compositor_detector.rb +2 -0
- data/lib/rosett_ai/dbus/focus_adapters/base.rb +1 -0
- data/lib/rosett_ai/dbus/focus_adapters/gnome_adapter.rb +5 -0
- data/lib/rosett_ai/dbus/focus_adapters/hyprland_adapter.rb +4 -0
- data/lib/rosett_ai/dbus/focus_adapters/i3_adapter.rb +4 -0
- data/lib/rosett_ai/dbus/focus_adapters/kwin_adapter.rb +4 -0
- data/lib/rosett_ai/dbus/focus_adapters/x11_adapter.rb +4 -0
- data/lib/rosett_ai/dbus/focus_monitor_interface.rb +1 -0
- data/lib/rosett_ai/dbus/manager_interface.rb +1 -0
- data/lib/rosett_ai/dbus/plugin_manager_interface.rb +2 -0
- data/lib/rosett_ai/dbus/rate_limiter.rb +1 -0
- data/lib/rosett_ai/dbus/service.rb +3 -0
- data/lib/rosett_ai/dbus/status_notifier_interface.rb +14 -0
- data/lib/rosett_ai/desktop/dbus_client.rb +6 -0
- data/lib/rosett_ai/desktop/gtk4_app.rb +3 -0
- data/lib/rosett_ai/desktop/gtk4_preferences.rb +1 -0
- data/lib/rosett_ai/desktop/gui_logger.rb +2 -0
- data/lib/rosett_ai/doctor/check.rb +1 -1
- data/lib/rosett_ai/doctor/checks/cache_health_check.rb +1 -0
- data/lib/rosett_ai/doctor.rb +1 -0
- data/lib/rosett_ai/documentation/reference_compiler.rb +9 -0
- data/lib/rosett_ai/documentation/translator.rb +8 -0
- data/lib/rosett_ai/engines/base_config_compiler.rb +71 -1
- data/lib/rosett_ai/engines/detector.rb +5 -0
- data/lib/rosett_ai/engines/registry.rb +7 -0
- data/lib/rosett_ai/exit_codes.rb +6 -0
- data/lib/rosett_ai/formatting.rb +1 -0
- data/lib/rosett_ai/gem_consistency_checker.rb +6 -0
- data/lib/rosett_ai/git_hooks/chain_detector.rb +1 -0
- data/lib/rosett_ai/git_hooks/installer.rb +4 -0
- data/lib/rosett_ai/git_hooks/script_generator.rb +2 -0
- data/lib/rosett_ai/gitlab/validators/supplementary_gitlab_ci_yaml_validator.rb +6 -0
- data/lib/rosett_ai/i18n/utf8_checker.rb +1 -0
- data/lib/rosett_ai/init/config_file_writer.rb +4 -0
- data/lib/rosett_ai/init/directory_builder.rb +15 -0
- data/lib/rosett_ai/init/file_copier.rb +51 -0
- data/lib/rosett_ai/init/mcp_registrar.rb +1 -0
- data/lib/rosett_ai/init/project_initializer.rb +1 -0
- data/lib/rosett_ai/licensing/license_key.rb +4 -0
- data/lib/rosett_ai/licensing/license_store.rb +11 -0
- data/lib/rosett_ai/licensing/tier.rb +9 -0
- data/lib/rosett_ai/mcp/admin/auditor.rb +1 -0
- data/lib/rosett_ai/mcp/admin/health_checker.rb +1 -0
- data/lib/rosett_ai/mcp/admin/registry.rb +1 -0
- data/lib/rosett_ai/mcp/enforcement/hook_generator.rb +27 -4
- data/lib/rosett_ai/mcp/enforcement/validator.rb +24 -3
- data/lib/rosett_ai/mcp/governance.rb +9 -0
- data/lib/rosett_ai/mcp/http_security_config.rb +22 -0
- data/lib/rosett_ai/mcp/key_hasher.rb +4 -2
- data/lib/rosett_ai/mcp/keyfile.rb +4 -0
- data/lib/rosett_ai/mcp/middleware/cors.rb +4 -0
- data/lib/rosett_ai/mcp/middleware/origin_validation.rb +1 -0
- data/lib/rosett_ai/mcp/middleware/rate_limit.rb +3 -0
- data/lib/rosett_ai/mcp/plugins.rb +1 -0
- data/lib/rosett_ai/mcp/prompts/compilation_prompt.rb +2 -0
- data/lib/rosett_ai/mcp/prompts/compliance_prompt.rb +3 -0
- data/lib/rosett_ai/mcp/prompts/diagnostics_prompt.rb +2 -0
- data/lib/rosett_ai/mcp/prompts/validation_prompt.rb +2 -0
- data/lib/rosett_ai/mcp/resources/behaviour_resource.rb +2 -0
- data/lib/rosett_ai/mcp/resources/config_resource.rb +2 -0
- data/lib/rosett_ai/mcp/resources/design_resource.rb +1 -0
- data/lib/rosett_ai/mcp/resources/hooks_resource.rb +3 -0
- data/lib/rosett_ai/mcp/resources/provenance_resource.rb +2 -0
- data/lib/rosett_ai/mcp/resources/rules_resource.rb +1 -0
- data/lib/rosett_ai/mcp/resources/schema_resource.rb +1 -0
- data/lib/rosett_ai/mcp/server.rb +7 -1
- data/lib/rosett_ai/mcp/settings/trust_manager.rb +3 -0
- data/lib/rosett_ai/mcp/tools/adopt_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/backup_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/behaviour_display_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/behaviour_list_tool.rb +3 -0
- data/lib/rosett_ai/mcp/tools/behaviour_manage_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/behaviour_show_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/compile_status_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/compile_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/comply_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/config_compile_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/config_status_tool.rb +3 -0
- data/lib/rosett_ai/mcp/tools/content_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/context_query_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/design_list_tool.rb +3 -0
- data/lib/rosett_ai/mcp/tools/design_show_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/doctor_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/documentation_status_tool.rb +3 -0
- data/lib/rosett_ai/mcp/tools/engines_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/hook_install_tool.rb +7 -0
- data/lib/rosett_ai/mcp/tools/hook_preview_tool.rb +33 -8
- data/lib/rosett_ai/mcp/tools/hooks_status_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/init_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/license_status_tool.rb +3 -0
- data/lib/rosett_ai/mcp/tools/project_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/provenance_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/provenance_write_tool.rb +3 -0
- data/lib/rosett_ai/mcp/tools/retrofit_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/rule_search_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/schema_get_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/tooling_tool.rb +5 -0
- data/lib/rosett_ai/mcp/tools/validate_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/workflow_execute_tool.rb +4 -0
- data/lib/rosett_ai/mcp/tools/workflow_tool.rb +5 -0
- data/lib/rosett_ai/migration/detector.rb +1 -0
- data/lib/rosett_ai/migration/nncc_config_migrator.rb +2 -0
- data/lib/rosett_ai/migration/xdg_migrator.rb +3 -1
- data/lib/rosett_ai/package_manager/apt.rb +5 -0
- data/lib/rosett_ai/package_manager/base.rb +1 -0
- data/lib/rosett_ai/package_manager/gem_backend.rb +1 -0
- data/lib/rosett_ai/packaging/variant_config.rb +12 -0
- data/lib/rosett_ai/plugins/contract.rb +1 -0
- data/lib/rosett_ai/plugins/engine_contract.rb +2 -0
- data/lib/rosett_ai/plugins/gui_contract.rb +2 -0
- data/lib/rosett_ai/plugins/mcp_contract.rb +2 -0
- data/lib/rosett_ai/plugins/registry.rb +10 -0
- data/lib/rosett_ai/policy/auditor.rb +1 -0
- data/lib/rosett_ai/policy/opt_out_scanner.rb +1 -0
- data/lib/rosett_ai/policy/tier_hierarchy.rb +2 -0
- data/lib/rosett_ai/policy/validator.rb +1 -0
- data/lib/rosett_ai/profiler.rb +7 -0
- data/lib/rosett_ai/project/drift_detector.rb +1 -0
- data/lib/rosett_ai/project/manager.rb +1 -0
- data/lib/rosett_ai/project/template_applier.rb +1 -0
- data/lib/rosett_ai/provenance/entry.rb +2 -0
- data/lib/rosett_ai/provenance/source.rb +1 -0
- data/lib/rosett_ai/provenance/store.rb +3 -0
- data/lib/rosett_ai/provenance/validator.rb +1 -0
- data/lib/rosett_ai/quorum/collector.rb +1 -0
- data/lib/rosett_ai/quorum/comparator.rb +2 -0
- data/lib/rosett_ai/quorum/strategies/adopt.rb +1 -0
- data/lib/rosett_ai/rai_config.rb +9 -0
- data/lib/rosett_ai/retrofit/engine.rb +2 -0
- data/lib/rosett_ai/retrofit/parsers/agents_md_parser.rb +8 -0
- data/lib/rosett_ai/retrofit/parsers/claude_parser.rb +10 -0
- data/lib/rosett_ai/retrofit/parsers/cursor_parser.rb +9 -0
- data/lib/rosett_ai/retrofit/secret_detector.rb +3 -0
- data/lib/rosett_ai/secrets_resolver.rb +1 -0
- data/lib/rosett_ai/session_hooks/installer.rb +130 -0
- data/lib/rosett_ai/smart_feedback/suggester.rb +4 -0
- data/lib/rosett_ai/smart_feedback/thor_middleware.rb +7 -0
- data/lib/rosett_ai/structured_logger.rb +1 -0
- data/lib/rosett_ai/telemetry/log_rotator.rb +1 -0
- data/lib/rosett_ai/telemetry.rb +1 -0
- data/lib/rosett_ai/thor/cli.rb +9 -0
- data/lib/rosett_ai/thor/tasks/adopt.rb +2 -0
- data/lib/rosett_ai/thor/tasks/backfill_user_yml.rb +207 -0
- data/lib/rosett_ai/thor/tasks/backup.rb +6 -0
- data/lib/rosett_ai/thor/tasks/behaviour.rb +12 -0
- data/lib/rosett_ai/thor/tasks/build.rb +87 -4
- data/lib/rosett_ai/thor/tasks/compile.rb +76 -32
- data/lib/rosett_ai/thor/tasks/completion.rb +9 -0
- data/lib/rosett_ai/thor/tasks/comply.rb +2 -0
- data/lib/rosett_ai/thor/tasks/config.rb +21 -5
- data/lib/rosett_ai/thor/tasks/content.rb +8 -0
- data/lib/rosett_ai/thor/tasks/dbus.rb +13 -0
- data/lib/rosett_ai/thor/tasks/design.rb +2 -0
- data/lib/rosett_ai/thor/tasks/desktop.rb +4 -0
- data/lib/rosett_ai/thor/tasks/doctor.rb +2 -0
- data/lib/rosett_ai/thor/tasks/documentation.rb +7 -0
- data/lib/rosett_ai/thor/tasks/engines.rb +8 -0
- data/lib/rosett_ai/thor/tasks/hooks.rb +8 -0
- data/lib/rosett_ai/thor/tasks/init.rb +1 -0
- data/lib/rosett_ai/thor/tasks/license.rb +8 -0
- data/lib/rosett_ai/thor/tasks/mcp.rb +40 -0
- data/lib/rosett_ai/thor/tasks/migrate.rb +2 -0
- data/lib/rosett_ai/thor/tasks/plugins.rb +15 -0
- data/lib/rosett_ai/thor/tasks/project.rb +8 -0
- data/lib/rosett_ai/thor/tasks/provenance.rb +8 -0
- data/lib/rosett_ai/thor/tasks/release.rb +8 -0
- data/lib/rosett_ai/thor/tasks/retrofit.rb +4 -0
- data/lib/rosett_ai/thor/tasks/validate.rb +1 -0
- data/lib/rosett_ai/thor/tasks/workflow.rb +14 -0
- data/lib/rosett_ai/tooling/version_checker.rb +1 -0
- data/lib/rosett_ai/ui/accessible_tui.rb +18 -0
- data/lib/rosett_ai/ui/base.rb +3 -0
- data/lib/rosett_ai/ui/gtk4.rb +19 -0
- data/lib/rosett_ai/ui/kde.rb +1 -0
- data/lib/rosett_ai/ui/qt6.rb +1 -0
- data/lib/rosett_ai/ui/registry.rb +15 -0
- data/lib/rosett_ai/ui/tui.rb +22 -0
- data/lib/rosett_ai/validators/behaviour_validator.rb +1 -0
- data/lib/rosett_ai/validators/design_validator.rb +2 -0
- data/lib/rosett_ai/validators/schema_validator.rb +4 -0
- data/lib/rosett_ai/validators/tooling_validator.rb +1 -0
- data/lib/rosett_ai/version.rb +2 -1
- data/lib/rosett_ai/version_consistency_checker.rb +6 -0
- data/lib/rosett_ai/workflow/engine.rb +1 -0
- data/lib/rosett_ai/workflow/manager.rb +1 -0
- data/lib/rosett_ai/workflow/schema_validator.rb +2 -0
- data/lib/rosett_ai/workflow/step_runner.rb +1 -0
- data/lib/rosett_ai/workflow/steps/rai_step.rb +1 -0
- data/lib/rosett_ai/yaml_loader.rb +2 -0
- data/lib/rosett_ai.rb +2 -0
- data/lib/scripts/generated/docker_hub_tags.rb +2 -0
- data/locales/ar.yml +2 -0
- data/locales/en.yml +5 -0
- data/locales/fr.yml +2 -0
- metadata +9 -189
- data/.ai-provenance.yml +0 -119
- data/.debride_whitelist +0 -186
- data/.fasterer.yml +0 -29
- data/.mdl_style.rb +0 -10
- data/.mdlrc +0 -3
- data/.mutant.yml +0 -49
- data/.namespace-allowlist +0 -42
- data/.reek.yml +0 -1040
- data/.rosett-ai/config.yml +0 -3
- data/.rspec +0 -5
- data/.rubocop.yml +0 -380
- data/.ruby-version +0 -1
- data/.yamllint +0 -51
- data/.yardopts +0 -12
- data/AI-DISCLOSURE.md +0 -48
- data/CLAUDE.md +0 -141
- data/CONTRIBUTING.md +0 -734
- data/INSTALL.md +0 -154
- data/LICENSE.md +0 -675
- data/QUICKSTART.md +0 -73
- data/Rakefile +0 -200
- data/SECURITY.md +0 -114
- data/cliff.toml +0 -52
- data/conf/behaviour/.gitkeep +0 -0
- data/conf/design/aaif_alignment.yml +0 -181
- data/conf/design/ab_testing.yml +0 -172
- data/conf/design/accessibility.yml +0 -84
- data/conf/design/ai_authorship.yml +0 -210
- data/conf/design/ai_provenance.yml +0 -224
- data/conf/design/ai_tool_configuration.yml +0 -207
- data/conf/design/architecture.yml +0 -139
- data/conf/design/autocompletion.yml +0 -115
- data/conf/design/backward_compatibility.yml +0 -112
- data/conf/design/behaviour_composition.yml +0 -246
- data/conf/design/build_rake_extraction.yml +0 -57
- data/conf/design/ci_pipeline.yml +0 -100
- data/conf/design/claude_code_configuration.yml +0 -157
- data/conf/design/compiler.yml +0 -128
- data/conf/design/comply.yml +0 -153
- data/conf/design/content_packs.yml +0 -84
- data/conf/design/desktop_integration.yml +0 -289
- data/conf/design/distribution.yml +0 -216
- data/conf/design/doctor.yml +0 -184
- data/conf/design/documentation.yml +0 -152
- data/conf/design/engine_architecture.yml +0 -257
- data/conf/design/error_handling.yml +0 -103
- data/conf/design/feature_flags.yml +0 -142
- data/conf/design/git_hooks.yml +0 -165
- data/conf/design/gui_plugins.yml +0 -475
- data/conf/design/i18n.yml +0 -84
- data/conf/design/integration_testing.yml +0 -56
- data/conf/design/licensing_system.yml +0 -88
- data/conf/design/lifecycle_management.yml +0 -208
- data/conf/design/mcp_integration.yml +0 -207
- data/conf/design/mcp_settings.yml +0 -126
- data/conf/design/migration.yml +0 -56
- data/conf/design/monitoring_observability.yml +0 -194
- data/conf/design/namespace_cleanup.yml +0 -145
- data/conf/design/plugin_test_segregation.yml +0 -145
- data/conf/design/policy_management.yml +0 -229
- data/conf/design/project_management.yml +0 -183
- data/conf/design/rai_mcp_asset_discovery.yml +0 -164
- data/conf/design/rai_mcp_server.yml +0 -605
- data/conf/design/release_management.yml +0 -117
- data/conf/design/retrofit.yml +0 -199
- data/conf/design/retrospective_analyzer.yml +0 -79
- data/conf/design/scope_hierarchy.yml +0 -352
- data/conf/design/security.yml +0 -115
- data/conf/design/session_retrospective.yml +0 -85
- data/conf/design/smart_ui_feedback.yml +0 -89
- data/conf/design/structured_logging.yml +0 -148
- data/conf/design/styles.yml +0 -123
- data/conf/design/test_peer_review.yml +0 -89
- data/conf/design/testing.yml +0 -136
- data/conf/design/threat_model.yml +0 -108
- data/conf/design/ui_framework.yml +0 -111
- data/conf/design/usage_optimization.yml +0 -122
- data/conf/design/version_management.yml +0 -60
- data/conf/design/workflow.yml +0 -227
- data/doc/AAIF_POSITIONING.md +0 -58
- data/doc/ADOPT.md +0 -224
- data/doc/AI_PROVENANCE.md +0 -139
- data/doc/ARCHITECTURE.md +0 -920
- data/doc/BEHAVIOUR.md +0 -409
- data/doc/BUILD.md +0 -138
- data/doc/CI_CD_RECIPES.md +0 -171
- data/doc/CLAUDE_SESSIONS_MOVED.md +0 -16
- data/doc/COMMAND_ANALYSIS.md +0 -229
- data/doc/CONFIGURATION.md +0 -281
- data/doc/DESIGN_AUDIT.md +0 -235
- data/doc/DESIGN_PEER_REVIEW.md +0 -771
- data/doc/DESKTOP.md +0 -447
- data/doc/ENGINES.md +0 -567
- data/doc/ENGINE_DEVELOPMENT_GUIDE.md +0 -417
- data/doc/FEATURE_AUDIT.md +0 -218
- data/doc/IMPLEMENTATION_PLAN.md +0 -669
- data/doc/INCIDENT_REPORT_2026-02-02.md +0 -251
- data/doc/MIGRATION_GUIDE.md +0 -88
- data/doc/PACKAGING.md +0 -232
- data/doc/PROJECT_DASHBOARD.md +0 -153
- data/doc/PULP_DEPLOYMENT.md +0 -164
- data/doc/QUALITY_FIX_SUMMARY.md +0 -110
- data/doc/QUICK_START.md +0 -162
- data/doc/REEK_CONFIGURATION.md +0 -166
- data/doc/REFERENCE.md +0 -253
- data/doc/REFERENCES.md +0 -324
- data/doc/SECURITY_REVIEW_CHECKLIST.md +0 -72
- data/doc/SESSION_2026-02-28_GTK4_HARDENING.md +0 -359
- data/doc/SETUP.md +0 -202
- data/doc/TEST_PEER_REVIEW.md +0 -152
- data/doc/THREAT_MODEL.md +0 -230
- data/doc/USAGE.md +0 -545
- data/doc/USER_MANUAL.md +0 -585
- data/doc/ai_test_review_checklist.md +0 -110
- data/doc/changes/2026-02-18-packaging-fpm.md +0 -155
- data/doc/changes/2026-02-19-testing-infrastructure.md +0 -221
- data/doc/changes/2026-02-20-security-implementation.md +0 -281
- data/doc/changes/2026-02-20-styles-implementation.md +0 -220
- data/doc/changes/2026-02-21-architecture-completion.md +0 -95
- data/doc/changes/2026-02-21-architecture-ui-layer.md +0 -253
- data/doc/changes/2026-02-21-cc-config-implementation.md +0 -108
- data/doc/changes/2026-02-21-ci-pipeline-implementation.md +0 -214
- data/doc/changes/2026-02-21-compiler-multi-target-pipeline.md +0 -241
- data/doc/changes/2026-02-21-config-design-show-commands.md +0 -61
- data/doc/changes/2026-02-21-design-implementation-overview.md +0 -455
- data/doc/changes/2026-02-21-lifecycle-management.md +0 -196
- data/doc/changes/2026-02-21-path-resolver.md +0 -128
- data/doc/changes/2026-02-24-ci-tmpdir-mutant-fetch.md +0 -45
- data/doc/changes/2026-03-01-ci-bundler-strategy.md +0 -120
- data/doc/changes/2026-03-20-security-hardening-phase2.md +0 -163
- data/doc/context/SESSION-HANDOFF.md +0 -69
- data/doc/context/ai-engine-usage-trends-2026.md +0 -80
- data/doc/context/plan-pluggable-engines.md +0 -590
- data/doc/decisions/001-flog-deferred.md +0 -32
- data/doc/decisions/002-path-resolution-strategy.md +0 -158
- data/doc/decisions/003-ui-adapter-selection.md +0 -193
- data/doc/decisions/004-design-document-validation.md +0 -179
- data/doc/decisions/005-package-splitting-strategy.md +0 -200
- data/doc/decisions/006-multi-engine-architecture.md +0 -147
- data/doc/decisions/007-engine-agnostic-pivot.md +0 -219
- data/doc/decisions/008-ci-bundler-strategy.md +0 -129
- data/doc/decisions/009-core-only-v1-release.md +0 -60
- data/doc/decisions/010-engine-debian-packaging.md +0 -66
- data/doc/decisions/011-context-aware-cli.md +0 -71
- data/doc/dependency_decisions.yml +0 -247
- data/doc/issues/001-wrapper-missing-environment-variables.md +0 -197
- data/doc/issues/002-embedded-ruby-wrong-prefix.md +0 -217
- data/doc/issues/003-smoke-test-false-positive.md +0 -127
- data/doc/issues/004-market-research-design-updates.md +0 -109
- data/doc/issues/005-compile-scope-coexistence.md +0 -161
- data/doc/locales/.gitkeep +0 -0
- data/doc/man/rai.1.ronn +0 -505
- data/doc/operations/packaging.md +0 -133
- data/doc/operations/rosett-ai-release.md +0 -65
- data/doc/reference/error-catalog.md +0 -107
- 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 +0 -4
- data/doc/reference/src/bibliography.bib +0 -79
- data/doc/reference/src/main.tex +0 -1288
- data/doc/reference/src/structure.tex +0 -303
- data/doc/rosett-ai-bookmarks.html +0 -301
- data/kitchen.yml +0 -46
- data/lib/rosett_ai/mcp/enforcement/.gitkeep +0 -0
- data/locales/.gitkeep +0 -0
- data/packaging/build-engine-deb.sh +0 -81
- data/packaging/scripts/postinst +0 -17
- data/packaging/scripts/postrm +0 -19
- data/packaging/scripts/prerm +0 -10
- data/packaging/wrapper.sh.template +0 -38
- data/rosett-ai.gemspec +0 -63
- data/rules/.gitkeep +0 -0
- data/scripts/publish/pulp_upload.sh +0 -123
- data/settings.json +0 -29
|
@@ -10,8 +10,11 @@ module RosettAi
|
|
|
10
10
|
# Tracks max tokens, output reserve, and truncation strategy
|
|
11
11
|
# for compilation into engine-native settings.
|
|
12
12
|
class ContextWindow
|
|
13
|
+
# @return [Array] Supported context truncation strategy names.
|
|
13
14
|
TRUNCATION_STRATEGIES = ['tail', 'head', 'middle'].freeze
|
|
15
|
+
# @return [Object] Default maximum token budget.
|
|
14
16
|
DEFAULT_MAX_TOKENS = 200_000
|
|
17
|
+
# @return [Integer] Default token reserve for response generation.
|
|
15
18
|
DEFAULT_RESERVE = 8192
|
|
16
19
|
|
|
17
20
|
attr_reader :max_tokens, :output_reserve, :truncation_strategy
|
|
@@ -11,6 +11,7 @@ module RosettAi
|
|
|
11
11
|
# These preferences guide model selection and are compiled into
|
|
12
12
|
# engine-specific configuration hints.
|
|
13
13
|
class CostControls
|
|
14
|
+
# @return [Array] Defined tier levels.
|
|
14
15
|
TIERS = ['economy', 'standard', 'premium'].freeze
|
|
15
16
|
|
|
16
17
|
attr_reader :preferred_tier, :monthly_budget_note
|
|
@@ -11,6 +11,7 @@ module RosettAi
|
|
|
11
11
|
# engines in order. Warns when a fallback would switch from local to
|
|
12
12
|
# remote (network requirement change).
|
|
13
13
|
class FallbackChain
|
|
14
|
+
# @return [Array] Engine names that run locally without API calls.
|
|
14
15
|
LOCAL_ENGINES = ['ollama', 'gpt_neox'].freeze
|
|
15
16
|
|
|
16
17
|
attr_reader :engines, :warnings
|
|
@@ -14,6 +14,7 @@ module RosettAi
|
|
|
14
14
|
# @author hugo
|
|
15
15
|
# @author claude
|
|
16
16
|
class ModelRouter
|
|
17
|
+
# @return [Array] Canonical model tier definitions.
|
|
17
18
|
CANONICAL_TIERS = ['economy', 'standard', 'premium'].freeze
|
|
18
19
|
|
|
19
20
|
# Default model mappings per engine (used when engine manifest unavailable).
|
|
@@ -7,9 +7,11 @@ require 'json'
|
|
|
7
7
|
require 'json_schemer'
|
|
8
8
|
|
|
9
9
|
module RosettAi
|
|
10
|
+
# AI model configuration: routing, cost controls, context windows.
|
|
10
11
|
module AiConfig
|
|
11
12
|
# Validates AI tool configuration files against the JSON Schema.
|
|
12
13
|
class Validator
|
|
14
|
+
# @return [Object] Path to the JSON Schema file used for validation.
|
|
13
15
|
SCHEMA_PATH = File.join(RosettAi.root, 'conf', 'schemas', 'ai_config_schema.json')
|
|
14
16
|
|
|
15
17
|
# Validates AI config data against the schema.
|
|
@@ -15,6 +15,7 @@ module RosettAi
|
|
|
15
15
|
# @author hugo
|
|
16
16
|
# @author claude
|
|
17
17
|
class AttributionCompiler
|
|
18
|
+
# @return [Array] YAML keys that hold file path arrays in authorship config.
|
|
18
19
|
FILES_KEYS = ['files', :files].freeze
|
|
19
20
|
|
|
20
21
|
# @param disclosure_policy [DisclosurePolicy] active disclosure policy
|
|
@@ -21,7 +21,9 @@ module RosettAi
|
|
|
21
21
|
# @author hugo
|
|
22
22
|
# @author claude
|
|
23
23
|
class DisclosurePolicy
|
|
24
|
+
# @return [Array] Supported level values.
|
|
24
25
|
LEVELS = ['none', 'minimal', 'standard', 'full'].freeze
|
|
26
|
+
# @return [String] Default log level.
|
|
25
27
|
DEFAULT_LEVEL = 'standard'
|
|
26
28
|
|
|
27
29
|
attr_reader :level
|
|
@@ -16,6 +16,7 @@ module RosettAi
|
|
|
16
16
|
# @author hugo
|
|
17
17
|
# @author claude
|
|
18
18
|
class TrailerGenerator
|
|
19
|
+
# @return [Object] Git trailer role identifiers for AI attribution.
|
|
19
20
|
TRAILER_ROLES = RosettAi::Provenance::Entry::ALLOWED_ROLES
|
|
20
21
|
|
|
21
22
|
# Generates a trailer string for a given engine.
|
|
@@ -8,9 +8,11 @@ require 'zlib'
|
|
|
8
8
|
require 'fileutils'
|
|
9
9
|
|
|
10
10
|
module RosettAi
|
|
11
|
+
# Configuration backup and restore functionality.
|
|
11
12
|
module Backup
|
|
12
13
|
# Factory and base for compression handlers
|
|
13
14
|
class Compressor
|
|
15
|
+
# @return [Array] Algorithms constant.
|
|
14
16
|
ALGORITHMS = ['zip', 'tar.gz', 'tar.xz'].freeze
|
|
15
17
|
|
|
16
18
|
# Returns a compressor instance for the given algorithm.
|
|
@@ -114,6 +116,7 @@ module RosettAi
|
|
|
114
116
|
|
|
115
117
|
File.open(output_path, 'wb', 0o644) do |file|
|
|
116
118
|
Zlib::GzipWriter.wrap(file, gz_level) do |gz|
|
|
119
|
+
gz.mtime = 0 # Deterministic header for idempotency checking
|
|
117
120
|
Gem::Package::TarWriter.new(gz) do |tar|
|
|
118
121
|
files.each do |entry|
|
|
119
122
|
content = File.read(entry[:full_path])
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# Copyright (C) 2026 Hugo Antonio Sepulveda Manriquez / NeatNerds
|
|
5
5
|
|
|
6
6
|
module RosettAi
|
|
7
|
+
# Compilation pipeline: behaviour YAML to engine-native rules.
|
|
7
8
|
module Compiler
|
|
8
9
|
# Abstract base class for compiler backends.
|
|
9
10
|
#
|
|
@@ -74,6 +75,8 @@ module RosettAi
|
|
|
74
75
|
false
|
|
75
76
|
end
|
|
76
77
|
|
|
78
|
+
# Return the output file extension for this backend.
|
|
79
|
+
# @return [String]
|
|
77
80
|
def file_extension
|
|
78
81
|
case profile.output_format
|
|
79
82
|
when 'json' then '.json'
|
|
@@ -13,6 +13,7 @@ module RosettAi
|
|
|
13
13
|
# source metadata, and the rosett-ai-claude-managed marker for idempotent
|
|
14
14
|
# updates.
|
|
15
15
|
class ClaudeBackend < Backend
|
|
16
|
+
# @return [String] Prefix for generated-file marker comments.
|
|
16
17
|
MARKER_PREFIX = '<!-- rosett-ai-claude-managed'
|
|
17
18
|
|
|
18
19
|
# Renders behaviour data into Claude Code rule format.
|
|
@@ -11,6 +11,7 @@ module RosettAi
|
|
|
11
11
|
# backend to the Claude engine backend. Existing callers that instantiate
|
|
12
12
|
# BehaviourCompiler continue to work without modification.
|
|
13
13
|
class BehaviourCompiler < CompilationPipeline
|
|
14
|
+
# @return [String] Marker string identifying generated files.
|
|
14
15
|
GENERATED_MARKER = '<!-- rosett-ai-claude-managed'
|
|
15
16
|
|
|
16
17
|
# Backward-compatible wrapper that defaults to the Claude engine backend.
|
|
@@ -28,6 +28,7 @@ module RosettAi
|
|
|
28
28
|
# globally would pollute ~/.claude/rules/ with empty files.
|
|
29
29
|
PROJECT_ONLY_CATEGORIES = ['design'].freeze
|
|
30
30
|
|
|
31
|
+
# @return [Array] Allowed compilation scope values.
|
|
31
32
|
VALID_SCOPES = [:global, :project].freeze
|
|
32
33
|
|
|
33
34
|
attr_reader :source_dir, :target_dir, :schema_dir, :backend, :scope,
|
|
@@ -42,13 +43,6 @@ module RosettAi
|
|
|
42
43
|
# (e.g. global conf/ when compiling in project scope). Files from additional
|
|
43
44
|
# sources are included unless overridden by a file with the same basename
|
|
44
45
|
# in the primary source_dir. Empty by default for backward compatibility.
|
|
45
|
-
# @param source_dir [String, Pathname] primary conf/ root
|
|
46
|
-
# @param target_dir [String, Pathname] output directory
|
|
47
|
-
# @param schema_dir [String, Pathname] JSON Schema directory
|
|
48
|
-
# @param backend [RosettAi::Compiler::Backend] rendering backend
|
|
49
|
-
# @param scope [Symbol] compilation scope (:global or :project)
|
|
50
|
-
# @param additional_source_dirs [Array<String, Pathname>] extra source
|
|
51
|
-
# directories (e.g. global conf/ when compiling in project scope)
|
|
52
46
|
def initialize(source_dir:, target_dir:, schema_dir:, backend:, # rubocop:disable Metrics/ParameterLists
|
|
53
47
|
scope: :global, additional_source_dirs: [])
|
|
54
48
|
validate_scope!(scope)
|
|
@@ -15,8 +15,10 @@ module RosettAi
|
|
|
15
15
|
# keys into dotted paths, and generates platform-native locale files
|
|
16
16
|
# for distribution.
|
|
17
17
|
class LocaleCompiler
|
|
18
|
+
# @return [Array] CLDR plural form definitions per locale.
|
|
18
19
|
PLURAL_FORMS = ['zero', 'one', 'two', 'few', 'many', 'other'].freeze
|
|
19
20
|
|
|
21
|
+
# @return [Hash] Gettext Plural-Forms header strings per locale.
|
|
20
22
|
PLURAL_HEADERS = {
|
|
21
23
|
'en' => 'nplurals=2; plural=(n != 1);',
|
|
22
24
|
'fr' => 'nplurals=2; plural=(n > 1);',
|
|
@@ -15,6 +15,7 @@ module RosettAi
|
|
|
15
15
|
# rendering options for a specific AI assistant target. Adding a new
|
|
16
16
|
# target requires only a new YAML file — no code changes.
|
|
17
17
|
class TargetProfile
|
|
18
|
+
# @return [Array] Attribute field names for this data object.
|
|
18
19
|
FIELDS = [
|
|
19
20
|
:name, :description, :backend, :engine_version, :output_format,
|
|
20
21
|
:output_dir, :max_context_window, :rendering
|
|
@@ -81,14 +82,24 @@ module RosettAi
|
|
|
81
82
|
(plugin_targets + engine_targets + legacy_targets).uniq.sort
|
|
82
83
|
end
|
|
83
84
|
|
|
85
|
+
# Return the target profile path for a named engine.
|
|
86
|
+
#
|
|
87
|
+
# @param name [Object] the name
|
|
88
|
+
# @return [Pathname]
|
|
84
89
|
def self.engine_target_path(name)
|
|
85
90
|
RosettAi.root.join('conf', 'engines', name, 'target.yml')
|
|
86
91
|
end
|
|
87
92
|
|
|
93
|
+
# Return the legacy target profile path.
|
|
94
|
+
#
|
|
95
|
+
# @param name [Object] the name
|
|
96
|
+
# @return [Pathname]
|
|
88
97
|
def self.legacy_target_path(name)
|
|
89
98
|
legacy_targets_dir.join("#{name}.yml")
|
|
90
99
|
end
|
|
91
100
|
|
|
101
|
+
# Return the legacy targets directory.
|
|
102
|
+
# @return [Pathname]
|
|
92
103
|
def self.legacy_targets_dir
|
|
93
104
|
RosettAi.root.join('conf', 'targets')
|
|
94
105
|
end
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# Copyright (C) 2026 Hugo Antonio Sepulveda Manriquez / NeatNerds
|
|
5
5
|
|
|
6
6
|
module RosettAi
|
|
7
|
+
# Shell completion script generation.
|
|
7
8
|
module Completion
|
|
8
9
|
# Extracts command metadata from the Thor CLI registry for completion
|
|
9
10
|
# script generation. This is the single source of truth for all
|
|
@@ -12,6 +13,7 @@ module RosettAi
|
|
|
12
13
|
# @author hugo
|
|
13
14
|
# @author claude
|
|
14
15
|
class Generator
|
|
16
|
+
# @return [Array] Shell types supported for completion generation.
|
|
15
17
|
SUPPORTED_SHELLS = ['bash', 'zsh', 'fish'].freeze
|
|
16
18
|
|
|
17
19
|
# @return [Hash] command tree extracted from Thor CLI
|
|
@@ -15,10 +15,12 @@ module RosettAi
|
|
|
15
15
|
# @author hugo
|
|
16
16
|
# @author claude
|
|
17
17
|
class LicenseChecker
|
|
18
|
+
# @return [Array] SPDX identifiers compatible with GPL-3.0-only.
|
|
18
19
|
GPL_COMPATIBLE = [
|
|
19
20
|
'MIT', 'BSD-2-Clause', 'BSD-3-Clause', 'Apache-2.0', 'ISC', 'Zlib', '0BSD', 'Unlicense', 'LGPL-2.0-only', 'LGPL-2.0-or-later', 'LGPL-2.1-only', 'LGPL-2.1-or-later', 'LGPL-3.0-only', 'LGPL-3.0-or-later', 'GPL-2.0-only', 'GPL-2.0-or-later', 'GPL-3.0-only', 'GPL-3.0-or-later', 'Ruby', 'PSF-2.0', 'Artistic-2.0', 'MPL-2.0'
|
|
20
21
|
].freeze
|
|
21
22
|
|
|
23
|
+
# @return [Array] SPDX identifiers incompatible with GPL-3.0-only.
|
|
22
24
|
GPL_INCOMPATIBLE = [
|
|
23
25
|
'AGPL-3.0-only', 'AGPL-3.0-or-later', 'SSPL-1.0', 'BUSL-1.1', 'Proprietary', 'CPAL-1.0', 'EUPL-1.1', 'EUPL-1.2'
|
|
24
26
|
].freeze
|
|
@@ -14,9 +14,12 @@ module RosettAi
|
|
|
14
14
|
# @author hugo
|
|
15
15
|
# @author claude
|
|
16
16
|
class SpdxHeaderChecker
|
|
17
|
+
# @return [Regexp] Regex matching valid SPDX license identifier lines.
|
|
17
18
|
SPDX_PATTERN = /SPDX-License-Identifier:/
|
|
19
|
+
# @return [Integer] Number of lines to scan for SPDX headers.
|
|
18
20
|
HEADER_SCAN_LINES = 10
|
|
19
21
|
|
|
22
|
+
# @return [Array] Glob patterns for source files requiring SPDX headers.
|
|
20
23
|
SOURCE_GLOBS = [
|
|
21
24
|
'**/*.rb',
|
|
22
25
|
'**/*.yml',
|
|
@@ -24,6 +27,7 @@ module RosettAi
|
|
|
24
27
|
'**/*.sh'
|
|
25
28
|
].freeze
|
|
26
29
|
|
|
30
|
+
# @return [Array] Directory names excluded from SPDX header scanning.
|
|
27
31
|
SKIP_DIRS = [
|
|
28
32
|
'vendor',
|
|
29
33
|
'node_modules',
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# Copyright (C) 2026 Hugo Antonio Sepulveda Manriquez / NeatNerds
|
|
5
5
|
|
|
6
6
|
module RosettAi
|
|
7
|
+
# Compliance verification for CRA, license, and SPDX requirements.
|
|
7
8
|
module Comply
|
|
8
9
|
# Orchestrates compliance checks across all registered checkers.
|
|
9
10
|
#
|
|
@@ -13,6 +14,7 @@ module RosettAi
|
|
|
13
14
|
# @author hugo
|
|
14
15
|
# @author claude
|
|
15
16
|
class Runner
|
|
17
|
+
# @return [Hash] Maps checker names to their implementation classes.
|
|
16
18
|
CHECKER_MAP = {
|
|
17
19
|
cra: Checkers::CraChecker,
|
|
18
20
|
license: Checkers::LicenseChecker,
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
# Copyright (C) 2026 Hugo Antonio Sepulveda Manriquez / NeatNerds
|
|
5
5
|
|
|
6
6
|
module RosettAi
|
|
7
|
+
# Multi-source rule composition and merging.
|
|
7
8
|
module Composition
|
|
8
9
|
# Orchestrates behaviour composition: discovers behaviour files,
|
|
9
10
|
# resolves scopes, sorts by priority, detects conflicts and
|
|
@@ -12,6 +12,7 @@ module RosettAi
|
|
|
12
12
|
# composition. Writes the exact composition result so that
|
|
13
13
|
# `--frozen` compilations can reproduce the same output.
|
|
14
14
|
class Lockfile
|
|
15
|
+
# @return [String] Default filename for this artifact.
|
|
15
16
|
FILENAME = '.rosett-ai-lock.yml'
|
|
16
17
|
|
|
17
18
|
# @param root [Pathname] project root directory
|
|
@@ -12,8 +12,13 @@ module RosettAi
|
|
|
12
12
|
# Follows the same interface as SecretResolver (resolve, resolve_all)
|
|
13
13
|
# and uses the same deterministic string parsing — no regex.
|
|
14
14
|
class MaskingSecretResolver
|
|
15
|
+
# @return [String] Placeholder string replacing resolved secrets in output.
|
|
15
16
|
MASKED_VALUE = '***'
|
|
16
17
|
|
|
18
|
+
# Resolve the value for the given key.
|
|
19
|
+
#
|
|
20
|
+
# @param value [Object] the value
|
|
21
|
+
# @return [String]
|
|
17
22
|
def resolve(value)
|
|
18
23
|
return value unless value.is_a?(String)
|
|
19
24
|
return value unless secret_reference?(value)
|
|
@@ -21,6 +26,10 @@ module RosettAi
|
|
|
21
26
|
MASKED_VALUE
|
|
22
27
|
end
|
|
23
28
|
|
|
29
|
+
# Resolve all secret references in the given hash.
|
|
30
|
+
#
|
|
31
|
+
# @param obj [Object] the obj
|
|
32
|
+
# @return [Hash]
|
|
24
33
|
def resolve_all(obj)
|
|
25
34
|
case obj
|
|
26
35
|
when Hash then obj.transform_values { |v| resolve_all(v) }
|
|
@@ -14,11 +14,15 @@ module RosettAi
|
|
|
14
14
|
# - File backend: 0600 permissions, owned by Process.uid, 64 KiB cap
|
|
15
15
|
# - Path backend: rejects ".." traversal
|
|
16
16
|
class SecretResolver
|
|
17
|
+
# @return [String] Prefix marking a secret reference in config.
|
|
17
18
|
SECRET_PREFIX = '${secret:'
|
|
19
|
+
# @return [String] Suffix marking a secret reference in config.
|
|
18
20
|
SECRET_SUFFIX = '}'
|
|
21
|
+
# @return [Array] Supported secrets backend names.
|
|
19
22
|
VALID_BACKENDS = ['env', 'file', 'path'].freeze
|
|
20
23
|
MAX_FILE_SIZE = 65_536 # 64 KiB
|
|
21
24
|
|
|
25
|
+
# SecretError implementation.
|
|
22
26
|
class SecretError < RosettAi::Error; end
|
|
23
27
|
|
|
24
28
|
# Resolve a single secret reference string.
|
|
@@ -10,9 +10,13 @@ module RosettAi
|
|
|
10
10
|
# Manages hierarchical configuration for Rosett-AI
|
|
11
11
|
# Supports global -> group -> project configuration inheritance
|
|
12
12
|
class Configuration
|
|
13
|
+
# @return [String] Filename for the main settings file.
|
|
13
14
|
SETTINGS_FILE = 'settings.json'
|
|
15
|
+
# @return [String] Filename for the local settings override file.
|
|
14
16
|
LOCAL_SETTINGS_FILE = 'settings.local.json'
|
|
17
|
+
# @return [String] Relative path to the behaviour configuration directory.
|
|
15
18
|
BEHAVIOUR_DIR = 'conf/behaviour'
|
|
19
|
+
# @return [String] Relative path to the JSON Schema directory.
|
|
16
20
|
SCHEMA_DIR = 'conf/schemas'
|
|
17
21
|
|
|
18
22
|
attr_reader :root_path
|
|
@@ -12,6 +12,7 @@ module RosettAi
|
|
|
12
12
|
# License key is sent as Bearer token. All requests use HTTPS.
|
|
13
13
|
# Gracefully handles offline scenarios.
|
|
14
14
|
class ContentClient
|
|
15
|
+
# @return [String] Default base URL for API requests.
|
|
15
16
|
DEFAULT_BASE_URL = 'https://content.neatnerds.be/v1/'
|
|
16
17
|
|
|
17
18
|
def initialize(license_key:, base_url: DEFAULT_BASE_URL)
|
|
@@ -22,6 +23,10 @@ module RosettAi
|
|
|
22
23
|
end
|
|
23
24
|
end
|
|
24
25
|
|
|
26
|
+
# Retrieve the content catalog from the remote source.
|
|
27
|
+
#
|
|
28
|
+
# @param tier [Object] the tier
|
|
29
|
+
# @return [Hash]
|
|
25
30
|
def catalog(tier:)
|
|
26
31
|
response = @connection.get('packs', tier: tier)
|
|
27
32
|
raise RosettAi::ContentError, "Server error: #{response.status}" unless response.success?
|
|
@@ -31,6 +36,11 @@ module RosettAi
|
|
|
31
36
|
raise RosettAi::ContentError, "Cannot reach content server: #{e.message}"
|
|
32
37
|
end
|
|
33
38
|
|
|
39
|
+
# Download a content pack from the remote source.
|
|
40
|
+
#
|
|
41
|
+
# @param pack_name [Object] the pack name
|
|
42
|
+
# @param version [Object] the version
|
|
43
|
+
# @return [String]
|
|
34
44
|
def download(pack_name, version:)
|
|
35
45
|
response = @connection.get("packs/#{pack_name}/#{version}/download")
|
|
36
46
|
raise RosettAi::ContentError, "Download failed: #{response.status}" unless response.success?
|
|
@@ -40,6 +50,11 @@ module RosettAi
|
|
|
40
50
|
raise RosettAi::ContentError, "Cannot reach content server: #{e.message}"
|
|
41
51
|
end
|
|
42
52
|
|
|
53
|
+
# Download the cryptographic signature for verification.
|
|
54
|
+
#
|
|
55
|
+
# @param pack_name [Object] the pack name
|
|
56
|
+
# @param version [Object] the version
|
|
57
|
+
# @return [String]
|
|
43
58
|
def download_signature(pack_name, version:)
|
|
44
59
|
response = @connection.get("packs/#{pack_name}/#{version}/signature")
|
|
45
60
|
raise RosettAi::ContentError, "Signature download failed: #{response.status}" unless response.success?
|
|
@@ -19,6 +19,7 @@ module RosettAi
|
|
|
19
19
|
# - Atomic install: extract to temp dir, validate manifest, then move
|
|
20
20
|
# - Uses same PUBLIC_KEY_HEX as LicenseKey for verification
|
|
21
21
|
class PackInstaller
|
|
22
|
+
# @return [Object] Directory permission mode for secure directories.
|
|
22
23
|
SAFE_DIR_MODE = 0o700
|
|
23
24
|
|
|
24
25
|
# Verifies signature and installs a content pack atomically.
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
require 'json_schemer'
|
|
7
7
|
|
|
8
8
|
module RosettAi
|
|
9
|
+
# Content pack distribution and installation.
|
|
9
10
|
module Content
|
|
10
11
|
# Loads, validates, and provides access to content pack manifest data.
|
|
11
12
|
#
|
|
@@ -19,18 +20,38 @@ module RosettAi
|
|
|
19
20
|
validate!
|
|
20
21
|
end
|
|
21
22
|
|
|
23
|
+
# Load a pack manifest from a YAML file.
|
|
24
|
+
#
|
|
25
|
+
# @param path [Object] the path
|
|
26
|
+
# @return [PackManifest]
|
|
22
27
|
def self.from_file(path)
|
|
23
28
|
data = RosettAi::YamlLoader.load_file(path)
|
|
24
29
|
new(data)
|
|
25
30
|
end
|
|
26
31
|
|
|
32
|
+
# Return the pack name.
|
|
33
|
+
# @return [String]
|
|
27
34
|
def name = data['name']
|
|
35
|
+
# Return the version string.
|
|
36
|
+
# @return [String]
|
|
28
37
|
def version = data['version']
|
|
38
|
+
# Return the minimum tier required for this pack.
|
|
39
|
+
# @return [String]
|
|
29
40
|
def tier_required = data['tier_required']
|
|
41
|
+
# Return the human-readable description.
|
|
42
|
+
# @return [String]
|
|
30
43
|
def description = data['description']
|
|
44
|
+
# Return the author name.
|
|
45
|
+
# @return [String]
|
|
31
46
|
def author = data['author']
|
|
47
|
+
# Return the manifest contents hash.
|
|
48
|
+
# @return [Hash]
|
|
32
49
|
def contents = data['contents'] || {}
|
|
50
|
+
# Return the list of behaviour file paths.
|
|
51
|
+
# @return [Array<String>]
|
|
33
52
|
def behaviour_files = contents['behaviours'] || []
|
|
53
|
+
# Return the list of design file paths.
|
|
54
|
+
# @return [Array<String>]
|
|
34
55
|
def design_files = contents['designs'] || []
|
|
35
56
|
|
|
36
57
|
private
|
|
@@ -18,12 +18,14 @@ module RosettAi
|
|
|
18
18
|
# 6. DISPLAY set, WAYLAND_DISPLAY unset → :x11
|
|
19
19
|
# 7. else → :unknown
|
|
20
20
|
module CompositorDetector
|
|
21
|
+
# @return [Array] Methods for detecting the active compositor.
|
|
21
22
|
COMPOSITOR_CHECKS = [
|
|
22
23
|
{ env: 'HYPRLAND_INSTANCE_SIGNATURE', type: :hyprland },
|
|
23
24
|
{ env: 'SWAYSOCK', type: :sway },
|
|
24
25
|
{ env: 'I3SOCK', type: :i3 }
|
|
25
26
|
].freeze
|
|
26
27
|
|
|
28
|
+
# @return [Hash] D-Bus service names for compositor detection.
|
|
27
29
|
DBUS_NAMES = {
|
|
28
30
|
'org.gnome.Shell' => :gnome,
|
|
29
31
|
'org.kde.KWin' => :kwin
|
|
@@ -15,6 +15,7 @@ module RosettAi
|
|
|
15
15
|
# For GNOME >= 41, Eval is removed; falls back to xdotool + xprop.
|
|
16
16
|
class GnomeAdapter < Base
|
|
17
17
|
POLL_INTERVAL = 0.5 # seconds
|
|
18
|
+
# @return [Integer] GNOME version that removed Eval D-Bus interface.
|
|
18
19
|
GNOME_EVAL_REMOVED_VERSION = 41
|
|
19
20
|
|
|
20
21
|
def initialize
|
|
@@ -26,6 +27,8 @@ module RosettAi
|
|
|
26
27
|
@use_xdotool = false
|
|
27
28
|
end
|
|
28
29
|
|
|
30
|
+
# Start the adapter or service.
|
|
31
|
+
# @return [void]
|
|
29
32
|
def start
|
|
30
33
|
return if @running
|
|
31
34
|
|
|
@@ -38,6 +41,8 @@ module RosettAi
|
|
|
38
41
|
@running = false
|
|
39
42
|
end
|
|
40
43
|
|
|
44
|
+
# Stop the adapter or service.
|
|
45
|
+
# @return [void]
|
|
41
46
|
def stop
|
|
42
47
|
super
|
|
43
48
|
@thread&.kill
|
|
@@ -17,6 +17,8 @@ module RosettAi
|
|
|
17
17
|
@thread = nil
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Start the adapter or service.
|
|
21
|
+
# @return [void]
|
|
20
22
|
def start
|
|
21
23
|
return if @running
|
|
22
24
|
|
|
@@ -34,6 +36,8 @@ module RosettAi
|
|
|
34
36
|
@running = false
|
|
35
37
|
end
|
|
36
38
|
|
|
39
|
+
# Stop the adapter or service.
|
|
40
|
+
# @return [void]
|
|
37
41
|
def stop
|
|
38
42
|
super
|
|
39
43
|
@thread&.kill
|
|
@@ -17,6 +17,8 @@ module RosettAi
|
|
|
17
17
|
@thread = nil
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
+
# Start the adapter or service.
|
|
21
|
+
# @return [void]
|
|
20
22
|
def start
|
|
21
23
|
return if @running
|
|
22
24
|
|
|
@@ -33,6 +35,8 @@ module RosettAi
|
|
|
33
35
|
@running = false
|
|
34
36
|
end
|
|
35
37
|
|
|
38
|
+
# Stop the adapter or service.
|
|
39
|
+
# @return [void]
|
|
36
40
|
def stop
|
|
37
41
|
super
|
|
38
42
|
@thread&.kill
|
|
@@ -20,6 +20,8 @@ module RosettAi
|
|
|
20
20
|
@thread = nil
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
# Start the adapter or service.
|
|
24
|
+
# @return [void]
|
|
23
25
|
def start
|
|
24
26
|
return if @running
|
|
25
27
|
|
|
@@ -32,6 +34,8 @@ module RosettAi
|
|
|
32
34
|
@running = false
|
|
33
35
|
end
|
|
34
36
|
|
|
37
|
+
# Stop the adapter or service.
|
|
38
|
+
# @return [void]
|
|
35
39
|
def stop
|
|
36
40
|
super
|
|
37
41
|
@main_loop&.quit
|
|
@@ -20,6 +20,8 @@ module RosettAi
|
|
|
20
20
|
@last_window_id = nil
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
+
# Start the adapter or service.
|
|
24
|
+
# @return [void]
|
|
23
25
|
def start
|
|
24
26
|
return if @running
|
|
25
27
|
return unless xprop_available?
|
|
@@ -28,6 +30,8 @@ module RosettAi
|
|
|
28
30
|
@thread = Thread.new { run_poll_loop }
|
|
29
31
|
end
|
|
30
32
|
|
|
33
|
+
# Stop the adapter or service.
|
|
34
|
+
# @return [void]
|
|
31
35
|
def stop
|
|
32
36
|
super
|
|
33
37
|
@thread&.kill
|