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.
Files changed (962) hide show
  1. api/__init__.py +4 -0
  2. api/cli/__init__.py +10 -0
  3. api/cli/audit_client.py +92 -0
  4. api/cli/census_client.py +77 -0
  5. api/cli/client.py +508 -0
  6. api/cli/coverage_client.py +121 -0
  7. api/cli/daemon_client.py +42 -0
  8. api/cli/fix_client.py +101 -0
  9. api/cli/inspect_client.py +143 -0
  10. api/cli/integration_client.py +42 -0
  11. api/cli/integrity_client.py +45 -0
  12. api/cli/proposals_client.py +101 -0
  13. api/cli/quality_client.py +83 -0
  14. api/cli/refactor_client.py +82 -0
  15. api/cli/sync_client.py +106 -0
  16. api/dependencies.py +37 -0
  17. api/errors.py +74 -0
  18. api/main.py +88 -0
  19. api/v1/__init__.py +4 -0
  20. api/v1/audit_routes.py +302 -0
  21. api/v1/census_routes.py +207 -0
  22. api/v1/coverage_routes.py +352 -0
  23. api/v1/daemon_routes.py +86 -0
  24. api/v1/development_routes.py +70 -0
  25. api/v1/fix_routes.py +428 -0
  26. api/v1/inspect_routes.py +220 -0
  27. api/v1/integration_routes.py +56 -0
  28. api/v1/integrity_routes.py +72 -0
  29. api/v1/knowledge_routes.py +36 -0
  30. api/v1/lint_routes.py +40 -0
  31. api/v1/proposals_routes.py +267 -0
  32. api/v1/quality_routes.py +272 -0
  33. api/v1/refactor_routes.py +225 -0
  34. api/v1/sync_routes.py +261 -0
  35. body/__init__.py +4 -0
  36. body/analyzers/__init__.py +25 -0
  37. body/analyzers/base_analyzer.py +28 -0
  38. body/analyzers/constitutional_path_analyzer.py +63 -0
  39. body/analyzers/file_analyzer.py +211 -0
  40. body/analyzers/knowledge_graph_analyzer.py +86 -0
  41. body/analyzers/prompt_analyzer.py +155 -0
  42. body/analyzers/symbol_extractor.py +280 -0
  43. body/atomic/__init__.py +74 -0
  44. body/atomic/build_tests_action.py +354 -0
  45. body/atomic/check_actions.py +142 -0
  46. body/atomic/crate_ops.py +59 -0
  47. body/atomic/executor.py +470 -0
  48. body/atomic/file_ops.py +153 -0
  49. body/atomic/fix_actions.py +1142 -0
  50. body/atomic/import_resolver.py +200 -0
  51. body/atomic/metadata_ops.py +161 -0
  52. body/atomic/modularity_fix.py +839 -0
  53. body/atomic/modularity_splitter.py +521 -0
  54. body/atomic/proposal_lifecycle_actions.py +171 -0
  55. body/atomic/registry.py +326 -0
  56. body/atomic/remediate_cognitive_role.py +104 -0
  57. body/atomic/sandbox_lifecycle.py +252 -0
  58. body/atomic/split_plan.py +155 -0
  59. body/atomic/sync_actions/__init__.py +22 -0
  60. body/atomic/sync_actions/chunking_helpers.py +218 -0
  61. body/atomic/sync_actions/sync_actions.py +431 -0
  62. body/atomic/test_actions.py +47 -0
  63. body/autonomy/__init__.py +16 -0
  64. body/autonomy/audit_analyzer.py +343 -0
  65. body/autonomy/micro_proposal_executor.py +316 -0
  66. body/crate_processing/canary_executor.py +144 -0
  67. body/evaluators/__init__.py +27 -0
  68. body/evaluators/atomic_actions_evaluator.py +162 -0
  69. body/evaluators/atomic_actions_format.py +45 -0
  70. body/evaluators/atomic_actions_rules.py +278 -0
  71. body/evaluators/base_evaluator.py +67 -0
  72. body/evaluators/clarity_evaluator.py +83 -0
  73. body/evaluators/constitutional_evaluator.py +227 -0
  74. body/evaluators/failure_evaluator.py +136 -0
  75. body/evaluators/performance_evaluator.py +341 -0
  76. body/evaluators/security_evaluator.py +393 -0
  77. body/flows/__init__.py +33 -0
  78. body/flows/executor.py +275 -0
  79. body/flows/registry.py +272 -0
  80. body/flows/result.py +113 -0
  81. body/governance/__init__.py +29 -0
  82. body/governance/body_contracts_service.py +317 -0
  83. body/governance/code_validator.py +118 -0
  84. body/governance/engine_dispatcher.py +128 -0
  85. body/governance/intent_guard.py +592 -0
  86. body/governance/intent_pattern_validators.py +197 -0
  87. body/governance/key_management_service.py +100 -0
  88. body/governance/path_validator.py +187 -0
  89. body/governance/remediation_service.py +263 -0
  90. body/governance/runtime_validator.py +184 -0
  91. body/infrastructure/bootstrap.py +135 -0
  92. body/infrastructure/lifespan.py +85 -0
  93. body/infrastructure/repositories/__init__.py +1 -0
  94. body/infrastructure/repositories/decision_trace_repository.py +210 -0
  95. body/infrastructure/repositories/refusal_repository.py +294 -0
  96. body/introspection/__init__.py +4 -0
  97. body/introspection/capability_discovery_service.py +107 -0
  98. body/introspection/discovery/from_kgb.py +33 -0
  99. body/introspection/discovery/from_source_scan.py +40 -0
  100. body/introspection/discovery/loader.py +62 -0
  101. body/introspection/discovery/registry.py +22 -0
  102. body/introspection/discovery/semantics.py +21 -0
  103. body/introspection/discovery/sync.py +47 -0
  104. body/introspection/drift_detector.py +81 -0
  105. body/introspection/drift_service.py +48 -0
  106. body/introspection/export_vectors.py +133 -0
  107. body/introspection/generate_capability_docs.py +130 -0
  108. body/introspection/generate_correction_map.py +98 -0
  109. body/introspection/graph_analysis_service.py +66 -0
  110. body/introspection/knowledge_graph_service.py +170 -0
  111. body/introspection/semantic_clusterer.py +128 -0
  112. body/introspection/symbol_index_builder.py +244 -0
  113. body/introspection/sync/engine.py +92 -0
  114. body/introspection/sync/scanner.py +56 -0
  115. body/introspection/sync/visitor.py +83 -0
  116. body/introspection/sync_service.py +62 -0
  117. body/invokers/__init__.py +4 -0
  118. body/invokers/capability_invoker.py +4 -0
  119. body/maintenance/command_sync_service.py +73 -0
  120. body/maintenance/dotenv_sync_service.py +99 -0
  121. body/maintenance/idempotency_harness.py +70 -0
  122. body/maintenance/maintenance_service.py +123 -0
  123. body/maintenance/memory_cleanup_service.py +131 -0
  124. body/maintenance/refactor_settings_access.py +274 -0
  125. body/maintenance/scripts/__init__.py +5 -0
  126. body/maintenance/scripts/context_export.py +278 -0
  127. body/maintenance/scripts/vector_verify.py +73 -0
  128. body/maintenance/sync_vectors.py +338 -0
  129. body/models/__init__.py +4 -0
  130. body/project_lifecycle/__init__.py +4 -0
  131. body/project_lifecycle/bootstrap_service.py +157 -0
  132. body/project_lifecycle/definition_service.py +264 -0
  133. body/project_lifecycle/integration_service.py +113 -0
  134. body/project_lifecycle/scaffolding_service.py +187 -0
  135. body/quality/coverage_analyzer.py +177 -0
  136. body/repositories/__init__.py +4 -0
  137. body/self_healing/atomic_actions_fixer.py +113 -0
  138. body/self_healing/body_ui_fixer.py +193 -0
  139. body/self_healing/capability_parser.py +65 -0
  140. body/self_healing/code_style_service.py +51 -0
  141. body/self_healing/complexity_filter.py +70 -0
  142. body/self_healing/docstring_service.py +345 -0
  143. body/self_healing/duplicate_id_service.py +407 -0
  144. body/self_healing/duplicates_service.py +165 -0
  145. body/self_healing/handlers/__init__.py +1 -0
  146. body/self_healing/handlers/id_assignment_handler.py +201 -0
  147. body/self_healing/handlers/import_sorting_handler.py +181 -0
  148. body/self_healing/header_service.py +308 -0
  149. body/self_healing/id_tagging_service.py +227 -0
  150. body/self_healing/knowledge_consolidation_service.py +80 -0
  151. body/self_healing/logging_service.py +292 -0
  152. body/self_healing/owner_tagging_service.py +5 -0
  153. body/self_healing/placeholder_fixer_service.py +27 -0
  154. body/self_healing/prune_private_capabilities.py +144 -0
  155. body/self_healing/purge_legacy_tags_service.py +146 -0
  156. body/self_healing/remediation_models.py +238 -0
  157. body/self_healing/test_context/__init__.py +10 -0
  158. body/self_healing/test_context/detectors.py +74 -0
  159. body/self_healing/test_context/examples.py +53 -0
  160. body/self_healing/test_context/formatter.py +65 -0
  161. body/self_healing/test_context/metrics.py +62 -0
  162. body/self_healing/test_context/models.py +83 -0
  163. body/self_healing/test_context/parsers.py +70 -0
  164. body/self_healing/test_context_analyzer.py +79 -0
  165. body/self_healing/test_failure_analyzer.py +259 -0
  166. body/self_healing/test_target_analyzer.py +118 -0
  167. body/self_healing/vulture_healer.py +161 -0
  168. body/services/__init__.py +4 -0
  169. body/services/artifact_service.py +155 -0
  170. body/services/blackboard_service/__init__.py +22 -0
  171. body/services/blackboard_service/blackboard_claim_service.py +216 -0
  172. body/services/blackboard_service/blackboard_proposal_service.py +305 -0
  173. body/services/blackboard_service/blackboard_query_service.py +333 -0
  174. body/services/blackboard_service/blackboard_service.py +602 -0
  175. body/services/capabilities.py +51 -0
  176. body/services/cim/__init__.py +22 -0
  177. body/services/cim/baselines.py +102 -0
  178. body/services/cim/census_service.py +190 -0
  179. body/services/cim/cim_constants.py +116 -0
  180. body/services/cim/cim_path_utils.py +123 -0
  181. body/services/cim/diff.py +152 -0
  182. body/services/cim/history.py +94 -0
  183. body/services/cim/models.py +319 -0
  184. body/services/cim/policy.py +149 -0
  185. body/services/cim/scanners.py +332 -0
  186. body/services/coherence_service.py +552 -0
  187. body/services/consequence_log_service.py +189 -0
  188. body/services/constitutional_rule_loader.py +141 -0
  189. body/services/constitutional_validator.py +366 -0
  190. body/services/crate_creation_service.py +217 -0
  191. body/services/crate_processing_service.py +279 -0
  192. body/services/crawl_service/__init__.py +10 -0
  193. body/services/crawl_service/main_module.py +531 -0
  194. body/services/crawl_service/orchestrator.py +452 -0
  195. body/services/crawl_service/symbol_processing.py +279 -0
  196. body/services/database_service.py +242 -0
  197. body/services/doc_service.py +57 -0
  198. body/services/file_service.py +260 -0
  199. body/services/governance_claims_service.py +240 -0
  200. body/services/governance_init.py +41 -0
  201. body/services/health_log_service.py +167 -0
  202. body/services/intent_schema_validator.py +211 -0
  203. body/services/llm_client.py +87 -0
  204. body/services/mind_state_service.py +129 -0
  205. body/services/policy_expression_evaluator.py +154 -0
  206. body/services/proposal_supervision_service.py +187 -0
  207. body/services/representation_coherence_service.py +209 -0
  208. body/services/service_registry.py +431 -0
  209. body/services/session_attached_service.py +51 -0
  210. body/services/symbol_query_service.py +218 -0
  211. body/services/symbol_service.py +94 -0
  212. body/services/validation/__init__.py +14 -0
  213. body/services/validation/python_validator.py +89 -0
  214. body/services/validation/validation_policies.py +121 -0
  215. body/services/worker_registry_service.py +184 -0
  216. body/validators/__init__.py +1 -0
  217. body/validators/logic_conservation_validator.py +201 -0
  218. body/workers/call_site_rewriter.py +527 -0
  219. body/workers/prompt_artifact_writer.py +323 -0
  220. cli/__init__.py +4 -0
  221. cli/admin_cli.py +98 -0
  222. cli/cli_user.py +121 -0
  223. cli/commands/__init__.py +4 -0
  224. cli/commands/audit_reporter.py +272 -0
  225. cli/commands/check/__init__.py +115 -0
  226. cli/commands/check/audit.py +130 -0
  227. cli/commands/check/converters.py +129 -0
  228. cli/commands/check/diagnostics_commands.py +70 -0
  229. cli/commands/check/formatters.py +310 -0
  230. cli/commands/check/imports.py +73 -0
  231. cli/commands/check/quality.py +71 -0
  232. cli/commands/check/quality_gates.py +107 -0
  233. cli/commands/check/rule.py +136 -0
  234. cli/commands/check/utils.py +28 -0
  235. cli/commands/check_atomic_actions.py +167 -0
  236. cli/commands/components.py +66 -0
  237. cli/commands/coverage/__init__.py +22 -0
  238. cli/commands/coverage/analysis_commands.py +87 -0
  239. cli/commands/coverage/check_commands.py +173 -0
  240. cli/commands/coverage/generation_commands.py +155 -0
  241. cli/commands/coverage/services/__init__.py +15 -0
  242. cli/commands/coverage/services/coverage_checker.py +50 -0
  243. cli/commands/coverage/services/coverage_reporter.py +81 -0
  244. cli/commands/coverage/services/gaps_analyzer.py +114 -0
  245. cli/commands/daemon.py +908 -0
  246. cli/commands/develop.py +127 -0
  247. cli/commands/diagnostics.py +32 -0
  248. cli/commands/fix/__init__.py +84 -0
  249. cli/commands/fix/all_commands.py +94 -0
  250. cli/commands/fix/atomic_actions.py +48 -0
  251. cli/commands/fix/audit.py +146 -0
  252. cli/commands/fix/body_ui.py +93 -0
  253. cli/commands/fix/code_style.py +52 -0
  254. cli/commands/fix/db_tools.py +90 -0
  255. cli/commands/fix/fix_ir.py +79 -0
  256. cli/commands/fix/handler_discovery.py +54 -0
  257. cli/commands/fix/imports.py +55 -0
  258. cli/commands/fix/list_commands.py +54 -0
  259. cli/commands/fix/metadata.py +160 -0
  260. cli/commands/fix/modularity.py +88 -0
  261. cli/commands/fix/settings_access.py +65 -0
  262. cli/commands/fix_governed.py +103 -0
  263. cli/commands/fix_logging.py +24 -0
  264. cli/commands/governance.py +294 -0
  265. cli/commands/guard.py +125 -0
  266. cli/commands/inspect/__init__.py +79 -0
  267. cli/commands/inspect/_helpers.py +226 -0
  268. cli/commands/inspect/analysis.py +158 -0
  269. cli/commands/inspect/decisions.py +140 -0
  270. cli/commands/inspect/diagnostics.py +126 -0
  271. cli/commands/inspect/drift.py +100 -0
  272. cli/commands/inspect/patterns.py +102 -0
  273. cli/commands/inspect/refusals.py +211 -0
  274. cli/commands/inspect/repo_census.py +175 -0
  275. cli/commands/inspect/status.py +48 -0
  276. cli/commands/interactive_test.py +85 -0
  277. cli/commands/mind.py +49 -0
  278. cli/commands/refactor.py +234 -0
  279. cli/commands/refactor_support/__init__.py +7 -0
  280. cli/commands/refactor_support/analyzer.py +107 -0
  281. cli/commands/refactor_support/config.py +67 -0
  282. cli/commands/refactor_support/display.py +170 -0
  283. cli/commands/refactor_support/recommendations.py +55 -0
  284. cli/commands/run.py +60 -0
  285. cli/commands/search.py +103 -0
  286. cli/commands/status.py +86 -0
  287. cli/commands/submit.py +23 -0
  288. cli/interactive.py +177 -0
  289. cli/logic/__init__.py +7 -0
  290. cli/logic/agent.py +110 -0
  291. cli/logic/audit_capability_domains.py +106 -0
  292. cli/logic/audit_renderer.py +150 -0
  293. cli/logic/autonomy/actions.py +36 -0
  294. cli/logic/autonomy/views.py +116 -0
  295. cli/logic/body_contracts_checker.py +23 -0
  296. cli/logic/build.py +27 -0
  297. cli/logic/byor.py +148 -0
  298. cli/logic/capability.py +27 -0
  299. cli/logic/cli_utils.py +210 -0
  300. cli/logic/context.py +7 -0
  301. cli/logic/db.py +154 -0
  302. cli/logic/db_manage.py +22 -0
  303. cli/logic/decision_inspect_logic.py +62 -0
  304. cli/logic/diagnostics.py +148 -0
  305. cli/logic/diagnostics_policy.py +100 -0
  306. cli/logic/diagnostics_registry.py +165 -0
  307. cli/logic/duplicates.py +19 -0
  308. cli/logic/embeddings_cli.py +43 -0
  309. cli/logic/governance/__init__.py +16 -0
  310. cli/logic/governance/engine.py +216 -0
  311. cli/logic/governance/forensics_service.py +67 -0
  312. cli/logic/governance/limb_status_service.py +83 -0
  313. cli/logic/governance/renderer.py +115 -0
  314. cli/logic/governance/traceability_service.py +78 -0
  315. cli/logic/governance_logic.py +33 -0
  316. cli/logic/hub/__init__.py +14 -0
  317. cli/logic/hub/app.py +107 -0
  318. cli/logic/hub/formatter.py +29 -0
  319. cli/logic/hub/introspection.py +20 -0
  320. cli/logic/hub/repository.py +17 -0
  321. cli/logic/init.py +22 -0
  322. cli/logic/interactive_test/__init__.py +21 -0
  323. cli/logic/interactive_test/session.py +102 -0
  324. cli/logic/interactive_test/steps/__init__.py +23 -0
  325. cli/logic/interactive_test/steps/execution.py +53 -0
  326. cli/logic/interactive_test/steps/generation.py +88 -0
  327. cli/logic/interactive_test/steps/healing.py +79 -0
  328. cli/logic/interactive_test/steps/utils.py +31 -0
  329. cli/logic/interactive_test/steps/verification.py +71 -0
  330. cli/logic/interactive_test/ui.py +203 -0
  331. cli/logic/interactive_test/workflow.py +168 -0
  332. cli/logic/interactive_test_logic.py +41 -0
  333. cli/logic/knowledge.py +47 -0
  334. cli/logic/legacy_scan_logic.py +306 -0
  335. cli/logic/list_audits.py +49 -0
  336. cli/logic/log_audit.py +53 -0
  337. cli/logic/new.py +8 -0
  338. cli/logic/project_docs.py +28 -0
  339. cli/logic/reconcile.py +127 -0
  340. cli/logic/refusal_inspect_logic.py +208 -0
  341. cli/logic/report.py +47 -0
  342. cli/logic/status.py +47 -0
  343. cli/logic/symbol_drift.py +77 -0
  344. cli/logic/sync.py +48 -0
  345. cli/logic/sync_domains.py +72 -0
  346. cli/logic/sync_manifest.py +31 -0
  347. cli/logic/tools.py +133 -0
  348. cli/logic/utils_migration.py +43 -0
  349. cli/logic/validate.py +107 -0
  350. cli/logic/vector_drift.py +109 -0
  351. cli/logic/yaml_processor.py +5 -0
  352. cli/renderers/audit_detail.py +37 -0
  353. cli/renderers/audit_overview.py +39 -0
  354. cli/resources/__init__.py +27 -0
  355. cli/resources/admin/__init__.py +23 -0
  356. cli/resources/admin/coverage.py +63 -0
  357. cli/resources/admin/debt_scan.py +195 -0
  358. cli/resources/admin/forensics.py +97 -0
  359. cli/resources/admin/health.py +66 -0
  360. cli/resources/admin/hub.py +9 -0
  361. cli/resources/admin/meta.py +47 -0
  362. cli/resources/admin/patterns.py +28 -0
  363. cli/resources/admin/refusals.py +31 -0
  364. cli/resources/admin/self_check.py +175 -0
  365. cli/resources/admin/status.py +66 -0
  366. cli/resources/admin/summary.py +67 -0
  367. cli/resources/admin/traces.py +46 -0
  368. cli/resources/admin/validate_env.py +56 -0
  369. cli/resources/code/__init__.py +31 -0
  370. cli/resources/code/actions.py +48 -0
  371. cli/resources/code/audit.py +416 -0
  372. cli/resources/code/audit_duplicates.py +22 -0
  373. cli/resources/code/check_imports.py +75 -0
  374. cli/resources/code/check_ui.py +62 -0
  375. cli/resources/code/clarity.py +51 -0
  376. cli/resources/code/complexity.py +55 -0
  377. cli/resources/code/docstrings.py +51 -0
  378. cli/resources/code/fix_atomic.py +51 -0
  379. cli/resources/code/format.py +62 -0
  380. cli/resources/code/hub.py +10 -0
  381. cli/resources/code/integrity.py +75 -0
  382. cli/resources/code/lint.py +37 -0
  383. cli/resources/code/logging.py +49 -0
  384. cli/resources/code/refactor.py +32 -0
  385. cli/resources/code/test.py +30 -0
  386. cli/resources/coherence/__init__.py +13 -0
  387. cli/resources/coherence/check.py +111 -0
  388. cli/resources/coherence/hub.py +13 -0
  389. cli/resources/coherence/repair_counts.py +73 -0
  390. cli/resources/coherence/report.py +144 -0
  391. cli/resources/coherence/seed.py +297 -0
  392. cli/resources/coherence/supersede.py +124 -0
  393. cli/resources/coherence/triage.py +81 -0
  394. cli/resources/constitution/__init__.py +19 -0
  395. cli/resources/constitution/audit.py +49 -0
  396. cli/resources/constitution/query.py +45 -0
  397. cli/resources/constitution/status.py +34 -0
  398. cli/resources/constitution/validate.py +36 -0
  399. cli/resources/context/__init__.py +21 -0
  400. cli/resources/context/build.py +374 -0
  401. cli/resources/context/cache.py +156 -0
  402. cli/resources/context/explain.py +140 -0
  403. cli/resources/context/hub.py +11 -0
  404. cli/resources/context/search.py +114 -0
  405. cli/resources/database/__init__.py +13 -0
  406. cli/resources/database/cleanup.py +107 -0
  407. cli/resources/database/export.py +61 -0
  408. cli/resources/database/hub.py +11 -0
  409. cli/resources/database/migrate.py +57 -0
  410. cli/resources/database/status.py +101 -0
  411. cli/resources/database/sync.py +84 -0
  412. cli/resources/database/sync_env.py +76 -0
  413. cli/resources/database/sync_registry.py +48 -0
  414. cli/resources/dev/__init__.py +14 -0
  415. cli/resources/dev/hub.py +11 -0
  416. cli/resources/dev/refactor.py +92 -0
  417. cli/resources/dev/stability.py +60 -0
  418. cli/resources/dev/strategic_audit.py +113 -0
  419. cli/resources/dev/sync.py +51 -0
  420. cli/resources/dev/test.py +34 -0
  421. cli/resources/intent/__init__.py +11 -0
  422. cli/resources/intent/hub.py +9 -0
  423. cli/resources/intent/sync_vocabulary.py +396 -0
  424. cli/resources/project/__init__.py +19 -0
  425. cli/resources/project/docs.py +41 -0
  426. cli/resources/project/new.py +40 -0
  427. cli/resources/project/onboard.py +31 -0
  428. cli/resources/proposals/__init__.py +28 -0
  429. cli/resources/proposals/create.py +82 -0
  430. cli/resources/proposals/integrate.py +49 -0
  431. cli/resources/proposals/list.py +76 -0
  432. cli/resources/proposals/manage.py +117 -0
  433. cli/resources/runtime/__init__.py +9 -0
  434. cli/resources/runtime/health.py +925 -0
  435. cli/resources/secrets/__init__.py +10 -0
  436. cli/resources/secrets/hub.py +9 -0
  437. cli/resources/secrets/manage.py +309 -0
  438. cli/resources/symbols/__init__.py +13 -0
  439. cli/resources/symbols/audit.py +46 -0
  440. cli/resources/symbols/fix_ids.py +43 -0
  441. cli/resources/symbols/hub.py +11 -0
  442. cli/resources/symbols/resolve_duplicates.py +30 -0
  443. cli/resources/symbols/sync.py +39 -0
  444. cli/resources/symbols/tag.py +47 -0
  445. cli/resources/vectors/__init__.py +11 -0
  446. cli/resources/vectors/cleanup.py +95 -0
  447. cli/resources/vectors/hub.py +9 -0
  448. cli/resources/vectors/query.py +105 -0
  449. cli/resources/vectors/status.py +30 -0
  450. cli/resources/vectors/sync.py +57 -0
  451. cli/resources/vectors/sync_code.py +67 -0
  452. cli/resources/workers/__init__.py +13 -0
  453. cli/resources/workers/blackboard.py +253 -0
  454. cli/resources/workers/remediate.py +337 -0
  455. cli/resources/workers/run.py +140 -0
  456. cli/utils/__init__.py +32 -0
  457. cli/utils/annotation_formatter.py +154 -0
  458. cli/utils/decorators.py +184 -0
  459. cli/utils/display.py +79 -0
  460. cli/utils/exit_codes.py +59 -0
  461. cli/utils/helpers.py +34 -0
  462. cli/utils/prompts.py +21 -0
  463. core_runtime-0.1.1.dist-info/LICENSE +21 -0
  464. core_runtime-0.1.1.dist-info/METADATA +346 -0
  465. core_runtime-0.1.1.dist-info/RECORD +962 -0
  466. core_runtime-0.1.1.dist-info/WHEEL +4 -0
  467. core_runtime-0.1.1.dist-info/entry_points.txt +4 -0
  468. mind/__init__.py +4 -0
  469. mind/coherence/__init__.py +1 -0
  470. mind/coherence/checker.py +314 -0
  471. mind/coherence/checks/__init__.py +4 -0
  472. mind/coherence/checks/base.py +34 -0
  473. mind/coherence/checks/r1_scoped.py +228 -0
  474. mind/coherence/checks/row2_grounding.py +69 -0
  475. mind/coherence/checks/row3_citation.py +119 -0
  476. mind/coherence/checks/row4_naming.py +126 -0
  477. mind/coherence/checks/sameconcern.py +136 -0
  478. mind/coherence/checks/specgap.py +233 -0
  479. mind/coherence/checks/vocabulary.py +112 -0
  480. mind/coherence/llm_judge.py +207 -0
  481. mind/enforcement/audit.py +78 -0
  482. mind/governance/__init__.py +22 -0
  483. mind/governance/assumption_extractor.py +326 -0
  484. mind/governance/audit_context.py +520 -0
  485. mind/governance/audit_postprocessor.py +36 -0
  486. mind/governance/audit_report_writer.py +46 -0
  487. mind/governance/audit_types.py +98 -0
  488. mind/governance/auditor.py +179 -0
  489. mind/governance/authority_package_builder.py +502 -0
  490. mind/governance/constitutional_auditor_dynamic.py +362 -0
  491. mind/governance/enforcement/__init__.py +24 -0
  492. mind/governance/enforcement_loader.py +245 -0
  493. mind/governance/enforcement_methods.py +28 -0
  494. mind/governance/entry_point_policy.py +62 -0
  495. mind/governance/executable_rule.py +127 -0
  496. mind/governance/filtered_audit.py +272 -0
  497. mind/governance/finding_processor.py +76 -0
  498. mind/governance/meta_validator.py +259 -0
  499. mind/governance/micro_proposal_validator.py +169 -0
  500. mind/governance/policy_coverage_service.py +183 -0
  501. mind/governance/policy_rule.py +94 -0
  502. mind/governance/rule_conflict_detector.py +127 -0
  503. mind/governance/rule_executor.py +306 -0
  504. mind/governance/rule_extractor.py +376 -0
  505. mind/governance/stateless_audit.py +206 -0
  506. mind/governance/violation_report.py +136 -0
  507. mind/logic/engines/_knowledge_gate_duplication.py +117 -0
  508. mind/logic/engines/action_gate.py +76 -0
  509. mind/logic/engines/artifact_gate.py +1168 -0
  510. mind/logic/engines/ast_gate/__init__.py +9 -0
  511. mind/logic/engines/ast_gate/base.py +263 -0
  512. mind/logic/engines/ast_gate/checks/__init__.py +35 -0
  513. mind/logic/engines/ast_gate/checks/async_checks.py +276 -0
  514. mind/logic/engines/ast_gate/checks/capability_checks.py +197 -0
  515. mind/logic/engines/ast_gate/checks/conservation_checks.py +126 -0
  516. mind/logic/engines/ast_gate/checks/generic_checks.py +244 -0
  517. mind/logic/engines/ast_gate/checks/import_checks.py +164 -0
  518. mind/logic/engines/ast_gate/checks/knowledge_source_check.py +88 -0
  519. mind/logic/engines/ast_gate/checks/logging_checks.py +133 -0
  520. mind/logic/engines/ast_gate/checks/metadata_checks.py +242 -0
  521. mind/logic/engines/ast_gate/checks/modularity_checks.py +436 -0
  522. mind/logic/engines/ast_gate/checks/naming_checks.py +120 -0
  523. mind/logic/engines/ast_gate/checks/prompt_model_checks.py +83 -0
  524. mind/logic/engines/ast_gate/checks/protected_namespace_access_check.py +298 -0
  525. mind/logic/engines/ast_gate/checks/purity_checks.py +421 -0
  526. mind/logic/engines/ast_gate/checks/purity_enforcement_check.py +56 -0
  527. mind/logic/engines/ast_gate/checks/runtime_import_boundary.py +198 -0
  528. mind/logic/engines/ast_gate/checks/schema_conformance_checks.py +130 -0
  529. mind/logic/engines/ast_gate/engine.py +317 -0
  530. mind/logic/engines/ast_gate.py +19 -0
  531. mind/logic/engines/base.py +106 -0
  532. mind/logic/engines/cli_gate/__init__.py +25 -0
  533. mind/logic/engines/cli_gate/base_check.py +45 -0
  534. mind/logic/engines/cli_gate/checks/__init__.py +31 -0
  535. mind/logic/engines/cli_gate/checks/async_execution.py +65 -0
  536. mind/logic/engines/cli_gate/checks/dangerous_explicit.py +60 -0
  537. mind/logic/engines/cli_gate/checks/discovery_strict.py +167 -0
  538. mind/logic/engines/cli_gate/checks/help_required.py +43 -0
  539. mind/logic/engines/cli_gate/checks/no_duplicates.py +57 -0
  540. mind/logic/engines/cli_gate/checks/no_layer_exposure.py +48 -0
  541. mind/logic/engines/cli_gate/checks/resource_first.py +58 -0
  542. mind/logic/engines/cli_gate/checks/standard_verbs.py +50 -0
  543. mind/logic/engines/cli_gate/engine.py +211 -0
  544. mind/logic/engines/glob_gate.py +214 -0
  545. mind/logic/engines/knowledge_gate.py +410 -0
  546. mind/logic/engines/llm_gate.py +407 -0
  547. mind/logic/engines/llm_gate_stub.py +67 -0
  548. mind/logic/engines/passive_gate.py +45 -0
  549. mind/logic/engines/regex_gate.py +97 -0
  550. mind/logic/engines/registry.py +134 -0
  551. mind/logic/engines/runtime_gate.py +265 -0
  552. mind/logic/engines/taxonomy_gate.py +229 -0
  553. mind/logic/engines/workflow_gate/__init__.py +22 -0
  554. mind/logic/engines/workflow_gate/base_check.py +42 -0
  555. mind/logic/engines/workflow_gate/checks/__init__.py +32 -0
  556. mind/logic/engines/workflow_gate/checks/alignment.py +93 -0
  557. mind/logic/engines/workflow_gate/checks/audit.py +80 -0
  558. mind/logic/engines/workflow_gate/checks/canary.py +47 -0
  559. mind/logic/engines/workflow_gate/checks/coverage.py +74 -0
  560. mind/logic/engines/workflow_gate/checks/dead_code.py +53 -0
  561. mind/logic/engines/workflow_gate/checks/import_resolution.py +97 -0
  562. mind/logic/engines/workflow_gate/checks/linter.py +104 -0
  563. mind/logic/engines/workflow_gate/checks/quality.py +49 -0
  564. mind/logic/engines/workflow_gate/checks/ruff_format.py +99 -0
  565. mind/logic/engines/workflow_gate/checks/tests.py +81 -0
  566. mind/logic/engines/workflow_gate/engine.py +207 -0
  567. shared/__init__.py +32 -0
  568. shared/action_logger.py +61 -0
  569. shared/action_types.py +199 -0
  570. shared/activity_logging.py +149 -0
  571. shared/ai/constitutional_envelope.py +341 -0
  572. shared/ai/prompt_model.py +585 -0
  573. shared/ai/response_parser.py +191 -0
  574. shared/ast_utility.py +279 -0
  575. shared/atomic_action.py +117 -0
  576. shared/cli/__init__.py +6 -0
  577. shared/cli/app_introspection.py +134 -0
  578. shared/cli/command_meta.py +224 -0
  579. shared/cli_types.py +92 -0
  580. shared/component_primitive.py +216 -0
  581. shared/config.py +216 -0
  582. shared/config_loader.py +54 -0
  583. shared/context.py +113 -0
  584. shared/exceptions.py +100 -0
  585. shared/governance/__init__.py +9 -0
  586. shared/governance/coherence_harvester.py +258 -0
  587. shared/governance_token.py +77 -0
  588. shared/infrastructure/__init__.py +5 -0
  589. shared/infrastructure/adapters/__init__.py +5 -0
  590. shared/infrastructure/adapters/embedding_provider.py +66 -0
  591. shared/infrastructure/bootstrap_registry.py +57 -0
  592. shared/infrastructure/clients/__init__.py +5 -0
  593. shared/infrastructure/clients/qdrant_client.py +455 -0
  594. shared/infrastructure/config_service.py +382 -0
  595. shared/infrastructure/config_validator.py +70 -0
  596. shared/infrastructure/context/__init__.py +45 -0
  597. shared/infrastructure/context/builder.py +804 -0
  598. shared/infrastructure/context/cache.py +101 -0
  599. shared/infrastructure/context/database.py +205 -0
  600. shared/infrastructure/context/limb_workspace.py +134 -0
  601. shared/infrastructure/context/models.py +65 -0
  602. shared/infrastructure/context/providers/__init__.py +18 -0
  603. shared/infrastructure/context/providers/ast.py +211 -0
  604. shared/infrastructure/context/providers/db.py +165 -0
  605. shared/infrastructure/context/providers/vectors.py +195 -0
  606. shared/infrastructure/context/redactor.py +109 -0
  607. shared/infrastructure/context/serializers.py +144 -0
  608. shared/infrastructure/context/service.py +271 -0
  609. shared/infrastructure/context/validator.py +247 -0
  610. shared/infrastructure/database/models/__init__.py +80 -0
  611. shared/infrastructure/database/models/autonomous_proposals.py +83 -0
  612. shared/infrastructure/database/models/decision_traces.py +129 -0
  613. shared/infrastructure/database/models/governance.py +183 -0
  614. shared/infrastructure/database/models/knowledge.py +205 -0
  615. shared/infrastructure/database/models/learning.py +99 -0
  616. shared/infrastructure/database/models/llm_config.py +274 -0
  617. shared/infrastructure/database/models/operations.py +152 -0
  618. shared/infrastructure/database/models/refusals.py +147 -0
  619. shared/infrastructure/database/models/system.py +124 -0
  620. shared/infrastructure/database/models/vectors.py +113 -0
  621. shared/infrastructure/database/models/workers.py +96 -0
  622. shared/infrastructure/database/session_manager.py +166 -0
  623. shared/infrastructure/diagnostic_service.py +103 -0
  624. shared/infrastructure/events/__init__.py +5 -0
  625. shared/infrastructure/events/base.py +44 -0
  626. shared/infrastructure/events/bus.py +76 -0
  627. shared/infrastructure/git_service.py +385 -0
  628. shared/infrastructure/intent/action_risk.py +135 -0
  629. shared/infrastructure/intent/audit_verdict.py +131 -0
  630. shared/infrastructure/intent/autonomy_dirty_tree.py +104 -0
  631. shared/infrastructure/intent/canonical_enums.py +116 -0
  632. shared/infrastructure/intent/cognitive_roles.py +96 -0
  633. shared/infrastructure/intent/errors.py +13 -0
  634. shared/infrastructure/intent/filesystem_operations.py +359 -0
  635. shared/infrastructure/intent/intent_connector.py +157 -0
  636. shared/infrastructure/intent/intent_repository.py +707 -0
  637. shared/infrastructure/intent/intent_validator.py +248 -0
  638. shared/infrastructure/intent/operational_capabilities.py +470 -0
  639. shared/infrastructure/intent/operational_config.py +1343 -0
  640. shared/infrastructure/intent/operational_mode.py +66 -0
  641. shared/infrastructure/intent/task_type_phases.py +180 -0
  642. shared/infrastructure/intent/test_coverage_paths.py +181 -0
  643. shared/infrastructure/intent/vocabulary_projection.py +241 -0
  644. shared/infrastructure/knowledge/knowledge_service.py +155 -0
  645. shared/infrastructure/knowledge_graph_service.py +214 -0
  646. shared/infrastructure/llm/client.py +448 -0
  647. shared/infrastructure/llm/client_registry.py +153 -0
  648. shared/infrastructure/llm/fallback_client.py +144 -0
  649. shared/infrastructure/llm/providers/anthropic.py +113 -0
  650. shared/infrastructure/llm/providers/base.py +130 -0
  651. shared/infrastructure/llm/providers/ollama.py +265 -0
  652. shared/infrastructure/llm/providers/openai.py +168 -0
  653. shared/infrastructure/repositories/__init__.py +5 -0
  654. shared/infrastructure/repositories/db/__init__.py +5 -0
  655. shared/infrastructure/repositories/db/common.py +138 -0
  656. shared/infrastructure/repositories/db/engine.py +26 -0
  657. shared/infrastructure/repositories/db/migration_service.py +75 -0
  658. shared/infrastructure/repositories/db/status_service.py +61 -0
  659. shared/infrastructure/repositories/memory_repository.py +134 -0
  660. shared/infrastructure/repositories/symbol_definition_repository.py +170 -0
  661. shared/infrastructure/repositories/task_repository.py +59 -0
  662. shared/infrastructure/repositories/vector_link_repository.py +83 -0
  663. shared/infrastructure/rooted_repository.py +50 -0
  664. shared/infrastructure/secrets_service.py +317 -0
  665. shared/infrastructure/specs/__init__.py +9 -0
  666. shared/infrastructure/specs/specs_repository.py +100 -0
  667. shared/infrastructure/storage/file_classifier.py +32 -0
  668. shared/infrastructure/storage/file_handler.py +330 -0
  669. shared/infrastructure/storage/file_provider.py +233 -0
  670. shared/infrastructure/storage/integrity_service.py +108 -0
  671. shared/infrastructure/validation/black_formatter.py +41 -0
  672. shared/infrastructure/validation/quality.py +46 -0
  673. shared/infrastructure/validation/ruff_linter.py +104 -0
  674. shared/infrastructure/validation/syntax_checker.py +45 -0
  675. shared/infrastructure/validation/test_runner.py +167 -0
  676. shared/infrastructure/validation/yaml_validator.py +45 -0
  677. shared/infrastructure/vector/__init__.py +15 -0
  678. shared/infrastructure/vector/adapters/__init__.py +20 -0
  679. shared/infrastructure/vector/adapters/constitutional/__init__.py +26 -0
  680. shared/infrastructure/vector/adapters/constitutional/chunker.py +246 -0
  681. shared/infrastructure/vector/adapters/constitutional/doc_key_resolver.py +109 -0
  682. shared/infrastructure/vector/adapters/constitutional/item_builder.py +158 -0
  683. shared/infrastructure/vector/adapters/constitutional/utils.py +39 -0
  684. shared/infrastructure/vector/adapters/constitutional_adapter.py +309 -0
  685. shared/infrastructure/vector/adapters/specs_adapter.py +171 -0
  686. shared/infrastructure/vector/cognitive_adapter.py +119 -0
  687. shared/infrastructure/vector/vector_index_service.py +230 -0
  688. shared/logger.py +195 -0
  689. shared/models/__init__.py +47 -0
  690. shared/models/action_result.py +77 -0
  691. shared/models/audit_models.py +106 -0
  692. shared/models/audit_rendering.py +30 -0
  693. shared/models/capability_models.py +22 -0
  694. shared/models/constitutional_validation.py +185 -0
  695. shared/models/drift_models.py +24 -0
  696. shared/models/embedding_payload.py +45 -0
  697. shared/models/execution_models.py +71 -0
  698. shared/models/pattern_graph.py +62 -0
  699. shared/models/prompt_model.py +244 -0
  700. shared/models/refusal_result.py +294 -0
  701. shared/models/remediation.py +35 -0
  702. shared/models/validation_result.py +34 -0
  703. shared/models/vector_models.py +62 -0
  704. shared/models/workflow_models.py +242 -0
  705. shared/path_resolver.py +408 -0
  706. shared/path_utils.py +60 -0
  707. shared/processors/base_processor.py +171 -0
  708. shared/processors/yaml_processor.py +72 -0
  709. shared/protocols/__init__.py +21 -0
  710. shared/protocols/brain_services.py +35 -0
  711. shared/protocols/cognitive.py +35 -0
  712. shared/protocols/executor.py +47 -0
  713. shared/protocols/interpreter.py +24 -0
  714. shared/protocols/knowledge.py +21 -0
  715. shared/protocols/llm.py +25 -0
  716. shared/protocols/typer_protocols.py +37 -0
  717. shared/time.py +18 -0
  718. shared/universal.py +43 -0
  719. shared/utils/__init__.py +81 -0
  720. shared/utils/audit_grouping.py +50 -0
  721. shared/utils/common_knowledge.py +82 -0
  722. shared/utils/domain_mapper.py +61 -0
  723. shared/utils/embedding_utils.py +182 -0
  724. shared/utils/glob_match.py +93 -0
  725. shared/utils/header_tools.py +177 -0
  726. shared/utils/parallel_processor.py +60 -0
  727. shared/utils/parsing.py +189 -0
  728. shared/utils/path_utils.py +268 -0
  729. shared/utils/subprocess_utils.py +87 -0
  730. shared/workers/__init__.py +19 -0
  731. shared/workers/base.py +533 -0
  732. shared/workers/declaration_validator.py +124 -0
  733. shared/workers/loop_hold_telemetry.py +210 -0
  734. shared/workers/schedule.py +123 -0
  735. will/__init__.py +4 -0
  736. will/agents/__init__.py +4 -0
  737. will/agents/base_planner.py +133 -0
  738. will/agents/code_generation/__init__.py +15 -0
  739. will/agents/code_generation/code_generator.py +247 -0
  740. will/agents/code_generation/context_formatters.py +99 -0
  741. will/agents/code_generation/correction_engine.py +157 -0
  742. will/agents/code_generation/extraction.py +165 -0
  743. will/agents/code_generation/pattern_validator.py +264 -0
  744. will/agents/code_generation/prompt_builders.py +209 -0
  745. will/agents/coder_agent.py +229 -0
  746. will/agents/coder_agent_refusal_handler.py +168 -0
  747. will/agents/cognitive_orchestrator.py +152 -0
  748. will/agents/conversational/__init__.py +13 -0
  749. will/agents/conversational/agent.py +271 -0
  750. will/agents/conversational/factory.py +72 -0
  751. will/agents/conversational/helpers.py +116 -0
  752. will/agents/execution_agent.py +294 -0
  753. will/agents/governance_mixin.py +132 -0
  754. will/agents/planner_agent.py +261 -0
  755. will/agents/resource_selector.py +228 -0
  756. will/agents/strategic_auditor/__init__.py +15 -0
  757. will/agents/strategic_auditor/agent.py +199 -0
  758. will/agents/strategic_auditor/context_gatherer.py +586 -0
  759. will/agents/strategic_auditor/effects.py +136 -0
  760. will/agents/strategic_auditor/models.py +61 -0
  761. will/agents/strategic_auditor/reasoning.py +169 -0
  762. will/agents/tagger_agent.py +294 -0
  763. will/agents/traced_agent_mixin.py +33 -0
  764. will/autonomy/__init__.py +20 -0
  765. will/autonomy/autonomous_developer.py +127 -0
  766. will/autonomy/proposal.py +585 -0
  767. will/autonomy/proposal_execution_pipeline.py +264 -0
  768. will/autonomy/proposal_executor.py +410 -0
  769. will/autonomy/proposal_mapper.py +187 -0
  770. will/autonomy/proposal_repository.py +118 -0
  771. will/autonomy/proposal_service.py +251 -0
  772. will/autonomy/proposal_state_manager.py +239 -0
  773. will/deciders/__init__.py +9 -0
  774. will/deciders/governance_decider.py +207 -0
  775. will/governance/__init__.py +13 -0
  776. will/governance/audit_remediation_runner.py +197 -0
  777. will/governance/audit_runner.py +368 -0
  778. will/governance/census_runner.py +278 -0
  779. will/governance/coverage_runner.py +489 -0
  780. will/governance/daemon_runner.py +164 -0
  781. will/governance/fix_runner.py +693 -0
  782. will/governance/inspect_runner.py +521 -0
  783. will/governance/integrity_runner.py +66 -0
  784. will/governance/lint_runner.py +93 -0
  785. will/governance/refactor_runner.py +372 -0
  786. will/governance/sync_runner.py +186 -0
  787. will/interpreters/__init__.py +44 -0
  788. will/interpreters/cli_args_interpreter.py +106 -0
  789. will/interpreters/natural_language_interpreter.py +276 -0
  790. will/interpreters/request_interpreter.py +126 -0
  791. will/lifecycle/__init__.py +12 -0
  792. will/lifecycle/integration_runner.py +54 -0
  793. will/maintenance/metadata_scribe_service.py +64 -0
  794. will/orchestration/__init__.py +4 -0
  795. will/orchestration/cognitive_service.py +185 -0
  796. will/orchestration/decision_tracer.py +257 -0
  797. will/orchestration/intent_alignment.py +59 -0
  798. will/orchestration/intent_guard.py +20 -0
  799. will/orchestration/phase_registry.py +92 -0
  800. will/orchestration/process_orchestrator.py +270 -0
  801. will/orchestration/prompt_pipeline.py +174 -0
  802. will/orchestration/remediation_orchestrator.py +292 -0
  803. will/orchestration/self_correction_engine.py +154 -0
  804. will/orchestration/validation_pipeline.py +45 -0
  805. will/orchestration/workflow_orchestrator.py +277 -0
  806. will/phases/__init__.py +24 -0
  807. will/phases/audit_phase.py +152 -0
  808. will/phases/canary/pytest_runner.py +156 -0
  809. will/phases/canary/result_builder.py +130 -0
  810. will/phases/canary/test_discovery.py +104 -0
  811. will/phases/canary_validation_phase.py +188 -0
  812. will/phases/code_generation/artifact_saver.py +175 -0
  813. will/phases/code_generation/code_sensor.py +117 -0
  814. will/phases/code_generation/file_path_extractor.py +53 -0
  815. will/phases/code_generation/work_directory_manager.py +83 -0
  816. will/phases/code_generation_phase.py +480 -0
  817. will/phases/execution_phase.py +179 -0
  818. will/phases/interpret_phase.py +266 -0
  819. will/phases/load_phase.py +102 -0
  820. will/phases/parse_phase.py +117 -0
  821. will/phases/planning_phase.py +182 -0
  822. will/phases/runtime_phase.py +112 -0
  823. will/phases/sandbox_validation_phase.py +130 -0
  824. will/phases/style_check_phase.py +209 -0
  825. will/phases/test_generation_phase.py +159 -0
  826. will/self_healing/alignment/persistence.py +53 -0
  827. will/self_healing/alignment/sandbox.py +51 -0
  828. will/self_healing/alignment/specialists.py +165 -0
  829. will/self_healing/alignment_orchestrator.py +140 -0
  830. will/self_healing/audit_remediation_service.py +199 -0
  831. will/self_healing/batch_remediation_service.py +280 -0
  832. will/self_healing/capability_reconciliation_service.py +96 -0
  833. will/self_healing/capability_tagging_service.py +224 -0
  834. will/self_healing/clarity_service.py +204 -0
  835. will/self_healing/complexity_service.py +260 -0
  836. will/self_healing/context_aware_test_generator.py +298 -0
  837. will/self_healing/coverage_remediation_service.py +97 -0
  838. will/self_healing/coverage_watcher.py +192 -0
  839. will/self_healing/enrichment_service.py +211 -0
  840. will/self_healing/linelength_service.py +168 -0
  841. will/self_healing/modularity_remediation_service.py +203 -0
  842. will/self_healing/remediation_evidence_writer.py +144 -0
  843. will/self_healing/remediation_executor.py +113 -0
  844. will/self_healing/remediation_interpretation/__init__.py +1 -0
  845. will/self_healing/remediation_interpretation/file_context_assembler.py +383 -0
  846. will/self_healing/remediation_interpretation/file_role_detector.py +599 -0
  847. will/self_healing/remediation_interpretation/finding_normalizer.py +221 -0
  848. will/self_healing/remediation_interpretation/models.py +198 -0
  849. will/self_healing/remediation_interpretation/reasoning_brief_builder.py +235 -0
  850. will/self_healing/remediation_interpretation/responsibility_extractor.py +421 -0
  851. will/self_healing/remediation_interpretation/service.py +202 -0
  852. will/self_healing/remediation_interpretation/strategy_catalog.py +252 -0
  853. will/self_healing/remediation_interpretation/strategy_selector.py +395 -0
  854. will/self_healing/remediation_pattern_matcher.py +126 -0
  855. will/self_healing/simple_test_generator.py +252 -0
  856. will/self_healing/single_file_remediation.py +137 -0
  857. will/self_healing/test_generation/automatic_repair.py +377 -0
  858. will/self_healing/test_generation/code_extractor.py +238 -0
  859. will/self_healing/test_generation/context_builder.py +140 -0
  860. will/self_healing/test_generation/executor.py +64 -0
  861. will/self_healing/test_generation/failure_parser.py +37 -0
  862. will/self_healing/test_generation/generation_workflow.py +140 -0
  863. will/self_healing/test_generation/generator.py +283 -0
  864. will/self_healing/test_generation/llm_correction.py +160 -0
  865. will/self_healing/test_generation/repair_workflow.py +128 -0
  866. will/self_healing/test_generation/single_test_fixer.py +77 -0
  867. will/self_healing/test_generation/test_extractor.py +50 -0
  868. will/self_healing/test_generation/test_scorer.py +53 -0
  869. will/self_healing/test_generation/test_validator.py +64 -0
  870. will/self_healing/test_generator.py +12 -0
  871. will/strategists/__init__.py +46 -0
  872. will/strategists/base_strategist.py +29 -0
  873. will/strategists/clarity_strategist.py +55 -0
  874. will/strategists/complexity_strategist.py +55 -0
  875. will/strategists/fix_strategist.py +467 -0
  876. will/strategists/sync_strategist.py +369 -0
  877. will/strategists/test_strategist.py +140 -0
  878. will/strategists/validation_strategist.py +315 -0
  879. will/test_generation/__init__.py +46 -0
  880. will/test_generation/adaptive_test_generator.py +123 -0
  881. will/test_generation/artifacts.py +102 -0
  882. will/test_generation/harness_detection.py +103 -0
  883. will/test_generation/helpers/__init__.py +14 -0
  884. will/test_generation/helpers/context_extractor.py +100 -0
  885. will/test_generation/helpers/test_executor.py +230 -0
  886. will/test_generation/llm_output.py +62 -0
  887. will/test_generation/models.py +25 -0
  888. will/test_generation/persistence.py +248 -0
  889. will/test_generation/phases/__init__.py +16 -0
  890. will/test_generation/phases/generation_phase.py +150 -0
  891. will/test_generation/phases/load_phase.py +53 -0
  892. will/test_generation/phases/parse_phase.py +50 -0
  893. will/test_generation/prompt_engine.py +123 -0
  894. will/test_generation/result_aggregator.py +73 -0
  895. will/test_generation/sandbox.py +203 -0
  896. will/test_generation/strategy_link.py +56 -0
  897. will/test_generation/test_extractor.py +140 -0
  898. will/test_generation/validation.py +89 -0
  899. will/tools/__init__.py +13 -0
  900. will/tools/anchor_builder.py +111 -0
  901. will/tools/anchor_search.py +73 -0
  902. will/tools/anchors/discovery.py +55 -0
  903. will/tools/anchors/storage.py +32 -0
  904. will/tools/architectural_context_builder.py +94 -0
  905. will/tools/cognitive_toolbox.py +47 -0
  906. will/tools/context/code_snippet_extractor.py +83 -0
  907. will/tools/context/embedding_search.py +76 -0
  908. will/tools/context/formatter.py +87 -0
  909. will/tools/context/models.py +38 -0
  910. will/tools/context/query_builder.py +42 -0
  911. will/tools/context/retriever.py +182 -0
  912. will/tools/context/standards.py +53 -0
  913. will/tools/file_navigator.py +180 -0
  914. will/tools/layers.py +31 -0
  915. will/tools/module_anchor_generator.py +137 -0
  916. will/tools/module_descriptor.py +154 -0
  917. will/tools/policy_vectorizer.py +184 -0
  918. will/tools/symbol_finder.py +188 -0
  919. will/tools/tool_generator.py +103 -0
  920. will/workers/audit_ingest_worker.py +207 -0
  921. will/workers/audit_violation_filter.py +108 -0
  922. will/workers/audit_violation_normalizer.py +108 -0
  923. will/workers/audit_violation_sensor.py +370 -0
  924. will/workers/blackboard_shop_manager.py +280 -0
  925. will/workers/capability_tagger.py +153 -0
  926. will/workers/circuit_breaker.py +335 -0
  927. will/workers/coherence_sensor.py +212 -0
  928. will/workers/commit_reachability_auditor.py +135 -0
  929. will/workers/db_sync_worker.py +96 -0
  930. will/workers/governance_embedding/__init__.py +9 -0
  931. will/workers/governance_embedding/governance_embedder_worker.py +189 -0
  932. will/workers/intent_inspector.py +599 -0
  933. will/workers/observer_worker.py +158 -0
  934. will/workers/prompt_extractor_worker.py +241 -0
  935. will/workers/proposal_consumer_effects.py +216 -0
  936. will/workers/proposal_consumer_revival.py +131 -0
  937. will/workers/proposal_consumer_worker.py +271 -0
  938. will/workers/proposal_pipeline_shop_manager.py +273 -0
  939. will/workers/repo_crawler.py +171 -0
  940. will/workers/repo_embedding/__init__.py +18 -0
  941. will/workers/repo_embedding/helpers.py +245 -0
  942. will/workers/repo_embedding/repo_embedder_workers.py +163 -0
  943. will/workers/test_coverage_sensor.py +208 -0
  944. will/workers/test_remediator/__init__.py +12 -0
  945. will/workers/test_remediator/_operations.py +295 -0
  946. will/workers/test_remediator/worker.py +187 -0
  947. will/workers/test_runner_sensor.py +430 -0
  948. will/workers/violation_executor.py +496 -0
  949. will/workers/violation_remediator.py +394 -0
  950. will/workers/violation_remediator_blackboard.py +225 -0
  951. will/workers/violation_remediator_body/__init__.py +12 -0
  952. will/workers/violation_remediator_body/blackboard.py +139 -0
  953. will/workers/violation_remediator_body/ceremony.py +154 -0
  954. will/workers/violation_remediator_body/context.py +70 -0
  955. will/workers/violation_remediator_body/llm.py +112 -0
  956. will/workers/violation_remediator_body/models.py +35 -0
  957. will/workers/violation_remediator_body/worker.py +518 -0
  958. will/workers/violation_remediator_proposal.py +328 -0
  959. will/workers/worker_shop_manager.py +244 -0
  960. will/workflows/__init__.py +23 -0
  961. will/workflows/dev_sync_reporter.py +274 -0
  962. will/workflows/dev_sync_workflow.py +118 -0
