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,201 @@
|
|
|
1
|
+
# src/body/self_healing/handlers/id_assignment_handler.py
|
|
2
|
+
"""
|
|
3
|
+
ID assignment handler for audit remediation.
|
|
4
|
+
|
|
5
|
+
Pure-AST, deterministic handler. Inserts # ID: <uuid> comments above public
|
|
6
|
+
functions, methods, and classes that lack one in the file identified by the
|
|
7
|
+
audit finding. No LLM required.
|
|
8
|
+
|
|
9
|
+
Handler for check_id: linkage.assign_ids
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import ast
|
|
15
|
+
import time
|
|
16
|
+
import uuid
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from body.self_healing.remediation_models import FixResult
|
|
20
|
+
from shared.ast_utility import find_symbol_id_and_def_line
|
|
21
|
+
from shared.infrastructure.storage.file_handler import FileHandler
|
|
22
|
+
from shared.logger import getLogger
|
|
23
|
+
from shared.models import AuditFinding
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
logger = getLogger(__name__)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def _is_public(node: ast.FunctionDef | ast.AsyncFunctionDef | ast.ClassDef) -> bool:
|
|
30
|
+
"""Returns True if the symbol is public — no leading underscore, not a dunder."""
|
|
31
|
+
is_dunder = node.name.startswith("__") and node.name.endswith("__")
|
|
32
|
+
return not node.name.startswith("_") and not is_dunder
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
# ID: 3e8f1a2b-c4d5-4e6f-9a7b-8c2d0e1f3a5b
|
|
36
|
+
async def assign_missing_ids_handler(
|
|
37
|
+
finding: AuditFinding,
|
|
38
|
+
file_handler: FileHandler,
|
|
39
|
+
repo_root: Path,
|
|
40
|
+
write: bool,
|
|
41
|
+
) -> FixResult:
|
|
42
|
+
"""
|
|
43
|
+
Insert # ID: <uuid> above every public function, method, and class in the
|
|
44
|
+
file identified by the audit finding that currently lacks one.
|
|
45
|
+
|
|
46
|
+
Algorithm:
|
|
47
|
+
1. Parse the file with ast.parse.
|
|
48
|
+
2. Walk the AST; for each public FunctionDef, AsyncFunctionDef, or
|
|
49
|
+
ClassDef, call find_symbol_id_and_def_line to determine whether an
|
|
50
|
+
ID tag already exists immediately above the def/class keyword
|
|
51
|
+
(decorator-aware).
|
|
52
|
+
3. Collect all missing-ID locations, sort descending by line number so
|
|
53
|
+
that inserting a new line above an early symbol does not shift the
|
|
54
|
+
line indices of later ones.
|
|
55
|
+
4. Insert indentation-matched # ID: <uuid4> lines into the line list.
|
|
56
|
+
5. Write the result via FileHandler (constitutional write gateway).
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
finding: Audit finding from check_id=linkage.assign_ids.
|
|
60
|
+
finding.file_path must be relative to repo_root.
|
|
61
|
+
file_handler: Constitutional write gateway.
|
|
62
|
+
repo_root: Repository root for path resolution.
|
|
63
|
+
write: If False, performs a dry-run and reports what would change.
|
|
64
|
+
|
|
65
|
+
Returns:
|
|
66
|
+
FixResult with ok=True on success or dry-run.
|
|
67
|
+
changes_made keys:
|
|
68
|
+
ids_inserted — number of IDs written (write mode)
|
|
69
|
+
would_insert — number of IDs that would be written (dry-run)
|
|
70
|
+
symbols — names of affected symbols
|
|
71
|
+
already_complete — True when no symbols are missing IDs
|
|
72
|
+
duration_ms — elapsed time
|
|
73
|
+
"""
|
|
74
|
+
start_time = time.time()
|
|
75
|
+
|
|
76
|
+
if not finding.file_path:
|
|
77
|
+
logger.warning("Finding has no file_path, cannot fix: %s", finding.message)
|
|
78
|
+
return FixResult(
|
|
79
|
+
ok=False,
|
|
80
|
+
error_message="No file path in finding",
|
|
81
|
+
changes_made=None,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
file_path = repo_root / finding.file_path
|
|
85
|
+
if not file_path.exists():
|
|
86
|
+
logger.error("File does not exist: %s", file_path)
|
|
87
|
+
return FixResult(
|
|
88
|
+
ok=False,
|
|
89
|
+
error_message=f"File not found: {finding.file_path}",
|
|
90
|
+
changes_made=None,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
try:
|
|
94
|
+
content = file_path.read_text(encoding="utf-8")
|
|
95
|
+
except Exception as e:
|
|
96
|
+
logger.error("Failed to read file %s: %s", file_path, e)
|
|
97
|
+
return FixResult(
|
|
98
|
+
ok=False,
|
|
99
|
+
error_message=f"Read failed: {e!s}",
|
|
100
|
+
changes_made=None,
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
try:
|
|
104
|
+
tree = ast.parse(content, filename=str(file_path))
|
|
105
|
+
except SyntaxError as e:
|
|
106
|
+
logger.error("Syntax error in %s — cannot assign IDs: %s", file_path.name, e)
|
|
107
|
+
return FixResult(
|
|
108
|
+
ok=False,
|
|
109
|
+
error_message=f"Syntax error: {e!s}",
|
|
110
|
+
changes_made=None,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
source_lines = content.splitlines()
|
|
114
|
+
|
|
115
|
+
# Collect all public symbols that are missing an ID tag.
|
|
116
|
+
missing: list[dict] = []
|
|
117
|
+
for node in ast.walk(tree):
|
|
118
|
+
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
|
|
119
|
+
if not _is_public(node):
|
|
120
|
+
continue
|
|
121
|
+
id_result = find_symbol_id_and_def_line(node, source_lines)
|
|
122
|
+
if not id_result.has_id:
|
|
123
|
+
missing.append(
|
|
124
|
+
{
|
|
125
|
+
"line_number": id_result.definition_line_num,
|
|
126
|
+
"name": node.name,
|
|
127
|
+
}
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
if not missing:
|
|
131
|
+
duration_ms = int((time.time() - start_time) * 1000)
|
|
132
|
+
logger.info("No missing IDs in %s", finding.file_path)
|
|
133
|
+
return FixResult(
|
|
134
|
+
ok=True,
|
|
135
|
+
error_message=None,
|
|
136
|
+
changes_made={
|
|
137
|
+
"ids_inserted": 0,
|
|
138
|
+
"already_complete": True,
|
|
139
|
+
"duration_ms": duration_ms,
|
|
140
|
+
},
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
# Sort descending so inserting a line above an earlier symbol does not
|
|
144
|
+
# shift the line indices of symbols that come later in the file.
|
|
145
|
+
missing.sort(key=lambda x: x["line_number"], reverse=True)
|
|
146
|
+
|
|
147
|
+
if not write:
|
|
148
|
+
duration_ms = int((time.time() - start_time) * 1000)
|
|
149
|
+
logger.info(
|
|
150
|
+
"Dry-run: Would insert %d ID(s) in %s",
|
|
151
|
+
len(missing),
|
|
152
|
+
finding.file_path,
|
|
153
|
+
)
|
|
154
|
+
return FixResult(
|
|
155
|
+
ok=True,
|
|
156
|
+
error_message=None,
|
|
157
|
+
changes_made={
|
|
158
|
+
"dry_run": True,
|
|
159
|
+
"would_insert": len(missing),
|
|
160
|
+
"symbols": [f["name"] for f in missing],
|
|
161
|
+
"duration_ms": duration_ms,
|
|
162
|
+
},
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
lines = source_lines[:]
|
|
166
|
+
for fix in missing:
|
|
167
|
+
line_index = fix["line_number"] - 1
|
|
168
|
+
original_line = lines[line_index]
|
|
169
|
+
indentation = len(original_line) - len(original_line.lstrip(" "))
|
|
170
|
+
tag_line = f"{' ' * indentation}# ID: {uuid.uuid4()}"
|
|
171
|
+
lines.insert(line_index, tag_line)
|
|
172
|
+
|
|
173
|
+
new_content = "\n".join(lines) + "\n"
|
|
174
|
+
|
|
175
|
+
try:
|
|
176
|
+
rel_path = str(file_path.relative_to(repo_root))
|
|
177
|
+
file_handler.write_runtime_text(rel_path, new_content)
|
|
178
|
+
duration_ms = int((time.time() - start_time) * 1000)
|
|
179
|
+
logger.info(
|
|
180
|
+
"Inserted %d ID(s) in %s (%d ms)",
|
|
181
|
+
len(missing),
|
|
182
|
+
finding.file_path,
|
|
183
|
+
duration_ms,
|
|
184
|
+
)
|
|
185
|
+
return FixResult(
|
|
186
|
+
ok=True,
|
|
187
|
+
error_message=None,
|
|
188
|
+
changes_made={
|
|
189
|
+
"ids_inserted": len(missing),
|
|
190
|
+
"symbols": [f["name"] for f in missing],
|
|
191
|
+
"duration_ms": duration_ms,
|
|
192
|
+
"file_path": rel_path,
|
|
193
|
+
},
|
|
194
|
+
)
|
|
195
|
+
except Exception as e:
|
|
196
|
+
logger.error("Failed to write via FileHandler: %s", e)
|
|
197
|
+
return FixResult(
|
|
198
|
+
ok=False,
|
|
199
|
+
error_message=f"FileHandler write failed: {e!s}",
|
|
200
|
+
changes_made=None,
|
|
201
|
+
)
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
# src/body/self_healing/handlers/import_sorting_handler.py
|
|
2
|
+
"""
|
|
3
|
+
Import sorting handler for audit remediation.
|
|
4
|
+
|
|
5
|
+
This is a SINGLE-FILE fixer that takes one audit finding and fixes
|
|
6
|
+
just that file's import ordering.
|
|
7
|
+
|
|
8
|
+
Different from the CLI command which fixes the whole codebase,
|
|
9
|
+
this works on individual files as directed by audit findings.
|
|
10
|
+
|
|
11
|
+
Uses ruff under the hood, but wraps it in the remediation interface.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from __future__ import annotations
|
|
15
|
+
|
|
16
|
+
import time
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
from body.self_healing.remediation_models import FixResult
|
|
20
|
+
from shared.infrastructure.storage.file_handler import FileHandler
|
|
21
|
+
from shared.logger import getLogger
|
|
22
|
+
from shared.models import AuditFinding
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
logger = getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ID: 97071a65-22bd-4966-b794-7a8801d37fc2
|
|
29
|
+
async def sort_imports_handler(
|
|
30
|
+
finding: AuditFinding, file_handler: FileHandler, repo_root: Path, write: bool
|
|
31
|
+
) -> FixResult:
|
|
32
|
+
"""
|
|
33
|
+
Fix import ordering in a single file using ruff.
|
|
34
|
+
|
|
35
|
+
This handler:
|
|
36
|
+
1. Takes the file path from the audit finding
|
|
37
|
+
2. Runs ruff's import sorter on JUST that file
|
|
38
|
+
3. If write=True, re-writes the file via FileHandler (constitutional compliance)
|
|
39
|
+
4. Returns success/failure status
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
finding: The audit finding that identified the import problem
|
|
43
|
+
file_handler: Constitutional write gateway (ensures IntentGuard enforcement)
|
|
44
|
+
repo_root: Repository root for path resolution
|
|
45
|
+
write: If False, just check if fix would work (dry-run)
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
FixResult indicating success/failure
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
# From audit finding: "Imports not sorted in src/body/cli/admin_cli.py"
|
|
52
|
+
result = await sort_imports_handler(
|
|
53
|
+
finding=finding,
|
|
54
|
+
file_handler=file_handler,
|
|
55
|
+
repo_root=Path("/opt/dev/CORE"),
|
|
56
|
+
write=True
|
|
57
|
+
)
|
|
58
|
+
# Result: FixResult(ok=True, error_message=None, changes_made={"sorted": True})
|
|
59
|
+
"""
|
|
60
|
+
start_time = time.time()
|
|
61
|
+
if not finding.file_path:
|
|
62
|
+
logger.warning("Finding has no file_path, cannot fix: %s", finding.message)
|
|
63
|
+
return FixResult(
|
|
64
|
+
ok=False, error_message="No file path in finding", changes_made=None
|
|
65
|
+
)
|
|
66
|
+
file_path = repo_root / finding.file_path
|
|
67
|
+
if not file_path.exists():
|
|
68
|
+
logger.error("File does not exist: %s", file_path)
|
|
69
|
+
return FixResult(
|
|
70
|
+
ok=False,
|
|
71
|
+
error_message=f"File not found: {finding.file_path}",
|
|
72
|
+
changes_made=None,
|
|
73
|
+
)
|
|
74
|
+
try:
|
|
75
|
+
original_content = file_path.read_text(encoding="utf-8")
|
|
76
|
+
except Exception as e:
|
|
77
|
+
logger.error("Failed to read file %s: %s", file_path, e)
|
|
78
|
+
return FixResult(
|
|
79
|
+
ok=False, error_message=f"Read failed: {e!s}", changes_made=None
|
|
80
|
+
)
|
|
81
|
+
try:
|
|
82
|
+
cmd = ["ruff", "check", str(file_path), "--select", "I", "--exit-zero"]
|
|
83
|
+
if write:
|
|
84
|
+
cmd.append("--fix")
|
|
85
|
+
import asyncio
|
|
86
|
+
|
|
87
|
+
process = await asyncio.create_subprocess_exec(
|
|
88
|
+
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
|
|
89
|
+
)
|
|
90
|
+
_stdout_bytes, _stderr_bytes = await process.communicate()
|
|
91
|
+
if write:
|
|
92
|
+
try:
|
|
93
|
+
new_content = file_path.read_text(encoding="utf-8")
|
|
94
|
+
except Exception as e:
|
|
95
|
+
logger.error("Failed to read modified file %s: %s", file_path, e)
|
|
96
|
+
return FixResult(
|
|
97
|
+
ok=False,
|
|
98
|
+
error_message=f"Post-fix read failed: {e!s}",
|
|
99
|
+
changes_made=None,
|
|
100
|
+
)
|
|
101
|
+
if new_content == original_content:
|
|
102
|
+
duration_ms = int((time.time() - start_time) * 1000)
|
|
103
|
+
logger.info(
|
|
104
|
+
"No changes needed for %s (already sorted)", finding.file_path
|
|
105
|
+
)
|
|
106
|
+
return FixResult(
|
|
107
|
+
ok=True,
|
|
108
|
+
error_message=None,
|
|
109
|
+
changes_made={
|
|
110
|
+
"imports_changed": False,
|
|
111
|
+
"already_sorted": True,
|
|
112
|
+
"duration_ms": duration_ms,
|
|
113
|
+
},
|
|
114
|
+
)
|
|
115
|
+
try:
|
|
116
|
+
rel_path = str(file_path.relative_to(repo_root))
|
|
117
|
+
file_handler.write_source_code(rel_path, new_content)
|
|
118
|
+
duration_ms = int((time.time() - start_time) * 1000)
|
|
119
|
+
logger.info(
|
|
120
|
+
"Successfully sorted imports in %s (%d ms)",
|
|
121
|
+
finding.file_path,
|
|
122
|
+
duration_ms,
|
|
123
|
+
)
|
|
124
|
+
return FixResult(
|
|
125
|
+
ok=True,
|
|
126
|
+
error_message=None,
|
|
127
|
+
changes_made={
|
|
128
|
+
"imports_changed": True,
|
|
129
|
+
"duration_ms": duration_ms,
|
|
130
|
+
"file_path": rel_path,
|
|
131
|
+
},
|
|
132
|
+
)
|
|
133
|
+
except Exception as e:
|
|
134
|
+
logger.error("Failed to write via FileHandler: %s", e)
|
|
135
|
+
return FixResult(
|
|
136
|
+
ok=False,
|
|
137
|
+
error_message=f"FileHandler write failed: {e!s}",
|
|
138
|
+
changes_made=None,
|
|
139
|
+
)
|
|
140
|
+
else:
|
|
141
|
+
duration_ms = int((time.time() - start_time) * 1000)
|
|
142
|
+
logger.info("Dry-run: Would sort imports in %s", finding.file_path)
|
|
143
|
+
return FixResult(
|
|
144
|
+
ok=True,
|
|
145
|
+
error_message=None,
|
|
146
|
+
changes_made={
|
|
147
|
+
"dry_run": True,
|
|
148
|
+
"would_fix": True,
|
|
149
|
+
"duration_ms": duration_ms,
|
|
150
|
+
},
|
|
151
|
+
)
|
|
152
|
+
except Exception as e:
|
|
153
|
+
logger.error("Ruff execution failed: %s", e)
|
|
154
|
+
return FixResult(
|
|
155
|
+
ok=False, error_message=f"Ruff failed: {e!s}", changes_made=None
|
|
156
|
+
)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# ID: 673eec52-3119-407d-b4ef-fbe0fdde22ef
|
|
160
|
+
async def test_handler(repo_root: Path):
|
|
161
|
+
"""
|
|
162
|
+
Quick test function to verify the handler works.
|
|
163
|
+
"""
|
|
164
|
+
from shared.models import AuditSeverity
|
|
165
|
+
|
|
166
|
+
test_finding = AuditFinding(
|
|
167
|
+
check_id="style.import_order",
|
|
168
|
+
severity=AuditSeverity.HIGH,
|
|
169
|
+
message="Imports not sorted",
|
|
170
|
+
file_path="src/body/cli/admin_cli.py",
|
|
171
|
+
line_number=None,
|
|
172
|
+
)
|
|
173
|
+
file_handler = FileHandler(str(repo_root))
|
|
174
|
+
result = await sort_imports_handler(
|
|
175
|
+
finding=test_finding,
|
|
176
|
+
file_handler=file_handler,
|
|
177
|
+
repo_root=repo_root,
|
|
178
|
+
write=False,
|
|
179
|
+
)
|
|
180
|
+
logger.info("Test result: %s", result)
|
|
181
|
+
return result
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
# src/body/self_healing/header_service.py
|
|
2
|
+
|
|
3
|
+
"""
|
|
4
|
+
HeaderService — enforces the constitutional file header law.
|
|
5
|
+
Refactored to use the canonical ActionExecutor Gateway for all mutations.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
10
|
+
import time
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import TYPE_CHECKING, Any
|
|
13
|
+
|
|
14
|
+
from body.atomic.executor import ActionExecutor
|
|
15
|
+
from shared.action_types import ActionImpact, ActionResult
|
|
16
|
+
from shared.atomic_action import atomic_action
|
|
17
|
+
|
|
18
|
+
# REFACTORED: Removed direct settings import
|
|
19
|
+
from shared.logger import getLogger
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if TYPE_CHECKING:
|
|
23
|
+
from shared.context import CoreContext
|
|
24
|
+
|
|
25
|
+
logger = getLogger(__name__)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ID: e1e63d42-0626-40d7-84bc-5d3469a00bc5
|
|
29
|
+
class HeaderService:
|
|
30
|
+
"""Detects and fixes missing or incorrect file path headers in src/**/*.py files."""
|
|
31
|
+
|
|
32
|
+
def __init__(self, repo_root: Path) -> None:
|
|
33
|
+
self.repo_root = repo_root
|
|
34
|
+
|
|
35
|
+
def _get_expected_header(self, file_path: Path) -> str:
|
|
36
|
+
rel_path = file_path.relative_to(self.repo_root).as_posix()
|
|
37
|
+
return f"# {rel_path}"
|
|
38
|
+
|
|
39
|
+
def _get_current_header(self, file_path: Path) -> str | None:
|
|
40
|
+
try:
|
|
41
|
+
lines = file_path.read_text(encoding="utf-8").splitlines()
|
|
42
|
+
except Exception:
|
|
43
|
+
return None
|
|
44
|
+
|
|
45
|
+
for line in lines:
|
|
46
|
+
stripped = line.strip()
|
|
47
|
+
if not stripped:
|
|
48
|
+
continue
|
|
49
|
+
# Check if it's a path comment (starts with # followed by a path)
|
|
50
|
+
if stripped.startswith("#") and "/" in stripped:
|
|
51
|
+
return stripped
|
|
52
|
+
# First non-blank, non-comment line means no header found
|
|
53
|
+
if not stripped.startswith("#"):
|
|
54
|
+
return None
|
|
55
|
+
return None
|
|
56
|
+
|
|
57
|
+
# ID: 8d49b70c-95b6-4aea-b392-6b3c30fac7aa
|
|
58
|
+
def analyze(self, paths: list[str]) -> list[dict[str, Any]]:
|
|
59
|
+
"""Identifies header violations in the provided paths."""
|
|
60
|
+
issues = []
|
|
61
|
+
for p in paths:
|
|
62
|
+
path = Path(p)
|
|
63
|
+
# Ensure we only target source files within the repo
|
|
64
|
+
if path.suffix != ".py" or not str(path.resolve()).startswith(
|
|
65
|
+
str(self.repo_root.resolve() / "src")
|
|
66
|
+
):
|
|
67
|
+
continue
|
|
68
|
+
|
|
69
|
+
expected = self._get_expected_header(path)
|
|
70
|
+
current = self._get_current_header(path)
|
|
71
|
+
|
|
72
|
+
if current != expected:
|
|
73
|
+
issues.append(
|
|
74
|
+
{
|
|
75
|
+
"file": str(path),
|
|
76
|
+
"issue": (
|
|
77
|
+
"missing_header" if current is None else "incorrect_header"
|
|
78
|
+
),
|
|
79
|
+
"current_header": current,
|
|
80
|
+
"expected_header": expected,
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
return issues
|
|
84
|
+
|
|
85
|
+
# ID: 900e1f3e-e89c-4ffc-8814-b6cba069509c
|
|
86
|
+
def analyze_all(self) -> list[dict[str, Any]]:
|
|
87
|
+
"""Scans the entire src directory for header violations."""
|
|
88
|
+
return self.analyze([str(p) for p in self.repo_root.rglob("src/**/*.py")])
|
|
89
|
+
|
|
90
|
+
# ID: fbb21920-5457-4aa2-9ae7-23da72fff8fd
|
|
91
|
+
async def fix(
|
|
92
|
+
self, context: CoreContext, paths: list[str], write: bool = False
|
|
93
|
+
) -> None:
|
|
94
|
+
"""Fixes headers for specific paths via the Action Gateway."""
|
|
95
|
+
issues = self.analyze(paths)
|
|
96
|
+
for issue in issues:
|
|
97
|
+
await self._apply_fix(
|
|
98
|
+
context, Path(issue["file"]), issue["expected_header"], write
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
async def _fix_all(self, context: CoreContext, write: bool = False) -> None:
|
|
102
|
+
"""Fixes all header violations in the project via the Action Gateway."""
|
|
103
|
+
issues = self.analyze_all()
|
|
104
|
+
for issue in issues:
|
|
105
|
+
await self._apply_fix(
|
|
106
|
+
context, Path(issue["file"]), issue["expected_header"], write
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
async def _apply_fix(
|
|
110
|
+
self, context: CoreContext, file_path: Path, expected_header: str, write: bool
|
|
111
|
+
) -> None:
|
|
112
|
+
"""Prepares the new source and dispatches to ActionExecutor."""
|
|
113
|
+
rel_path = str(file_path.relative_to(self.repo_root))
|
|
114
|
+
executor = ActionExecutor(context)
|
|
115
|
+
|
|
116
|
+
try:
|
|
117
|
+
content = file_path.read_text(encoding="utf-8")
|
|
118
|
+
except Exception as e:
|
|
119
|
+
logger.error("Could not read %s for header fix: %s", rel_path, e)
|
|
120
|
+
return
|
|
121
|
+
|
|
122
|
+
lines = content.splitlines(keepends=True)
|
|
123
|
+
new_lines = []
|
|
124
|
+
skip_next_blank = False
|
|
125
|
+
|
|
126
|
+
for line in lines:
|
|
127
|
+
stripped = line.strip()
|
|
128
|
+
# Skip existing header line
|
|
129
|
+
if stripped.startswith("# src/"):
|
|
130
|
+
skip_next_blank = True
|
|
131
|
+
continue
|
|
132
|
+
# Skip blank line immediately after removed header
|
|
133
|
+
if skip_next_blank and not stripped:
|
|
134
|
+
skip_next_blank = False
|
|
135
|
+
continue
|
|
136
|
+
skip_next_blank = False
|
|
137
|
+
new_lines.append(line)
|
|
138
|
+
|
|
139
|
+
# Reconstruct with the correct header
|
|
140
|
+
final_lines = [expected_header + "\n"]
|
|
141
|
+
if new_lines and new_lines[0].strip():
|
|
142
|
+
final_lines.append("\n")
|
|
143
|
+
final_lines.extend(new_lines)
|
|
144
|
+
|
|
145
|
+
final_code = "".join(final_lines)
|
|
146
|
+
|
|
147
|
+
# CONSTITUTIONAL GATEWAY: Mutation is audited and guarded
|
|
148
|
+
result = await executor.execute(
|
|
149
|
+
action_id="file.edit", write=write, file_path=rel_path, code=final_code
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
if result.ok:
|
|
153
|
+
status = "Fixed" if write else "Proposed (Dry Run)"
|
|
154
|
+
logger.info(" -> [%s] Header in %s", status, rel_path)
|
|
155
|
+
else:
|
|
156
|
+
logger.error(" -> [BLOCKED] %s: %s", rel_path, result.data.get("error"))
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# ID: 4828affd-f7da-4995-9493-7037211b4144
|
|
160
|
+
async def _run_header_fix_cycle(
|
|
161
|
+
context: CoreContext, dry_run: bool, all_py_files: list[str]
|
|
162
|
+
) -> dict[str, Any]:
|
|
163
|
+
"""
|
|
164
|
+
Enforce the src/**/*.py path-header invariant.
|
|
165
|
+
|
|
166
|
+
Invariant: line 1 MUST be exactly '# <repo-relative-path>' for each src/**/*.py file.
|
|
167
|
+
This exists to keep file metadata deterministic and machine-verifiable.
|
|
168
|
+
"""
|
|
169
|
+
logger.info("🔍 Scanning %d files for header compliance...", len(all_py_files))
|
|
170
|
+
|
|
171
|
+
executor = ActionExecutor(context)
|
|
172
|
+
write_mode = not dry_run
|
|
173
|
+
files_changed = 0
|
|
174
|
+
files_created = 0
|
|
175
|
+
changed_paths: list[str] = []
|
|
176
|
+
|
|
177
|
+
def _enforce_line1_path_header(
|
|
178
|
+
content: str, expected_header: str
|
|
179
|
+
) -> tuple[str, bool]:
|
|
180
|
+
"""
|
|
181
|
+
Return (new_content, did_change) enforcing the path-header invariant:
|
|
182
|
+
- Empty file -> insert header
|
|
183
|
+
- Line 1 == correct -> no change
|
|
184
|
+
- Line 1 is a # src/.. -> wrong path, replace line 1
|
|
185
|
+
- Anything else -> prepend header, leave file content intact
|
|
186
|
+
"""
|
|
187
|
+
if content == "":
|
|
188
|
+
return expected_header + "\n", True
|
|
189
|
+
|
|
190
|
+
lines = content.splitlines(keepends=True)
|
|
191
|
+
first_line_text = lines[0].rstrip("\r\n")
|
|
192
|
+
|
|
193
|
+
if first_line_text == expected_header:
|
|
194
|
+
return content, False
|
|
195
|
+
|
|
196
|
+
if first_line_text.startswith("# src/"):
|
|
197
|
+
# Wrong path header — replace only line 1
|
|
198
|
+
lines[0] = expected_header + "\n"
|
|
199
|
+
return "".join(lines), True
|
|
200
|
+
|
|
201
|
+
# Not a path header (could be # ID:, docstring, code, anything)
|
|
202
|
+
# Prepend and leave everything else intact
|
|
203
|
+
return expected_header + "\n" + content, True
|
|
204
|
+
|
|
205
|
+
for i, file_path_str in enumerate(all_py_files, 1):
|
|
206
|
+
if i % 50 == 0:
|
|
207
|
+
logger.debug("Header analysis progress: %d/%d", i, len(all_py_files))
|
|
208
|
+
|
|
209
|
+
file_path = context.git_service.repo_path / file_path_str
|
|
210
|
+
try:
|
|
211
|
+
original_content = file_path.read_text(encoding="utf-8")
|
|
212
|
+
expected_header = f"# {Path(file_path_str).as_posix()}"
|
|
213
|
+
corrected_code, changed = _enforce_line1_path_header(
|
|
214
|
+
original_content, expected_header
|
|
215
|
+
)
|
|
216
|
+
if not changed:
|
|
217
|
+
continue
|
|
218
|
+
|
|
219
|
+
result = await executor.execute(
|
|
220
|
+
action_id="file.edit",
|
|
221
|
+
write=write_mode,
|
|
222
|
+
file_path=file_path_str,
|
|
223
|
+
code=corrected_code,
|
|
224
|
+
)
|
|
225
|
+
if result.ok:
|
|
226
|
+
files_changed += 1
|
|
227
|
+
changed_paths.append(file_path_str)
|
|
228
|
+
if original_content == "":
|
|
229
|
+
files_created += 1
|
|
230
|
+
else:
|
|
231
|
+
logger.warning(" -> [BLOCKED] %s", file_path_str)
|
|
232
|
+
|
|
233
|
+
except Exception as e:
|
|
234
|
+
logger.warning("Could not process %s: %s", file_path_str, e)
|
|
235
|
+
|
|
236
|
+
if files_changed == 0:
|
|
237
|
+
logger.info("✅ All file headers are constitutionally compliant.")
|
|
238
|
+
else:
|
|
239
|
+
mode_label = "Fixed" if write_mode else "Proposed fixes for"
|
|
240
|
+
logger.info(
|
|
241
|
+
"🏁 Header fix cycle complete. %s %d file(s).", mode_label, files_changed
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
if write_mode:
|
|
245
|
+
logger.info("🔄 Rebuilding Knowledge Graph to reflect metadata changes...")
|
|
246
|
+
await executor.execute(action_id="sync.db", write=True)
|
|
247
|
+
logger.info("✅ Knowledge Graph successfully updated.")
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
"total_files_scanned": len(all_py_files),
|
|
251
|
+
"files_changed": files_changed,
|
|
252
|
+
"files_unchanged": len(all_py_files) - files_changed,
|
|
253
|
+
"files_created": files_created,
|
|
254
|
+
"changed_file_paths": changed_paths,
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
@atomic_action(
|
|
259
|
+
action_id="fix.headers",
|
|
260
|
+
intent="Ensure all Python files have constitutionally compliant headers",
|
|
261
|
+
impact=ActionImpact.WRITE_METADATA,
|
|
262
|
+
policies=["file_headers"],
|
|
263
|
+
category="fixers",
|
|
264
|
+
)
|
|
265
|
+
# ID: 936e32e6-18a3-4b7c-a0f2-06cc8ca654f7
|
|
266
|
+
async def fix_headers_internal(
|
|
267
|
+
context: CoreContext, write: bool = False, **kwargs
|
|
268
|
+
) -> ActionResult:
|
|
269
|
+
"""
|
|
270
|
+
Core orchestrator for fix.headers — moved from cli/commands/fix/code_style.py
|
|
271
|
+
under ADR-050. Walks src/, dispatches to _run_header_fix_cycle.
|
|
272
|
+
"""
|
|
273
|
+
start_time = time.time()
|
|
274
|
+
repo_root = context.git_service.repo_path
|
|
275
|
+
try:
|
|
276
|
+
src_dir = repo_root / "src"
|
|
277
|
+
all_py_files = [
|
|
278
|
+
p.relative_to(repo_root).as_posix() for p in src_dir.rglob("*.py")
|
|
279
|
+
]
|
|
280
|
+
summary = await _run_header_fix_cycle(
|
|
281
|
+
context, dry_run=not write, all_py_files=all_py_files
|
|
282
|
+
)
|
|
283
|
+
return ActionResult(
|
|
284
|
+
action_id="fix.headers",
|
|
285
|
+
ok=True,
|
|
286
|
+
data={
|
|
287
|
+
"total_files_scanned": summary["total_files_scanned"],
|
|
288
|
+
"files_changed": summary["files_changed"],
|
|
289
|
+
"files_unchanged": summary["files_unchanged"],
|
|
290
|
+
"files_created": summary["files_created"],
|
|
291
|
+
"changed_file_paths": summary["changed_file_paths"],
|
|
292
|
+
"files_scanned": summary["total_files_scanned"],
|
|
293
|
+
"violations_found": summary["files_changed"],
|
|
294
|
+
"fixed_count": summary["files_changed"] if write else 0,
|
|
295
|
+
"dry_run": not write,
|
|
296
|
+
"mode": "write" if write else "dry-run",
|
|
297
|
+
},
|
|
298
|
+
duration_sec=time.time() - start_time,
|
|
299
|
+
impact=ActionImpact.WRITE_METADATA if write else ActionImpact.READ_ONLY,
|
|
300
|
+
)
|
|
301
|
+
except Exception as e:
|
|
302
|
+
return ActionResult(
|
|
303
|
+
action_id="fix.headers",
|
|
304
|
+
ok=False,
|
|
305
|
+
data={"error": str(e), "error_type": type(e).__name__},
|
|
306
|
+
duration_sec=time.time() - start_time,
|
|
307
|
+
logs=[f"Exception during header fix: {e}"],
|
|
308
|
+
)
|