claude-code-conductor 2.47.0__tar.gz → 2.48.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 (220) hide show
  1. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/tier_autoapply.py +24 -1
  2. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/scripts/record_agent_outcome.py +94 -19
  3. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/parallel-agents/SKILL.md +17 -11
  4. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/CHANGELOG.md +17 -0
  5. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/PKG-INFO +1 -1
  6. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/__init__.py +1 -1
  7. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_record_agent_outcome.py +535 -0
  8. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_tier_autoapply.py +150 -0
  9. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_tier_gap_check.py +57 -0
  10. claude_code_conductor-2.48.0/tests/skills/test_parallel_agents_skill_tier.py +209 -0
  11. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/CLAUDE.md +0 -0
  12. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/architect.md +0 -0
  13. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/code-reviewer.md +0 -0
  14. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/design-critic.md +0 -0
  15. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/developer.md +0 -0
  16. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/doc-writer.md +0 -0
  17. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/interviewer.md +0 -0
  18. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/planner.md +0 -0
  19. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/project-setup.md +0 -0
  20. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/security-reviewer.md +0 -0
  21. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/systematic-debugger.md +0 -0
  22. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/tester.md +0 -0
  23. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/wt_developer.md +0 -0
  24. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/wt_systematic-debugger.md +0 -0
  25. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/agents/wt_tester.md +0 -0
  26. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/breaking-changes.txt +0 -0
  27. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/deletions.txt +0 -0
  28. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/docs/config-policy.md +0 -0
  29. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/docs/parallel-agents-setup.md +0 -0
  30. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/docs/platform-adapters.md +0 -0
  31. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/docs/settings.json.md +0 -0
  32. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/_hook_utils.py +0 -0
  33. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/check_agent_invocation.py +0 -0
  34. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/consolidate_memory.py +0 -0
  35. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/permission_handler.py +0 -0
  36. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/permission_handler_toast.py +0 -0
  37. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/planner_check.py +0 -0
  38. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/post_tool.py +0 -0
  39. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/pre_compact.py +0 -0
  40. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/pre_tool.py +0 -0
  41. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/recall_autorebuild.py +0 -0
  42. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/recall_inject.py +0 -0
  43. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/restore_session.py +0 -0
  44. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/select_tier.py +0 -0
  45. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/session_start.py +0 -0
  46. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/session_stop.py +0 -0
  47. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/session_utils.py +0 -0
  48. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/statusline.py +0 -0
  49. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/stop.py +0 -0
  50. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/tier_gap_check.py +0 -0
  51. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/hooks/worktree_guard.py +0 -0
  52. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/memory/.gitkeep +0 -0
  53. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/permission_rules.json +0 -0
  54. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/rules/promoted/index.md +0 -0
  55. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/settings.json +0 -0
  56. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/brainstorm/SKILL.md +0 -0
  57. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/codex-review/SKILL.md +0 -0
  58. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/SKILL.md +0 -0
  59. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/references/code-review-checklist.md +0 -0
  60. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/references/design-critic-rubric.md +0 -0
  61. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/references/design-rubric.md +0 -0
  62. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/references/interview-rubric.md +0 -0
  63. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/references/plan-design-guidelines.md +0 -0
  64. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/references/security-review-checklist.md +0 -0
  65. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/scripts/record_review_decision.py +0 -0
  66. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/dev-workflow/scripts/review_hint_inject.py +0 -0
  67. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/develop/SKILL.md +0 -0
  68. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/doc/SKILL.md +0 -0
  69. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/extract-lib/SKILL.md +0 -0
  70. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/init-session/SKILL.md +0 -0
  71. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/init-session/scripts/session_guard.py +0 -0
  72. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/mcp-config/SKILL.md +0 -0
  73. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/pattern-status/SKILL.md +0 -0
  74. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/promote-pattern/SKILL.md +0 -0
  75. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/recall/SKILL.md +0 -0
  76. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/report-timestamp/SKILL.md +0 -0
  77. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/report-timestamp/scripts/get_timestamp.py +0 -0
  78. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/review-phase/SKILL.md +0 -0
  79. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/setup/SKILL.md +0 -0
  80. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/setup/reference.md +0 -0
  81. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/setup/templates/coding-standards-template.md +0 -0
  82. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/setup/templates/project-conventions-template.md +0 -0
  83. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/skills/start/SKILL.md +0 -0
  84. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.claude/state/.gitkeep +0 -0
  85. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/.gitignore +0 -0
  86. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/ARCHITECTURE.md +0 -0
  87. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/LICENSE +0 -0
  88. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/LICENSES/fastembed-LICENSE +0 -0
  89. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/LICENSES/fastembed-NOTICE +0 -0
  90. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/LICENSES/numpy-LICENSE +0 -0
  91. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/LICENSES/onnxruntime-LICENSE +0 -0
  92. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/LICENSES/paraphrase-multilingual-MiniLM-L12-v2-LICENSE +0 -0
  93. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/README.md +0 -0
  94. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/hatch_build.py +0 -0
  95. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/pyproject.toml +0 -0
  96. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/__main__.py +0 -0
  97. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/_db_params.py +0 -0
  98. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/_excludes.py +0 -0
  99. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/_terminal.py +0 -0
  100. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/adapters.py +0 -0
  101. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli.py +0 -0
  102. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_ask.py +0 -0
  103. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_doctor.py +0 -0
  104. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_init.py +0 -0
  105. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_list.py +0 -0
  106. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_metrics.py +0 -0
  107. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_plan.py +0 -0
  108. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_recall.py +0 -0
  109. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_tier.py +0 -0
  110. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/cli_update.py +0 -0
  111. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/db.py +0 -0
  112. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/embedding.py +0 -0
  113. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/gitutil.py +0 -0
  114. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/mcp_server.py +0 -0
  115. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrate.py +0 -0
  116. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrations/001_initial.sql +0 -0
  117. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrations/002_agent_cost_runs.sql +0 -0
  118. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrations/003_tier_cost.sql +0 -0
  119. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrations/004_agent_outcomes.sql +0 -0
  120. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrations/005_drop_agent_tier_bandit.sql +0 -0
  121. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrations/006_review_decisions_severity.sql +0 -0
  122. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrations/README.md +0 -0
  123. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/migrations/__init__.py +0 -0
  124. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/paths.py +0 -0
  125. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/plan_validator.py +0 -0
  126. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/platforms.py +0 -0
  127. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/pricing.py +0 -0
  128. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/question.py +0 -0
  129. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/recall_chunker.py +0 -0
  130. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/recall_index.py +0 -0
  131. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/src/c3/usage_ingester.py +0 -0
  132. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/__init__.py +0 -0
  133. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/_pre_compact_helpers.py +0 -0
  134. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/conftest.py +0 -0
  135. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/fixtures/usage/README.md +0 -0
  136. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/fixtures/usage/mainline.jsonl +0 -0
  137. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/fixtures/usage/subagents/agent-deadbeef.jsonl +0 -0
  138. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/fixtures/usage/subagents/agent-deadbeef.meta.json +0 -0
  139. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/__init__.py +0 -0
  140. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_check_agent_invocation.py +0 -0
  141. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_consolidate_memory.py +0 -0
  142. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_hook_utils.py +0 -0
  143. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_permission_handler.py +0 -0
  144. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_permission_handler_toast.py +0 -0
  145. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_pip_reinstall_reminder.py +0 -0
  146. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_planner_check.py +0 -0
  147. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_planner_check_dev.py +0 -0
  148. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_post_tool.py +0 -0
  149. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_pre_tool.py +0 -0
  150. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_recall_autorebuild.py +0 -0
  151. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_recall_inject.py +0 -0
  152. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_record_review_decision.py +0 -0
  153. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_restore_session.py +0 -0
  154. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_review_hint_inject.py +0 -0
  155. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_select_tier.py +0 -0
  156. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_select_tier_escalation.py +0 -0
  157. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_session_start.py +0 -0
  158. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_session_stop.py +0 -0
  159. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_session_utils.py +0 -0
  160. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_settings_local_absolute_paths.py +0 -0
  161. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_settings_tier_autoapply_registration.py +0 -0
  162. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_similarity_boost.py +0 -0
  163. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_statusline.py +0 -0
  164. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_statusline_template_sync.py +0 -0
  165. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_sync_check.py +0 -0
  166. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_template_guard.py +0 -0
  167. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/hooks/test_tier_security_fixes.py +0 -0
  168. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/__init__.py +0 -0
  169. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/_skill_helpers.py +0 -0
  170. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_dev_workflow_no_task_type.py +0 -0
  171. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_init_session_no_task_type.py +0 -0
  172. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_planner_lightweight.py +0 -0
  173. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_recall_skill.py +0 -0
  174. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_session_backlog_reconciliation.py +0 -0
  175. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_session_guard.py +0 -0
  176. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_setup_templates.py +0 -0
  177. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_start_skill_bugfix_flow.py +0 -0
  178. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_start_skill_new_flow.py +0 -0
  179. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/skills/test_start_skill_security_audit_phase.py +0 -0
  180. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_adapters.py +0 -0
  181. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_check_deletions.py +0 -0
  182. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_ask.py +0 -0
  183. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_doctor.py +0 -0
  184. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_entry.py +0 -0
  185. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_init.py +0 -0
  186. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_list.py +0 -0
  187. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_metrics.py +0 -0
  188. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_plan.py +0 -0
  189. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_recall.py +0 -0
  190. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_tier.py +0 -0
  191. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_update_breaking_changes.py +0 -0
  192. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_cli_update_deletions.py +0 -0
  193. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_db.py +0 -0
  194. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_docstring_consistency.py +0 -0
  195. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_embedding.py +0 -0
  196. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_excludes.py +0 -0
  197. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_extract_breaking_changes.py +0 -0
  198. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_gitutil.py +0 -0
  199. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_mcp_server_elicit.py +0 -0
  200. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_migrate.py +0 -0
  201. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_paths.py +0 -0
  202. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_plan_validator.py +0 -0
  203. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_pre_compact.py +0 -0
  204. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_pre_tool_hook.py +0 -0
  205. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_precompact_additional.py +0 -0
  206. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_precompact_toctou_fixes.py +0 -0
  207. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_pricing.py +0 -0
  208. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_recall_chunker.py +0 -0
  209. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_recall_index.py +0 -0
  210. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_references_migration.py +0 -0
  211. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_session_utils_additional.py +0 -0
  212. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_skill_no_builtin_conflict.py +0 -0
  213. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_statusline.py +0 -0
  214. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_stop_additional.py +0 -0
  215. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_stop_hook.py +0 -0
  216. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_stop_precompact_fixes.py +0 -0
  217. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_sync_template_stop.py +0 -0
  218. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_template_pre_tool_hook.py +0 -0
  219. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_usage_ingester.py +0 -0
  220. {claude_code_conductor-2.47.0 → claude_code_conductor-2.48.0}/tests/test_worktree_guard.py +0 -0
