claude-code-conductor 2.69.0__tar.gz → 2.70.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 (269) hide show
  1. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/SKILL.md +49 -1
  2. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/CHANGELOG.md +29 -0
  3. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/PKG-INFO +1 -1
  4. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/__init__.py +1 -1
  5. claude_code_conductor-2.70.0/tests/skills/test_e0_verification_exit.py +226 -0
  6. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/.gitignore +0 -0
  7. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/CLAUDE.md +0 -0
  8. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/architect.md +0 -0
  9. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/code-reviewer.md +0 -0
  10. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/design-critic.md +0 -0
  11. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/developer.md +0 -0
  12. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/doc-writer.md +0 -0
  13. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/interviewer.md +0 -0
  14. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/planner.md +0 -0
  15. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/project-setup.md +0 -0
  16. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/security-reviewer.md +0 -0
  17. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/systematic-debugger.md +0 -0
  18. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/tester.md +0 -0
  19. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/wt_developer.md +0 -0
  20. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/wt_systematic-debugger.md +0 -0
  21. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/agents/wt_tester.md +0 -0
  22. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/breaking-changes.txt +0 -0
  23. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/deletions.txt +0 -0
  24. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/docs/autonomous-mode-onboarding.md +0 -0
  25. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/docs/config-policy.md +0 -0
  26. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/docs/nul-boundary.md +0 -0
  27. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/docs/parallel-agents-setup.md +0 -0
  28. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/docs/platform-adapters.md +0 -0
  29. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/docs/settings.json.md +0 -0
  30. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/_hook_utils.py +0 -0
  31. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/check_agent_invocation.py +0 -0
  32. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/consolidate_memory.py +0 -0
  33. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/patterns_guard.py +0 -0
  34. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/permission_handler.py +0 -0
  35. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/permission_handler_toast.py +0 -0
  36. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/planner_check.py +0 -0
  37. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/post_tool.py +0 -0
  38. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/pre_compact.py +0 -0
  39. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/pre_tool.py +0 -0
  40. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/recall_autorebuild.py +0 -0
  41. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/recall_inject.py +0 -0
  42. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/report_contract_check.py +0 -0
  43. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/report_path_guard.py +0 -0
  44. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/restore_session.py +0 -0
  45. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/select_tier.py +0 -0
  46. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/session_mode_watch.py +0 -0
  47. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/session_start.py +0 -0
  48. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/session_stop.py +0 -0
  49. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/session_utils.py +0 -0
  50. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/statusline.py +0 -0
  51. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/stop.py +0 -0
  52. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/tier_autoapply.py +0 -0
  53. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/tier_gap_check.py +0 -0
  54. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/hooks/worktree_guard.py +0 -0
  55. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/memory/.gitkeep +0 -0
  56. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/permission_rules.json +0 -0
  57. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/rules/promoted/index.md +0 -0
  58. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/settings.json +0 -0
  59. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/autonomous-mode/SKILL.md +0 -0
  60. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/autonomous-mode/scripts/mode_line.py +0 -0
  61. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/brainstorm/SKILL.md +0 -0
  62. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/codex-review/SKILL.md +0 -0
  63. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/c3-omission-declaration.md +0 -0
  64. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/code-review-checklist.md +0 -0
  65. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/design-critic-rubric.md +0 -0
  66. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/design-rubric.md +0 -0
  67. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/interview-rubric.md +0 -0
  68. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/plan-design-guidelines.md +0 -0
  69. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/reachability-map.md +0 -0
  70. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/record-protocol.md +0 -0
  71. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/references/security-review-checklist.md +0 -0
  72. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/scripts/detect_execution_verification.py +0 -0
  73. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/scripts/record_agent_outcome.py +0 -0
  74. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/scripts/record_review_decision.py +0 -0
  75. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/dev-workflow/scripts/review_hint_inject.py +0 -0
  76. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/develop/SKILL.md +0 -0
  77. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/doc/SKILL.md +0 -0
  78. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/extract-lib/SKILL.md +0 -0
  79. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/init-session/SKILL.md +0 -0
  80. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/init-session/scripts/session_guard.py +0 -0
  81. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/mcp-config/SKILL.md +0 -0
  82. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/parallel-agents/SKILL.md +0 -0
  83. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/pattern-status/SKILL.md +0 -0
  84. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/promote-pattern/SKILL.md +0 -0
  85. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/recall/SKILL.md +0 -0
  86. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/report-timestamp/SKILL.md +0 -0
  87. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/report-timestamp/scripts/get_timestamp.py +0 -0
  88. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/review-phase/SKILL.md +0 -0
  89. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/setup/SKILL.md +0 -0
  90. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/setup/reference.md +0 -0
  91. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/setup/templates/coding-standards-template.md +0 -0
  92. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/setup/templates/project-conventions-template.md +0 -0
  93. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/start/SKILL.md +0 -0
  94. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/skills/start/scripts/archive_reports.py +0 -0
  95. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.claude/state/.gitkeep +0 -0
  96. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/.gitignore +0 -0
  97. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/ARCHITECTURE.md +0 -0
  98. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/LICENSE +0 -0
  99. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/LICENSES/fastembed-LICENSE +0 -0
  100. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/LICENSES/fastembed-NOTICE +0 -0
  101. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/LICENSES/numpy-LICENSE +0 -0
  102. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/LICENSES/onnxruntime-LICENSE +0 -0
  103. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/LICENSES/paraphrase-multilingual-MiniLM-L12-v2-LICENSE +0 -0
  104. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/README.md +0 -0
  105. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/hatch_build.py +0 -0
  106. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/pyproject.toml +0 -0
  107. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/__main__.py +0 -0
  108. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/_db_params.py +0 -0
  109. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/_excludes.py +0 -0
  110. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/_terminal.py +0 -0
  111. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/adapters.py +0 -0
  112. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli.py +0 -0
  113. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_ask.py +0 -0
  114. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_doctor.py +0 -0
  115. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_init.py +0 -0
  116. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_list.py +0 -0
  117. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_metrics.py +0 -0
  118. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_plan.py +0 -0
  119. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_recall.py +0 -0
  120. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_run.py +0 -0
  121. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_tier.py +0 -0
  122. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/cli_update.py +0 -0
  123. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/db.py +0 -0
  124. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/embedding.py +0 -0
  125. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/gitutil.py +0 -0
  126. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/mcp_server.py +0 -0
  127. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrate.py +0 -0
  128. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/001_initial.sql +0 -0
  129. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/002_agent_cost_runs.sql +0 -0
  130. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/003_tier_cost.sql +0 -0
  131. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/004_agent_outcomes.sql +0 -0
  132. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/005_drop_agent_tier_bandit.sql +0 -0
  133. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/006_review_decisions_severity.sql +0 -0
  134. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/007_review_decisions_resolution.sql +0 -0
  135. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/008_drop_agent_runs.sql +0 -0
  136. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/README.md +0 -0
  137. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/migrations/__init__.py +0 -0
  138. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/paths.py +0 -0
  139. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/plan_validator.py +0 -0
  140. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/platforms.py +0 -0
  141. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/pricing.py +0 -0
  142. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/question.py +0 -0
  143. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/recall_chunker.py +0 -0
  144. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/recall_index.py +0 -0
  145. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/refgraph.py +0 -0
  146. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/src/c3/usage_ingester.py +0 -0
  147. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/__init__.py +0 -0
  148. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/_pre_compact_helpers.py +0 -0
  149. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/conftest.py +0 -0
  150. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/fixtures/usage/README.md +0 -0
  151. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/fixtures/usage/mainline.jsonl +0 -0
  152. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/fixtures/usage/subagents/agent-deadbeef.jsonl +0 -0
  153. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/fixtures/usage/subagents/agent-deadbeef.meta.json +0 -0
  154. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/__init__.py +0 -0
  155. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_check_agent_invocation.py +0 -0
  156. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_consolidate_memory.py +0 -0
  157. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_detect_execution_verification.py +0 -0
  158. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_hook_utils.py +0 -0
  159. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_permission_handler.py +0 -0
  160. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_permission_handler_toast.py +0 -0
  161. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_pip_reinstall_reminder.py +0 -0
  162. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_planner_check.py +0 -0
  163. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_planner_check_dev.py +0 -0
  164. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_post_tool.py +0 -0
  165. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_pre_tool.py +0 -0
  166. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_recall_autorebuild.py +0 -0
  167. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_recall_inject.py +0 -0
  168. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_record_agent_outcome.py +0 -0
  169. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_record_review_decision.py +0 -0
  170. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_report_path_guard.py +0 -0
  171. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_restore_session.py +0 -0
  172. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_review_hint_inject.py +0 -0
  173. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_select_tier.py +0 -0
  174. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_select_tier_escalation.py +0 -0
  175. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_session_start.py +0 -0
  176. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_session_stop.py +0 -0
  177. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_session_utils.py +0 -0
  178. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_settings_local_absolute_paths.py +0 -0
  179. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_settings_tier_autoapply_registration.py +0 -0
  180. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_similarity_boost.py +0 -0
  181. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_statusline.py +0 -0
  182. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_statusline_template_sync.py +0 -0
  183. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_sync_check.py +0 -0
  184. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_template_guard.py +0 -0
  185. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_tier_autoapply.py +0 -0
  186. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_tier_gap_check.py +0 -0
  187. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/hooks/test_tier_security_fixes.py +0 -0
  188. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/__init__.py +0 -0
  189. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/_skill_helpers.py +0 -0
  190. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_c3_omission_declaration.py +0 -0
  191. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_dev_workflow_no_task_type.py +0 -0
  192. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_init_session_no_task_type.py +0 -0
  193. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_marker_compliance.py +0 -0
  194. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_parallel_agents_skill_tier.py +0 -0
  195. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_planner_lightweight.py +0 -0
  196. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_reachability_map.py +0 -0
  197. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_recall_skill.py +0 -0
  198. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_session_backlog_reconciliation.py +0 -0
  199. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_session_guard.py +0 -0
  200. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_setup_templates.py +0 -0
  201. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_start_skill_bugfix_flow.py +0 -0
  202. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_start_skill_new_flow.py +0 -0
  203. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/skills/test_start_skill_security_audit_phase.py +0 -0
  204. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_adapters.py +0 -0
  205. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_archive_reports.py +0 -0
  206. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_audit_review_decisions.py +0 -0
  207. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_check_deletions.py +0 -0
  208. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_ci_workflows.py +0 -0
  209. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_claude_gitignore.py +0 -0
  210. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_ask.py +0 -0
  211. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_doctor.py +0 -0
  212. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_doctor_launcher.py +0 -0
  213. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_entry.py +0 -0
  214. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_init.py +0 -0
  215. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_list.py +0 -0
  216. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_metrics.py +0 -0
  217. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_plan.py +0 -0
  218. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_recall.py +0 -0
  219. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_run.py +0 -0
  220. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_tier.py +0 -0
  221. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_update_breaking_changes.py +0 -0
  222. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_cli_update_deletions.py +0 -0
  223. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_db.py +0 -0
  224. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_db_connect_lint.py +0 -0
  225. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_docstring_consistency.py +0 -0
  226. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_embedding.py +0 -0
  227. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_excludes.py +0 -0
  228. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_extract_breaking_changes.py +0 -0
  229. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_gitutil.py +0 -0
  230. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_hooks_stdin_idiom.py +0 -0
  231. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_init_only_patterns.py +0 -0
  232. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_mcp_server_elicit.py +0 -0
  233. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_migrate.py +0 -0
  234. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_mode_line.py +0 -0
  235. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_no_bare_python_launcher.py +0 -0
  236. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_no_passonly_tests.py +0 -0
  237. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_nul_boundary_lint.py +0 -0
  238. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_paths.py +0 -0
  239. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_patterns_guard.py +0 -0
  240. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_plan_validator.py +0 -0
  241. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_pre_compact.py +0 -0
  242. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_pre_tool_hook.py +0 -0
  243. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_precompact_additional.py +0 -0
  244. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_precompact_toctou_fixes.py +0 -0
  245. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_pricing.py +0 -0
  246. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_recall_chunker.py +0 -0
  247. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_recall_index.py +0 -0
  248. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_references_migration.py +0 -0
  249. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_refgraph.py +0 -0
  250. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_refgraph_query.py +0 -0
  251. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_refgraph_structural.py +0 -0
  252. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_report_contract_check.py +0 -0
  253. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_scripts_src_bootstrap.py +0 -0
  254. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_scripts_stdout_encoding.py +0 -0
  255. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_session_mode_watch.py +0 -0
  256. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_session_utils_additional.py +0 -0
  257. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_settings_hooks_registration.py +0 -0
  258. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_skill_no_builtin_conflict.py +0 -0
  259. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_start_skill_archive_contract.py +0 -0
  260. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_statusline.py +0 -0
  261. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_stop_additional.py +0 -0
  262. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_stop_agent_memory_warn.py +0 -0
  263. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_stop_hook.py +0 -0
  264. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_stop_precompact_fixes.py +0 -0
  265. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_sync_template_stop.py +0 -0
  266. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_template_pre_tool_hook.py +0 -0
  267. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_usage_ingester.py +0 -0
  268. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_worktree_guard.py +0 -0
  269. {claude_code_conductor-2.69.0 → claude_code_conductor-2.70.0}/tests/test_wt_agent_sync.py +0 -0
