claude-code-conductor 2.71.1__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 (277) hide show
  1. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/breaking-changes.txt +1 -0
  2. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/deletions.txt +6 -1
  3. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/docs/config-policy.md +14 -24
  4. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/settings.json +0 -13
  5. claude_code_conductor-2.73.0/.claude/state/setup_done.flag +0 -0
  6. claude_code_conductor-2.73.0/.claude/tmp/.gitkeep +0 -0
  7. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.gitignore +8 -3
  8. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/ARCHITECTURE.md +0 -1
  9. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/CHANGELOG.md +54 -0
  10. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/PKG-INFO +1 -3
  11. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/pyproject.toml +18 -4
  12. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/__init__.py +1 -1
  13. claude_code_conductor-2.73.0/tests/__init__.py +0 -0
  14. claude_code_conductor-2.73.0/tests/hooks/__init__.py +0 -0
  15. claude_code_conductor-2.73.0/tests/skills/__init__.py +0 -0
  16. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_ci_workflows.py +124 -2
  17. claude_code_conductor-2.73.0/tests/test_permission_handler_removal.py +154 -0
  18. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_refgraph.py +6 -6
  19. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_refgraph_query.py +1 -1
  20. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_refgraph_structural.py +22 -15
  21. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_scripts_src_bootstrap.py +5 -5
  22. claude_code_conductor-2.73.0/tests/test_verify_wheel.py +1939 -0
  23. claude_code_conductor-2.71.1/.claude/hooks/permission_handler.py +0 -402
  24. claude_code_conductor-2.71.1/.claude/hooks/permission_handler_toast.py +0 -208
  25. claude_code_conductor-2.71.1/.claude/permission_rules.json +0 -41
  26. claude_code_conductor-2.71.1/tests/hooks/test_permission_handler.py +0 -1495
  27. claude_code_conductor-2.71.1/tests/hooks/test_permission_handler_toast.py +0 -199
  28. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/.gitignore +0 -0
  29. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/CLAUDE.md +0 -0
  30. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/architect.md +0 -0
  31. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/code-reviewer.md +0 -0
  32. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/design-critic.md +0 -0
  33. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/developer.md +0 -0
  34. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/doc-writer.md +0 -0
  35. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/interviewer.md +0 -0
  36. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/planner.md +0 -0
  37. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/project-setup.md +0 -0
  38. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/security-reviewer.md +0 -0
  39. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/systematic-debugger.md +0 -0
  40. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/tester.md +0 -0
  41. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/wt_developer.md +0 -0
  42. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/wt_systematic-debugger.md +0 -0
  43. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/agents/wt_tester.md +0 -0
  44. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/docs/autonomous-mode-onboarding.md +0 -0
  45. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/docs/nul-boundary.md +0 -0
  46. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/docs/parallel-agents-setup.md +0 -0
  47. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/docs/platform-adapters.md +0 -0
  48. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/docs/settings.json.md +0 -0
  49. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/_hook_utils.py +0 -0
  50. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/check_agent_invocation.py +0 -0
  51. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/consolidate_memory.py +0 -0
  52. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/patterns_guard.py +0 -0
  53. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/planner_check.py +0 -0
  54. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/post_tool.py +0 -0
  55. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/pre_compact.py +0 -0
  56. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/pre_tool.py +0 -0
  57. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/recall_autorebuild.py +0 -0
  58. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/recall_inject.py +0 -0
  59. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/report_contract_check.py +0 -0
  60. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/report_path_guard.py +0 -0
  61. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/restore_session.py +0 -0
  62. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/select_tier.py +0 -0
  63. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/session_mode_watch.py +0 -0
  64. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/session_start.py +0 -0
  65. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/session_stop.py +0 -0
  66. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/session_utils.py +0 -0
  67. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/statusline.py +0 -0
  68. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/stop.py +0 -0
  69. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/tier_autoapply.py +0 -0
  70. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/tier_gap_check.py +0 -0
  71. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/hooks/worktree_guard.py +0 -0
  72. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/memory/.gitkeep +0 -0
  73. {claude_code_conductor-2.71.1/.claude/state → claude_code_conductor-2.73.0/.claude/memory/archive}/.gitkeep +0 -0
  74. /claude_code_conductor-2.71.1/tests/__init__.py → /claude_code_conductor-2.73.0/.claude/memory/sessions/.gitkeep +0 -0
  75. /claude_code_conductor-2.71.1/tests/hooks/__init__.py → /claude_code_conductor-2.73.0/.claude/reports/.gitkeep +0 -0
  76. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/rules/judgment-principles.md +0 -0
  77. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/rules/promoted/index.md +0 -0
  78. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/autonomous-mode/SKILL.md +0 -0
  79. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/autonomous-mode/scripts/mode_line.py +0 -0
  80. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/brainstorm/SKILL.md +0 -0
  81. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/codex-review/SKILL.md +0 -0
  82. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/SKILL.md +0 -0
  83. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/c3-omission-declaration.md +0 -0
  84. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/code-review-checklist.md +0 -0
  85. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/design-critic-rubric.md +0 -0
  86. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/design-rubric.md +0 -0
  87. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/interview-rubric.md +0 -0
  88. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/plan-design-guidelines.md +0 -0
  89. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/reachability-map.md +0 -0
  90. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/record-protocol.md +0 -0
  91. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/references/security-review-checklist.md +0 -0
  92. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/scripts/detect_execution_verification.py +0 -0
  93. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/scripts/record_agent_outcome.py +0 -0
  94. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/scripts/record_review_decision.py +0 -0
  95. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/dev-workflow/scripts/review_hint_inject.py +0 -0
  96. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/develop/SKILL.md +0 -0
  97. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/doc/SKILL.md +0 -0
  98. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/extract-lib/SKILL.md +0 -0
  99. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/init-session/SKILL.md +0 -0
  100. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/init-session/scripts/session_guard.py +0 -0
  101. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/mcp-config/SKILL.md +0 -0
  102. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/parallel-agents/SKILL.md +0 -0
  103. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/pattern-status/SKILL.md +0 -0
  104. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/promote-pattern/SKILL.md +0 -0
  105. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/recall/SKILL.md +0 -0
  106. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/report-timestamp/SKILL.md +0 -0
  107. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/report-timestamp/scripts/get_timestamp.py +0 -0
  108. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/review-phase/SKILL.md +0 -0
  109. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/setup/SKILL.md +0 -0
  110. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/setup/reference.md +0 -0
  111. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/setup/templates/coding-standards-template.md +0 -0
  112. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/setup/templates/project-conventions-template.md +0 -0
  113. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/start/SKILL.md +0 -0
  114. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/.claude/skills/start/scripts/archive_reports.py +0 -0
  115. /claude_code_conductor-2.71.1/tests/skills/__init__.py → /claude_code_conductor-2.73.0/.claude/state/.gitkeep +0 -0
  116. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/LICENSE +0 -0
  117. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/LICENSES/fastembed-LICENSE +0 -0
  118. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/LICENSES/fastembed-NOTICE +0 -0
  119. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/LICENSES/numpy-LICENSE +0 -0
  120. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/LICENSES/onnxruntime-LICENSE +0 -0
  121. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/LICENSES/paraphrase-multilingual-MiniLM-L12-v2-LICENSE +0 -0
  122. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/README.md +0 -0
  123. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/hatch_build.py +0 -0
  124. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/__main__.py +0 -0
  125. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/_db_params.py +0 -0
  126. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/_excludes.py +0 -0
  127. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/_terminal.py +0 -0
  128. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/adapters.py +0 -0
  129. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli.py +0 -0
  130. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_ask.py +0 -0
  131. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_doctor.py +0 -0
  132. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_init.py +0 -0
  133. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_list.py +0 -0
  134. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_metrics.py +0 -0
  135. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_plan.py +0 -0
  136. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_recall.py +0 -0
  137. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_run.py +0 -0
  138. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_tier.py +0 -0
  139. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/cli_update.py +0 -0
  140. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/db.py +0 -0
  141. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/embedding.py +0 -0
  142. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/gitutil.py +0 -0
  143. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/mcp_server.py +0 -0
  144. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrate.py +0 -0
  145. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/001_initial.sql +0 -0
  146. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/002_agent_cost_runs.sql +0 -0
  147. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/003_tier_cost.sql +0 -0
  148. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/004_agent_outcomes.sql +0 -0
  149. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/005_drop_agent_tier_bandit.sql +0 -0
  150. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/006_review_decisions_severity.sql +0 -0
  151. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/007_review_decisions_resolution.sql +0 -0
  152. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/008_drop_agent_runs.sql +0 -0
  153. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/README.md +0 -0
  154. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/migrations/__init__.py +0 -0
  155. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/paths.py +0 -0
  156. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/plan_validator.py +0 -0
  157. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/platforms.py +0 -0
  158. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/pricing.py +0 -0
  159. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/question.py +0 -0
  160. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/recall_chunker.py +0 -0
  161. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/recall_index.py +0 -0
  162. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/refgraph.py +0 -0
  163. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/src/c3/usage_ingester.py +0 -0
  164. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/_pre_compact_helpers.py +0 -0
  165. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/conftest.py +0 -0
  166. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/fixtures/usage/README.md +0 -0
  167. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/fixtures/usage/mainline.jsonl +0 -0
  168. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/fixtures/usage/subagents/agent-deadbeef.jsonl +0 -0
  169. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/fixtures/usage/subagents/agent-deadbeef.meta.json +0 -0
  170. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_check_agent_invocation.py +0 -0
  171. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_consolidate_memory.py +0 -0
  172. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_detect_execution_verification.py +0 -0
  173. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_hook_utils.py +0 -0
  174. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_pip_reinstall_reminder.py +0 -0
  175. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_planner_check.py +0 -0
  176. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_planner_check_dev.py +0 -0
  177. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_post_tool.py +0 -0
  178. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_pre_tool.py +0 -0
  179. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_recall_autorebuild.py +0 -0
  180. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_recall_inject.py +0 -0
  181. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_record_agent_outcome.py +0 -0
  182. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_record_review_decision.py +0 -0
  183. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_report_path_guard.py +0 -0
  184. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_restore_session.py +0 -0
  185. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_review_hint_inject.py +0 -0
  186. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_select_tier.py +0 -0
  187. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_select_tier_escalation.py +0 -0
  188. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_session_start.py +0 -0
  189. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_session_stop.py +0 -0
  190. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_session_utils.py +0 -0
  191. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_settings_local_absolute_paths.py +0 -0
  192. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_settings_tier_autoapply_registration.py +0 -0
  193. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_similarity_boost.py +0 -0
  194. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_statusline.py +0 -0
  195. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_statusline_template_sync.py +0 -0
  196. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_sync_check.py +0 -0
  197. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_template_guard.py +0 -0
  198. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_tier_autoapply.py +0 -0
  199. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_tier_gap_check.py +0 -0
  200. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/hooks/test_tier_security_fixes.py +0 -0
  201. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/_skill_helpers.py +0 -0
  202. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_c3_omission_declaration.py +0 -0
  203. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_dev_workflow_no_task_type.py +0 -0
  204. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_e0_verification_exit.py +0 -0
  205. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_init_session_no_task_type.py +0 -0
  206. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_marker_compliance.py +0 -0
  207. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_parallel_agents_skill_tier.py +0 -0
  208. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_planner_lightweight.py +0 -0
  209. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_reachability_map.py +0 -0
  210. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_recall_skill.py +0 -0
  211. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_session_backlog_reconciliation.py +0 -0
  212. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_session_guard.py +0 -0
  213. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_setup_templates.py +0 -0
  214. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_start_skill_bugfix_flow.py +0 -0
  215. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_start_skill_new_flow.py +0 -0
  216. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/skills/test_start_skill_security_audit_phase.py +0 -0
  217. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_adapters.py +0 -0
  218. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_archive_reports.py +0 -0
  219. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_audit_review_decisions.py +0 -0
  220. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_check_deletions.py +0 -0
  221. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_claude_gitignore.py +0 -0
  222. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_ask.py +0 -0
  223. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_doctor.py +0 -0
  224. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_doctor_launcher.py +0 -0
  225. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_entry.py +0 -0
  226. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_init.py +0 -0
  227. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_list.py +0 -0
  228. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_metrics.py +0 -0
  229. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_plan.py +0 -0
  230. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_recall.py +0 -0
  231. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_run.py +0 -0
  232. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_tier.py +0 -0
  233. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_update_breaking_changes.py +0 -0
  234. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_cli_update_deletions.py +0 -0
  235. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_db.py +0 -0
  236. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_db_connect_lint.py +0 -0
  237. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_docstring_consistency.py +0 -0
  238. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_embedding.py +0 -0
  239. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_excludes.py +0 -0
  240. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_extract_breaking_changes.py +0 -0
  241. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_gitutil.py +0 -0
  242. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_hooks_stdin_idiom.py +0 -0
  243. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_init_only_patterns.py +0 -0
  244. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_mcp_server_elicit.py +0 -0
  245. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_migrate.py +0 -0
  246. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_mode_line.py +0 -0
  247. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_no_bare_python_launcher.py +0 -0
  248. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_no_passonly_tests.py +0 -0
  249. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_nul_boundary_lint.py +0 -0
  250. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_paths.py +0 -0
  251. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_patterns_guard.py +0 -0
  252. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_plan_validator.py +0 -0
  253. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_pre_compact.py +0 -0
  254. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_pre_tool_hook.py +0 -0
  255. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_precompact_additional.py +0 -0
  256. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_precompact_toctou_fixes.py +0 -0
  257. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_pricing.py +0 -0
  258. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_recall_chunker.py +0 -0
  259. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_recall_index.py +0 -0
  260. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_references_migration.py +0 -0
  261. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_report_contract_check.py +0 -0
  262. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_scripts_stdout_encoding.py +0 -0
  263. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_session_mode_watch.py +0 -0
  264. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_session_utils_additional.py +0 -0
  265. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_settings_hooks_registration.py +0 -0
  266. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_skill_no_builtin_conflict.py +0 -0
  267. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_start_skill_archive_contract.py +0 -0
  268. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_statusline.py +0 -0
  269. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_stop_additional.py +0 -0
  270. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_stop_agent_memory_warn.py +0 -0
  271. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_stop_hook.py +0 -0
  272. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_stop_precompact_fixes.py +0 -0
  273. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_sync_template_stop.py +0 -0
  274. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_template_pre_tool_hook.py +0 -0
  275. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_usage_ingester.py +0 -0
  276. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_worktree_guard.py +0 -0
  277. {claude_code_conductor-2.71.1 → claude_code_conductor-2.73.0}/tests/test_wt_agent_sync.py +0 -0
