core-runtime 0.1.1__py3-none-any.whl
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.
- api/__init__.py +4 -0
- api/cli/__init__.py +10 -0
- api/cli/audit_client.py +92 -0
- api/cli/census_client.py +77 -0
- api/cli/client.py +508 -0
- api/cli/coverage_client.py +121 -0
- api/cli/daemon_client.py +42 -0
- api/cli/fix_client.py +101 -0
- api/cli/inspect_client.py +143 -0
- api/cli/integration_client.py +42 -0
- api/cli/integrity_client.py +45 -0
- api/cli/proposals_client.py +101 -0
- api/cli/quality_client.py +83 -0
- api/cli/refactor_client.py +82 -0
- api/cli/sync_client.py +106 -0
- api/dependencies.py +37 -0
- api/errors.py +74 -0
- api/main.py +88 -0
- api/v1/__init__.py +4 -0
- api/v1/audit_routes.py +302 -0
- api/v1/census_routes.py +207 -0
- api/v1/coverage_routes.py +352 -0
- api/v1/daemon_routes.py +86 -0
- api/v1/development_routes.py +70 -0
- api/v1/fix_routes.py +428 -0
- api/v1/inspect_routes.py +220 -0
- api/v1/integration_routes.py +56 -0
- api/v1/integrity_routes.py +72 -0
- api/v1/knowledge_routes.py +36 -0
- api/v1/lint_routes.py +40 -0
- api/v1/proposals_routes.py +267 -0
- api/v1/quality_routes.py +272 -0
- api/v1/refactor_routes.py +225 -0
- api/v1/sync_routes.py +261 -0
- body/__init__.py +4 -0
- body/analyzers/__init__.py +25 -0
- body/analyzers/base_analyzer.py +28 -0
- body/analyzers/constitutional_path_analyzer.py +63 -0
- body/analyzers/file_analyzer.py +211 -0
- body/analyzers/knowledge_graph_analyzer.py +86 -0
- body/analyzers/prompt_analyzer.py +155 -0
- body/analyzers/symbol_extractor.py +280 -0
- body/atomic/__init__.py +74 -0
- body/atomic/build_tests_action.py +354 -0
- body/atomic/check_actions.py +142 -0
- body/atomic/crate_ops.py +59 -0
- body/atomic/executor.py +470 -0
- body/atomic/file_ops.py +153 -0
- body/atomic/fix_actions.py +1142 -0
- body/atomic/import_resolver.py +200 -0
- body/atomic/metadata_ops.py +161 -0
- body/atomic/modularity_fix.py +839 -0
- body/atomic/modularity_splitter.py +521 -0
- body/atomic/proposal_lifecycle_actions.py +171 -0
- body/atomic/registry.py +326 -0
- body/atomic/remediate_cognitive_role.py +104 -0
- body/atomic/sandbox_lifecycle.py +252 -0
- body/atomic/split_plan.py +155 -0
- body/atomic/sync_actions/__init__.py +22 -0
- body/atomic/sync_actions/chunking_helpers.py +218 -0
- body/atomic/sync_actions/sync_actions.py +431 -0
- body/atomic/test_actions.py +47 -0
- body/autonomy/__init__.py +16 -0
- body/autonomy/audit_analyzer.py +343 -0
- body/autonomy/micro_proposal_executor.py +316 -0
- body/crate_processing/canary_executor.py +144 -0
- body/evaluators/__init__.py +27 -0
- body/evaluators/atomic_actions_evaluator.py +162 -0
- body/evaluators/atomic_actions_format.py +45 -0
- body/evaluators/atomic_actions_rules.py +278 -0
- body/evaluators/base_evaluator.py +67 -0
- body/evaluators/clarity_evaluator.py +83 -0
- body/evaluators/constitutional_evaluator.py +227 -0
- body/evaluators/failure_evaluator.py +136 -0
- body/evaluators/performance_evaluator.py +341 -0
- body/evaluators/security_evaluator.py +393 -0
- body/flows/__init__.py +33 -0
- body/flows/executor.py +275 -0
- body/flows/registry.py +272 -0
- body/flows/result.py +113 -0
- body/governance/__init__.py +29 -0
- body/governance/body_contracts_service.py +317 -0
- body/governance/code_validator.py +118 -0
- body/governance/engine_dispatcher.py +128 -0
- body/governance/intent_guard.py +592 -0
- body/governance/intent_pattern_validators.py +197 -0
- body/governance/key_management_service.py +100 -0
- body/governance/path_validator.py +187 -0
- body/governance/remediation_service.py +263 -0
- body/governance/runtime_validator.py +184 -0
- body/infrastructure/bootstrap.py +135 -0
- body/infrastructure/lifespan.py +85 -0
- body/infrastructure/repositories/__init__.py +1 -0
- body/infrastructure/repositories/decision_trace_repository.py +210 -0
- body/infrastructure/repositories/refusal_repository.py +294 -0
- body/introspection/__init__.py +4 -0
- body/introspection/capability_discovery_service.py +107 -0
- body/introspection/discovery/from_kgb.py +33 -0
- body/introspection/discovery/from_source_scan.py +40 -0
- body/introspection/discovery/loader.py +62 -0
- body/introspection/discovery/registry.py +22 -0
- body/introspection/discovery/semantics.py +21 -0
- body/introspection/discovery/sync.py +47 -0
- body/introspection/drift_detector.py +81 -0
- body/introspection/drift_service.py +48 -0
- body/introspection/export_vectors.py +133 -0
- body/introspection/generate_capability_docs.py +130 -0
- body/introspection/generate_correction_map.py +98 -0
- body/introspection/graph_analysis_service.py +66 -0
- body/introspection/knowledge_graph_service.py +170 -0
- body/introspection/semantic_clusterer.py +128 -0
- body/introspection/symbol_index_builder.py +244 -0
- body/introspection/sync/engine.py +92 -0
- body/introspection/sync/scanner.py +56 -0
- body/introspection/sync/visitor.py +83 -0
- body/introspection/sync_service.py +62 -0
- body/invokers/__init__.py +4 -0
- body/invokers/capability_invoker.py +4 -0
- body/maintenance/command_sync_service.py +73 -0
- body/maintenance/dotenv_sync_service.py +99 -0
- body/maintenance/idempotency_harness.py +70 -0
- body/maintenance/maintenance_service.py +123 -0
- body/maintenance/memory_cleanup_service.py +131 -0
- body/maintenance/refactor_settings_access.py +274 -0
- body/maintenance/scripts/__init__.py +5 -0
- body/maintenance/scripts/context_export.py +278 -0
- body/maintenance/scripts/vector_verify.py +73 -0
- body/maintenance/sync_vectors.py +338 -0
- body/models/__init__.py +4 -0
- body/project_lifecycle/__init__.py +4 -0
- body/project_lifecycle/bootstrap_service.py +157 -0
- body/project_lifecycle/definition_service.py +264 -0
- body/project_lifecycle/integration_service.py +113 -0
- body/project_lifecycle/scaffolding_service.py +187 -0
- body/quality/coverage_analyzer.py +177 -0
- body/repositories/__init__.py +4 -0
- body/self_healing/atomic_actions_fixer.py +113 -0
- body/self_healing/body_ui_fixer.py +193 -0
- body/self_healing/capability_parser.py +65 -0
- body/self_healing/code_style_service.py +51 -0
- body/self_healing/complexity_filter.py +70 -0
- body/self_healing/docstring_service.py +345 -0
- body/self_healing/duplicate_id_service.py +407 -0
- body/self_healing/duplicates_service.py +165 -0
- body/self_healing/handlers/__init__.py +1 -0
- body/self_healing/handlers/id_assignment_handler.py +201 -0
- body/self_healing/handlers/import_sorting_handler.py +181 -0
- body/self_healing/header_service.py +308 -0
- body/self_healing/id_tagging_service.py +227 -0
- body/self_healing/knowledge_consolidation_service.py +80 -0
- body/self_healing/logging_service.py +292 -0
- body/self_healing/owner_tagging_service.py +5 -0
- body/self_healing/placeholder_fixer_service.py +27 -0
- body/self_healing/prune_private_capabilities.py +144 -0
- body/self_healing/purge_legacy_tags_service.py +146 -0
- body/self_healing/remediation_models.py +238 -0
- body/self_healing/test_context/__init__.py +10 -0
- body/self_healing/test_context/detectors.py +74 -0
- body/self_healing/test_context/examples.py +53 -0
- body/self_healing/test_context/formatter.py +65 -0
- body/self_healing/test_context/metrics.py +62 -0
- body/self_healing/test_context/models.py +83 -0
- body/self_healing/test_context/parsers.py +70 -0
- body/self_healing/test_context_analyzer.py +79 -0
- body/self_healing/test_failure_analyzer.py +259 -0
- body/self_healing/test_target_analyzer.py +118 -0
- body/self_healing/vulture_healer.py +161 -0
- body/services/__init__.py +4 -0
- body/services/artifact_service.py +155 -0
- body/services/blackboard_service/__init__.py +22 -0
- body/services/blackboard_service/blackboard_claim_service.py +216 -0
- body/services/blackboard_service/blackboard_proposal_service.py +305 -0
- body/services/blackboard_service/blackboard_query_service.py +333 -0
- body/services/blackboard_service/blackboard_service.py +602 -0
- body/services/capabilities.py +51 -0
- body/services/cim/__init__.py +22 -0
- body/services/cim/baselines.py +102 -0
- body/services/cim/census_service.py +190 -0
- body/services/cim/cim_constants.py +116 -0
- body/services/cim/cim_path_utils.py +123 -0
- body/services/cim/diff.py +152 -0
- body/services/cim/history.py +94 -0
- body/services/cim/models.py +319 -0
- body/services/cim/policy.py +149 -0
- body/services/cim/scanners.py +332 -0
- body/services/coherence_service.py +552 -0
- body/services/consequence_log_service.py +189 -0
- body/services/constitutional_rule_loader.py +141 -0
- body/services/constitutional_validator.py +366 -0
- body/services/crate_creation_service.py +217 -0
- body/services/crate_processing_service.py +279 -0
- body/services/crawl_service/__init__.py +10 -0
- body/services/crawl_service/main_module.py +531 -0
- body/services/crawl_service/orchestrator.py +452 -0
- body/services/crawl_service/symbol_processing.py +279 -0
- body/services/database_service.py +242 -0
- body/services/doc_service.py +57 -0
- body/services/file_service.py +260 -0
- body/services/governance_claims_service.py +240 -0
- body/services/governance_init.py +41 -0
- body/services/health_log_service.py +167 -0
- body/services/intent_schema_validator.py +211 -0
- body/services/llm_client.py +87 -0
- body/services/mind_state_service.py +129 -0
- body/services/policy_expression_evaluator.py +154 -0
- body/services/proposal_supervision_service.py +187 -0
- body/services/representation_coherence_service.py +209 -0
- body/services/service_registry.py +431 -0
- body/services/session_attached_service.py +51 -0
- body/services/symbol_query_service.py +218 -0
- body/services/symbol_service.py +94 -0
- body/services/validation/__init__.py +14 -0
- body/services/validation/python_validator.py +89 -0
- body/services/validation/validation_policies.py +121 -0
- body/services/worker_registry_service.py +184 -0
- body/validators/__init__.py +1 -0
- body/validators/logic_conservation_validator.py +201 -0
- body/workers/call_site_rewriter.py +527 -0
- body/workers/prompt_artifact_writer.py +323 -0
- cli/__init__.py +4 -0
- cli/admin_cli.py +98 -0
- cli/cli_user.py +121 -0
- cli/commands/__init__.py +4 -0
- cli/commands/audit_reporter.py +272 -0
- cli/commands/check/__init__.py +115 -0
- cli/commands/check/audit.py +130 -0
- cli/commands/check/converters.py +129 -0
- cli/commands/check/diagnostics_commands.py +70 -0
- cli/commands/check/formatters.py +310 -0
- cli/commands/check/imports.py +73 -0
- cli/commands/check/quality.py +71 -0
- cli/commands/check/quality_gates.py +107 -0
- cli/commands/check/rule.py +136 -0
- cli/commands/check/utils.py +28 -0
- cli/commands/check_atomic_actions.py +167 -0
- cli/commands/components.py +66 -0
- cli/commands/coverage/__init__.py +22 -0
- cli/commands/coverage/analysis_commands.py +87 -0
- cli/commands/coverage/check_commands.py +173 -0
- cli/commands/coverage/generation_commands.py +155 -0
- cli/commands/coverage/services/__init__.py +15 -0
- cli/commands/coverage/services/coverage_checker.py +50 -0
- cli/commands/coverage/services/coverage_reporter.py +81 -0
- cli/commands/coverage/services/gaps_analyzer.py +114 -0
- cli/commands/daemon.py +908 -0
- cli/commands/develop.py +127 -0
- cli/commands/diagnostics.py +32 -0
- cli/commands/fix/__init__.py +84 -0
- cli/commands/fix/all_commands.py +94 -0
- cli/commands/fix/atomic_actions.py +48 -0
- cli/commands/fix/audit.py +146 -0
- cli/commands/fix/body_ui.py +93 -0
- cli/commands/fix/code_style.py +52 -0
- cli/commands/fix/db_tools.py +90 -0
- cli/commands/fix/fix_ir.py +79 -0
- cli/commands/fix/handler_discovery.py +54 -0
- cli/commands/fix/imports.py +55 -0
- cli/commands/fix/list_commands.py +54 -0
- cli/commands/fix/metadata.py +160 -0
- cli/commands/fix/modularity.py +88 -0
- cli/commands/fix/settings_access.py +65 -0
- cli/commands/fix_governed.py +103 -0
- cli/commands/fix_logging.py +24 -0
- cli/commands/governance.py +294 -0
- cli/commands/guard.py +125 -0
- cli/commands/inspect/__init__.py +79 -0
- cli/commands/inspect/_helpers.py +226 -0
- cli/commands/inspect/analysis.py +158 -0
- cli/commands/inspect/decisions.py +140 -0
- cli/commands/inspect/diagnostics.py +126 -0
- cli/commands/inspect/drift.py +100 -0
- cli/commands/inspect/patterns.py +102 -0
- cli/commands/inspect/refusals.py +211 -0
- cli/commands/inspect/repo_census.py +175 -0
- cli/commands/inspect/status.py +48 -0
- cli/commands/interactive_test.py +85 -0
- cli/commands/mind.py +49 -0
- cli/commands/refactor.py +234 -0
- cli/commands/refactor_support/__init__.py +7 -0
- cli/commands/refactor_support/analyzer.py +107 -0
- cli/commands/refactor_support/config.py +67 -0
- cli/commands/refactor_support/display.py +170 -0
- cli/commands/refactor_support/recommendations.py +55 -0
- cli/commands/run.py +60 -0
- cli/commands/search.py +103 -0
- cli/commands/status.py +86 -0
- cli/commands/submit.py +23 -0
- cli/interactive.py +177 -0
- cli/logic/__init__.py +7 -0
- cli/logic/agent.py +110 -0
- cli/logic/audit_capability_domains.py +106 -0
- cli/logic/audit_renderer.py +150 -0
- cli/logic/autonomy/actions.py +36 -0
- cli/logic/autonomy/views.py +116 -0
- cli/logic/body_contracts_checker.py +23 -0
- cli/logic/build.py +27 -0
- cli/logic/byor.py +148 -0
- cli/logic/capability.py +27 -0
- cli/logic/cli_utils.py +210 -0
- cli/logic/context.py +7 -0
- cli/logic/db.py +154 -0
- cli/logic/db_manage.py +22 -0
- cli/logic/decision_inspect_logic.py +62 -0
- cli/logic/diagnostics.py +148 -0
- cli/logic/diagnostics_policy.py +100 -0
- cli/logic/diagnostics_registry.py +165 -0
- cli/logic/duplicates.py +19 -0
- cli/logic/embeddings_cli.py +43 -0
- cli/logic/governance/__init__.py +16 -0
- cli/logic/governance/engine.py +216 -0
- cli/logic/governance/forensics_service.py +67 -0
- cli/logic/governance/limb_status_service.py +83 -0
- cli/logic/governance/renderer.py +115 -0
- cli/logic/governance/traceability_service.py +78 -0
- cli/logic/governance_logic.py +33 -0
- cli/logic/hub/__init__.py +14 -0
- cli/logic/hub/app.py +107 -0
- cli/logic/hub/formatter.py +29 -0
- cli/logic/hub/introspection.py +20 -0
- cli/logic/hub/repository.py +17 -0
- cli/logic/init.py +22 -0
- cli/logic/interactive_test/__init__.py +21 -0
- cli/logic/interactive_test/session.py +102 -0
- cli/logic/interactive_test/steps/__init__.py +23 -0
- cli/logic/interactive_test/steps/execution.py +53 -0
- cli/logic/interactive_test/steps/generation.py +88 -0
- cli/logic/interactive_test/steps/healing.py +79 -0
- cli/logic/interactive_test/steps/utils.py +31 -0
- cli/logic/interactive_test/steps/verification.py +71 -0
- cli/logic/interactive_test/ui.py +203 -0
- cli/logic/interactive_test/workflow.py +168 -0
- cli/logic/interactive_test_logic.py +41 -0
- cli/logic/knowledge.py +47 -0
- cli/logic/legacy_scan_logic.py +306 -0
- cli/logic/list_audits.py +49 -0
- cli/logic/log_audit.py +53 -0
- cli/logic/new.py +8 -0
- cli/logic/project_docs.py +28 -0
- cli/logic/reconcile.py +127 -0
- cli/logic/refusal_inspect_logic.py +208 -0
- cli/logic/report.py +47 -0
- cli/logic/status.py +47 -0
- cli/logic/symbol_drift.py +77 -0
- cli/logic/sync.py +48 -0
- cli/logic/sync_domains.py +72 -0
- cli/logic/sync_manifest.py +31 -0
- cli/logic/tools.py +133 -0
- cli/logic/utils_migration.py +43 -0
- cli/logic/validate.py +107 -0
- cli/logic/vector_drift.py +109 -0
- cli/logic/yaml_processor.py +5 -0
- cli/renderers/audit_detail.py +37 -0
- cli/renderers/audit_overview.py +39 -0
- cli/resources/__init__.py +27 -0
- cli/resources/admin/__init__.py +23 -0
- cli/resources/admin/coverage.py +63 -0
- cli/resources/admin/debt_scan.py +195 -0
- cli/resources/admin/forensics.py +97 -0
- cli/resources/admin/health.py +66 -0
- cli/resources/admin/hub.py +9 -0
- cli/resources/admin/meta.py +47 -0
- cli/resources/admin/patterns.py +28 -0
- cli/resources/admin/refusals.py +31 -0
- cli/resources/admin/self_check.py +175 -0
- cli/resources/admin/status.py +66 -0
- cli/resources/admin/summary.py +67 -0
- cli/resources/admin/traces.py +46 -0
- cli/resources/admin/validate_env.py +56 -0
- cli/resources/code/__init__.py +31 -0
- cli/resources/code/actions.py +48 -0
- cli/resources/code/audit.py +416 -0
- cli/resources/code/audit_duplicates.py +22 -0
- cli/resources/code/check_imports.py +75 -0
- cli/resources/code/check_ui.py +62 -0
- cli/resources/code/clarity.py +51 -0
- cli/resources/code/complexity.py +55 -0
- cli/resources/code/docstrings.py +51 -0
- cli/resources/code/fix_atomic.py +51 -0
- cli/resources/code/format.py +62 -0
- cli/resources/code/hub.py +10 -0
- cli/resources/code/integrity.py +75 -0
- cli/resources/code/lint.py +37 -0
- cli/resources/code/logging.py +49 -0
- cli/resources/code/refactor.py +32 -0
- cli/resources/code/test.py +30 -0
- cli/resources/coherence/__init__.py +13 -0
- cli/resources/coherence/check.py +111 -0
- cli/resources/coherence/hub.py +13 -0
- cli/resources/coherence/repair_counts.py +73 -0
- cli/resources/coherence/report.py +144 -0
- cli/resources/coherence/seed.py +297 -0
- cli/resources/coherence/supersede.py +124 -0
- cli/resources/coherence/triage.py +81 -0
- cli/resources/constitution/__init__.py +19 -0
- cli/resources/constitution/audit.py +49 -0
- cli/resources/constitution/query.py +45 -0
- cli/resources/constitution/status.py +34 -0
- cli/resources/constitution/validate.py +36 -0
- cli/resources/context/__init__.py +21 -0
- cli/resources/context/build.py +374 -0
- cli/resources/context/cache.py +156 -0
- cli/resources/context/explain.py +140 -0
- cli/resources/context/hub.py +11 -0
- cli/resources/context/search.py +114 -0
- cli/resources/database/__init__.py +13 -0
- cli/resources/database/cleanup.py +107 -0
- cli/resources/database/export.py +61 -0
- cli/resources/database/hub.py +11 -0
- cli/resources/database/migrate.py +57 -0
- cli/resources/database/status.py +101 -0
- cli/resources/database/sync.py +84 -0
- cli/resources/database/sync_env.py +76 -0
- cli/resources/database/sync_registry.py +48 -0
- cli/resources/dev/__init__.py +14 -0
- cli/resources/dev/hub.py +11 -0
- cli/resources/dev/refactor.py +92 -0
- cli/resources/dev/stability.py +60 -0
- cli/resources/dev/strategic_audit.py +113 -0
- cli/resources/dev/sync.py +51 -0
- cli/resources/dev/test.py +34 -0
- cli/resources/intent/__init__.py +11 -0
- cli/resources/intent/hub.py +9 -0
- cli/resources/intent/sync_vocabulary.py +396 -0
- cli/resources/project/__init__.py +19 -0
- cli/resources/project/docs.py +41 -0
- cli/resources/project/new.py +40 -0
- cli/resources/project/onboard.py +31 -0
- cli/resources/proposals/__init__.py +28 -0
- cli/resources/proposals/create.py +82 -0
- cli/resources/proposals/integrate.py +49 -0
- cli/resources/proposals/list.py +76 -0
- cli/resources/proposals/manage.py +117 -0
- cli/resources/runtime/__init__.py +9 -0
- cli/resources/runtime/health.py +925 -0
- cli/resources/secrets/__init__.py +10 -0
- cli/resources/secrets/hub.py +9 -0
- cli/resources/secrets/manage.py +309 -0
- cli/resources/symbols/__init__.py +13 -0
- cli/resources/symbols/audit.py +46 -0
- cli/resources/symbols/fix_ids.py +43 -0
- cli/resources/symbols/hub.py +11 -0
- cli/resources/symbols/resolve_duplicates.py +30 -0
- cli/resources/symbols/sync.py +39 -0
- cli/resources/symbols/tag.py +47 -0
- cli/resources/vectors/__init__.py +11 -0
- cli/resources/vectors/cleanup.py +95 -0
- cli/resources/vectors/hub.py +9 -0
- cli/resources/vectors/query.py +105 -0
- cli/resources/vectors/status.py +30 -0
- cli/resources/vectors/sync.py +57 -0
- cli/resources/vectors/sync_code.py +67 -0
- cli/resources/workers/__init__.py +13 -0
- cli/resources/workers/blackboard.py +253 -0
- cli/resources/workers/remediate.py +337 -0
- cli/resources/workers/run.py +140 -0
- cli/utils/__init__.py +32 -0
- cli/utils/annotation_formatter.py +154 -0
- cli/utils/decorators.py +184 -0
- cli/utils/display.py +79 -0
- cli/utils/exit_codes.py +59 -0
- cli/utils/helpers.py +34 -0
- cli/utils/prompts.py +21 -0
- core_runtime-0.1.1.dist-info/LICENSE +21 -0
- core_runtime-0.1.1.dist-info/METADATA +346 -0
- core_runtime-0.1.1.dist-info/RECORD +962 -0
- core_runtime-0.1.1.dist-info/WHEEL +4 -0
- core_runtime-0.1.1.dist-info/entry_points.txt +4 -0
- mind/__init__.py +4 -0
- mind/coherence/__init__.py +1 -0
- mind/coherence/checker.py +314 -0
- mind/coherence/checks/__init__.py +4 -0
- mind/coherence/checks/base.py +34 -0
- mind/coherence/checks/r1_scoped.py +228 -0
- mind/coherence/checks/row2_grounding.py +69 -0
- mind/coherence/checks/row3_citation.py +119 -0
- mind/coherence/checks/row4_naming.py +126 -0
- mind/coherence/checks/sameconcern.py +136 -0
- mind/coherence/checks/specgap.py +233 -0
- mind/coherence/checks/vocabulary.py +112 -0
- mind/coherence/llm_judge.py +207 -0
- mind/enforcement/audit.py +78 -0
- mind/governance/__init__.py +22 -0
- mind/governance/assumption_extractor.py +326 -0
- mind/governance/audit_context.py +520 -0
- mind/governance/audit_postprocessor.py +36 -0
- mind/governance/audit_report_writer.py +46 -0
- mind/governance/audit_types.py +98 -0
- mind/governance/auditor.py +179 -0
- mind/governance/authority_package_builder.py +502 -0
- mind/governance/constitutional_auditor_dynamic.py +362 -0
- mind/governance/enforcement/__init__.py +24 -0
- mind/governance/enforcement_loader.py +245 -0
- mind/governance/enforcement_methods.py +28 -0
- mind/governance/entry_point_policy.py +62 -0
- mind/governance/executable_rule.py +127 -0
- mind/governance/filtered_audit.py +272 -0
- mind/governance/finding_processor.py +76 -0
- mind/governance/meta_validator.py +259 -0
- mind/governance/micro_proposal_validator.py +169 -0
- mind/governance/policy_coverage_service.py +183 -0
- mind/governance/policy_rule.py +94 -0
- mind/governance/rule_conflict_detector.py +127 -0
- mind/governance/rule_executor.py +306 -0
- mind/governance/rule_extractor.py +376 -0
- mind/governance/stateless_audit.py +206 -0
- mind/governance/violation_report.py +136 -0
- mind/logic/engines/_knowledge_gate_duplication.py +117 -0
- mind/logic/engines/action_gate.py +76 -0
- mind/logic/engines/artifact_gate.py +1168 -0
- mind/logic/engines/ast_gate/__init__.py +9 -0
- mind/logic/engines/ast_gate/base.py +263 -0
- mind/logic/engines/ast_gate/checks/__init__.py +35 -0
- mind/logic/engines/ast_gate/checks/async_checks.py +276 -0
- mind/logic/engines/ast_gate/checks/capability_checks.py +197 -0
- mind/logic/engines/ast_gate/checks/conservation_checks.py +126 -0
- mind/logic/engines/ast_gate/checks/generic_checks.py +244 -0
- mind/logic/engines/ast_gate/checks/import_checks.py +164 -0
- mind/logic/engines/ast_gate/checks/knowledge_source_check.py +88 -0
- mind/logic/engines/ast_gate/checks/logging_checks.py +133 -0
- mind/logic/engines/ast_gate/checks/metadata_checks.py +242 -0
- mind/logic/engines/ast_gate/checks/modularity_checks.py +436 -0
- mind/logic/engines/ast_gate/checks/naming_checks.py +120 -0
- mind/logic/engines/ast_gate/checks/prompt_model_checks.py +83 -0
- mind/logic/engines/ast_gate/checks/protected_namespace_access_check.py +298 -0
- mind/logic/engines/ast_gate/checks/purity_checks.py +421 -0
- mind/logic/engines/ast_gate/checks/purity_enforcement_check.py +56 -0
- mind/logic/engines/ast_gate/checks/runtime_import_boundary.py +198 -0
- mind/logic/engines/ast_gate/checks/schema_conformance_checks.py +130 -0
- mind/logic/engines/ast_gate/engine.py +317 -0
- mind/logic/engines/ast_gate.py +19 -0
- mind/logic/engines/base.py +106 -0
- mind/logic/engines/cli_gate/__init__.py +25 -0
- mind/logic/engines/cli_gate/base_check.py +45 -0
- mind/logic/engines/cli_gate/checks/__init__.py +31 -0
- mind/logic/engines/cli_gate/checks/async_execution.py +65 -0
- mind/logic/engines/cli_gate/checks/dangerous_explicit.py +60 -0
- mind/logic/engines/cli_gate/checks/discovery_strict.py +167 -0
- mind/logic/engines/cli_gate/checks/help_required.py +43 -0
- mind/logic/engines/cli_gate/checks/no_duplicates.py +57 -0
- mind/logic/engines/cli_gate/checks/no_layer_exposure.py +48 -0
- mind/logic/engines/cli_gate/checks/resource_first.py +58 -0
- mind/logic/engines/cli_gate/checks/standard_verbs.py +50 -0
- mind/logic/engines/cli_gate/engine.py +211 -0
- mind/logic/engines/glob_gate.py +214 -0
- mind/logic/engines/knowledge_gate.py +410 -0
- mind/logic/engines/llm_gate.py +407 -0
- mind/logic/engines/llm_gate_stub.py +67 -0
- mind/logic/engines/passive_gate.py +45 -0
- mind/logic/engines/regex_gate.py +97 -0
- mind/logic/engines/registry.py +134 -0
- mind/logic/engines/runtime_gate.py +265 -0
- mind/logic/engines/taxonomy_gate.py +229 -0
- mind/logic/engines/workflow_gate/__init__.py +22 -0
- mind/logic/engines/workflow_gate/base_check.py +42 -0
- mind/logic/engines/workflow_gate/checks/__init__.py +32 -0
- mind/logic/engines/workflow_gate/checks/alignment.py +93 -0
- mind/logic/engines/workflow_gate/checks/audit.py +80 -0
- mind/logic/engines/workflow_gate/checks/canary.py +47 -0
- mind/logic/engines/workflow_gate/checks/coverage.py +74 -0
- mind/logic/engines/workflow_gate/checks/dead_code.py +53 -0
- mind/logic/engines/workflow_gate/checks/import_resolution.py +97 -0
- mind/logic/engines/workflow_gate/checks/linter.py +104 -0
- mind/logic/engines/workflow_gate/checks/quality.py +49 -0
- mind/logic/engines/workflow_gate/checks/ruff_format.py +99 -0
- mind/logic/engines/workflow_gate/checks/tests.py +81 -0
- mind/logic/engines/workflow_gate/engine.py +207 -0
- shared/__init__.py +32 -0
- shared/action_logger.py +61 -0
- shared/action_types.py +199 -0
- shared/activity_logging.py +149 -0
- shared/ai/constitutional_envelope.py +341 -0
- shared/ai/prompt_model.py +585 -0
- shared/ai/response_parser.py +191 -0
- shared/ast_utility.py +279 -0
- shared/atomic_action.py +117 -0
- shared/cli/__init__.py +6 -0
- shared/cli/app_introspection.py +134 -0
- shared/cli/command_meta.py +224 -0
- shared/cli_types.py +92 -0
- shared/component_primitive.py +216 -0
- shared/config.py +216 -0
- shared/config_loader.py +54 -0
- shared/context.py +113 -0
- shared/exceptions.py +100 -0
- shared/governance/__init__.py +9 -0
- shared/governance/coherence_harvester.py +258 -0
- shared/governance_token.py +77 -0
- shared/infrastructure/__init__.py +5 -0
- shared/infrastructure/adapters/__init__.py +5 -0
- shared/infrastructure/adapters/embedding_provider.py +66 -0
- shared/infrastructure/bootstrap_registry.py +57 -0
- shared/infrastructure/clients/__init__.py +5 -0
- shared/infrastructure/clients/qdrant_client.py +455 -0
- shared/infrastructure/config_service.py +382 -0
- shared/infrastructure/config_validator.py +70 -0
- shared/infrastructure/context/__init__.py +45 -0
- shared/infrastructure/context/builder.py +804 -0
- shared/infrastructure/context/cache.py +101 -0
- shared/infrastructure/context/database.py +205 -0
- shared/infrastructure/context/limb_workspace.py +134 -0
- shared/infrastructure/context/models.py +65 -0
- shared/infrastructure/context/providers/__init__.py +18 -0
- shared/infrastructure/context/providers/ast.py +211 -0
- shared/infrastructure/context/providers/db.py +165 -0
- shared/infrastructure/context/providers/vectors.py +195 -0
- shared/infrastructure/context/redactor.py +109 -0
- shared/infrastructure/context/serializers.py +144 -0
- shared/infrastructure/context/service.py +271 -0
- shared/infrastructure/context/validator.py +247 -0
- shared/infrastructure/database/models/__init__.py +80 -0
- shared/infrastructure/database/models/autonomous_proposals.py +83 -0
- shared/infrastructure/database/models/decision_traces.py +129 -0
- shared/infrastructure/database/models/governance.py +183 -0
- shared/infrastructure/database/models/knowledge.py +205 -0
- shared/infrastructure/database/models/learning.py +99 -0
- shared/infrastructure/database/models/llm_config.py +274 -0
- shared/infrastructure/database/models/operations.py +152 -0
- shared/infrastructure/database/models/refusals.py +147 -0
- shared/infrastructure/database/models/system.py +124 -0
- shared/infrastructure/database/models/vectors.py +113 -0
- shared/infrastructure/database/models/workers.py +96 -0
- shared/infrastructure/database/session_manager.py +166 -0
- shared/infrastructure/diagnostic_service.py +103 -0
- shared/infrastructure/events/__init__.py +5 -0
- shared/infrastructure/events/base.py +44 -0
- shared/infrastructure/events/bus.py +76 -0
- shared/infrastructure/git_service.py +385 -0
- shared/infrastructure/intent/action_risk.py +135 -0
- shared/infrastructure/intent/audit_verdict.py +131 -0
- shared/infrastructure/intent/autonomy_dirty_tree.py +104 -0
- shared/infrastructure/intent/canonical_enums.py +116 -0
- shared/infrastructure/intent/cognitive_roles.py +96 -0
- shared/infrastructure/intent/errors.py +13 -0
- shared/infrastructure/intent/filesystem_operations.py +359 -0
- shared/infrastructure/intent/intent_connector.py +157 -0
- shared/infrastructure/intent/intent_repository.py +707 -0
- shared/infrastructure/intent/intent_validator.py +248 -0
- shared/infrastructure/intent/operational_capabilities.py +470 -0
- shared/infrastructure/intent/operational_config.py +1343 -0
- shared/infrastructure/intent/operational_mode.py +66 -0
- shared/infrastructure/intent/task_type_phases.py +180 -0
- shared/infrastructure/intent/test_coverage_paths.py +181 -0
- shared/infrastructure/intent/vocabulary_projection.py +241 -0
- shared/infrastructure/knowledge/knowledge_service.py +155 -0
- shared/infrastructure/knowledge_graph_service.py +214 -0
- shared/infrastructure/llm/client.py +448 -0
- shared/infrastructure/llm/client_registry.py +153 -0
- shared/infrastructure/llm/fallback_client.py +144 -0
- shared/infrastructure/llm/providers/anthropic.py +113 -0
- shared/infrastructure/llm/providers/base.py +130 -0
- shared/infrastructure/llm/providers/ollama.py +265 -0
- shared/infrastructure/llm/providers/openai.py +168 -0
- shared/infrastructure/repositories/__init__.py +5 -0
- shared/infrastructure/repositories/db/__init__.py +5 -0
- shared/infrastructure/repositories/db/common.py +138 -0
- shared/infrastructure/repositories/db/engine.py +26 -0
- shared/infrastructure/repositories/db/migration_service.py +75 -0
- shared/infrastructure/repositories/db/status_service.py +61 -0
- shared/infrastructure/repositories/memory_repository.py +134 -0
- shared/infrastructure/repositories/symbol_definition_repository.py +170 -0
- shared/infrastructure/repositories/task_repository.py +59 -0
- shared/infrastructure/repositories/vector_link_repository.py +83 -0
- shared/infrastructure/rooted_repository.py +50 -0
- shared/infrastructure/secrets_service.py +317 -0
- shared/infrastructure/specs/__init__.py +9 -0
- shared/infrastructure/specs/specs_repository.py +100 -0
- shared/infrastructure/storage/file_classifier.py +32 -0
- shared/infrastructure/storage/file_handler.py +330 -0
- shared/infrastructure/storage/file_provider.py +233 -0
- shared/infrastructure/storage/integrity_service.py +108 -0
- shared/infrastructure/validation/black_formatter.py +41 -0
- shared/infrastructure/validation/quality.py +46 -0
- shared/infrastructure/validation/ruff_linter.py +104 -0
- shared/infrastructure/validation/syntax_checker.py +45 -0
- shared/infrastructure/validation/test_runner.py +167 -0
- shared/infrastructure/validation/yaml_validator.py +45 -0
- shared/infrastructure/vector/__init__.py +15 -0
- shared/infrastructure/vector/adapters/__init__.py +20 -0
- shared/infrastructure/vector/adapters/constitutional/__init__.py +26 -0
- shared/infrastructure/vector/adapters/constitutional/chunker.py +246 -0
- shared/infrastructure/vector/adapters/constitutional/doc_key_resolver.py +109 -0
- shared/infrastructure/vector/adapters/constitutional/item_builder.py +158 -0
- shared/infrastructure/vector/adapters/constitutional/utils.py +39 -0
- shared/infrastructure/vector/adapters/constitutional_adapter.py +309 -0
- shared/infrastructure/vector/adapters/specs_adapter.py +171 -0
- shared/infrastructure/vector/cognitive_adapter.py +119 -0
- shared/infrastructure/vector/vector_index_service.py +230 -0
- shared/logger.py +195 -0
- shared/models/__init__.py +47 -0
- shared/models/action_result.py +77 -0
- shared/models/audit_models.py +106 -0
- shared/models/audit_rendering.py +30 -0
- shared/models/capability_models.py +22 -0
- shared/models/constitutional_validation.py +185 -0
- shared/models/drift_models.py +24 -0
- shared/models/embedding_payload.py +45 -0
- shared/models/execution_models.py +71 -0
- shared/models/pattern_graph.py +62 -0
- shared/models/prompt_model.py +244 -0
- shared/models/refusal_result.py +294 -0
- shared/models/remediation.py +35 -0
- shared/models/validation_result.py +34 -0
- shared/models/vector_models.py +62 -0
- shared/models/workflow_models.py +242 -0
- shared/path_resolver.py +408 -0
- shared/path_utils.py +60 -0
- shared/processors/base_processor.py +171 -0
- shared/processors/yaml_processor.py +72 -0
- shared/protocols/__init__.py +21 -0
- shared/protocols/brain_services.py +35 -0
- shared/protocols/cognitive.py +35 -0
- shared/protocols/executor.py +47 -0
- shared/protocols/interpreter.py +24 -0
- shared/protocols/knowledge.py +21 -0
- shared/protocols/llm.py +25 -0
- shared/protocols/typer_protocols.py +37 -0
- shared/time.py +18 -0
- shared/universal.py +43 -0
- shared/utils/__init__.py +81 -0
- shared/utils/audit_grouping.py +50 -0
- shared/utils/common_knowledge.py +82 -0
- shared/utils/domain_mapper.py +61 -0
- shared/utils/embedding_utils.py +182 -0
- shared/utils/glob_match.py +93 -0
- shared/utils/header_tools.py +177 -0
- shared/utils/parallel_processor.py +60 -0
- shared/utils/parsing.py +189 -0
- shared/utils/path_utils.py +268 -0
- shared/utils/subprocess_utils.py +87 -0
- shared/workers/__init__.py +19 -0
- shared/workers/base.py +533 -0
- shared/workers/declaration_validator.py +124 -0
- shared/workers/loop_hold_telemetry.py +210 -0
- shared/workers/schedule.py +123 -0
- will/__init__.py +4 -0
- will/agents/__init__.py +4 -0
- will/agents/base_planner.py +133 -0
- will/agents/code_generation/__init__.py +15 -0
- will/agents/code_generation/code_generator.py +247 -0
- will/agents/code_generation/context_formatters.py +99 -0
- will/agents/code_generation/correction_engine.py +157 -0
- will/agents/code_generation/extraction.py +165 -0
- will/agents/code_generation/pattern_validator.py +264 -0
- will/agents/code_generation/prompt_builders.py +209 -0
- will/agents/coder_agent.py +229 -0
- will/agents/coder_agent_refusal_handler.py +168 -0
- will/agents/cognitive_orchestrator.py +152 -0
- will/agents/conversational/__init__.py +13 -0
- will/agents/conversational/agent.py +271 -0
- will/agents/conversational/factory.py +72 -0
- will/agents/conversational/helpers.py +116 -0
- will/agents/execution_agent.py +294 -0
- will/agents/governance_mixin.py +132 -0
- will/agents/planner_agent.py +261 -0
- will/agents/resource_selector.py +228 -0
- will/agents/strategic_auditor/__init__.py +15 -0
- will/agents/strategic_auditor/agent.py +199 -0
- will/agents/strategic_auditor/context_gatherer.py +586 -0
- will/agents/strategic_auditor/effects.py +136 -0
- will/agents/strategic_auditor/models.py +61 -0
- will/agents/strategic_auditor/reasoning.py +169 -0
- will/agents/tagger_agent.py +294 -0
- will/agents/traced_agent_mixin.py +33 -0
- will/autonomy/__init__.py +20 -0
- will/autonomy/autonomous_developer.py +127 -0
- will/autonomy/proposal.py +585 -0
- will/autonomy/proposal_execution_pipeline.py +264 -0
- will/autonomy/proposal_executor.py +410 -0
- will/autonomy/proposal_mapper.py +187 -0
- will/autonomy/proposal_repository.py +118 -0
- will/autonomy/proposal_service.py +251 -0
- will/autonomy/proposal_state_manager.py +239 -0
- will/deciders/__init__.py +9 -0
- will/deciders/governance_decider.py +207 -0
- will/governance/__init__.py +13 -0
- will/governance/audit_remediation_runner.py +197 -0
- will/governance/audit_runner.py +368 -0
- will/governance/census_runner.py +278 -0
- will/governance/coverage_runner.py +489 -0
- will/governance/daemon_runner.py +164 -0
- will/governance/fix_runner.py +693 -0
- will/governance/inspect_runner.py +521 -0
- will/governance/integrity_runner.py +66 -0
- will/governance/lint_runner.py +93 -0
- will/governance/refactor_runner.py +372 -0
- will/governance/sync_runner.py +186 -0
- will/interpreters/__init__.py +44 -0
- will/interpreters/cli_args_interpreter.py +106 -0
- will/interpreters/natural_language_interpreter.py +276 -0
- will/interpreters/request_interpreter.py +126 -0
- will/lifecycle/__init__.py +12 -0
- will/lifecycle/integration_runner.py +54 -0
- will/maintenance/metadata_scribe_service.py +64 -0
- will/orchestration/__init__.py +4 -0
- will/orchestration/cognitive_service.py +185 -0
- will/orchestration/decision_tracer.py +257 -0
- will/orchestration/intent_alignment.py +59 -0
- will/orchestration/intent_guard.py +20 -0
- will/orchestration/phase_registry.py +92 -0
- will/orchestration/process_orchestrator.py +270 -0
- will/orchestration/prompt_pipeline.py +174 -0
- will/orchestration/remediation_orchestrator.py +292 -0
- will/orchestration/self_correction_engine.py +154 -0
- will/orchestration/validation_pipeline.py +45 -0
- will/orchestration/workflow_orchestrator.py +277 -0
- will/phases/__init__.py +24 -0
- will/phases/audit_phase.py +152 -0
- will/phases/canary/pytest_runner.py +156 -0
- will/phases/canary/result_builder.py +130 -0
- will/phases/canary/test_discovery.py +104 -0
- will/phases/canary_validation_phase.py +188 -0
- will/phases/code_generation/artifact_saver.py +175 -0
- will/phases/code_generation/code_sensor.py +117 -0
- will/phases/code_generation/file_path_extractor.py +53 -0
- will/phases/code_generation/work_directory_manager.py +83 -0
- will/phases/code_generation_phase.py +480 -0
- will/phases/execution_phase.py +179 -0
- will/phases/interpret_phase.py +266 -0
- will/phases/load_phase.py +102 -0
- will/phases/parse_phase.py +117 -0
- will/phases/planning_phase.py +182 -0
- will/phases/runtime_phase.py +112 -0
- will/phases/sandbox_validation_phase.py +130 -0
- will/phases/style_check_phase.py +209 -0
- will/phases/test_generation_phase.py +159 -0
- will/self_healing/alignment/persistence.py +53 -0
- will/self_healing/alignment/sandbox.py +51 -0
- will/self_healing/alignment/specialists.py +165 -0
- will/self_healing/alignment_orchestrator.py +140 -0
- will/self_healing/audit_remediation_service.py +199 -0
- will/self_healing/batch_remediation_service.py +280 -0
- will/self_healing/capability_reconciliation_service.py +96 -0
- will/self_healing/capability_tagging_service.py +224 -0
- will/self_healing/clarity_service.py +204 -0
- will/self_healing/complexity_service.py +260 -0
- will/self_healing/context_aware_test_generator.py +298 -0
- will/self_healing/coverage_remediation_service.py +97 -0
- will/self_healing/coverage_watcher.py +192 -0
- will/self_healing/enrichment_service.py +211 -0
- will/self_healing/linelength_service.py +168 -0
- will/self_healing/modularity_remediation_service.py +203 -0
- will/self_healing/remediation_evidence_writer.py +144 -0
- will/self_healing/remediation_executor.py +113 -0
- will/self_healing/remediation_interpretation/__init__.py +1 -0
- will/self_healing/remediation_interpretation/file_context_assembler.py +383 -0
- will/self_healing/remediation_interpretation/file_role_detector.py +599 -0
- will/self_healing/remediation_interpretation/finding_normalizer.py +221 -0
- will/self_healing/remediation_interpretation/models.py +198 -0
- will/self_healing/remediation_interpretation/reasoning_brief_builder.py +235 -0
- will/self_healing/remediation_interpretation/responsibility_extractor.py +421 -0
- will/self_healing/remediation_interpretation/service.py +202 -0
- will/self_healing/remediation_interpretation/strategy_catalog.py +252 -0
- will/self_healing/remediation_interpretation/strategy_selector.py +395 -0
- will/self_healing/remediation_pattern_matcher.py +126 -0
- will/self_healing/simple_test_generator.py +252 -0
- will/self_healing/single_file_remediation.py +137 -0
- will/self_healing/test_generation/automatic_repair.py +377 -0
- will/self_healing/test_generation/code_extractor.py +238 -0
- will/self_healing/test_generation/context_builder.py +140 -0
- will/self_healing/test_generation/executor.py +64 -0
- will/self_healing/test_generation/failure_parser.py +37 -0
- will/self_healing/test_generation/generation_workflow.py +140 -0
- will/self_healing/test_generation/generator.py +283 -0
- will/self_healing/test_generation/llm_correction.py +160 -0
- will/self_healing/test_generation/repair_workflow.py +128 -0
- will/self_healing/test_generation/single_test_fixer.py +77 -0
- will/self_healing/test_generation/test_extractor.py +50 -0
- will/self_healing/test_generation/test_scorer.py +53 -0
- will/self_healing/test_generation/test_validator.py +64 -0
- will/self_healing/test_generator.py +12 -0
- will/strategists/__init__.py +46 -0
- will/strategists/base_strategist.py +29 -0
- will/strategists/clarity_strategist.py +55 -0
- will/strategists/complexity_strategist.py +55 -0
- will/strategists/fix_strategist.py +467 -0
- will/strategists/sync_strategist.py +369 -0
- will/strategists/test_strategist.py +140 -0
- will/strategists/validation_strategist.py +315 -0
- will/test_generation/__init__.py +46 -0
- will/test_generation/adaptive_test_generator.py +123 -0
- will/test_generation/artifacts.py +102 -0
- will/test_generation/harness_detection.py +103 -0
- will/test_generation/helpers/__init__.py +14 -0
- will/test_generation/helpers/context_extractor.py +100 -0
- will/test_generation/helpers/test_executor.py +230 -0
- will/test_generation/llm_output.py +62 -0
- will/test_generation/models.py +25 -0
- will/test_generation/persistence.py +248 -0
- will/test_generation/phases/__init__.py +16 -0
- will/test_generation/phases/generation_phase.py +150 -0
- will/test_generation/phases/load_phase.py +53 -0
- will/test_generation/phases/parse_phase.py +50 -0
- will/test_generation/prompt_engine.py +123 -0
- will/test_generation/result_aggregator.py +73 -0
- will/test_generation/sandbox.py +203 -0
- will/test_generation/strategy_link.py +56 -0
- will/test_generation/test_extractor.py +140 -0
- will/test_generation/validation.py +89 -0
- will/tools/__init__.py +13 -0
- will/tools/anchor_builder.py +111 -0
- will/tools/anchor_search.py +73 -0
- will/tools/anchors/discovery.py +55 -0
- will/tools/anchors/storage.py +32 -0
- will/tools/architectural_context_builder.py +94 -0
- will/tools/cognitive_toolbox.py +47 -0
- will/tools/context/code_snippet_extractor.py +83 -0
- will/tools/context/embedding_search.py +76 -0
- will/tools/context/formatter.py +87 -0
- will/tools/context/models.py +38 -0
- will/tools/context/query_builder.py +42 -0
- will/tools/context/retriever.py +182 -0
- will/tools/context/standards.py +53 -0
- will/tools/file_navigator.py +180 -0
- will/tools/layers.py +31 -0
- will/tools/module_anchor_generator.py +137 -0
- will/tools/module_descriptor.py +154 -0
- will/tools/policy_vectorizer.py +184 -0
- will/tools/symbol_finder.py +188 -0
- will/tools/tool_generator.py +103 -0
- will/workers/audit_ingest_worker.py +207 -0
- will/workers/audit_violation_filter.py +108 -0
- will/workers/audit_violation_normalizer.py +108 -0
- will/workers/audit_violation_sensor.py +370 -0
- will/workers/blackboard_shop_manager.py +280 -0
- will/workers/capability_tagger.py +153 -0
- will/workers/circuit_breaker.py +335 -0
- will/workers/coherence_sensor.py +212 -0
- will/workers/commit_reachability_auditor.py +135 -0
- will/workers/db_sync_worker.py +96 -0
- will/workers/governance_embedding/__init__.py +9 -0
- will/workers/governance_embedding/governance_embedder_worker.py +189 -0
- will/workers/intent_inspector.py +599 -0
- will/workers/observer_worker.py +158 -0
- will/workers/prompt_extractor_worker.py +241 -0
- will/workers/proposal_consumer_effects.py +216 -0
- will/workers/proposal_consumer_revival.py +131 -0
- will/workers/proposal_consumer_worker.py +271 -0
- will/workers/proposal_pipeline_shop_manager.py +273 -0
- will/workers/repo_crawler.py +171 -0
- will/workers/repo_embedding/__init__.py +18 -0
- will/workers/repo_embedding/helpers.py +245 -0
- will/workers/repo_embedding/repo_embedder_workers.py +163 -0
- will/workers/test_coverage_sensor.py +208 -0
- will/workers/test_remediator/__init__.py +12 -0
- will/workers/test_remediator/_operations.py +295 -0
- will/workers/test_remediator/worker.py +187 -0
- will/workers/test_runner_sensor.py +430 -0
- will/workers/violation_executor.py +496 -0
- will/workers/violation_remediator.py +394 -0
- will/workers/violation_remediator_blackboard.py +225 -0
- will/workers/violation_remediator_body/__init__.py +12 -0
- will/workers/violation_remediator_body/blackboard.py +139 -0
- will/workers/violation_remediator_body/ceremony.py +154 -0
- will/workers/violation_remediator_body/context.py +70 -0
- will/workers/violation_remediator_body/llm.py +112 -0
- will/workers/violation_remediator_body/models.py +35 -0
- will/workers/violation_remediator_body/worker.py +518 -0
- will/workers/violation_remediator_proposal.py +328 -0
- will/workers/worker_shop_manager.py +244 -0
- will/workflows/__init__.py +23 -0
- will/workflows/dev_sync_reporter.py +274 -0
- will/workflows/dev_sync_workflow.py +118 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
# src/body/evaluators/security_evaluator.py
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
SecurityEvaluator - Identifies security risks and vulnerabilities.
|
|
5
|
+
|
|
6
|
+
Constitutional Alignment:
|
|
7
|
+
- Phase: AUDIT (Quality assessment and pattern detection)
|
|
8
|
+
- Authority: POLICY (Enforces data.security.no_raw_secrets and security rules)
|
|
9
|
+
- Purpose: Evaluate security posture of code and operations
|
|
10
|
+
- Boundary: Read-only analysis, no mutations
|
|
11
|
+
|
|
12
|
+
This component EVALUATES security, does not FIX vulnerabilities.
|
|
13
|
+
Remediation happens in subsequent phases based on evaluation results.
|
|
14
|
+
|
|
15
|
+
Security Dimensions:
|
|
16
|
+
1. **Secrets**: API keys, passwords, tokens in code
|
|
17
|
+
2. **Injection**: SQL injection, command injection risks
|
|
18
|
+
3. **Authentication**: Auth bypass, weak credentials
|
|
19
|
+
4. **Authorization**: Permission checks, access control
|
|
20
|
+
5. **Data**: Sensitive data exposure, encryption
|
|
21
|
+
|
|
22
|
+
Usage:
|
|
23
|
+
evaluator = SecurityEvaluator()
|
|
24
|
+
result = await evaluator.execute(
|
|
25
|
+
file_path="src/services/user.py",
|
|
26
|
+
code_content=code
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
if not result.ok:
|
|
30
|
+
print(f"Security issues: {result.data['vulnerabilities']}")
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
import re
|
|
36
|
+
import time
|
|
37
|
+
from typing import Any, ClassVar
|
|
38
|
+
|
|
39
|
+
from body.evaluators.base_evaluator import BaseEvaluator
|
|
40
|
+
|
|
41
|
+
# from shared.component_primitive import Component, ComponentPhase, ComponentResult
|
|
42
|
+
from shared.component_primitive import ComponentResult
|
|
43
|
+
from shared.logger import getLogger
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
logger = getLogger(__name__)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ID: 38cbc2dd-3201-428c-bd8a-9001d5236768
|
|
50
|
+
class SecurityEvaluator(BaseEvaluator):
|
|
51
|
+
"""
|
|
52
|
+
Evaluates security posture and identifies vulnerabilities.
|
|
53
|
+
|
|
54
|
+
Security Checks:
|
|
55
|
+
- secrets_exposure: Hardcoded API keys, passwords
|
|
56
|
+
- sql_injection: Unsafe SQL query construction
|
|
57
|
+
- command_injection: Unsafe shell command construction
|
|
58
|
+
- path_traversal: Directory traversal vulnerabilities
|
|
59
|
+
- insecure_deserialization: Pickle, eval() usage
|
|
60
|
+
- weak_crypto: MD5, SHA1, weak algorithms
|
|
61
|
+
- sensitive_data_logging: PII in logs
|
|
62
|
+
|
|
63
|
+
Severity Levels:
|
|
64
|
+
- critical: Immediate security risk (secrets exposure, SQL injection)
|
|
65
|
+
- high: Significant risk (command injection, weak crypto)
|
|
66
|
+
- medium: Potential risk (insecure patterns)
|
|
67
|
+
- low: Security concern (missing validations)
|
|
68
|
+
|
|
69
|
+
Output provides:
|
|
70
|
+
- Binary security status (ok: True/False)
|
|
71
|
+
- List of vulnerabilities with severity
|
|
72
|
+
- Security score (0.0-1.0)
|
|
73
|
+
- Risk assessment
|
|
74
|
+
- Remediation guidance
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
# Regex patterns for security checks
|
|
78
|
+
PATTERNS: ClassVar[dict[str, list[str]]] = {
|
|
79
|
+
"api_keys": [
|
|
80
|
+
r"(sk-[a-zA-Z0-9]{32,})", # Generic API key
|
|
81
|
+
r"(AI[a-zA-Z0-9]{32,})", # Anthropic/Ollama pattern
|
|
82
|
+
r"(ghp_[a-zA-Z0-9]{36})", # GitHub token
|
|
83
|
+
r"(xox[baprs]-[a-zA-Z0-9-]{10,})", # Slack token
|
|
84
|
+
],
|
|
85
|
+
"passwords": [
|
|
86
|
+
r"PASSWORD\s*=\s*['\"][^'\"]+['\"]",
|
|
87
|
+
r"password\s*:\s*['\"][^'\"]+['\"]",
|
|
88
|
+
r"pwd\s*=\s*['\"][^'\"]+['\"]",
|
|
89
|
+
],
|
|
90
|
+
"sql_unsafe": [
|
|
91
|
+
r"execute\([^)]*%[^)]*\)", # String formatting in execute
|
|
92
|
+
r"execute\([^)]*\+[^)]*\)", # String concatenation
|
|
93
|
+
r"execute\([^)]*f['\"]", # F-string in execute
|
|
94
|
+
],
|
|
95
|
+
"command_unsafe": [
|
|
96
|
+
r"os\.system\([^)]*\+", # String concat in os.system
|
|
97
|
+
r"subprocess\.(run|call|Popen)\([^)]*\+", # Unsafe subprocess
|
|
98
|
+
r"shell=True", # Shell=True without validation
|
|
99
|
+
],
|
|
100
|
+
"eval_usage": [
|
|
101
|
+
r"\beval\(",
|
|
102
|
+
r"\bexec\(",
|
|
103
|
+
r"pickle\.loads?\(",
|
|
104
|
+
],
|
|
105
|
+
"weak_crypto": [
|
|
106
|
+
r"hashlib\.md5\(",
|
|
107
|
+
r"hashlib\.sha1\(",
|
|
108
|
+
r"random\.random\(", # Weak random for security
|
|
109
|
+
],
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
# ID: 486b01bb-c6e6-493f-a19a-bf0d7a0ed3d8
|
|
113
|
+
async def execute(
|
|
114
|
+
self,
|
|
115
|
+
file_path: str | None = None,
|
|
116
|
+
code_content: str | None = None,
|
|
117
|
+
check_scope: list[str] | None = None,
|
|
118
|
+
**kwargs: Any,
|
|
119
|
+
) -> ComponentResult:
|
|
120
|
+
"""
|
|
121
|
+
Evaluate security posture of code.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
file_path: Path to file being evaluated
|
|
125
|
+
code_content: Code to analyze (if not reading from file)
|
|
126
|
+
check_scope: Specific checks to run (default: all)
|
|
127
|
+
**kwargs: Additional context
|
|
128
|
+
|
|
129
|
+
Returns:
|
|
130
|
+
ComponentResult with security assessment
|
|
131
|
+
"""
|
|
132
|
+
start_time = time.time()
|
|
133
|
+
|
|
134
|
+
# Default to all checks
|
|
135
|
+
scope = check_scope or [
|
|
136
|
+
"secrets_exposure",
|
|
137
|
+
"sql_injection",
|
|
138
|
+
"command_injection",
|
|
139
|
+
"insecure_deserialization",
|
|
140
|
+
"weak_crypto",
|
|
141
|
+
]
|
|
142
|
+
|
|
143
|
+
# Collect vulnerabilities
|
|
144
|
+
vulnerabilities = []
|
|
145
|
+
|
|
146
|
+
if code_content:
|
|
147
|
+
if "secrets_exposure" in scope:
|
|
148
|
+
vulnerabilities.extend(self._check_secrets(code_content, file_path))
|
|
149
|
+
|
|
150
|
+
if "sql_injection" in scope:
|
|
151
|
+
vulnerabilities.extend(
|
|
152
|
+
self._check_sql_injection(code_content, file_path)
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
if "command_injection" in scope:
|
|
156
|
+
vulnerabilities.extend(
|
|
157
|
+
self._check_command_injection(code_content, file_path)
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
if "insecure_deserialization" in scope:
|
|
161
|
+
vulnerabilities.extend(
|
|
162
|
+
self._check_insecure_deserialization(code_content, file_path)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
if "weak_crypto" in scope:
|
|
166
|
+
vulnerabilities.extend(self._check_weak_crypto(code_content, file_path))
|
|
167
|
+
|
|
168
|
+
# Calculate security score
|
|
169
|
+
security_score = self._calculate_score(vulnerabilities)
|
|
170
|
+
|
|
171
|
+
# Determine if security is acceptable
|
|
172
|
+
# Critical or High vulnerabilities = fail
|
|
173
|
+
blocking_vulns = [
|
|
174
|
+
v for v in vulnerabilities if v["severity"] in ["critical", "high"]
|
|
175
|
+
]
|
|
176
|
+
ok = len(blocking_vulns) == 0
|
|
177
|
+
|
|
178
|
+
logger.info(
|
|
179
|
+
"SecurityEvaluator: %s (score: %.2f, %d vulnerabilities)",
|
|
180
|
+
"PASS" if ok else "FAIL",
|
|
181
|
+
security_score,
|
|
182
|
+
len(vulnerabilities),
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return ComponentResult(
|
|
186
|
+
component_id=self.component_id,
|
|
187
|
+
ok=ok,
|
|
188
|
+
phase=self.phase,
|
|
189
|
+
data={
|
|
190
|
+
"vulnerabilities": vulnerabilities,
|
|
191
|
+
"security_score": security_score,
|
|
192
|
+
"risk_level": self._assess_risk(vulnerabilities),
|
|
193
|
+
"check_scope": scope,
|
|
194
|
+
},
|
|
195
|
+
confidence=security_score,
|
|
196
|
+
next_suggested="security_remediation" if vulnerabilities else None,
|
|
197
|
+
metadata={
|
|
198
|
+
"file_path": file_path,
|
|
199
|
+
"critical_count": len(
|
|
200
|
+
[v for v in vulnerabilities if v["severity"] == "critical"]
|
|
201
|
+
),
|
|
202
|
+
"high_count": len(
|
|
203
|
+
[v for v in vulnerabilities if v["severity"] == "high"]
|
|
204
|
+
),
|
|
205
|
+
"medium_count": len(
|
|
206
|
+
[v for v in vulnerabilities if v["severity"] == "medium"]
|
|
207
|
+
),
|
|
208
|
+
},
|
|
209
|
+
duration_sec=time.time() - start_time,
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
# ID: 33fc128d-2634-4561-8930-3459a8d757cc
|
|
213
|
+
def _check_secrets(self, code: str, file_path: str | None) -> list[dict[str, Any]]:
|
|
214
|
+
"""Check for hardcoded secrets (API keys, passwords)."""
|
|
215
|
+
vulnerabilities = []
|
|
216
|
+
|
|
217
|
+
# Check API keys
|
|
218
|
+
for pattern in self.PATTERNS["api_keys"]:
|
|
219
|
+
matches = re.finditer(pattern, code)
|
|
220
|
+
for match in matches:
|
|
221
|
+
vulnerabilities.append(
|
|
222
|
+
{
|
|
223
|
+
"type": "secrets_exposure",
|
|
224
|
+
"severity": "critical",
|
|
225
|
+
"message": "Hardcoded API key detected",
|
|
226
|
+
"file_path": file_path,
|
|
227
|
+
"pattern": pattern,
|
|
228
|
+
"matched_text": match.group(0)[:10] + "...", # Redact
|
|
229
|
+
"remediation": "Store secrets in database using SecretsService",
|
|
230
|
+
}
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
# Check passwords
|
|
234
|
+
for pattern in self.PATTERNS["passwords"]:
|
|
235
|
+
matches = re.finditer(pattern, code, re.IGNORECASE)
|
|
236
|
+
for match in matches:
|
|
237
|
+
vulnerabilities.append(
|
|
238
|
+
{
|
|
239
|
+
"type": "secrets_exposure",
|
|
240
|
+
"severity": "critical",
|
|
241
|
+
"message": "Hardcoded password detected",
|
|
242
|
+
"file_path": file_path,
|
|
243
|
+
"pattern": pattern,
|
|
244
|
+
"remediation": "Use SecretService.get_secret() for password retrieval",
|
|
245
|
+
}
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
return vulnerabilities
|
|
249
|
+
|
|
250
|
+
# ID: 6dcecf50-1498-4274-87c5-a804d273fe1b
|
|
251
|
+
def _check_sql_injection(
|
|
252
|
+
self, code: str, file_path: str | None
|
|
253
|
+
) -> list[dict[str, Any]]:
|
|
254
|
+
"""Check for SQL injection vulnerabilities."""
|
|
255
|
+
vulnerabilities = []
|
|
256
|
+
|
|
257
|
+
for pattern in self.PATTERNS["sql_unsafe"]:
|
|
258
|
+
matches = re.finditer(pattern, code)
|
|
259
|
+
for match in matches:
|
|
260
|
+
vulnerabilities.append(
|
|
261
|
+
{
|
|
262
|
+
"type": "sql_injection",
|
|
263
|
+
"severity": "critical",
|
|
264
|
+
"message": "Potential SQL injection vulnerability",
|
|
265
|
+
"file_path": file_path,
|
|
266
|
+
"pattern": pattern,
|
|
267
|
+
"code_snippet": match.group(0),
|
|
268
|
+
"remediation": "Use parameterized queries with text() binding or ORM methods",
|
|
269
|
+
}
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
return vulnerabilities
|
|
273
|
+
|
|
274
|
+
# ID: 78cc9f10-458f-4b1b-935e-4d273b1ffbb5
|
|
275
|
+
def _check_command_injection(
|
|
276
|
+
self, code: str, file_path: str | None
|
|
277
|
+
) -> list[dict[str, Any]]:
|
|
278
|
+
"""Check for command injection vulnerabilities."""
|
|
279
|
+
vulnerabilities = []
|
|
280
|
+
|
|
281
|
+
for pattern in self.PATTERNS["command_unsafe"]:
|
|
282
|
+
matches = re.finditer(pattern, code)
|
|
283
|
+
for match in matches:
|
|
284
|
+
severity = "critical" if "shell=True" in match.group(0) else "high"
|
|
285
|
+
vulnerabilities.append(
|
|
286
|
+
{
|
|
287
|
+
"type": "command_injection",
|
|
288
|
+
"severity": severity,
|
|
289
|
+
"message": "Potential command injection vulnerability",
|
|
290
|
+
"file_path": file_path,
|
|
291
|
+
"pattern": pattern,
|
|
292
|
+
"code_snippet": match.group(0),
|
|
293
|
+
"remediation": "Use list arguments instead of string concatenation; avoid shell=True",
|
|
294
|
+
}
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
return vulnerabilities
|
|
298
|
+
|
|
299
|
+
# ID: 5c43ccb9-1e8b-4c61-b74b-fb92395896f8
|
|
300
|
+
def _check_insecure_deserialization(
|
|
301
|
+
self, code: str, file_path: str | None
|
|
302
|
+
) -> list[dict[str, Any]]:
|
|
303
|
+
"""Check for insecure deserialization (eval, exec, pickle)."""
|
|
304
|
+
vulnerabilities = []
|
|
305
|
+
|
|
306
|
+
for pattern in self.PATTERNS["eval_usage"]:
|
|
307
|
+
matches = re.finditer(pattern, code)
|
|
308
|
+
for match in matches:
|
|
309
|
+
func_name = match.group(0).split("(")[0]
|
|
310
|
+
vulnerabilities.append(
|
|
311
|
+
{
|
|
312
|
+
"type": "insecure_deserialization",
|
|
313
|
+
"severity": "high",
|
|
314
|
+
"message": f"Unsafe deserialization using {func_name}",
|
|
315
|
+
"file_path": file_path,
|
|
316
|
+
"pattern": pattern,
|
|
317
|
+
"code_snippet": match.group(0),
|
|
318
|
+
"remediation": f"Avoid {func_name}; use safe alternatives like ast.literal_eval or json",
|
|
319
|
+
}
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
return vulnerabilities
|
|
323
|
+
|
|
324
|
+
# ID: 23ef335e-2536-46b4-9bdd-44b3bb300180
|
|
325
|
+
def _check_weak_crypto(
|
|
326
|
+
self, code: str, file_path: str | None
|
|
327
|
+
) -> list[dict[str, Any]]:
|
|
328
|
+
"""Check for weak cryptographic algorithms."""
|
|
329
|
+
vulnerabilities = []
|
|
330
|
+
|
|
331
|
+
for pattern in self.PATTERNS["weak_crypto"]:
|
|
332
|
+
matches = re.finditer(pattern, code)
|
|
333
|
+
for match in matches:
|
|
334
|
+
algo = match.group(0)
|
|
335
|
+
vulnerabilities.append(
|
|
336
|
+
{
|
|
337
|
+
"type": "weak_crypto",
|
|
338
|
+
"severity": "high", # Weak crypto is a real security issue
|
|
339
|
+
"message": f"Weak cryptographic algorithm: {algo}",
|
|
340
|
+
"file_path": file_path,
|
|
341
|
+
"pattern": pattern,
|
|
342
|
+
"code_snippet": match.group(0),
|
|
343
|
+
"remediation": "Use SHA256 or better; use secrets.token_bytes() for random",
|
|
344
|
+
}
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
return vulnerabilities
|
|
348
|
+
|
|
349
|
+
# ID: ad6da84d-5870-4c55-ae35-5c18f895587d
|
|
350
|
+
def _calculate_score(self, vulnerabilities: list[dict[str, Any]]) -> float:
|
|
351
|
+
"""
|
|
352
|
+
Calculate security score (0.0-1.0).
|
|
353
|
+
|
|
354
|
+
Score decreases based on vulnerability severity:
|
|
355
|
+
- critical: -0.4 per vuln
|
|
356
|
+
- high: -0.2 per vuln
|
|
357
|
+
- medium: -0.1 per vuln
|
|
358
|
+
- low: -0.05 per vuln
|
|
359
|
+
"""
|
|
360
|
+
score = 1.0
|
|
361
|
+
|
|
362
|
+
severity_penalties = {
|
|
363
|
+
"critical": 0.4,
|
|
364
|
+
"high": 0.2,
|
|
365
|
+
"medium": 0.1,
|
|
366
|
+
"low": 0.05,
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
for vuln in vulnerabilities:
|
|
370
|
+
penalty = severity_penalties.get(vuln["severity"], 0.1)
|
|
371
|
+
score -= penalty
|
|
372
|
+
|
|
373
|
+
return max(0.0, round(score, 2))
|
|
374
|
+
|
|
375
|
+
# ID: e0a92afc-1159-479c-a204-6324a0197a91
|
|
376
|
+
def _assess_risk(self, vulnerabilities: list[dict[str, Any]]) -> str:
|
|
377
|
+
"""
|
|
378
|
+
Assess overall risk level.
|
|
379
|
+
|
|
380
|
+
Returns: "critical" | "high" | "medium" | "low" | "none"
|
|
381
|
+
"""
|
|
382
|
+
if not vulnerabilities:
|
|
383
|
+
return "none"
|
|
384
|
+
|
|
385
|
+
severities = [v["severity"] for v in vulnerabilities]
|
|
386
|
+
|
|
387
|
+
if "critical" in severities:
|
|
388
|
+
return "critical"
|
|
389
|
+
if "high" in severities:
|
|
390
|
+
return "high"
|
|
391
|
+
if "medium" in severities:
|
|
392
|
+
return "medium"
|
|
393
|
+
return "low"
|
body/flows/__init__.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# src/body/flows/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
Constitutional Flow layer — composition primitives between AtomicActions and Workers.
|
|
4
|
+
|
|
5
|
+
Flows are declared in .intent/flows/*.yaml and loaded by FlowRegistry at
|
|
6
|
+
first access. No Flow is hardcoded here.
|
|
7
|
+
|
|
8
|
+
Constitutional alignment: CORE-Flow.md
|
|
9
|
+
|
|
10
|
+
Hierarchy:
|
|
11
|
+
AtomicAction — does exactly one thing
|
|
12
|
+
↓ composes into
|
|
13
|
+
Flow — named, ordered sequence of AtomicActions or Flows
|
|
14
|
+
↓ invoked by
|
|
15
|
+
Worker — constitutional officer that decides when and why
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
from body.flows.executor import FlowExecutor
|
|
21
|
+
from body.flows.registry import FlowDefinition, FlowStep, StepKind, flow_registry
|
|
22
|
+
from body.flows.result import FlowResult, StepResult
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = [
|
|
26
|
+
"FlowDefinition",
|
|
27
|
+
"FlowExecutor",
|
|
28
|
+
"FlowResult",
|
|
29
|
+
"FlowStep",
|
|
30
|
+
"StepKind",
|
|
31
|
+
"StepResult",
|
|
32
|
+
"flow_registry",
|
|
33
|
+
]
|
body/flows/executor.py
ADDED
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
# src/body/flows/executor.py
|
|
2
|
+
"""
|
|
3
|
+
FlowExecutor — the Body-layer dispatcher for constitutional Flows.
|
|
4
|
+
|
|
5
|
+
Mirrors ActionExecutor in structure and governance contract. Resolves
|
|
6
|
+
a flow_id to its FlowDefinition, executes each step in declaration order
|
|
7
|
+
via ActionExecutor (for AtomicAction steps) or recursively via
|
|
8
|
+
FlowExecutor (for nested Flow steps), and returns a FlowResult.
|
|
9
|
+
|
|
10
|
+
Constitutional alignment: CORE-Flow.md §6
|
|
11
|
+
|
|
12
|
+
Key invariants enforced here:
|
|
13
|
+
- write=False is propagated to every step without exception.
|
|
14
|
+
- A required step failure halts execution immediately.
|
|
15
|
+
- An optional step failure is recorded and execution continues.
|
|
16
|
+
- FlowExecutor never posts to the Blackboard — that is Worker territory.
|
|
17
|
+
- FlowExecutor never creates Proposals — that is Worker territory.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
import time
|
|
23
|
+
from typing import TYPE_CHECKING, Any
|
|
24
|
+
|
|
25
|
+
from body.flows.registry import FlowStep, StepKind, flow_registry
|
|
26
|
+
from body.flows.result import FlowResult, StepResult
|
|
27
|
+
from shared.logger import getLogger
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
if TYPE_CHECKING:
|
|
31
|
+
from shared.context import CoreContext
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
logger = getLogger(__name__)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# ID: ebd9a0de-3e90-4c97-af3a-49847598fda8
|
|
38
|
+
class FlowExecutor:
|
|
39
|
+
"""
|
|
40
|
+
Universal execution gateway for constitutional Flows.
|
|
41
|
+
|
|
42
|
+
Architecture:
|
|
43
|
+
- Resolves flow_id from FlowRegistry
|
|
44
|
+
- Dispatches AtomicAction steps via ActionExecutor
|
|
45
|
+
- Dispatches nested Flow steps recursively via FlowExecutor
|
|
46
|
+
- Propagates write=False to every step unconditionally
|
|
47
|
+
- Halts on required step failure; continues on optional step failure
|
|
48
|
+
- Returns FlowResult — never raises
|
|
49
|
+
|
|
50
|
+
Usage:
|
|
51
|
+
executor = FlowExecutor(core_context)
|
|
52
|
+
result = await executor.execute("flow.fix_code", write=True)
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
def __init__(self, core_context: CoreContext) -> None:
|
|
56
|
+
self._core_context = core_context
|
|
57
|
+
self._registry = flow_registry
|
|
58
|
+
|
|
59
|
+
# ID: 6896dd9d-063b-4c19-86e5-246b28738651
|
|
60
|
+
async def execute(
|
|
61
|
+
self,
|
|
62
|
+
flow_id: str,
|
|
63
|
+
write: bool = False,
|
|
64
|
+
**params: Any,
|
|
65
|
+
) -> FlowResult:
|
|
66
|
+
"""
|
|
67
|
+
Execute a Flow by flow_id.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
flow_id: The registered flow_id to execute.
|
|
71
|
+
write: Dry-run flag. Propagated to every step unchanged.
|
|
72
|
+
write=False means no step may mutate state.
|
|
73
|
+
**params: Runtime parameters merged with each step's static
|
|
74
|
+
params. Step static params are overridden by caller
|
|
75
|
+
params of the same key.
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
FlowResult — always. Never raises.
|
|
79
|
+
"""
|
|
80
|
+
start = time.time()
|
|
81
|
+
|
|
82
|
+
# 1. Resolve flow from registry
|
|
83
|
+
definition = self._registry.get(flow_id)
|
|
84
|
+
if not definition:
|
|
85
|
+
logger.error("FlowExecutor: flow_id not found in registry: %s", flow_id)
|
|
86
|
+
return FlowResult(
|
|
87
|
+
flow_id=flow_id,
|
|
88
|
+
ok=False,
|
|
89
|
+
steps=[],
|
|
90
|
+
duration_sec=time.time() - start,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
logger.info(
|
|
94
|
+
"FlowExecutor: executing flow '%s' (%d steps, write=%s)",
|
|
95
|
+
flow_id,
|
|
96
|
+
len(definition.steps),
|
|
97
|
+
write,
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# 2. Execute steps in declaration order
|
|
101
|
+
step_results: list[StepResult] = []
|
|
102
|
+
|
|
103
|
+
for step in definition.steps:
|
|
104
|
+
step_result = await self._execute_step(
|
|
105
|
+
step, write=write, caller_params=params
|
|
106
|
+
)
|
|
107
|
+
step_results.append(step_result)
|
|
108
|
+
|
|
109
|
+
if not step_result.ok and step.required:
|
|
110
|
+
# Required step failed — halt and return immediately
|
|
111
|
+
logger.error(
|
|
112
|
+
"FlowExecutor: required step '%s' failed in flow '%s' — halting",
|
|
113
|
+
step.ref_id,
|
|
114
|
+
flow_id,
|
|
115
|
+
)
|
|
116
|
+
return FlowResult(
|
|
117
|
+
flow_id=flow_id,
|
|
118
|
+
ok=False,
|
|
119
|
+
steps=step_results,
|
|
120
|
+
duration_sec=time.time() - start,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
if not step_result.ok and not step.required:
|
|
124
|
+
logger.warning(
|
|
125
|
+
"FlowExecutor: optional step '%s' failed in flow '%s' — continuing",
|
|
126
|
+
step.ref_id,
|
|
127
|
+
flow_id,
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
duration = time.time() - start
|
|
131
|
+
all_required_passed = all(s.ok for s in step_results if s.required)
|
|
132
|
+
|
|
133
|
+
logger.info(
|
|
134
|
+
"FlowExecutor: flow '%s' complete in %.2fs — ok=%s",
|
|
135
|
+
flow_id,
|
|
136
|
+
duration,
|
|
137
|
+
all_required_passed,
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
return FlowResult(
|
|
141
|
+
flow_id=flow_id,
|
|
142
|
+
ok=all_required_passed,
|
|
143
|
+
steps=step_results,
|
|
144
|
+
duration_sec=duration,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# ID: 5ead0cc7-b5bc-4c9c-8d23-242ebf238e24
|
|
148
|
+
async def _execute_step(
|
|
149
|
+
self,
|
|
150
|
+
step: FlowStep,
|
|
151
|
+
write: bool,
|
|
152
|
+
caller_params: dict[str, Any],
|
|
153
|
+
) -> StepResult:
|
|
154
|
+
"""
|
|
155
|
+
Execute a single step — dispatches to ActionExecutor or
|
|
156
|
+
recursively to FlowExecutor depending on step.kind.
|
|
157
|
+
|
|
158
|
+
write=False is enforced unconditionally — a step cannot
|
|
159
|
+
escalate to write mode even if its static params request it.
|
|
160
|
+
"""
|
|
161
|
+
# Merge params: static step params first, then caller params.
|
|
162
|
+
# step.consumes governs caller-param forwarding. None means "forward
|
|
163
|
+
# all caller params" (the safe default — silent swallow is a worse
|
|
164
|
+
# failure mode than an unexpected-kwarg TypeError in a governed
|
|
165
|
+
# system; see issue #445). A tuple restricts forwarding to those
|
|
166
|
+
# keys (explicit allowlist). An empty tuple drops everything
|
|
167
|
+
# explicitly. Static params always pass through. Caller-supplied
|
|
168
|
+
# keys override static params on conflict.
|
|
169
|
+
if step.consumes is None:
|
|
170
|
+
filtered_caller: dict[str, Any] = dict(caller_params)
|
|
171
|
+
else:
|
|
172
|
+
filtered_caller = {
|
|
173
|
+
k: v for k, v in caller_params.items() if k in step.consumes
|
|
174
|
+
}
|
|
175
|
+
merged_params = {**step.params, **filtered_caller}
|
|
176
|
+
|
|
177
|
+
step_start = time.time()
|
|
178
|
+
|
|
179
|
+
if step.kind == StepKind.ACTION:
|
|
180
|
+
return await self._execute_action_step(
|
|
181
|
+
step, write, merged_params, step_start
|
|
182
|
+
)
|
|
183
|
+
elif step.kind == StepKind.FLOW:
|
|
184
|
+
return await self._execute_flow_step(step, write, merged_params, step_start)
|
|
185
|
+
else:
|
|
186
|
+
# Defensive — StepKind is an enum, this should never fire
|
|
187
|
+
logger.error(
|
|
188
|
+
"FlowExecutor: unknown step kind '%s' for step '%s'",
|
|
189
|
+
step.kind,
|
|
190
|
+
step.ref_id,
|
|
191
|
+
)
|
|
192
|
+
return StepResult(
|
|
193
|
+
ref_id=step.ref_id,
|
|
194
|
+
required=step.required,
|
|
195
|
+
ok=False,
|
|
196
|
+
data={"error": f"Unknown step kind: {step.kind}"},
|
|
197
|
+
duration_sec=time.time() - step_start,
|
|
198
|
+
kind=str(step.kind),
|
|
199
|
+
)
|
|
200
|
+
|
|
201
|
+
# ID: cb8eea14-5b0e-4d2b-bcb6-ebd45ab9d14f
|
|
202
|
+
async def _execute_action_step(
|
|
203
|
+
self,
|
|
204
|
+
step: FlowStep,
|
|
205
|
+
write: bool,
|
|
206
|
+
params: dict[str, Any],
|
|
207
|
+
step_start: float,
|
|
208
|
+
) -> StepResult:
|
|
209
|
+
"""Dispatch an AtomicAction step via ActionExecutor."""
|
|
210
|
+
from body.atomic.executor import ActionExecutor
|
|
211
|
+
|
|
212
|
+
executor = ActionExecutor(self._core_context)
|
|
213
|
+
|
|
214
|
+
try:
|
|
215
|
+
action_result = await executor.execute(step.ref_id, write=write, **params)
|
|
216
|
+
return StepResult(
|
|
217
|
+
ref_id=step.ref_id,
|
|
218
|
+
required=step.required,
|
|
219
|
+
ok=action_result.ok,
|
|
220
|
+
data=action_result.data
|
|
221
|
+
if isinstance(action_result.data, dict)
|
|
222
|
+
else {"result": str(action_result.data)},
|
|
223
|
+
duration_sec=action_result.duration_sec,
|
|
224
|
+
kind="action",
|
|
225
|
+
)
|
|
226
|
+
except Exception as exc:
|
|
227
|
+
logger.error(
|
|
228
|
+
"FlowExecutor: action step '%s' raised: %s",
|
|
229
|
+
step.ref_id,
|
|
230
|
+
exc,
|
|
231
|
+
exc_info=True,
|
|
232
|
+
)
|
|
233
|
+
return StepResult(
|
|
234
|
+
ref_id=step.ref_id,
|
|
235
|
+
required=step.required,
|
|
236
|
+
ok=False,
|
|
237
|
+
data={"error": str(exc)},
|
|
238
|
+
duration_sec=time.time() - step_start,
|
|
239
|
+
kind="action",
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
# ID: 28e9c338-d7ad-49a5-95de-e91edb324989
|
|
243
|
+
async def _execute_flow_step(
|
|
244
|
+
self,
|
|
245
|
+
step: FlowStep,
|
|
246
|
+
write: bool,
|
|
247
|
+
params: dict[str, Any],
|
|
248
|
+
step_start: float,
|
|
249
|
+
) -> StepResult:
|
|
250
|
+
"""Dispatch a nested Flow step recursively via FlowExecutor."""
|
|
251
|
+
try:
|
|
252
|
+
nested_result = await self.execute(step.ref_id, write=write, **params)
|
|
253
|
+
return StepResult(
|
|
254
|
+
ref_id=step.ref_id,
|
|
255
|
+
required=step.required,
|
|
256
|
+
ok=nested_result.ok,
|
|
257
|
+
data=nested_result.data,
|
|
258
|
+
duration_sec=nested_result.duration_sec,
|
|
259
|
+
kind="flow",
|
|
260
|
+
)
|
|
261
|
+
except Exception as exc:
|
|
262
|
+
logger.error(
|
|
263
|
+
"FlowExecutor: nested flow step '%s' raised: %s",
|
|
264
|
+
step.ref_id,
|
|
265
|
+
exc,
|
|
266
|
+
exc_info=True,
|
|
267
|
+
)
|
|
268
|
+
return StepResult(
|
|
269
|
+
ref_id=step.ref_id,
|
|
270
|
+
required=step.required,
|
|
271
|
+
ok=False,
|
|
272
|
+
data={"error": str(exc)},
|
|
273
|
+
duration_sec=time.time() - step_start,
|
|
274
|
+
kind="flow",
|
|
275
|
+
)
|