@@ -784,7 +784,55 @@ TOKEN は `NEEDS_VERIFY` / `NOT_NEEDED` / `UNKNOWN`。UNKNOWN の場合は `{件
784
784
 
785
785
  #### NEEDS_VERIFY または UNKNOWN の場合
786
786
 
787
- 実行検証が必要。tester エージェントを起動して以下の指示を与える:
787
+ **省略の出口(HITL 専用)**
788
+
789
+ 当該ワークフロー内で既に実行検証を済ませている場合に限り、ユーザーへ 1 問だけ確認して
790
+ 実行検証を省略できる出口を置く。省略可否を決めるのはユーザーであり、ここでの LLM の役割は
791
+ 「実績の有無を実物の Read で確認して質問を出すか判断する」「証跡を整理して提示する」
792
+ 「回答を記録する」の 3 点に限る。機械的な適格判定・鮮度判定は行わない。
793
+
794
+ - **適用範囲**: 本出口は NEEDS_VERIFY のみを対象とする。UNKNOWN は本出口の対象外とする
795
+ (検出器が対象を出せていない状態では、検出対象への実行検証の実績を提示できないため)
796
+ - **HITL 専用**: 自律モードでは本出口を適用しない(AskUserQuestion を用いるため構造的にも
797
+ 発生しない)。autonomous-mode skill 側の「例外なく tester を起動する」規定は変更しない
798
+ - **提示条件**: 当該ワークフロー内の test-report に、E-0 の検出対象に対する実行検証の実績
799
+ (実際に実行したコマンドとその結果の記録)があると確認できた場合に限り、質問を出せる。
800
+ この確認は必ず test-report の実物を Read して行う。記憶や推測での判断は禁止する
801
+ - **質問**: 証跡(test-report のファイル名・実績が記録されている節(節名は問わない)・検証内容の要旨・
802
+ E-0 判定の件数)をテキストで提示したうえで、AskUserQuestion を単独ターンで出す
803
+ (同じツールブロックに副作用のあるツールを混ぜない)。選択肢は「省略する」「実行検証を行う」の 2 択
804
+ - **fail-safe**: 実績が確認できない場合や、判断に迷う場合は従来どおり tester を起動する
805
+ (質問を出さない側が安全側)。「実行検証を行う」が選ばれた場合も同じく従来どおり起動する
806
+
807
+ 証跡 4 項目(test-report のファイル名・実績が記録されている節・検証内容の要旨・E-0 判定の件数)は
808
+ このツール呼び出しの前にテキストで提示済みであることを前提に、AskUserQuestion は次の形で出す:
809
+
810
+ ```json
811
+ {
812
+ "questions": [{
813
+ "question": "実行検証は当該ワークフロー内で実施済みです。上記の証跡で実行検証を省略してよいですか?",
814
+ "options": [
815
+ { "label": "省略する", "description": "提示した証跡をもって検証済みとみなし tester を起動せず E-1 へ進む" },
816
+ { "label": "実行検証を行う", "description": "従来どおり tester を起動して実行検証を行う" }
817
+ ]
818
+ }]
819
+ }
820
+ ```
821
+
822
+ 「省略する」が選ばれた場合の処理:
823
+
824
+ 1. E-0 判定行を拡張書式で記録する(基本書式はそのまま保ち、末尾に追記するだけ):
825
+ `E-0判定: NEEDS_VERIFY {件数} plan-report-{タイムスタンプ} 省略(既検証: {test-report ファイル名} ユーザー承認済)`
826
+ この拡張書式は HITL 専用であり、自律モードでは基本書式のままとする
827
+ 2. セッションファイルの実行検証タスク行を更新する。当該ワークフローの未消費の `- [ ] 実行検証` 行が
828
+ あれば `- [x] 実行検証(省略・既検証 {ファイル名})` に Edit する。無ければ(当日 2 本目以降)
829
+ `- [x] 実行検証(省略・既検証 {ファイル名}・plan-report-{タイムスタンプ})` を新規に追記し、
830
+ 既存の `[x]` 行は書き換えない
831
+ 3. `現在地:` を `現在地: フェーズE code-review中` に Edit する(NOT_NEEDED 経路と同一)
832
+ 4. tier-routing 記録は行わない(tester を起動していないため)
833
+ 5. 以降の対象ファイル一覧の生成と tester 起動は実行せず、E-1 へ進む
834
+
835
+ 省略の出口が不成立の場合、実行検証が必要。tester エージェントを起動して以下の指示を与える:
788
836
 
789
837
  **tester への指示**(3 点):
790
838
 
@@ -1,5 +1,34 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.70.0] - 2026-08-13
4
+
5
+ ### 追加
6
+
7
+ - **E-0(実行検証判定)に「省略の出口(HITL 専用)」を追加した**。E-0 が NEEDS_VERIFY を
8
+ 返しても、当該ワークフロー内の test-report に検出対象への実行検証の実績があると
9
+ **実物の Read で確認できた場合に限り**、証跡(test-report のファイル名・実績が記録されて
10
+ いる節〔節名は問わない〕・検証内容の要旨・E-0 判定の件数)を提示して AskUserQuestion
11
+ (「省略する」「実行検証を行う」の 2 択)で確認できる。省略可否を決めるのはユーザーであり、
12
+ LLM の役割は実績確認・証跡提示・回答記録の 3 点に限る(機械的な適格判定・鮮度判定は
13
+ 持たない)。従来はこの状況(修正タスク自身が実行検証を内包しているのに E-0 が重複要求する。
14
+ 実発生 2 回)を定義されていないアドホック裁定で回避していた
15
+ - 省略成立時は E-0 判定行に `省略(既検証: {ファイル名} ユーザー承認済)` の証跡が残る
16
+ (基本書式は保持・末尾追記のみ。拡張書式は HITL 専用で自律モードは基本書式のまま)
17
+
18
+ ### 変更なし(明示)
19
+
20
+ - **既定挙動は従来どおり**(破壊的変更なし)。実績が確認できない・判断に迷う場合は質問を
21
+ 出さず従来どおり tester を起動する(fail-safe)。UNKNOWN は対象外。**自律モードでは本出口を
22
+ 適用しない**(autonomous-mode の「例外なく tester を起動する」規定は不変更)
23
+
24
+ ### 内部
25
+
26
+ - `tests/skills/test_e0_verification_exit.py` を新規追加(P1〜P8 の文言凍結。行頭アンカーに
27
+ よる節範囲切り出し・UNKNOWN 除外の負の対照・autonomous-mode 側文言の回帰ガードを含む)
28
+ - 設計過程の記録: 当初の自動省略設計(機械的文書条件による LLM 自動判定)は C-3 監査
29
+ 3 サイクル連続で新造欠陥を生み(DC 計 48 件)打切・1 問ゲートへ前提転換した
30
+ (architecture-report ADR-8)
31
+
3
32
  ## [2.69.0] - 2026-08-13
4
33
 
5
34
  ### 修正
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: claude-code-conductor
3
- Version: 2.69.0
3
+ Version: 2.70.0
4
4
  Summary: Multi-agent orchestration framework for Claude Code with Codex/Cursor adapters (C3)
5
5
  Project-URL: Homepage, https://github.com/satoh-y-0323/claude-code-conductor
6
6
  Project-URL: Repository, https://github.com/satoh-y-0323/claude-code-conductor
@@ -1,3 +1,3 @@
1
1
  """Claude Code Conductor (C3) - multi-agent orchestration framework for Claude Code."""
2
2
 
3
- __version__ = "2.69.0"
3
+ __version__ = "2.70.0"
@@ -0,0 +1,226 @@
1
+ """E-0「省略の出口(1 問ゲート)」を凍結する静的テスト。
2
+
3
+ 上流: architecture-report-20260813-183024 §2(出口ブロック仕様)/ §6(検証方針・P1〜P8)。
4
+
5
+ 検査は純テキスト走査(pathlib + 正規表現)のみで行い、subprocess・実行系は使わない。
6
+
7
+ **節範囲の契約(§6・逸脱禁止)**:
8
+ `re.MULTILINE` の行頭アンカー ``^#### NEEDS_VERIFY または UNKNOWN の場合`` から、
9
+ 次の行頭見出し(``^### `` または ``^## ``)の直前までを切り出す。
10
+ ``^#### `` は終端にならない(``###``/``##`` の直後に空白を要求するため)。
11
+ 非アンカーの見出し検索(インラインの ``## `` に一致する実装)と近傍固定ウィンドウ検索は禁止。
12
+
13
+ **読み込み契約**: `_skill_helpers.read_skill()` は未登録名に対して空文字列を返す
14
+ fail-silent API のため使わない(空文字列は全ての「不在」assert を素通りさせ、
15
+ 負の対照 P6 を空の緑にする)。パスを明示して読み、各テストの冒頭で
16
+ `assert content` の空ガードを置く。`extract_section` / `find_section_range` も
17
+ ``## `` 境界専用のため使わない。
18
+
19
+ **性質と対応表(§6 の定義表と同一)**:
20
+
21
+ ===== ===================================== ==========================
22
+ 性質 検査内容 Red フェーズでの期待
23
+ ===== ===================================== ==========================
24
+ P1 節範囲内に A1 赤(実装前)
25
+ P2 節範囲内に A5 赤(実装前)
26
+ P3 節範囲内に A6 赤(実装前)
27
+ P4 autonomous-mode/SKILL.md に既存文言 **緑**(既存文言の凍結)
28
+ P5 節範囲内に A7 赤(実装前)
29
+ P6 節範囲内に A4 かつ全文に否定文が不在 赤(実装前)
30
+ P7 節範囲内に A3 赤(実装前)
31
+ P8 節範囲内に ``AskUserQuestion`` 赤(実装前)
32
+ ===== ===================================== ==========================
33
+
34
+ P4 は既存文言の**回帰ガード**であり、実装前から緑であることが正しい
35
+ (tester.md の「テストが最初から Pass する場合は修正する」規範は P4 に適用しない。
36
+ architecture-report §7「P4 適用除外文」)。
37
+
38
+ **検知力の実証(ルール 19)**: 文言凍結型の静的検査のため do-nothing スタブ 2 種は
39
+ 原理的に非適用。代替として「実装前の SKILL.md で P1〜P3・P5〜P8 が赤(test-e0exit で実測)・
40
+ 実装後に緑へ反転(confirm-e0exit で実測)」の両状態反転をもって双方向の実証とする。
41
+ """
42
+
43
+ from __future__ import annotations
44
+
45
+ import re
46
+ from pathlib import Path
47
+
48
+ # --------------------------------------------------------------------------
49
+ # 対象パス(明示・fail-silent API を経由しない)
50
+ # --------------------------------------------------------------------------
51
+
52
+ WORKTREE_ROOT = Path(__file__).resolve().parents[2]
53
+ DEV_WORKFLOW_SKILL_PATH = WORKTREE_ROOT / ".claude" / "skills" / "dev-workflow" / "SKILL.md"
54
+ AUTONOMOUS_MODE_SKILL_PATH = WORKTREE_ROOT / ".claude" / "skills" / "autonomous-mode" / "SKILL.md"
55
+
56
+ # --------------------------------------------------------------------------
57
+ # 節範囲の契約(§6)
58
+ # --------------------------------------------------------------------------
59
+
60
+ #: E-0 出口ブロックが属する節の開始見出し(行頭アンカー・逐語)
61
+ SECTION_HEADING = "#### NEEDS_VERIFY または UNKNOWN の場合"
62
+
63
+ #: 節の終端となる行頭見出し。``### `` / ``## `` のみ(``#### `` は終端にしない)。
64
+ _SECTION_END_RE = re.compile(r"^(?:###|##)\s", re.MULTILINE)
65
+
66
+ # --------------------------------------------------------------------------
67
+ # 凍結アンカー literal(impl 側 prompt と同一文字列・逐語で含有判定する。
68
+ # 内部に ** ・バッククォート・括弧を挟まない)
69
+ # --------------------------------------------------------------------------
70
+
71
+ A1_EXIT_BLOCK_TITLE = "省略の出口(HITL 専用)"
72
+ A3_SCOPE_NEEDS_VERIFY_ONLY = "NEEDS_VERIFY のみを対象とする"
73
+ A4_UNKNOWN_OUT_OF_SCOPE = "UNKNOWN は本出口の対象外"
74
+ A5_FAIL_SAFE = "判断に迷う場合は従来どおり tester を起動する"
75
+ A6_NOT_APPLIED_IN_AUTONOMOUS = "自律モードでは本出口を適用しない"
76
+ A7_RECORD_FORMAT = "省略(既検証:"
77
+
78
+ #: P8 は固有アンカーでなく既存語の節範囲内存在を見る(§6 脚注)
79
+ P8_ASK_USER_QUESTION = "AskUserQuestion"
80
+
81
+ #: P4: autonomous-mode/SKILL.md 側の既存文言(変更しないことの凍結)
82
+ P4_AUTONOMOUS_FROZEN = "例外なく tester を起動する"
83
+
84
+ #: P6 の負の対照: SKILL.md 全文に現れてはならない文言
85
+ P6_FORBIDDEN_PHRASE = "UNKNOWN も省略できる"
86
+
87
+
88
+ # --------------------------------------------------------------------------
89
+ # ヘルパー
90
+ # --------------------------------------------------------------------------
91
+
92
+
93
+ def _read(path: Path) -> str:
94
+ """指定パスを UTF-8 で読む。存在しなければ空文字列(空ガードで検出させる)。"""
95
+ if not path.exists():
96
+ return ""
97
+ return path.read_text(encoding="utf-8")
98
+
99
+
100
+ def _e0_branch_section(content: str) -> str:
101
+ """``#### NEEDS_VERIFY または UNKNOWN の場合`` 節の本文を切り出す。
102
+
103
+ 行頭アンカー(`re.MULTILINE`)で見出しを探し、そこから次の行頭 ``### `` /
104
+ ``## `` 見出しの直前まで(見つからなければ末尾まで)を返す。
105
+ 見出しが存在しなければ空文字列を返す。
106
+ """
107
+ head = re.search("^" + re.escape(SECTION_HEADING), content, re.MULTILINE)
108
+ if head is None:
109
+ return ""
110
+ start = head.start()
111
+ rest_offset = head.end()
112
+ end_match = _SECTION_END_RE.search(content, rest_offset)
113
+ end = end_match.start() if end_match else len(content)
114
+ return content[start:end]
115
+
116
+
117
+ def _load_section() -> tuple[str, str]:
118
+ """(SKILL.md 全文, E-0 分岐節本文) を返す。呼び出し側で空ガードすること。"""
119
+ content = _read(DEV_WORKFLOW_SKILL_PATH)
120
+ return content, _e0_branch_section(content)
121
+
122
+
123
+ # --------------------------------------------------------------------------
124
+ # P1〜P8
125
+ # --------------------------------------------------------------------------
126
+
127
+
128
+ def test_p1_exit_block_exists_in_section() -> None:
129
+ """P1: 出口の存在 — 節範囲内に A1 が存在する。"""
130
+ content, section = _load_section()
131
+ assert content, f"SKILL.md が読めない/空: {DEV_WORKFLOW_SKILL_PATH}"
132
+ assert section, f"節見出しが見つからない(アンカー破損を疑う): {SECTION_HEADING}"
133
+
134
+ assert A1_EXIT_BLOCK_TITLE in section, (
135
+ f"E-0 分岐節に出口ブロック見出し {A1_EXIT_BLOCK_TITLE!r} が無い"
136
+ )
137
+
138
+
139
+ def test_p2_fail_safe_in_section() -> None:
140
+ """P2: fail-safe — 節範囲内に A5 が存在する。"""
141
+ content, section = _load_section()
142
+ assert content, f"SKILL.md が読めない/空: {DEV_WORKFLOW_SKILL_PATH}"
143
+ assert section, f"節見出しが見つからない(アンカー破損を疑う): {SECTION_HEADING}"
144
+
145
+ assert A5_FAIL_SAFE in section, (
146
+ f"E-0 分岐節に fail-safe 規定 {A5_FAIL_SAFE!r} が無い"
147
+ )
148
+
149
+
150
+ def test_p3_not_applied_in_autonomous_mode() -> None:
151
+ """P3: 自律不適用 — 節範囲内に A6 が存在する。"""
152
+ content, section = _load_section()
153
+ assert content, f"SKILL.md が読めない/空: {DEV_WORKFLOW_SKILL_PATH}"
154
+ assert section, f"節見出しが見つからない(アンカー破損を疑う): {SECTION_HEADING}"
155
+
156
+ assert A6_NOT_APPLIED_IN_AUTONOMOUS in section, (
157
+ f"E-0 分岐節に自律モード不適用の規定 {A6_NOT_APPLIED_IN_AUTONOMOUS!r} が無い"
158
+ )
159
+
160
+
161
+ def test_p4_autonomous_mode_skill_wording_frozen() -> None:
162
+ """P4: autonomous-mode 側の凍結(既存文言の回帰ガード・実装前から緑が正しい)。
163
+
164
+ tester.md の「テストが最初から Pass する場合は修正する」規範は本テストに適用しない
165
+ (architecture-report-20260813-183024 §7「P4 適用除外文」)。
166
+ """
167
+ content = _read(AUTONOMOUS_MODE_SKILL_PATH)
168
+ assert content, f"autonomous-mode/SKILL.md が読めない/空: {AUTONOMOUS_MODE_SKILL_PATH}"
169
+
170
+ assert P4_AUTONOMOUS_FROZEN in content, (
171
+ f"autonomous-mode/SKILL.md の既存規定 {P4_AUTONOMOUS_FROZEN!r} が失われている"
172
+ "(E-0 出口の追加で自律モード側を変更してはならない)"
173
+ )
174
+
175
+
176
+ def test_p5_record_format_in_section() -> None:
177
+ """P5: 証跡書式 — 節範囲内に A7 が存在する。"""
178
+ content, section = _load_section()
179
+ assert content, f"SKILL.md が読めない/空: {DEV_WORKFLOW_SKILL_PATH}"
180
+ assert section, f"節見出しが見つからない(アンカー破損を疑う): {SECTION_HEADING}"
181
+
182
+ assert A7_RECORD_FORMAT in section, (
183
+ f"E-0 分岐節に判定行の拡張書式 {A7_RECORD_FORMAT!r} が無い"
184
+ )
185
+
186
+
187
+ def test_p6_unknown_excluded_with_negative_control() -> None:
188
+ """P6: UNKNOWN 除外+負の対照。
189
+
190
+ 肯定(節範囲内に A4)と否定(SKILL.md 全文に禁止文言が不在)を**同一関数内で
191
+ 同じ content に対して** assert する。分割すると否定側が単独で緑になり
192
+ (実装前でも禁止文言は不在のため)空の緑になる。
193
+ """
194
+ content, section = _load_section()
195
+ assert content, f"SKILL.md が読めない/空: {DEV_WORKFLOW_SKILL_PATH}"
196
+ assert section, f"節見出しが見つからない(アンカー破損を疑う): {SECTION_HEADING}"
197
+
198
+ assert A4_UNKNOWN_OUT_OF_SCOPE in section, (
199
+ f"E-0 分岐節に UNKNOWN 除外の規定 {A4_UNKNOWN_OUT_OF_SCOPE!r} が無い"
200
+ )
201
+ assert P6_FORBIDDEN_PHRASE not in content, (
202
+ f"SKILL.md 全文に禁止文言 {P6_FORBIDDEN_PHRASE!r} が現れている"
203
+ "(UNKNOWN は本出口の対象外であり省略できない)"
204
+ )
205
+
206
+
207
+ def test_p7_scope_limited_to_needs_verify() -> None:
208
+ """P7: 適用範囲 — 節範囲内に A3 が存在する。"""
209
+ content, section = _load_section()
210
+ assert content, f"SKILL.md が読めない/空: {DEV_WORKFLOW_SKILL_PATH}"
211
+ assert section, f"節見出しが見つからない(アンカー破損を疑う): {SECTION_HEADING}"
212
+
213
+ assert A3_SCOPE_NEEDS_VERIFY_ONLY in section, (
214
+ f"E-0 分岐節に適用範囲の規定 {A3_SCOPE_NEEDS_VERIFY_ONLY!r} が無い"
215
+ )
216
+
217
+
218
+ def test_p8_one_question_gate_uses_ask_user_question() -> None:
219
+ """P8: 1 問ゲートであること — 節範囲内に ``AskUserQuestion`` が存在する。"""
220
+ content, section = _load_section()
221
+ assert content, f"SKILL.md が読めない/空: {DEV_WORKFLOW_SKILL_PATH}"
222
+ assert section, f"節見出しが見つからない(アンカー破損を疑う): {SECTION_HEADING}"
223
+
224
+ assert P8_ASK_USER_QUESTION in section, (
225
+ f"E-0 分岐節に {P8_ASK_USER_QUESTION!r} が無い(1 問ゲートが未設置)"
226
+ )