@@ -13,3 +13,4 @@ v2.58.0|c3 init and c3 update now place .claude/.gitignore in the target project
13
13
  v2.60.0|c3 plan validate/waves now strictly validate po_plan_version: only "0.1" (parallel) or "sequential" (sequential TDD) quoted strings are accepted; unknown or non-string values fail with exit 2. Migrate existing plan-reports by setting po_plan_version: "0.1" or "sequential" (quoted).|po_plan_version の値を厳格検査("0.1"/"sequential" のみ受理・他は exit 2)。既存 plan-report は引用符付きの正値へ修正する。
14
14
  v2.66.0|record_review_decision.py: --severity is now a required argument (omitting it exits 2 and records nothing; out-of-vocabulary values still fail-safe to NULL with a warning). --finding now rejects empty or whitespace-only values (exit 2). Update any custom invocations to pass --severity with one of critical/high/medium/low. Shipped SKILL.md call sites and docstrings are already updated.|
15
15
  v2.68.0|New PreToolUse Write hook report_path_guard.py is registered in the distributed settings.json. It blocks (exit 2) writes of report-prefixed filenames (requirements-report-, architecture-report-, plan-report-, design-review-report-, code-review-report-, security-review-report-, test-report-, debug-analysis-, debug-needed-) outside .claude/reports/, overwrites of existing timestamp-named reports, and non-timestamp naming for the strict 4 report types. Ordinary files whose names start with those prefixes can no longer be written outside .claude/reports/. Set C3_REPORT_GUARD_DISABLE=1 to bypass, or remove the hook registration from settings.json.|レポート 9 prefix 名ファイルの .claude/reports/ 外への Write・タイムスタンプ形式既存レポートの上書き・strict-4 の非タイムスタンプ命名を exit 2 で block する report_path_guard hook を配布 settings.json に登録。対象 prefix 名の一般ファイルも block されうる。回避は C3_REPORT_GUARD_DISABLE=1 または settings.json から登録を外す。
