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.
- {devsquad-4.5.8 → devsquad-4.5.9}/PKG-INFO +3 -3
- {devsquad-4.5.8 → devsquad-4.5.9}/README.md +2 -2
- {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/PKG-INFO +3 -3
- {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/SOURCES.txt +1 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/pyproject.toml +1 -1
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/dispatch.py +15 -5
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_module_activation.py +39 -2
- devsquad-4.5.9/scripts/collaboration/_version.py +1 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/async_coordinator.py +28 -44
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/coordinator.py +68 -29
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps.py +2 -0
- devsquad-4.5.9/scripts/collaboration/gather_core.py +118 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/worker.py +219 -104
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/__init__.py +1 -1
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_performance_benchmarks.py +21 -7
- devsquad-4.5.8/scripts/collaboration/_version.py +0 -1
- {devsquad-4.5.8 → devsquad-4.5.9}/LICENSE +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/dependency_links.txt +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/entry_points.txt +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/requires.txt +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/devsquad.egg-info/top_level.txt +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/models.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/rate_limit.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/lifecycle.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/metrics.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/routes/metrics_gates.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api/security.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/api_server.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/auth.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/benchmark_async_dispatch.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/benchmark_ponytail_smart.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/benchmark_real_llm.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_async_coverage.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_config_consistency.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_constructor_params.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_dependency_lock.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_dependency_sync.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_doc_consistency.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_hidden_content.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_test_pyramid.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_test_quality.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/check_version_consistency.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli/cli_visual.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_audit.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_backend.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_dispatch.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_doctor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_lifecycle.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_metrics.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_modules.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_risks.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_sessions.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/cli_utils.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/adaptive_role_selector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/adversarial_verify.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/agent_briefing.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/agent_identity.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ai_semantic_matcher.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/anchor_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/anti_rationalization.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/approval_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/artifact_store.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/async_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/async_coeffect_resolver.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/async_llm_backend.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/audit_logger.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/git_driver.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/loop_controller.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/notes_memory.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/run_state.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/sleep_guard.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/autonomous/smart_confirmation.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/backend_config.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/backend_paths.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/batch_scheduler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/benchmark_regression_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/cache_interface.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ccr_store.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/checkpoint_manager.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ci_feedback_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/cli_command_classifier.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/code_graph_query.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/code_graph_storage.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/code_knowledge_graph.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/code_map_generator.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/coeffect.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/concern_pack_loader.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/confidence_score.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/config_manager.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/connector_framework.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/consensus.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/consensus_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/constants.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/content_cache.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/content_crusher.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/context_compressor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dashboard_live_mode.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/debt_collector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dependency_hallucination_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/deployment_compliance_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_audit.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_component_factory.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_effect.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_hooks.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_lifecycle.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_models.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_performance.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_pre_steps.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_rbac.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_result_assembler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_services.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_consensus_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_feedback_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_mixins.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_quality_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatch_steps_services_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_async_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_audit_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_config.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_error_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_factory.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_intent_mapper.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_lifecycle_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_loop_controller.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_mixins.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_status_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_transaction.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dispatcher_utils_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dora_metrics_collector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/dual_layer_context.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/effect_registry.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/enhanced_worker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/enterprise_feature.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/error_budget_tracker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/event_bus.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/execution_guard.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/feature_usage_tracker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/feedback_control_loop.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/file_bundler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/file_risk_store.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/five_axis_consensus.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/gap_analyzer.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/gitlab_connector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/host_llm_bridge.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/host_llm_bridge_v2.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/input_validator.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/intent_workflow_mapper.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/judge_agent.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/language_parsers.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/learned_rule_store.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_protocol.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_shortcut_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_shortcut_helpers.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/lifecycle_templates.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_backend.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_cache.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_cache_async.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_cache_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_retry.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_retry_async.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/llm_retry_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/discovery_probe.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/handoff_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/independent_evaluator.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/kernel.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/loop_scheduler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/models.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/protocols.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/rollback_strategy.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/loop_engineering/unified_memory.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/mce_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_bridge.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_claw_source.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_forgetting.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_index.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_query.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_serializer.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/memory_types.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/meta_skill_layering.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/micro_task_planner.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/models.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/models_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/models_dispatch.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/models_lifecycle.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/module_fiber.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/moka_backend.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/multi_host_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/multi_level_cache.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/multi_tenant.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/null_providers.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/operation_classifier.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/order_chain_detector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/output_slicer.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/output_validator.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/perf_baseline.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/performance_fingerprint.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/performance_monitor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/permission_guard.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/plugins/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/plugins/hot_loader.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ponytail_rule_injector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prometheus_metrics.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_formatting_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_mixins.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_substitution_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_template_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_assembler_validation_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/prompt_dials.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/protocols.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/quality_calibration_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/quality_probe_slice.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/rbac_engine.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/redesign_auditor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/redesign_checkers.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/redis_cache.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/report_formatter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/requirement_tracer.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/retrospective.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/review_checkers.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/risk_register.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/role_matcher.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/role_skill_loader.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/role_specific_mock_backend.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/rule_collector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/scratchpad.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/scratchpad_history_store.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/secret_patterns.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/severity_router.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/similar_task_recommender.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_extractor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_provider_builtin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_provider_mcp.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_registry.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skill_storage.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/skillifier.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/standardized_role_template.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/task_completion_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/task_scale_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/tech_debt_manager.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/test_quality_guard.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/todo_drift_monitor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/two_stage_review_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_accessibility_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_framework.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_framework_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_heuristic_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_journey_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_mixins.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/ue_test_persona_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/unified_gate_engine.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/usage_tracker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/user_friendly_error.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/verification_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/viewpoint_registry.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/warmup_manager.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_lifecycle_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_mixins.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_persistence_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_state_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/workflow_engine_transition_mixin.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collaboration/yagni_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/collect_baseline.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/app.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/auth_views.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/components.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/dag_views.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/dispatch_views.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/i18n.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/lifecycle_views.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/metrics_views.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/state.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard/v43_panels.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/dashboard.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/generate_benchmark_report.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/generate_quality_decision_report.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/history_manager.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/mcp_server.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/deterministic_rule_engine.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/models.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/taste_dials.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/uiux_analyzer.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/uiux_subitems.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/qa/visual_regression.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/scan_pickle_payloads.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/utils/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/scripts/utils/_find_missing_hints.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/setup.cfg +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/_version.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/dispatch/handler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/intent/handler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/prototype/handler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/registry.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/retrospective/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/retrospective/handler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/review/handler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/security/handler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/teach/handler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/test/__init__.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/skills/test/handler.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_4pt_grid.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_adaptive_role_selector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_adversarial_verify.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_agent_briefing.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_anchor_retrospective.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_anti_rationalization.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_antipattern_bans.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_api_budget_status_endpoint.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_api_security.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_api_server_v362.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_approval_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_artifact_effect_binding.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_artifact_store.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_async_coordinator.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_async_modules.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_audit_logger.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_auth_phase5.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_autonomous.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_backend_config.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_benchmark_ponytail_smart.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cache_interface.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_ccr_store.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_async_coverage.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_config_consistency.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_constructor_params.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_dependency_lock.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_hidden_content.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_test_pyramid.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_test_quality.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_check_version_consistency.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_ci_feedback_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_audit.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_command_classifier.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_deep_v362.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_doctor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_lifecycle.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_metrics.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_cli_phase5.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_code_knowledge_graph.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_claw_integration_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_context_compressor_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_core_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_dispatcher_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_dispatcher_ux_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_e2e_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_enhanced_e2e_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_llm_cache_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_llm_retry_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_mce_adapter_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_memory_bridge_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_performance_monitor_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_permission_guard_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_prompt_optimization_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_role_mapping_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_skillifier_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_test_quality_guard.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_test_quality_guard_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_upstream_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_collaboration_warmup_manager_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_confidence_score.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_config_injection.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_consensus_dissent.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_consensus_fatigue.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_consensus_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_content_cache.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_content_crusher.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_coordinator_smart_compression.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dag_views.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dashboard_live_mode.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dashboard_split.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dashboard_ui_e2e.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dashboard_v43_panels.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_data_backup.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_debt_collector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_deep_shallow.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_deletion_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dependency_hallucination_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dependency_lock.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_deployment_compliance_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_deterministic_rule_engine.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatch_audit.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatch_performance.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatch_rbac.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatch_steps.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_intent_mapper.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_loop_controller.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_mixins.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_phase5_core.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dispatcher_transaction.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_docker_deployment.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_dual_layer_context.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_effect_registry.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_enhanced_worker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_fallback_fuse.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_feedback_control_loop.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_five_axis_consensus.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_flow_standalone.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_full_lifecycle_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_git_guardrails.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_gitlab_connector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_glossary_loader.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_grilling_mode.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_handoff_redaction.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_history_manager_v362.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_host_bridge_unit.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_host_llm_bridge_v2.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_input_validator_phase5.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_input_validator_sensitive.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_intent_workflow_mapper.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_judge_agent.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_learned_rule_phase4.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_lifecycle_protocol.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_llm_auto_fallback.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_llm_backend_resolve.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_llm_cache_protocol.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_loop_engineering.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_loop_engineering_rollback.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_mcp_server_v362.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_memory_benchmarks.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_meta_skill_layering.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_micro_task_planner.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_moka_backend.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_multi_host_adapter.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_multi_tenant.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_multi_tenant_isolation_e2e.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_no_op_test.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_node_type_separation.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_null_providers.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_oklch_color.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_operation_classifier.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_order_chain_detector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_output_slicer.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_output_validator_prompt_injection.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_perf_baseline.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_perf_baseline_ci_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_performance_fingerprint.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_performance_monitor_protocol.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_permission_guard_human_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_permission_guard_phase5.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_phase4_ghost_feature_defense.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_pipeline_step19_20.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_plan_c_unified_architecture.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_plugins_hot_loader.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_ponytail_rule_injector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_production_features.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_prometheus_metrics.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_prompt_dials.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_protocols.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_prototype_skill.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_qa_uiux_visual_regression.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_quick_bonus.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rate_limit.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rbac_engine.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rbac_fail_closed.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_red_capable_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_redesign_auditor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_redis_cache.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_requirement_tracer.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_retry_jitter_strategies.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_role_skill_loader.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rule_collector.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_rule_injection_security.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_secret_patterns.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_severity_router.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_similar_task_recommender.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_skill_registry_coverage.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_skill_security.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_sleep_guard.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_standardized_role_template.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_start_script.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_step_node_types.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_suggested_next_steps.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_task_completion_checker.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_task_scale_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_taste_dials.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_tautological_seams.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_teach_skill.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_tech_debt_manager.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_todo_drift_monitor.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_token_budget_compressed_scratchpad.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_triage_label.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_two_stage_review_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_ue_test_framework.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_uiux_subitems.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_usage_tracker_coverage.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_v39_e2e.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_v39_performance.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_v411_security_hardening.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_verification_gate.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_version.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_vertical_slice.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_worker_artifact_integration.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine_base.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine_lifecycle.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine_state.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_engine_transition.py +0 -0
- {devsquad-4.5.8 → devsquad-4.5.9}/tests/test_workflow_persistence_coverage.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
@@ -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
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
-
|
|
433
|
-
|
|
434
|
-
-
|
|
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
|
|
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
|
-
|
|
491
|
-
|
|
492
|
-
#
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
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
|
-
#
|
|
163
|
-
#
|
|
164
|
-
#
|
|
165
|
-
|
|
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
|
-
|
|
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
|
|
723
|
-
|
|
724
|
-
|
|
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
|
-
|
|
728
|
-
|
|
729
|
-
|
|
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
|
-
|
|
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
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
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
|
-
|
|
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
|