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,328 @@
|
|
|
1
|
+
# src/will/workers/violation_remediator_proposal.py
|
|
2
|
+
"""
|
|
3
|
+
Proposal creation, active-proposal dedup index, and circuit-breaker
|
|
4
|
+
gate for ViolationRemediatorWorker.
|
|
5
|
+
|
|
6
|
+
Collaborator module. Owns three operations that ViolationRemediatorWorker
|
|
7
|
+
calls from its run loop:
|
|
8
|
+
|
|
9
|
+
- create_proposal: build a Proposal from a (ref_id, ref_kind, findings) group,
|
|
10
|
+
validate it, persist via ProposalRepository, auto-approve through
|
|
11
|
+
ProposalStateManager when risk classification says safe, and return the
|
|
12
|
+
proposal_id. Safe proposals land in APPROVED status so the consumer worker
|
|
13
|
+
can pick them up without a separate human approval step (ADR-035 D1;
|
|
14
|
+
per-finding scope keyed by (action_id, file_path) for atomic actions, or
|
|
15
|
+
by flow_id alone for flows).
|
|
16
|
+
- get_active_proposal_id_by_action_file: load all proposals in active states
|
|
17
|
+
({DRAFT, PENDING, APPROVED, EXECUTING}) and return a
|
|
18
|
+
(ref_id, file_path) → proposal_id map keyed for the dedup-subsume check
|
|
19
|
+
(ADR-035 D2). Earliest by Proposal.created_at wins — the original anchor
|
|
20
|
+
whose existence caused subsequent dedup-subsume decisions. The dedup-
|
|
21
|
+
subsume path records the subsuming proposal_id on the resolved finding's
|
|
22
|
+
payload as the audit linkage (URS Q1.F / ADR-015 D4).
|
|
23
|
+
- check_circuit_breaker: opens a short-lived session and returns the
|
|
24
|
+
ADR-038 consecutive-identical-failure streak count for a
|
|
25
|
+
(ref_id, file_path) before the next proposal is minted. Fail-soft on
|
|
26
|
+
DB error: returns (0, None, None, None) so the breaker degrades
|
|
27
|
+
toward retry rather than silent rejection on transient infra.
|
|
28
|
+
|
|
29
|
+
Implements:
|
|
30
|
+
ADR-035 — per-finding proposal scoping (one proposal per (action, file))
|
|
31
|
+
ADR-010 — Finding→Proposal linkage on the happy path
|
|
32
|
+
ADR-038 — circuit-breaker context (this module produces the proposal that
|
|
33
|
+
the breaker counts failures on; the trip itself lives in
|
|
34
|
+
circuit_breaker.py)
|
|
35
|
+
|
|
36
|
+
Dependencies are acquired lazily inside each function via the body service
|
|
37
|
+
registry — same pattern as proposal_consumer_revival.mark_proposal_failed,
|
|
38
|
+
which is the precedent for proposal-row mutations from a will collaborator
|
|
39
|
+
module. No file writes, no LLM calls. No Worker reference required —
|
|
40
|
+
nothing in this module posts to the blackboard.
|
|
41
|
+
|
|
42
|
+
LAYER: will/workers — internal collaborator of ViolationRemediatorWorker.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from __future__ import annotations
|
|
46
|
+
|
|
47
|
+
from typing import Any
|
|
48
|
+
|
|
49
|
+
from shared.logger import getLogger
|
|
50
|
+
from will.autonomy.proposal import (
|
|
51
|
+
Proposal,
|
|
52
|
+
ProposalAction,
|
|
53
|
+
ProposalScope,
|
|
54
|
+
ProposalStatus,
|
|
55
|
+
)
|
|
56
|
+
from will.workers.circuit_breaker import recent_consecutive_identical_count
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
logger = getLogger(__name__)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
_ACTIVE_STATUSES: frozenset[ProposalStatus] = frozenset(
|
|
63
|
+
{
|
|
64
|
+
ProposalStatus.DRAFT,
|
|
65
|
+
ProposalStatus.PENDING,
|
|
66
|
+
ProposalStatus.APPROVED,
|
|
67
|
+
ProposalStatus.EXECUTING,
|
|
68
|
+
}
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _entry_id(finding: dict[str, Any]) -> str:
|
|
73
|
+
"""Extract the blackboard-entry id from a finding dict.
|
|
74
|
+
|
|
75
|
+
Findings arriving from BlackboardService carry either 'id' or 'entry_id'
|
|
76
|
+
depending on the serialization path; both are accepted. Raises
|
|
77
|
+
ValueError if neither is present.
|
|
78
|
+
"""
|
|
79
|
+
value = finding.get("id") or finding.get("entry_id")
|
|
80
|
+
if value is None:
|
|
81
|
+
raise ValueError(f"Finding has neither 'id' nor 'entry_id': {finding!r}")
|
|
82
|
+
return str(value)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# ID: f922189d-4c9d-478b-ab6f-6bf179221773
|
|
86
|
+
async def create_proposal(
|
|
87
|
+
ref_id: str,
|
|
88
|
+
ref_kind: str,
|
|
89
|
+
findings: list[dict[str, Any]],
|
|
90
|
+
) -> str | None:
|
|
91
|
+
"""Create and persist a Proposal for the given remediation reference.
|
|
92
|
+
|
|
93
|
+
ref_kind selects the ProposalAction shape: "action" produces
|
|
94
|
+
ProposalAction(action_id=ref_id, ...) and "flow" produces
|
|
95
|
+
ProposalAction(flow_id=ref_id, ...). The two are mutually exclusive
|
|
96
|
+
per ProposalAction.__post_init__.
|
|
97
|
+
|
|
98
|
+
Safe proposals (approval_required=False) are auto-approved through
|
|
99
|
+
ProposalStateManager so the row carries approval_authority
|
|
100
|
+
(URS NFR.5; ADR-015 D6) and the consumer worker can execute without
|
|
101
|
+
a separate approval step. Proposals requiring human approval stay
|
|
102
|
+
in DRAFT.
|
|
103
|
+
|
|
104
|
+
Returns proposal_id on success, None on validation or persistence
|
|
105
|
+
failure.
|
|
106
|
+
"""
|
|
107
|
+
from body.services.service_registry import service_registry
|
|
108
|
+
from will.autonomy.proposal_repository import ProposalRepository
|
|
109
|
+
from will.autonomy.proposal_state_manager import ProposalStateManager
|
|
110
|
+
|
|
111
|
+
affected_files: list[str] = sorted(
|
|
112
|
+
{
|
|
113
|
+
f["payload"].get("file_path", "")
|
|
114
|
+
for f in findings
|
|
115
|
+
if f["payload"].get("file_path")
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
rules = sorted(
|
|
120
|
+
{
|
|
121
|
+
f["payload"].get("check_id") or f["payload"].get("rule", "unknown")
|
|
122
|
+
for f in findings
|
|
123
|
+
}
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
# finding_ids mirrors the entry_ids subsequently passed to
|
|
127
|
+
# defer_to_proposal in the worker run loop, making the proposal→finding
|
|
128
|
+
# read path symmetric with the finding→proposal write path. Consumed
|
|
129
|
+
# by ProposalExecutor when emitting consequence-log entries
|
|
130
|
+
# (proposal_executor.py:265-266). ADR-015 D7: forward-only — historical
|
|
131
|
+
# proposals predating this field are not backfilled.
|
|
132
|
+
finding_ids = [_entry_id(f) for f in findings]
|
|
133
|
+
|
|
134
|
+
# ADR-032+: omit file_path from parameters when the ref is a flow.
|
|
135
|
+
# Flows are codebase-wide operations; per-file file_path is a category
|
|
136
|
+
# mismatch. ADR-033's parameter-routing filter discards it at runtime,
|
|
137
|
+
# but persisting meaningless data here is confusing. Atomic actions
|
|
138
|
+
# keep file_path because ADR-035 makes (action_id, file_path) the
|
|
139
|
+
# proposal scope unit.
|
|
140
|
+
if affected_files:
|
|
141
|
+
proposal_actions = [
|
|
142
|
+
ProposalAction(
|
|
143
|
+
action_id=ref_id if ref_kind == "action" else None,
|
|
144
|
+
flow_id=ref_id if ref_kind == "flow" else None,
|
|
145
|
+
parameters=(
|
|
146
|
+
{"write": True, "file_path": file_path}
|
|
147
|
+
if ref_kind == "action"
|
|
148
|
+
else {"write": True}
|
|
149
|
+
),
|
|
150
|
+
order=order,
|
|
151
|
+
)
|
|
152
|
+
for order, file_path in enumerate(affected_files)
|
|
153
|
+
]
|
|
154
|
+
else:
|
|
155
|
+
proposal_actions = [
|
|
156
|
+
ProposalAction(
|
|
157
|
+
action_id=ref_id if ref_kind == "action" else None,
|
|
158
|
+
flow_id=ref_id if ref_kind == "flow" else None,
|
|
159
|
+
parameters=(
|
|
160
|
+
{"write": True, "file_path": None}
|
|
161
|
+
if ref_kind == "action"
|
|
162
|
+
else {"write": True}
|
|
163
|
+
),
|
|
164
|
+
order=0,
|
|
165
|
+
)
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
proposal = Proposal(
|
|
169
|
+
goal=(
|
|
170
|
+
f"Autonomous remediation: {ref_id} "
|
|
171
|
+
f"({len(findings)} violation(s) — rules: {', '.join(rules)})"
|
|
172
|
+
),
|
|
173
|
+
actions=proposal_actions,
|
|
174
|
+
scope=ProposalScope(files=affected_files),
|
|
175
|
+
created_by="violation_remediator_worker",
|
|
176
|
+
constitutional_constraints={
|
|
177
|
+
"source": "blackboard_findings",
|
|
178
|
+
"rules": rules,
|
|
179
|
+
"affected_files_count": len(affected_files),
|
|
180
|
+
"finding_ids": finding_ids,
|
|
181
|
+
},
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
proposal.compute_risk()
|
|
185
|
+
|
|
186
|
+
is_valid, errors = proposal.validate()
|
|
187
|
+
if not is_valid:
|
|
188
|
+
logger.warning(
|
|
189
|
+
"ViolationRemediatorWorker: proposal for '%s' failed validation: %s",
|
|
190
|
+
ref_id,
|
|
191
|
+
errors,
|
|
192
|
+
)
|
|
193
|
+
return None
|
|
194
|
+
|
|
195
|
+
try:
|
|
196
|
+
async with service_registry.session() as session:
|
|
197
|
+
repo = ProposalRepository(session)
|
|
198
|
+
proposal_id = await repo.create(proposal)
|
|
199
|
+
|
|
200
|
+
if not proposal.approval_required:
|
|
201
|
+
state_manager = ProposalStateManager(session)
|
|
202
|
+
await state_manager.approve(
|
|
203
|
+
proposal_id,
|
|
204
|
+
approved_by="autonomous_self_promote",
|
|
205
|
+
approval_authority="risk_classification.safe_auto_approval",
|
|
206
|
+
)
|
|
207
|
+
logger.info(
|
|
208
|
+
"ViolationRemediatorWorker: proposal for '%s' auto-approved "
|
|
209
|
+
"(risk=%s, approval_required=False)",
|
|
210
|
+
ref_id,
|
|
211
|
+
proposal.risk.overall_risk if proposal.risk else "unknown",
|
|
212
|
+
)
|
|
213
|
+
else:
|
|
214
|
+
logger.info(
|
|
215
|
+
"ViolationRemediatorWorker: proposal for '%s' requires human "
|
|
216
|
+
"approval (risk=%s) — created in DRAFT",
|
|
217
|
+
ref_id,
|
|
218
|
+
proposal.risk.overall_risk if proposal.risk else "unknown",
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
await session.commit()
|
|
222
|
+
return proposal_id
|
|
223
|
+
except Exception as e:
|
|
224
|
+
logger.error(
|
|
225
|
+
"ViolationRemediatorWorker: failed to persist proposal for '%s': %s",
|
|
226
|
+
ref_id,
|
|
227
|
+
e,
|
|
228
|
+
)
|
|
229
|
+
return None
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
# ID: 18141610-fad9-423f-9b8f-cc81c6028f40
|
|
233
|
+
async def get_active_proposal_id_by_action_file() -> dict[tuple[str, str | None], str]:
|
|
234
|
+
"""Return (ref_id, file_path) → proposal_id for active proposals — ADR-035 D2.
|
|
235
|
+
|
|
236
|
+
Per-finding scoping (ADR-035 D1) makes the dedup unit (ref_id,
|
|
237
|
+
file_path), not ref_id alone. ref_id is action.action_id for atomic-
|
|
238
|
+
action proposals or action.flow_id for flow-based proposals.
|
|
239
|
+
file_path lives on action.parameters. The dedup-subsume path needs
|
|
240
|
+
the proposal_id (not just the ref_id) to record the linkage in the
|
|
241
|
+
subsumed finding's payload — URS Q1.F / ADR-015 D4.
|
|
242
|
+
|
|
243
|
+
Historical batch proposals (pre-ADR-035) with multiple ProposalActions
|
|
244
|
+
across different file_paths are handled correctly: each action
|
|
245
|
+
contributes its own (ref_id, file_path) entry.
|
|
246
|
+
|
|
247
|
+
When multiple active proposals share a (ref_id, file_path), the
|
|
248
|
+
earliest by Proposal.created_at wins — the original anchor whose
|
|
249
|
+
existence caused subsequent dedup-subsume decisions.
|
|
250
|
+
|
|
251
|
+
Fail-open: on exception returns an empty dict so the worker
|
|
252
|
+
proceeds without dedup rather than blocking remediation.
|
|
253
|
+
"""
|
|
254
|
+
from body.services.service_registry import service_registry
|
|
255
|
+
from will.autonomy.proposal_repository import ProposalRepository
|
|
256
|
+
|
|
257
|
+
candidates: list[tuple[tuple[str, str | None], str, Any]] = []
|
|
258
|
+
try:
|
|
259
|
+
async with service_registry.session() as session:
|
|
260
|
+
repo = ProposalRepository(session)
|
|
261
|
+
for status in _ACTIVE_STATUSES:
|
|
262
|
+
proposals = await repo.list_by_status(status, limit=200)
|
|
263
|
+
for proposal in proposals:
|
|
264
|
+
for action in proposal.actions:
|
|
265
|
+
action_file_path = (
|
|
266
|
+
action.parameters.get("file_path")
|
|
267
|
+
if action.parameters
|
|
268
|
+
else None
|
|
269
|
+
)
|
|
270
|
+
candidates.append(
|
|
271
|
+
(
|
|
272
|
+
(action.ref_id, action_file_path),
|
|
273
|
+
proposal.proposal_id,
|
|
274
|
+
proposal.created_at,
|
|
275
|
+
)
|
|
276
|
+
)
|
|
277
|
+
except Exception as e:
|
|
278
|
+
logger.warning(
|
|
279
|
+
"ViolationRemediatorWorker: could not load active proposals (%s). "
|
|
280
|
+
"Proceeding without deduplication.",
|
|
281
|
+
e,
|
|
282
|
+
)
|
|
283
|
+
return {}
|
|
284
|
+
|
|
285
|
+
candidates.sort(key=lambda t: t[2])
|
|
286
|
+
result: dict[tuple[str, str | None], str] = {}
|
|
287
|
+
for key, proposal_id, _created_at in candidates:
|
|
288
|
+
result.setdefault(key, proposal_id)
|
|
289
|
+
return result
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
# ID: 856e5070-2566-4a25-be09-4c9ae9cf6964
|
|
293
|
+
async def check_circuit_breaker(
|
|
294
|
+
*,
|
|
295
|
+
ref_id: str,
|
|
296
|
+
ref_kind: str,
|
|
297
|
+
file_path: str | None,
|
|
298
|
+
config: Any,
|
|
299
|
+
) -> tuple[int, str | None, str | None, str | None]:
|
|
300
|
+
"""ADR-038 consecutive-identical-failure streak for (ref_id, file_path).
|
|
301
|
+
|
|
302
|
+
Opens its own short-lived session so the breaker query does not
|
|
303
|
+
extend the lifetime of the ProposalRepository session that backs
|
|
304
|
+
create_proposal. Fail-soft: any DB error returns (0, None, None, None)
|
|
305
|
+
so the breaker degrades toward retry rather than silent rejection on
|
|
306
|
+
transient infra issues.
|
|
307
|
+
"""
|
|
308
|
+
from body.services.service_registry import service_registry
|
|
309
|
+
|
|
310
|
+
try:
|
|
311
|
+
async with service_registry.session() as session:
|
|
312
|
+
return await recent_consecutive_identical_count(
|
|
313
|
+
session,
|
|
314
|
+
ref_id=ref_id,
|
|
315
|
+
ref_kind=ref_kind,
|
|
316
|
+
file_path=file_path,
|
|
317
|
+
config=config,
|
|
318
|
+
)
|
|
319
|
+
except Exception as exc:
|
|
320
|
+
logger.warning(
|
|
321
|
+
"ViolationRemediatorWorker: circuit-breaker session failed for "
|
|
322
|
+
"(%s, %s, %s): %s — proceeding without gate.",
|
|
323
|
+
ref_kind,
|
|
324
|
+
ref_id,
|
|
325
|
+
file_path,
|
|
326
|
+
exc,
|
|
327
|
+
)
|
|
328
|
+
return 0, None, None, None
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
# src/will/workers/worker_shop_manager.py
|
|
2
|
+
"""
|
|
3
|
+
WorkerShopManager - Worker Liveness Supervisory Worker.
|
|
4
|
+
|
|
5
|
+
Responsibility: Detect workers that have missed their declared heartbeat
|
|
6
|
+
schedule and post a finding to the Blackboard for each silent or abandoned
|
|
7
|
+
worker.
|
|
8
|
+
|
|
9
|
+
Constitutional standing:
|
|
10
|
+
- Declaration: .intent/workers/worker_shop_manager.yaml
|
|
11
|
+
- Class: supervision
|
|
12
|
+
- Phase: audit
|
|
13
|
+
- Permitted tools: none — deterministic DB reads only
|
|
14
|
+
- Approval: false — findings are observations only
|
|
15
|
+
- Schedule: max_interval=120s, glide_off=12s (10% default)
|
|
16
|
+
|
|
17
|
+
Self-scheduling: WorkerShopManager manages its own asyncio loop via run_loop().
|
|
18
|
+
Sanctuary starts run_loop() once on bootstrap.
|
|
19
|
+
|
|
20
|
+
LAYER: will/workers — supervisory worker. Reads worker_registry, reads
|
|
21
|
+
.intent/workers/ declarations for scheduled workers. Writes to Blackboard
|
|
22
|
+
only. No LLM. No file writes.
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
import asyncio
|
|
28
|
+
import re
|
|
29
|
+
import time
|
|
30
|
+
from typing import Any
|
|
31
|
+
|
|
32
|
+
from shared.infrastructure.intent.operational_config import load_operational_config
|
|
33
|
+
from shared.logger import getLogger
|
|
34
|
+
from shared.workers.base import Worker
|
|
35
|
+
from shared.workers.schedule import (
|
|
36
|
+
WorkerScheduleState,
|
|
37
|
+
load_worker_schedule_state,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
logger = getLogger(__name__)
|
|
42
|
+
|
|
43
|
+
_FINDING_SUBJECT = "worker.silent"
|
|
44
|
+
|
|
45
|
+
_CFG = load_operational_config().workers.worker_shop
|
|
46
|
+
|
|
47
|
+
# Strip non-ASCII characters that PostgreSQL SQL_ASCII encoding cannot store.
|
|
48
|
+
# Worker names from .intent/workers/ YAML titles may contain Unicode dashes or
|
|
49
|
+
# other decorative characters that cause UntranslatableCharacterError on insert.
|
|
50
|
+
_NON_ASCII_RE = re.compile(r"[^\x09\x0A\x0D\x20-\x7E]")
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _sanitize(value: str) -> str:
|
|
54
|
+
"""Replace non-ASCII characters with '?' for SQL_ASCII database safety."""
|
|
55
|
+
if not isinstance(value, str):
|
|
56
|
+
return str(value)
|
|
57
|
+
return _NON_ASCII_RE.sub("?", value)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
# ID: c3e4f5a6-b7c8-4d9e-0f1a-2b3c4d5e6f7a
|
|
61
|
+
class WorkerShopManager(Worker):
|
|
62
|
+
"""
|
|
63
|
+
Governance worker. Reads worker_registry, computes per-worker liveness
|
|
64
|
+
thresholds from .intent/ declarations, and posts a finding for each
|
|
65
|
+
worker that has exceeded max_interval + glide_off since last heartbeat.
|
|
66
|
+
|
|
67
|
+
Uses deduplication — does not re-post a finding for a worker already
|
|
68
|
+
flagged as silent unless the previous finding is resolved.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
declaration_name = "worker_shop_manager"
|
|
72
|
+
|
|
73
|
+
def __init__(self) -> None:
|
|
74
|
+
super().__init__()
|
|
75
|
+
schedule = self._declaration.get("mandate", {}).get("schedule", {})
|
|
76
|
+
self._max_interval: int = schedule.get("max_interval", 120)
|
|
77
|
+
self._glide_off: int = schedule.get(
|
|
78
|
+
"glide_off", max(int(self._max_interval * _CFG.glide_off_multiplier), 10)
|
|
79
|
+
)
|
|
80
|
+
# Per-worker schedule state loaded once per cycle from .intent/workers/.
|
|
81
|
+
# Sourced via the shared loader (ADR-041 D4) so the dashboard and
|
|
82
|
+
# health_log_service apply the same per-worker thresholds and the same
|
|
83
|
+
# orphan-skip rule as this supervisor.
|
|
84
|
+
self._schedule_state: WorkerScheduleState = WorkerScheduleState(
|
|
85
|
+
thresholds={},
|
|
86
|
+
active_uuids=frozenset(),
|
|
87
|
+
fallback_sec=_CFG.fallback_threshold_sec,
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
# -------------------------------------------------------------------------
|
|
91
|
+
# Self-scheduling entry point — called once by Sanctuary
|
|
92
|
+
# -------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
# ID: d4f5a6b7-c8d9-4e0f-1a2b-3c4d5e6f7a8b
|
|
95
|
+
async def run_loop(self) -> None:
|
|
96
|
+
"""
|
|
97
|
+
Continuous self-scheduling loop. Runs one audit cycle per
|
|
98
|
+
max_interval seconds. Sanctuary calls this once on bootstrap.
|
|
99
|
+
"""
|
|
100
|
+
logger.info(
|
|
101
|
+
"WorkerShopManager: starting loop (max_interval=%ds, glide_off=%ds)",
|
|
102
|
+
self._max_interval,
|
|
103
|
+
self._glide_off,
|
|
104
|
+
)
|
|
105
|
+
await self._register()
|
|
106
|
+
|
|
107
|
+
while True:
|
|
108
|
+
cycle_start = time.monotonic()
|
|
109
|
+
try:
|
|
110
|
+
await self.run()
|
|
111
|
+
except Exception as exc:
|
|
112
|
+
logger.error("WorkerShopManager: cycle failed: %s", exc, exc_info=True)
|
|
113
|
+
try:
|
|
114
|
+
await self._post_entry(
|
|
115
|
+
entry_type="report",
|
|
116
|
+
subject="worker_shop_manager.cycle_error",
|
|
117
|
+
payload={"error": _sanitize(str(exc))},
|
|
118
|
+
status="abandoned",
|
|
119
|
+
)
|
|
120
|
+
except Exception:
|
|
121
|
+
logger.exception("WorkerShopManager: failed to post error report")
|
|
122
|
+
|
|
123
|
+
elapsed = time.monotonic() - cycle_start
|
|
124
|
+
await asyncio.sleep(max(self._max_interval - elapsed, 0))
|
|
125
|
+
|
|
126
|
+
# -------------------------------------------------------------------------
|
|
127
|
+
# Single audit cycle
|
|
128
|
+
# -------------------------------------------------------------------------
|
|
129
|
+
|
|
130
|
+
# ID: e5a6b7c8-d9e0-4f1a-2b3c-4d5e6f7a8b9c
|
|
131
|
+
async def run(self) -> None:
|
|
132
|
+
"""
|
|
133
|
+
Execute one liveness audit cycle:
|
|
134
|
+
1. Post heartbeat
|
|
135
|
+
2. Load per-worker schedules from .intent/
|
|
136
|
+
3. Fetch registered workers from DB
|
|
137
|
+
4. For each worker exceeding threshold: post finding (deduplicated)
|
|
138
|
+
5. Resolve open findings whose worker has resumed heartbeating
|
|
139
|
+
6. Post completion report
|
|
140
|
+
"""
|
|
141
|
+
from body.services.service_registry import service_registry
|
|
142
|
+
|
|
143
|
+
await self.post_heartbeat()
|
|
144
|
+
|
|
145
|
+
self._schedule_state = load_worker_schedule_state()
|
|
146
|
+
workers = await self._fetch_registered_workers(service_registry)
|
|
147
|
+
existing = await self._fetch_existing_findings(service_registry)
|
|
148
|
+
|
|
149
|
+
flagged = 0
|
|
150
|
+
flagged_subjects: set[str] = set()
|
|
151
|
+
for worker in workers:
|
|
152
|
+
# Sanitize worker_name — registry may contain non-ASCII characters
|
|
153
|
+
# from YAML titles (e.g. em dashes). SQL_ASCII encoding rejects them.
|
|
154
|
+
worker_name = _sanitize(worker["worker_name"])
|
|
155
|
+
worker_uuid = str(worker["worker_uuid"])
|
|
156
|
+
seconds_silent = worker["seconds_silent"]
|
|
157
|
+
|
|
158
|
+
if worker_uuid not in self._schedule_state.active_uuids:
|
|
159
|
+
logger.debug(
|
|
160
|
+
"WorkerShopManager: skipping orphan registry row "
|
|
161
|
+
"%s (%s) — UUID not declared in any active worker YAML",
|
|
162
|
+
worker_uuid,
|
|
163
|
+
worker_name,
|
|
164
|
+
)
|
|
165
|
+
continue
|
|
166
|
+
|
|
167
|
+
threshold = self._schedule_state.thresholds.get(
|
|
168
|
+
worker_uuid, _CFG.fallback_threshold_sec
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
if seconds_silent > threshold:
|
|
172
|
+
subject = f"{_FINDING_SUBJECT}::{worker_uuid}"
|
|
173
|
+
flagged_subjects.add(subject)
|
|
174
|
+
if subject in existing:
|
|
175
|
+
logger.debug(
|
|
176
|
+
"WorkerShopManager: %s already flagged, skipping.", worker_name
|
|
177
|
+
)
|
|
178
|
+
continue
|
|
179
|
+
|
|
180
|
+
await self.post_observation(
|
|
181
|
+
subject=subject,
|
|
182
|
+
payload={
|
|
183
|
+
"worker_name": worker_name,
|
|
184
|
+
"worker_uuid": worker_uuid,
|
|
185
|
+
"seconds_silent": seconds_silent,
|
|
186
|
+
"threshold": threshold,
|
|
187
|
+
},
|
|
188
|
+
status="abandoned",
|
|
189
|
+
)
|
|
190
|
+
flagged += 1
|
|
191
|
+
logger.warning(
|
|
192
|
+
"WorkerShopManager: %s silent for %ds (threshold=%ds)",
|
|
193
|
+
worker_name,
|
|
194
|
+
seconds_silent,
|
|
195
|
+
threshold,
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
# Resolution pass — any open worker.silent finding whose subject is
|
|
199
|
+
# no longer over threshold means the worker has resumed heartbeating.
|
|
200
|
+
svc = await service_registry.get_blackboard_service()
|
|
201
|
+
resolved = 0
|
|
202
|
+
for subject, entry_id in existing.items():
|
|
203
|
+
if subject not in flagged_subjects:
|
|
204
|
+
await svc.resolve_entries([entry_id])
|
|
205
|
+
resolved += 1
|
|
206
|
+
logger.info(
|
|
207
|
+
"WorkerShopManager: %s recovered — resolving open finding",
|
|
208
|
+
subject,
|
|
209
|
+
)
|
|
210
|
+
|
|
211
|
+
await self.post_report(
|
|
212
|
+
subject="worker_shop_manager.run.complete",
|
|
213
|
+
payload={
|
|
214
|
+
"workers_checked": len(workers),
|
|
215
|
+
"flagged": flagged,
|
|
216
|
+
"resolved": resolved,
|
|
217
|
+
},
|
|
218
|
+
)
|
|
219
|
+
logger.info(
|
|
220
|
+
"WorkerShopManager: cycle complete — checked=%d flagged=%d resolved=%d",
|
|
221
|
+
len(workers),
|
|
222
|
+
flagged,
|
|
223
|
+
resolved,
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
# -------------------------------------------------------------------------
|
|
227
|
+
# DB reads
|
|
228
|
+
# -------------------------------------------------------------------------
|
|
229
|
+
|
|
230
|
+
async def _fetch_registered_workers(self, registry: Any) -> list[dict[str, Any]]:
|
|
231
|
+
"""Return all active workers with seconds since last heartbeat."""
|
|
232
|
+
svc = await registry.get_worker_registry_service()
|
|
233
|
+
return await svc.fetch_registered_workers()
|
|
234
|
+
|
|
235
|
+
async def _fetch_existing_findings(self, registry: Any) -> dict[str, str]:
|
|
236
|
+
"""
|
|
237
|
+
Return mapping of subject → entry_id for open worker.silent findings.
|
|
238
|
+
|
|
239
|
+
The entry_id is needed so the resolution pass in run() can call
|
|
240
|
+
resolve_entries() on findings whose worker has recovered.
|
|
241
|
+
"""
|
|
242
|
+
svc = await registry.get_blackboard_service()
|
|
243
|
+
rows = await svc.fetch_open_findings(prefix=f"{_FINDING_SUBJECT}::%", limit=200)
|
|
244
|
+
return {row["subject"]: row["id"] for row in rows}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# src/will/workflows/__init__.py
|
|
2
|
+
"""
|
|
3
|
+
Workflow Orchestrators - Constitutional Composition
|
|
4
|
+
|
|
5
|
+
Workflows compose atomic actions into governed, multi-phase operations.
|
|
6
|
+
Each workflow has:
|
|
7
|
+
- Declared goal
|
|
8
|
+
- Organized phases
|
|
9
|
+
- Structured results
|
|
10
|
+
- Full audit trail
|
|
11
|
+
- Constitutional validation
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
from shared.models.workflow_models import WorkflowResult
|
|
17
|
+
from will.workflows.dev_sync_workflow import DevSyncWorkflow
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
__all__ = [
|
|
21
|
+
"DevSyncWorkflow",
|
|
22
|
+
"WorkflowResult",
|
|
23
|
+
]
|