16
+ v2.72.0|Removed the C3 PermissionRequest hook suite (permission_handler.py, permission_handler_toast.py, permission_rules.json) and the [notify] extra, superseded by upstream auto mode and permissions.allow. If you have not yet copied your auto_allow patterns from .claude/permission_rules.json, answer N (default) at the upcoming deletion prompt, copy them into permissions.allow in .claude/settings.local.json (personal, not the shared settings.json; same syntax; upstream checks each separator-delimited subcommand of compound commands independently, but command substitution handling is unverified -- narrow broad Bash wildcards to the minimum prefix; copying is a must where auto mode is unavailable), then rerun c3 update. windows-toasts can be uninstalled.|C3 の PermissionRequest hook 一式(permission_handler.py・permission_handler_toast.py・permission_rules.json)と [notify] extra を削除しました(上流 auto mode / permissions.allow へ委譲)。auto_allow パターンを未転記の場合は、この後の削除プロンプトで N(既定)を選び、.claude/permission_rules.json の内容を .claude/settings.local.json(個人設定・共有の settings.json ではない)の permissions.allow へ転記してから c3 update を再実行してください(書式は同一。上流は複合コマンドをセパレータ単位で独立照合しますが、コマンド置換〔$() 等〕の扱いは未確認のため、広い Bash ワイルドカードは必要最小のプレフィックスへ狭めること。auto mode が使えない環境では転記必須)。windows-toasts はアンインストール可。
@@ -8,7 +8,7 @@
8
8
  # - 絶対パス / ../ を含むパス / シンボリックリンク は無視
