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,154 @@
|
|
|
1
|
+
# src/body/services/policy_expression_evaluator.py
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
Policy Expression Evaluator - Safe Boolean Expression Evaluation
|
|
5
|
+
|
|
6
|
+
CONSTITUTIONAL ALIGNMENT:
|
|
7
|
+
- Single Responsibility: Evaluate policy expressions safely
|
|
8
|
+
- No CLI dependencies
|
|
9
|
+
- Reusable for governance checks
|
|
10
|
+
|
|
11
|
+
Extracted from cli/logic/validate.py to separate evaluation logic.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import ast
|
|
17
|
+
from dataclasses import dataclass
|
|
18
|
+
from typing import Any, ClassVar
|
|
19
|
+
|
|
20
|
+
from shared.logger import getLogger
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
logger = getLogger(__name__)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass
|
|
27
|
+
# ID: 24950f8a-5412-483a-9af7-e02427769ee7
|
|
28
|
+
class ReviewContext:
|
|
29
|
+
"""Context for policy expression evaluation."""
|
|
30
|
+
|
|
31
|
+
risk_tier: str = "low"
|
|
32
|
+
score: float = 0.0
|
|
33
|
+
touches_critical_paths: bool = False
|
|
34
|
+
checkpoint: bool = False
|
|
35
|
+
canary: bool = False
|
|
36
|
+
approver_quorum: bool = False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# ID: e09d9c07-2e67-4e7a-a58c-2c647dd354a1
|
|
40
|
+
class PolicyExpressionEvaluator:
|
|
41
|
+
"""
|
|
42
|
+
Safely evaluates boolean policy expressions.
|
|
43
|
+
|
|
44
|
+
SECURITY: Uses AST validation to ensure only safe operations.
|
|
45
|
+
No arbitrary code execution possible.
|
|
46
|
+
|
|
47
|
+
Usage:
|
|
48
|
+
evaluator = PolicyExpressionEvaluator()
|
|
49
|
+
context = {"risk_tier": "high", "checkpoint": True}
|
|
50
|
+
result = evaluator.evaluate("risk_tier == 'high' and checkpoint", context)
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
# AST allowlist for safe policy evaluation
|
|
54
|
+
_ALLOWED_NODES: ClassVar[set[type]] = {
|
|
55
|
+
ast.Expression,
|
|
56
|
+
ast.BoolOp,
|
|
57
|
+
ast.BinOp,
|
|
58
|
+
ast.UnaryOp,
|
|
59
|
+
ast.Compare,
|
|
60
|
+
ast.Name,
|
|
61
|
+
ast.Load,
|
|
62
|
+
ast.Constant,
|
|
63
|
+
ast.List,
|
|
64
|
+
ast.Tuple,
|
|
65
|
+
ast.And,
|
|
66
|
+
ast.Or,
|
|
67
|
+
ast.Not,
|
|
68
|
+
ast.In,
|
|
69
|
+
ast.Eq,
|
|
70
|
+
ast.NotEq,
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# ID: a1c30251-1e32-459c-bf1d-44b6f649c7b6
|
|
74
|
+
def evaluate(self, expr: str, context: dict[str, Any]) -> bool:
|
|
75
|
+
"""
|
|
76
|
+
Safely evaluate a boolean expression string against a context dictionary.
|
|
77
|
+
|
|
78
|
+
SECURITY NOTE: This function uses eval() but is SAFE because:
|
|
79
|
+
1. Input is parsed and validated via AST whitelist
|
|
80
|
+
2. Only safe nodes are permitted (no calls, imports, attribute access)
|
|
81
|
+
3. Builtins are disabled ({"__builtins__": {}})
|
|
82
|
+
4. Only whitelisted context variables are available
|
|
83
|
+
5. Used exclusively for evaluating policy conditions from .intent/
|
|
84
|
+
|
|
85
|
+
This is verified safe code execution for constitutional governance.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
expr: Boolean expression string
|
|
89
|
+
context: Dictionary of allowed variables
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Evaluation result
|
|
93
|
+
|
|
94
|
+
Raises:
|
|
95
|
+
ValueError: If expression contains disallowed operations
|
|
96
|
+
"""
|
|
97
|
+
# Normalize boolean literals
|
|
98
|
+
expr = expr.replace(" true", " True").replace(" false", " False")
|
|
99
|
+
|
|
100
|
+
# Layer 1: Parse to AST
|
|
101
|
+
try:
|
|
102
|
+
tree = ast.parse(expr, mode="eval")
|
|
103
|
+
except SyntaxError as e:
|
|
104
|
+
raise ValueError(f"Invalid expression syntax: {e}") from e
|
|
105
|
+
|
|
106
|
+
# Layer 2: AST Validation
|
|
107
|
+
for node in ast.walk(tree):
|
|
108
|
+
if type(node) not in self._ALLOWED_NODES:
|
|
109
|
+
raise ValueError(
|
|
110
|
+
f"Disallowed node in expression: {type(node).__name__}"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Layer 3: Restricted Execution (Sandboxing)
|
|
114
|
+
# SECURITY: Using compile() on validated AST is safer than eval(str)
|
|
115
|
+
# SECURITY: __builtins__ is empty to prevent access to globals
|
|
116
|
+
compiled = compile(tree, "<policy_expr>", "eval")
|
|
117
|
+
|
|
118
|
+
# SECURITY: context variables only
|
|
119
|
+
try:
|
|
120
|
+
return bool(eval(compiled, {"__builtins__": {}}, context))
|
|
121
|
+
except Exception as e:
|
|
122
|
+
raise ValueError(f"Expression evaluation failed: {e}") from e
|
|
123
|
+
|
|
124
|
+
# ID: 0d1e2f3a-4b5c-6d7e-8f9a-0b1c2d3e4f5a
|
|
125
|
+
def validate_expression(self, expr: str) -> tuple[bool, str | None]:
|
|
126
|
+
"""
|
|
127
|
+
Validate expression without evaluating it.
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
expr: Expression to validate
|
|
131
|
+
|
|
132
|
+
Returns:
|
|
133
|
+
(is_valid, error_message)
|
|
134
|
+
"""
|
|
135
|
+
try:
|
|
136
|
+
# Normalize
|
|
137
|
+
expr = expr.replace(" true", " True").replace(" false", " False")
|
|
138
|
+
|
|
139
|
+
# Parse
|
|
140
|
+
tree = ast.parse(expr, mode="eval")
|
|
141
|
+
|
|
142
|
+
# Validate nodes
|
|
143
|
+
for node in ast.walk(tree):
|
|
144
|
+
if type(node) not in self._ALLOWED_NODES:
|
|
145
|
+
return (
|
|
146
|
+
False,
|
|
147
|
+
f"Disallowed operation: {type(node).__name__}",
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
return True, None
|
|
151
|
+
except SyntaxError as e:
|
|
152
|
+
return False, f"Syntax error: {e}"
|
|
153
|
+
except Exception as e:
|
|
154
|
+
return False, f"Validation error: {e}"
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
# src/body/services/proposal_supervision_service.py
|
|
2
|
+
"""
|
|
3
|
+
ProposalSupervisionService - Data-access layer for proposal pipeline health.
|
|
4
|
+
|
|
5
|
+
Body-layer service exposing the three supervisory queries the
|
|
6
|
+
ProposalPipelineShopManager needs against core.autonomous_proposals:
|
|
7
|
+
|
|
8
|
+
- fetch_stuck_approved: rows in status='approved' older than SLA
|
|
9
|
+
- fetch_stuck_executing: rows in status='executing' older than SLA
|
|
10
|
+
- fetch_repeated_failures: (first action_id, source_check_id) pairs
|
|
11
|
+
with status='failed' count >= threshold
|
|
12
|
+
within the lookback window
|
|
13
|
+
|
|
14
|
+
Constitutional alignment:
|
|
15
|
+
- Layer: body — data-access only, no decisions
|
|
16
|
+
- Boundary: no Will imports, no domain reasoning, no LLM
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from datetime import UTC, datetime, timedelta
|
|
22
|
+
from typing import Any
|
|
23
|
+
|
|
24
|
+
from sqlalchemy import text
|
|
25
|
+
|
|
26
|
+
from shared.logger import getLogger
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
logger = getLogger(__name__)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# ID: 0e4dacfe-1f57-4978-b30d-94ebea06f862
|
|
33
|
+
class ProposalSupervisionService:
|
|
34
|
+
"""
|
|
35
|
+
Body layer service. Exposes named methods for the three
|
|
36
|
+
proposal-pipeline-health queries used by ProposalPipelineShopManager.
|
|
37
|
+
|
|
38
|
+
All methods open their own session via ServiceRegistry — callers do
|
|
39
|
+
not pass one in. This matches the AuditFindingsService /
|
|
40
|
+
WorkerRegistryService pattern.
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
# ID: b9263f77-0a50-4fb1-a845-2e91c7e25eb4
|
|
44
|
+
async def fetch_stuck_approved(
|
|
45
|
+
self, sla_sec: int, limit: int
|
|
46
|
+
) -> list[dict[str, Any]]:
|
|
47
|
+
"""
|
|
48
|
+
Return proposals stuck in status='approved' beyond the SLA.
|
|
49
|
+
|
|
50
|
+
Each row carries the proposal_id, approved_at, and seconds_stuck
|
|
51
|
+
so the worker can build a precise finding payload.
|
|
52
|
+
"""
|
|
53
|
+
from body.services.service_registry import ServiceRegistry
|
|
54
|
+
|
|
55
|
+
cutoff = datetime.now(UTC) - timedelta(seconds=sla_sec)
|
|
56
|
+
|
|
57
|
+
async with ServiceRegistry.session() as session:
|
|
58
|
+
result = await session.execute(
|
|
59
|
+
text(
|
|
60
|
+
"""
|
|
61
|
+
SELECT
|
|
62
|
+
proposal_id,
|
|
63
|
+
approved_at,
|
|
64
|
+
EXTRACT(EPOCH FROM (now() - approved_at))::int AS seconds_stuck
|
|
65
|
+
FROM core.autonomous_proposals
|
|
66
|
+
WHERE status = 'approved'
|
|
67
|
+
AND approved_at IS NOT NULL
|
|
68
|
+
AND approved_at < :cutoff
|
|
69
|
+
ORDER BY approved_at ASC
|
|
70
|
+
LIMIT :limit
|
|
71
|
+
"""
|
|
72
|
+
),
|
|
73
|
+
{"cutoff": cutoff, "limit": limit},
|
|
74
|
+
)
|
|
75
|
+
rows = result.fetchall()
|
|
76
|
+
|
|
77
|
+
return [
|
|
78
|
+
{
|
|
79
|
+
"proposal_id": str(row[0]),
|
|
80
|
+
"approved_at": row[1],
|
|
81
|
+
"seconds_stuck": int(row[2]),
|
|
82
|
+
}
|
|
83
|
+
for row in rows
|
|
84
|
+
]
|
|
85
|
+
|
|
86
|
+
# ID: ed19598e-6d0f-431d-897b-e5f69bc4c78a
|
|
87
|
+
async def fetch_stuck_executing(
|
|
88
|
+
self, sla_sec: int, limit: int
|
|
89
|
+
) -> list[dict[str, Any]]:
|
|
90
|
+
"""
|
|
91
|
+
Return proposals stuck in status='executing' beyond the SLA.
|
|
92
|
+
|
|
93
|
+
Uses execution_started_at as the anchor (not updated_at — that
|
|
94
|
+
moves on any UPDATE and would hide a genuinely stuck row).
|
|
95
|
+
"""
|
|
96
|
+
from body.services.service_registry import ServiceRegistry
|
|
97
|
+
|
|
98
|
+
cutoff = datetime.now(UTC) - timedelta(seconds=sla_sec)
|
|
99
|
+
|
|
100
|
+
async with ServiceRegistry.session() as session:
|
|
101
|
+
result = await session.execute(
|
|
102
|
+
text(
|
|
103
|
+
"""
|
|
104
|
+
SELECT
|
|
105
|
+
proposal_id,
|
|
106
|
+
execution_started_at,
|
|
107
|
+
EXTRACT(EPOCH FROM (now() - execution_started_at))::int
|
|
108
|
+
AS seconds_stuck
|
|
109
|
+
FROM core.autonomous_proposals
|
|
110
|
+
WHERE status = 'executing'
|
|
111
|
+
AND execution_started_at IS NOT NULL
|
|
112
|
+
AND execution_started_at < :cutoff
|
|
113
|
+
ORDER BY execution_started_at ASC
|
|
114
|
+
LIMIT :limit
|
|
115
|
+
"""
|
|
116
|
+
),
|
|
117
|
+
{"cutoff": cutoff, "limit": limit},
|
|
118
|
+
)
|
|
119
|
+
rows = result.fetchall()
|
|
120
|
+
|
|
121
|
+
return [
|
|
122
|
+
{
|
|
123
|
+
"proposal_id": str(row[0]),
|
|
124
|
+
"execution_started_at": row[1],
|
|
125
|
+
"seconds_stuck": int(row[2]),
|
|
126
|
+
}
|
|
127
|
+
for row in rows
|
|
128
|
+
]
|
|
129
|
+
|
|
130
|
+
# ID: 3f325bf4-3f14-4b15-bcfa-17a64f8c56db
|
|
131
|
+
async def fetch_repeated_failures(
|
|
132
|
+
self,
|
|
133
|
+
threshold: int,
|
|
134
|
+
lookback_sec: int,
|
|
135
|
+
limit: int,
|
|
136
|
+
) -> list[dict[str, Any]]:
|
|
137
|
+
"""
|
|
138
|
+
Return (action_id, rule_id) pairs whose proposals have failed
|
|
139
|
+
at least *threshold* times within the lookback window.
|
|
140
|
+
|
|
141
|
+
Action_id is read from actions[0]->>'action_id' — the first
|
|
142
|
+
action of the proposal, by design decision (the secondary-
|
|
143
|
+
action variant is deferred; see #170 design notes).
|
|
144
|
+
|
|
145
|
+
Rule_id is read from constitutional_constraints->>'source_check_id',
|
|
146
|
+
the conventional key for the audit rule that triggered the
|
|
147
|
+
autonomous proposal.
|
|
148
|
+
"""
|
|
149
|
+
from body.services.service_registry import ServiceRegistry
|
|
150
|
+
|
|
151
|
+
since = datetime.now(UTC) - timedelta(seconds=lookback_sec)
|
|
152
|
+
|
|
153
|
+
async with ServiceRegistry.session() as session:
|
|
154
|
+
result = await session.execute(
|
|
155
|
+
text(
|
|
156
|
+
"""
|
|
157
|
+
SELECT
|
|
158
|
+
actions->0->>'action_id' AS action_id,
|
|
159
|
+
constitutional_constraints->>'source_check_id' AS rule_id,
|
|
160
|
+
COUNT(*) AS failure_count,
|
|
161
|
+
MAX(updated_at) AS last_failure_at,
|
|
162
|
+
array_agg(proposal_id ORDER BY updated_at DESC) AS proposal_ids
|
|
163
|
+
FROM core.autonomous_proposals
|
|
164
|
+
WHERE status = 'failed'
|
|
165
|
+
AND updated_at >= :since
|
|
166
|
+
AND actions->0->>'action_id' IS NOT NULL
|
|
167
|
+
AND constitutional_constraints->>'source_check_id' IS NOT NULL
|
|
168
|
+
GROUP BY action_id, rule_id
|
|
169
|
+
HAVING COUNT(*) >= :threshold
|
|
170
|
+
ORDER BY failure_count DESC, last_failure_at DESC
|
|
171
|
+
LIMIT :limit
|
|
172
|
+
"""
|
|
173
|
+
),
|
|
174
|
+
{"since": since, "threshold": threshold, "limit": limit},
|
|
175
|
+
)
|
|
176
|
+
rows = result.fetchall()
|
|
177
|
+
|
|
178
|
+
return [
|
|
179
|
+
{
|
|
180
|
+
"action_id": str(row[0]),
|
|
181
|
+
"rule_id": str(row[1]),
|
|
182
|
+
"failure_count": int(row[2]),
|
|
183
|
+
"last_failure_at": row[3],
|
|
184
|
+
"proposal_ids": [str(p) for p in (row[4] or [])][:5],
|
|
185
|
+
}
|
|
186
|
+
for row in rows
|
|
187
|
+
]
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
# src/body/services/representation_coherence_service.py
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
RepresentationCoherenceService — Body layer service for ADR-070 D6 verdict line.
|
|
5
|
+
|
|
6
|
+
Governing ADR: .specs/decisions/ADR-070-source-projection-coherence.md
|
|
7
|
+
|
|
8
|
+
Constitutional Compliance:
|
|
9
|
+
- Body layer service: provides DB access without making decisions.
|
|
10
|
+
- Reads .intent/governance/projections.yaml (inventory) and derives per-pair
|
|
11
|
+
state from existing observable signals (blackboard reports, worker_registry
|
|
12
|
+
heartbeats, open findings under each pair's rule_id).
|
|
13
|
+
- No business logic about remediation — the service reports, it does not
|
|
14
|
+
prescribe. Drift is named through the existing finding lifecycle; this
|
|
15
|
+
service only summarizes.
|
|
16
|
+
|
|
17
|
+
Used by: src/cli/resources/code/audit.py (D6 composite verdict line)
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
from __future__ import annotations
|
|
21
|
+
|
|
22
|
+
from datetime import UTC, datetime, timedelta
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from typing import Any
|
|
25
|
+
|
|
26
|
+
import yaml
|
|
27
|
+
from sqlalchemy import text
|
|
28
|
+
|
|
29
|
+
from body.services.session_attached_service import SessionAttachedService
|
|
30
|
+
from shared.logger import getLogger
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
logger = getLogger(__name__)
|
|
34
|
+
|
|
35
|
+
__all__ = ["RepresentationCoherenceService"]
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
_INVENTORY_PATH = Path(".intent/governance/projections.yaml")
|
|
39
|
+
|
|
40
|
+
# How long a writer-as-sensor pair's signal stays "fresh" before being
|
|
41
|
+
# considered sensor-stale. Conservative default — 2x the longest declared
|
|
42
|
+
# crawler interval (600s in repo_crawler.yaml) gives 1200s. Per-pair
|
|
43
|
+
# overrides via inventory entry's `freshness_seconds` field when present.
|
|
44
|
+
_DEFAULT_FRESHNESS_SECONDS = 1200
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
# ID: 6a8d9c1e-2b4f-4d3a-9c7e-5f8b1a3d6c9e
|
|
48
|
+
class RepresentationCoherenceService(SessionAttachedService):
|
|
49
|
+
"""
|
|
50
|
+
Reads the projection inventory and derives per-pair coherence state.
|
|
51
|
+
|
|
52
|
+
Returns aggregated state for the audit advisory line (ADR-070 D6).
|
|
53
|
+
Per-pair details surface through findings under each pair's rule_id;
|
|
54
|
+
this service produces the summary roll-up only.
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
# ID: a3f5d7c9-1e2b-4a6d-8c9f-3e5d7b9c1a4e
|
|
58
|
+
async def get_summary(self) -> dict[str, Any]:
|
|
59
|
+
"""
|
|
60
|
+
Return a roll-up of inventory state for the audit advisory line.
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
{
|
|
64
|
+
"inventory_loaded": bool,
|
|
65
|
+
"pairs_declared": int,
|
|
66
|
+
"in_lease": int,
|
|
67
|
+
"drifted": int,
|
|
68
|
+
"sensor_stale": int,
|
|
69
|
+
"last_check_at": datetime | None,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
`inventory_loaded=False` indicates the inventory file is absent or
|
|
73
|
+
unreadable. `pairs_declared=0` with loaded=True indicates the
|
|
74
|
+
inventory exists but declares no pairs (pre-first-pair state).
|
|
75
|
+
"""
|
|
76
|
+
inventory = _load_inventory()
|
|
77
|
+
if inventory is None:
|
|
78
|
+
return {
|
|
79
|
+
"inventory_loaded": False,
|
|
80
|
+
"pairs_declared": 0,
|
|
81
|
+
"in_lease": 0,
|
|
82
|
+
"drifted": 0,
|
|
83
|
+
"sensor_stale": 0,
|
|
84
|
+
"last_check_at": None,
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
pairs = inventory.get("projections", []) or []
|
|
88
|
+
if not pairs:
|
|
89
|
+
return {
|
|
90
|
+
"inventory_loaded": True,
|
|
91
|
+
"pairs_declared": 0,
|
|
92
|
+
"in_lease": 0,
|
|
93
|
+
"drifted": 0,
|
|
94
|
+
"sensor_stale": 0,
|
|
95
|
+
"last_check_at": None,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
in_lease = 0
|
|
99
|
+
drifted = 0
|
|
100
|
+
sensor_stale = 0
|
|
101
|
+
latest_check: datetime | None = None
|
|
102
|
+
|
|
103
|
+
for pair in pairs:
|
|
104
|
+
state = await self._get_pair_state(pair)
|
|
105
|
+
if state["status"] == "in_lease":
|
|
106
|
+
in_lease += 1
|
|
107
|
+
elif state["status"] == "drifted":
|
|
108
|
+
drifted += 1
|
|
109
|
+
elif state["status"] == "sensor_stale":
|
|
110
|
+
sensor_stale += 1
|
|
111
|
+
|
|
112
|
+
if state["last_check_at"] is not None:
|
|
113
|
+
if latest_check is None or state["last_check_at"] > latest_check:
|
|
114
|
+
latest_check = state["last_check_at"]
|
|
115
|
+
|
|
116
|
+
return {
|
|
117
|
+
"inventory_loaded": True,
|
|
118
|
+
"pairs_declared": len(pairs),
|
|
119
|
+
"in_lease": in_lease,
|
|
120
|
+
"drifted": drifted,
|
|
121
|
+
"sensor_stale": sensor_stale,
|
|
122
|
+
"last_check_at": latest_check,
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async def _get_pair_state(self, pair: dict[str, Any]) -> dict[str, Any]:
|
|
126
|
+
"""
|
|
127
|
+
Derive the current state of one projection pair.
|
|
128
|
+
|
|
129
|
+
States:
|
|
130
|
+
- in_lease: sensor recently heartbeated; no open drift findings
|
|
131
|
+
- drifted: one or more open findings under the pair's rule_id
|
|
132
|
+
- sensor_stale: sensor has not heartbeated within the freshness window
|
|
133
|
+
"""
|
|
134
|
+
session = self._require_session()
|
|
135
|
+
sensor_worker_name = pair.get("sensor_worker", "")
|
|
136
|
+
rule_id = pair.get("rule_id", "")
|
|
137
|
+
freshness_seconds = pair.get("freshness_seconds", _DEFAULT_FRESHNESS_SECONDS)
|
|
138
|
+
|
|
139
|
+
# Most recent heartbeat for the declared sensor worker.
|
|
140
|
+
heartbeat_result = await session.execute(
|
|
141
|
+
text(
|
|
142
|
+
"""
|
|
143
|
+
SELECT last_heartbeat
|
|
144
|
+
FROM core.worker_registry
|
|
145
|
+
WHERE declaration_name = :name
|
|
146
|
+
ORDER BY last_heartbeat DESC NULLS LAST
|
|
147
|
+
LIMIT 1
|
|
148
|
+
"""
|
|
149
|
+
),
|
|
150
|
+
{"name": sensor_worker_name},
|
|
151
|
+
)
|
|
152
|
+
heartbeat_row = heartbeat_result.fetchone()
|
|
153
|
+
last_heartbeat: datetime | None = heartbeat_row[0] if heartbeat_row else None
|
|
154
|
+
|
|
155
|
+
# Sensor-stale check: if no heartbeat at all, OR last heartbeat older
|
|
156
|
+
# than the freshness window, the sensor is not observable.
|
|
157
|
+
if last_heartbeat is None:
|
|
158
|
+
return {"status": "sensor_stale", "last_check_at": None}
|
|
159
|
+
now = datetime.now(UTC)
|
|
160
|
+
# Heartbeats persist as TIMESTAMPTZ but may be returned naive on some
|
|
161
|
+
# drivers; coerce defensively.
|
|
162
|
+
if last_heartbeat.tzinfo is None:
|
|
163
|
+
last_heartbeat = last_heartbeat.replace(tzinfo=UTC)
|
|
164
|
+
if now - last_heartbeat > timedelta(seconds=freshness_seconds):
|
|
165
|
+
return {"status": "sensor_stale", "last_check_at": last_heartbeat}
|
|
166
|
+
|
|
167
|
+
# Drift check: any open findings under this pair's rule_id.
|
|
168
|
+
# Writer-as-sensor pairs (remediation.mode: inline) post findings
|
|
169
|
+
# with status='resolved' directly, so they never count as drifted
|
|
170
|
+
# here even when a reap happened — which is the correct semantic
|
|
171
|
+
# per ADR-070 D4 (drift was detected and immediately remediated).
|
|
172
|
+
if rule_id:
|
|
173
|
+
drift_result = await session.execute(
|
|
174
|
+
text(
|
|
175
|
+
"""
|
|
176
|
+
SELECT count(*) FROM core.blackboard_entries
|
|
177
|
+
WHERE entry_type = 'finding'
|
|
178
|
+
AND subject = :rule_id
|
|
179
|
+
AND status = 'open'
|
|
180
|
+
"""
|
|
181
|
+
),
|
|
182
|
+
{"rule_id": rule_id},
|
|
183
|
+
)
|
|
184
|
+
open_count = int(drift_result.scalar_one() or 0)
|
|
185
|
+
if open_count > 0:
|
|
186
|
+
return {"status": "drifted", "last_check_at": last_heartbeat}
|
|
187
|
+
|
|
188
|
+
return {"status": "in_lease", "last_check_at": last_heartbeat}
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def _load_inventory() -> dict[str, Any] | None:
|
|
192
|
+
"""
|
|
193
|
+
Load the projection inventory from .intent/governance/projections.yaml.
|
|
194
|
+
|
|
195
|
+
Returns None if the file is absent or unparseable — the audit advisory
|
|
196
|
+
line treats this as "no pairs declared." A failure to load is not
|
|
197
|
+
raised because the advisory line must not block audit completion.
|
|
198
|
+
"""
|
|
199
|
+
if not _INVENTORY_PATH.exists():
|
|
200
|
+
return None
|
|
201
|
+
try:
|
|
202
|
+
return yaml.safe_load(_INVENTORY_PATH.read_text(encoding="utf-8"))
|
|
203
|
+
except Exception as exc:
|
|
204
|
+
logger.warning(
|
|
205
|
+
"RepresentationCoherenceService: failed to load %s: %s",
|
|
206
|
+
_INVENTORY_PATH,
|
|
207
|
+
exc,
|
|
208
|
+
)
|
|
209
|
+
return None
|