@@ -0,0 +1,521 @@
1
+ # src/body/atomic/modularity_splitter.py
2
+
3
+ """
4
+ Deterministic modularization splitter.
5
+
6
+ Given a source file and a validated SplitPlan, produces a SplitResult
7
+ describing every file that *would* be written — without writing anything.
8
+ The Execution phase decides whether to persist.
9
+
10
+ Constitutional note:
11
+ Body layer — read-only. SplitResult is a proposal, not an action.
12
+ No settings access, no file writes.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import ast
18
+ from collections.abc import Iterable
19
+ from dataclasses import dataclass, field
20
+ from pathlib import Path
21
+
22
+ from body.atomic.import_resolver import ImportResolver
23
+ from body.atomic.split_plan import ModuleSpec, SplitPlan, SplitPlanError
24
+ from shared.logger import getLogger
25
+
26
+
27
+ logger = getLogger(__name__)
28
+
29
+
30
+ # Issue #213 / Failure 5 in CORE-ModularityLessons.md.
31
+ # Names that are public-by-syntax (no leading underscore) but private-by-
32
+ # convention. They must not be re-exported from a split package's
33
+ # __init__.py — doing so leaks implementation details (e.g. each module's
34
+ # logger instance) into the package's public API surface.
35
+ _PRIVATE_BY_CONVENTION: frozenset[str] = frozenset({"logger", "log", "_logger", "_log"})
36
+
37
+
38
+ def _filter_public_reexports(names: Iterable[str]) -> list[str]:
39
+ """Drop underscore-prefixed and convention-private names from a re-export
40
+ symbol list. Used at every __init__.py emission site so both passes apply
41
+ the same predicate. See issue #213.
42
+ """
43
+ return [
44
+ n for n in names if not n.startswith("_") and n not in _PRIVATE_BY_CONVENTION
45
+ ]
46
+
47
+
48
+ @dataclass
49
+ # ID: 9b77fadf-6869-44bd-a1fd-12a8f24d830c
50
+ class SplitResult:
51
+ """Describes the files a modularization split would produce."""
52
+
53
+ files: list[tuple[Path, str]] = field(default_factory=list)
54
+ original_path: Path = field(default_factory=lambda: Path())
55
+ package_path: Path = field(default_factory=lambda: Path())
56
+
57
+
58
+ # ID: 6a9c0d1e-2f3b-4c5d-8e7f-0a1b2c3d4e5f
59
+ class ModularitySplitter:
60
+ """Split a single source file into a package according to a SplitPlan.
61
+
62
+ All work is AST-based and deterministic. The returned SplitResult
63
+ contains *proposed* file contents; nothing is written to disk.
64
+ """
65
+
66
+ def __init__(self) -> None:
67
+ self._resolver = ImportResolver()
68
+
69
+ # ID: 4e7f8a9b-0c1d-2e3f-4a5b-6c7d8e9f0a1b
70
+ def split(self, source_path: Path, plan: SplitPlan) -> SplitResult:
71
+ """Produce a SplitResult from *source_path* and a validated *plan*.
72
+
73
+ Parameters
74
+ ----------
75
+ source_path:
76
+ Absolute path to the file being split.
77
+ plan:
78
+ A validated ``SplitPlan`` (caller must have called ``validate()``).
79
+
80
+ Returns
81
+ -------
82
+ SplitResult
83
+ Proposed files. Nothing is written to disk.
84
+
85
+ Raises
86
+ ------
87
+ SplitPlanError
88
+ If a symbol listed in the plan cannot be found in the source AST.
89
+ """
90
+ source = source_path.read_text(encoding="utf-8")
91
+ source_lines = source.splitlines(keepends=True)
92
+ tree = ast.parse(source)
93
+
94
+ package_path = source_path.parent / plan.new_package_name
95
+
96
+ # Build name → AST-node index for top-level definitions
97
+ top_level: dict[str, ast.stmt] = {}
98
+ for node in ast.iter_child_nodes(tree):
99
+ if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef)):
100
+ top_level[node.name] = node
101
+
102
+ # Also index top-level assignments (constants, module-level vars)
103
+ for node in ast.iter_child_nodes(tree):
104
+ if isinstance(node, ast.Assign):
105
+ for target in node.targets:
106
+ if isinstance(target, ast.Name):
107
+ top_level[target.id] = node
108
+
109
+ # Determine up-front whether the plan targets class members.
110
+ is_class_split_plan = any(m.is_class_split for m in plan.modules)
111
+
112
+ # Second indexing pass: detect the single-dominant-class case.
113
+ # If one top-level ClassDef contains more than half the total symbols
114
+ # in the plan, build a method-name → AST-node index for that class.
115
+ class_methods: dict[str, ast.stmt] = {}
116
+ dominant_class_name: str | None = None
117
+ class_defs = [
118
+ n for n in ast.iter_child_nodes(tree) if isinstance(n, ast.ClassDef)
119
+ ]
120
+ total_plan_symbols = sum(len(m.symbols) for m in plan.modules)
121
+ if class_defs and total_plan_symbols > 0:
122
+ largest = max(
123
+ class_defs,
124
+ key=lambda c: sum(
125
+ 1
126
+ for n in c.body
127
+ if isinstance(
128
+ n,
129
+ (
130
+ ast.FunctionDef,
131
+ ast.AsyncFunctionDef,
132
+ ast.AnnAssign,
133
+ ast.Assign,
134
+ ),
135
+ )
136
+ ),
137
+ )
138
+ largest_member_count = sum(
139
+ 1
140
+ for n in largest.body
141
+ if isinstance(
142
+ n,
143
+ (ast.FunctionDef, ast.AsyncFunctionDef, ast.AnnAssign, ast.Assign),
144
+ )
145
+ )
146
+ if is_class_split_plan or 2 * largest_member_count > total_plan_symbols:
147
+ dominant_class_name = largest.name
148
+ for member in largest.body:
149
+ if isinstance(member, (ast.FunctionDef, ast.AsyncFunctionDef)):
150
+ class_methods[member.name] = member
151
+ elif isinstance(member, ast.AnnAssign) and isinstance(
152
+ member.target, ast.Name
153
+ ):
154
+ class_methods[member.target.id] = member
155
+ elif isinstance(member, ast.Assign):
156
+ for target in member.targets:
157
+ if isinstance(target, ast.Name):
158
+ class_methods[target.id] = member
159
+
160
+ # Build symbol → module_name map for cross-module resolution
161
+ symbol_to_module: dict[str, str] = {}
162
+ for mod in plan.modules:
163
+ for sym in mod.symbols:
164
+ symbol_to_module[sym] = mod.module_name
165
+
166
+ # Collect all module-level assignment names from original source
167
+ module_assigns: set[str] = set()
168
+ for node in ast.iter_child_nodes(tree):
169
+ if isinstance(node, ast.Assign):
170
+ for target in node.targets:
171
+ if isinstance(target, ast.Name):
172
+ module_assigns.add(target.id)
173
+ elif isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name):
174
+ module_assigns.add(node.target.id)
175
+
176
+ result = SplitResult(
177
+ files=[],
178
+ original_path=source_path,
179
+ package_path=package_path,
180
+ )
181
+
182
+ init_lines: list[str] = [
183
+ f"# {plan.new_package_name}/__init__.py",
184
+ '"""',
185
+ f"Package split from {source_path.name}.",
186
+ '"""',
187
+ "",
188
+ "from __future__ import annotations",
189
+ "",
190
+ ]
191
+
192
+ # ----- class-split branch ----------------------------------------
193
+ if is_class_split_plan:
194
+ # Order modules so that the one containing __init__ comes first;
195
+ # multiple inheritance MRO will use its constructor.
196
+ primary_idx = next(
197
+ (i for i, m in enumerate(plan.modules) if "__init__" in m.symbols),
198
+ 0,
199
+ )
200
+ ordered = [plan.modules[primary_idx]] + [
201
+ m for i, m in enumerate(plan.modules) if i != primary_idx
202
+ ]
203
+
204
+ parent_classes: list[str] = []
205
+ for mod in ordered:
206
+ content = self._build_module(
207
+ source,
208
+ source_lines,
209
+ tree,
210
+ top_level,
211
+ mod,
212
+ symbol_to_module,
213
+ class_methods=class_methods,
214
+ )
215
+ target = package_path / f"{mod.module_name}.py"
216
+ result.files.append((target, content))
217
+
218
+ class_name = self._to_title_case(mod.module_name)
219
+ init_lines.append(f"from .{mod.module_name} import {class_name}")
220
+ parent_classes.append(class_name)
221
+
222
+ # Re-export the original class name for backward compatibility
223
+ # by composing the new per-module classes via multiple inheritance.
224
+ if dominant_class_name and parent_classes:
225
+ init_lines.append("")
226
+ init_lines.append("")
227
+ init_lines.append(
228
+ f"class {dominant_class_name}({', '.join(parent_classes)}):"
229
+ )
230
+ init_lines.append(" pass")
231
+
232
+ init_lines.append("") # trailing newline
233
+ result.files.append((package_path / "__init__.py", "\n".join(init_lines)))
234
+ return result
235
+
236
+ # ----- regular (top-level symbol) branch -------------------------
237
+ plan_symbols: set[str] = set()
238
+ for mod in plan.modules:
239
+ plan_symbols.update(mod.symbols)
240
+
241
+ # Track which module first includes each module-level assignment
242
+ assign_to_first_module: dict[str, str] = {}
243
+
244
+ for mod in plan.modules:
245
+ content = self._build_module(
246
+ source, source_lines, tree, top_level, mod, symbol_to_module
247
+ )
248
+ target = package_path / f"{mod.module_name}.py"
249
+ result.files.append((target, content))
250
+
251
+ # __init__.py re-export line for plan symbols (issue #213:
252
+ # filter underscore-prefixed and convention-private names; skip
253
+ # the line entirely if filtering empties the symbol set,
254
+ # otherwise we'd emit malformed `from .mod import` syntax).
255
+ public_symbols = _filter_public_reexports(mod.symbols)
256
+ if public_symbols:
257
+ init_lines.append(
258
+ f"from .{mod.module_name} import {', '.join(public_symbols)}"
259
+ )
260
+
261
+ # Track module-level assigns referenced by this module's symbols
262
+ refs = self._collect_all_refs(top_level, mod.symbols)
263
+ for assign_name in module_assigns:
264
+ if (
265
+ assign_name in refs
266
+ and assign_name not in plan_symbols
267
+ and assign_name not in assign_to_first_module
268
+ ):
269
+ assign_to_first_module[assign_name] = mod.module_name
270
+
271
+ # Re-export public module-level assignments in __init__.py (issue
272
+ # #213: same convention-private filter as plan-symbol pass; skip
273
+ # empty groups so we never emit a malformed `from .X import` line).
274
+ reexport_by_module: dict[str, list[str]] = {}
275
+ for name, mod_name in assign_to_first_module.items():
276
+ if name.startswith("_") or name in _PRIVATE_BY_CONVENTION:
277
+ continue
278
+ reexport_by_module.setdefault(mod_name, []).append(name)
279
+
280
+ for mod_name, names in sorted(reexport_by_module.items()):
281
+ if not names:
282
+ continue
283
+ init_lines.append(f"from .{mod_name} import {', '.join(sorted(names))}")
284
+
285
+ init_lines.append("") # trailing newline
286
+ result.files.append((package_path / "__init__.py", "\n".join(init_lines)))
287
+
288
+ return result
289
+
290
+ # ------------------------------------------------------------------
291
+ # Internal helpers
292
+ # ------------------------------------------------------------------
293
+
294
+ def _build_module(
295
+ self,
296
+ source: str,
297
+ source_lines: list[str],
298
+ tree: ast.Module,
299
+ top_level: dict[str, ast.stmt],
300
+ mod: ModuleSpec,
301
+ symbol_to_module: dict[str, str],
302
+ *,
303
+ class_methods: dict[str, ast.stmt] | None = None,
304
+ ) -> str:
305
+ """Compose the content for a single target module file."""
306
+ # Branch on is_class_split BEFORE choosing which index to use.
307
+ if mod.is_class_split:
308
+ symbol_index: dict[str, ast.stmt] = class_methods or {}
309
+ else:
310
+ symbol_index = top_level
311
+
312
+ # Validate that every symbol exists in the chosen index
313
+ missing = [s for s in mod.symbols if s not in symbol_index]
314
+ if missing:
315
+ raise SplitPlanError(f"Symbols not found in source AST: {missing}")
316
+
317
+ # Resolve imports
318
+ if mod.is_class_split:
319
+ method_nodes = [symbol_index[s] for s in mod.symbols]
320
+ import_lines = self._resolve_imports_for_methods(source, method_nodes)
321
+ # Methods reach each other via ``self.x``; no relative imports
322
+ cross_import_lines: list[str] = []
323
+ else:
324
+ import_lines = self._resolver.resolve(source, mod.symbols)
325
+
326
+ # Compute cross-module imports for symbols in other split modules
327
+ cross_imports: dict[str, set[str]] = {}
328
+ for sym_name in mod.symbols:
329
+ node = top_level[sym_name]
330
+ for child in ast.walk(node):
331
+ if isinstance(child, ast.Name) and child.id in symbol_to_module:
332
+ other_mod = symbol_to_module[child.id]
333
+ if other_mod != mod.module_name:
334
+ cross_imports.setdefault(other_mod, set()).add(child.id)
335
+
336
+ cross_import_lines = []
337
+ for other_mod, syms in sorted(cross_imports.items()):
338
+ cross_import_lines.append(
339
+ f"from .{other_mod} import {', '.join(sorted(syms))}"
340
+ )
341
+
342
+ # Extract symbol source text, preserving originals
343
+ symbol_blocks: list[str] = []
344
+ for sym_name in mod.symbols:
345
+ node = symbol_index[sym_name]
346
+ block = self._extract_node_source(node, source_lines)
347
+ symbol_blocks.append(block)
348
+
349
+ # Compose file
350
+ parts: list[str] = []
351
+
352
+ # Header comment
353
+ parts.append(f"# {mod.module_name}.py")
354
+ parts.append(f'"""{mod.rationale}"""')
355
+ parts.append("")
356
+
357
+ # External imports + module-level assignments
358
+ for imp in import_lines:
359
+ parts.append(imp)
360
+
361
+ # Cross-module relative imports
362
+ if cross_import_lines:
363
+ if import_lines:
364
+ parts.append("")
365
+ for line in cross_import_lines:
366
+ parts.append(line)
367
+
368
+ if import_lines or cross_import_lines:
369
+ parts.append("")
370
+ parts.append("")
371
+
372
+ # Symbol bodies — wrap in a class for class splits, otherwise emit
373
+ # them as top-level definitions.
374
+ if mod.is_class_split:
375
+ class_name = self._to_title_case(mod.module_name)
376
+ parts.append(f"class {class_name}:")
377
+ # Methods are already indented for class scope in the original
378
+ # source, so we keep their text verbatim.
379
+ parts.append("\n\n".join(symbol_blocks))
380
+ else:
381
+ parts.append("\n\n".join(symbol_blocks))
382
+ parts.append("") # trailing newline
383
+
384
+ return "\n".join(parts)
385
+
386
+ @staticmethod
387
+ def _to_title_case(snake: str) -> str:
388
+ """Convert ``snake_case`` → ``TitleCase``."""
389
+ return "".join(part.capitalize() for part in snake.split("_") if part)
390
+
391
+ def _resolve_imports_for_methods(
392
+ self, source: str, method_nodes: list[ast.stmt]
393
+ ) -> list[str]:
394
+ """Resolve minimal imports needed by a set of class method nodes.
395
+
396
+ Mirrors :meth:`ImportResolver.resolve` but starts from arbitrary AST
397
+ nodes rather than top-level symbol names — required for class splits
398
+ where the "symbols" are methods nested inside a ClassDef.
399
+ """
400
+ tree = ast.parse(source)
401
+ source_lines = source.splitlines(keepends=True)
402
+
403
+ # Collect top-level imports and any TYPE_CHECKING block
404
+ import_nodes: list[ast.stmt] = []
405
+ type_checking_block: list[ast.stmt] = []
406
+ for node in ast.iter_child_nodes(tree):
407
+ if isinstance(node, (ast.Import, ast.ImportFrom)):
408
+ import_nodes.append(node)
409
+ elif isinstance(node, ast.If) and self._resolver._is_type_checking_guard(
410
+ node
411
+ ):
412
+ type_checking_block.append(node)
413
+
414
+ # Module-level assignments
415
+ module_assigns: dict[str, ast.stmt] = {}
416
+ for node in ast.iter_child_nodes(tree):
417
+ if isinstance(node, ast.Assign):
418
+ for target in node.targets:
419
+ if isinstance(target, ast.Name):
420
+ module_assigns[target.id] = node
421
+ elif isinstance(node, ast.AnnAssign) and isinstance(node.target, ast.Name):
422
+ module_assigns[node.target.id] = node
423
+
424
+ # Classify imports
425
+ future_imports: list[str] = []
426
+ regular_imports: list[tuple[ast.stmt, str]] = []
427
+ for node in import_nodes:
428
+ stmt_text = self._resolver._node_source(node, source_lines)
429
+ if isinstance(node, ast.ImportFrom) and node.module == "__future__":
430
+ future_imports.append(stmt_text)
431
+ else:
432
+ regular_imports.append((node, stmt_text))
433
+
434
+ # Names referenced by the method bodies
435
+ needed_names: set[str] = set()
436
+ for mnode in method_nodes:
437
+ for child in ast.walk(mnode):
438
+ if isinstance(child, ast.Name):
439
+ needed_names.add(child.id)
440
+ elif isinstance(child, ast.Attribute):
441
+ root = self._resolver._attribute_root(child)
442
+ if root:
443
+ needed_names.add(root)
444
+
445
+ # Module-level assignments referenced by the method bodies
446
+ needed_assigns: dict[str, ast.stmt] = {}
447
+ for name, node in module_assigns.items():
448
+ if name in needed_names:
449
+ needed_assigns[name] = node
450
+ for node in needed_assigns.values():
451
+ for child in ast.walk(node):
452
+ if isinstance(child, ast.Name):
453
+ needed_names.add(child.id)
454
+ elif isinstance(child, ast.Attribute):
455
+ root = self._resolver._attribute_root(child)
456
+ if root:
457
+ needed_names.add(root)
458
+
459
+ # Match regular imports against expanded needed-name set
460
+ matched: list[str] = []
461
+ for node, stmt_text in regular_imports:
462
+ if self._resolver._import_provides(node, needed_names):
463
+ matched.append(stmt_text)
464
+
465
+ result: list[str] = list(future_imports)
466
+ if type_checking_block:
467
+ for block_node in type_checking_block:
468
+ result.append(self._resolver._node_source(block_node, source_lines))
469
+ result.extend(matched)
470
+
471
+ seen_lines: set[int] = set()
472
+ for node in needed_assigns.values():
473
+ if node.lineno not in seen_lines:
474
+ result.append("")
475
+ result.append(self._resolver._node_source(node, source_lines))
476
+ seen_lines.add(node.lineno)
477
+
478
+ return result
479
+
480
+ @staticmethod
481
+ def _collect_all_refs(
482
+ top_level: dict[str, ast.stmt], symbol_names: list[str]
483
+ ) -> set[str]:
484
+ """Collect all Name references from the bodies of *symbol_names*."""
485
+ refs: set[str] = set()
486
+ for sym_name in symbol_names:
487
+ node = top_level.get(sym_name)
488
+ if node is None:
489
+ continue
490
+ for child in ast.walk(node):
491
+ if isinstance(child, ast.Name):
492
+ refs.add(child.id)
493
+ return refs
494
+
495
+ def _extract_node_source(self, node: ast.stmt, source_lines: list[str]) -> str:
496
+ """Extract the original source text of *node* including leading comments.
497
+
498
+ When *node* carries decorators, extraction starts at the first
499
+ decorator line so framework-registration decorators
500
+ (``@register_action``, ``@atomic_action``, …) survive a split.
501
+ ``node.lineno`` points at the ``def``/``class`` line and would
502
+ silently drop the decorator block.
503
+
504
+ Preserves ``# ID:`` anchors that appear on the line before the
505
+ definition (above the decorator block when present) — required
506
+ by the constitutional symbol-ID rule.
507
+ """
508
+ decorators: list[ast.expr] = getattr(node, "decorator_list", []) or []
509
+ if decorators:
510
+ start = decorators[0].lineno - 1 # 0-based
511
+ else:
512
+ start = node.lineno - 1
513
+ end = node.end_lineno if node.end_lineno is not None else node.lineno
514
+
515
+ # Look backwards for comment lines attached to this definition
516
+ # (e.g. ``# ID: ...`` or docstring preamble comments). With
517
+ # decorators present, this scans above the decorator block.
518
+ while start > 0 and source_lines[start - 1].strip().startswith("#"):
519
+ start -= 1
520
+
521
+ return "".join(source_lines[start:end]).rstrip()
@@ -0,0 +1,171 @@
1
+ # src/body/atomic/proposal_lifecycle_actions.py
2
+
3
+ """
4
+ Proposal lifecycle atomic actions. Per ADR-017, state mutations on
5
+ core.autonomous_proposals belong in governed atomic actions. This file
6
+ currently contains claim.proposal; future complete.proposal /
7
+ fail.proposal / approve.proposal / reject.proposal actions will live
8
+ here when the case for migrating them accumulates.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import time
14
+ from datetime import UTC, datetime
15
+ from typing import TYPE_CHECKING
16
+ from uuid import UUID
17
+
18
+ from sqlalchemy import select, update
19
+
20
+ from body.atomic.registry import ActionCategory, register_action
21
+ from body.services.service_registry import service_registry
22
+ from shared.action_types import ActionImpact, ActionResult
23
+ from shared.atomic_action import atomic_action
24
+ from shared.logger import getLogger
25
+ from will.autonomy.proposal import ProposalStatus
26
+
27
+
28
+ if TYPE_CHECKING:
29
+ from shared.context import CoreContext
30
+
31
+ logger = getLogger(__name__)
32
+
33
+
34
+ @register_action(
35
+ action_id="claim.proposal",
36
+ description=(
37
+ "Atomically claim an approved proposal for execution under worker attribution"
38
+ ),
39
+ category=ActionCategory.STATE,
40
+ policies=["rules/will/proposal_lifecycle"],
41
+ requires_db=True,
42
+ remediates=[],
43
+ )
44
+ @atomic_action(
45
+ action_id="claim.proposal",
46
+ intent="Atomically claim an approved proposal under worker attribution",
47
+ impact=ActionImpact.WRITE_DATA,
48
+ policies=["atomic_actions"],
49
+ )
50
+ # ID: 7d2f4a18-9c3e-4b50-8e21-3f6a5b8d1c04
51
+ async def action_claim_proposal(
52
+ core_context: CoreContext,
53
+ write: bool = False,
54
+ proposal_id: str | None = None,
55
+ claimed_by: UUID | None = None,
56
+ **kwargs,
57
+ ) -> ActionResult:
58
+ """Atomically claim an approved proposal for execution.
59
+
60
+ UPDATEs core.autonomous_proposals setting status='executing',
61
+ execution_started_at=NOW(), claimed_by=$claimed_by with a WHERE that
62
+ requires status='approved'. Single-claim atomicity rides on the
63
+ autonomous_proposals_executing_once partial unique index (ADR-017 D1).
64
+
65
+ write=False: read-only existence/status check; returns would_claim=True
66
+ on a row that could be claimed.
67
+ write=True: the UPDATE; rowcount==0 means lost-the-race or not-approved.
68
+ """
69
+ start_time = time.time()
70
+
71
+ if not proposal_id:
72
+ return ActionResult(
73
+ action_id="claim.proposal",
74
+ ok=False,
75
+ data={"error": "proposal_id is required"},
76
+ duration_sec=time.time() - start_time,
77
+ )
78
+ if claimed_by is None:
79
+ return ActionResult(
80
+ action_id="claim.proposal",
81
+ ok=False,
82
+ data={"error": "claimed_by is required"},
83
+ duration_sec=time.time() - start_time,
84
+ )
85
+
86
+ try:
87
+ async with service_registry.session() as session:
88
+ from shared.infrastructure.database.models.autonomous_proposals import (
89
+ AutonomousProposal,
90
+ )
91
+
92
+ if not write:
93
+ check_stmt = select(AutonomousProposal.proposal_id).where(
94
+ AutonomousProposal.proposal_id == proposal_id,
95
+ AutonomousProposal.status == ProposalStatus.APPROVED.value,
96
+ )
97
+ check_result = await session.execute(check_stmt)
98
+ if check_result.scalar_one_or_none() is None:
99
+ return ActionResult(
100
+ action_id="claim.proposal",
101
+ ok=False,
102
+ data={
103
+ "error": "proposal not found or not approved",
104
+ "proposal_id": proposal_id,
105
+ },
106
+ duration_sec=time.time() - start_time,
107
+ )
108
+ return ActionResult(
109
+ action_id="claim.proposal",
110
+ ok=True,
111
+ data={
112
+ "proposal_id": proposal_id,
113
+ "claimed_by": str(claimed_by),
114
+ "would_claim": True,
115
+ "dry_run": True,
116
+ },
117
+ duration_sec=time.time() - start_time,
118
+ )
119
+
120
+ stmt = (
121
+ update(AutonomousProposal)
122
+ .where(
123
+ AutonomousProposal.proposal_id == proposal_id,
124
+ AutonomousProposal.status == ProposalStatus.APPROVED.value,
125
+ )
126
+ .values(
127
+ status=ProposalStatus.EXECUTING.value,
128
+ execution_started_at=datetime.now(UTC),
129
+ claimed_by=claimed_by,
130
+ )
131
+ )
132
+ result = await session.execute(stmt)
133
+ if result.rowcount == 0:
134
+ await session.rollback()
135
+ logger.warning(
136
+ "claim.proposal: %s already claimed or not approved",
137
+ proposal_id,
138
+ )
139
+ return ActionResult(
140
+ action_id="claim.proposal",
141
+ ok=False,
142
+ data={
143
+ "error": "proposal already claimed or not approved",
144
+ "proposal_id": proposal_id,
145
+ },
146
+ duration_sec=time.time() - start_time,
147
+ )
148
+ await session.commit()
149
+ logger.info("claim.proposal: claimed %s by %s", proposal_id, claimed_by)
150
+ return ActionResult(
151
+ action_id="claim.proposal",
152
+ ok=True,
153
+ data={
154
+ "proposal_id": proposal_id,
155
+ "claimed_by": str(claimed_by),
156
+ "claimed": True,
157
+ },
158
+ duration_sec=time.time() - start_time,
159
+ )
160
+ except Exception as e:
161
+ logger.exception("claim.proposal: failed for %s", proposal_id)
162
+ return ActionResult(
163
+ action_id="claim.proposal",
164
+ ok=False,
165
+ data={
166
+ "error": str(e),
167
+ "error_type": type(e).__name__,
168
+ "proposal_id": proposal_id,
169
+ },
170
+ duration_sec=time.time() - start_time,
171
+ )