9
9
  # - ディレクトリは削除しない(ファイルのみ)
10
10
  #
11
- # 詳細は .claude/docs/config-policy.md §3 #13 と §7 落とし穴 5 を参照。
11
+ # 詳細は .claude/docs/config-policy.md §3 #13 と §7 落とし穴 4 を参照。
12
12
 
13
13
  # ---- v2.1.0: tdd-develop / worktree-tdd-workflow 廃止 ----
14
14
  agents/tdd-develop.md
@@ -87,3 +87,8 @@ hooks/po_heartbeat.py
87
87
 
88
88
  # ---- v2.41.0: tier-routing 学習シグナル再設計(record_agent_outcome.py へ置換) ----
89
89
  skills/dev-workflow/scripts/record_tier_outcome.py
90
+
91
+ # ---- v2.72.0: permission_handler 一式廃止(上流 permissions.allow へ委譲) ----
92
+ hooks/permission_handler.py
93
+ hooks/permission_handler_toast.py
94
+ permission_rules.json
@@ -20,7 +20,6 @@
20
20
  .claude/CLAUDE.md 配布元・配布先共通(常時注入)
21
21
  .claude/settings.json プロジェクト共通設定(配布される)
22
22
  .claude/settings.local.json 個人 override(配布されない)
23
- .claude/permission_rules.json C3 独自の自動承認パターン(配布される)
24
23
  .claude/rules/ C3 配布デフォルトルール(配布される)
25
24
  .claude/rules/promoted/ プロジェクト固有昇格ルール(配布される、update は触らない)
26
25
  .claude/hooks/ Claude Code lifecycle hooks(配布される)
@@ -36,7 +35,6 @@ src/c3/migrations/ SQLite schema migration SQL ファイル
36
35
  .claude/CLAUDE.md c3 init で配置・c3 update で更新
37
36
  .claude/settings.json c3 init で配置・c3 update で更新
38
37
  .claude/settings.local.json ユーザーが個別作成(c3 は触らない)
39
- .claude/permission_rules.json c3 init で配置・c3 update で更新
40
38
  .claude/rules/ c3 init で配置・c3 update で更新
41
39
  .claude/rules/promoted/index.md c3 init で空雛形のみ配置(c3 update は触らない)
42
40
  .claude/hooks/ c3 init で配置・c3 update で更新
@@ -128,7 +126,7 @@ src/c3/migrations/ SQLite schema migration SQL ファイル
128
126
 
129
127
  ## 2. 設定優先順位と書き込み権限
130
128
 
131
- 設定は性質の異なる **3 つのレイヤー** に分かれる。1 列に並べると誤解を生むため分離して記述する。
129
+ 設定は性質の異なる **3 つのレイヤー**(レイヤー B は v2.72.0 で削除済み)に分かれる。1 列に並べると誤解を生むため分離して記述する。
132
130
 
133
131
  ### レイヤー A: ツール権限(Claude Code 公式)
134
132
 
@@ -146,15 +144,10 @@ src/c3/migrations/ SQLite schema migration SQL ファイル
146
144
 
147
145
  ### レイヤー B: 自動承認パターン(C3 独自拡張)
148
146
 
149
- - `.claude/permission_rules.json` の `auto_allow` 配列
150
- - `permission_handler.py`(`PermissionRequest` hook)が読み込んで、パターンにマッチすれば自動承認
151
- - レイヤー A で `deny` 判定されたものを覆すことはできない(hook の決定権の範囲内)
152
- - `notify_on_auto: false` で通知を抑止できる
153
-
154
- > **注意**: `permission_rules.json` は Claude Code 公式の `permissions.allow` とは **独立した別レイヤー**。
155
- > 同列に並べると「どちらが優先されるか」で誤解が生じる。レイヤー A と B は並立している。
156
-
157
- > **注意**: `auto_allow` パターンは最小限に留めること。広範なパターン(例: `Bash(*)`)は C3 の意図する動作範囲を超えた危険コマンドも自動承認する可能性がある。
147
+ (削除済み・v2.72.0)C3 独自の自動承認パターン(`.claude/permission_rules.json` の `auto_allow` 配列と
148
+ `permission_handler.py` hook)は v2.72.0 で削除された。自動承認は上流 Claude Code の
149
+ `permissions.allow`(レイヤー A)へ委譲する。移行手順は `.claude/breaking-changes.txt` の
150
+ v2.72.0 行を参照。
158
151
 
159
152
  ### レイヤー C: LLM 指示・知識(CLAUDE.md / rules)
160
153
 
@@ -173,7 +166,6 @@ src/c3/migrations/ SQLite schema migration SQL ファイル
173
166
  |---|---|---|---|
