claude-code-conductor 2.42.0__tar.gz → 2.43.0__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 (209) hide show
  1. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/breaking-changes.txt +1 -0
  2. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/select_tier.py +4 -4
  3. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/SKILL.md +12 -0
  4. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/scripts/record_agent_outcome.py +8 -16
  5. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/CHANGELOG.md +23 -0
  6. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/PKG-INFO +1 -1
  7. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/__init__.py +1 -1
  8. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/_db_params.py +31 -0
  9. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli_tier.py +3 -4
  10. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/db.py +67 -219
  11. claude_code_conductor-2.43.0/src/c3/migrations/005_drop_agent_tier_bandit.sql +18 -0
  12. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_record_agent_outcome.py +267 -8
  13. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_select_tier_escalation.py +48 -31
  14. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_session_start.py +5 -1
  15. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_session_stop.py +16 -26
  16. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_tier.py +41 -26
  17. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_db.py +497 -309
  18. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_migrate.py +181 -6
  19. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/CLAUDE.md +0 -0
  20. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/architect.md +0 -0
  21. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/code-reviewer.md +0 -0
  22. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/design-critic.md +0 -0
  23. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/developer.md +0 -0
  24. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/doc-writer.md +0 -0
  25. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/interviewer.md +0 -0
  26. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/planner.md +0 -0
  27. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/project-setup.md +0 -0
  28. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/security-reviewer.md +0 -0
  29. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/systematic-debugger.md +0 -0
  30. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/tester.md +0 -0
  31. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/wt_developer.md +0 -0
  32. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/wt_systematic-debugger.md +0 -0
  33. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/agents/wt_tester.md +0 -0
  34. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/deletions.txt +0 -0
  35. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/docs/config-policy.md +0 -0
  36. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/docs/parallel-agents-setup.md +0 -0
  37. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/docs/platform-adapters.md +0 -0
  38. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/docs/settings.json.md +0 -0
  39. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/_hook_utils.py +0 -0
  40. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/check_agent_invocation.py +0 -0
  41. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/consolidate_memory.py +0 -0
  42. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/permission_handler.py +0 -0
  43. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/permission_handler_toast.py +0 -0
  44. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/planner_check.py +0 -0
  45. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/post_tool.py +0 -0
  46. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/pre_compact.py +0 -0
  47. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/pre_tool.py +0 -0
  48. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/recall_autorebuild.py +0 -0
  49. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/recall_inject.py +0 -0
  50. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/restore_session.py +0 -0
  51. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/session_start.py +0 -0
  52. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/session_stop.py +0 -0
  53. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/session_utils.py +0 -0
  54. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/statusline.py +0 -0
  55. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/stop.py +0 -0
  56. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/hooks/worktree_guard.py +0 -0
  57. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/memory/.gitkeep +0 -0
  58. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/permission_rules.json +0 -0
  59. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/rules/promoted/index.md +0 -0
  60. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/settings.json +0 -0
  61. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/brainstorm/SKILL.md +0 -0
  62. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/codex-review/SKILL.md +0 -0
  63. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/references/code-review-checklist.md +0 -0
  64. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/references/design-critic-rubric.md +0 -0
  65. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/references/design-rubric.md +0 -0
  66. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/references/interview-rubric.md +0 -0
  67. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/references/plan-design-guidelines.md +0 -0
  68. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/references/security-review-checklist.md +0 -0
  69. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/scripts/record_review_decision.py +0 -0
  70. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/dev-workflow/scripts/review_hint_inject.py +0 -0
  71. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/develop/SKILL.md +0 -0
  72. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/doc/SKILL.md +0 -0
  73. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/extract-lib/SKILL.md +0 -0
  74. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/init-session/SKILL.md +0 -0
  75. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/init-session/scripts/session_guard.py +0 -0
  76. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/mcp-config/SKILL.md +0 -0
  77. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/parallel-agents/SKILL.md +0 -0
  78. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/pattern-status/SKILL.md +0 -0
  79. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/promote-pattern/SKILL.md +0 -0
  80. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/recall/SKILL.md +0 -0
  81. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/report-timestamp/SKILL.md +0 -0
  82. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/report-timestamp/scripts/get_timestamp.py +0 -0
  83. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/review-phase/SKILL.md +0 -0
  84. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/setup/SKILL.md +0 -0
  85. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/setup/reference.md +0 -0
  86. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/setup/templates/coding-standards-template.md +0 -0
  87. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/setup/templates/project-conventions-template.md +0 -0
  88. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/skills/start/SKILL.md +0 -0
  89. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.claude/state/.gitkeep +0 -0
  90. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/.gitignore +0 -0
  91. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/ARCHITECTURE.md +0 -0
  92. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/LICENSE +0 -0
  93. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/LICENSES/fastembed-LICENSE +0 -0
  94. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/LICENSES/fastembed-NOTICE +0 -0
  95. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/LICENSES/numpy-LICENSE +0 -0
  96. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/LICENSES/onnxruntime-LICENSE +0 -0
  97. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/LICENSES/paraphrase-multilingual-MiniLM-L12-v2-LICENSE +0 -0
  98. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/README.md +0 -0
  99. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/hatch_build.py +0 -0
  100. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/pyproject.toml +0 -0
  101. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/__main__.py +0 -0
  102. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/_excludes.py +0 -0
  103. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/_terminal.py +0 -0
  104. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/adapters.py +0 -0
  105. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli.py +0 -0
  106. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli_ask.py +0 -0
  107. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli_doctor.py +0 -0
  108. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli_init.py +0 -0
  109. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli_list.py +0 -0
  110. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli_plan.py +0 -0
  111. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli_recall.py +0 -0
  112. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/cli_update.py +0 -0
  113. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/embedding.py +0 -0
  114. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/gitutil.py +0 -0
  115. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/mcp_server.py +0 -0
  116. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/migrate.py +0 -0
  117. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/migrations/001_initial.sql +0 -0
  118. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/migrations/002_agent_cost_runs.sql +0 -0
  119. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/migrations/003_tier_cost.sql +0 -0
  120. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/migrations/004_agent_outcomes.sql +0 -0
  121. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/migrations/README.md +0 -0
  122. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/migrations/__init__.py +0 -0
  123. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/paths.py +0 -0
  124. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/plan_validator.py +0 -0
  125. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/platforms.py +0 -0
  126. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/pricing.py +0 -0
  127. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/question.py +0 -0
  128. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/recall_chunker.py +0 -0
  129. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/recall_index.py +0 -0
  130. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/src/c3/usage_ingester.py +0 -0
  131. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/__init__.py +0 -0
  132. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/conftest.py +0 -0
  133. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/fixtures/usage/README.md +0 -0
  134. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/fixtures/usage/mainline.jsonl +0 -0
  135. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/fixtures/usage/subagents/agent-deadbeef.jsonl +0 -0
  136. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/fixtures/usage/subagents/agent-deadbeef.meta.json +0 -0
  137. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/__init__.py +0 -0
  138. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_check_agent_invocation.py +0 -0
  139. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_consolidate_memory.py +0 -0
  140. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_hook_utils.py +0 -0
  141. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_permission_handler.py +0 -0
  142. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_permission_handler_toast.py +0 -0
  143. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_pip_reinstall_reminder.py +0 -0
  144. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_planner_check.py +0 -0
  145. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_planner_check_dev.py +0 -0
  146. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_post_tool.py +0 -0
  147. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_pre_tool.py +0 -0
  148. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_recall_autorebuild.py +0 -0
  149. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_recall_inject.py +0 -0
  150. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_record_review_decision.py +0 -0
  151. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_restore_session.py +0 -0
  152. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_review_hint_inject.py +0 -0
  153. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_select_tier.py +0 -0
  154. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_session_utils.py +0 -0
  155. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_settings_local_absolute_paths.py +0 -0
  156. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_similarity_boost.py +0 -0
  157. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_statusline.py +0 -0
  158. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_statusline_template_sync.py +0 -0
  159. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_sync_check.py +0 -0
  160. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/hooks/test_template_guard.py +0 -0
  161. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/__init__.py +0 -0
  162. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/_skill_helpers.py +0 -0
  163. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_dev_workflow_no_task_type.py +0 -0
  164. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_init_session_no_task_type.py +0 -0
  165. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_planner_lightweight.py +0 -0
  166. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_recall_skill.py +0 -0
  167. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_session_backlog_reconciliation.py +0 -0
  168. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_session_guard.py +0 -0
  169. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_setup_templates.py +0 -0
  170. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_start_skill_bugfix_flow.py +0 -0
  171. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_start_skill_new_flow.py +0 -0
  172. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/skills/test_start_skill_security_audit_phase.py +0 -0
  173. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_adapters.py +0 -0
  174. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_check_deletions.py +0 -0
  175. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_ask.py +0 -0
  176. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_doctor.py +0 -0
  177. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_entry.py +0 -0
  178. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_init.py +0 -0
  179. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_list.py +0 -0
  180. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_plan.py +0 -0
  181. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_recall.py +0 -0
  182. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_update_breaking_changes.py +0 -0
  183. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_cli_update_deletions.py +0 -0
  184. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_docstring_consistency.py +0 -0
  185. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_embedding.py +0 -0
  186. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_excludes.py +0 -0
  187. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_extract_breaking_changes.py +0 -0
  188. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_gitutil.py +0 -0
  189. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_mcp_server_elicit.py +0 -0
  190. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_paths.py +0 -0
  191. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_plan_validator.py +0 -0
  192. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_pre_compact.py +0 -0
  193. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_pre_tool_hook.py +0 -0
  194. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_precompact_additional.py +0 -0
  195. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_precompact_toctou_fixes.py +0 -0
  196. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_pricing.py +0 -0
  197. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_recall_chunker.py +0 -0
  198. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_recall_index.py +0 -0
  199. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_references_migration.py +0 -0
  200. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_session_utils_additional.py +0 -0
  201. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_skill_no_builtin_conflict.py +0 -0
  202. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_statusline.py +0 -0
  203. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_stop_additional.py +0 -0
  204. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_stop_hook.py +0 -0
  205. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_stop_precompact_fixes.py +0 -0
  206. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_sync_template_stop.py +0 -0
  207. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_template_pre_tool_hook.py +0 -0
  208. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_usage_ingester.py +0 -0
  209. {claude_code_conductor-2.42.0 → claude_code_conductor-2.43.0}/tests/test_worktree_guard.py +0 -0
