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,119 @@
|
|
|
1
|
+
# src/mind/coherence/checks/row3_citation.py
|
|
2
|
+
"""ROW3_CITATION — every normative paper § cites an enforcing rule or marks
|
|
3
|
+
itself aspirational.
|
|
4
|
+
|
|
5
|
+
Per ADR-073 D6 / topology §10.2 row 3. Operationalizes ADR-049 D2's existing
|
|
6
|
+
constitutional obligation that has been declared-but-unenforced.
|
|
7
|
+
|
|
8
|
+
Mechanism: split each paper into top-level §s, classify each via the §2.5
|
|
9
|
+
marker register from D10, emit when a normative section has no rule citation
|
|
10
|
+
and no aspirational/pending/deferred marker.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
import re
|
|
16
|
+
from pathlib import Path
|
|
17
|
+
|
|
18
|
+
from shared.governance.coherence_harvester import NormativeMarkerRegister
|
|
19
|
+
|
|
20
|
+
from .base import CoherenceCandidate
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
_HEADING = re.compile(r"^(#{1,3})\s+(.+?)\s*$", re.MULTILINE)
|
|
24
|
+
_RULE_CITE = re.compile(r"\.intent/[\w\-.]+/[\w\-./*{}]+\.[a-z]+", re.IGNORECASE)
|
|
25
|
+
_LEADING_NUMBERING = re.compile(r"^[\d.]+\s*")
|
|
26
|
+
|
|
27
|
+
# Headings that legitimately use normative vocabulary about the paper's own
|
|
28
|
+
# process (amendment mechanism, status lifecycle) rather than about runtime
|
|
29
|
+
# behavior. ADR-049 D2's citation obligation does not apply — there is no
|
|
30
|
+
# operational rule to cite. Definition sections are deliberately NOT in this
|
|
31
|
+
# set; they carry rule-enforceable claims about the paper's subject.
|
|
32
|
+
_BOILERPLATE_HEADINGS = frozenset(
|
|
33
|
+
{
|
|
34
|
+
"purpose",
|
|
35
|
+
"abstract",
|
|
36
|
+
"motivation",
|
|
37
|
+
"problem statement",
|
|
38
|
+
"the problem",
|
|
39
|
+
"alignment statement",
|
|
40
|
+
"conclusion",
|
|
41
|
+
"closing statement",
|
|
42
|
+
"summary",
|
|
43
|
+
"non-goals",
|
|
44
|
+
"relationship to other papers",
|
|
45
|
+
"amendment discipline",
|
|
46
|
+
"status: superseded",
|
|
47
|
+
"why it was superseded",
|
|
48
|
+
"constitutional identity",
|
|
49
|
+
"constitutional identity (historical)",
|
|
50
|
+
}
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ID: b70fb5d2-9de3-4575-b1b2-58f4c88cc147
|
|
55
|
+
class Row3CitationCheck:
|
|
56
|
+
"""Emit ROW3_CITATION for normative paper §s missing rule citation or aspirational marker."""
|
|
57
|
+
|
|
58
|
+
relation = "ROW3_CITATION"
|
|
59
|
+
|
|
60
|
+
# ID: 2cf281c7-a32b-4b91-ab6e-abe4ad406427
|
|
61
|
+
def __init__(self, repo_root: Path, register: NormativeMarkerRegister) -> None:
|
|
62
|
+
self._repo_root = Path(repo_root)
|
|
63
|
+
self._register = register
|
|
64
|
+
self._aspirational = re.compile(
|
|
65
|
+
"|".join(re.escape(m) for m in register.aspirational_markers),
|
|
66
|
+
re.IGNORECASE,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# ID: 8cbccb3a-6a50-4d88-82d6-e6b231434064
|
|
70
|
+
async def run(self) -> list[CoherenceCandidate]:
|
|
71
|
+
papers = self._repo_root / ".specs" / "papers"
|
|
72
|
+
if not papers.is_dir():
|
|
73
|
+
return []
|
|
74
|
+
candidates: list[CoherenceCandidate] = []
|
|
75
|
+
for path in sorted(papers.glob("*.md")):
|
|
76
|
+
content = path.read_text(encoding="utf-8", errors="replace")
|
|
77
|
+
rel = str(path.relative_to(self._repo_root))
|
|
78
|
+
for heading, section_text in _iter_sections(content):
|
|
79
|
+
normalized = _LEADING_NUMBERING.sub("", heading).strip().lower()
|
|
80
|
+
if normalized in _BOILERPLATE_HEADINGS:
|
|
81
|
+
continue
|
|
82
|
+
if not self._register.marker_pattern.search(section_text):
|
|
83
|
+
continue
|
|
84
|
+
if _RULE_CITE.search(section_text):
|
|
85
|
+
continue
|
|
86
|
+
if self._register.aspirational_markers and self._aspirational.search(
|
|
87
|
+
section_text
|
|
88
|
+
):
|
|
89
|
+
continue
|
|
90
|
+
candidates.append(
|
|
91
|
+
CoherenceCandidate(
|
|
92
|
+
relation=self.relation,
|
|
93
|
+
documents=[rel],
|
|
94
|
+
claim=(
|
|
95
|
+
f"Paper § '{heading}' contains normative markers but "
|
|
96
|
+
"cites no enforcing rule and carries no aspirational/pending marker."
|
|
97
|
+
),
|
|
98
|
+
rationale=(
|
|
99
|
+
"ADR-049 D2 (operationalized by topology row 3) requires "
|
|
100
|
+
"every normative paper § to either name a `.intent/rules/...` "
|
|
101
|
+
"artifact that enforces the claim, or explicitly mark "
|
|
102
|
+
"itself aspirational/pending/deferred. Neither was detected in "
|
|
103
|
+
"this section. Either backfill the rule citation or add "
|
|
104
|
+
"an aspirational marker so the claim's status is honest."
|
|
105
|
+
),
|
|
106
|
+
)
|
|
107
|
+
)
|
|
108
|
+
return candidates
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def _iter_sections(content: str):
|
|
112
|
+
"""Yield (heading_text, section_body) for each top-level heading."""
|
|
113
|
+
matches = list(_HEADING.finditer(content))
|
|
114
|
+
if not matches:
|
|
115
|
+
return
|
|
116
|
+
for i, m in enumerate(matches):
|
|
117
|
+
start = m.end()
|
|
118
|
+
end = matches[i + 1].start() if i + 1 < len(matches) else len(content)
|
|
119
|
+
yield m.group(2).strip(), content[start:end]
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# src/mind/coherence/checks/row4_naming.py
|
|
2
|
+
"""ROW4_NAMING — every `.intent/` artifact is named in at least one accepted
|
|
3
|
+
ADR's D-text, or predates topology paper acceptance (grandfathered).
|
|
4
|
+
|
|
5
|
+
Per ADR-073 D6 / topology §10.2 row 4 + §11.1 backfill-on-touch posture.
|
|
6
|
+
|
|
7
|
+
Grandfather signal is git-history first-appearance date
|
|
8
|
+
(`git log --diff-filter=A`) compared against the topology paper's acceptance
|
|
9
|
+
date (2026-05-26). Filesystem mtime is not used — it does not survive clone
|
|
10
|
+
or touch.
|
|
11
|
+
|
|
12
|
+
Mechanism: structural grep over ADR D-text for the artifact's path. No LLM.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import re
|
|
18
|
+
import subprocess
|
|
19
|
+
from datetime import date
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
from .base import CoherenceCandidate
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
_TOPOLOGY_ACCEPTANCE = date(2026, 5, 26)
|
|
26
|
+
_STATUS_ACCEPTED = re.compile(
|
|
27
|
+
r"^\*\*Status:\*\*\s*Accepted", re.IGNORECASE | re.MULTILINE
|
|
28
|
+
)
|
|
29
|
+
_META_PARTS = {"META"}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# ID: a7968f92-b6b9-4d0d-bb5d-6e6a7a6a4d43
|
|
33
|
+
class Row4NamingCheck:
|
|
34
|
+
"""Emit ROW4_NAMING for post-topology artifacts not named in any accepted ADR."""
|
|
35
|
+
|
|
36
|
+
relation = "ROW4_NAMING"
|
|
37
|
+
|
|
38
|
+
# ID: 99603b79-9830-4568-98bc-c59d9f5eb676
|
|
39
|
+
def __init__(self, repo_root: Path) -> None:
|
|
40
|
+
self._repo_root = Path(repo_root)
|
|
41
|
+
|
|
42
|
+
# ID: 809cc4b0-5fd8-47f0-a29d-930848b6e279
|
|
43
|
+
async def run(self) -> list[CoherenceCandidate]:
|
|
44
|
+
intent = self._repo_root / ".intent"
|
|
45
|
+
if not intent.is_dir():
|
|
46
|
+
return []
|
|
47
|
+
accepted_adr_texts = self._collect_accepted_adr_text()
|
|
48
|
+
candidates: list[CoherenceCandidate] = []
|
|
49
|
+
for path in _iter_intent_artifacts(intent):
|
|
50
|
+
rel = str(path.relative_to(self._repo_root))
|
|
51
|
+
if any(rel in text for text in accepted_adr_texts):
|
|
52
|
+
continue
|
|
53
|
+
first_seen = self._git_first_seen(rel)
|
|
54
|
+
if first_seen is not None and first_seen < _TOPOLOGY_ACCEPTANCE:
|
|
55
|
+
continue
|
|
56
|
+
candidates.append(
|
|
57
|
+
CoherenceCandidate(
|
|
58
|
+
relation=self.relation,
|
|
59
|
+
documents=[rel],
|
|
60
|
+
claim=(
|
|
61
|
+
f"`.intent/` artifact `{rel}` is not named in any accepted "
|
|
62
|
+
"ADR's D-text and post-dates topology paper acceptance "
|
|
63
|
+
"(2026-05-26)."
|
|
64
|
+
),
|
|
65
|
+
rationale=(
|
|
66
|
+
"Topology paper §3 row 4 strict requires every governance "
|
|
67
|
+
"change in `.intent/` to be named in its governing ADR's "
|
|
68
|
+
"D-text at acceptance. Grandfather exemption applies only "
|
|
69
|
+
"to artifacts whose git first-appearance precedes topology "
|
|
70
|
+
"acceptance. Either author the governing ADR (or amend an "
|
|
71
|
+
"existing one) to reference this path, or — if the artifact "
|
|
72
|
+
"is in fact pre-acceptance — verify the git history claim."
|
|
73
|
+
),
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
return candidates
|
|
77
|
+
|
|
78
|
+
def _collect_accepted_adr_text(self) -> list[str]:
|
|
79
|
+
decisions = self._repo_root / ".specs" / "decisions"
|
|
80
|
+
if not decisions.is_dir():
|
|
81
|
+
return []
|
|
82
|
+
texts: list[str] = []
|
|
83
|
+
for adr in sorted(decisions.glob("ADR-*.md")):
|
|
84
|
+
content = adr.read_text(encoding="utf-8", errors="replace")
|
|
85
|
+
if _STATUS_ACCEPTED.search(content):
|
|
86
|
+
texts.append(content)
|
|
87
|
+
return texts
|
|
88
|
+
|
|
89
|
+
def _git_first_seen(self, rel_path: str) -> date | None:
|
|
90
|
+
try:
|
|
91
|
+
result = subprocess.run(
|
|
92
|
+
[
|
|
93
|
+
"git",
|
|
94
|
+
"-C",
|
|
95
|
+
str(self._repo_root),
|
|
96
|
+
"log",
|
|
97
|
+
"--diff-filter=A",
|
|
98
|
+
"--format=%aI",
|
|
99
|
+
"--",
|
|
100
|
+
rel_path,
|
|
101
|
+
],
|
|
102
|
+
capture_output=True,
|
|
103
|
+
text=True,
|
|
104
|
+
timeout=15,
|
|
105
|
+
check=False,
|
|
106
|
+
)
|
|
107
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
108
|
+
return None
|
|
109
|
+
if result.returncode != 0 or not result.stdout.strip():
|
|
110
|
+
return None
|
|
111
|
+
last_line = result.stdout.strip().splitlines()[-1]
|
|
112
|
+
try:
|
|
113
|
+
return date.fromisoformat(last_line[:10])
|
|
114
|
+
except ValueError:
|
|
115
|
+
return None
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def _iter_intent_artifacts(intent_root: Path):
|
|
119
|
+
for path in sorted(intent_root.rglob("*")):
|
|
120
|
+
if not path.is_file():
|
|
121
|
+
continue
|
|
122
|
+
if _META_PARTS.intersection(path.parts):
|
|
123
|
+
continue
|
|
124
|
+
if path.suffix.lower() not in {".json", ".yaml", ".yml"}:
|
|
125
|
+
continue
|
|
126
|
+
yield path
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# src/mind/coherence/checks/sameconcern.py
|
|
2
|
+
"""SAMECONCERN — §6.1 same-concern contradiction via vector kNN + LLM judge.
|
|
3
|
+
|
|
4
|
+
Per ADR-073 D5 tiered cosine policy. Refuses if governance_claims is not
|
|
5
|
+
seeded (per D4 governor-CLI bootstrap posture).
|
|
6
|
+
|
|
7
|
+
Mechanism:
|
|
8
|
+
1. For each claim in the corpus, embed and kNN-search governance_claims.
|
|
9
|
+
2. Tier each hit: high-confidence (≥0.78), ambiguous (0.74-0.78), drop (<0.74).
|
|
10
|
+
3. Forward both tiers to the LLM judge (ambiguous tier gets a different prompt).
|
|
11
|
+
4. Dedupe pairs across the bi-directional iteration.
|
|
12
|
+
|
|
13
|
+
Cosine thresholds are tunable per D5 telemetry feedback; defaults live here.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import TYPE_CHECKING, Any
|
|
20
|
+
|
|
21
|
+
from shared.logger import getLogger
|
|
22
|
+
|
|
23
|
+
from ..llm_judge import judge_contradiction_pair
|
|
24
|
+
from .base import CoherenceCandidate
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
if TYPE_CHECKING:
|
|
28
|
+
from body.services.governance_claims_service import GovernanceClaimsService
|
|
29
|
+
from shared.governance.coherence_harvester import NormativeMarkerRegister
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
logger = getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
_HIGH_CONFIDENCE_COSINE = 0.78
|
|
36
|
+
_AMBIGUOUS_COSINE = 0.74
|
|
37
|
+
_KNN_LIMIT = 10
|
|
38
|
+
_DEFAULT_MAX_QUERIES = 200
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# ID: 5be96f7c-4c2b-4946-819a-b118b0535e19
|
|
42
|
+
class SameConcernCheck:
|
|
43
|
+
"""Emit SAMECONCERN candidates for contradicting pairs flagged by kNN + LLM."""
|
|
44
|
+
|
|
45
|
+
relation = "SAMECONCERN"
|
|
46
|
+
|
|
47
|
+
# ID: b34dfca3-3cb3-49e6-97c1-cd65bfdeb228
|
|
48
|
+
def __init__(
|
|
49
|
+
self,
|
|
50
|
+
repo_root: Path,
|
|
51
|
+
register: NormativeMarkerRegister,
|
|
52
|
+
claims_service: GovernanceClaimsService,
|
|
53
|
+
cognitive_service: Any,
|
|
54
|
+
max_queries: int | None = _DEFAULT_MAX_QUERIES,
|
|
55
|
+
) -> None:
|
|
56
|
+
self._repo_root = Path(repo_root)
|
|
57
|
+
self._register = register
|
|
58
|
+
self._claims_service = claims_service
|
|
59
|
+
self._cognitive_service = cognitive_service
|
|
60
|
+
self._max_queries = max_queries
|
|
61
|
+
|
|
62
|
+
# ID: 43f12752-e72e-43e4-9d87-027d762e4e9e
|
|
63
|
+
async def run(self) -> list[CoherenceCandidate]:
|
|
64
|
+
from shared.governance.coherence_harvester import GovernanceClaimHarvester
|
|
65
|
+
from shared.infrastructure.vector.cognitive_adapter import (
|
|
66
|
+
CognitiveEmbedderAdapter,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
if not await self._claims_service.is_seeded():
|
|
70
|
+
logger.info(
|
|
71
|
+
"SAMECONCERN: governance_claims collection not seeded; "
|
|
72
|
+
"skipping (run `core-admin coherence seed bootstrap` per D4)"
|
|
73
|
+
)
|
|
74
|
+
return []
|
|
75
|
+
|
|
76
|
+
harvester = GovernanceClaimHarvester(self._repo_root, self._register)
|
|
77
|
+
claims = list(harvester.harvest())
|
|
78
|
+
if self._max_queries is not None and len(claims) > self._max_queries:
|
|
79
|
+
import random
|
|
80
|
+
|
|
81
|
+
random.seed(42)
|
|
82
|
+
claims = random.sample(claims, self._max_queries)
|
|
83
|
+
|
|
84
|
+
embedder = CognitiveEmbedderAdapter(self._cognitive_service)
|
|
85
|
+
seen: set[frozenset[tuple[str, str]]] = set()
|
|
86
|
+
candidates: list[CoherenceCandidate] = []
|
|
87
|
+
|
|
88
|
+
for claim in claims:
|
|
89
|
+
try:
|
|
90
|
+
vector = await embedder.get_embedding(claim.text)
|
|
91
|
+
except Exception as exc:
|
|
92
|
+
logger.warning("SAMECONCERN: embed failed for query claim: %s", exc)
|
|
93
|
+
continue
|
|
94
|
+
|
|
95
|
+
hits = await self._claims_service.search(
|
|
96
|
+
query_vector=vector,
|
|
97
|
+
limit=_KNN_LIMIT,
|
|
98
|
+
score_threshold=_AMBIGUOUS_COSINE,
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
for hit in hits:
|
|
102
|
+
if (
|
|
103
|
+
hit.source_path == claim.source_path
|
|
104
|
+
and hit.content_sha == claim.content_sha
|
|
105
|
+
):
|
|
106
|
+
continue
|
|
107
|
+
tier = (
|
|
108
|
+
"high_confidence"
|
|
109
|
+
if hit.cosine >= _HIGH_CONFIDENCE_COSINE
|
|
110
|
+
else "ambiguous"
|
|
111
|
+
)
|
|
112
|
+
pair_key: frozenset[tuple[str, str]] = frozenset(
|
|
113
|
+
{
|
|
114
|
+
(claim.source_path, claim.content_sha),
|
|
115
|
+
(hit.source_path, hit.content_sha),
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
if pair_key in seen:
|
|
119
|
+
continue
|
|
120
|
+
seen.add(pair_key)
|
|
121
|
+
|
|
122
|
+
verdict = await judge_contradiction_pair(
|
|
123
|
+
cognitive_service=self._cognitive_service,
|
|
124
|
+
text_a=claim.text,
|
|
125
|
+
source_a=claim.source_path,
|
|
126
|
+
text_b=hit.text,
|
|
127
|
+
source_b=hit.source_path,
|
|
128
|
+
tier=tier,
|
|
129
|
+
relation=self.relation,
|
|
130
|
+
category_a=claim.category,
|
|
131
|
+
category_b=hit.category,
|
|
132
|
+
)
|
|
133
|
+
if verdict is not None:
|
|
134
|
+
candidates.append(verdict)
|
|
135
|
+
|
|
136
|
+
return candidates
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
# src/mind/coherence/checks/specgap.py
|
|
2
|
+
"""SPECGAP — upstream normative claim with no downstream operationalizing artifact.
|
|
3
|
+
|
|
4
|
+
Per ADR-073 D7 + D11. Detects gaps where Northstar (or paper) declares a
|
|
5
|
+
required behavior that the corresponding phase YAML's failure_mode does not
|
|
6
|
+
address. Vector kNN cannot detect this class — the conflict is absence, not
|
|
7
|
+
opposition.
|
|
8
|
+
|
|
9
|
+
v1 detection rule per D7:
|
|
10
|
+
For each pair (N, P) where N is a Northstar/paper paragraph and P is a
|
|
11
|
+
workflow phase, emit when ALL of:
|
|
12
|
+
1. N qualifies as upstream-normative
|
|
13
|
+
2. N is operationally linked to P (D11 bridge or textual mention)
|
|
14
|
+
3. N contains a required-behavior action verb from D10
|
|
15
|
+
4. The phase YAML exists with a non-empty failure_mode
|
|
16
|
+
5. No failure_mode value overlaps the action-verb signal
|
|
17
|
+
|
|
18
|
+
No LLM. No vectors.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import re
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
from typing import TYPE_CHECKING
|
|
26
|
+
|
|
27
|
+
import yaml
|
|
28
|
+
|
|
29
|
+
from .base import CoherenceCandidate
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
if TYPE_CHECKING:
|
|
33
|
+
from shared.governance.coherence_harvester import NormativeMarkerRegister
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
_UR_HEADING = re.compile(r"^###\s+(UR-\d{2}):\s*(.+?)\s*$", re.MULTILINE)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# ID: 8a9fd6fc-ce33-4b47-ba55-fe24b5d37bc5
|
|
40
|
+
def _phases() -> tuple[str, ...]:
|
|
41
|
+
"""Canonical `phase` membership from .intent/META/enums.json.
|
|
42
|
+
|
|
43
|
+
Sourced from the canonical enum store rather than inlined here so
|
|
44
|
+
SpecGap's iteration order tracks the constitutional vocabulary
|
|
45
|
+
without drift (closed-enum discipline, issue #460). Lazy because
|
|
46
|
+
coherence checks are constructed before IntentRepository may be
|
|
47
|
+
fully warm during cold-start scans.
|
|
48
|
+
"""
|
|
49
|
+
from shared.infrastructure.intent.canonical_enums import get_enum_members
|
|
50
|
+
|
|
51
|
+
return tuple(sorted(get_enum_members("phase")))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
# ID: 462e86d4-ce44-4239-8fb0-4efaf0a5278d
|
|
55
|
+
class SpecGapCheck:
|
|
56
|
+
"""Emit SPECGAP when upstream required behavior has no downstream operationalization."""
|
|
57
|
+
|
|
58
|
+
relation = "SPECGAP"
|
|
59
|
+
|
|
60
|
+
# ID: 9fb8fe6c-ae8c-4be5-9022-fc6c4ac0c362
|
|
61
|
+
def __init__(self, repo_root: Path, register: NormativeMarkerRegister) -> None:
|
|
62
|
+
self._repo_root = Path(repo_root)
|
|
63
|
+
self._register = register
|
|
64
|
+
self._action_verb_pattern = re.compile(
|
|
65
|
+
"|".join(rf"\b{re.escape(v)}\w*\b" for v in register.action_verbs),
|
|
66
|
+
re.IGNORECASE,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# ID: 43197388-342a-495c-844f-2889159e9994
|
|
70
|
+
async def run(self) -> list[CoherenceCandidate]:
|
|
71
|
+
phase_modes = self._load_phase_failure_modes()
|
|
72
|
+
responsibility = self._load_phase_responsibility()
|
|
73
|
+
ur_paragraphs = self._extract_ur_paragraphs()
|
|
74
|
+
|
|
75
|
+
candidates: list[CoherenceCandidate] = []
|
|
76
|
+
for ur_id, ur_rel, paragraph in ur_paragraphs:
|
|
77
|
+
action_verbs = self._action_verbs_in(paragraph)
|
|
78
|
+
if not action_verbs:
|
|
79
|
+
continue
|
|
80
|
+
for phase in _phases():
|
|
81
|
+
if not self._operationally_linked(
|
|
82
|
+
ur_id, paragraph, phase, responsibility
|
|
83
|
+
):
|
|
84
|
+
continue
|
|
85
|
+
failure_modes = phase_modes.get(phase) or {}
|
|
86
|
+
if not failure_modes:
|
|
87
|
+
continue
|
|
88
|
+
if self._verbs_covered_by(failure_modes):
|
|
89
|
+
continue
|
|
90
|
+
phase_rel = f".intent/phases/{phase}.yaml"
|
|
91
|
+
rendered = ", ".join(
|
|
92
|
+
f"{cls}:{strat}" for cls, strat in sorted(failure_modes.items())
|
|
93
|
+
)
|
|
94
|
+
candidates.append(
|
|
95
|
+
CoherenceCandidate(
|
|
96
|
+
relation=self.relation,
|
|
97
|
+
documents=[ur_rel, phase_rel],
|
|
98
|
+
claim=(
|
|
99
|
+
f"Northstar §{ur_id} declares required behavior "
|
|
100
|
+
f"({', '.join(sorted(action_verbs))}) for phase "
|
|
101
|
+
f"`{phase}`, but `{phase}.yaml`'s failure_modes "
|
|
102
|
+
f"({rendered}) do not address it."
|
|
103
|
+
),
|
|
104
|
+
rationale=(
|
|
105
|
+
f"Topology paper §6.1 contradiction invariant via "
|
|
106
|
+
f"the D11 phase-responsibility bridge identifies "
|
|
107
|
+
f"`{phase}` as responsible for {ur_id}. The Northstar "
|
|
108
|
+
f"paragraph asserts the system should "
|
|
109
|
+
f"{', '.join(sorted(action_verbs))} under some condition, "
|
|
110
|
+
f"but the phase declares failure_modes "
|
|
111
|
+
f"({rendered}) — neither the failure-class names "
|
|
112
|
+
f"nor the response-strategy values match a halt-class "
|
|
113
|
+
"action verb. Either extend the phase's failure_modes "
|
|
114
|
+
"to cover the upstream required behavior (ADR-074 D2 "
|
|
115
|
+
"map shape), or — if the upstream claim is no longer "
|
|
116
|
+
"authoritative — amend Northstar."
|
|
117
|
+
),
|
|
118
|
+
)
|
|
119
|
+
)
|
|
120
|
+
return candidates
|
|
121
|
+
|
|
122
|
+
def _load_phase_failure_modes(self) -> dict[str, dict[str, str]]:
|
|
123
|
+
"""Return per-phase failure-class → response-strategy map (ADR-074 D2).
|
|
124
|
+
|
|
125
|
+
Reads `.intent/phases/<phase>.yaml` and returns the `failure_modes:`
|
|
126
|
+
mapping. Returns an empty dict for the phase if the file is missing
|
|
127
|
+
or declares no `failure_modes`. Legacy scalar `failure_mode:` keys
|
|
128
|
+
are intentionally not read — ADR-074 D12 retires the singular field.
|
|
129
|
+
"""
|
|
130
|
+
result: dict[str, dict[str, str]] = {}
|
|
131
|
+
for phase in _phases():
|
|
132
|
+
path = self._repo_root / ".intent" / "phases" / f"{phase}.yaml"
|
|
133
|
+
if not path.exists():
|
|
134
|
+
result[phase] = {}
|
|
135
|
+
continue
|
|
136
|
+
data = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
|
|
137
|
+
modes = data.get("failure_modes")
|
|
138
|
+
if isinstance(modes, dict):
|
|
139
|
+
result[phase] = {str(k): str(v) for k, v in modes.items()}
|
|
140
|
+
else:
|
|
141
|
+
result[phase] = {}
|
|
142
|
+
return result
|
|
143
|
+
|
|
144
|
+
def _load_phase_responsibility(self) -> dict[str, dict]:
|
|
145
|
+
path = (
|
|
146
|
+
self._repo_root
|
|
147
|
+
/ ".intent"
|
|
148
|
+
/ "enforcement"
|
|
149
|
+
/ "config"
|
|
150
|
+
/ "phase_responsibility.yaml"
|
|
151
|
+
)
|
|
152
|
+
if not path.exists():
|
|
153
|
+
return {}
|
|
154
|
+
data = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
|
|
155
|
+
return data.get("phases", {}) or {}
|
|
156
|
+
|
|
157
|
+
def _extract_ur_paragraphs(self) -> list[tuple[str, str, str]]:
|
|
158
|
+
path = self._repo_root / ".specs" / "northstar" / "CORE-USER-REQUIREMENTS.md"
|
|
159
|
+
if not path.exists():
|
|
160
|
+
return []
|
|
161
|
+
content = path.read_text(encoding="utf-8")
|
|
162
|
+
rel = str(path.relative_to(self._repo_root))
|
|
163
|
+
matches = list(_UR_HEADING.finditer(content))
|
|
164
|
+
result: list[tuple[str, str, str]] = []
|
|
165
|
+
for i, m in enumerate(matches):
|
|
166
|
+
ur_id = m.group(1)
|
|
167
|
+
start = m.end()
|
|
168
|
+
end = matches[i + 1].start() if i + 1 < len(matches) else len(content)
|
|
169
|
+
section = content[start:end]
|
|
170
|
+
for paragraph in _iter_paragraphs(section):
|
|
171
|
+
result.append((ur_id, rel, paragraph))
|
|
172
|
+
return result
|
|
173
|
+
|
|
174
|
+
# ID: b891e1a5-db39-4243-a3e9-79f5425e8bdc
|
|
175
|
+
def _operationally_linked(
|
|
176
|
+
self,
|
|
177
|
+
ur_id: str,
|
|
178
|
+
paragraph: str,
|
|
179
|
+
phase: str,
|
|
180
|
+
responsibility: dict[str, dict],
|
|
181
|
+
) -> bool:
|
|
182
|
+
"""D7 condition 2: phase mentioned in text OR linked via D11 mapping."""
|
|
183
|
+
phase_entry = responsibility.get(phase) or {}
|
|
184
|
+
if phase_entry.get("cross_cutting"):
|
|
185
|
+
return False
|
|
186
|
+
urs = phase_entry.get("operationalizes_urs") or []
|
|
187
|
+
if ur_id in urs:
|
|
188
|
+
return True
|
|
189
|
+
return _whole_word(paragraph, phase) or _whole_word(paragraph, phase + "s")
|
|
190
|
+
|
|
191
|
+
def _action_verbs_in(self, text: str) -> set[str]:
|
|
192
|
+
verbs: set[str] = set()
|
|
193
|
+
for m in self._action_verb_pattern.finditer(text):
|
|
194
|
+
verbs.add(m.group(0).lower())
|
|
195
|
+
return verbs
|
|
196
|
+
|
|
197
|
+
# ID: 4b4328d6-4874-4d40-87b8-123c510da8ce
|
|
198
|
+
def _verbs_covered_by(self, failure_modes: dict[str, str]) -> bool:
|
|
199
|
+
"""Covered iff any failure-class key OR response-strategy value declares an action verb.
|
|
200
|
+
|
|
201
|
+
Per ADR-074 D9: a phase addresses an upstream halt-class signal when
|
|
202
|
+
either the failure-class name (e.g., `contradiction`) or the
|
|
203
|
+
response-strategy value (e.g., `block`) string-matches a verb from
|
|
204
|
+
the normative-marker register. Map keys and values are both checked
|
|
205
|
+
because either signal independently operationalizes the upstream
|
|
206
|
+
required behavior.
|
|
207
|
+
"""
|
|
208
|
+
for key, value in failure_modes.items():
|
|
209
|
+
if self._action_verb_pattern.search(key):
|
|
210
|
+
return True
|
|
211
|
+
if self._action_verb_pattern.search(value):
|
|
212
|
+
return True
|
|
213
|
+
return False
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _iter_paragraphs(section: str):
|
|
217
|
+
para: list[str] = []
|
|
218
|
+
for line in section.split("\n"):
|
|
219
|
+
if line.strip():
|
|
220
|
+
para.append(line)
|
|
221
|
+
elif para:
|
|
222
|
+
text = "\n".join(para).strip()
|
|
223
|
+
if text:
|
|
224
|
+
yield text
|
|
225
|
+
para = []
|
|
226
|
+
if para:
|
|
227
|
+
text = "\n".join(para).strip()
|
|
228
|
+
if text:
|
|
229
|
+
yield text
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _whole_word(content: str, token: str) -> bool:
|
|
233
|
+
return re.search(rf"\b{re.escape(token)}\b", content, re.IGNORECASE) is not None
|