174
167
  | `.claude/settings.json` | ○ | ○ | △(チーム合意のもと) |
175
168
  | `.claude/settings.local.json` | × | × | ○(個人 override / 秘匿情報) |
176
- | `.claude/permission_rules.json` | ○ | ○ | △(ファイル全体を上書き編集する場合は注意) |
177
169
  | `.claude/CLAUDE.md` | ○ | ○ | △(c3 update で上書きされる前提で) |
178
170
  | `.claude/rules/*.md` | ○ | ○ | △(同上) |
179
171
  | `.claude/rules/promoted/index.md` | ○(空雛形のみ) | × | ○(`/promote-pattern` が追記、手動編集も可) |
@@ -196,11 +188,11 @@ src/c3/migrations/ SQLite schema migration SQL ファイル
196
188
  | 6 | `.claude/docs/*.md` | △(一部のみ) | ○ | 利用先向けリファレンス。配布対象は `autonomous-mode-onboarding.md` / `config-policy.md`(本ドキュメント)/ `nul-boundary.md` / `parallel-agents-setup.md` / `platform-adapters.md` / `settings.json.md` の 6 ファイル。配布元固有の設計メモ等は `_excludes.py` で個別除外。`taxonomy.md` は tracked(GitHub 公開)だが EXCLUDE 対象のため wheel 非配布(詳細は §7 落とし穴 2 参照)。 |
197
189
  | 7 | `.claude/CLAUDE.md` | ○ | ○ | 配布先で常時注入される共通ルール |
198
190
  | 8 | `.claude/settings.json` | ○ | ○ | プロジェクト共通設定(hooks 登録・permissions など) |
199
- | 9 | `.claude/permission_rules.json` | ○ | ○ | C3 独自の自動承認パターン(PermissionRequest hook が参照) |
191
+ | 9 | `.claude/permission_rules.json` | ×(削除済み・v2.72.0) | — | C3 独自の自動承認パターンは v2.72.0 で削除された。上流 `permissions.allow` へ委譲(移行手順は `.claude/breaking-changes.txt` の v2.72.0 行を参照) |
200
192
  | 10 | `.claude/settings.local.json` | × | — | 個人 override・秘匿情報。`_excludes.py` でも除外、`.gitignore` でも除外、c3 update も触らない |
201
193
  | 11 | `.claude/reports/*` / `memory/*` / `agent-memory/*` / `state/*` / `tmp/*` / `worktrees/*` / `logs/*` | × (`.gitkeep` のみ ○) | — | 実行時生成領域。空ディレクトリのみ `KEEP_PATTERNS` の `.gitkeep` で配布。データ本体は除外。v2.19.0 で `.claude/state/c3_version.txt`(バージョン checkpoint)を追加(`state/*` 一括除外により自動非配布) |
202
194
  | 12 | `.dev/*` / `/CLAUDE.md` / `/AGENTS.md` / `/.codex/` / `/.cursor/` / `/.agents/` | × | — | 配布元専用または adapter 生成物。wheel には構造的に含まれない(`src/c3/_template/.claude/` 配下のみ同梱)が、配布元 `.gitignore` で commit 混入も防ぐ |
203
- | 13 | `.claude/deletions.txt` | ○ | ○ | `c3 update` が読み込み、利用先 `.claude/` から該当ファイルを削除候補として扱う。配布元の `.claude/deletions.txt` に追記したエントリは次回 pip install → `c3 update` で利用先に伝播。`KEEP_PATTERNS` で明示配布。`c3 update` 自体は本ファイルを削除しない(§7 落とし穴 5 参照) |
195
+ | 13 | `.claude/deletions.txt` | ○ | ○ | `c3 update` が読み込み、利用先 `.claude/` から該当ファイルを削除候補として扱う。配布元の `.claude/deletions.txt` に追記したエントリは次回 pip install → `c3 update` で利用先に伝播。`KEEP_PATTERNS` で明示配布。`c3 update` 自体は本ファイルを削除しない(§7 落とし穴 4 参照) |
204
196
  | 14 | `.claude/breaking-changes.txt` | ○ | ○ | `c3 update` が読み込み、利用先の `.claude/state/c3_version.txt`(バージョン checkpoint)と diff を計算して破壊的変更を表示する。MAJOR bump 時は y/N 承認プロンプトを発火。`KEEP_PATTERNS` で明示配布。配布元 `.claude/breaking-changes.txt` を更新すれば次回 pip install → `c3 update` で利用先に伝播。利用先 git 管理は tracked(上書きされる) |
205
197
  | 15 | `.claude/.gitignore` | ○ | ×(INIT_ONLY) | 利用先の実行時生成領域のうち「再生成可能」「セッション一時」だけを除外する配布 `.gitignore`(§1-2 の方針の実装)。プロジェクトルートの `.gitignore` は編集しないため既存設定と衝突しない。`INIT_ONLY_PATTERNS` により初回配置のみで **c3 update は上書きしない**(利用先の追記を守る)。C3 側で分類を更新した場合はリリースノートで手動マージを案内する |
206
198
 
@@ -288,6 +280,9 @@ C3 の wheel 配布除外パターンは **3 つのファイルに分散して
288
280
  `hatch_build.py` の重複が必要な理由: hatch build hook はパッケージ import 前に走るため、
289
281
  `_excludes.py` を import できない。2 ファイルの完全一致が必須。
290
282
 
283
+ **KEEP 対象が sdist exclude 配下にある場合は `pyproject.toml` の force-include も同期対象**:
284
+ 公開ビルドは sdist を経由するため、sdist から落ちたファイルは wheel にも届かない。
285
+
291
286
  ### 同期確認の方法
292
287
 
293
288
  `.dev/hooks/_sync_check.py`(PostToolUse hook)が、3 ファイルのいずれかを変更した時に
