claude-code-conductor 2.72.0__tar.gz → 2.73.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 (272) hide show
  1. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/docs/config-policy.md +5 -2
  2. claude_code_conductor-2.73.0/.claude/state/setup_done.flag +0 -0
  3. claude_code_conductor-2.73.0/.claude/tmp/.gitkeep +0 -0
  4. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.gitignore +8 -3
  5. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/CHANGELOG.md +28 -0
  6. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/PKG-INFO +1 -1
  7. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/pyproject.toml +18 -0
  8. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/__init__.py +1 -1
  9. claude_code_conductor-2.73.0/tests/__init__.py +0 -0
  10. claude_code_conductor-2.73.0/tests/hooks/__init__.py +0 -0
  11. claude_code_conductor-2.73.0/tests/skills/__init__.py +0 -0
  12. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_ci_workflows.py +124 -2
  13. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_scripts_src_bootstrap.py +5 -5
  14. claude_code_conductor-2.73.0/tests/test_verify_wheel.py +1939 -0
  15. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/.gitignore +0 -0
  16. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/CLAUDE.md +0 -0
  17. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/architect.md +0 -0
  18. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/code-reviewer.md +0 -0
  19. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/design-critic.md +0 -0
  20. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/developer.md +0 -0
  21. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/doc-writer.md +0 -0
  22. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/interviewer.md +0 -0
  23. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/planner.md +0 -0
  24. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/project-setup.md +0 -0
  25. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/security-reviewer.md +0 -0
  26. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/systematic-debugger.md +0 -0
  27. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/tester.md +0 -0
  28. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/wt_developer.md +0 -0
  29. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/wt_systematic-debugger.md +0 -0
  30. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/agents/wt_tester.md +0 -0
  31. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/breaking-changes.txt +0 -0
  32. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/deletions.txt +0 -0
  33. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/docs/autonomous-mode-onboarding.md +0 -0
  34. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/docs/nul-boundary.md +0 -0
  35. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/docs/parallel-agents-setup.md +0 -0
  36. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/docs/platform-adapters.md +0 -0
  37. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/docs/settings.json.md +0 -0
  38. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/_hook_utils.py +0 -0
  39. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/check_agent_invocation.py +0 -0
  40. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/consolidate_memory.py +0 -0
  41. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/patterns_guard.py +0 -0
  42. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/planner_check.py +0 -0
  43. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/post_tool.py +0 -0
  44. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/pre_compact.py +0 -0
  45. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/pre_tool.py +0 -0
  46. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/recall_autorebuild.py +0 -0
  47. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/recall_inject.py +0 -0
  48. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/report_contract_check.py +0 -0
  49. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/report_path_guard.py +0 -0
  50. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/restore_session.py +0 -0
  51. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/select_tier.py +0 -0
  52. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/session_mode_watch.py +0 -0
  53. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/session_start.py +0 -0
  54. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/session_stop.py +0 -0
  55. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/session_utils.py +0 -0
  56. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/statusline.py +0 -0
  57. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/stop.py +0 -0
  58. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/tier_autoapply.py +0 -0
  59. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/tier_gap_check.py +0 -0
  60. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/hooks/worktree_guard.py +0 -0
  61. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/memory/.gitkeep +0 -0
  62. {claude_code_conductor-2.72.0/.claude/state → claude_code_conductor-2.73.0/.claude/memory/archive}/.gitkeep +0 -0
  63. /claude_code_conductor-2.72.0/tests/__init__.py → /claude_code_conductor-2.73.0/.claude/memory/sessions/.gitkeep +0 -0
  64. /claude_code_conductor-2.72.0/tests/hooks/__init__.py → /claude_code_conductor-2.73.0/.claude/reports/.gitkeep +0 -0
  65. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/rules/judgment-principles.md +0 -0
  66. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/rules/promoted/index.md +0 -0
  67. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/settings.json +0 -0
  68. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/autonomous-mode/SKILL.md +0 -0
  69. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/autonomous-mode/scripts/mode_line.py +0 -0
  70. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/brainstorm/SKILL.md +0 -0
  71. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/codex-review/SKILL.md +0 -0
  72. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/SKILL.md +0 -0
  73. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/c3-omission-declaration.md +0 -0
  74. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/code-review-checklist.md +0 -0
  75. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/design-critic-rubric.md +0 -0
  76. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/design-rubric.md +0 -0
  77. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/interview-rubric.md +0 -0
  78. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/plan-design-guidelines.md +0 -0
  79. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/reachability-map.md +0 -0
  80. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/record-protocol.md +0 -0
  81. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/security-review-checklist.md +0 -0
  82. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/scripts/detect_execution_verification.py +0 -0
  83. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/scripts/record_agent_outcome.py +0 -0
  84. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/scripts/record_review_decision.py +0 -0
  85. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/scripts/review_hint_inject.py +0 -0
  86. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/develop/SKILL.md +0 -0
  87. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/doc/SKILL.md +0 -0
  88. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/extract-lib/SKILL.md +0 -0
  89. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/init-session/SKILL.md +0 -0
  90. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/init-session/scripts/session_guard.py +0 -0
  91. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/mcp-config/SKILL.md +0 -0
  92. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/parallel-agents/SKILL.md +0 -0
  93. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/pattern-status/SKILL.md +0 -0
  94. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/promote-pattern/SKILL.md +0 -0
  95. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/recall/SKILL.md +0 -0
  96. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/report-timestamp/SKILL.md +0 -0
  97. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/report-timestamp/scripts/get_timestamp.py +0 -0
  98. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/review-phase/SKILL.md +0 -0
  99. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/setup/SKILL.md +0 -0
  100. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/setup/reference.md +0 -0
  101. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/setup/templates/coding-standards-template.md +0 -0
  102. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/setup/templates/project-conventions-template.md +0 -0
  103. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/start/SKILL.md +0 -0
  104. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/.claude/skills/start/scripts/archive_reports.py +0 -0
  105. /claude_code_conductor-2.72.0/tests/skills/__init__.py → /claude_code_conductor-2.73.0/.claude/state/.gitkeep +0 -0
  106. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/ARCHITECTURE.md +0 -0
  107. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/LICENSE +0 -0
  108. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/LICENSES/fastembed-LICENSE +0 -0
  109. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/LICENSES/fastembed-NOTICE +0 -0
  110. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/LICENSES/numpy-LICENSE +0 -0
  111. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/LICENSES/onnxruntime-LICENSE +0 -0
  112. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/LICENSES/paraphrase-multilingual-MiniLM-L12-v2-LICENSE +0 -0
  113. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/README.md +0 -0
  114. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/hatch_build.py +0 -0
  115. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/__main__.py +0 -0
  116. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/_db_params.py +0 -0
  117. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/_excludes.py +0 -0
  118. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/_terminal.py +0 -0
  119. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/adapters.py +0 -0
  120. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli.py +0 -0
  121. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_ask.py +0 -0
  122. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_doctor.py +0 -0
  123. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_init.py +0 -0
  124. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_list.py +0 -0
  125. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_metrics.py +0 -0
  126. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_plan.py +0 -0
  127. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_recall.py +0 -0
  128. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_run.py +0 -0
  129. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_tier.py +0 -0
  130. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/cli_update.py +0 -0
  131. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/db.py +0 -0
  132. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/embedding.py +0 -0
  133. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/gitutil.py +0 -0
  134. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/mcp_server.py +0 -0
  135. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrate.py +0 -0
  136. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/001_initial.sql +0 -0
  137. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/002_agent_cost_runs.sql +0 -0
  138. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/003_tier_cost.sql +0 -0
  139. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/004_agent_outcomes.sql +0 -0
  140. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/005_drop_agent_tier_bandit.sql +0 -0
  141. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/006_review_decisions_severity.sql +0 -0
  142. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/007_review_decisions_resolution.sql +0 -0
  143. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/008_drop_agent_runs.sql +0 -0
  144. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/README.md +0 -0
  145. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/migrations/__init__.py +0 -0
  146. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/paths.py +0 -0
  147. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/plan_validator.py +0 -0
  148. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/platforms.py +0 -0
  149. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/pricing.py +0 -0
  150. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/question.py +0 -0
  151. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/recall_chunker.py +0 -0
  152. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/recall_index.py +0 -0
  153. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/refgraph.py +0 -0
  154. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/src/c3/usage_ingester.py +0 -0
  155. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/_pre_compact_helpers.py +0 -0
  156. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/conftest.py +0 -0
  157. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/fixtures/usage/README.md +0 -0
  158. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/fixtures/usage/mainline.jsonl +0 -0
  159. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/fixtures/usage/subagents/agent-deadbeef.jsonl +0 -0
  160. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/fixtures/usage/subagents/agent-deadbeef.meta.json +0 -0
  161. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_check_agent_invocation.py +0 -0
  162. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_consolidate_memory.py +0 -0
  163. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_detect_execution_verification.py +0 -0
  164. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_hook_utils.py +0 -0
  165. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_pip_reinstall_reminder.py +0 -0
  166. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_planner_check.py +0 -0
  167. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_planner_check_dev.py +0 -0
  168. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_post_tool.py +0 -0
  169. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_pre_tool.py +0 -0
  170. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_recall_autorebuild.py +0 -0
  171. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_recall_inject.py +0 -0
  172. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_record_agent_outcome.py +0 -0
  173. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_record_review_decision.py +0 -0
  174. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_report_path_guard.py +0 -0
  175. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_restore_session.py +0 -0
  176. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_review_hint_inject.py +0 -0
  177. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_select_tier.py +0 -0
  178. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_select_tier_escalation.py +0 -0
  179. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_session_start.py +0 -0
  180. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_session_stop.py +0 -0
  181. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_session_utils.py +0 -0
  182. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_settings_local_absolute_paths.py +0 -0
  183. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_settings_tier_autoapply_registration.py +0 -0
  184. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_similarity_boost.py +0 -0
  185. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_statusline.py +0 -0
  186. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_statusline_template_sync.py +0 -0
  187. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_sync_check.py +0 -0
  188. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_template_guard.py +0 -0
  189. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_tier_autoapply.py +0 -0
  190. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_tier_gap_check.py +0 -0
  191. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/hooks/test_tier_security_fixes.py +0 -0
  192. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/_skill_helpers.py +0 -0
  193. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_c3_omission_declaration.py +0 -0
  194. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_dev_workflow_no_task_type.py +0 -0
  195. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_e0_verification_exit.py +0 -0
  196. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_init_session_no_task_type.py +0 -0
  197. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_marker_compliance.py +0 -0
  198. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_parallel_agents_skill_tier.py +0 -0
  199. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_planner_lightweight.py +0 -0
  200. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_reachability_map.py +0 -0
  201. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_recall_skill.py +0 -0
  202. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_session_backlog_reconciliation.py +0 -0
  203. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_session_guard.py +0 -0
  204. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_setup_templates.py +0 -0
  205. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_start_skill_bugfix_flow.py +0 -0
  206. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_start_skill_new_flow.py +0 -0
  207. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/skills/test_start_skill_security_audit_phase.py +0 -0
  208. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_adapters.py +0 -0
  209. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_archive_reports.py +0 -0
  210. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_audit_review_decisions.py +0 -0
  211. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_check_deletions.py +0 -0
  212. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_claude_gitignore.py +0 -0
  213. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_ask.py +0 -0
  214. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_doctor.py +0 -0
  215. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_doctor_launcher.py +0 -0
  216. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_entry.py +0 -0
  217. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_init.py +0 -0
  218. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_list.py +0 -0
  219. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_metrics.py +0 -0
  220. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_plan.py +0 -0
  221. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_recall.py +0 -0
  222. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_run.py +0 -0
  223. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_tier.py +0 -0
  224. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_update_breaking_changes.py +0 -0
  225. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_cli_update_deletions.py +0 -0
  226. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_db.py +0 -0
  227. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_db_connect_lint.py +0 -0
  228. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_docstring_consistency.py +0 -0
  229. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_embedding.py +0 -0
  230. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_excludes.py +0 -0
  231. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_extract_breaking_changes.py +0 -0
  232. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_gitutil.py +0 -0
  233. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_hooks_stdin_idiom.py +0 -0
  234. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_init_only_patterns.py +0 -0
  235. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_mcp_server_elicit.py +0 -0
  236. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_migrate.py +0 -0
  237. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_mode_line.py +0 -0
  238. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_no_bare_python_launcher.py +0 -0
  239. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_no_passonly_tests.py +0 -0
  240. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_nul_boundary_lint.py +0 -0
  241. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_paths.py +0 -0
  242. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_patterns_guard.py +0 -0
  243. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_permission_handler_removal.py +0 -0
  244. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_plan_validator.py +0 -0
  245. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_pre_compact.py +0 -0
  246. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_pre_tool_hook.py +0 -0
  247. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_precompact_additional.py +0 -0
  248. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_precompact_toctou_fixes.py +0 -0
  249. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_pricing.py +0 -0
  250. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_recall_chunker.py +0 -0
  251. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_recall_index.py +0 -0
  252. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_references_migration.py +0 -0
  253. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_refgraph.py +0 -0
  254. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_refgraph_query.py +0 -0
  255. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_refgraph_structural.py +0 -0
  256. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_report_contract_check.py +0 -0
  257. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_scripts_stdout_encoding.py +0 -0
  258. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_session_mode_watch.py +0 -0
  259. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_session_utils_additional.py +0 -0
  260. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_settings_hooks_registration.py +0 -0
  261. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_skill_no_builtin_conflict.py +0 -0
  262. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_start_skill_archive_contract.py +0 -0
  263. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_statusline.py +0 -0
  264. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_stop_additional.py +0 -0
  265. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_stop_agent_memory_warn.py +0 -0
  266. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_stop_hook.py +0 -0
  267. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_stop_precompact_fixes.py +0 -0
  268. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_sync_template_stop.py +0 -0
  269. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_template_pre_tool_hook.py +0 -0
  270. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_usage_ingester.py +0 -0
  271. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_worktree_guard.py +0 -0
  272. {claude_code_conductor-2.72.0 → claude_code_conductor-2.73.0}/tests/test_wt_agent_sync.py +0 -0