@@ -7,3 +7,4 @@
7
7
  v2.11.0|summarize-memory agent + skill removed; replaced by `c3 recall`|summarize-memory エージェント / skill を完全廃止。代替は `c3 recall` の意味検索。
8
8
  v2.20.0|hooks/schema.sql removed; SQLite schema is now managed by c3/migrations/ (auto-applied at session_start)|hooks/schema.sql を削除しました。SQLite スキーマは c3/migrations/ (wheel 内) で管理され session_start で自動適用されます。
9
9
  v2.41.0|Learning tables tier_bandit/tier_recent_outcomes are DROPPED and learning data resets; record_tier_outcome.py replaced by record_agent_outcome.py; c3 tier stats --json shape changed; old db.py tier APIs removed or shimmed (shims removed next release)|
10
+ v2.43.0|Dropped agent_tier_bandit table (migration 005; bandit params now derived from agent_outcomes event log at read time, learning data preserved). Removed update_agent_tier_params and five v2.41.0 deprecated shims (read_tier_params, read_tier_failure_rate, update_tier_params, record_tier_recent_outcome, sync_tier_bandit_cost). read_agent_failure_rate signature changed: last_n replaced by window_days (time-based window, default 14 days via C3_FAILURE_WINDOW_DAYS).|
@@ -16,8 +16,8 @@ MVP スコープ(ユーザー承認済み・tier-routing 自動適用フェー
16
16
  学習データ:
17
17
  - 結果は ``.claude/state/tier_selection.json`` に直近 1 件のみ書き込む
18
18
  - dev-workflow の各フェーズ承認ゲート(並列タスク単位を含む)で
19
- ``record_agent_outcome.py`` がこの json を読んで ``agent_tier_bandit``
20
- テーブルを更新する
19
+ ``record_agent_outcome.py`` が結果を ``agent_outcomes`` イベントログに記録し、
20
+ bandit params(α/β)は読み取り時に ``read_agent_tier_params`` が導出集計で計算する
21
21
 
22
22
  入力 / 出力:
23
23
  - stdin: UserPromptSubmit payload(``prompt`` フィールドを参照)
@@ -505,8 +505,8 @@ def write_tier_selection(
505
505
  ) -> None:
506
506
  """直近の選択結果を ``tier_selection.json`` に書く。
507
507
 
508
- record_agent_outcome.py がこの json を読んで agent_tier_bandit の α/β を更新する。
509
- 既存ファイルは上書きされる(最新 1 件のみ保持)。
508
+ record_agent_outcome.py が結果を ``agent_outcomes`` イベントログに記録し、
509
+ α/β は読み取り時に導出される。既存ファイルは上書きされる(最新 1 件のみ保持)。
510
510
 
511
511
  ``suggested_model`` を併せて書く。tier 名と model の短縮名は同一とする。
512
512
  (PO 廃止前は runner.py が読んで ``claude --agents`` 用に使っていたが、v2.0.0 以降は
@@ -41,6 +41,11 @@ user-invocable: false
41
41
  - **推奨 Tier の SSOT**: 「推奨 Tier」の唯一のソースは `.claude/state/tier_selection.json` の `tier`(無ければ `suggested_model`)であり、`[tier-routing 推奨]` の additionalContext テキストはその値を人間可読に射影した派生表示で SSOT ではない。この値は kickoff プロンプトの UserPromptSubmit で select_tier が 1 度だけ書き、E-2 の `--final` で削除されるまで wave/ゲートをまたいで安定する(承認応答は UserPromptSubmit を発火しないため途中で上書きされない)。
42
42
  - developer の record ブロックは**原則 `--tier` を付けない**(record_agent_outcome.py が tier_selection.json から実適用 tier を機械解決する。tier 値の LLM 申告を行わない)。**例外(機械条件・ADR-AS-2)**: developer 起動時に指定した `model:` が推奨 Tier(tier_selection.json.tier)と**異なる値だった場合は、必ずその実際に指定した値を `--tier {実 model の tier}` に付けて**実態を記録する(「指定 model: ≠ 推奨 Tier なら必ず付与」という観測可能な二値条件で判定する)。
43
43
 
44
+ **集計注記**(DC-AS-002 / ADR-25-3):
45
+
46
+ - E-1/E-2(レビュー指摘由来)のイベントは全 gate 不可逆に記録するが、bandit params・escalation 判定の集計対象は **BANDIT_GATES(D-2.5/D-3/D-5/D-2.5-stuck)のみ**である。E-1/E-2 の成否は個別の集計から除外される(意図どおり・read-side フィルタで実現)。
47
+ - **reviewer role(code-reviewer/security-reviewer・および E-gate のみの role)は BANDIT_GATES に該当 gate を持たないため、`c3 tier stats` 等の表示で当該 role の bandit は常に uniform(全 tier `(1.0,1.0,0)`・0 trials)になる**。これは設計意図の帰結であり退行ではない。tier 選択の実消費者は `select_tier`(developer role 固定)のみで、reviewer role の bandit が uniform でも tier 選択ロジックには影響しない。
48
+
44
49
  ---
45
50
 
46
51
  ## フェーズ A: ヒアリング
@@ -488,6 +493,13 @@ Agent ツールで `developer` エージェントを起動する(`model:` に
488
493
  Glob で `.claude/reports/debug-needed-*.md` の最新を確認する。
489
494
 
490
495
  **ファイルが存在する場合:**
496
+ 0. **stuck 記録**(削除前記録・ADR-25-6):
497
+ ```bash
498
+ python .claude/skills/dev-workflow/scripts/record_agent_outcome.py \
499
+ --role developer --outcome failure --gate D-2.5-stuck \
500
+ --execution subagent --task {plan タスクID} --complexity {セッションファイルの tier-routing複雑度: 行の値} \
501
+ --note "stuck: debug-needed 検出(自力完走不能)"
502
+ ```
491
503
  1. Agent ツールで `systematic-debugger` を起動する。プロンプトに debug-needed ファイルのパスのみを含め、内容は agent 側で Read させる(プロンプトに直接展開しない)[SR-AI-001]
492
504
  2. 生成された `.claude/reports/debug-analysis-*.md` を Glob で取得してパスのみコンテキストに保持する(内容は次段で agent に Read させる)
493
505
  3. D-2 の developer を再実行する(`model:` に推奨 Tier を指定・上記「tier-routing 結果記録の運用」節参照)。プロンプトに debug-analysis の**ファイルパスのみ**を含め、内容は agent 側で Read させる(プロンプトに展開しない)[SR-AI-001]
@@ -44,9 +44,10 @@ Usage:
44
44
  - --tier を明示した場合は TIERS(haiku/sonnet/opus) に含まれるか検証し、
45
45
  含まれなければ警告 + 記録スキップとする。ただし --execution=persona かつ
46
46
  --tier unknown は明示的な escape 値として許容する。
47
- - --execution=subagent のみ bandit(agent_tier_bandit)を更新する。
48
- --execution=persona agent_outcomes イベントログのみ(親 Claude ペルソナは
49
- 実行時に frontmatter model が効かないため)。
47
+ - execution モードとも agent_outcomes イベントログに記録する。bandit params は
48
+ 読み取り時に agent_outcomes から導出計算される(agent_tier_bandit 削除・
49
+ ADR-25-4)。--execution=persona は親 Claude ペルソナ実行のため frontmatter
50
+ model が効かず tier="unknown" で記録される。
50
51
  - dedupe: 同一 (session_id, gate, role, outcome, task) が直近 5 分以内に
51
52
  記録済みなら 2 回目は skip。--task は任意引数で、省略時同士は従来通り
52
53
  (session_id, gate, role, outcome) のみで判定する(後方互換)。task の
@@ -632,19 +633,10 @@ def main(argv: list[str] | None = None) -> int:
632
633
  note = _compose_note(note_body, task)
633
634
 
634
635
  try:
635
- if execution == "subagent":
636
- c3_db.update_agent_tier_params(
637
- role, complexity, tier, success=success, db_path=db_path
638
- )
639
- c3_db.record_agent_outcome_event(
640
- role=role, complexity=complexity, tier=tier, success=success,
641
- gate=gate, note=note, session_id=session_id, db_path=db_path,
642
- )
643
- else: # persona
644
- c3_db.record_agent_outcome_event(
645
- role=role, complexity=complexity, tier=tier, success=success,
646
- gate=gate, note=note, session_id=session_id, db_path=db_path,
647
- )
636
+ c3_db.record_agent_outcome_event(
637
+ role=role, complexity=complexity, tier=tier, success=success,
638
+ gate=gate, note=note, session_id=session_id, db_path=db_path,
639
+ )
648
640
  except Exception as exc: # noqa: BLE001
649
641
  print(
650
642
  f"[record_agent_outcome] recording failed: {type(exc).__name__}",
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.43.0] - 2026-07-03
4
+
5
+ ### 変更
6
+
7
+ - **tier-routing 学習シグナルの客観化と bandit のイベントログ導出化(フェーズ2.5)**: v2.42.0 ソフト適用の実運用で確定した 2 つの構造問題(escalation×ソフト適用による sonnet 探索閉塞デッドロック・レビュー指摘由来の失敗シグナルがモデル能力とタスク難度と レビュワー厳しさの混合物になる問題)を解消する。
8
+ - **失敗シグナルの客観化**: bandit(推奨算出)と escalation の failure rate に集計されるのは `BANDIT_GATES`(D-2.5 / D-3 / D-5 / D-2.5-stuck)の客観ゲートのみになった。E-1/E-2 レビュー指摘由来の記録は**イベントログとして保存を継続**しつつ、集計からは成功・失敗とも対称に除外する(developer の仕事は「動く実装」であり「レビュワーに指摘されない実装」ではない、というシグナル哲学)。
9
+ - **bandit のイベントログ導出化**: `read_agent_tier_params` は `agent_outcomes` イベントログからの導出集計(gate フィルタ付き GROUP BY・placeholder は `len(BANDIT_GATES)` から動的生成)になった。シグナル定義の変更が**過去ログへ遡及適用**されるため、今後の調整で学習データのリセットが不要になる。戻り値契約は不変で select_tier.py / `c3 tier stats` は無改修。
10
+ - **失敗率の時間ベース窓**: `read_agent_failure_rate` の窓が「直近 N 件」から「時間ベース」(`C3_FAILURE_WINDOW_DAYS`・既定 14 日)になった。古い失敗が失効 → サンプル 5 件未満で escalation 停止 → 敗者復活が自然に働き、sonnet 閉塞が解消される(実機で `(None, 1)`・escalation 非発動を確認済み)。
11
+ - **stuck failure の新設**: dev-workflow D-2.5 が `debug-needed-*.md` 検出時(削除前)に `--gate D-2.5-stuck` で developer failure を記録する。「その tier が自力で完走できなかった」という最も客観的な能力シグナル。
12
+ - `record_agent_outcome.py` はイベント記録のみに簡素化(bandit 更新呼び出しを削除)。
13
+
14
+ ### 破壊的変更
15
+
16
+ - **旧学習テーブル `agent_tier_bandit` を DROP**(migration 005 が `c3 update` 後の session 開始時に自動適用)。累積 α/β は `agent_outcomes` からの導出に置き換わるため**学習データ自体は失われない**(イベントログから新ルールで即再計算される)。
17
+ - **`src/c3/db.py` の `update_agent_tier_params` を削除**(bandit は書き込み更新されず読み取り時導出になったため)。
18
+ - **v2.41.0 で deprecated 化したシム 5 関数を削除**: `read_tier_params` / `read_tier_failure_rate` / `update_tier_params` / `record_tier_recent_outcome` / `sync_tier_bandit_cost`(予告どおりの削除。直接呼んでいるカスタマイズは移行が必要)。
19
+ - **`read_agent_failure_rate` のシグネチャ変更**: `last_n` 引数を撤去し `window_days`(時間窓)に置換。
20
+
21
+ ### 後方互換
22
+
23
+ - `read_agent_tier_params` の戻り値契約(`{tier: (alpha, beta, trials)}`・初期値・DB 不在フォールバック)は不変。環境変数(`C3_TIER_EPSILON` / `C3_TIER_COST_LAMBDA` / `C3_ESCALATION_THRESHOLD`)・`LEARNING_THRESHOLD=30`・cost-aware tie-break・ソフト適用(v2.42.0)のロジックは不変。新 env `C3_FAILURE_WINDOW_DAYS` は任意設定(未設定時 14 日)。
24
+ - 集計対象 gate の限定により `c3 tier stats` の trials 表示は従来より少なくなる(正しいデータでの数え直しであり意図した挙動)。レビュワー系 role(E gate の記録しか持たない role)は bandit 上恒久 uniform 表示になる。
25
+
3
26
  ## [2.42.0] - 2026-07-03
4
27
 
5
28
  ### 追加
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-code-conductor
3
- Version: 2.42.0
3
+ Version: 2.43.0
4
4
  Summary: Multi-agent orchestration framework for Claude Code with Codex/Cursor adapters (C3)
5
5
  Project-URL: Homepage, https://github.com/satoh-y-0323/claude-code-conductor
6
6
  Project-URL: Repository, https://github.com/satoh-y-0323/claude-code-conductor
@@ -1,3 +1,3 @@
1
1
  """Claude Code Conductor (C3) - multi-agent orchestration framework for Claude Code."""
2
2
 
3
- __version__ = "2.42.0"
3
+ __version__ = "2.43.0"
@@ -46,6 +46,18 @@ COST_LAMBDA_MAX = 5.0
46
46
  # record_agent_outcome.py の --role 検証・cli_tier.py の role 別表示グルーピングが参照する。
47
47
  AGENT_ROLES: tuple[str, ...] = ("interviewer", "architect", "planner", "developer", "tester")
48
48
 
49
+ # bandit 集計・escalation failure_rate でカウントする客観 gate の SSOT(フェーズ2.5・ADR-25-1)。
50
+ # D-2.5=実装完了 / D-3・D-5=テスト合否(「動く実装」の直接測定) / D-2.5-stuck=自力完走不能。
51
+ # E-1/E-2(レビュー指摘由来)は success/failure とも対称に除外する(含めない)。
52
+ # db.py の read_agent_tier_params / read_agent_failure_rate が read-side でのみ参照する
53
+ # (record 側は全 gate を無条件記録するため参照不要)。
54
+ BANDIT_GATES: tuple[str, ...] = ("D-2.5", "D-3", "D-5", "D-2.5-stuck")
55
+
56
+ # escalation failure_rate 計算の時間窓デフォルト(日数・フェーズ2.5・ADR-25-2)。
57
+ # C3_FAILURE_WINDOW_DAYS 環境変数で上書き可。妥当域は半開区間 (0, 3650](0 拒否・上限 10 年)。
58
+ # 本定数が SSOT(read_agent_failure_rate がここから解決する)。
59
+ FAILURE_WINDOW_DAYS_DEFAULT = 14.0
60
+
49
61
 
50
62
  def _resolve_float_env(
51
63
  env_key: str,
@@ -146,3 +158,22 @@ def resolve_escalation_threshold() -> float:
146
158
  )
147
159
  # default=ESCALATION_THRESHOLD_DEFAULT のため None になり得ない(戻り値型を float に絞る)
148
160
  return cast(float, value)
161
+
162
+
163
+ def resolve_failure_window_days() -> float:
164
+ """``C3_FAILURE_WINDOW_DAYS`` を安全に解決する(read_agent_failure_rate 用 SSOT)。
165
+
166
+ 妥当域: (0, 3650](x=0 拒否の半開区間・上限 10 年で過大窓を弾く)。
167
+ default が float のため戻り値は常に float。
168
+ 詳細な共通挙動は :func:`_resolve_float_env` を参照。
169
+ """
170
+ value = _resolve_float_env(
171
+ "C3_FAILURE_WINDOW_DAYS",
172
+ FAILURE_WINDOW_DAYS_DEFAULT,
173
+ min_val=0.0,
174
+ max_val=3650.0,
175
+ min_inclusive=False,
176
+ log_prefix="[c3:failure_window]",
177
+ )
178
+ # default=FAILURE_WINDOW_DAYS_DEFAULT のため None になり得ない(戻り値型を float に絞る)
179
+ return cast(float, value)
@@ -3,8 +3,8 @@
3
3
  tier-routing (Phase 2 完成) の効果計測用ダッシュボード。
4
4
 
5
5
  主な機能:
6
- - ``c3 tier stats``: role 別 complexity × tier の累積(agent_tier_bandit)と
7
- 直近 outcome(agent_outcomes)を表形式表示
6
+ - ``c3 tier stats``: role 別 complexity × tier の bandit params(agent_outcomes からの導出集計)と
7
+ 直近 outcome を表形式表示
8
8
  - ``c3 tier stats --json``: 機械可読 JSON 出力
9
9
  - ``c3 tier stats --recent N``: 直近 outcome の表示件数を変更(デフォルト 10)
10
10
  - ``c3 tier stats --role <role>``: 指定 role のみに絞り込む
@@ -13,8 +13,7 @@ tier-routing (Phase 2 完成) の効果計測用ダッシュボード。
13
13
  - PO 廃止前の ``c3 status`` CLI パターンを踏襲(旧 ``cli_status.py`` / v2.0.0 で削除)
14
14
  - データがゼロでも「収集中」と分かる表示にする
15
15
  - escalation 発動回数は専用テーブルがないため今回は表示なし(将来拡張余地)
16
- - v2.41.0 cli-tier-stats タスクで role 次元(agent_tier_bandit / agent_outcomes)
17
- に対応。旧フラット tier_bandit / learning_progress / tier_cost(session 合計
16
+ - v2.41.0 cli-tier-stats タスクで role 次元(agent_outcomes)に対応。旧フラット tier_bandit / learning_progress / tier_cost(session 合計
18
17
  USD 概算セクション)は廃止(architecture-report-20260702-214748.md §3-7)
19
18
  """
20
19
 
@@ -30,15 +30,18 @@ from pathlib import Path
30
30
  # 後方互換のため c3.db からも参照可能にする(cli_tier.py / select_tier.py 等)。
31
31
  from c3._db_params import (
32
32
  AGENT_ROLES as AGENT_ROLES,
33
+ BANDIT_GATES as BANDIT_GATES,
33
34
  COST_LAMBDA_DEFAULT as COST_LAMBDA_DEFAULT,
34
35
  COST_LAMBDA_MAX as COST_LAMBDA_MAX,
35
36
  COST_LAMBDA_MIN as COST_LAMBDA_MIN,
36
37
  EPSILON_TIEBREAK as EPSILON_TIEBREAK,
37
38
  ESCALATION_THRESHOLD_DEFAULT as ESCALATION_THRESHOLD_DEFAULT,
39
+ FAILURE_WINDOW_DAYS_DEFAULT as FAILURE_WINDOW_DAYS_DEFAULT,
38
40
  LEARNING_THRESHOLD as LEARNING_THRESHOLD,
39
41
  resolve_cost_lambda as resolve_cost_lambda,
40
42
  resolve_epsilon as resolve_epsilon,
41
43
  resolve_escalation_threshold as resolve_escalation_threshold,
44
+ resolve_failure_window_days as resolve_failure_window_days,
42
45
  )
43
46
 
44
47
  logger = logging.getLogger(__name__)
@@ -251,124 +254,18 @@ def aggregate_decisions(rows: list[dict]) -> dict:
251
254
  _TIER_BANDIT_TIERS: tuple[str, ...] = ("haiku", "sonnet", "opus")
252
255
 
253
256
 
254
- def read_tier_params(
255
- complexity: str,
256
- *,
257
- db_path: Path | None = None,
258
- ) -> dict[str, tuple[float, float, int]]:
259
- """[Deprecated] 全 tier 一様 (1.0, 1.0, 0) を返す後方互換シム。
260
-
261
- Deprecated: v2.41.0 で `read_agent_tier_params` に置換済み。次リリースで削除予定。
262
-
263
- 旧 tier_bandit テーブルは migration 004 で DROP 済みのため、DB には一切
264
- 接続せず常に uniform 初期値を返す(旧 select_tier.py が uniform 表示に
265
- 自然フォールバックする。ADR-5)。
266
-
267
- Args:
268
- complexity: 後方互換のため受け取るが値は無視する。
269
- db_path: 後方互換のため受け取るが値は無視する。
270
-
271
- Returns:
272
- ``{"haiku": (1.0, 1.0, 0), "sonnet": (1.0, 1.0, 0), "opus": (1.0, 1.0, 0)}``。
273
- """
274
- return {t: (1.0, 1.0, 0) for t in _TIER_BANDIT_TIERS}
275
-
276
-
277
- def update_tier_params(
278
- complexity: str,
279
- tier: str,
280
- *,
281
- success: bool,
282
- db_path: Path | None = None,
283
- ) -> bool:
284
- """[Deprecated] no-op で True を返す後方互換シム。
285
-
286
- Deprecated: v2.41.0 で `update_agent_tier_params` に置換済み。次リリースで削除予定。
287
-
288
- 旧 tier_bandit テーブルは DROP 済みのため DB には一切接続しない。False を
289
- 返すと旧 record_tier_outcome.py が json を保持し警告を出し続けるため、
290
- 常に True を返して静かに捨てる(ADR-5)。
291
-
292
- Args:
293
- complexity: 後方互換のため受け取るが値は無視する。
294
- tier: 後方互換のため受け取るが値は無視する。
295
- success: 後方互換のため受け取るが値は無視する。
296
- db_path: 後方互換のため受け取るが値は無視する。
297
-
298
- Returns:
299
- 常に True。
300
- """
301
- return True
302
-
303
-
304
257
  # Phase 2-B 用: tier_recent_outcomes ヘルパー(直近 N 件の outcome 履歴)
305
258
 
306
259
  # escalation 判定の最小サンプル数。これより少ないと escalation しない(統計的に弱い)。
307
260
  _FAILURE_RATE_MIN_SAMPLES = 5
308
261
 
309
262
 
310
- def record_tier_recent_outcome(
311
- *,
312
- complexity: str,
313
- tier: str,
314
- success: bool,
315
- db_path: Path | None = None,
316
- session_id: str | None = None,
317
- ) -> bool:
318
- """[Deprecated] no-op で True を返す後方互換シム。
319
-
320
- Deprecated: v2.41.0 で `record_agent_outcome_event` に置換済み。次リリースで削除予定。
321
-
322
- 旧 tier_recent_outcomes テーブルは DROP 済みのため DB には一切接続しない。
323
- False を返すと旧 record_tier_outcome.py が json を保持し警告を出し続けるため、
324
- 常に True を返して静かに捨てる(ADR-5)。
325
-
326
- Args:
327
- complexity: 後方互換のため受け取るが値は無視する。
328
- tier: 後方互換のため受け取るが値は無視する。
329
- success: 後方互換のため受け取るが値は無視する。
330
- db_path: 後方互換のため受け取るが値は無視する。
331
- session_id: 後方互換のため受け取るが値は無視する。
332
-
333
- Returns:
334
- 常に True。
335
- """
336
- return True
337
-
338
-
339
- def read_tier_failure_rate(
340
- complexity: str,
341
- tier: str,
342
- *,
343
- last_n: int = 10,
344
- db_path: Path | None = None,
345
- ) -> tuple[float | None, int]:
346
- """[Deprecated] 常に (None, 0) を返す後方互換シム。
347
-
348
- Deprecated: v2.41.0 で `read_agent_failure_rate` に置換済み。次リリースで削除予定。
349
-
350
- 旧 tier_recent_outcomes テーブルは DROP 済みのため DB には一切接続しない。
351
- ``(None, 0)`` はサンプル不足と同じ扱いのため、旧 select_tier.py の
352
- escalation 判定が自然に無効化される(ADR-5)。
353
-
354
- Args:
355
- complexity: 後方互換のため受け取るが値は無視する。
356
- tier: 後方互換のため受け取るが値は無視する。
357
- last_n: 後方互換のため受け取るが値は無視する。
358
- db_path: 後方互換のため受け取るが値は無視する。
359
-
360
- Returns:
361
- 常に ``(None, 0)``。
362
- """
363
- return None, 0
364
-
365
-
366
263
  # ---------------------------------------------------------------------------
367
264
  # agent-tier-routing 学習シグナル再設計(v2.41.0 db-foundation)
368
265
  #
369
- # migration 004 で新設された agent_tier_bandit / agent_outcomes 用ヘルパー。
370
- # tier_bandit / tier_recent_outcomes 系(read_tier_params 等)と役割は同じだが、
371
- # PK/列に role が加わる(ADR-1: DROP + 新テーブル一本化)。
266
+ # migration 005(フェーズ2.5)で agent_outcomes 導出集計へ全面移行した
267
+ # agent-tier-routing ヘルパー群。旧 agent_tier_bandit テーブルは DROP され、
268
+ # 学習シグナルは agent_outcomes からの読み取り時導出に統一。
372
269
  # ---------------------------------------------------------------------------
373
270
 
374
271
 
@@ -380,6 +277,17 @@ def read_agent_tier_params(
380
277
  ) -> dict[str, tuple[float, float, int]]:
381
278
  """指定 role/complexity の各 Tier の (alpha, beta, trials) を返す。
382
279
 
280
+ フェーズ2.5(ADR-25-3)で ``agent_tier_bandit`` 累積テーブル読みから
281
+ ``agent_outcomes`` イベントログの GROUP BY 導出集計へ移行した。
282
+ ``BANDIT_GATES``(D-2.5 / D-3 / D-5 / D-2.5-stuck)に該当する gate の
283
+ イベントのみを集計対象とし、E-1/E-2(レビュー指摘由来)は success/failure
284
+ とも対称に除外される(read-side フィルタ 1 点で完結・記録層は全 gate 継続)。
285
+ シグナル定義(BANDIT_GATES)を変えても過去ログへ即遡及再計算される(累積
286
+ テーブルに依存しない)のが導出化の眼目。
287
+
288
+ 集計規則: ``alpha = 1.0 + Σsuccess`` / ``beta = 1.0 + Σ(1 - success)`` /
289
+ ``trials = COUNT(*)``(Beta(1,1) 事前分布 + 観測)。
290
+
383
291
  Args:
384
292
  role: '_db_params.AGENT_ROLES' のいずれか(例: 'developer')。
385
293
  complexity: 'simple' | 'medium' | 'complex'。
@@ -387,9 +295,11 @@ def read_agent_tier_params(
387
295
 
388
296
  Returns:
389
297
  ``{"haiku": (alpha, beta, trials), "sonnet": ..., "opus": ...}``。
390
- 行が無い tier は ``(1.0, 1.0, 0)`` で初期化扱い(Beta(1,1)=一様分布)。
391
- DB 不在 / エラー時も全 tier を初期値で返す。role が異なれば別セルとして
392
- 分離される(tester の更新が developer に漏れない)。
298
+ BANDIT_GATES 該当イベントが無い tier は ``(1.0, 1.0, 0)`` で初期化扱い
299
+ (Beta(1,1)=一様分布)。DB 不在 / エラー時も全 tier を初期値で返す。
300
+ role が異なれば別セルとして分離される(tester の更新が developer に漏れない)。
301
+ E-gate しか記録されない role(reviewer 系)は恒久的に全 tier uniform になる
302
+ (BANDIT_GATES に該当 gate を持たないため・意図どおり・ADR-25-3 DC-AS-002)。
393
303
  """
394
304
  defaults: dict[str, tuple[float, float, int]] = {
395
305
  t: (1.0, 1.0, 0) for t in _TIER_BANDIT_TIERS
@@ -400,16 +310,25 @@ def read_agent_tier_params(
400
310
  if db_path is None:
401
311
  return defaults
402
312
 
313
+ # gate IN の placeholder は BANDIT_GATES 長から動的生成する(DC-GP-001)。
314
+ # literal '(?, ?, ?, ?)' 写経は将来 BANDIT_GATES 増減でバインド個数エラーを招く。
315
+ gate_placeholders = ",".join("?" * len(BANDIT_GATES))
316
+
403
317
  try:
404
318
  conn = sqlite3.connect(str(db_path))
405
319
  try:
406
320
  _apply_busy_timeout(conn)
407
321
  conn.row_factory = sqlite3.Row
408
322
  rows = conn.execute(
409
- "SELECT tier, alpha, beta, trials "
410
- "FROM agent_tier_bandit "
411
- "WHERE role = ? AND task_complexity = ?",
412
- (role, complexity),
323
+ "SELECT tier, "
324
+ " SUM(success) AS succ, "
325
+ " SUM(1 - success) AS fail, "
326
+ " COUNT(*) AS trials "
327
+ "FROM agent_outcomes "
328
+ "WHERE role = ? AND task_complexity = ? "
329
+ f" AND gate IN ({gate_placeholders}) "
330
+ "GROUP BY tier",
331
+ (role, complexity, *BANDIT_GATES),
413
332
  ).fetchall()
414
333
  finally:
415
334
  conn.close()
@@ -424,82 +343,13 @@ def read_agent_tier_params(
424
343
  for r in rows:
425
344
  tier = r["tier"]
426
345
  if tier in result:
427
- result[tier] = (float(r["alpha"]), float(r["beta"]), int(r["trials"]))
346
+ succ = int(r["succ"] or 0)
347
+ fail = int(r["fail"] or 0)
348
+ trials = int(r["trials"] or 0)
349
+ result[tier] = (1.0 + succ, 1.0 + fail, trials)
428
350
  return result
429
351
 
430
352
 
431
- def update_agent_tier_params(
432
- role: str,
433
- complexity: str,
434
- tier: str,
435
- *,
436
- success: bool,
437
- db_path: Path | None = None,
438
- ) -> bool:
439
- """agent_tier_bandit の (alpha, beta, trials) を 1 試行分更新する。
440
-
441
- Args:
442
- role: '_db_params.AGENT_ROLES' のいずれか。
443
- complexity: 'simple' | 'medium' | 'complex'。
444
- tier: 'haiku' | 'sonnet' | 'opus'。
445
- success: True なら alpha+=1、False なら beta+=1。
446
- db_path: c3.db のパス。省略時は :func:`locate_c3_db` で探索。
447
-
448
- Returns:
449
- UPSERT 成功時 True、DB 不在 / エラー時 False。
450
-
451
- Notes:
452
- - 【DC-GP-002】success=True → alpha+=1、success=False → beta+=1。
453
- いずれの場合も trials+=1・last_updated 更新(旧 update_tier_params と同一規則)。
454
- - 行が無ければ INSERT(初期 alpha=1.0, beta=1.0, trials=0 から開始)。
455
- - PK は (role, task_complexity, tier) のため、role が異なれば別行になる。
456
- """
457
- if db_path is None:
458
- db_path = locate_c3_db()
459
- if db_path is None:
460
- return False
461
-
462
- if tier not in _TIER_BANDIT_TIERS:
463
- logger.warning("update_agent_tier_params: unknown tier %r (continuing)", tier)
464
-
465
- from datetime import timezone as _tz # noqa: PLC0415
466
- now_iso = datetime.now(_tz.utc).isoformat(timespec="seconds")
467
- alpha_delta = 1.0 if success else 0.0
468
- beta_delta = 0.0 if success else 1.0
469
-
470
- try:
471
- conn = sqlite3.connect(str(db_path))
472
- try:
473
- conn.execute("PRAGMA journal_mode=WAL")
474
- _apply_busy_timeout(conn)
475
- # SQLite 3.24+ の UPSERT。既存行があれば加算更新、無ければ初期値 + 1 試行分
476
- conn.execute(
477
- "INSERT INTO agent_tier_bandit "
478
- "(role, task_complexity, tier, alpha, beta, trials, last_updated) "
479
- "VALUES (?, ?, ?, ?, ?, 1, ?) "
480
- "ON CONFLICT(role, task_complexity, tier) DO UPDATE SET "
481
- " alpha = alpha + ?, "
482
- " beta = beta + ?, "
483
- " trials = trials + 1, "
484
- " last_updated = excluded.last_updated",
485
- (
486
- role, complexity, tier,
487
- 1.0 + alpha_delta, 1.0 + beta_delta, now_iso,
488
- alpha_delta, beta_delta,
489
- ),
490
- )
491
- conn.commit()
492
- finally:
493
- conn.close()
494
- return True
495
- except sqlite3.OperationalError as exc:
496
- logger.debug("update_agent_tier_params: table not found or inaccessible: %s", type(exc).__name__)
497
- return False
498
- except Exception as exc: # noqa: BLE001
499
- logger.warning("failed to update agent_tier_params: %s", type(exc).__name__)
500
- return False
501
-
502
-
503
353
  def record_agent_outcome_event(
504
354
  *,
505
355
  role: str,
@@ -569,26 +419,32 @@ def read_agent_failure_rate(
569
419
  complexity: str,
570
420
  tier: str,
571
421
  *,
572
- last_n: int = 10,
422
+ window_days: float | None = None,
573
423
  db_path: Path | None = None,
574
424
  ) -> tuple[float | None, int]:
575
- """直近 ``last_n`` 件の agent_outcomes から failure rate を計算する。
425
+ """時間窓内の agent_outcomes(BANDIT_GATES のみ)から failure rate を計算する。
426
+
427
+ フェーズ2.5(ADR-25-2)で直近 ``last_n`` 件窓から時間窓(``window_days``)+
428
+ ``gate IN BANDIT_GATES`` フィルタへ全面移行した。cutoff より新しく、かつ
429
+ BANDIT_GATES(D-2.5 / D-3 / D-5 / D-2.5-stuck)に該当する gate のイベント
430
+ のみを対象とする。E-1/E-2(レビュー指摘由来)の失敗は escalation シグナルを
431
+ 押し上げなくなる(②の gate 除外を bandit だけでなく escalation にも一貫適用)。
576
432
 
577
433
  Args:
578
434
  role: '_db_params.AGENT_ROLES' のいずれか。
579
435
  complexity: 'simple' / 'medium' / 'complex'。
580
436
  tier: 'haiku' / 'sonnet' / 'opus'。
581
- last_n: 何件を対象にするか(デフォルト 10 件)。
437
+ window_days: 時間窓の日数。``None`` のとき ``resolve_failure_window_days()``
438
+ で解決する(env ``C3_FAILURE_WINDOW_DAYS`` 未設定なら既定 14.0 日)。
582
439
  db_path: c3.db のパス。
583
440
 
584
441
  Returns:
585
442
  ``(failure_rate, sample_count)`` のタプル。
586
443
 
587
- - ``sample_count`` は実際に取得できた件数(最大 last_n)。
444
+ - ``sample_count`` は窓内かつ BANDIT_GATES 該当の実イベント件数。
588
445
  - ``failure_rate`` は失敗件数 / sample_count。
589
446
  - サンプルが ``_FAILURE_RATE_MIN_SAMPLES`` 未満の場合は
590
- ``failure_rate = None`` を返し、escalation 判定を skip する目印にする
591
- (旧 read_tier_failure_rate と同一規則を role 分離して継承)。
447
+ ``failure_rate = None`` を返し、escalation 判定を skip する目印にする。
592
448
  - DB 不在 / エラー時も ``(None, 0)`` を返す。
593
449
  """
594
450
  if db_path is None:
@@ -596,6 +452,18 @@ def read_agent_failure_rate(
596
452
  if db_path is None:
597
453
  return None, 0
598
454
 
455
+ if window_days is None:
456
+ window_days = resolve_failure_window_days()
457
+
458
+ # cutoff は record 側書式(UTC 秒精度 ISO 文字列)と一致させ文字列比較する。
459
+ from datetime import timedelta, timezone as _tz # noqa: PLC0415
460
+ cutoff = (
461
+ datetime.now(_tz.utc) - timedelta(days=window_days)
462
+ ).isoformat(timespec="seconds")
463
+
464
+ # gate IN の placeholder は BANDIT_GATES 長から動的生成する(DC-GP-001)。
465
+ gate_placeholders = ",".join("?" * len(BANDIT_GATES))
466
+
599
467
  try:
600
468
  conn = sqlite3.connect(str(db_path))
601
469
  try:
@@ -603,8 +471,10 @@ def read_agent_failure_rate(
603
471
  rows = conn.execute(
604
472
  "SELECT success FROM agent_outcomes "
605
473
  "WHERE role = ? AND task_complexity = ? AND tier = ? "
606
- "ORDER BY ts DESC LIMIT ?",
607
- (role, complexity, tier, last_n),
474
+ f" AND gate IN ({gate_placeholders}) "
475
+ " AND ts >= ? "
476
+ "ORDER BY ts DESC",
477
+ (role, complexity, tier, *BANDIT_GATES, cutoff),
608
478
  ).fetchall()
609
479
  finally:
610
480
  conn.close()
@@ -1177,25 +1047,3 @@ def set_ingest_offset(
1177
1047
  except Exception as exc: # noqa: BLE001
1178
1048
  logger.warning("failed to set_ingest_offset: %s", type(exc).__name__)
1179
1049
  return False
1180
-
1181
-
1182
- def sync_tier_bandit_cost(
1183
- *,
1184
- db_path: Path | None = None,
1185
- ) -> int:
1186
- """[Deprecated] no-op で 0 を返す後方互換シム。
1187
-
1188
- Deprecated: v2.41.0 で cost 列キャッシュ自体を廃止(ADR-4)。次リリースで削除予定。
1189
-
1190
- 旧 tier_bandit テーブルは DROP 済みのため DB には一切接続しない
1191
- (``read_tier_cost_rate_summary`` も呼ばない)。cost レートが必要な箇所は
1192
- ``read_tier_cost_rate_summary`` / ``read_tier_cost_rate_for_complexity`` を
1193
- 直読みすること。
1194
-
1195
- Args:
1196
- db_path: 後方互換のため受け取るが値は無視する。
1197
-
1198
- Returns:
1199
- 常に 0。
1200
- """
1201
- return 0
@@ -0,0 +1,18 @@
1
+ -- C3 SQLite migration 005: bandit のイベントログ導出化に伴い agent_tier_bandit を撤去。
2
+ --
3
+ -- 変更内容:
4
+ -- - agent_tier_bandit(累積 α/β/trials テーブル)を DROP
5
+ --
6
+ -- 背景: read_agent_tier_params は agent_outcomes からの GROUP BY 集計へ移行した
7
+ -- (フェーズ2.5・ADR-25-3/25-4)。累積テーブルと導出集計の二重の真実源は
8
+ -- 乖離しうるため累積テーブルを撤去する。イベントログ(agent_outcomes)は
9
+ -- 全 gate で不変に保持され、シグナル定義変更が過去ログへ遡及再計算される。
10
+ -- 後方互換: なし(update_agent_tier_params 削除と同一 breaking・累積値は破棄)。
11
+
12
+ BEGIN;
13
+
14
+ DROP TABLE IF EXISTS agent_tier_bandit;
15
+
16
+ INSERT OR IGNORE INTO schema_migrations (version) VALUES ('005');
17
+
18
+ COMMIT;