devsquad 4.5.8__tar.gz → 4.5.9__tar.gz

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 (516) hide show
  1. {devsquad-4.5.8 → devsquad-4.5.9}/PKG-INFO +3 -3
  2. {devsquad-4.5.8 → devsquad-4.5.9}/README.md +2 -2
  3. {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/PKG-INFO +3 -3
  4. {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/SOURCES.txt +1 -0
  5. {devsquad-4.5.8 → devsquad-4.5.9}/pyproject.toml +1 -1
  6. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/dispatch.py +15 -5
  7. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_module_activation.py +39 -2
  8. devsquad-4.5.9/scripts/collaboration/_version.py +1 -0
  9. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/async_coordinator.py +28 -44
  10. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/coordinator.py +68 -29
  11. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps.py +2 -0
  12. devsquad-4.5.9/scripts/collaboration/gather_core.py +118 -0
  13. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/worker.py +219 -104
  14. {devsquad-4.5.8 → devsquad-4.5.9}/skills/__init__.py +1 -1
  15. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_performance_benchmarks.py +21 -7
  16. devsquad-4.5.8/scripts/collaboration/_version.py +0 -1
  17. {devsquad-4.5.8 → devsquad-4.5.9}/LICENSE +0 -0
  18. {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/dependency_links.txt +0 -0
  19. {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/entry_points.txt +0 -0
  20. {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/requires.txt +0 -0
  21. {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/top_level.txt +0 -0
  22. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/__init__.py +0 -0
  23. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/__init__.py +0 -0
  24. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/models.py +0 -0
  25. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/rate_limit.py +0 -0
  26. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/__init__.py +0 -0
  27. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/lifecycle.py +0 -0
  28. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/metrics.py +0 -0
  29. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/metrics_gates.py +0 -0
  30. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/security.py +0 -0
  31. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api_server.py +0 -0
  32. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/auth.py +0 -0
  33. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/benchmark_async_dispatch.py +0 -0
  34. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/benchmark_ponytail_smart.py +0 -0
  35. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/benchmark_real_llm.py +0 -0
  36. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_async_coverage.py +0 -0
  37. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_config_consistency.py +0 -0
  38. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_constructor_params.py +0 -0
  39. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_dependency_lock.py +0 -0
  40. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_dependency_sync.py +0 -0
  41. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_doc_consistency.py +0 -0
  42. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_hidden_content.py +0 -0
  43. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_test_pyramid.py +0 -0
  44. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_test_quality.py +0 -0
  45. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_version_consistency.py +0 -0
  46. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli/__init__.py +0 -0
  47. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli/cli_visual.py +0 -0
  48. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli.py +0 -0
  49. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_audit.py +0 -0
  50. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_backend.py +0 -0
  51. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_dispatch.py +0 -0
  52. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_doctor.py +0 -0
  53. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_lifecycle.py +0 -0
  54. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_metrics.py +0 -0
  55. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_modules.py +0 -0
  56. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_risks.py +0 -0
  57. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_sessions.py +0 -0
  58. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_utils.py +0 -0
  59. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/__init__.py +0 -0
  60. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/adaptive_role_selector.py +0 -0
  61. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/adversarial_verify.py +0 -0
  62. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/agent_briefing.py +0 -0
  63. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/agent_identity.py +0 -0
  64. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ai_semantic_matcher.py +0 -0
  65. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/anchor_checker.py +0 -0
  66. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/anti_rationalization.py +0 -0
  67. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/approval_gate.py +0 -0
  68. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/artifact_store.py +0 -0
  69. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/async_adapter.py +0 -0
  70. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/async_coeffect_resolver.py +0 -0
  71. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/async_llm_backend.py +0 -0
  72. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/audit_logger.py +0 -0
  73. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/__init__.py +0 -0
  74. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/git_driver.py +0 -0
  75. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/loop_controller.py +0 -0
  76. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/notes_memory.py +0 -0
  77. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/run_state.py +0 -0
  78. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/sleep_guard.py +0 -0
  79. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/smart_confirmation.py +0 -0
  80. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/backend_config.py +0 -0
  81. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/backend_paths.py +0 -0
  82. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/batch_scheduler.py +0 -0
  83. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/benchmark_regression_checker.py +0 -0
  84. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/cache_interface.py +0 -0
  85. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ccr_store.py +0 -0
  86. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/checkpoint_manager.py +0 -0
  87. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ci_feedback_adapter.py +0 -0
  88. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/cli_command_classifier.py +0 -0
  89. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/code_graph_query.py +0 -0
  90. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/code_graph_storage.py +0 -0
  91. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/code_knowledge_graph.py +0 -0
  92. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/code_map_generator.py +0 -0
  93. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/coeffect.py +0 -0
  94. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/concern_pack_loader.py +0 -0
  95. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/confidence_score.py +0 -0
  96. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/config_manager.py +0 -0
  97. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/connector_framework.py +0 -0
  98. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/consensus.py +0 -0
  99. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/consensus_gate.py +0 -0
  100. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/constants.py +0 -0
  101. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/content_cache.py +0 -0
  102. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/content_crusher.py +0 -0
  103. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/context_compressor.py +0 -0
  104. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dashboard_live_mode.py +0 -0
  105. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/debt_collector.py +0 -0
  106. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dependency_hallucination_checker.py +0 -0
  107. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/deployment_compliance_checker.py +0 -0
  108. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_audit.py +0 -0
  109. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_component_factory.py +0 -0
  110. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_effect.py +0 -0
  111. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_hooks.py +0 -0
  112. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_lifecycle.py +0 -0
  113. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_models.py +0 -0
  114. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_performance.py +0 -0
  115. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_pre_steps.py +0 -0
  116. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_rbac.py +0 -0
  117. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_result_assembler.py +0 -0
  118. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_services.py +0 -0
  119. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_base.py +0 -0
  120. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_consensus_mixin.py +0 -0
  121. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_feedback_mixin.py +0 -0
  122. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_mixins.py +0 -0
  123. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_quality_mixin.py +0 -0
  124. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_services_mixin.py +0 -0
  125. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher.py +0 -0
  126. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_async_mixin.py +0 -0
  127. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_audit_mixin.py +0 -0
  128. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_base.py +0 -0
  129. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_config.py +0 -0
  130. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_error_mixin.py +0 -0
  131. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_factory.py +0 -0
  132. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_intent_mapper.py +0 -0
  133. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_lifecycle_mixin.py +0 -0
  134. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_loop_controller.py +0 -0
  135. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_mixins.py +0 -0
  136. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_status_mixin.py +0 -0
  137. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_transaction.py +0 -0
  138. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_utils_mixin.py +0 -0
  139. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dora_metrics_collector.py +0 -0
  140. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dual_layer_context.py +0 -0
  141. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/effect_registry.py +0 -0
  142. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/enhanced_worker.py +0 -0
  143. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/enterprise_feature.py +0 -0
  144. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/error_budget_tracker.py +0 -0
  145. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/event_bus.py +0 -0
  146. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/execution_guard.py +0 -0
  147. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/feature_usage_tracker.py +0 -0
  148. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/feedback_control_loop.py +0 -0
  149. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/file_bundler.py +0 -0
  150. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/file_risk_store.py +0 -0
  151. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/five_axis_consensus.py +0 -0
  152. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/gap_analyzer.py +0 -0
  153. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/gitlab_connector.py +0 -0
  154. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/host_llm_bridge.py +0 -0
  155. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/host_llm_bridge_v2.py +0 -0
  156. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/input_validator.py +0 -0
  157. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/intent_workflow_mapper.py +0 -0
  158. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/judge_agent.py +0 -0
  159. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/language_parsers.py +0 -0
  160. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/learned_rule_store.py +0 -0
  161. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_gate.py +0 -0
  162. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_protocol.py +0 -0
  163. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_shortcut_adapter.py +0 -0
  164. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_shortcut_helpers.py +0 -0
  165. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_templates.py +0 -0
  166. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_backend.py +0 -0
  167. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_cache.py +0 -0
  168. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_cache_async.py +0 -0
  169. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_cache_base.py +0 -0
  170. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_retry.py +0 -0
  171. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_retry_async.py +0 -0
  172. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_retry_base.py +0 -0
  173. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/__init__.py +0 -0
  174. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/discovery_probe.py +0 -0
  175. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/handoff_adapter.py +0 -0
  176. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/independent_evaluator.py +0 -0
  177. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/kernel.py +0 -0
  178. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/loop_scheduler.py +0 -0
  179. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/models.py +0 -0
  180. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/protocols.py +0 -0
  181. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/rollback_strategy.py +0 -0
  182. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/unified_memory.py +0 -0
  183. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/mce_adapter.py +0 -0
  184. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_bridge.py +0 -0
  185. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_claw_source.py +0 -0
  186. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_forgetting.py +0 -0
  187. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_index.py +0 -0
  188. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_query.py +0 -0
  189. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_serializer.py +0 -0
  190. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_types.py +0 -0
  191. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/meta_skill_layering.py +0 -0
  192. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/micro_task_planner.py +0 -0
  193. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/models.py +0 -0
  194. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/models_base.py +0 -0
  195. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/models_dispatch.py +0 -0
  196. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/models_lifecycle.py +0 -0
  197. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/module_fiber.py +0 -0
  198. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/moka_backend.py +0 -0
  199. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/multi_host_adapter.py +0 -0
  200. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/multi_level_cache.py +0 -0
  201. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/multi_tenant.py +0 -0
  202. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/null_providers.py +0 -0
  203. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/operation_classifier.py +0 -0
  204. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/order_chain_detector.py +0 -0
  205. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/output_slicer.py +0 -0
  206. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/output_validator.py +0 -0
  207. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/perf_baseline.py +0 -0
  208. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/performance_fingerprint.py +0 -0
  209. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/performance_monitor.py +0 -0
  210. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/permission_guard.py +0 -0
  211. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/plugins/__init__.py +0 -0
  212. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/plugins/hot_loader.py +0 -0
  213. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ponytail_rule_injector.py +0 -0
  214. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prometheus_metrics.py +0 -0
  215. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler.py +0 -0
  216. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_base.py +0 -0
  217. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_formatting_mixin.py +0 -0
  218. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_mixins.py +0 -0
  219. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_substitution_mixin.py +0 -0
  220. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_template_mixin.py +0 -0
  221. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_validation_mixin.py +0 -0
  222. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_dials.py +0 -0
  223. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/protocols.py +0 -0
  224. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/quality_calibration_gate.py +0 -0
  225. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/quality_probe_slice.py +0 -0
  226. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/rbac_engine.py +0 -0
  227. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/redesign_auditor.py +0 -0
  228. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/redesign_checkers.py +0 -0
  229. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/redis_cache.py +0 -0
  230. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/report_formatter.py +0 -0
  231. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/requirement_tracer.py +0 -0
  232. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/retrospective.py +0 -0
  233. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/review_checkers.py +0 -0
  234. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/risk_register.py +0 -0
  235. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/role_matcher.py +0 -0
  236. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/role_skill_loader.py +0 -0
  237. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/role_specific_mock_backend.py +0 -0
  238. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/rule_collector.py +0 -0
  239. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/scratchpad.py +0 -0
  240. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/scratchpad_history_store.py +0 -0
  241. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/secret_patterns.py +0 -0
  242. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/severity_router.py +0 -0
  243. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/similar_task_recommender.py +0 -0
  244. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_extractor.py +0 -0
  245. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_provider_builtin.py +0 -0
  246. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_provider_mcp.py +0 -0
  247. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_registry.py +0 -0
  248. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_storage.py +0 -0
  249. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skillifier.py +0 -0
  250. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/standardized_role_template.py +0 -0
  251. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/task_completion_checker.py +0 -0
  252. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/task_scale_gate.py +0 -0
  253. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/tech_debt_manager.py +0 -0
  254. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/test_quality_guard.py +0 -0
  255. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/todo_drift_monitor.py +0 -0
  256. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/two_stage_review_gate.py +0 -0
  257. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_accessibility_mixin.py +0 -0
  258. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_framework.py +0 -0
  259. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_framework_base.py +0 -0
  260. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_heuristic_mixin.py +0 -0
  261. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_journey_mixin.py +0 -0
  262. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_mixins.py +0 -0
  263. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_persona_mixin.py +0 -0
  264. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/unified_gate_engine.py +0 -0
  265. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/usage_tracker.py +0 -0
  266. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/user_friendly_error.py +0 -0
  267. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/verification_gate.py +0 -0
  268. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/viewpoint_registry.py +0 -0
  269. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/warmup_manager.py +0 -0
  270. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine.py +0 -0
  271. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_base.py +0 -0
  272. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_lifecycle_mixin.py +0 -0
  273. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_mixins.py +0 -0
  274. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_persistence_mixin.py +0 -0
  275. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_state_mixin.py +0 -0
  276. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_transition_mixin.py +0 -0
  277. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/yagni_checker.py +0 -0
  278. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collect_baseline.py +0 -0
  279. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/__init__.py +0 -0
  280. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/app.py +0 -0
  281. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/auth_views.py +0 -0
  282. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/components.py +0 -0
  283. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/dag_views.py +0 -0
  284. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/dispatch_views.py +0 -0
  285. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/i18n.py +0 -0
  286. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/lifecycle_views.py +0 -0
  287. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/metrics_views.py +0 -0
  288. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/state.py +0 -0
  289. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/v43_panels.py +0 -0
  290. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard.py +0 -0
  291. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/generate_benchmark_report.py +0 -0
  292. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/generate_quality_decision_report.py +0 -0
  293. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/history_manager.py +0 -0
  294. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/mcp_server.py +0 -0
  295. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/__init__.py +0 -0
  296. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/deterministic_rule_engine.py +0 -0
  297. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/models.py +0 -0
  298. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/taste_dials.py +0 -0
  299. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/uiux_analyzer.py +0 -0
  300. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/uiux_subitems.py +0 -0
  301. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/visual_regression.py +0 -0
  302. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/scan_pickle_payloads.py +0 -0
  303. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/utils/__init__.py +0 -0
  304. {devsquad-4.5.8 → devsquad-4.5.9}/scripts/utils/_find_missing_hints.py +0 -0
  305. {devsquad-4.5.8 → devsquad-4.5.9}/setup.cfg +0 -0
  306. {devsquad-4.5.8 → devsquad-4.5.9}/skills/_version.py +0 -0
  307. {devsquad-4.5.8 → devsquad-4.5.9}/skills/dispatch/handler.py +0 -0
  308. {devsquad-4.5.8 → devsquad-4.5.9}/skills/intent/handler.py +0 -0
  309. {devsquad-4.5.8 → devsquad-4.5.9}/skills/prototype/handler.py +0 -0
  310. {devsquad-4.5.8 → devsquad-4.5.9}/skills/registry.py +0 -0
  311. {devsquad-4.5.8 → devsquad-4.5.9}/skills/retrospective/__init__.py +0 -0
  312. {devsquad-4.5.8 → devsquad-4.5.9}/skills/retrospective/handler.py +0 -0
  313. {devsquad-4.5.8 → devsquad-4.5.9}/skills/review/handler.py +0 -0
  314. {devsquad-4.5.8 → devsquad-4.5.9}/skills/security/handler.py +0 -0
  315. {devsquad-4.5.8 → devsquad-4.5.9}/skills/teach/handler.py +0 -0
  316. {devsquad-4.5.8 → devsquad-4.5.9}/skills/test/__init__.py +0 -0
  317. {devsquad-4.5.8 → devsquad-4.5.9}/skills/test/handler.py +0 -0
  318. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_4pt_grid.py +0 -0
  319. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_adaptive_role_selector.py +0 -0
  320. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_adversarial_verify.py +0 -0
  321. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_agent_briefing.py +0 -0
  322. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_anchor_retrospective.py +0 -0
  323. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_anti_rationalization.py +0 -0
  324. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_antipattern_bans.py +0 -0
  325. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_api_budget_status_endpoint.py +0 -0
  326. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_api_security.py +0 -0
  327. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_api_server_v362.py +0 -0
  328. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_approval_gate.py +0 -0
  329. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_artifact_effect_binding.py +0 -0
  330. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_artifact_store.py +0 -0
  331. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_async_coordinator.py +0 -0
  332. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_async_modules.py +0 -0
  333. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_audit_logger.py +0 -0
  334. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_auth_phase5.py +0 -0
  335. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_autonomous.py +0 -0
  336. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_backend_config.py +0 -0
  337. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_benchmark_ponytail_smart.py +0 -0
  338. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cache_interface.py +0 -0
  339. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_ccr_store.py +0 -0
  340. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_async_coverage.py +0 -0
  341. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_config_consistency.py +0 -0
  342. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_constructor_params.py +0 -0
  343. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_dependency_lock.py +0 -0
  344. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_hidden_content.py +0 -0
  345. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_test_pyramid.py +0 -0
  346. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_test_quality.py +0 -0
  347. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_version_consistency.py +0 -0
  348. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_ci_feedback_adapter.py +0 -0
  349. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_audit.py +0 -0
  350. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_command_classifier.py +0 -0
  351. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_deep_v362.py +0 -0
  352. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_doctor.py +0 -0
  353. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_lifecycle.py +0 -0
  354. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_metrics.py +0 -0
  355. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_phase5.py +0 -0
  356. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_code_knowledge_graph.py +0 -0
  357. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_claw_integration_test.py +0 -0
  358. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_context_compressor_test.py +0 -0
  359. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_core_test.py +0 -0
  360. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_dispatcher_test.py +0 -0
  361. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_dispatcher_ux_test.py +0 -0
  362. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_e2e_test.py +0 -0
  363. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_enhanced_e2e_test.py +0 -0
  364. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_llm_cache_test.py +0 -0
  365. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_llm_retry_test.py +0 -0
  366. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_mce_adapter_test.py +0 -0
  367. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_memory_bridge_test.py +0 -0
  368. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_performance_monitor_test.py +0 -0
  369. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_permission_guard_test.py +0 -0
  370. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_prompt_optimization_test.py +0 -0
  371. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_role_mapping_test.py +0 -0
  372. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_skillifier_test.py +0 -0
  373. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_test_quality_guard.py +0 -0
  374. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_test_quality_guard_test.py +0 -0
  375. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_upstream_test.py +0 -0
  376. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_warmup_manager_test.py +0 -0
  377. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_confidence_score.py +0 -0
  378. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_config_injection.py +0 -0
  379. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_consensus_dissent.py +0 -0
  380. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_consensus_fatigue.py +0 -0
  381. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_consensus_gate.py +0 -0
  382. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_content_cache.py +0 -0
  383. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_content_crusher.py +0 -0
  384. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_coordinator_smart_compression.py +0 -0
  385. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dag_views.py +0 -0
  386. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dashboard_live_mode.py +0 -0
  387. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dashboard_split.py +0 -0
  388. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dashboard_ui_e2e.py +0 -0
  389. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dashboard_v43_panels.py +0 -0
  390. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_data_backup.py +0 -0
  391. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_debt_collector.py +0 -0
  392. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_deep_shallow.py +0 -0
  393. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_deletion_test.py +0 -0
  394. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dependency_hallucination_checker.py +0 -0
  395. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dependency_lock.py +0 -0
  396. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_deployment_compliance_checker.py +0 -0
  397. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_deterministic_rule_engine.py +0 -0
  398. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatch_audit.py +0 -0
  399. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatch_performance.py +0 -0
  400. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatch_rbac.py +0 -0
  401. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatch_steps.py +0 -0
  402. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_intent_mapper.py +0 -0
  403. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_loop_controller.py +0 -0
  404. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_mixins.py +0 -0
  405. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_phase5_core.py +0 -0
  406. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_transaction.py +0 -0
  407. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_docker_deployment.py +0 -0
  408. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dual_layer_context.py +0 -0
  409. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_effect_registry.py +0 -0
  410. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_enhanced_worker.py +0 -0
  411. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_fallback_fuse.py +0 -0
  412. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_feedback_control_loop.py +0 -0
  413. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_five_axis_consensus.py +0 -0
  414. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_flow_standalone.py +0 -0
  415. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_full_lifecycle_adapter.py +0 -0
  416. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_git_guardrails.py +0 -0
  417. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_gitlab_connector.py +0 -0
  418. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_glossary_loader.py +0 -0
  419. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_grilling_mode.py +0 -0
  420. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_handoff_redaction.py +0 -0
  421. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_history_manager_v362.py +0 -0
  422. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_host_bridge_unit.py +0 -0
  423. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_host_llm_bridge_v2.py +0 -0
  424. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_input_validator_phase5.py +0 -0
  425. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_input_validator_sensitive.py +0 -0
  426. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_intent_workflow_mapper.py +0 -0
  427. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_judge_agent.py +0 -0
  428. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_learned_rule_phase4.py +0 -0
  429. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_lifecycle_protocol.py +0 -0
  430. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_llm_auto_fallback.py +0 -0
  431. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_llm_backend_resolve.py +0 -0
  432. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_llm_cache_protocol.py +0 -0
  433. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_loop_engineering.py +0 -0
  434. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_loop_engineering_rollback.py +0 -0
  435. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_mcp_server_v362.py +0 -0
  436. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_memory_benchmarks.py +0 -0
  437. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_meta_skill_layering.py +0 -0
  438. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_micro_task_planner.py +0 -0
  439. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_moka_backend.py +0 -0
  440. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_multi_host_adapter.py +0 -0
  441. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_multi_tenant.py +0 -0
  442. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_multi_tenant_isolation_e2e.py +0 -0
  443. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_no_op_test.py +0 -0
  444. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_node_type_separation.py +0 -0
  445. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_null_providers.py +0 -0
  446. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_oklch_color.py +0 -0
  447. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_operation_classifier.py +0 -0
  448. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_order_chain_detector.py +0 -0
  449. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_output_slicer.py +0 -0
  450. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_output_validator_prompt_injection.py +0 -0
  451. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_perf_baseline.py +0 -0
  452. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_perf_baseline_ci_gate.py +0 -0
  453. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_performance_fingerprint.py +0 -0
  454. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_performance_monitor_protocol.py +0 -0
  455. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_permission_guard_human_gate.py +0 -0
  456. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_permission_guard_phase5.py +0 -0
  457. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_phase4_ghost_feature_defense.py +0 -0
  458. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_pipeline_step19_20.py +0 -0
  459. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_plan_c_unified_architecture.py +0 -0
  460. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_plugins_hot_loader.py +0 -0
  461. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_ponytail_rule_injector.py +0 -0
  462. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_production_features.py +0 -0
  463. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_prometheus_metrics.py +0 -0
  464. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_prompt_dials.py +0 -0
  465. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_protocols.py +0 -0
  466. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_prototype_skill.py +0 -0
  467. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_qa_uiux_visual_regression.py +0 -0
  468. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_quick_bonus.py +0 -0
  469. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rate_limit.py +0 -0
  470. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rbac_engine.py +0 -0
  471. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rbac_fail_closed.py +0 -0
  472. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_red_capable_gate.py +0 -0
  473. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_redesign_auditor.py +0 -0
  474. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_redis_cache.py +0 -0
  475. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_requirement_tracer.py +0 -0
  476. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_retry_jitter_strategies.py +0 -0
  477. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_role_skill_loader.py +0 -0
  478. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rule_collector.py +0 -0
  479. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rule_injection_security.py +0 -0
  480. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_secret_patterns.py +0 -0
  481. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_severity_router.py +0 -0
  482. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_similar_task_recommender.py +0 -0
  483. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_skill_registry_coverage.py +0 -0
  484. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_skill_security.py +0 -0
  485. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_sleep_guard.py +0 -0
  486. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_standardized_role_template.py +0 -0
  487. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_start_script.py +0 -0
  488. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_step_node_types.py +0 -0
  489. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_suggested_next_steps.py +0 -0
  490. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_task_completion_checker.py +0 -0
  491. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_task_scale_gate.py +0 -0
  492. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_taste_dials.py +0 -0
  493. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_tautological_seams.py +0 -0
  494. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_teach_skill.py +0 -0
  495. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_tech_debt_manager.py +0 -0
  496. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_todo_drift_monitor.py +0 -0
  497. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_token_budget_compressed_scratchpad.py +0 -0
  498. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_triage_label.py +0 -0
  499. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_two_stage_review_gate.py +0 -0
  500. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_ue_test_framework.py +0 -0
  501. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_uiux_subitems.py +0 -0
  502. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_usage_tracker_coverage.py +0 -0
  503. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_v39_e2e.py +0 -0
  504. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_v39_performance.py +0 -0
  505. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_v411_security_hardening.py +0 -0
  506. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_verification_gate.py +0 -0
  507. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_version.py +0 -0
  508. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_vertical_slice.py +0 -0
  509. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_worker_artifact_integration.py +0 -0
  510. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine.py +0 -0
  511. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine_base.py +0 -0
  512. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine_lifecycle.py +0 -0
  513. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine_state.py +0 -0
  514. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine_transition.py +0 -0
  515. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_persistence_coverage.py +0 -0
  516. {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_yagni_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devsquad
3
- Version: 4.5.8
3
+ Version: 4.5.9
4
4
  Summary: Production-Ready Multi-Role AI Task Orchestrator
5
5
  Author-email: DevSquad Team <devsquad@example.com>
6
6
  License: MIT
@@ -96,14 +96,14 @@ Dynamic: license-file
96
96
  <p align="center">
97
97
  <strong>🎯 把「单个 AI 助手」升级成「7 人 AI 专业团队」</strong>
98
98
  <br>
99
- <em>One task → Multi-role AI collaboration → One conclusion | V4.5.8 (FileRiskStore persistence + risks add/assess/mitigate/close + exposure filters) | V4.5.7 (Coeffect Async + Risk Register UX CLI) | V4.5.6 (Module Fiber + Coeffect: 6-state FSM + topological activation + modules CLI) | V4.5.3 (Artifacts + Effect — ArtifactStore + DispatchEffect + EffectRegistry + Audit CLI) | V4.5.2 (Experience polish: MOKA + Metrics + GitLab + Doctor + BackendConfig) | V4.5.0 (cross-session continuity + protocol-native skills)</em>
99
+ <em>One task → Multi-role AI collaboration → One conclusion | V4.5.9 (Unified Gather Execution Core + Native Async Worker: 执行层统一 gather 化 + Worker 原生异步) | V4.5.8 (FileRiskStore persistence + risks add/assess/mitigate/close + exposure filters) | V4.5.7 (Coeffect Async + Risk Register UX CLI) | V4.5.6 (Module Fiber + Coeffect: 6-state FSM + topological activation + modules CLI) | V4.5.3 (Artifacts + Effect — ArtifactStore + DispatchEffect + EffectRegistry + Audit CLI) | V4.5.2 (Experience polish: MOKA + Metrics + GitLab + Doctor + BackendConfig) | V4.5.0 (cross-session continuity + protocol-native skills)</em>
100
100
  </p>
101
101
 
102
102
  <p align="center">
103
103
  <img alt="Python" src="https://img.shields.io/badge/Python-3.10+-blue?logo=python&logoColor=white" />
104
104
  <img alt="License" src="https://img.shields.io/badge/License-MIT-green" />
105
105
  <img alt="Tests" src="https://img.shields.io/badge/Tests-8996%2B%20passing-brightgreen" />
106
- <img alt="Version" src="https://img.shields.io/badge/V4.5.8-success" />
106
+ <img alt="Version" src="https://img.shields.io/badge/V4.5.9-success" />
107
107
  <img alt="CI" src="https://img.shields.io/badge/CI-GitHub_Actions-blue?logo=githubactions" />
108
108
  <img alt="Quality" src="https://img.shields.io/badge/Code%20Quality-4.3%2F5%20%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%86-blue" />
109
109
  <img alt="Security" src="https://img.shields.io/badge/Security-5%2F5%20%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-success" />
@@ -3,14 +3,14 @@
3
3
  <p align="center">
4
4
  <strong>🎯 把「单个 AI 助手」升级成「7 人 AI 专业团队」</strong>
5
5
  <br>
6
- <em>One task → Multi-role AI collaboration → One conclusion | V4.5.8 (FileRiskStore persistence + risks add/assess/mitigate/close + exposure filters) | V4.5.7 (Coeffect Async + Risk Register UX CLI) | V4.5.6 (Module Fiber + Coeffect: 6-state FSM + topological activation + modules CLI) | V4.5.3 (Artifacts + Effect — ArtifactStore + DispatchEffect + EffectRegistry + Audit CLI) | V4.5.2 (Experience polish: MOKA + Metrics + GitLab + Doctor + BackendConfig) | V4.5.0 (cross-session continuity + protocol-native skills)</em>
6
+ <em>One task → Multi-role AI collaboration → One conclusion | V4.5.9 (Unified Gather Execution Core + Native Async Worker: 执行层统一 gather 化 + Worker 原生异步) | V4.5.8 (FileRiskStore persistence + risks add/assess/mitigate/close + exposure filters) | V4.5.7 (Coeffect Async + Risk Register UX CLI) | V4.5.6 (Module Fiber + Coeffect: 6-state FSM + topological activation + modules CLI) | V4.5.3 (Artifacts + Effect — ArtifactStore + DispatchEffect + EffectRegistry + Audit CLI) | V4.5.2 (Experience polish: MOKA + Metrics + GitLab + Doctor + BackendConfig) | V4.5.0 (cross-session continuity + protocol-native skills)</em>
7
7
  </p>
8
8
 
9
9
  <p align="center">
10
10
  <img alt="Python" src="https://img.shields.io/badge/Python-3.10+-blue?logo=python&logoColor=white" />
11
11
  <img alt="License" src="https://img.shields.io/badge/License-MIT-green" />
12
12
  <img alt="Tests" src="https://img.shields.io/badge/Tests-8996%2B%20passing-brightgreen" />
13
- <img alt="Version" src="https://img.shields.io/badge/V4.5.8-success" />
13
+ <img alt="Version" src="https://img.shields.io/badge/V4.5.9-success" />
14
14
  <img alt="CI" src="https://img.shields.io/badge/CI-GitHub_Actions-blue?logo=githubactions" />
15
15
  <img alt="Quality" src="https://img.shields.io/badge/Code%20Quality-4.3%2F5%20%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%86-blue" />
16
16
  <img alt="Security" src="https://img.shields.io/badge/Security-5%2F5%20%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-success" />
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: devsquad
3
- Version: 4.5.8
3
+ Version: 4.5.9
4
4
  Summary: Production-Ready Multi-Role AI Task Orchestrator
5
5
  Author-email: DevSquad Team <devsquad@example.com>
6
6
  License: MIT
@@ -96,14 +96,14 @@ Dynamic: license-file
96
96
  <p align="center">
97
97
  <strong>🎯 把「单个 AI 助手」升级成「7 人 AI 专业团队」</strong>
98
98
  <br>
99
- <em>One task → Multi-role AI collaboration → One conclusion | V4.5.8 (FileRiskStore persistence + risks add/assess/mitigate/close + exposure filters) | V4.5.7 (Coeffect Async + Risk Register UX CLI) | V4.5.6 (Module Fiber + Coeffect: 6-state FSM + topological activation + modules CLI) | V4.5.3 (Artifacts + Effect — ArtifactStore + DispatchEffect + EffectRegistry + Audit CLI) | V4.5.2 (Experience polish: MOKA + Metrics + GitLab + Doctor + BackendConfig) | V4.5.0 (cross-session continuity + protocol-native skills)</em>
99
+ <em>One task → Multi-role AI collaboration → One conclusion | V4.5.9 (Unified Gather Execution Core + Native Async Worker: 执行层统一 gather 化 + Worker 原生异步) | V4.5.8 (FileRiskStore persistence + risks add/assess/mitigate/close + exposure filters) | V4.5.7 (Coeffect Async + Risk Register UX CLI) | V4.5.6 (Module Fiber + Coeffect: 6-state FSM + topological activation + modules CLI) | V4.5.3 (Artifacts + Effect — ArtifactStore + DispatchEffect + EffectRegistry + Audit CLI) | V4.5.2 (Experience polish: MOKA + Metrics + GitLab + Doctor + BackendConfig) | V4.5.0 (cross-session continuity + protocol-native skills)</em>
100
100
  </p>
101
101
 
102
102
  <p align="center">
103
103
  <img alt="Python" src="https://img.shields.io/badge/Python-3.10+-blue?logo=python&logoColor=white" />
104
104
  <img alt="License" src="https://img.shields.io/badge/License-MIT-green" />
105
105
  <img alt="Tests" src="https://img.shields.io/badge/Tests-8996%2B%20passing-brightgreen" />
106
- <img alt="Version" src="https://img.shields.io/badge/V4.5.8-success" />
106
+ <img alt="Version" src="https://img.shields.io/badge/V4.5.9-success" />
107
107
  <img alt="CI" src="https://img.shields.io/badge/CI-GitHub_Actions-blue?logo=githubactions" />
108
108
  <img alt="Quality" src="https://img.shields.io/badge/Code%20Quality-4.3%2F5%20%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%86-blue" />
109
109
  <img alt="Security" src="https://img.shields.io/badge/Security-5%2F5%20%E2%98%85%E2%98%85%E2%98%85%E2%98%85%E2%98%85-success" />
@@ -144,6 +144,7 @@ scripts/collaboration/file_bundler.py
144
144
  scripts/collaboration/file_risk_store.py
145
145
  scripts/collaboration/five_axis_consensus.py
146
146
  scripts/collaboration/gap_analyzer.py
147
+ scripts/collaboration/gather_core.py
147
148
  scripts/collaboration/gitlab_connector.py
148
149
  scripts/collaboration/host_llm_bridge.py
149
150
  scripts/collaboration/host_llm_bridge_v2.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devsquad"
7
- version = "4.5.8"
7
+ version = "4.5.9"
8
8
  description = "Production-Ready Multi-Role AI Task Orchestrator"
9
9
  readme = "README.md"
10
10
  license = {text = "MIT"}
@@ -13,6 +13,8 @@ Endpoints:
13
13
 
14
14
  from __future__ import annotations
15
15
 
16
+ import asyncio
17
+ import functools
16
18
  import logging
17
19
  import os
18
20
  import sys
@@ -216,11 +218,19 @@ async def dispatch_task(
216
218
  logger.warning("Failed to create LLM backend '%s': %s, using default", request.backend, backend_err)
217
219
  pass
218
220
 
219
- result = dispatcher.dispatch(
220
- task_description=request.task,
221
- roles=request.roles,
222
- mode=request.mode,
223
- dry_run=request.dry_run,
221
+ # V4.5.9: dispatch() is synchronous and its Coordinator raises
222
+ # RuntimeError inside a running event loop (fail-fast sync bridge,
223
+ # see PRD V4.5.9 R3). Move the blocking call off the event loop.
224
+ loop = asyncio.get_running_loop()
225
+ result = await loop.run_in_executor(
226
+ None,
227
+ functools.partial(
228
+ dispatcher.dispatch,
229
+ task_description=request.task,
230
+ roles=request.roles,
231
+ mode=request.mode,
232
+ dry_run=request.dry_run,
233
+ ),
224
234
  )
225
235
 
226
236
  response_data = _convert_dispatch_result(result)
@@ -25,6 +25,9 @@ V4.5.8: Extended to include:
25
25
  - FileRiskStore (file-backed risk persistence)
26
26
  - CliRisks mutators (add/mitigate/close/list --min-exposure)
27
27
 
28
+ V4.5.9: Extended to include:
29
+ - GatherCore (shared asyncio.gather execution core, _call_counter_gather)
30
+
28
31
  Usage:
29
32
  python3 scripts/check_module_activation.py
30
33
  CI: python3 scripts/check_module_activation.py || exit 1
@@ -177,12 +180,20 @@ def main() -> int:
177
180
  get_call_counter_er as _get_file_risk_store_counter_er,
178
181
  )
179
182
 
183
+ # V4.5.9 modules — touch counters in main scope
184
+ from scripts.collaboration.gather_core import (
185
+ get_call_counter_gather as _get_gather_counter,
186
+ )
187
+
180
188
  # V4.5.7 P12.5 activation (2 new modules)
181
189
  _activate_v457_modules()
182
190
 
183
191
  # V4.5.8 activation (FileRiskStore + CliRisks mutators)
184
192
  _activate_v458_modules()
185
193
 
194
+ # V4.5.9 activation (GatherCore — shared asyncio.gather execution core)
195
+ _activate_v459_modules()
196
+
186
197
  counters = {
187
198
  "TaskScaleGate": tsg(),
188
199
  "PerfBaseline": pb(),
@@ -212,9 +223,11 @@ def main() -> int:
212
223
  # V4.5.8 modules
213
224
  "FileRiskStore_V458.1": _get_file_risk_store_counter_er(),
214
225
  "CliRisksMutators_V458.2": _get_cli_risks_counter_er(),
226
+ # V4.5.9 modules
227
+ "GatherCore_V459.1": _get_gather_counter(),
215
228
  }
216
229
 
217
- print("V4.5.8 Anti-Ghost Verification")
230
+ print("V4.5.9 Anti-Ghost Verification")
218
231
  print("=" * 60)
219
232
  failed = []
220
233
  for name, count in counters.items():
@@ -230,10 +243,34 @@ def main() -> int:
230
243
  print(f" - {name}")
231
244
  return 1
232
245
 
233
- print("All V4.5.8 modules activated. Anti-ghost gate PASSED.")
246
+ print("All V4.5.9 modules activated. Anti-ghost gate PASSED.")
234
247
  return 0
235
248
 
236
249
 
250
+ def _activate_v459_modules() -> None:
251
+ """Exercise the V4.5.9 gather core to bump its anti-ghost counter.
252
+
253
+ Runs one minimal execute_batch_gather() batch — the same entry point a
254
+ parallel dispatch hits — so ``_call_counter_gather`` reflects real usage.
255
+ """
256
+ import asyncio
257
+
258
+ from scripts.collaboration.gather_core import execute_batch_gather
259
+ from scripts.collaboration.models import TaskDefinition, WorkerResult
260
+
261
+ async def _run_one(task: TaskDefinition) -> WorkerResult:
262
+ return WorkerResult(worker_id="anti-ghost", task_id=task.task_id, success=True)
263
+
264
+ async def _drive() -> list[WorkerResult]:
265
+ return await execute_batch_gather(
266
+ [TaskDefinition(description="anti-ghost check", role_id="architect")],
267
+ _run_one,
268
+ 1,
269
+ )
270
+
271
+ asyncio.run(_drive())
272
+
273
+
237
274
  def _activate_v458_modules() -> None:
238
275
  """Exercise V4.5.8 modules to bump their anti-ghost counters.
239
276
 
@@ -0,0 +1 @@
1
+ __version__ = "4.5.9"
@@ -37,6 +37,7 @@ from .context_compressor import (
37
37
  Message,
38
38
  MessageType,
39
39
  )
40
+ from .gather_core import execute_batch_gather
40
41
  from .models import (
41
42
  BatchMode,
42
43
  ConsensusRecord,
@@ -75,6 +76,11 @@ class AsyncWorkerWrapper:
75
76
  """
76
77
  Execute worker task asynchronously with optional timeout.
77
78
 
79
+ V4.5.9 (AC-W4): when the wrapped Worker exposes ``aexecute`` (async
80
+ backends run natively inside it, sync backends bridge internally),
81
+ await it directly — no thread bridge at this layer. Otherwise fall
82
+ back to the legacy run_in_executor bridge.
83
+
78
84
  Args:
79
85
  task: Task definition to execute.
80
86
 
@@ -84,19 +90,15 @@ class AsyncWorkerWrapper:
84
90
  Raises:
85
91
  asyncio.TimeoutError: If task exceeds timeout.
86
92
  """
87
- loop = asyncio.get_event_loop()
93
+ if hasattr(self.worker, "aexecute"):
94
+ coro = self.worker.aexecute(task)
95
+ else:
96
+ loop = asyncio.get_event_loop()
97
+ coro = loop.run_in_executor(None, self.worker.execute, task)
88
98
 
89
99
  if self.timeout:
90
-
91
- async def _execute_with_timeout() -> WorkerResult:
92
- return await asyncio.wait_for(
93
- loop.run_in_executor(None, self.worker.execute, task),
94
- timeout=self.timeout,
95
- )
96
-
97
- return await _execute_with_timeout()
98
- else:
99
- return await loop.run_in_executor(None, self.worker.execute, task)
100
+ return await asyncio.wait_for(coro, timeout=self.timeout)
101
+ return await coro
100
102
 
101
103
 
102
104
  class AsyncCoordinator:
@@ -425,20 +427,20 @@ class AsyncCoordinator:
425
427
 
426
428
  async def _execute_parallel_async(self, batch: TaskBatch) -> list[WorkerResult]:
427
429
  """
428
- Execute tasks in parallel using asyncio.gather.
429
-
430
- Key advantage over ThreadPoolExecutor:
431
- - No thread creation/destruction overhead
432
- - Single event loop context switching
433
- - Better memory efficiency
434
- - Natural integration with async backends
430
+ Execute tasks in parallel via the shared gather core (V4.5.9).
431
+
432
+ The gather mechanism (Semaphore cap, return_exceptions=True so one
433
+ Worker failure never discards sibling results, BaseException defense,
434
+ submission-order results) lives in ``gather_core.execute_batch_gather``
435
+ — the single source of truth shared with the sync Coordinator. The
436
+ per-task shell (worker routing, briefing, timeout/retry, per-task
437
+ Exception isolation) stays in ``_execute_with_semaphore`` below.
435
438
  """
436
439
  semaphore = await self._get_semaphore()
437
- results: list[WorkerResult] = []
438
440
  max_workers = min(batch.max_concurrency or len(batch.tasks), len(batch.tasks))
439
441
 
440
442
  if max_workers <= 0:
441
- return results
443
+ return []
442
444
 
443
445
  async def _execute_with_semaphore(
444
446
  task: TaskDefinition,
@@ -487,30 +489,12 @@ class AsyncCoordinator:
487
489
  error=str(e),
488
490
  )
489
491
 
490
- tasks = [_execute_with_semaphore(task) for task in batch.tasks]
491
- # P0-2 (V4.1.2): return_exceptions=True so one Worker failure does not
492
- # discard the results of all other parallel Workers. The per-task
493
- # _execute_with_semaphore already wraps exceptions into WorkerResult,
494
- # but return_exceptions=True is the defensive belt-and-suspenders.
495
- raw_results = await asyncio.gather(*tasks, return_exceptions=True)
496
- results = []
497
- for r in raw_results:
498
- if isinstance(r, BaseException):
499
- # Defensive: should rarely hit because _execute_with_semaphore
500
- # catches Exception, but KeyboardInterrupt/SystemExit could propagate.
501
- logger.error(
502
- "Worker raised unexpected exception in async gather: %s", r, exc_info=r
503
- )
504
- results.append(
505
- WorkerResult(
506
- worker_id="<unknown>",
507
- task_id="<unknown>",
508
- success=False,
509
- error=f"Unexpected exception: {r!r}",
510
- )
511
- )
512
- else:
513
- results.append(r)
492
+ results = await execute_batch_gather(batch.tasks, _execute_with_semaphore, max_workers)
493
+
494
+ # V4.5.9 (DESIGN §6): user-visible evidence of the gather executor.
495
+ for r in results:
496
+ if isinstance(r.output, dict):
497
+ r.output["executor"] = "gather"
514
498
 
515
499
  return results
516
500
 
@@ -14,15 +14,16 @@ Core component for multi-Worker collaboration:
14
14
 
15
15
  from __future__ import annotations
16
16
 
17
+ import asyncio
17
18
  import logging
18
19
  import re
19
20
  import time
20
21
  import uuid
21
- from concurrent.futures import ThreadPoolExecutor, as_completed
22
22
  from typing import TYPE_CHECKING, Any
23
23
 
24
24
  from .consensus import ConsensusEngine
25
25
  from .context_compressor import CompressedContext, CompressionLevel, ContextCompressor, Message, MessageType
26
+ from .gather_core import execute_batch_gather
26
27
  from .models import (
27
28
  BatchMode,
28
29
  ConsensusRecord,
@@ -90,7 +91,6 @@ class Coordinator:
90
91
  "consensus",
91
92
  "workers",
92
93
  "_worker_index",
93
- "_executor",
94
94
  "_execution_history",
95
95
  "coordinator_id",
96
96
  "enable_compression",
@@ -159,10 +159,10 @@ class Coordinator:
159
159
  self.consensus = ConsensusEngine()
160
160
  self.workers: dict[str, Worker] = {}
161
161
  self._worker_index: dict[str, Worker] = {}
162
- # P2-4 (V4.1.2): max_workers aligned with max_roles=10 (.devsquad.yaml)
163
- # so the pool can accommodate up to 10 parallel Workers when needed.
164
- # Previously hardcoded to 7, which undersized the pool when max_roles=10.
165
- self._executor = ThreadPoolExecutor(max_workers=10)
162
+ # V4.5.9: ThreadPoolExecutor removed — parallel batches execute through
163
+ # the shared asyncio.gather core (gather_core.execute_batch_gather)
164
+ # via the sync bridge in _execute_parallel. The thread bridge now only
165
+ # exists at the sync-Worker boundary (AC-C6).
166
166
  self._execution_history: list[dict[str, Any]] = []
167
167
  self.coordinator_id = f"coord-{uuid.uuid4().hex[:8]}"
168
168
  self.enable_compression = enable_compression
@@ -716,30 +716,73 @@ class Coordinator:
716
716
  return results, errors
717
717
 
718
718
  def _execute_parallel(self, batch: TaskBatch) -> list[WorkerResult]:
719
- results: list[WorkerResult] = []
719
+ """Execute a PARALLEL batch through the shared gather core (V4.5.9, AC-C1).
720
+
721
+ Sync bridge (AC-C4): safe to call without a running event loop (enters
722
+ via ``asyncio.run``); raises an informative RuntimeError when a loop is
723
+ already running — use AsyncCoordinator / async_dispatch instead
724
+ (L-V457-002 pattern).
725
+
726
+ Semantics preserved from the legacy thread-pool implementation:
727
+ - tasks without a matching Worker are dropped (no result);
728
+ - a Worker failure yields ``WorkerResult(worker_id="unknown", ...)``
729
+ without losing the sibling results (AC-C3);
730
+ - concurrency is capped by ``asyncio.Semaphore(max_concurrency)`` (AC-C5);
731
+ - results keep submission order (new contract, PRD V4.5.9 R1).
732
+ """
733
+ try:
734
+ asyncio.get_running_loop()
735
+ except RuntimeError:
736
+ pass
737
+ else:
738
+ raise RuntimeError(
739
+ "Coordinator._execute_parallel cannot run inside a running event loop; "
740
+ "use AsyncCoordinator / async_dispatch in async context."
741
+ )
720
742
  max_workers = min(batch.max_concurrency or len(batch.tasks), len(batch.tasks))
721
- if max_workers <= 0:
722
- return results
723
- futures = {}
724
- for task in batch.tasks:
743
+ if max_workers <= 0 or not batch.tasks:
744
+ return []
745
+ results = asyncio.run(self._aexecute_parallel(batch, max_workers))
746
+ # V4.5.9 (DESIGN §6): user-visible evidence of the gather executor.
747
+ for r in results:
748
+ if isinstance(r.output, dict):
749
+ r.output["executor"] = "gather"
750
+ return results
751
+
752
+ async def _aexecute_parallel(self, batch: TaskBatch, max_workers: int) -> list[WorkerResult]:
753
+ """Async half of the sync bridge — runs inside ``asyncio.run()``."""
754
+ loop = asyncio.get_running_loop()
755
+
756
+ async def run_one(task: TaskDefinition) -> WorkerResult:
725
757
  worker = self._get_worker_for_task(task)
726
- if worker:
727
- future = self._executor.submit(worker.execute, task)
728
- futures[future] = task.task_id
729
- for future in as_completed(futures):
758
+ if worker is None: # unreachable: batch is pre-filtered below
759
+ return WorkerResult(
760
+ worker_id="unknown",
761
+ task_id=task.task_id,
762
+ success=False,
763
+ error="No worker found for task",
764
+ )
730
765
  try:
731
- results.append(future.result())
766
+ if hasattr(worker, "aexecute"):
767
+ # 真异步入口:async 后端原生 await;sync 后端在 aexecute
768
+ # 内部经 run_in_executor 桥接(AC-C6/W2/W3)。
769
+ return await worker.aexecute(task)
770
+ return await loop.run_in_executor(None, worker.execute, task)
732
771
  except Exception as e:
733
- # Broad catch: wraps arbitrary worker execution in thread pool
734
- results.append(
735
- WorkerResult(
736
- worker_id="unknown",
737
- task_id=futures[future],
738
- success=False,
739
- error=str(e),
740
- )
772
+ # Broad catch: wraps arbitrary worker execution; per-task
773
+ # isolation aligned with the legacy thread-pool
774
+ # future.result() -> worker_id="unknown" path (AC-C3).
775
+ return WorkerResult(
776
+ worker_id="unknown",
777
+ task_id=task.task_id,
778
+ success=False,
779
+ error=str(e),
741
780
  )
742
- return results
781
+
782
+ # Legacy thread-pool semantics: tasks without a matching Worker were
783
+ # never submitted (dropped silently) — preserve that behavior (AC-C2).
784
+ tasks = [t for t in batch.tasks if self._get_worker_for_task(t) is not None]
785
+ return await execute_batch_gather(tasks, run_one, max_workers)
743
786
 
744
787
  def _inject_briefing_to_worker(self, worker: Any) -> None:
745
788
  """Inject compressed briefing from preceding Agents into the next Worker."""
@@ -1025,7 +1068,3 @@ class Coordinator:
1025
1068
  duration: Any = self._execution_history[-1]["result"]["duration"]
1026
1069
  return float(duration)
1027
1070
  return 0.0
1028
-
1029
- def __del__(self) -> None:
1030
- if hasattr(self, "_executor"):
1031
- self._executor.shutdown(wait=False)
@@ -687,6 +687,8 @@ class PostDispatchPipeline(
687
687
  if r.output
688
688
  else None,
689
689
  "error": r.error,
690
+ # V4.5.9 (DESIGN §6): user-visible gather-executor evidence.
691
+ "executor": (r.output.get("executor", "gather") if isinstance(r.output, dict) else "gather"),
690
692
  }
691
693
  )
692
694
  step7_time = time.time()
@@ -0,0 +1,118 @@
1
+ #!/usr/bin/env python3
2
+ """Shared asyncio.gather execution core (V4.5.9).
3
+
4
+ Single source of truth for parallel batch execution. Both the sync
5
+ Coordinator (via the asyncio.run bridge in ``_execute_parallel``) and the
6
+ AsyncCoordinator (native) delegate here. Do NOT reimplement gather
7
+ semantics elsewhere.
8
+
9
+ Semantics (the single implementation):
10
+ 1. ``asyncio.Semaphore(max_concurrency)`` caps in-flight tasks (AC-C5).
11
+ 2. ``asyncio.gather(..., return_exceptions=True)`` — a single Worker failure
12
+ never discards the results of the other parallel Workers (hard constraint).
13
+ 3. BaseException defense — KeyboardInterrupt/SystemExit (or any exception that
14
+ escapes ``run_one``) is converted into a failure ``WorkerResult`` instead of
15
+ unwinding the whole batch.
16
+ 4. Results keep submission order (``tasks`` order) — a deliberate behavior
17
+ change from the legacy completion-order thread pool (PRD V4.5.9 R1, logged).
18
+
19
+ ``run_one`` is the per-task callback injected by the calling Coordinator: it
20
+ owns worker routing, briefing, timeout and retry, and is expected to catch
21
+ per-task ``Exception`` itself (translating them into ``WorkerResult``). This
22
+ core only owns the gather mechanism — keeping it small is a design constraint.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import asyncio
28
+ import logging
29
+ from collections.abc import Awaitable, Callable
30
+
31
+ from .models import TaskDefinition, WorkerResult
32
+
33
+ logger = logging.getLogger(__name__)
34
+
35
+ # V4.5.9 anti-ghost counter: bumped once per execute_batch_gather() entry.
36
+ # Verified by scripts/check_module_activation.py (GatherCore_V459.1).
37
+ _call_counter_gather = 0
38
+
39
+
40
+ def _inc_call_counter_gather() -> None:
41
+ """Bump the module-level anti-ghost counter."""
42
+ global _call_counter_gather
43
+ _call_counter_gather += 1
44
+
45
+
46
+ def get_call_counter_gather() -> int:
47
+ """Return the current anti-ghost counter value."""
48
+ return _call_counter_gather
49
+
50
+
51
+ async def execute_batch_gather(
52
+ tasks: list[TaskDefinition],
53
+ run_one: Callable[[TaskDefinition], Awaitable[WorkerResult]],
54
+ max_concurrency: int,
55
+ ) -> list[WorkerResult]:
56
+ """Execute ``tasks`` concurrently through ``run_one`` under a semaphore.
57
+
58
+ Args:
59
+ tasks: Task definitions in submission order.
60
+ run_one: Per-task coroutine factory injected by the calling
61
+ Coordinator (routes to ``Worker.aexecute`` or a sync bridge).
62
+ max_concurrency: Semaphore cap on in-flight tasks. Non-positive
63
+ values are treated as unbounded (clamped to ``len(tasks)``).
64
+
65
+ Returns:
66
+ WorkerResult list in submission order; never shorter than ``tasks``.
67
+ """
68
+ _inc_call_counter_gather()
69
+ if not tasks:
70
+ return []
71
+
72
+ limit = max_concurrency if max_concurrency and max_concurrency > 0 else len(tasks)
73
+ semaphore = asyncio.Semaphore(limit)
74
+
75
+ async def _run_one_limited(task: TaskDefinition) -> WorkerResult:
76
+ async with semaphore:
77
+ try:
78
+ return await run_one(task)
79
+ except asyncio.CancelledError:
80
+ raise
81
+ except BaseException as e:
82
+ # BaseException defense (AC-C1 hard constraint). Since Python
83
+ # 3.8 (bpo-32528) gather(return_exceptions=True) does NOT
84
+ # capture KeyboardInterrupt/SystemExit raised inside a child —
85
+ # they would unwind the whole batch. Convert any escaped
86
+ # exception into a failure WorkerResult so one Worker can
87
+ # never discard the sibling results.
88
+ logger.error("Worker raised unexpected exception in gather: %s", e, exc_info=e)
89
+ return WorkerResult(
90
+ worker_id="<unknown>",
91
+ task_id="<unknown>",
92
+ success=False,
93
+ error=f"Unexpected exception: {e!r}",
94
+ )
95
+
96
+ raw_results = await asyncio.gather(
97
+ *(_run_one_limited(t) for t in tasks),
98
+ return_exceptions=True,
99
+ )
100
+
101
+ results: list[WorkerResult] = []
102
+ for r in raw_results:
103
+ if isinstance(r, BaseException):
104
+ # Belt-and-suspenders: should be unreachable because
105
+ # _run_one_limited converts escaped exceptions, but a defensive
106
+ # conversion keeps the result list pure WorkerResult.
107
+ logger.error("Worker raised unexpected exception in gather: %s", r, exc_info=r)
108
+ results.append(
109
+ WorkerResult(
110
+ worker_id="<unknown>",
111
+ task_id="<unknown>",
112
+ success=False,
113
+ error=f"Unexpected exception: {r!r}",
114
+ )
115
+ )
116
+ else:
117
+ results.append(r)
118
+ return results