@@ -280,6 +280,9 @@ C3 の wheel 配布除外パターンは **3 つのファイルに分散して
280
280
  `hatch_build.py` の重複が必要な理由: hatch build hook はパッケージ import 前に走るため、
281
281
  `_excludes.py` を import できない。2 ファイルの完全一致が必須。
282
282
 
283
+ **KEEP 対象が sdist exclude 配下にある場合は `pyproject.toml` の force-include も同期対象**:
284
+ 公開ビルドは sdist を経由するため、sdist から落ちたファイルは wheel にも届かない。
285
+
283
286
  ### 同期確認の方法
284
287
 
285
288
  `.dev/hooks/_sync_check.py`(PostToolUse hook)が、3 ファイルのいずれかを変更した時に
@@ -289,8 +292,8 @@ C3 の wheel 配布除外パターンは **3 つのファイルに分散して
289
292
 
290
293
  1. `.gitignore` / `_excludes.py` / `hatch_build.py` のいずれかを変更
291
294
  2. `_sync_check.py` の警告を確認
292
- 3. 残り 2 ファイルに同じパターンを追加(または削除)
293
- 4. `python -m build --wheel` で wheel を再生成して実体検証
295
+ 3. 残り 2 ファイルに同じパターンを追加(または削除)。3 ファイルが既に同じ意図を持っている場合は、出遅れた 1 ファイルを合わせるだけでよい(配布元の root `.gitignore` を `KEEP_PATTERNS` の意図へ合わせた 2026-08-14 の是正が実例)
296
+ 4. 配布元では `python scripts/verify_wheel.py` で wheel 実体を機械検証する(`scripts/` は配布物に含まれないため、利用先には存在しないコマンド)
294
297
 
