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,148 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: structured_logging
|
|
3
|
+
domain: operations
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 3
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-03-16"
|
|
9
|
+
modified_at: "2026-03-16"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- architecture
|
|
13
|
+
- security
|
|
14
|
+
- error_handling
|
|
15
|
+
- monitoring_observability
|
|
16
|
+
#
|
|
17
|
+
intent: |
|
|
18
|
+
Enhance the existing rosett-ai logger with correlation IDs and structured JSON
|
|
19
|
+
output for cross-command tracing and debugging. When a user reports a problem,
|
|
20
|
+
the support workflow requires correlating log entries from a single CLI
|
|
21
|
+
invocation — which is impossible with unstructured text logs that lack a
|
|
22
|
+
shared identifier. This design adds a per-invocation correlation ID (UUID v4)
|
|
23
|
+
to every log entry, enables JSON-formatted output for machine parsing, and
|
|
24
|
+
provides configurable log levels that align with the telemetry system.
|
|
25
|
+
|
|
26
|
+
Structured logging complements telemetry (monitoring_observability.yml):
|
|
27
|
+
telemetry captures high-level command events (start, end, duration) for
|
|
28
|
+
operational metrics, while structured logging captures detailed diagnostic
|
|
29
|
+
messages (debug, info, warn, error) for troubleshooting. Both share the
|
|
30
|
+
correlation ID so that telemetry events and log entries from the same
|
|
31
|
+
invocation can be joined. Error handling (error_handling.yml) governs
|
|
32
|
+
user-facing error display; structured logging governs developer-facing
|
|
33
|
+
diagnostic output.
|
|
34
|
+
#
|
|
35
|
+
constraints:
|
|
36
|
+
- "Each CLI invocation generates a unique correlation ID (UUID v4) at startup"
|
|
37
|
+
- "The correlation ID is included in every log entry and every telemetry event"
|
|
38
|
+
- "Log format is controlled via RAI_LOG_FORMAT={text,json} (default text)"
|
|
39
|
+
- "JSON log format produces one JSON object per line (JSON Lines compatible)"
|
|
40
|
+
- "Text log format produces human-readable output: [LEVEL] [correlation_id] message"
|
|
41
|
+
- "Log level is controlled via RAI_LOG_LEVEL={DEBUG,INFO,WARN,ERROR}
|
|
42
|
+
(default WARN)"
|
|
43
|
+
- "Log output goes to stderr — never stdout (stdout is for command output)"
|
|
44
|
+
- "Structured logger must be a drop-in replacement for the existing
|
|
45
|
+
Ruby Logger interface (respond_to debug, info, warn, error, fatal)"
|
|
46
|
+
- "No new runtime dependencies — uses stdlib Logger, JSON, SecureRandom"
|
|
47
|
+
- "Log entries must never contain secrets, API keys, or file contents
|
|
48
|
+
(same constraint as telemetry)"
|
|
49
|
+
- "Correlation ID is accessible via RosettAi::StructuredLogger.correlation_id
|
|
50
|
+
for passing to telemetry and error handlers"
|
|
51
|
+
- "Logger must be thread-safe (Mutex-protected writes)"
|
|
52
|
+
- "This design governs diagnostic logging (developer-facing debug output).
|
|
53
|
+
Runtime telemetry is governed by monitoring_observability.yml. User-facing
|
|
54
|
+
error display is governed by error_handling.yml"
|
|
55
|
+
#
|
|
56
|
+
acceptance_criteria:
|
|
57
|
+
- "RosettAi::StructuredLogger class exists and implements Ruby Logger interface"
|
|
58
|
+
- "Every log entry includes a correlation_id field (UUID v4)"
|
|
59
|
+
- "RAI_LOG_FORMAT=json produces JSON Lines output on stderr"
|
|
60
|
+
- "RAI_LOG_FORMAT=text produces [LEVEL] [correlation_id] message on stderr"
|
|
61
|
+
- "RAI_LOG_LEVEL filters entries below the configured severity"
|
|
62
|
+
- "Correlation ID is generated once per CLI invocation and reused for all
|
|
63
|
+
log entries"
|
|
64
|
+
- "RosettAi::StructuredLogger.correlation_id returns the current correlation ID"
|
|
65
|
+
- "Telemetry events include the same correlation_id as log entries"
|
|
66
|
+
- "Structured logger is wired as the default logger in RosettAi module"
|
|
67
|
+
- "Log entries include timestamp (ISO 8601), level, correlation_id, message"
|
|
68
|
+
- "JSON log entries additionally include pid, command (when available)"
|
|
69
|
+
- "No secrets or file contents appear in log output"
|
|
70
|
+
- "Logger is thread-safe under concurrent writes"
|
|
71
|
+
#
|
|
72
|
+
examples:
|
|
73
|
+
- scenario: "Developer debugs a compile failure with JSON logs"
|
|
74
|
+
expected: |
|
|
75
|
+
RAI_LOG_LEVEL=DEBUG RAI_LOG_FORMAT=json bin/raictl compile
|
|
76
|
+
stderr output (one JSON object per line):
|
|
77
|
+
{"timestamp":"2026-03-16T10:00:00.123Z","level":"debug","correlation_id":"a1b2c3d4-...","pid":12345,"command":"compile","message":"Loading behaviour files from conf/behaviour/"}
|
|
78
|
+
{"timestamp":"2026-03-16T10:00:00.145Z","level":"debug","correlation_id":"a1b2c3d4-...","pid":12345,"command":"compile","message":"Validating 8 behaviour files"}
|
|
79
|
+
{"timestamp":"2026-03-16T10:00:00.189Z","level":"error","correlation_id":"a1b2c3d4-...","pid":12345,"command":"compile","message":"Validation failed: conf/behaviour/broken.yml:14 — missing required field 'rules'"}
|
|
80
|
+
not: |
|
|
81
|
+
Log entries lack correlation_id. JSON output goes to stdout and
|
|
82
|
+
corrupts piped command output. Debug messages appear at default log level.
|
|
83
|
+
- scenario: "User runs rosett-ai with default settings (no log env vars)"
|
|
84
|
+
expected: |
|
|
85
|
+
Only WARN and ERROR messages appear on stderr in text format.
|
|
86
|
+
No DEBUG or INFO noise. Correlation ID is still generated internally
|
|
87
|
+
but not visible unless log level is lowered.
|
|
88
|
+
not: |
|
|
89
|
+
DEBUG output floods stderr by default. No log output at all even
|
|
90
|
+
for warnings.
|
|
91
|
+
- scenario: "Support request includes correlation ID for cross-referencing"
|
|
92
|
+
expected: |
|
|
93
|
+
User provides correlation_id from error output. Developer searches
|
|
94
|
+
telemetry logs and structured logs using that ID to find all events
|
|
95
|
+
from the same CLI invocation.
|
|
96
|
+
not: |
|
|
97
|
+
Correlation ID is different between log entries and telemetry events
|
|
98
|
+
from the same invocation.
|
|
99
|
+
- scenario: "Multiple CLI invocations run in parallel (e.g., CI)"
|
|
100
|
+
expected: |
|
|
101
|
+
Each invocation has a unique correlation ID. Log entries from
|
|
102
|
+
different invocations can be separated by filtering on correlation_id.
|
|
103
|
+
Thread-safe writes prevent interleaved JSON objects.
|
|
104
|
+
not: |
|
|
105
|
+
Same correlation ID used across invocations. JSON objects are
|
|
106
|
+
interleaved mid-line due to race conditions.
|
|
107
|
+
#
|
|
108
|
+
anti_patterns:
|
|
109
|
+
- "Using puts or $stderr.puts instead of the structured logger"
|
|
110
|
+
- "Logging file contents or secrets (even at DEBUG level)"
|
|
111
|
+
- "Generating a new correlation ID per log entry instead of per invocation"
|
|
112
|
+
- "Sending logs to stdout (reserved for command output)"
|
|
113
|
+
- "Different correlation IDs for log entries and telemetry events"
|
|
114
|
+
- "Requiring an external logging gem (use stdlib Logger)"
|
|
115
|
+
- "Eagerly formatting log messages when the level is filtered out"
|
|
116
|
+
- "Making log format or level configurable via config files (env vars only)"
|
|
117
|
+
#
|
|
118
|
+
gui_notes: |
|
|
119
|
+
Document interactions (cross-references):
|
|
120
|
+
|
|
121
|
+
1. monitoring_observability.yml: telemetry events include the same
|
|
122
|
+
correlation_id as log entries for cross-referencing.
|
|
123
|
+
|
|
124
|
+
2. error_handling.yml: error handler can include correlation_id in
|
|
125
|
+
user-facing error output for support reference.
|
|
126
|
+
|
|
127
|
+
3. security.yml: log entries must never contain secrets, API keys, or PII.
|
|
128
|
+
|
|
129
|
+
4. architecture.yml: structured logger replaces the simple logger in
|
|
130
|
+
RosettAi module as a drop-in compatible upgrade.
|
|
131
|
+
|
|
132
|
+
Module structure:
|
|
133
|
+
|
|
134
|
+
lib/rosett_ai/structured_logger.rb — Logger subclass with correlation ID,
|
|
135
|
+
JSON/text formatters, level filtering
|
|
136
|
+
#
|
|
137
|
+
preferences:
|
|
138
|
+
language: ruby
|
|
139
|
+
patterns:
|
|
140
|
+
- "Ruby Logger interface compatibility"
|
|
141
|
+
- "Per-invocation correlation ID (UUID v4)"
|
|
142
|
+
- "JSON Lines structured output"
|
|
143
|
+
- "Mutex thread-safety for writes"
|
|
144
|
+
- "Lazy message formatting (block form)"
|
|
145
|
+
testing: rspec with correlation ID propagation, JSON output parsing,
|
|
146
|
+
level filtering, thread-safety under concurrent writes, and
|
|
147
|
+
telemetry integration
|
|
148
|
+
gems: []
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: styles
|
|
3
|
+
domain: styles
|
|
4
|
+
version: 1.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 1
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-02-18"
|
|
9
|
+
modified_at: "2026-03-17"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- security
|
|
13
|
+
- testing
|
|
14
|
+
|
|
15
|
+
intent: |
|
|
16
|
+
Codify all code conventions, linting rules, YAML formatting, documentation
|
|
17
|
+
structure, and commit message standards into a single authoritative design
|
|
18
|
+
document. Style enforcement eliminates bikeshedding, ensures consistency
|
|
19
|
+
across human and AI contributors, and makes code review focus on logic
|
|
20
|
+
rather than formatting. This depends on testing because the enforcement
|
|
21
|
+
tools (rubocop, yamllint, reek, mdl, overcommit) must be present and
|
|
22
|
+
configured before style gates can be enforced. Style rules are enforced
|
|
23
|
+
automatically via pre-commit hooks (overcommit) and CI pipeline — they
|
|
24
|
+
are not optional guidelines.
|
|
25
|
+
|
|
26
|
+
constraints:
|
|
27
|
+
- All Ruby code must pass RuboCop with zero violations (no rubocop:disable without justification)
|
|
28
|
+
- All YAML files must pass yamllint with the project .yamllint configuration
|
|
29
|
+
- All Ruby code must pass Reek with zero violations above configured thresholds
|
|
30
|
+
- All JSON files must be syntactically valid (validated by overcommit JsonSyntax hook)
|
|
31
|
+
- All Markdown documentation must pass mdl (markdownlint) with project rules
|
|
32
|
+
- "Commit messages must follow Conventional Commits format: type(scope): description"
|
|
33
|
+
- Frozen string literal comment is required on every Ruby file
|
|
34
|
+
- Single quotes for strings unless interpolation is needed
|
|
35
|
+
- 2-space indentation for Ruby, YAML, and JSON — no tabs except Makefiles
|
|
36
|
+
- Maximum line length is 120 characters for Ruby, 240 for YAML (warning)
|
|
37
|
+
- RSpec examples follow behaviour-driven descriptions (what it does, not how)
|
|
38
|
+
- No trailing whitespace (except Markdown where it may be intentional)
|
|
39
|
+
- Structural duplication detected by Flay must stay below threshold (mass >= 16)
|
|
40
|
+
- Cyclomatic complexity enforced by RuboCop Metrics cops (AbcSize <= 25, CyclomaticComplexity <= 10, PerceivedComplexity <= 10)
|
|
41
|
+
|
|
42
|
+
acceptance_criteria:
|
|
43
|
+
- .rubocop.yml exists with all project conventions and zero violations on main
|
|
44
|
+
- .yamllint exists with project YAML formatting rules
|
|
45
|
+
- .reek.yml exists with code smell detection thresholds
|
|
46
|
+
- .overcommit.yml enforces rubocop, yamllint, reek, json, bundler-audit, and trailing whitespace on pre-commit
|
|
47
|
+
- Commit message format is enforced by overcommit CommitMsg hooks (Conventional Commits pattern)
|
|
48
|
+
- mdl (markdownlint) is configured and enforced for all .md files in doc/
|
|
49
|
+
- bundle exec rubocop exits zero on the entire codebase
|
|
50
|
+
- bundle exec reek exits zero on the entire codebase
|
|
51
|
+
- yamllint exits zero on all YAML files outside vendor/ and tmp/
|
|
52
|
+
- Flay is configured with mass threshold 16 and enforced via overcommit pre-commit hook; cyclomatic complexity enforced by RuboCop Metrics cops (AbcSize <= 25, CyclomaticComplexity <= 10, PerceivedComplexity <= 10)
|
|
53
|
+
|
|
54
|
+
examples:
|
|
55
|
+
- scenario: "AI generates a new Ruby class with double-quoted strings"
|
|
56
|
+
expected: |
|
|
57
|
+
Pre-commit hook catches the violation: RuboCop Style/StringLiterals
|
|
58
|
+
flags double quotes. Developer (or AI) fixes to single quotes. Commit
|
|
59
|
+
proceeds after fix.
|
|
60
|
+
not: "Code merges with inconsistent quoting style."
|
|
61
|
+
- scenario: "Developer writes a commit message 'fixed the bug'"
|
|
62
|
+
expected: |
|
|
63
|
+
Overcommit CommitMsg hook rejects: 'Commit message must follow
|
|
64
|
+
Conventional Commits format: <type>(<scope>): <description>'.
|
|
65
|
+
Developer rewrites as 'fix(compiler): handle nil input in validate method'.
|
|
66
|
+
not: "Freeform commit messages merge without convention."
|
|
67
|
+
- scenario: "New YAML configuration file uses 4-space indentation"
|
|
68
|
+
expected: |
|
|
69
|
+
yamllint flags indentation violation. Pre-commit hook blocks commit.
|
|
70
|
+
Developer fixes to 2-space indentation per project convention.
|
|
71
|
+
not: "Mixed indentation styles across YAML files."
|
|
72
|
+
- scenario: "New method has cyclomatic complexity of 15"
|
|
73
|
+
expected: |
|
|
74
|
+
RuboCop Metrics/CyclomaticComplexity flags the method above threshold
|
|
75
|
+
(max 10). Reek flags complexity smells. Developer refactors into smaller
|
|
76
|
+
methods. If threshold exception is truly justified, it is added to
|
|
77
|
+
.reek.yml or .rubocop.yml with a comment explaining why.
|
|
78
|
+
not: "Complex code merges without review. Thresholds silently increased."
|
|
79
|
+
- scenario: "Documentation in doc/ uses inconsistent heading styles"
|
|
80
|
+
expected: |
|
|
81
|
+
mdl flags heading style violation (e.g., mixed ATX and setext headings).
|
|
82
|
+
CI lint stage blocks merge. Author fixes to consistent ATX style (# headings).
|
|
83
|
+
not: "Documentation has mixed formatting that degrades readability."
|
|
84
|
+
|
|
85
|
+
anti_patterns:
|
|
86
|
+
- Disabling linting rules inline without a justification comment
|
|
87
|
+
- Blanket rubocop:disable at file level instead of fixing the issue
|
|
88
|
+
- Excluding entire directories from style checks without justification
|
|
89
|
+
- Treating style warnings as non-blocking (all style violations block in this project)
|
|
90
|
+
- Inconsistent configuration between local hooks and CI (they must match)
|
|
91
|
+
- Skipping pre-commit hooks with --no-verify
|
|
92
|
+
- Adding Reek exclusions without first attempting to refactor the code smell
|
|
93
|
+
- Commit messages that bypass Conventional Commits format
|
|
94
|
+
|
|
95
|
+
preferences:
|
|
96
|
+
language: ruby
|
|
97
|
+
gems:
|
|
98
|
+
- rubocop
|
|
99
|
+
- rubocop-performance
|
|
100
|
+
- rubocop-rspec
|
|
101
|
+
- rubocop-rake
|
|
102
|
+
- reek
|
|
103
|
+
- flay
|
|
104
|
+
- overcommit
|
|
105
|
+
tools:
|
|
106
|
+
- yamllint
|
|
107
|
+
- mdl
|
|
108
|
+
patterns:
|
|
109
|
+
- convention_over_configuration
|
|
110
|
+
- automated_enforcement_over_manual_review
|
|
111
|
+
- zero_tolerance_for_style_violations
|
|
112
|
+
conventions:
|
|
113
|
+
string_literals: single_quotes
|
|
114
|
+
frozen_string_literal: always
|
|
115
|
+
indentation: 2_spaces
|
|
116
|
+
line_length_ruby: 120
|
|
117
|
+
line_length_yaml: 240
|
|
118
|
+
hash_syntax: ruby19
|
|
119
|
+
array_style: brackets
|
|
120
|
+
symbol_array_style: brackets
|
|
121
|
+
trailing_comma: no_comma
|
|
122
|
+
class_children: nested
|
|
123
|
+
commit_format: conventional_commits
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test_peer_review
|
|
3
|
+
domain: testing
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 1
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-03-14"
|
|
9
|
+
modified_at: "2026-03-15"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- testing
|
|
13
|
+
- security
|
|
14
|
+
|
|
15
|
+
intent: |
|
|
16
|
+
Establish a structured, questionnaire-based peer review process for all
|
|
17
|
+
test suites across the Rosett-AI ecosystem (core + 11 engine plugins). This
|
|
18
|
+
addresses the fundamental trust problem: when AI generates both code and
|
|
19
|
+
tests, a human must independently verify that tests reflect actual
|
|
20
|
+
requirements, not just mirror implementation details.
|
|
21
|
+
|
|
22
|
+
The process produces a signed-off test registry where every spec file has
|
|
23
|
+
been reviewed, its intent documented, and its correctness confirmed by the
|
|
24
|
+
human maintainer. This creates an auditable trail of test quality that is
|
|
25
|
+
independent of the AI that wrote the tests.
|
|
26
|
+
|
|
27
|
+
The review follows a questionnaire format (similar to the Q1-Q5 design
|
|
28
|
+
review process) where each test file is examined through structured
|
|
29
|
+
questions that expose gaps, redundancy, incorrect assumptions, and
|
|
30
|
+
missing edge cases. The human reviewer signs off on each file, creating
|
|
31
|
+
a permanent record.
|
|
32
|
+
|
|
33
|
+
constraints:
|
|
34
|
+
- Every spec file must be reviewed before v1.0.0 release
|
|
35
|
+
- Each review must be signed off by the human maintainer (hugo)
|
|
36
|
+
- The review questionnaire must be reproducible and version-controlled
|
|
37
|
+
- Reviews must cover intent, correctness, completeness, and independence
|
|
38
|
+
- AI cannot sign off on its own tests — only the human reviewer can
|
|
39
|
+
- Review findings that require code changes must be tracked as issues
|
|
40
|
+
- The review registry must be machine-readable (YAML) for automation
|
|
41
|
+
- Reviews are per-file, not per-example, to keep the process practical
|
|
42
|
+
|
|
43
|
+
acceptance_criteria:
|
|
44
|
+
- A review questionnaire template exists with numbered questions (Q1-Qn)
|
|
45
|
+
- A review registry YAML file tracks status per spec file per repo
|
|
46
|
+
- Each registry entry includes reviewer, date, verdict, and notes
|
|
47
|
+
- The questionnaire covers at minimum these dimensions — intent clarity, assertion quality, edge case coverage, mock appropriateness, independence from implementation, mutation resilience, naming quality, fixture quality
|
|
48
|
+
- A CLI command or script can report review progress across all repos
|
|
49
|
+
- All 174 spec files (141 core + 33 engine) have been reviewed
|
|
50
|
+
- All critical findings have been resolved before sign-off
|
|
51
|
+
- The review process is documented in doc/TEST_PEER_REVIEW.md
|
|
52
|
+
|
|
53
|
+
examples:
|
|
54
|
+
- scenario: "Reviewing spec/rosett_ai/compiler/behaviour_compiler_spec.rb"
|
|
55
|
+
expected: |
|
|
56
|
+
Reviewer reads the file, answers each questionnaire question,
|
|
57
|
+
records findings in the registry. If Q3 (edge cases) reveals
|
|
58
|
+
missing nil input handling, this is recorded as a finding with
|
|
59
|
+
severity. The file is not signed off until the finding is resolved.
|
|
60
|
+
Once all questions are answered satisfactorily, the reviewer signs
|
|
61
|
+
off with date and verdict.
|
|
62
|
+
|
|
63
|
+
- scenario: "Reviewing spec/rosett_ai_engine/acme/backend_spec.rb"
|
|
64
|
+
expected: |
|
|
65
|
+
Reviewer examines engine contract tests. Q5 (implementation
|
|
66
|
+
independence) reveals that a test checks internal hash structure
|
|
67
|
+
rather than observable behaviour. This is flagged as a finding.
|
|
68
|
+
After the test is rewritten to check only the public interface,
|
|
69
|
+
the reviewer re-examines and signs off.
|
|
70
|
+
|
|
71
|
+
- scenario: "Generating progress report"
|
|
72
|
+
expected: |
|
|
73
|
+
CLI command reads all registry files and outputs a summary table:
|
|
74
|
+
Total files: 174, Reviewed: 87, Signed off: 72, Pending fixes: 15,
|
|
75
|
+
Not started: 87. Per-repo breakdown shows completion percentage.
|
|
76
|
+
|
|
77
|
+
anti_patterns:
|
|
78
|
+
- AI signing off on its own tests (only human reviewer can sign off)
|
|
79
|
+
- Reviewing tests without reading the implementation under test
|
|
80
|
+
- Batch sign-off without individual file assessment
|
|
81
|
+
- Skipping edge case review for seemingly simple specs
|
|
82
|
+
- Using test count as a proxy for test quality
|
|
83
|
+
- Approving tests that mirror implementation details
|
|
84
|
+
|
|
85
|
+
preferences:
|
|
86
|
+
questionnaire_format: "Numbered Q1-Q10 with verdict per question (pass/concern/fail)"
|
|
87
|
+
registry_format: "One YAML file per repo in conf/review/, keyed by spec file path"
|
|
88
|
+
review_workflow: "AI summary → human Q&A → registry → fix → sign-off"
|
|
89
|
+
batch_order: "Foundation → compiler → security → CLI → modules → UI → utils → engines"
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing
|
|
3
|
+
domain: testing
|
|
4
|
+
version: 0.3.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 1
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-02-18"
|
|
9
|
+
modified_at: "2026-03-17"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- security
|
|
13
|
+
|
|
14
|
+
intent: |
|
|
15
|
+
Establish a testing strategy that validates both code correctness AND test
|
|
16
|
+
quality, specifically addressing the circular trust problem of AI-generated
|
|
17
|
+
tests. When AI writes both code and tests, the test suite can be perfectly
|
|
18
|
+
consistent yet meaningless. Mutation testing (Mutant) acts as an independent
|
|
19
|
+
third-party validator that mechanically verifies tests catch real bugs,
|
|
20
|
+
regardless of who wrote them. This must be in place before feature development
|
|
21
|
+
begins so all future code is validated from day one.
|
|
22
|
+
|
|
23
|
+
constraints:
|
|
24
|
+
- Mutation testing (mutant-rspec) must be integrated before feature development begins
|
|
25
|
+
- All AI-generated tests must pass the 11-point review checklist before acceptance
|
|
26
|
+
- Unit tests must use concrete expected values, never computed expectations that mirror implementation
|
|
27
|
+
- Mocking is only permitted at boundaries (file system, network, shell commands)
|
|
28
|
+
- The unit under test must never be mocked
|
|
29
|
+
- Every public method must have tests for happy path, edge cases (empty, nil, boundary), negative cases, and error cases
|
|
30
|
+
- Test descriptions must be behaviour-focused, not implementation-focused
|
|
31
|
+
- "SimpleCov minimum line coverage is 88% overall and 25% per file (target: 90% line, 80% per-file)"
|
|
32
|
+
- Mutation score must meet threshold before code can merge (70% initial, 85% established, 95% critical paths)
|
|
33
|
+
- CI must run rspec on every push and mutant on merge requests
|
|
34
|
+
- Property-based testing must be used for cryptographic/security-critical code (licensing validation)
|
|
35
|
+
- Snapshot testing must be used for compiled output regression — baseline snapshots stored in spec/fixtures/snapshots/
|
|
36
|
+
- Snapshot files must be committed to git and reviewed in merge requests (not auto-updated)
|
|
37
|
+
- Property-based testing uses Rantly gem for random input generation
|
|
38
|
+
- Rantly generators for domain objects are defined in spec/support/rantly_generators.rb
|
|
39
|
+
|
|
40
|
+
acceptance_criteria:
|
|
41
|
+
- mutant-rspec is installed and configured with .mutant.yml
|
|
42
|
+
- SimpleCov is configured with minimum thresholds that block CI on violation
|
|
43
|
+
- RSpec runs on every CI push and produces JUnit XML report
|
|
44
|
+
- Mutant runs on every merge request for changed code and blocks merge if score drops
|
|
45
|
+
- spec/support/factories/ contains factory_bot factories for core domain objects
|
|
46
|
+
- spec/support/shared_examples/ contains interface contract tests for UI base
|
|
47
|
+
- spec/fixtures/ contains valid, invalid, malicious, and unicode test fixtures
|
|
48
|
+
- AI-generated test review checklist is documented and enforced in review process
|
|
49
|
+
- At least one property-based test exists for licensing key validation
|
|
50
|
+
- spec/fixtures/snapshots/ contains baseline compiled output for each engine backend
|
|
51
|
+
- Snapshot tests compare compiled output against committed baselines (exact match)
|
|
52
|
+
- spec/support/rantly_generators.rb contains Rantly generators for behaviour rules, design documents, and policy objects
|
|
53
|
+
- Property-based tests exist for composition edge cases (priority ordering, merge strategies)
|
|
54
|
+
|
|
55
|
+
examples:
|
|
56
|
+
- scenario: "AI generates tests for RosettAi::Compiler::BehaviourCompiler"
|
|
57
|
+
expected: |
|
|
58
|
+
Tests use concrete values (eq(3), not input.select(&:enabled?).count).
|
|
59
|
+
Tests cover enabled rules included, disabled rules excluded, empty input,
|
|
60
|
+
nil input, and invalid rule format. Mutant score >= 85%.
|
|
61
|
+
not: |
|
|
62
|
+
Tests reimplement the code logic in expectations. Tests only cover
|
|
63
|
+
happy path. Mocks replace the compiler itself. Descriptions say
|
|
64
|
+
'calls select then map' instead of 'includes only enabled rules'.
|
|
65
|
+
- scenario: "Mutant reports a surviving mutation: select changed to reject"
|
|
66
|
+
expected: |
|
|
67
|
+
Developer (or AI) writes a new test that explicitly asserts disabled
|
|
68
|
+
rules are NOT in the output. Mutant is re-run to confirm the mutation
|
|
69
|
+
is now killed. New commit created (not amending).
|
|
70
|
+
not: |
|
|
71
|
+
Surviving mutation is ignored. Mutant threshold is lowered to accommodate.
|
|
72
|
+
Test is marked as pending.
|
|
73
|
+
- scenario: "AI generates tests and mutant score is 60%"
|
|
74
|
+
expected: |
|
|
75
|
+
Surviving mutations are fed back to AI with prompt: 'These mutations
|
|
76
|
+
survived, write tests to kill them: [list]'. AI generates targeted
|
|
77
|
+
tests. Mutant re-run. Repeat until >= 85%.
|
|
78
|
+
not: "Tests are accepted at 60%. Mutant is skipped."
|
|
79
|
+
- scenario: "New code adds a security-critical licensing validator"
|
|
80
|
+
expected: |
|
|
81
|
+
Unit tests with concrete values. Property-based tests with random
|
|
82
|
+
payloads verifying forged keys always rejected. Mutant score >= 95%.
|
|
83
|
+
Fixtures include valid, expired, forged, and tampered keys.
|
|
84
|
+
- scenario: "Compiled output changes unexpectedly after a refactor"
|
|
85
|
+
expected: |
|
|
86
|
+
Snapshot test compares compiled output against spec/fixtures/snapshots/
|
|
87
|
+
baseline. Test fails with a diff showing exactly what changed. Developer
|
|
88
|
+
reviews the diff and either fixes the regression or updates the snapshot.
|
|
89
|
+
not: |
|
|
90
|
+
Compiled output changes go undetected. Snapshots auto-update without
|
|
91
|
+
human review. No baseline exists for regression comparison.
|
|
92
|
+
- scenario: "Composition with random priority and scope combinations"
|
|
93
|
+
expected: |
|
|
94
|
+
Rantly generates 100 random behaviour rule sets with varying priorities,
|
|
95
|
+
scopes, and merge strategies. Property: output is always deterministic
|
|
96
|
+
(same input → same output). Property: security-domain rules are never
|
|
97
|
+
overridden by non-security rules.
|
|
98
|
+
not: |
|
|
99
|
+
Only hand-crafted examples are tested. Edge cases in priority ordering
|
|
100
|
+
are missed because the test space is too small.
|
|
101
|
+
- scenario: "Developer refactors compile method from select+map to filter_map"
|
|
102
|
+
expected: "All tests continue to pass because they test outcomes, not method calls"
|
|
103
|
+
not: "Tests break because they asserted select was called"
|
|
104
|
+
|
|
105
|
+
anti_patterns:
|
|
106
|
+
- Tautological tests (expectation reimplements the code logic)
|
|
107
|
+
- Over-mocking (mocking the unit under test, mocking everything)
|
|
108
|
+
- Weak assertions (not_to be_nil, to be_a(Array) without content checks)
|
|
109
|
+
- Happy path only (no edge cases, no error paths, no boundary values)
|
|
110
|
+
- Implementation coupling (testing call sequences instead of outcomes)
|
|
111
|
+
- Missing negative tests (no assertions about what should NOT be in output)
|
|
112
|
+
- Computed expectations (expect(x).to eq(input.select(&:foo?).count))
|
|
113
|
+
- Lowering mutation score thresholds to accommodate weak tests
|
|
114
|
+
- Skipping mutant on merge requests to save time
|
|
115
|
+
- Accepting AI-generated tests without review checklist verification
|
|
116
|
+
- Auto-updating snapshot baselines without human review
|
|
117
|
+
- Using only hand-crafted examples when property-based testing would catch more edge cases
|
|
118
|
+
- Defining Rantly generators outside spec/support/ (scattered generator definitions)
|
|
119
|
+
|
|
120
|
+
preferences:
|
|
121
|
+
language: ruby
|
|
122
|
+
testing: rspec with factory_bot and mutant-rspec
|
|
123
|
+
gems:
|
|
124
|
+
- rspec
|
|
125
|
+
- factory_bot
|
|
126
|
+
- mutant-rspec
|
|
127
|
+
- simplecov
|
|
128
|
+
- rspec-junit-formatter
|
|
129
|
+
- rantly
|
|
130
|
+
patterns:
|
|
131
|
+
- behaviour_driven_test_descriptions
|
|
132
|
+
- concrete_value_assertions
|
|
133
|
+
- boundary_only_mocking
|
|
134
|
+
- context_blocks_for_scenarios
|
|
135
|
+
- shared_examples_for_interfaces
|
|
136
|
+
- named_subjects_and_let_blocks
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: threat_model
|
|
3
|
+
domain: security
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
status: implemented
|
|
6
|
+
priority: 1
|
|
7
|
+
author: hugo
|
|
8
|
+
created_at: "2026-03-15"
|
|
9
|
+
modified_at: "2026-03-16"
|
|
10
|
+
modified_by: claude
|
|
11
|
+
depends_on:
|
|
12
|
+
- security
|
|
13
|
+
- architecture
|
|
14
|
+
- engine_architecture
|
|
15
|
+
- content_packs
|
|
16
|
+
- licensing_system
|
|
17
|
+
#
|
|
18
|
+
intent: |
|
|
19
|
+
Define the adversary model, trust boundaries, and threat scenarios for Rosett-AI.
|
|
20
|
+
Security.yml establishes coding rules; this document maps the attack surface —
|
|
21
|
+
who might attack, what they target, and which mitigations apply. Without a
|
|
22
|
+
threat model, security constraints are disconnected from real-world risks.
|
|
23
|
+
This document ensures every security decision traces back to a concrete threat.
|
|
24
|
+
#
|
|
25
|
+
constraints:
|
|
26
|
+
- Trust boundaries must be defined for every external input channel (CLI args, YAML files, content packs, engine gems, environment variables, D-Bus messages)
|
|
27
|
+
- Each identified threat must map to at least one mitigation in security.yml or this document
|
|
28
|
+
- Content packs from untrusted sources must be treated as hostile input (sandboxed parsing, no code execution)
|
|
29
|
+
- Engine gems are trusted only if installed via system package manager or bundler with locked checksums
|
|
30
|
+
- YAML files from external sources must pass schema validation before any processing
|
|
31
|
+
- D-Bus messages must be validated against expected method signatures before dispatch
|
|
32
|
+
- Supply chain attacks on dependencies must be mitigated by lockfile pinning and bundler-audit
|
|
33
|
+
- The threat model must be reviewed whenever a new input channel or external integration is added
|
|
34
|
+
- File path traversal attacks must be prevented by canonicalisation and whitelist checks
|
|
35
|
+
- No design document may introduce a new trust boundary without updating this threat model
|
|
36
|
+
#
|
|
37
|
+
acceptance_criteria:
|
|
38
|
+
- Trust boundary diagram exists (ASCII art or structured YAML) covering all input channels
|
|
39
|
+
- Each trust boundary has documented validation rules
|
|
40
|
+
- Content pack installation validates integrity (checksum verification) before extraction
|
|
41
|
+
- Engine gem loading validates gemspec metadata against expected patterns
|
|
42
|
+
- D-Bus method handlers reject messages with unexpected argument types or counts
|
|
43
|
+
- bin/raictl compile rejects YAML files containing path traversal sequences (../, symlinks to outside whitelist)
|
|
44
|
+
- bundler-audit and gitleaks run in CI and block merge on any finding
|
|
45
|
+
- Supply chain risk assessment exists for each runtime dependency (Gemfile.lock pinned)
|
|
46
|
+
- RSpec tests exist for each trust boundary validation (at least one positive and one negative test)
|
|
47
|
+
- Threat model review checklist is referenced in the design document template
|
|
48
|
+
#
|
|
49
|
+
examples:
|
|
50
|
+
- scenario: "User installs a content pack from an untrusted community repository"
|
|
51
|
+
expected: |
|
|
52
|
+
Content pack is downloaded to a temporary directory. Checksum is verified
|
|
53
|
+
against manifest. YAML files are validated against schemas. No Ruby code
|
|
54
|
+
in content packs is executed. Pack is installed only after all checks pass.
|
|
55
|
+
not: |
|
|
56
|
+
Content pack is extracted directly into ~/.config/rosett-ai/. Ruby files in
|
|
57
|
+
the pack are loaded via require. No checksum verification.
|
|
58
|
+
- scenario: "A malicious YAML behaviour file contains a path traversal in a rule's output path"
|
|
59
|
+
expected: |
|
|
60
|
+
Path is canonicalised with File.expand_path. Resulting path is checked
|
|
61
|
+
against whitelist (~/. claude/rules/, project .claude/). Traversal
|
|
62
|
+
detected: "Validation failed: output path escapes allowed directory."
|
|
63
|
+
not: |
|
|
64
|
+
Path traversal succeeds. File is written to /etc/cron.d/ or ~/.ssh/.
|
|
65
|
+
- scenario: "A compromised RubyGem is pushed as a dependency update"
|
|
66
|
+
expected: |
|
|
67
|
+
bundler-audit detects known CVE in CI. Merge is blocked. Developer
|
|
68
|
+
reviews advisory and pins to safe version in Gemfile.lock.
|
|
69
|
+
not: |
|
|
70
|
+
Compromised gem is installed. Malicious code executes at require time.
|
|
71
|
+
- scenario: "A D-Bus client sends an unexpected method call to be.neatnerds.rosettai"
|
|
72
|
+
expected: |
|
|
73
|
+
Method signature is validated. Unknown methods return D-Bus error
|
|
74
|
+
org.freedesktop.DBus.Error.UnknownMethod. Arguments are type-checked.
|
|
75
|
+
not: |
|
|
76
|
+
Arbitrary method calls are dispatched to internal handlers.
|
|
77
|
+
- scenario: "An engine gem's gemspec declares a dependency on a gem that executes native code"
|
|
78
|
+
expected: |
|
|
79
|
+
Engine loader checks gemspec dependencies against an allowlist.
|
|
80
|
+
Unknown native extensions trigger a warning. User must explicitly
|
|
81
|
+
approve gems with native extensions.
|
|
82
|
+
not: |
|
|
83
|
+
Native extension compiles and executes arbitrary C code without notice.
|
|
84
|
+
#
|
|
85
|
+
anti_patterns:
|
|
86
|
+
- Trusting input from any external channel without validation
|
|
87
|
+
- Assuming content packs are safe because they are YAML (YAML deserialization attacks)
|
|
88
|
+
- Loading engine gems via require without validating source or integrity
|
|
89
|
+
- Processing D-Bus messages without type-checking arguments
|
|
90
|
+
- Relying solely on file permissions for security (defence in depth needed)
|
|
91
|
+
- Hardcoding trust assumptions instead of documenting them in the threat model
|
|
92
|
+
- Treating all RubyGems as equally trusted regardless of source
|
|
93
|
+
- Skipping threat model review when adding new external integrations
|
|
94
|
+
- Using string comparison for paths instead of canonicalised path comparison
|
|
95
|
+
#
|
|
96
|
+
preferences:
|
|
97
|
+
language: ruby
|
|
98
|
+
patterns:
|
|
99
|
+
- defence_in_depth
|
|
100
|
+
- trust_boundary_validation
|
|
101
|
+
- input_sanitisation_at_boundaries
|
|
102
|
+
- least_privilege
|
|
103
|
+
- fail_secure
|
|
104
|
+
testing: rspec with adversarial input fixtures
|
|
105
|
+
gems:
|
|
106
|
+
- bundler-audit
|
|
107
|
+
- gitleaks
|
|
108
|
+
- json_schemer
|