@@ -18,6 +18,8 @@ check_agent は reviewer 系のみ)のため実行順序に依存しない(
18
18
  - `LAUNCH_LOG_ROLES = {developer, wt_developer, tester, wt_tester}` は
19
19
  注入有無に関わらず applied-state(tier_autoapply.jsonl)へ 1 行追記した。
20
20
  reviewer 系・その他 role は記録も注入もしない(exit 0 素通り)。
21
+ - 起動プロンプト先頭の `C3_TASK_ID:` マーカーを抽出し jsonl の `task_id` に
22
+ 載せた(T8・並列経路の record 突合キー)。
21
23
 
22
24
  ## 安全弁
23
25
 
@@ -97,6 +99,10 @@ _ROTATE_TAIL_LINES = 500
97
99
 
98
100
  _PROMPT_PREFIX_MAX_CHARS = 200
99
101
 
102
+ # T8: 起動プロンプト先頭の C3_TASK_ID マーカー抽出用(§3-1)。行頭アンカー +
103
+ # allowlist + 上限200字で誤抽出・秘密混入を構造排除する(record MAX_TASK_LEN=200 と整合)。
104
+ _TASK_ID_MARKER_RE = re.compile(r'^C3_TASK_ID:[ ]([A-Za-z0-9._\-]{1,200})[ ]*$', re.MULTILINE)
105
+
100
106
 
101
107
  def _load_pricing_module():
102
108
  """c3.pricing モジュールを返した(import 失敗時は None)。"""
@@ -167,6 +173,21 @@ def _clean_prompt_prefix(prompt: object) -> str:
167
173
  return "".join(out)[:_PROMPT_PREFIX_MAX_CHARS]
168
174
 
169
175
 
176
+ def _extract_task_id(prompt: object) -> str | None:
177
+ """起動プロンプトから C3_TASK_ID マーカー(最初の 1 個)を抽出した(§3)。
178
+
179
+ 許容文字集合 [A-Za-z0-9._-]・行頭アンカー・上限200字で誤抽出と秘密混入を防ぐ。
180
+ prompt_prefix の mask→truncate パイプラインとは独立(正規表現自体がサニタイザ・§3-3)。
181
+ 非文字列・不一致は None(→ jsonl は task_id: null で従来挙動・逐次経路も None)。
182
+ """
183
+ if not isinstance(prompt, str):
184
+ return None
185
+ m = _TASK_ID_MARKER_RE.search(prompt)
186
+ if m is None:
187
+ return None
188
+ return m.group(1)
189
+
190
+
170
191
  def _read_selection() -> dict | None:
171
192
  """tier_selection.json を読んだ(無い/壊れていれば None)。"""
172
193
  if not os.path.isfile(TIER_SELECTION_PATH):
@@ -351,6 +372,7 @@ def main() -> None:
351
372
  source = "frontmatter-default"
352
373
  model_applied = None
353
374
 
375
+ prompt = tool_input.get("prompt")
354
376
  row = {
355
377
  "ts": datetime.now(timezone.utc).isoformat(timespec="seconds"),
356
378
  "session_id": session_id,
@@ -358,7 +380,8 @@ def main() -> None:
358
380
  "role_recorded": role_recorded,
359
381
  "model_applied": model_applied,
360
382
  "source": source,
361
- "prompt_prefix": _clean_prompt_prefix(tool_input.get("prompt")),
383
+ "prompt_prefix": _clean_prompt_prefix(prompt),
384
+ "task_id": _extract_task_id(prompt),
362
385
  }
363
386
  _append_applied_state(row)
364
387
 
@@ -20,12 +20,22 @@ Usage:
20
20
 
21
21
  | 優先 | ソース | 対象 |
22
22
  |----|--------------------------------------------------|-------------------------------|
23
- | 1 | --tier(明示・TIERS 検証) | 全 role(並列/worktree 経路は常用申告) |
24
- | 2 | applied-state(tier_autoapply.jsonl・session_id 一致の最新行) | _SOFT_APPLY_ROLES(developer |
23
+ | 1 | --tier(明示・TIERS 検証) | 全 role(escape hatch・優先1 存続) |
24
+ | 2a | applied-state(session_id + role + task_id 全一致の最新行) | _SOFT_APPLY_ROLES(developer)かつ --task 指定時(T8・並列経路の task 突合) |
25
+ | 2b | applied-state(session_id + role 一致の最新行) | 同上・2a が 0 件 or --task 未指定時(現行の優先2=呼称のみ細分化) |
25
26
  | 3 | tier_selection.json の tier→suggested_model | 同上・優先2 不成立時(フォールバック A 互換) |
26
27
  | 4 | agents/{role}.md frontmatter model: | developer 以外、および 2・3 が不成立の developer |
27
28
  | 5 | 解決不能 | 記録スキップ(stderr 警告 + exit 0) |
28
29
 
30
+ T8(architecture §5): 並列経路(wt_developer→developer)は起動プロンプトの
31
+ ``C3_TASK_ID:`` マーカーを tier_autoapply.py が jsonl の task_id に載せ、record は
32
+ ``--task`` 値と (session_id, role, task_id) 突合で実適用 tier を機械解決する(優先2a)。
33
+ これにより同一 session_id の複数 wt_developer を task 単位で一意分離し `--tier` 明示を
34
+ 不要化した(ADR-AS-4 解消)。逐次経路は ``--task`` を渡すがマーカー未注入で全行
35
+ task_id=null のため優先2b で従来どおり解決する(挙動不変)。task 突合 0 件かつ当該
36
+ session/role に task_id 非 null 行が存在するとき(マーカー運用中の突合失敗)は record が
37
+ stderr へ 1 行警告する(§5-7・戻り値/exit code 不変の「警告のみ」)。
38
+
29
39
  --execution=subagent かつ role が _SOFT_APPLY_ROLES に含まれる場合(現状
30
40
  developer のみ)、--tier 省略時はまず applied-state を読む(優先2)。
31
41
  フェーズ3で PreToolUse hook(tier_autoapply.py)が Agent 起動時の実適用
@@ -42,9 +52,9 @@ Usage:
42
52
  推奨 Tier と異なる場合は必ず --tier に実際の tier を付す運用を dev-workflow
43
53
  SKILL.md 側が担う(本スクリプトは優先 1 で受けるのみでコード変更は無い)。
44
54
  並列(worktree isolation)経路は wt_developer→developer の記録を親 Claude
45
- が main リポジトリで実行し、tier_selection.json を読まず常に --tier
46
- 明示する(ADR-AS-4)。そのため本スクリプトは並列経路向けの追加コードを
47
- 持たず、優先 1(--tier 明示)を共用するだけで足りる。
55
+ が main リポジトリで実行するが、T8 以降は --tier を明示せず C3_TASK_ID:
56
+ マーカー由来の task_id を --task と (session_id, role, task_id) 突合して
57
+ 優先2a で機械解決する(上記 L27-37 の新記述に一本化。ADR-AS-4 解消済み)。
48
58
  --execution=persona は --tier 省略時、frontmatter へも tier_selection.json
49
59
  へも fallback せず常に tier="unknown" 固定でイベントログのみ記録する
50
60
  (frontmatter/tier_selection は subagent の実使用 tier であり、persona の
@@ -379,27 +389,49 @@ def _iter_applied_state_capped_lines(path: str):
379
389
  yield raw.decode("utf-8", errors="replace")
380
390
 
381
391
 
382
- def _read_applied_tier(session_id: str | None, role: str, c3_pricing) -> str | None:
383
- """applied-state(tier_autoapply.jsonl)から実適用 tier を解決する(優先2・§4-2)。
392
+ def _read_applied_tier(
393
+ session_id: str | None, role: str, c3_pricing, task: str | None = None
394
+ ) -> str | None:
395
+ """applied-state(tier_autoapply.jsonl)から実適用 tier を解決する(優先2・§5)。
384
396
 
385
397
  フェーズ3で PreToolUse hook(tier_autoapply.py)が Agent 起動時の実適用値を
386
398
  session_id・role_recorded 付きで JSONL 追記する。record はこれを session_id
387
399
  一致で読むことで「適用者=記録 SSOT」を成立させる(tier_selection.json の
388
400
  推奨値を読む優先3 より優先する)。
389
401
 
402
+ 優先2 の内部細分(T8・architecture §5-4。優先1/3/4 の体系は不変):
403
+ - 優先2a(task-exact): ``task`` 指定時、(session_id, role_recorded, task_id)
404
+ 全一致の最新行を優先する。並列 wave(parallel-agents)で同一 session_id の
405
+ 複数 wt_developer を task_id で一意分離し、`--tier` 明示なしに実適用 tier を
406
+ 機械解決する(ADR-AS-4 解消)。task_id は起動プロンプトの ``C3_TASK_ID:``
407
+ マーカーを tier_autoapply.py が抽出して jsonl に載せた値。
408
+ - 優先2b(session-latest): 優先2a が 0 件、または ``task`` 未指定(task=None)の
409
+ とき、(session_id, role_recorded) 一致の最新行(現行ロジックそのもの)を採用する。
410
+ - 後方互換: ``task=None`` では優先2a 候補が常に None のまま → 現行と bit 一致。
411
+ 逐次経路は ``--task {plan タスクID}`` を渡すが ``C3_TASK_ID:`` マーカーを注入
412
+ しないため jsonl 全行が task_id=null で、優先2b で従来どおり解決される(挙動不変)。
413
+
390
414
  突合規則(_read_selection() と同じ防御思想):
391
415
  - APPLIED_STATE_PATH 不在なら None。
392
416
  - session_id が None なら None(突合不能・§0-4 の NULL 制約。session_id
393
417
  NULL の行同士を突き合わせない)。
394
418
  - 行単位で json.loads し、壊れ行は skip(try/except continue)。
395
- - session_id 一致 かつ role_recorded == role の行を収集し、最新
396
- (末尾側/ts 最大)の model_applied を採用する。
419
+ - session_id 一致 かつ role_recorded == role の行を 1 パスで走査し、優先2b
420
+ 候補(session+role 最新)と優先2a 候補(task 一致の最新)を同時収集する。
397
421
  - model_applied 非文字列(int/list/dict 等)は skip(resolve_tier の
398
422
  内部 .lower() による AttributeError 防止。soft-apply 側 L566-574 と同理由)。
399
423
  source=frontmatter-default(model_applied=null)の行は tier を持たない
400
424
  ため自然に skip される。
401
425
  - resolve_tier で正規化し _VALID_TIERS に含まれれば返す。
402
426
 
427
+ §5-7 additive 警告ガード(ADR-T8-9・C-3 R2 反映: DC-T8-AS-003):
428
+ - ``task`` 指定・優先2a 0 件・かつ当該 (session_id, role) に task_id 非 null 行が
429
+ 1 件以上存在する(``saw_task_id_row`` 真=マーカー運用中)ときのみ、stderr へ
430
+ 1 行の英語警告を出す(マーカー未注入 or task 表記ゆれ or tier 未注入による真の
431
+ 突合失敗の可視化)。全行 task_id=null(=マーカー未運用の純逐次)や task=None
432
+ では発火しない(逐次 crying-wolf 回避)。
433
+ - 警告のみで戻り値・exit code・chosen の決定式は一切変えない(fail-safe 不変)。
434
+
403
435
  Returns:
404
436
  解決できた正規化 tier 文字列、または解決不能なら None。
405
437
  """
@@ -414,8 +446,12 @@ def _read_applied_tier(session_id: str | None, role: str, c3_pricing) -> str | N
414
446
  or os.path.islink(APPLIED_STATE_PATH)
415
447
  ):
416
448
  return None
417
- latest_model: str | None = None
418
- latest_ts: str | None = None
449
+ # 1 パス 2 候補収集(architecture §5-2・GP-003: 既存ループを土台に候補を 2 本化)。
450
+ latest_session_model: str | None = None # 優先2b(session+role 最新・現行ロジック)
451
+ latest_session_ts: str | None = None
452
+ latest_task_model: str | None = None # 優先2a(session+role+task 全一致の最新)
453
+ latest_task_ts: str | None = None
454
+ saw_task_id_row = False # 当該 (session_id, role) に task_id 非 null 行が存在するか(§5-7)
419
455
  try:
420
456
  # item5(SR-NEW): 末尾優先で最大 5MB のみ走査する(_iter_applied_state_capped_lines)。
421
457
  for line in _iter_applied_state_capped_lines(APPLIED_STATE_PATH):
@@ -432,6 +468,11 @@ def _read_applied_tier(session_id: str | None, role: str, c3_pricing) -> str | N
432
468
  continue
433
469
  if row.get("role_recorded") != role:
434
470
  continue
471
+ # §5-7: マーカー運用中の検出。model_applied 非文字列ガードより前に判定
472
+ # する(frontmatter-default 行〈model_applied=null〉でも task_id が
473
+ # 非 null なら運用中と見なす。追加走査コストゼロ)。
474
+ if row.get("task_id") is not None:
475
+ saw_task_id_row = True
435
476
  model_applied = row.get("model_applied")
436
477
  if not isinstance(model_applied, str):
437
478
  continue
@@ -440,18 +481,48 @@ def _read_applied_tier(session_id: str | None, role: str, c3_pricing) -> str | N
440
481
  # 最新(ts 最大)を採用。ts 同値/欠落時は後勝ち(末尾側)で
441
482
  # 上書きするため >= で比較する。ts プロファイルは
442
483
  # tier_autoapply.py と同一 UTC 秒精度 ISO8601(辞書順=時系列)。
443
- if latest_ts is None or ts_key >= latest_ts:
444
- latest_ts = ts_key
445
- latest_model = model_applied
484
+ # 優先2b 候補(session+role 最新)=現行ロジックそのもの。
485
+ if latest_session_ts is None or ts_key >= latest_session_ts:
486
+ latest_session_ts = ts_key
487
+ latest_session_model = model_applied
488
+ # 優先2a 候補(task 指定時のみ・session+role+task 全一致の最新)。
489
+ if task is not None and row.get("task_id") == task:
490
+ if latest_task_ts is None or ts_key >= latest_task_ts:
491
+ latest_task_ts = ts_key
492
+ latest_task_model = model_applied
446
493
  except OSError as exc:
447
494
  print(
448
495
  f"[record_agent_outcome] failed to read applied-state: {exc}",
449
496
  file=sys.stderr,
450
497
  )
451
498
  return None
452
- if latest_model is None:
499
+ # 決定: task-exact(優先2a)を優先し、0 件なら session-latest(優先2b)へ。
500
+ chosen = latest_task_model if latest_task_model is not None else latest_session_model
501
+ # §5-7 additive 警告: task 指定・優先2a 0 件・かつマーカー運用中(saw_task_id_row 真)
502
+ # のときのみ 1 行警告する(戻り値/exit code/chosen は不変・fail-safe 不変)。
503
+ # 安全性根拠(SR-K-003 解消): --task 値(task 変数)自体は allowlist 検証を受けない。
504
+ # allowlist([A-Za-z0-9._\-])が適用されるのは tier_autoapply.py の task_id 抽出
505
+ # 経路のみで、--task CLI 引数経路には存在しない(_truncate は文字数/バイト数の
506
+ # 切り詰めのみで文字種検証はしない)。この警告文の安全性は下記の二段で担保する:
507
+ # (1) _mask_secrets(task) で既知の秘密パターン(token=/api_key=/Bearer/PEM 等)を
508
+ # *** に潰す(allowlist 非検証の --task に秘密様文字列が混入しても stderr へ
509
+ # 生の秘密を出さない・display-only)。
510
+ # (2) その結果を {...!r} で repr エスケープする(制御文字・改行・引用符混入時も
511
+ # 1 行維持・インジェクション不成立)。
512
+ # マスクは警告表示だけに閉じる(chosen 決定・突合・DB note は生の task を使う)。
513
+ # 将来 !r を !s 等へ変更する/_mask_secrets 適用を外すリファクタが入るとこの前提
514
+ # (二段防御)が崩れるため、_mask_secrets(task) + !r 依存であることに留意する。
515
+ if task is not None and latest_task_model is None and saw_task_id_row:
516
+ print(
517
+ f"[record_agent_outcome] --task {_mask_secrets(task)!r} specified but no matching "
518
+ "(session,role,task) row in applied-state though task_id rows exist "
519
+ "for this session/role; falling back to session-latest (priority 2b). "
520
+ "marker not injected or task mismatch?",
521
+ file=sys.stderr,
522
+ )
523
+ if chosen is None:
453
524
  return None
454
- resolved = c3_pricing.resolve_tier(latest_model)
525
+ resolved = c3_pricing.resolve_tier(chosen)
455
526
  if resolved in _VALID_TIERS:
456
527
  return resolved
457
528
  return None
@@ -698,14 +769,18 @@ def main(argv: list[str] | None = None) -> int:
698
769
  # 一致で読む。role が soft-apply 対象のときのみ突合する(tester 等は
699
770
  # _SOFT_APPLY_ROLES 外なので applied-state を読まない・role gating)。
700
771
  if role in _SOFT_APPLY_ROLES:
701
- tier = _read_applied_tier(session_id, role, c3_pricing)
772
+ # T8: 切り詰め済み task を突合キーとして配線(優先2a)。task=None の
773
+ # 従来呼び出し・逐次経路(マーカー未注入)は優先2b で従来どおり解決。
774
+ tier = _read_applied_tier(session_id, role, c3_pricing, task=task)
702
775
  # 優先 3(降格・旧優先2): role が soft-apply 対象(_SOFT_APPLY_ROLES)なら
703
776
  # tier_selection.json の tier(無ければ suggested_model)を
704
777
  # resolve_tier で正規化し、_VALID_TIERS に含まれれば採用する。
705
778
  # 優先2(applied-state)が不成立のとき(applied-state 不在/session_id
706
779
  # 不一致/kill-switch で jsonl に行が無い等)のフォールバック A 互換。
707
- # 逐次経路(worktree なし)のみが対象。並列(worktree)経路は親が
708
- # --tier を明示するため優先 1 で解決され、ここには来ない(ADR-AS-4)。
780
+ # 逐次経路(worktree なし)はマーカー未注入で優先2b により解決される。
781
+ # 並列(worktree)経路は T8 以降 --tier を渡さないため、task_id 突合
782
+ # (優先2a/2b)が不成立の場合はこの優先3フォールバックに到達しうる
783
+ # (ADR-AS-4 解消後は「ここには来ない」という言い切りは成立しない)。
709
784
  if tier is None and role in _SOFT_APPLY_ROLES and selection is not None:
710
785
  soft_apply_raw = selection.get("tier") or selection.get("suggested_model")
711
786
  # 非文字列ガード: resolve_tier() は内部で無条件に model.lower() を
@@ -164,6 +164,14 @@ plan-report 承認時点で全タスク・agent・writes・prompt が確認済
164
164
  Bash でまず以下を実行: `export PO_WORKTREE_GUARD=1`(worktree_guard.py PreToolUse が worktree 外書き込みをブロックする条件)
165
165
  ```
166
166
  worktree_guard.py はこの env 未設定時 `sys.exit(0)` で完全無効化されるため、wt_* agent 起動プロンプトの先頭で必ず設定すること。
167
+ - **全 `read_only: false` タスク(wt_developer / wt_tester): プロンプト先頭付近(PO_WORKTREE_GUARD の Bash 行の直後・タスク本文の前)に機械可読マーカー行を必須で 1 行含める**:
168
+ ```
169
+ C3_TASK_ID: {task_id}
170
+ ```
171
+ - `{task_id}` は `description`(タスク id)および record の `--task` に渡す値と**完全一致**させる(英数と `.` `_` `-` のみ・200 字以内)。
172
+ - この行を PreToolUse hook(`tier_autoapply.py`)が抽出し applied-state(`tier_autoapply.jsonl`)の `task_id` に記録する。record が `--task` と突合して適用 tier を機械解決するための入力キー。
173
+ - **三者一致の責務は親 Claude が負う**: マーカー値 `C3_TASK_ID: {task_id}`・`description`(タスク id)・record `--task {task_id}` の三者は、**親 Claude が同一の `task_id` 変数から 3 箇所(description / C3_TASK_ID マーカー / record `--task`)へ転記**し、大小・末尾空白・省略の表記ゆれを生じさせない(by convention の保証者を明文化)。転記ミス時の静かな優先2b フォールバックは record 側の stderr 警告で検知する二段構え。
174
+ - **不均質 wave ではマーカー注入が必須**: escape hatch として一部タスクに `model:` を明示し wave 内で tier が不均質になる場合、マーカー欠落で優先2b に落ちると 2b は task を無視して session+role 最新の 1 行を拾うため、**別タスクの tier を誤帰属しうる**。均質 wave では顕在化しないが、`model:` 明示混在の**不均質 wave ではマーカー欠落=誤帰属リスクのためマーカー注入を必須**とする。
167
175
  - タスクの `prompt` 本文
168
176
  - 「**禁止事項: git add / git commit / git push を実行しないこと**。コミットは親 Claude がユーザー承認後に行う」
169
177
  - 「**返り値フォーマット厳守**:
@@ -215,19 +223,18 @@ worktree path は Agent ツール返り値の `<worktree><worktreePath>...</work
215
223
 
216
224
  **tier-routing 結果記録(失敗タスク)**: 選択肢に関わらず、この wave で失敗した各タスクのうち `wt_developer`/`wt_tester` で起動したものについて、1 タスク = 1 記録で failure を記録する(`wt_developer`→`--role developer`、`wt_tester`→`--role tester`。`--execution subagent`)。`code-reviewer`/`security-reviewer`/`wt_systematic-debugger` のタスクは記録対象外。この記録は親 Claude が **main リポジトリ(2-F-0 の `cd <ROOT>` 後)で実行**する。**「スキップして次の wave へ」を選んだ場合も、次の wave に進む前に必ずこの記録を済ませること**(`--complexity` は dev-workflow 開始時の `[tier-routing 推奨]` 表示の複雑度をそのまま渡す。「リトライ」を選び再実行が成功した場合は 1 タスク 1 記録の原則により 2-F-4 で改めて success を記録する=リトライ結果は新たな別記録になる)。
217
225
 
218
- **`--tier` の付与ルール(ADR-AS-4・worktree state 分離対応)**:
219
- - `wt_developer`→`developer` の記録は **`--tier {当該 wt_developer 起動時に hooktier_autoapply)が model: へ自動適用した推奨 Tier}` を明示する**(tier_selection.json worktree 自己解決には依存せず親が申告する)。この値の SSOT`tier_selection.json.tier`(kickoff 1 度確定・以降 wave をまたいで安定)で、2-C hook が `model:` へ自動適用したのと同一値を渡す。並列 wave 内の複数 wt_developer は同一の推奨 Tier を共有する(単一 tier_selection.json・DC-AS-003 で許容済み)。逸脱時(明示指定した `model:` が推奨 Tier と異なる)はその実際に適用された tier `--tier` に渡す(並列経路では常に実適用値を申告するため、逸脱の有無に依らず `--tier` を付ける運用に一本化される)。**hook worktree 側で実適用 model `.claude/state/tier_autoapply.jsonl` に記録するが、worktree state 分離により親 main record からは session_id 一致で読めないことがあるため、並列経路では初回は `--tier` 明示を維持する(applied-state 経由の自己解決への一本化は T8 で対応)。**
226
+ **tier 記録ルール(ADR-AS-4 解消・applied-state task_id 突合)**:
227
+ - `wt_developer`→`developer` の記録は **`--tier` を付けない**。起動時に PreToolUse hook(`tier_autoapply`)が applied-state(`tier_autoapply.jsonl`)に記録した実適用 tier を、record が `(session_id, role, task_id)` 突合で機械解決する(優先2a)。**`--task {task_id}` は突合キーとして必須**であり、2-C のマーカー `C3_TASK_ID: {task_id}` と完全一致させる。**従来 `--task` dedupe 専用の任意引数だったが、T8 で突合の必須キーへ役割が変わる**(未注入だと優先2b フォールバック=session_id 一致だけの曖昧解決に戻り、並列で誤 tier 帰属リスクが残る)。applied-state `task_id` 突合により、並列 wave 内の複数 wt_developer が同一 session_id でも task 単位で**一意**に実適用 tier を解決できる(ADR-AS-4 解消・T8)。hook の書き込み先が main `.claude/state/` であること(cwd リーク下でも `__file__` 基準で不変)は T4 E2E で実測確認済み(2026-07-07・並列 wt_developer×2 worktree jsonl 0 件・main 2 行・record `--tier` なしで正解 tier を機械解決)。
220
228
  - `wt_tester`→`tester` の記録は **`--tier` を付けない**(frontmatter 解決のまま不変。tester は機械適用対象外)。
221
229
 
222
230
  ```bash
223
- # wt_developer→developer(--tier を明示)
231
+ # wt_developer→developertier フラグは付けない・applied-state task 突合で機械解決)
224
232
  python .claude/skills/dev-workflow/scripts/record_agent_outcome.py \
225
233
  --role developer --outcome failure --gate 2-E \
226
234
  --execution subagent --complexity {セッションファイルの tier-routing複雑度: 行の値} \
227
- --tier {当該 wt_developer 起動時に hook model: へ自動適用した推奨 Tier(tier_selection.json.tier と同値)} \
228
- --task {task_id}
235
+ --task {task_id} # 2-C C3_TASK_ID マーカーと完全一致・突合の必須キー
229
236
 
230
- # wt_tester→tester(--tier を付けない・frontmatter 解決)
237
+ # wt_tester→testertier フラグは付けない・frontmatter 解決)
231
238
  python .claude/skills/dev-workflow/scripts/record_agent_outcome.py \
232
239
  --role tester --outcome failure --gate 2-E \
233
240
  --execution subagent --complexity {セッションファイルの tier-routing複雑度: 行の値} \
@@ -320,17 +327,16 @@ git branch -D worktree-agent-{id}
320
327
 
321
328
  **tier-routing 結果記録(成功タスクのみ)**: この wave で成功した各タスクのうち `wt_developer`/`wt_tester` で起動したものについて、1 タスク = 1 記録で success を記録する(`wt_developer`→`--role developer`、`wt_tester`→`--role tester`。`--execution subagent`)。`code-reviewer`/`security-reviewer`/`wt_systematic-debugger` のタスクは記録対象外(`--complexity` は dev-workflow 開始時の `[tier-routing 推奨]` 表示の複雑度をそのまま渡す)。この記録は親 Claude が **main リポジトリ(2-F-0 の `cd <ROOT>` 後)で実行**する。
322
329
 
323
- **`--tier` の付与ルール(ADR-AS-42-E と同一)**: `wt_developer`→`developer` は **`--tier {当該 wt_developer 起動時に hooktier_autoapply)が model: へ自動適用した推奨 Tier(tier_selection.json.tier と同値)}` を明示**する(worktree 自己解決に依存しない・並列 wave 内の複数 wt_developer は同一 tier を共有〈DC-AS-003〉・逸脱時は実際に適用された tier を渡す)。**hook は実適用 model `.claude/state/tier_autoapply.jsonl` に記録するが、worktree state 分離により親 main record が読めないことがあるため並列経路では初回 `--tier` 明示を維持する(T8 で一本化)。** `wt_tester`→`tester` は **`--tier` を付けない**(frontmatter 解決のまま不変・機械適用対象外)。
330
+ **tier 記録ルール(ADR-AS-4 解消・2-E と同一)**: `wt_developer`→`developer` は **`--tier` を付けない**。起動時に hook(`tier_autoapply`)が applied-state(`tier_autoapply.jsonl`)に記録した実適用 tier を、record が `(session_id, role, task_id)` 突合で機械解決する(優先2a)。**`--task {task_id}` は突合キーとして必須**であり、2-C のマーカー `C3_TASK_ID: {task_id}` と完全一致させる(従来 `--task` は dedupe 専用の任意引数だったが、T8 で突合の必須キーへ役割が変わる)。applied-state の `task_id` 突合により、同一 session_id の複数 wt_developer task 単位で**一意**に分離できる(ADR-AS-4 解消・T8)。hook の書き込み先が main `.claude/state/` であること(cwd リーク下でも `__file__` 基準で不変)は T4 E2E で実測確認済み(2026-07-07・並列 wt_developer×2 で worktree jsonl 0 件・main 2 行・record `--tier` なしで正解 tier を機械解決)。 `wt_tester`→`tester` は **`--tier` を付けない**(frontmatter 解決のまま不変・機械適用対象外)。
324
331
 
325
332
  ```bash
326
- # wt_developer→developer(--tier を明示)
333
+ # wt_developer→developertier フラグは付けない・applied-state task 突合で機械解決)
327
334
  python .claude/skills/dev-workflow/scripts/record_agent_outcome.py \
328
335
  --role developer --outcome success --gate 2-D \
329
336
  --execution subagent --complexity {セッションファイルの tier-routing複雑度: 行の値} \
330
- --tier {当該 wt_developer 起動時に hook model: へ自動適用した推奨 Tier(tier_selection.json.tier と同値)} \
331
- --task {task_id}
337
+ --task {task_id} # 2-C C3_TASK_ID マーカーと完全一致・突合の必須キー
332
338
 
333
- # wt_tester→tester(--tier を付けない・frontmatter 解決)
339
+ # wt_tester→testertier フラグは付けない・frontmatter 解決)
334
340
  python .claude/skills/dev-workflow/scripts/record_agent_outcome.py \
335
341
  --role tester --outcome success --gate 2-D \
336
342
  --execution subagent --complexity {セッションファイルの tier-routing複雑度: 行の値} \
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.48.0] - 2026-07-07
4
+
5
+ ### 追加
6
+
7
+ - **並列経路の record `--tier` 明示を不要化(T8・ADR-AS-4 解消)**: applied-state(`.claude/state/tier_autoapply.jsonl`)に `task_id` フィールドを追加し、`record_agent_outcome.py` が `(session_id, role, task_id)` の全一致で実適用 tier を一意解決できるようにした(優先2a)。並列 wave 内の複数 wt_developer が同一 session_id でも task 単位で分離される。task 一致行が 0 件なら従来の「session 最新行」(優先2b)へフォールバックし後方互換(task 未指定の逐次経路は挙動 bit 一致)。`--tier` 明示は優先1 の escape hatch として存続
8
+ - **`C3_TASK_ID:` マーカー**: parallel-agents skill の起動プロンプトに機械可読マーカー行(`C3_TASK_ID: {task_id}`)を必須注入し、`tier_autoapply.py` が行頭アンカー+厳格書式(`[A-Za-z0-9._-]{1,200}`・first-match)で抽出して jsonl に記録する。allowlist が制御文字・秘密情報パターンを構造的に排除(誤抽出・秘密混入・ReDoS 耐性を security-review で確認済み)。マーカー不在(逐次経路等)は `task_id: null` で従来挙動
9
+ - **2b フォールバック警告(additive)**: record が `--task` 指定かつ task 一致 0 件かつ当該 session/role に task_id 非 null 行が存在する場合のみ、stderr に 1 行警告(マーカー運用中の真の突合失敗に限定・純逐次 0 回・並列正常 0 回の発火設計・警告のみで戻り値/exit code 不変・task 値は `_mask_secrets`+repr の二段防御で表示)
10
+
11
+ ### 変更
12
+
13
+ - parallel-agents SKILL.md: 2-E / 2-F-4 の wt_developer 向け `--tier` 付与ルールと bash 例を撤去し「applied-state task 突合で機械解決・`--task` は突合の必須キー」に一本化。2-C にマーカー注入手順(三者一致責務: 親 Claude が同一 task_id 変数から description / マーカー / `--task` へ転記)と不均質 wave でのマーカー必須性を明記。wt_tester の「`--tier` を付けない」は不変
14
+ - 旧 ADR-AS-4 注記(「worktree state 分離で session_id 一致でも読めないことがある」)は E2E 実測(並列 wt_developer×2)で反証し解消形に更新: hook の書き込み先は cwd リーク下でも `__file__` 基準で常に main の `.claude/state/`(worktree 側 jsonl 0 件を実測確認)
15
+
16
+ ### 後方互換
17
+
18
+ - 全て additive(jsonl はキー追加のみ・既存 7 フィールド不変・読者 `tier_gap_check.py` は無改修で耐性確認済み・record は task 未指定経路が bit 一致・DB migration なし)。既存 fail-safe(kill-switch `C3_TIER_AUTOAPPLY_DISABLE`・全例外 exit 0・壊れ行 skip・5MB 上限・symlink 防御)は不変。**破壊的変更なし**
19
+
3
20
  ## [2.47.0] - 2026-07-07
4
21
 
5
22
  ### 追加
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-code-conductor
3
- Version: 2.47.0
3
+ Version: 2.48.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.47.0"
3
+ __version__ = "2.48.0"