295
298
  ### 過去の同期漏れ defect
296
299
 
File without changes
@@ -3,8 +3,12 @@
3
3
  !.claude/reports/.gitkeep
4
4
 
5
5
  # Session memory (personal)
6
- .claude/memory/sessions/
7
- .claude/memory/archive/
6
+ # ディレクトリ形除外(`dir/`)の中へ git は降りないため否定行が効かない。
7
+ # KEEP_PATTERNS(_excludes.py / hatch_build.py)は各ディレクトリの .gitkeep を
8
+ # 配布対象としているため、`dir/*` 形+否定行で .gitkeep だけを tracked にする。
9
+ .claude/memory/sessions/*
10
+ !.claude/memory/sessions/.gitkeep
11
+ .claude/memory/archive/*
8
12
  !.claude/memory/archive/.gitkeep
9
13
  .claude/memory/patterns.json
10
14
  .claude/memory/agent-audit.log
@@ -15,7 +19,8 @@
15
19
  .claude/agent-memory/
16
20
 
17
21
  # Temporary files
18
- .claude/tmp/
22
+ .claude/tmp/*
23
+ !.claude/tmp/.gitkeep
19
24
 
20
25
  # PO task execution logs
21
26
  .claude/logs/
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.73.0] - 2026-08-15
4
+
5
+ ### 追加
6
+
7
+ - **リリース前 wheel 実体検証を CI 機械化した**: `scripts/verify_wheel.py`(配布元専用 dev ツール・
8
+ wheel/sdist 非収録)を追加し、`.github/workflows/test.yml` に `wheel-check` job を新設した。
9
+ 公開経路と同じビルド(sdist 経由)で作った wheel の中身が `src/c3/_excludes.py` の意図
10
+ (EXCLUDE 不混入・KEEP 全件存在・`breaking-changes.txt` 在/`state/c3_version.txt` 不在)と
11
+ 一致するかを毎 push 検証する。exit code は 0 = PASS / 1 = 違反 / 3 = 検証不能。
12
+ 「除外フィルタが実際には何も落としていないのに緑」になるのを防ぐため、
13
+ `.claude/state/setup_done.flag` を sdist にだけ注入する正の対照を組み込んでいる。
14
+ - sdist(第二の公開成果物)側の EXCLUDE 混入検査と対照サイズ検査を追加
15
+ (違反種別 `SDIST_EXCLUDE_VIOLATION` / `CONTROL_NOT_EMPTY`)。違反 detail のサニタイズは
16
+ 正本 `.claude/hooks/_hook_utils.py` の `_TERMINAL_SANITIZE_RE` と同一の全クラス
17
+ (C0/DEL/C1・ゼロ幅・行区切り・双方向制御・BOM)へ被覆拡張し、sdist member は
18
+ 種別(file/link/dir)で検査対象を振り分ける(EXCLUDE 名前検査は file+link・
19
+ 候補件数の母数と対照系検査は file のみ・dir は全検査の対象外)。
20
+
21
+ ### 修正
22
+
23
+ - **KEEP 対象の `.gitkeep` が公開 wheel に届いていなかった問題を是正した**: `KEEP_PATTERNS` が
24
+ 配布対象と定めている `.claude/memory/sessions/.gitkeep` と `.claude/tmp/.gitkeep` を新規作成し、
25
+ root `.gitignore` のディレクトリ形除外(否定行が効かない形)を `dir/*` 形+否定行へ直した。
26
+ この是正により、既存の `.claude/memory/archive/.gitkeep` も新たに git 追跡対象になった。
27
+ あわせて `pyproject.toml` の sdist force-include で `reports/.gitkeep` /
28
+ `memory/sessions/.gitkeep` / `tmp/.gitkeep` を救済し、sdist 経由の公開 wheel に KEEP 8 件が
29
+ すべて入るようにした(これまでの公開 wheel は `reports/.gitkeep` 等を欠いていた)。
30
+
3
31
  ## [2.72.0] - 2026-08-14
4
32
 
5
33
  ### 破壊的変更
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: claude-code-conductor
3
- Version: 2.72.0
3
+ Version: 2.73.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
@@ -72,6 +72,24 @@ exclude = [
72
72
  ".claude/docs/taxonomy.md",
73
73
  ]
74
74
 
75
+ # 公開ビルドは `python -m build`(引数なし)= sdist を作り、その sdist から wheel を作る。
76
+ # 上の exclude / VCS ignore で落ちるが sdist に入れなければならないファイルをここで救済する。
77
+ # **役割が逆向きの 2 群**が同居しているので取り違えないこと。
78
+ #
79
+ # 群 1: KEEP 救済(wheel に **残る** べき側)
80
+ # `_excludes.py` / `hatch_build.py` の KEEP_PATTERNS が配布対象と定めている .gitkeep。
81
+ # sdist exclude に該当して落ちると、sdist 経由の wheel から KEEP が欠落する。
82
+ # 群 2: 注入対照(wheel で **落ちる** べき側)
83
+ # `state/setup_done.flag` は VCS ignore(root `.gitignore` の `.claude/state/*`)で
84
+ # sdist から落ちるが、これが無いと除外フィルタが実際に通過する候補が 0 件になり
85
+ # 「空の緑」(何も落とさずに緑)になる。sdist にだけ入れ、wheel ビルド時に
86
+ # hatch_build の should_skip が `state/*` で落とすことを scripts/verify_wheel.py が検証する。
87
+ [tool.hatch.build.targets.sdist.force-include]
88
+ ".claude/reports/.gitkeep" = ".claude/reports/.gitkeep"
89
+ ".claude/memory/sessions/.gitkeep" = ".claude/memory/sessions/.gitkeep"
90
+ ".claude/tmp/.gitkeep" = ".claude/tmp/.gitkeep"
91
+ ".claude/state/setup_done.flag" = ".claude/state/setup_done.flag"
92
+
75
93
  [tool.pytest.ini_options]
76
94
  testpaths = ["tests"]
77
95
  markers = ["slow: marks tests as slow"]
@@ -1,3 +1,3 @@
1
1
  """Claude Code Conductor (C3) - multi-agent orchestration framework for Claude Code."""
2
2
 
3
- __version__ = "2.72.0"
3
+ __version__ = "2.73.0"
File without changes
File without changes
File without changes
@@ -1,8 +1,18 @@
1
1
  """
2
2
  tests/test_ci_workflows.py
3
3
 
4
- .github/workflows/test.yml が `scripts/check_deletions.py --check` を実行する CI job を
5
- 持ち続けること、かつその job の checkout が `fetch-depth: 0` を持ち続けることを守るテスト。
4
+ .github/workflows/test.yml が dev script を実行する CI job を持ち続けることを守るテスト。
5
+
6
+ 対象は 2 系統:
7
+
8
+ 1. `scripts/check_deletions.py --check` を実行する job(+ checkout の `fetch-depth: 0`)
9
+ 2. `scripts/verify_wheel.py` を実行する job(`wheel-check`。P6・**Red フェーズでは不在**)
10
+
11
+ 2 の凍結項目は 4 つ(architecture 改訂 3 ADR-5 改訂 2):
12
+ (1) job の存在 (2) run に `--wheel` を含まない(公開等価=実ビルド経路の凍結)
13
+ (3) `build`(PyPA build)のインストールステップ (4) `permissions == {contents: read}`。
14
+ 「空の緑」対策(注入対照の実働実証)は script 内蔵のため YAML では測らない
15
+ (tests/test_verify_wheel.py の P8 が凍結する)。
6
16
 
7
17
  ## なぜ fetch-depth: 0 が本質か
8
18
 
@@ -54,6 +64,7 @@ YAML 1.1 のブール解決により、PyYAML の `yaml.safe_load()` は `on:`
54
64
  from __future__ import annotations
55
65
 
56
66
  import os
67
+ import re
57
68
  from pathlib import Path
58
69
 
59
70
  import yaml
@@ -203,3 +214,114 @@ def test_test_yml_check_deletions_job_declares_permissions():
203
214
  " 本 job は checkout して読み取り専用の削除検出を行うだけなので、"
204
215
  " permissions: {contents: read} を想定している。"
205
216
  )
217
+
218
+
219
+ # ---------------------------------------------------------------------------
220
+ # P6: wheel-check job(scripts/verify_wheel.py)の静的検査
221
+ #
222
+ # Red フェーズでは job 自体が test.yml に無いため、4 本とも「job が無い」で失敗する。
223
+ # ---------------------------------------------------------------------------
224
+
225
+ _VERIFY_WHEEL_MARKER = "verify_wheel.py"
226
+ _WHEEL_FLAG_MARKER = "--wheel"
227
+ # PyPA build の導入ステップ(`python -m pip install build` 等)。
228
+ # `pip install -e .` と同一 job 内の別ステップでも良いよう、run 文字列単位で探す。
229
+ _BUILD_INSTALL_RE = re.compile(r"pip\s+install\b[^\n]*\bbuild\b")
230
+
231
+
232
+ def _iter_step_runs(job_def: dict) -> list[str]:
233
+ """job の各ステップの `run:` 文字列を列挙する。"""
234
+ runs: list[str] = []
235
+ steps = job_def.get("steps", [])
236
+ if not isinstance(steps, list):
237
+ return runs
238
+ for step in steps:
239
+ if not isinstance(step, dict):
240
+ continue
241
+ run = step.get("run", "")
242
+ if isinstance(run, str) and run:
243
+ runs.append(run)
244
+ return runs
245
+
246
+
247
+ def _find_job_running_marker(workflow: dict, marker: str) -> tuple[str | None, dict | None]:
248
+ """`run:` 文字列に `marker` を含むステップを持つ job を探す(job 名に依存しない)。"""
249
+ jobs = workflow.get("jobs", {})
250
+ if not isinstance(jobs, dict):
251
+ return None, None
252
+
253
+ for job_name, job_def in jobs.items():
254
+ if not isinstance(job_def, dict):
255
+ continue
256
+ if any(marker in run for run in _iter_step_runs(job_def)):
257
+ return job_name, job_def
258
+
259
+ return None, None
260
+
261
+
262
+ def _require_wheel_check_job() -> tuple[str, dict]:
263
+ """wheel-check job を取得する。無ければ失敗させる(4 本共通の前提)。"""
264
+ workflow = _load_workflow("test.yml")
265
+ job_name, job_def = _find_job_running_marker(workflow, _VERIFY_WHEEL_MARKER)
266
+ assert job_name is not None and job_def is not None, (
267
+ "test.yml に 'python scripts/verify_wheel.py' を実行する job が見つからない。"
268
+ " リリース前の wheel 実体検証(/CLAUDE.md §3・§6 手順 5)を CI で機械強制するには、"
269
+ " 専用 job(wheel-check)のステップに verify_wheel.py の実行を追加する必要がある。"
270
+ )
271
+ return job_name, job_def
272
+
273
+
274
+ def test_test_yml_has_wheel_check_job():
275
+ """P6-(1) test.yml に scripts/verify_wheel.py を実行する job が存在すること。"""
276
+ _require_wheel_check_job()
277
+
278
+
279
+ def test_wheel_check_job_runs_the_build_route_not_an_existing_wheel():
280
+ """P6-(2) verify_wheel.py の run に `--wheel` を含まないこと。
281
+
282
+ `--wheel <path>` は「手元にある既存 wheel を検証する」モードであり、公開経路と
283
+ 同一のビルド(sdist 経由)を回さない。CI がこちらに倒れると、検証対象が
284
+ 「公開される wheel」ではなくなり、実ビルド経路の退行を検出できなくなる。
285
+ """
286
+ job_name, job_def = _require_wheel_check_job()
287
+
288
+ offending = [
289
+ run
290
+ for run in _iter_step_runs(job_def)
291
+ if _VERIFY_WHEEL_MARKER in run and _WHEEL_FLAG_MARKER in run
292
+ ]
293
+ assert not offending, (
294
+ f"job '{job_name}' の verify_wheel.py 実行に --wheel が含まれている: {offending!r}。"
295
+ " CI は既定(フラグなし= sdist 経由の実ビルド)で実行すること。"
296
+ )
297
+
298
+
299
+ def test_wheel_check_job_installs_pypa_build():
300
+ """P6-(3) PyPA `build` を導入するステップがあること。
301
+
302
+ 既定モードは `python -m build` を呼ぶため、build が未導入だと job は
303
+ BUILD_TOOL_MISSING(exit 3)で常に赤くなる。
304
+ """
305
+ job_name, job_def = _require_wheel_check_job()
306
+
307
+ runs = _iter_step_runs(job_def)
308
+ assert any(_BUILD_INSTALL_RE.search(run) for run in runs), (
309
+ f"job '{job_name}' に PyPA build を導入するステップ(例: "
310
+ f"`python -m pip install build`)が見つからない: {runs!r}"
311
+ )
312
+
313
+
314
+ def test_wheel_check_job_declares_read_only_permissions():
315
+ """P6-(4) permissions が `{contents: read}` に完全一致すること。
316
+
317
+ job レベルで permissions を明示しないと、GITHUB_TOKEN はリポジトリ設定依存の
318
+ 既定権限で動作する。本 job は checkout してビルドと読み取り検証を行うだけなので
319
+ 最小権限に絞る(deletions-check job と同じ方針)。
320
+ """
321
+ job_name, job_def = _require_wheel_check_job()
322
+
323
+ permissions = job_def.get("permissions")
324
+ assert permissions == {"contents": "read"}, (
325
+ f"job '{job_name}' の permissions が {{contents: read}} と一致しない"
326
+ f"(実際の値: {permissions!r})。"
327
+ )
@@ -24,13 +24,13 @@ architecture-report-20260804-235224.md ADR-10
24
24
  ## 検査内容
25
25
 
26
26
  1. `scripts/*.py` のうち `c3` を import しているファイルを動的に列挙する
27
- (ハードコードしない。3本目が増えても黙って検査を免れない)
27
+ (ハードコードしない。対象ファイルが増えても黙って検査を免れない)
28
28
  2. 各ファイルについて、`PYTHONPATH` を明示的に除いた subprocess で
29
29
  `runpy.run_path(<file>, run_name=<"__main__" 以外>)` によりモジュールレベルの
30
30
  コード(bootstrap 行を含む)を実行し、`sys.modules["c3"].__file__` を取得する
31
31
  (`run_name` を `"__main__"` 以外にすることで `if __name__ == "__main__":` 配下の
32
32
  処理は実行されない。ADR-10 改訂3-b の前提: 対象スクリプトは import 時に
33
- 副作用を持たない = 現行2本は実測済み)
33
+ 副作用を持たない = 現行の対象ファイルは全て実測済み)
34
34
  3. その `__file__` が repo の `src/c3/` 配下であることを確認する。
35
35
  site-packages 等それ以外を指していたら違反とする
36
36
 
@@ -71,7 +71,7 @@ Windows は非 editable のため全緑に見えて検出できなかった)
71
71
 
72
72
  `-S`(site を読まない)で起動する案も検討したが不採用。`site-packages` 全体が
73
73
  落ちるため、`scripts/*.py` が将来 stdlib と `c3` 以外へ依存した時点で**正の対照が
74
- 壊れる**(現行 2 本は stdlib のみと実測済みだが、その前提に検査の正しさを
74
+ 壊れる**(現行の対象ファイルは stdlib のみと実測済みだが、その前提に検査の正しさを
75
75
  括り付けたくない)。また `sitecustomize` 等 `-S` で消えない注入経路もあり、
76
76
  「除去」方式の方が射程が広い。
77
77
 
@@ -245,7 +245,7 @@ def _iter_scripts_importing_c3() -> list[Path]:
245
245
  """`scripts/*.py` のうち `c3` を import しているファイルを動的に列挙する。
246
246
 
247
247
  ハードコードされたファイル名リストに依存すると、将来 `scripts/` 配下に
248
- 第3のファイルが追加され `c3` を import しても、リストへの追記漏れで
248
+ 新たなファイルが追加され `c3` を import しても、リストへの追記漏れで
249
249
  この検査を黙ってすり抜ける(CR-NEW Medium 実測・E周回2)。走査結果を毎回
250
250
  AST で判定することでこれを防ぐ。
251
251
  """
@@ -408,7 +408,7 @@ class TestScriptsResolveC3FromRepoSrc:
408
408
 
409
409
  class TestResolveC3FileViaSubprocessDetectsViolations:
410
410
  """`resolve_c3_file_via_subprocess()` 自体が振る舞いレベルで違反を検出できる
411
- ことの合成スクリプトでの裏取り。実運用ファイル(現状2件とも正しい)だけでは
411
+ ことの合成スクリプトでの裏取り。実運用ファイル(現状は全て正しい)だけでは
412
412
  この関数の検出力そのものは裏取りできないため、合成スクリプトで直接検証する。
413
413
 
414
414
  - 「見逃さない」: ブートストラップが無い/壊れている/誤った場所を指す