@@ -297,8 +292,8 @@ C3 の wheel 配布除外パターンは **3 つのファイルに分散して
297
292
 
298
293
  1. `.gitignore` / `_excludes.py` / `hatch_build.py` のいずれかを変更
299
294
  2. `_sync_check.py` の警告を確認
300
- 3. 残り 2 ファイルに同じパターンを追加(または削除)
301
- 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/` は配布物に含まれないため、利用先には存在しないコマンド)
302
297
 
303
298
  ### 過去の同期漏れ defect
304
299
 
@@ -391,11 +386,8 @@ C3 side で `promoted/` の雛形を更新した場合は、リリースノー
391
386
 
392
387
  ### 落とし穴 5: `permission_rules.json` は `settings.json.permissions.deny` を覆せない(要検証)
393
388
 
394
- **現状**: `permission_handler.py` の実装を読む限り、`PermissionRequest` hook は
395
- Claude Code 側で `deny` 判定が出た後に発火するため、`permission_rules.json` の `auto_allow` で
396
- `deny` を覆すことはできないはず。ただし Claude Code 公式仕様に明記なし。
397
-
398
- **残課題**: v2.18.0 以降の検証タスクとして記録。現時点では「覆せない前提で設計する」ことを推奨。
389
+ 対象機能は v2.72.0 で削除済み(C3 独自の自動承認パターン一式)。上流 `permissions.allow` へ委譲した。
390
+ 移行手順は `.claude/breaking-changes.txt` の v2.72.0 行を参照。
399
391
 
400
392
  ### 落とし穴 6: `permissions.allow` のワイルドカードはプレフィックス一致のため `../` パストラバーサルに対応していない
401
393
 
@@ -471,11 +463,9 @@ CI のジョブ環境変数として設定する・親プロセスから子プ
471
463
  | 除外パターン定義 | `src/c3/_excludes.py` | `EXCLUDE_PATTERNS` / `KEEP_PATTERNS` 定数 + `should_skip()` |
472
464
  | ビルド時除外 | `hatch_build.py` | `_excludes.py` の重複定義(ビルドフック用) |
473
465
  | 同期確認 hook | `.dev/hooks/_sync_check.py` | 3 ファイル変更時の警告(配布元専用) |
474
- | 自動承認 hook | `.claude/hooks/permission_handler.py` | `permission_rules.json` を読んで自動承認 |
475
466
 
476
467
  ### 残課題リンク(v2.18.0 以降)
477
468
 
478
- - `permission_rules.json` の `auto_allow` が `settings.json.permissions.deny` を覆せるか検証
479
469
  - `~/.claude/settings.json` のグローバル設定と `.claude/settings.json` の同キー競合時のマージ範囲確認
480
470
  - ~~`c3 update` の削除検出(`deletions.txt` 方式、v2.18.0 予定)~~ → v2.18.0 で実装
481
471
  - `c3 update` 時の Breaking changes 警告(v2.19.0 予定)
@@ -5,7 +5,6 @@
5
5
  "Bash(c3 run .claude/hooks/pre_tool.py*)",
6
6
  "Bash(c3 run .claude/hooks/pre_compact.py*)",
7
7
  "Bash(c3 run .claude/hooks/restore_session.py*)",
8
- "Bash(c3 run .claude/hooks/permission_handler.py*)",
9
8
  "Bash(c3 run .claude/hooks/statusline.py*)",
10
9
  "Bash(c3 run .claude/hooks/recall_autorebuild.py*)",
11
10
  "Bash(c3 run .claude/skills/dev-workflow/scripts/detect_execution_verification.py*)",
@@ -168,18 +167,6 @@
168
167
  ]
169
168
  }
170
169
  ],
171
- "PermissionRequest": [
172
- {
173
- "matcher": "",
174
- "hooks": [
175
- {
176
- "type": "command",
177
- "command": "c3",
178
- "args": ["run", "${CLAUDE_PROJECT_DIR}/.claude/hooks/permission_handler.py"]
179
- }
180
- ]
181
- }
182
- ],
183
170
  "UserPromptSubmit": [
184
171
  {
185
172
  "matcher": "",
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/
@@ -122,7 +122,6 @@ A ヒアリング → B 設計 → C 計画 → D 実装(TDD) → E レビュー
122
122
  | `PostToolUse` | `Write` / `Edit` | `planner_check.py` | plan-report の YAML/タイムスタンプ/reviewer 規約検査 |
123
123
  | `PostToolUse` | `Write` | `report_contract_check.py` | reports 直下の命名契約逸脱を warn(strict-4〔requirements/architecture/plan/design-review〕はタイムスタンプ形式の厳密検査、loose-3〔code-review/security-review/test〕はタイムスタンプ形式または task_id 形式のどちらかを許容する緩検査。stderr + additionalContext) |
124
124
  | `PostToolUse` | `Edit` | `session_mode_watch.py` | session.tmp のモード行挿入・plan= 差し替えを warn(stderr + additionalContext) |
125
- | `PermissionRequest` | (全て) | `permission_handler.py` | `permission_rules.json` の `auto_allow` で自動承認([config-policy §2 レイヤー B](.claude/docs/config-policy.md)) |
126
125
  | `PreCompact` | (全て) | `pre_compact.py` | compact 前にチェックポイントマーカー注入 |
127
126
  | `Stop` | (全て) | `session_stop.py` | セッション終了処理のオーケストレータ |
128
127
 
@@ -1,5 +1,59 @@
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
+
31
+ ## [2.72.0] - 2026-08-14
32
+
33
+ ### 破壊的変更
34
+
35
+ - **C3 独自の `PermissionRequest` hook 一式を削除した**: `.claude/hooks/permission_handler.py` /
36
+ `.claude/hooks/permission_handler_toast.py` / `.claude/permission_rules.json`、および
37
+ `pyproject.toml` の `[notify]` extra(`windows-toasts` 依存)。失うものは auto_allow による
38
+ 自動承認・承認待ちの OS 通知(Windows トースト承認 UX)・`[notify]` extra。代替は上流
39
+ Claude Code の auto mode(Pro/Max/Team の新規セッション既定。**Enterprise/API/cloud の展開前・
40
+ 既存セッションは対象外**)と `permissions.allow`(書式互換)、上流の通知設定。
41
+ 移行手順(`c3 update` 実行中の視点で記述):
42
+ 1. `c3 update` 実行中にこの案内を見た時点では `settings.json` は新版へ更新済みだが、
43
+ 旧ファイルの削除はまだ確定していない(直後の削除プロンプトは `[y/N]`・既定 N)
44
+ 2. まだ転記していない場合: 削除プロンプトで N(既定)を選び、
45
+ `.claude/permission_rules.json` の `auto_allow` を `.claude/settings.local.json`
46
+ (個人設定・共有の `settings.json` ではない)の `permissions.allow` へ転記してから
47
+ `c3 update` を再実行して y で削除する。書式は同一のためそのまま転記できる
48
+ 3. 但し書き: 上流はコマンドセパレータ(`&&` `||` `;` `|` `|&` `&` 改行)で分割した
49
+ 各サブコマンドを独立に照合する(公式ドキュメント確認済み(2026-08-14))。
50
+ ただしコマンド置換(`$()` やバッククォート)の扱いは未確認のため、
51
+ `Bash(git *)` 等の広いワイルドカードはそのまま転記せず、必要最小のプレフィックスへ狭めること
52
+ 4. auto mode が既定でない・使わない環境(Enterprise/API/cloud の展開前・既存セッション・
53
+ 手動運用)では `permissions.allow` への転記が実質必須
54
+ 5. `pip uninstall windows-toasts` 可。転記漏れは git 履歴から回収可能
55
+ 詳細は `.claude/docs/config-policy.md` を参照。
56
+
3
57
  ## [2.71.1] - 2026-08-14
4
58
 
5
59
  ### 修正
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: claude-code-conductor
3
- Version: 2.71.1
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
@@ -41,8 +41,6 @@ Requires-Dist: duckdb>=0.10
41
41
  Requires-Dist: fastembed>=0.8.0
42
42
  Requires-Dist: numpy>=1.22
43
43
  Requires-Dist: pyyaml>=6.0
44
- Provides-Extra: notify
45
- Requires-Dist: windows-toasts>=1.0; (sys_platform == 'win32') and extra == 'notify'
46
44
  Description-Content-Type: text/markdown
47
45
 
48
46
  # Claude Code Conductor (C3)
@@ -30,10 +30,6 @@ dependencies = [
30
30
  "fastembed>=0.8.0",
31
31
  ]
32
32
 
33
- [project.optional-dependencies]
34
- # Windows でボタン付き通知(permission_handler の「自動承認に追加」UI)を有効化する
35
- notify = ["windows-toasts>=1.0; sys_platform == 'win32'"]
36
-
37
33
  [project.scripts]
38
34
  c3 = "c3.cli:main"
39
35
 
@@ -76,6 +72,24 @@ exclude = [
76
72
  ".claude/docs/taxonomy.md",
77
73
  ]
78
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
+
79
93
  [tool.pytest.ini_options]
80
94
  testpaths = ["tests"]
81
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.71.1"
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
+ )
@@ -0,0 +1,154 @@
1
+ """tests/test_permission_handler_removal.py
2
+
3
+ permission_handler 一式(PermissionRequest hook 本体 / Windows トーストワーカー /
4
+ auto_allow ルール定義)の削除完了を凍結する検証テスト。
5
+
6
+ 測る性質(architecture-report-20260814-123008.md §0-A / 改訂 2 §A-7 /
7
+ 改訂 3 §3 / 改訂 4 §2 に対応):
8
+
9
+ 1. 削除対象 3 ファイルがリポジトリに存在しないこと(A-1 / A-2 / A-3)
10
+ 2. `.claude/settings.json` に `PermissionRequest` キーが無く、
11
+ permissions.allow に permission_handler を含む行が無いこと(A-4 / A-5)
12
+ 3. `pyproject.toml` に `[project.optional-dependencies]` セクションと
13
+ windows-toasts が無いこと(A-7)
14
+ 4. `.claude/deletions.txt` に削除 3 行が記載されていること(B-12)
15
+ 5. `.claude/breaking-changes.txt` の `v` で始まる非コメント行のいずれかが
16
+ `permission_handler` を含むこと(B-16・存在断言・順序非依存・版番号非依存)
17
+
18
+ 本ファイルは削除スライスの実施前は**赤であることが正常**(Red フェーズ)。
19
+ 削除完了後に緑へ反転することで削除が凍結される。
20
+
21
+ なお本ファイルは不在検証の性質上、対象名 `permission_handler` /
22
+ `permission_rules` を必然的に含む(architecture 改訂 3 §0-B 補記 2 の
23
+ 「§6 ヒットしてよい対象」(a) に該当)。
24
+ """
25
+ from __future__ import annotations
26
+
27
+ import json
28
+ from pathlib import Path
29
+
30
+ import pytest
31
+
32
+ REPO_ROOT = Path(__file__).resolve().parent.parent
33
+
34
+ # 削除対象ファイル(リポジトリルート相対・POSIX 表記)
35
+ REMOVED_FILES = (
36
+ ".claude/hooks/permission_handler.py",
37
+ ".claude/hooks/permission_handler_toast.py",
38
+ ".claude/permission_rules.json",
39
+ )
40
+
41
+ # deletions.txt に記載されるべきパス(.claude/ 相対表記)
42
+ DELETION_ENTRIES = (
43
+ "hooks/permission_handler.py",
44
+ "hooks/permission_handler_toast.py",
45
+ "permission_rules.json",
46
+ )
47
+
48
+
49
+ def _read(relative: str) -> str:
50
+ return (REPO_ROOT / relative).read_text(encoding="utf-8")
51
+
52
+
53
+ # ===========================================================================
54
+ # 1. 削除対象ファイルの不在(A-1 / A-2 / A-3)
55
+ # ===========================================================================
56
+ class TestRemovedFilesAreGone:
57
+ @pytest.mark.parametrize("relative", REMOVED_FILES)
58
+ def test_file_does_not_exist(self, relative: str) -> None:
59
+ """削除対象ファイルがリポジトリに存在しないこと."""
60
+ target = REPO_ROOT / relative
61
+ assert not target.exists(), f"deleted file still exists: {relative}"
62
+
63
+
64
+ # ===========================================================================
65
+ # 2. settings.json の登録消滅(A-4 / A-5)
66
+ # ===========================================================================
67
+ class TestSettingsJsonHasNoPermissionRequest:
68
+ @pytest.fixture()
69
+ def settings(self) -> dict:
70
+ """`.claude/settings.json` を JSON としてパースして返す(valid JSON 前提)."""
71
+ return json.loads(_read(".claude/settings.json"))
72
+
73
+ def test_hooks_section_has_no_permission_request_key(self, settings: dict) -> None:
74
+ """hooks 節に `PermissionRequest` キーが存在しないこと(キーごと削除)."""
75
+ hooks = settings.get("hooks", {})
76
+ assert isinstance(hooks, dict), "settings.json の hooks 節が dict ではない"
77
+ assert "PermissionRequest" not in hooks, (
78
+ "settings.json の hooks 節に PermissionRequest キーが残っている"
79
+ )
80
+
81
+ def test_permissions_allow_has_no_permission_handler_entry(self, settings: dict) -> None:
82
+ """permissions.allow に permission_handler を含むエントリが無いこと."""
83
+ allow = settings.get("permissions", {}).get("allow", [])
84
+ assert isinstance(allow, list), "settings.json の permissions.allow が list ではない"
85
+ assert len(allow) > 0, "positive control: permissions.allow が空(読み取り経路が壊れている)"
86
+
87
+ leftovers = [entry for entry in allow if "permission_handler" in str(entry)]
88
+ assert leftovers == [], f"permissions.allow に残存エントリがある: {leftovers}"
89
+
90
+
91
+ # ===========================================================================
92
+ # 3. pyproject.toml の extra 削除(A-7)
93
+ # ===========================================================================
94
+ class TestPyprojectHasNoNotifyExtra:
95
+ def test_optional_dependencies_section_is_absent(self) -> None:
96
+ """`[project.optional-dependencies]` セクションが存在しないこと(空テーブルも残さない)."""
97
+ lines = [line.strip() for line in _read("pyproject.toml").splitlines()]
98
+ assert "[project]" in lines, "positive control: pyproject.toml の読み取り経路が壊れている"
99
+ assert "[project.optional-dependencies]" not in lines, (
100
+ "pyproject.toml に [project.optional-dependencies] セクションが残っている"
101
+ )
102
+
103
+ def test_windows_toasts_is_absent(self) -> None:
104
+ """windows-toasts への依存記述が残っていないこと."""
105
+ text = _read("pyproject.toml")
106
+ assert "windows-toasts" not in text, (
107
+ "pyproject.toml に windows-toasts への依存が残っている"
108
+ )
109
+
110
+
111
+ # ===========================================================================
112
+ # 4. deletions.txt への追記(B-12)
113
+ # ===========================================================================
114
+ class TestDeletionsTxtListsRemovedFiles:
115
+ @pytest.fixture()
116
+ def entries(self) -> list[str]:
117
+ """`.claude/deletions.txt` の実エントリ行(コメント・空行を除く)."""
118
+ out = []
119
+ for raw in _read(".claude/deletions.txt").splitlines():
120
+ line = raw.strip()
121
+ if not line or line.startswith("#"):
122
+ continue
123
+ out.append(line)
124
+ return out
125
+
126
+ @pytest.mark.parametrize("entry", DELETION_ENTRIES)
127
+ def test_entry_is_listed(self, entries: list[str], entry: str) -> None:
128
+ """削除 3 行が deletions.txt に記載されていること."""
129
+ assert len(entries) > 0, "positive control: deletions.txt に実エントリが 1 行も無い"
130
+ assert entry in entries, f"deletions.txt に未記載: {entry}"
131
+
132
+
133
+ # ===========================================================================
134
+ # 5. breaking-changes.txt への追記(B-16・版番号非依存)
135
+ # ===========================================================================
136
+ class TestBreakingChangesTxtAnnouncesRemoval:
137
+ def test_some_version_line_mentions_permission_handler(self) -> None:
138
+ """`v` で始まる非コメント行のいずれかが `permission_handler` を含むこと.
139
+
140
+ 存在断言のみ。順序(末尾かどうか)にも版番号リテラルにも依存させない。
141
+ """
142
+ version_lines = [
143
+ line
144
+ for line in (raw.strip() for raw in _read(".claude/breaking-changes.txt").splitlines())
145
+ if line.startswith("v")
146
+ ]
147
+ assert len(version_lines) > 0, (
148
+ "positive control: breaking-changes.txt に v で始まる行が 1 行も無い"
149
+ )
150
+
151
+ hits = [line for line in version_lines if "permission_handler" in line]
152
+ assert len(hits) >= 1, (
153
+ "breaking-changes.txt に permission_handler の削除を告知する行が無い"
154
+ )