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,305 @@
|
|
|
1
|
+
# src/body/services/blackboard_service/blackboard_proposal_service.py
|
|
2
|
+
# blackboard_proposal_service.py
|
|
3
|
+
"""Proposal-lifecycle methods that implement the finding↔proposal contract per CORE-Finding.md §7/§7a"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from sqlalchemy import text
|
|
10
|
+
|
|
11
|
+
from shared.logger import getLogger
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
logger = getLogger(__name__)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# ID: f83444e2-fae1-46f0-a704-d592d62a116e
|
|
18
|
+
class BlackboardProposalService:
|
|
19
|
+
# ID: 7f2a3c51-b9d0-48e4-9d2b-4a6f1e8c0b52
|
|
20
|
+
async def defer_entries_to_proposal(
|
|
21
|
+
self, entry_ids: list[str], proposal_id: str
|
|
22
|
+
) -> int:
|
|
23
|
+
"""
|
|
24
|
+
Transition findings to 'deferred_to_proposal' terminal status and
|
|
25
|
+
write the proposal_id into each finding's payload.
|
|
26
|
+
|
|
27
|
+
Implements CORE-Finding.md §7 row 4:
|
|
28
|
+
> The rule has an active RemediationMap entry. A Proposal has been
|
|
29
|
+
> created. The `proposal_id` field in the payload MUST be set to
|
|
30
|
+
> the created Proposal's ID.
|
|
31
|
+
|
|
32
|
+
Only transitions entries currently in 'open' or 'claimed' — matches
|
|
33
|
+
the predicate used by resolve_entries. Entries in any other status
|
|
34
|
+
are left untouched and not counted.
|
|
35
|
+
|
|
36
|
+
Sets resolved_at because 'deferred_to_proposal' is terminal per
|
|
37
|
+
the blackboard_entry_status enum declaration in
|
|
38
|
+
.intent/META/enums.json.
|
|
39
|
+
|
|
40
|
+
Payload merge uses the 'payload = payload || jsonb_build_object(...)'
|
|
41
|
+
idiom already established elsewhere in this service. If an earlier
|
|
42
|
+
proposal_id was written (e.g. in unusual retry flows), this call
|
|
43
|
+
overwrites it with the current value — last-writer-wins, which
|
|
44
|
+
matches the semantic "this finding is now linked to THIS proposal."
|
|
45
|
+
|
|
46
|
+
Returns the count of rows actually updated.
|
|
47
|
+
|
|
48
|
+
Covers:
|
|
49
|
+
- ViolationRemediatorWorker._defer_to_proposal
|
|
50
|
+
"""
|
|
51
|
+
if not entry_ids:
|
|
52
|
+
return 0
|
|
53
|
+
|
|
54
|
+
from body.services.service_registry import ServiceRegistry
|
|
55
|
+
|
|
56
|
+
deferred_count = 0
|
|
57
|
+
async with ServiceRegistry.session() as session:
|
|
58
|
+
async with session.begin():
|
|
59
|
+
for entry_id in entry_ids:
|
|
60
|
+
result = await session.execute(
|
|
61
|
+
text(
|
|
62
|
+
"""
|
|
63
|
+
UPDATE core.blackboard_entries
|
|
64
|
+
SET status = 'deferred_to_proposal',
|
|
65
|
+
resolved_at = now(),
|
|
66
|
+
updated_at = now(),
|
|
67
|
+
payload = payload || jsonb_build_object(
|
|
68
|
+
'proposal_id', cast(:proposal_id as text)
|
|
69
|
+
)
|
|
70
|
+
WHERE id = cast(:entry_id as uuid)
|
|
71
|
+
AND status IN ('open', 'claimed')
|
|
72
|
+
"""
|
|
73
|
+
),
|
|
74
|
+
{"entry_id": entry_id, "proposal_id": proposal_id},
|
|
75
|
+
)
|
|
76
|
+
deferred_count += result.rowcount
|
|
77
|
+
return deferred_count
|
|
78
|
+
|
|
79
|
+
# ID: 5e2d8f1a-94c3-4b07-a8f2-3c7e9b1d6a45
|
|
80
|
+
async def resolve_entries_for_proposal(
|
|
81
|
+
self, entry_ids: list[str], proposal_id: str
|
|
82
|
+
) -> int:
|
|
83
|
+
"""
|
|
84
|
+
Mark each entry in *entry_ids* as resolved AND store the subsuming
|
|
85
|
+
*proposal_id* in its payload. Mirror of defer_entries_to_proposal,
|
|
86
|
+
but with terminal status 'resolved' instead of 'deferred_to_proposal'.
|
|
87
|
+
|
|
88
|
+
Used by ViolationRemediatorWorker's dedup-subsume path: when a
|
|
89
|
+
finding is subsumed by an already-active proposal, it closes as
|
|
90
|
+
'resolved' (the subsuming proposal does not track it in its scope,
|
|
91
|
+
so the §7a revival path does not apply), but the payload pointer
|
|
92
|
+
to the subsuming proposal_id makes the linkage auditable per URS
|
|
93
|
+
Q1.F and ADR-015 D4.
|
|
94
|
+
|
|
95
|
+
Bare resolve_entries (no proposal_id) remains in use by
|
|
96
|
+
TestRemediatorWorker and TestRunnerSensor — those callers do not
|
|
97
|
+
carry a proposal_id at the resolve site and should not be forced
|
|
98
|
+
to invent one.
|
|
99
|
+
|
|
100
|
+
Predicate matches resolve_entries and defer_entries_to_proposal:
|
|
101
|
+
only entries currently in 'open' or 'claimed' transition; rows
|
|
102
|
+
already terminalized or missing are not counted. All updates run
|
|
103
|
+
inside a single transaction. Returns the count of rows actually
|
|
104
|
+
updated.
|
|
105
|
+
|
|
106
|
+
Covers:
|
|
107
|
+
- ViolationRemediatorWorker._resolve_entries (dedup-subsume path)
|
|
108
|
+
"""
|
|
109
|
+
if not entry_ids:
|
|
110
|
+
return 0
|
|
111
|
+
|
|
112
|
+
from body.services.service_registry import ServiceRegistry
|
|
113
|
+
|
|
114
|
+
resolved_count = 0
|
|
115
|
+
async with ServiceRegistry.session() as session:
|
|
116
|
+
async with session.begin():
|
|
117
|
+
for entry_id in entry_ids:
|
|
118
|
+
result = await session.execute(
|
|
119
|
+
text(
|
|
120
|
+
"""
|
|
121
|
+
UPDATE core.blackboard_entries
|
|
122
|
+
SET status = 'resolved',
|
|
123
|
+
resolved_at = now(),
|
|
124
|
+
updated_at = now(),
|
|
125
|
+
payload = payload || jsonb_build_object(
|
|
126
|
+
'proposal_id', cast(:proposal_id as text)
|
|
127
|
+
)
|
|
128
|
+
WHERE id = cast(:entry_id as uuid)
|
|
129
|
+
AND status IN ('open', 'claimed')
|
|
130
|
+
"""
|
|
131
|
+
),
|
|
132
|
+
{"entry_id": entry_id, "proposal_id": proposal_id},
|
|
133
|
+
)
|
|
134
|
+
resolved_count += result.rowcount
|
|
135
|
+
return resolved_count
|
|
136
|
+
|
|
137
|
+
# ID: e1c4b8a7-6f03-4d29-b8a2-9c5d7e0f3a14
|
|
138
|
+
async def revive_findings_for_failed_proposal(
|
|
139
|
+
self, proposal_id: str, failure_reason: str
|
|
140
|
+
) -> dict[str, Any] | None:
|
|
141
|
+
"""
|
|
142
|
+
Restore findings that were deferred to a now-failed proposal back
|
|
143
|
+
to active status, and return the revival outcome.
|
|
144
|
+
|
|
145
|
+
Implements CORE-Finding.md §7a steps 1-2 (state transition only).
|
|
146
|
+
§7a step 3 (posting a `report` entry recording the revival) is the
|
|
147
|
+
calling Worker's responsibility per ADR-011 — this method is
|
|
148
|
+
UPDATE-only. The Worker consumes this method's return value and
|
|
149
|
+
posts the revival report via self.post_report() so the entry
|
|
150
|
+
carries Worker attribution.
|
|
151
|
+
|
|
152
|
+
Revival target is 'awaiting_reaudit', not 'open' (ADR-045). The
|
|
153
|
+
finding's payload was authored when the violation was originally
|
|
154
|
+
posted; after a proposal failure or rejection the underlying file
|
|
155
|
+
may have been refactored, the rule's threshold may have moved, or
|
|
156
|
+
the governor may judge the finding stale. Routing the finding
|
|
157
|
+
through awaiting_reaudit gates the remediator's claim queue until
|
|
158
|
+
AuditViolationSensor's next cycle re-evaluates the rule against
|
|
159
|
+
the current file state and either releases the finding to 'open'
|
|
160
|
+
(violation still holds) or resolves it (cleared). The previous
|
|
161
|
+
immediate-revival-to-'open' behaviour produced a temporal race
|
|
162
|
+
where the remediator could re-claim a stale finding before the
|
|
163
|
+
audit sensor's next cycle ran.
|
|
164
|
+
|
|
165
|
+
The UPDATE filter restricts to status = 'deferred_to_proposal'. This
|
|
166
|
+
protects against retry races and against findings that drifted to
|
|
167
|
+
some other status (abandoned, indeterminate) for unrelated reasons
|
|
168
|
+
— only findings still parked on this proposal's deferral are
|
|
169
|
+
revived. resolved_at is cleared so the row's terminal-state marker
|
|
170
|
+
matches its new non-terminal status (ADR-010 hygiene rule, tracking
|
|
171
|
+
the Option A+ convention from 2026-04-22).
|
|
172
|
+
|
|
173
|
+
Returns:
|
|
174
|
+
None if no findings were revived (revived_count == 0) — nothing
|
|
175
|
+
to report.
|
|
176
|
+
dict with keys ``proposal_id``, ``failure_reason``,
|
|
177
|
+
``revived_count``, ``revived_finding_ids``, ``revived_subjects``
|
|
178
|
+
when one or more rows were revived. Both id and subject lists
|
|
179
|
+
are returned — IDs for precise downstream queries, subjects for
|
|
180
|
+
human-readable audit trails in the revival report payload.
|
|
181
|
+
|
|
182
|
+
The caller MUST NOT rely on this method raising on partial failure.
|
|
183
|
+
Zero rows revived is a legitimate outcome when the failed proposal
|
|
184
|
+
had no findings deferred to it (e.g. proposals created by paths
|
|
185
|
+
other than ViolationRemediatorWorker); the caller receives None
|
|
186
|
+
and skips posting a revival report.
|
|
187
|
+
"""
|
|
188
|
+
from body.services.service_registry import ServiceRegistry
|
|
189
|
+
|
|
190
|
+
async with ServiceRegistry.session() as session:
|
|
191
|
+
async with session.begin():
|
|
192
|
+
# §7a steps 1+2: query-and-reset in one UPDATE ... RETURNING.
|
|
193
|
+
# RETURNING id, subject so the Worker can persist both in
|
|
194
|
+
# the revival report payload (IDs for queries, subjects for
|
|
195
|
+
# audit trails).
|
|
196
|
+
update_result = await session.execute(
|
|
197
|
+
text(
|
|
198
|
+
"""
|
|
199
|
+
UPDATE core.blackboard_entries
|
|
200
|
+
SET status = 'awaiting_reaudit',
|
|
201
|
+
claimed_by = NULL,
|
|
202
|
+
claimed_at = NULL,
|
|
203
|
+
resolved_at = NULL,
|
|
204
|
+
updated_at = now()
|
|
205
|
+
WHERE entry_type = 'finding'
|
|
206
|
+
AND status = 'deferred_to_proposal'
|
|
207
|
+
AND payload->>'proposal_id' = :proposal_id
|
|
208
|
+
RETURNING id, subject
|
|
209
|
+
"""
|
|
210
|
+
),
|
|
211
|
+
{"proposal_id": proposal_id},
|
|
212
|
+
)
|
|
213
|
+
rows = update_result.fetchall()
|
|
214
|
+
revived_ids = [str(row[0]) for row in rows]
|
|
215
|
+
revived_subjects = [str(row[1]) for row in rows]
|
|
216
|
+
|
|
217
|
+
logger.info(
|
|
218
|
+
"Revived %d finding(s) for failed proposal %s (reason: %s)",
|
|
219
|
+
len(revived_ids),
|
|
220
|
+
proposal_id,
|
|
221
|
+
failure_reason,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
if not revived_ids:
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
return {
|
|
228
|
+
"proposal_id": proposal_id,
|
|
229
|
+
"failure_reason": failure_reason,
|
|
230
|
+
"revived_count": len(revived_ids),
|
|
231
|
+
"revived_finding_ids": revived_ids,
|
|
232
|
+
"revived_subjects": revived_subjects,
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
# ID: 90c7c05a-a380-4d5a-9b1e-a911c3ed5d02
|
|
236
|
+
async def resolve_deferred_entries_for_completed_proposal(
|
|
237
|
+
self, proposal_id: str
|
|
238
|
+
) -> dict[str, Any] | None:
|
|
239
|
+
"""
|
|
240
|
+
Mark findings deferred to a now-completed proposal as 'resolved'
|
|
241
|
+
and return the resolution outcome.
|
|
242
|
+
|
|
243
|
+
Success-side mirror of revive_findings_for_failed_proposal: flips
|
|
244
|
+
every finding whose payload.proposal_id matches *proposal_id* and
|
|
245
|
+
is still parked in 'deferred_to_proposal' to terminal 'resolved'
|
|
246
|
+
status, closing the §7-style finding↔proposal lifecycle.
|
|
247
|
+
|
|
248
|
+
The UPDATE filter restricts to status = 'deferred_to_proposal' so
|
|
249
|
+
findings that drifted elsewhere (abandoned, manually overridden)
|
|
250
|
+
are not retroactively re-terminalized. resolved_at is set per the
|
|
251
|
+
ADR-010 hygiene rule for terminal-state rows.
|
|
252
|
+
|
|
253
|
+
Unlike the failure-revival counterpart this method does not post
|
|
254
|
+
a downstream report: no new entry is created (only existing rows
|
|
255
|
+
are flipped), so the ADR-011 Worker-attribution rule does not
|
|
256
|
+
apply. The caller (ProposalExecutor) is therefore not required
|
|
257
|
+
to be a Worker subclass.
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
None if no findings were resolved (resolved_count == 0) —
|
|
261
|
+
nothing to report.
|
|
262
|
+
dict with keys ``proposal_id``, ``resolved_count``,
|
|
263
|
+
``resolved_finding_ids``, ``resolved_subjects`` when one or
|
|
264
|
+
more rows were resolved. Both id and subject lists are
|
|
265
|
+
returned — IDs for precise downstream queries, subjects for
|
|
266
|
+
human-readable audit trails.
|
|
267
|
+
"""
|
|
268
|
+
from body.services.service_registry import ServiceRegistry
|
|
269
|
+
|
|
270
|
+
async with ServiceRegistry.session() as session:
|
|
271
|
+
async with session.begin():
|
|
272
|
+
update_result = await session.execute(
|
|
273
|
+
text(
|
|
274
|
+
"""
|
|
275
|
+
UPDATE core.blackboard_entries
|
|
276
|
+
SET status = 'resolved',
|
|
277
|
+
resolved_at = now(),
|
|
278
|
+
updated_at = now()
|
|
279
|
+
WHERE entry_type = 'finding'
|
|
280
|
+
AND status = 'deferred_to_proposal'
|
|
281
|
+
AND payload->>'proposal_id' = :proposal_id
|
|
282
|
+
RETURNING id, subject
|
|
283
|
+
"""
|
|
284
|
+
),
|
|
285
|
+
{"proposal_id": proposal_id},
|
|
286
|
+
)
|
|
287
|
+
rows = update_result.fetchall()
|
|
288
|
+
resolved_ids = [str(row[0]) for row in rows]
|
|
289
|
+
resolved_subjects = [str(row[1]) for row in rows]
|
|
290
|
+
|
|
291
|
+
logger.info(
|
|
292
|
+
"Resolved %d deferred finding(s) for completed proposal %s",
|
|
293
|
+
len(resolved_ids),
|
|
294
|
+
proposal_id,
|
|
295
|
+
)
|
|
296
|
+
|
|
297
|
+
if not resolved_ids:
|
|
298
|
+
return None
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
"proposal_id": proposal_id,
|
|
302
|
+
"resolved_count": len(resolved_ids),
|
|
303
|
+
"resolved_finding_ids": resolved_ids,
|
|
304
|
+
"resolved_subjects": resolved_subjects,
|
|
305
|
+
}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# src/body/services/blackboard_service/blackboard_query_service.py
|
|
2
|
+
"""Pure-read query methods — SELECT only, no mutations."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
from typing import Any
|
|
8
|
+
|
|
9
|
+
from sqlalchemy import text
|
|
10
|
+
|
|
11
|
+
from shared.infrastructure.intent.operational_config import load_operational_config
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
_SLA: dict[str, int] = {
|
|
15
|
+
"heartbeat": 600,
|
|
16
|
+
"finding": 3600,
|
|
17
|
+
"report": 7200,
|
|
18
|
+
"proposal": 1800,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
_CFG = load_operational_config().blackboard
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# ID: 0f7e0bf6-9fba-44b1-9605-b7dcadf97fac
|
|
25
|
+
class BlackboardQueryService:
|
|
26
|
+
# ID: b980a1a9-eca8-4268-b8ba-86fbcf94b6ce
|
|
27
|
+
async def fetch_open_finding_subjects_by_prefix(self, prefix: str) -> set[str]:
|
|
28
|
+
"""
|
|
29
|
+
Return subjects of non-terminal finding entries whose subject matches
|
|
30
|
+
*prefix* (SQL LIKE pattern — caller supplies the trailing wildcard).
|
|
31
|
+
|
|
32
|
+
'suppressed' is treated as terminal and excluded — suppressed entries
|
|
33
|
+
are not "open" by any definition. (See #263 for the suppressed/abandoned
|
|
34
|
+
split: only ``fetch_active_finding_subjects_by_prefix`` keeps suppressed
|
|
35
|
+
in its result set, because dedup-vs-permanent-skip is its purpose.)
|
|
36
|
+
|
|
37
|
+
'awaiting_reaudit' (ADR-045) is NOT excluded — those rows are
|
|
38
|
+
non-terminal and represent unresolved work that has not yet been
|
|
39
|
+
adjudicated by the audit sensor's release pass.
|
|
40
|
+
|
|
41
|
+
Covers:
|
|
42
|
+
- AuditViolationSensor._fetch_existing_subjects
|
|
43
|
+
- BlackboardShopManager._fetch_existing_findings
|
|
44
|
+
- IntentInspector._fetch_existing_subjects
|
|
45
|
+
"""
|
|
46
|
+
from body.services.service_registry import ServiceRegistry
|
|
47
|
+
|
|
48
|
+
async with ServiceRegistry.session() as session:
|
|
49
|
+
result = await session.execute(
|
|
50
|
+
text(
|
|
51
|
+
"""
|
|
52
|
+
SELECT subject FROM core.blackboard_entries
|
|
53
|
+
WHERE entry_type = 'finding'
|
|
54
|
+
AND subject LIKE :prefix
|
|
55
|
+
AND status NOT IN (
|
|
56
|
+
'resolved',
|
|
57
|
+
'abandoned',
|
|
58
|
+
'suppressed',
|
|
59
|
+
'dry_run_complete',
|
|
60
|
+
'deferred_to_proposal',
|
|
61
|
+
'indeterminate'
|
|
62
|
+
)
|
|
63
|
+
"""
|
|
64
|
+
),
|
|
65
|
+
{"prefix": prefix},
|
|
66
|
+
)
|
|
67
|
+
return {row[0] for row in result.fetchall()}
|
|
68
|
+
|
|
69
|
+
# ID: 9c4e1f7a-2b3d-4e85-a6f7-90bc8d1e2f43
|
|
70
|
+
async def fetch_awaiting_reaudit_subjects_by_prefix(self, prefix: str) -> set[str]:
|
|
71
|
+
"""
|
|
72
|
+
Return subjects of awaiting_reaudit finding entries matching *prefix*.
|
|
73
|
+
|
|
74
|
+
Used by quarantine drainers (ADR-072) to determine the scope of
|
|
75
|
+
work for the current drain cycle — e.g. TestRunnerSensor uses this
|
|
76
|
+
to enumerate test_files referenced by quarantined test.failure
|
|
77
|
+
rows so it can re-run pytest only for what is actually parked.
|
|
78
|
+
"""
|
|
79
|
+
from body.services.service_registry import ServiceRegistry
|
|
80
|
+
|
|
81
|
+
async with ServiceRegistry.session() as session:
|
|
82
|
+
result = await session.execute(
|
|
83
|
+
text(
|
|
84
|
+
"""
|
|
85
|
+
SELECT subject FROM core.blackboard_entries
|
|
86
|
+
WHERE entry_type = 'finding'
|
|
87
|
+
AND status = 'awaiting_reaudit'
|
|
88
|
+
AND subject LIKE :prefix
|
|
89
|
+
"""
|
|
90
|
+
),
|
|
91
|
+
{"prefix": prefix},
|
|
92
|
+
)
|
|
93
|
+
return {row[0] for row in result.fetchall()}
|
|
94
|
+
|
|
95
|
+
# ID: 1b8e7a4c-3f2d-4c5b-9a01-8e6d2f9b0a31
|
|
96
|
+
async def fetch_active_finding_subjects_by_prefix(self, prefix: str) -> set[str]:
|
|
97
|
+
"""
|
|
98
|
+
Return subjects of finding entries whose subject matches *prefix*
|
|
99
|
+
that should be treated as "still on the board" for sensor dedup.
|
|
100
|
+
|
|
101
|
+
Sensor-dedup contract (see #263 for the rationale):
|
|
102
|
+
|
|
103
|
+
- 'resolved' is excluded: the issue is closed; the sensor MAY re-post
|
|
104
|
+
if it re-detects the same subject (re-emergence is meaningful).
|
|
105
|
+
- 'abandoned' is excluded: workers gave up on this entry without
|
|
106
|
+
resolving the underlying issue, so a fresh detection deserves a
|
|
107
|
+
fresh entry — re-emit is correct.
|
|
108
|
+
- 'suppressed' is INTENTIONALLY KEPT in the result set: it is the
|
|
109
|
+
governor's deliberate "do not surface this again" signal. Its
|
|
110
|
+
subject must remain in the dedup set so sensors skip it
|
|
111
|
+
permanently.
|
|
112
|
+
- All other statuses (open, claimed, deferred_to_proposal,
|
|
113
|
+
indeterminate, awaiting_reaudit per ADR-045) are included —
|
|
114
|
+
those subjects are still on the board (active or quarantined)
|
|
115
|
+
and a sensor must not pile on duplicates.
|
|
116
|
+
|
|
117
|
+
Covers:
|
|
118
|
+
- AuditViolationSensor._fetch_existing_subjects
|
|
119
|
+
"""
|
|
120
|
+
from body.services.service_registry import ServiceRegistry
|
|
121
|
+
|
|
122
|
+
async with ServiceRegistry.session() as session:
|
|
123
|
+
result = await session.execute(
|
|
124
|
+
text(
|
|
125
|
+
"""
|
|
126
|
+
SELECT subject FROM core.blackboard_entries
|
|
127
|
+
WHERE entry_type = 'finding'
|
|
128
|
+
AND subject LIKE :prefix
|
|
129
|
+
AND status NOT IN ('resolved', 'abandoned')
|
|
130
|
+
"""
|
|
131
|
+
),
|
|
132
|
+
{"prefix": prefix},
|
|
133
|
+
)
|
|
134
|
+
return {row[0] for row in result.fetchall()}
|
|
135
|
+
|
|
136
|
+
# ID: d98fae16-259d-4993-9e10-4b18c7ea7a70
|
|
137
|
+
async def fetch_open_finding_subjects_by_worker(
|
|
138
|
+
self, worker_uuid: str, prefix: str
|
|
139
|
+
) -> set[str]:
|
|
140
|
+
"""
|
|
141
|
+
Return subjects of non-terminal finding entries posted by *worker_uuid*
|
|
142
|
+
whose subject matches *prefix*.
|
|
143
|
+
|
|
144
|
+
'suppressed' is treated as terminal and excluded — see #263.
|
|
145
|
+
|
|
146
|
+
Covers:
|
|
147
|
+
- AuditIngestWorker._fetch_existing_subjects
|
|
148
|
+
"""
|
|
149
|
+
from body.services.service_registry import ServiceRegistry
|
|
150
|
+
|
|
151
|
+
async with ServiceRegistry.session() as session:
|
|
152
|
+
result = await session.execute(
|
|
153
|
+
text(
|
|
154
|
+
"""
|
|
155
|
+
SELECT subject FROM core.blackboard_entries
|
|
156
|
+
WHERE worker_uuid = :worker_uuid
|
|
157
|
+
AND entry_type = 'finding'
|
|
158
|
+
AND subject LIKE :prefix
|
|
159
|
+
AND status NOT IN (
|
|
160
|
+
'resolved',
|
|
161
|
+
'abandoned',
|
|
162
|
+
'suppressed',
|
|
163
|
+
'dry_run_complete',
|
|
164
|
+
'deferred_to_proposal',
|
|
165
|
+
'indeterminate'
|
|
166
|
+
)
|
|
167
|
+
"""
|
|
168
|
+
),
|
|
169
|
+
{"worker_uuid": worker_uuid, "prefix": prefix},
|
|
170
|
+
)
|
|
171
|
+
return {row[0] for row in result.fetchall()}
|
|
172
|
+
|
|
173
|
+
# ID: e38d5bb0-ad45-4d45-9350-28ca7d92f8de
|
|
174
|
+
async def fetch_stale_entries(self) -> list[dict[str, Any]]:
|
|
175
|
+
"""
|
|
176
|
+
Return blackboard entries whose age exceeds their constitutional SLA tier.
|
|
177
|
+
|
|
178
|
+
Stale detection is for non-terminal stuck entries only. Every declared
|
|
179
|
+
terminal status is excluded because terminal entries cannot be acted
|
|
180
|
+
on further and must not trigger stale alerts. Per the canonical
|
|
181
|
+
``blackboard_entry_status`` enum (.intent/META/enums.json), the
|
|
182
|
+
terminal set is:
|
|
183
|
+
|
|
184
|
+
* resolved
|
|
185
|
+
* abandoned
|
|
186
|
+
* suppressed (#263)
|
|
187
|
+
* dry_run_complete (#265 — historical; no new writers)
|
|
188
|
+
* deferred_to_proposal
|
|
189
|
+
* indeterminate
|
|
190
|
+
|
|
191
|
+
Excludes self-referential stale-finding and silent-worker subjects.
|
|
192
|
+
|
|
193
|
+
Covers:
|
|
194
|
+
- BlackboardShopManager._fetch_stale_entries
|
|
195
|
+
"""
|
|
196
|
+
from body.services.service_registry import ServiceRegistry
|
|
197
|
+
|
|
198
|
+
async with ServiceRegistry.session() as session:
|
|
199
|
+
result = await session.execute(
|
|
200
|
+
text(
|
|
201
|
+
"""
|
|
202
|
+
SELECT
|
|
203
|
+
id,
|
|
204
|
+
entry_type,
|
|
205
|
+
subject,
|
|
206
|
+
worker_uuid,
|
|
207
|
+
status,
|
|
208
|
+
EXTRACT(EPOCH FROM (now() - created_at))::int AS age_seconds,
|
|
209
|
+
CASE entry_type
|
|
210
|
+
WHEN 'heartbeat' THEN CAST(:sla_heartbeat AS INT)
|
|
211
|
+
WHEN 'finding' THEN CAST(:sla_finding AS INT)
|
|
212
|
+
WHEN 'report' THEN CAST(:sla_report AS INT)
|
|
213
|
+
WHEN 'proposal' THEN CAST(:sla_proposal AS INT)
|
|
214
|
+
ELSE CAST(:sla_default AS INT)
|
|
215
|
+
END AS sla_seconds
|
|
216
|
+
FROM core.blackboard_entries
|
|
217
|
+
WHERE status NOT IN (
|
|
218
|
+
'resolved',
|
|
219
|
+
'abandoned',
|
|
220
|
+
'suppressed',
|
|
221
|
+
'dry_run_complete',
|
|
222
|
+
'deferred_to_proposal',
|
|
223
|
+
'indeterminate'
|
|
224
|
+
)
|
|
225
|
+
AND entry_type IN ('finding', 'proposal')
|
|
226
|
+
AND subject NOT LIKE 'blackboard.entry_stale::%'
|
|
227
|
+
AND subject NOT LIKE 'worker.silent::%'
|
|
228
|
+
AND EXTRACT(EPOCH FROM (now() - created_at)) >
|
|
229
|
+
CASE entry_type
|
|
230
|
+
WHEN 'heartbeat' THEN CAST(:sla_heartbeat AS INT)
|
|
231
|
+
WHEN 'finding' THEN CAST(:sla_finding AS INT)
|
|
232
|
+
WHEN 'report' THEN CAST(:sla_report AS INT)
|
|
233
|
+
WHEN 'proposal' THEN CAST(:sla_proposal AS INT)
|
|
234
|
+
ELSE CAST(:sla_default AS INT)
|
|
235
|
+
END
|
|
236
|
+
ORDER BY age_seconds DESC
|
|
237
|
+
"""
|
|
238
|
+
),
|
|
239
|
+
{
|
|
240
|
+
"sla_heartbeat": _SLA["heartbeat"],
|
|
241
|
+
"sla_finding": _SLA["finding"],
|
|
242
|
+
"sla_report": _SLA["report"],
|
|
243
|
+
"sla_proposal": _SLA["proposal"],
|
|
244
|
+
"sla_default": _CFG.sla_default_seconds,
|
|
245
|
+
},
|
|
246
|
+
)
|
|
247
|
+
return [
|
|
248
|
+
{
|
|
249
|
+
"id": row[0],
|
|
250
|
+
"entry_type": row[1],
|
|
251
|
+
"subject": row[2],
|
|
252
|
+
"worker_uuid": row[3],
|
|
253
|
+
"status": row[4],
|
|
254
|
+
"age_seconds": row[5] or 0,
|
|
255
|
+
"sla_seconds": row[6],
|
|
256
|
+
}
|
|
257
|
+
for row in result.fetchall()
|
|
258
|
+
]
|
|
259
|
+
|
|
260
|
+
# ID: cdfba0a0-a746-4e3c-97a8-cc0a0eff2c59
|
|
261
|
+
async def count_active_entries(self) -> int:
|
|
262
|
+
"""
|
|
263
|
+
Count total non-terminal blackboard entries.
|
|
264
|
+
|
|
265
|
+
Covers:
|
|
266
|
+
- BlackboardShopManager._count_active_entries
|
|
267
|
+
"""
|
|
268
|
+
from body.services.service_registry import ServiceRegistry
|
|
269
|
+
|
|
270
|
+
async with ServiceRegistry.session() as session:
|
|
271
|
+
result = await session.execute(
|
|
272
|
+
text(
|
|
273
|
+
"""
|
|
274
|
+
SELECT COUNT(*) FROM core.blackboard_entries
|
|
275
|
+
WHERE status NOT IN (
|
|
276
|
+
'resolved',
|
|
277
|
+
'abandoned',
|
|
278
|
+
'suppressed',
|
|
279
|
+
'dry_run_complete',
|
|
280
|
+
'deferred_to_proposal',
|
|
281
|
+
'indeterminate'
|
|
282
|
+
)
|
|
283
|
+
"""
|
|
284
|
+
)
|
|
285
|
+
)
|
|
286
|
+
return result.scalar() or 0
|
|
287
|
+
|
|
288
|
+
# ID: 7e4f9a1b-2c3d-4e5f-8a6b-7c8d9e0f1a2b
|
|
289
|
+
async def fetch_open_findings(
|
|
290
|
+
self, prefix: str, limit: int
|
|
291
|
+
) -> list[dict[str, Any]]:
|
|
292
|
+
"""
|
|
293
|
+
Return up to *limit* open finding entries whose subject matches *prefix*,
|
|
294
|
+
ordered oldest-first. Payload is always returned as a dict.
|
|
295
|
+
|
|
296
|
+
Covers:
|
|
297
|
+
- ViolationRemediatorWorker._load_open_findings
|
|
298
|
+
"""
|
|
299
|
+
from body.services.service_registry import ServiceRegistry
|
|
300
|
+
|
|
301
|
+
async with ServiceRegistry.session() as session:
|
|
302
|
+
result = await session.execute(
|
|
303
|
+
text(
|
|
304
|
+
"""
|
|
305
|
+
SELECT id, subject, payload
|
|
306
|
+
FROM core.blackboard_entries
|
|
307
|
+
WHERE entry_type = 'finding'
|
|
308
|
+
AND subject LIKE :prefix
|
|
309
|
+
AND status = 'open'
|
|
310
|
+
ORDER BY created_at ASC
|
|
311
|
+
LIMIT :limit
|
|
312
|
+
"""
|
|
313
|
+
),
|
|
314
|
+
{"prefix": prefix, "limit": limit},
|
|
315
|
+
)
|
|
316
|
+
rows = result.fetchall()
|
|
317
|
+
|
|
318
|
+
findings = []
|
|
319
|
+
for row in rows:
|
|
320
|
+
raw_payload = row[2]
|
|
321
|
+
payload = (
|
|
322
|
+
raw_payload
|
|
323
|
+
if isinstance(raw_payload, dict)
|
|
324
|
+
else json.loads(raw_payload)
|
|
325
|
+
)
|
|
326
|
+
findings.append(
|
|
327
|
+
{
|
|
328
|
+
"id": str(row[0]),
|
|
329
|
+
"subject": row[1],
|
|
330
|
+
"payload": payload or {},
|
|
331
|
+
}
|
|
332
|
+
)
|
|
333
|
+
return findings
|