claude-code-conductor 2.68.0__tar.gz → 2.69.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 (268) hide show
  1. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/tier_autoapply.py +101 -37
  2. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/CHANGELOG.md +32 -0
  3. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/PKG-INFO +1 -1
  4. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/__init__.py +1 -1
  5. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_tier_autoapply.py +648 -37
  6. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_tier_security_fixes.py +5 -0
  7. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/.gitignore +0 -0
  8. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/CLAUDE.md +0 -0
  9. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/architect.md +0 -0
  10. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/code-reviewer.md +0 -0
  11. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/design-critic.md +0 -0
  12. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/developer.md +0 -0
  13. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/doc-writer.md +0 -0
  14. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/interviewer.md +0 -0
  15. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/planner.md +0 -0
  16. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/project-setup.md +0 -0
  17. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/security-reviewer.md +0 -0
  18. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/systematic-debugger.md +0 -0
  19. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/tester.md +0 -0
  20. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/wt_developer.md +0 -0
  21. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/wt_systematic-debugger.md +0 -0
  22. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/agents/wt_tester.md +0 -0
  23. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/breaking-changes.txt +0 -0
  24. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/deletions.txt +0 -0
  25. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/docs/autonomous-mode-onboarding.md +0 -0
  26. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/docs/config-policy.md +0 -0
  27. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/docs/nul-boundary.md +0 -0
  28. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/docs/parallel-agents-setup.md +0 -0
  29. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/docs/platform-adapters.md +0 -0
  30. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/docs/settings.json.md +0 -0
  31. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/_hook_utils.py +0 -0
  32. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/check_agent_invocation.py +0 -0
  33. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/consolidate_memory.py +0 -0
  34. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/patterns_guard.py +0 -0
  35. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/permission_handler.py +0 -0
  36. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/permission_handler_toast.py +0 -0
  37. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/planner_check.py +0 -0
  38. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/post_tool.py +0 -0
  39. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/pre_compact.py +0 -0
  40. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/pre_tool.py +0 -0
  41. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/recall_autorebuild.py +0 -0
  42. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/recall_inject.py +0 -0
  43. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/report_contract_check.py +0 -0
  44. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/report_path_guard.py +0 -0
  45. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/restore_session.py +0 -0
  46. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/select_tier.py +0 -0
  47. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/session_mode_watch.py +0 -0
  48. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/session_start.py +0 -0
  49. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/session_stop.py +0 -0
  50. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/session_utils.py +0 -0
  51. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/statusline.py +0 -0
  52. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/stop.py +0 -0
  53. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/tier_gap_check.py +0 -0
  54. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/hooks/worktree_guard.py +0 -0
  55. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/memory/.gitkeep +0 -0
  56. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/permission_rules.json +0 -0
  57. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/rules/promoted/index.md +0 -0
  58. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/settings.json +0 -0
  59. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/autonomous-mode/SKILL.md +0 -0
  60. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/autonomous-mode/scripts/mode_line.py +0 -0
  61. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/brainstorm/SKILL.md +0 -0
  62. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/codex-review/SKILL.md +0 -0
  63. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/SKILL.md +0 -0
  64. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/c3-omission-declaration.md +0 -0
  65. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/code-review-checklist.md +0 -0
  66. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/design-critic-rubric.md +0 -0
  67. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/design-rubric.md +0 -0
  68. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/interview-rubric.md +0 -0
  69. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/plan-design-guidelines.md +0 -0
  70. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/reachability-map.md +0 -0
  71. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/record-protocol.md +0 -0
  72. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/references/security-review-checklist.md +0 -0
  73. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/scripts/detect_execution_verification.py +0 -0
  74. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/scripts/record_agent_outcome.py +0 -0
  75. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/scripts/record_review_decision.py +0 -0
  76. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/dev-workflow/scripts/review_hint_inject.py +0 -0
  77. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/develop/SKILL.md +0 -0
  78. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/doc/SKILL.md +0 -0
  79. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/extract-lib/SKILL.md +0 -0
  80. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/init-session/SKILL.md +0 -0
  81. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/init-session/scripts/session_guard.py +0 -0
  82. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/mcp-config/SKILL.md +0 -0
  83. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/parallel-agents/SKILL.md +0 -0
  84. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/pattern-status/SKILL.md +0 -0
  85. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/promote-pattern/SKILL.md +0 -0
  86. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/recall/SKILL.md +0 -0
  87. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/report-timestamp/SKILL.md +0 -0
  88. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/report-timestamp/scripts/get_timestamp.py +0 -0
  89. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/review-phase/SKILL.md +0 -0
  90. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/setup/SKILL.md +0 -0
  91. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/setup/reference.md +0 -0
  92. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/setup/templates/coding-standards-template.md +0 -0
  93. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/setup/templates/project-conventions-template.md +0 -0
  94. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/start/SKILL.md +0 -0
  95. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/skills/start/scripts/archive_reports.py +0 -0
  96. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.claude/state/.gitkeep +0 -0
  97. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/.gitignore +0 -0
  98. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/ARCHITECTURE.md +0 -0
  99. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/LICENSE +0 -0
  100. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/LICENSES/fastembed-LICENSE +0 -0
  101. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/LICENSES/fastembed-NOTICE +0 -0
  102. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/LICENSES/numpy-LICENSE +0 -0
  103. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/LICENSES/onnxruntime-LICENSE +0 -0
  104. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/LICENSES/paraphrase-multilingual-MiniLM-L12-v2-LICENSE +0 -0
  105. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/README.md +0 -0
  106. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/hatch_build.py +0 -0
  107. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/pyproject.toml +0 -0
  108. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/__main__.py +0 -0
  109. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/_db_params.py +0 -0
  110. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/_excludes.py +0 -0
  111. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/_terminal.py +0 -0
  112. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/adapters.py +0 -0
  113. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli.py +0 -0
  114. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_ask.py +0 -0
  115. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_doctor.py +0 -0
  116. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_init.py +0 -0
  117. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_list.py +0 -0
  118. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_metrics.py +0 -0
  119. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_plan.py +0 -0
  120. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_recall.py +0 -0
  121. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_run.py +0 -0
  122. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_tier.py +0 -0
  123. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/cli_update.py +0 -0
  124. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/db.py +0 -0
  125. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/embedding.py +0 -0
  126. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/gitutil.py +0 -0
  127. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/mcp_server.py +0 -0
  128. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrate.py +0 -0
  129. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/001_initial.sql +0 -0
  130. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/002_agent_cost_runs.sql +0 -0
  131. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/003_tier_cost.sql +0 -0
  132. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/004_agent_outcomes.sql +0 -0
  133. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/005_drop_agent_tier_bandit.sql +0 -0
  134. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/006_review_decisions_severity.sql +0 -0
  135. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/007_review_decisions_resolution.sql +0 -0
  136. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/008_drop_agent_runs.sql +0 -0
  137. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/README.md +0 -0
  138. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/migrations/__init__.py +0 -0
  139. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/paths.py +0 -0
  140. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/plan_validator.py +0 -0
  141. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/platforms.py +0 -0
  142. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/pricing.py +0 -0
  143. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/question.py +0 -0
  144. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/recall_chunker.py +0 -0
  145. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/recall_index.py +0 -0
  146. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/refgraph.py +0 -0
  147. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/src/c3/usage_ingester.py +0 -0
  148. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/__init__.py +0 -0
  149. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/_pre_compact_helpers.py +0 -0
  150. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/conftest.py +0 -0
  151. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/fixtures/usage/README.md +0 -0
  152. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/fixtures/usage/mainline.jsonl +0 -0
  153. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/fixtures/usage/subagents/agent-deadbeef.jsonl +0 -0
  154. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/fixtures/usage/subagents/agent-deadbeef.meta.json +0 -0
  155. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/__init__.py +0 -0
  156. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_check_agent_invocation.py +0 -0
  157. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_consolidate_memory.py +0 -0
  158. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_detect_execution_verification.py +0 -0
  159. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_hook_utils.py +0 -0
  160. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_permission_handler.py +0 -0
  161. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_permission_handler_toast.py +0 -0
  162. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_pip_reinstall_reminder.py +0 -0
  163. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_planner_check.py +0 -0
  164. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_planner_check_dev.py +0 -0
  165. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_post_tool.py +0 -0
  166. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_pre_tool.py +0 -0
  167. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_recall_autorebuild.py +0 -0
  168. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_recall_inject.py +0 -0
  169. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_record_agent_outcome.py +0 -0
  170. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_record_review_decision.py +0 -0
  171. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_report_path_guard.py +0 -0
  172. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_restore_session.py +0 -0
  173. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_review_hint_inject.py +0 -0
  174. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_select_tier.py +0 -0
  175. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_select_tier_escalation.py +0 -0
  176. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_session_start.py +0 -0
  177. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_session_stop.py +0 -0
  178. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_session_utils.py +0 -0
  179. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_settings_local_absolute_paths.py +0 -0
  180. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_settings_tier_autoapply_registration.py +0 -0
  181. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_similarity_boost.py +0 -0
  182. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_statusline.py +0 -0
  183. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_statusline_template_sync.py +0 -0
  184. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_sync_check.py +0 -0
  185. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_template_guard.py +0 -0
  186. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/hooks/test_tier_gap_check.py +0 -0
  187. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/__init__.py +0 -0
  188. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/_skill_helpers.py +0 -0
  189. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_c3_omission_declaration.py +0 -0
  190. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_dev_workflow_no_task_type.py +0 -0
  191. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_init_session_no_task_type.py +0 -0
  192. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_marker_compliance.py +0 -0
  193. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_parallel_agents_skill_tier.py +0 -0
  194. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_planner_lightweight.py +0 -0
  195. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_reachability_map.py +0 -0
  196. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_recall_skill.py +0 -0
  197. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_session_backlog_reconciliation.py +0 -0
  198. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_session_guard.py +0 -0
  199. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_setup_templates.py +0 -0
  200. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_start_skill_bugfix_flow.py +0 -0
  201. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_start_skill_new_flow.py +0 -0
  202. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/skills/test_start_skill_security_audit_phase.py +0 -0
  203. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_adapters.py +0 -0
  204. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_archive_reports.py +0 -0
  205. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_audit_review_decisions.py +0 -0
  206. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_check_deletions.py +0 -0
  207. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_ci_workflows.py +0 -0
  208. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_claude_gitignore.py +0 -0
  209. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_ask.py +0 -0
  210. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_doctor.py +0 -0
  211. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_doctor_launcher.py +0 -0
  212. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_entry.py +0 -0
  213. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_init.py +0 -0
  214. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_list.py +0 -0
  215. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_metrics.py +0 -0
  216. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_plan.py +0 -0
  217. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_recall.py +0 -0
  218. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_run.py +0 -0
  219. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_tier.py +0 -0
  220. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_update_breaking_changes.py +0 -0
  221. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_cli_update_deletions.py +0 -0
  222. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_db.py +0 -0
  223. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_db_connect_lint.py +0 -0
  224. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_docstring_consistency.py +0 -0
  225. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_embedding.py +0 -0
  226. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_excludes.py +0 -0
  227. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_extract_breaking_changes.py +0 -0
  228. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_gitutil.py +0 -0
  229. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_hooks_stdin_idiom.py +0 -0
  230. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_init_only_patterns.py +0 -0
  231. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_mcp_server_elicit.py +0 -0
  232. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_migrate.py +0 -0
  233. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_mode_line.py +0 -0
  234. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_no_bare_python_launcher.py +0 -0
  235. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_no_passonly_tests.py +0 -0
  236. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_nul_boundary_lint.py +0 -0
  237. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_paths.py +0 -0
  238. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_patterns_guard.py +0 -0
  239. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_plan_validator.py +0 -0
  240. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_pre_compact.py +0 -0
  241. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_pre_tool_hook.py +0 -0
  242. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_precompact_additional.py +0 -0
  243. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_precompact_toctou_fixes.py +0 -0
  244. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_pricing.py +0 -0
  245. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_recall_chunker.py +0 -0
  246. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_recall_index.py +0 -0
  247. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_references_migration.py +0 -0
  248. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_refgraph.py +0 -0
  249. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_refgraph_query.py +0 -0
  250. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_refgraph_structural.py +0 -0
  251. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_report_contract_check.py +0 -0
  252. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_scripts_src_bootstrap.py +0 -0
  253. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_scripts_stdout_encoding.py +0 -0
  254. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_session_mode_watch.py +0 -0
  255. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_session_utils_additional.py +0 -0
  256. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_settings_hooks_registration.py +0 -0
  257. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_skill_no_builtin_conflict.py +0 -0
  258. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_start_skill_archive_contract.py +0 -0
  259. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_statusline.py +0 -0
  260. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_stop_additional.py +0 -0
  261. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_stop_agent_memory_warn.py +0 -0
  262. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_stop_hook.py +0 -0
  263. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_stop_precompact_fixes.py +0 -0
  264. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_sync_template_stop.py +0 -0
  265. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_template_pre_tool_hook.py +0 -0
  266. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_usage_ingester.py +0 -0
  267. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_worktree_guard.py +0 -0
  268. {claude_code_conductor-2.68.0 → claude_code_conductor-2.69.0}/tests/test_wt_agent_sync.py +0 -0
@@ -20,7 +20,9 @@ check_agent は reviewer 系のみ)のため実行順序に依存しない(
20
20
  - tier_selection 不在/破損/非文字列 tier のときは注入せず素通り
21
21
  (source=frontmatter-default・frontmatter の sonnet が実効するため)。
22
22
  - `LAUNCH_LOG_ROLES = {developer, wt_developer, tester, wt_tester}` は
23
- 注入有無に関わらず applied-state(tier_autoapply.jsonl)へ 1 行追記した。
23
+ 注入有無に関わらず applied-state(tier_autoapply.jsonl)へ 1 行追記した
24
+ (ロックを取得できない場合のみ追記を断念する。注入は断念に影響されない・
25
+ `_append_applied_state` 参照)。
24
26
  reviewer 系・その他 role は記録も注入もしない(exit 0 素通り)。
25
27
  - 起動プロンプト先頭の `C3_TASK_ID:` マーカーを抽出し jsonl の `task_id` に
26
28
  載せた(T8・並列経路の record 突合キー)。
@@ -46,8 +48,10 @@ from __future__ import annotations
46
48
  import collections
47
49
  import json
48
50
  import os
51
+ import random
49
52
  import re
50
53
  import sys
54
+ import time
51
55
  from datetime import datetime, timezone
52
56
 
53
57
  try:
@@ -83,6 +87,7 @@ if not (_CLAUDE_DIR.endswith(os.sep + ".claude") or _CLAUDE_DIR.endswith("/.clau
83
87
 
84
88
  TIER_SELECTION_PATH = os.path.join(_CLAUDE_DIR, "state", "tier_selection.json")
85
89
  APPLIED_STATE_PATH = os.path.join(_CLAUDE_DIR, "state", "tier_autoapply.jsonl")
90
+ LOCK_FILE_PATH = APPLIED_STATE_PATH + ".lock"
86
91
 
87
92
  # §3-2 ロール分岐表の定数。
88
93
  # APPLY_ROLES: 無条件 APPLY(起動フェーズを問わず tier_selection.json のトップレベル
@@ -117,6 +122,12 @@ _ROTATE_TAIL_LINES = 500
117
122
 
118
123
  _PROMPT_PREFIX_MAX_CHARS = 200
119
124
 
125
+ # ロック取得の非ブロック試行+ms リトライパラメータ(§2-1)。
126
+ # 非ブロック 1 回試行で失敗時に以下の間隔で再試行し、締切 5 秒で断念する。
127
+ _LOCK_RETRY_INTERVAL_SEC = 0.02 # 基本リトライ間隔 20ms
128
+ _LOCK_RETRY_JITTER_SEC = 0.02 # 一様乱数 [0, 20ms) を毎回加算(脱同期・P4)
129
+ _LOCK_DEADLINE_SEC = 5.0 # 締切(P2・B 裁定 #3)
130
+
120
131
  # T8: 起動プロンプト先頭の C3_TASK_ID マーカー抽出用(§3-1・SR-AI-001 で \A 化)。
121
132
  # 文字列先頭アンカー \A + allowlist + 上限200字で誤抽出・秘密混入を構造排除する
122
133
  # (record MAX_TASK_LEN=200 と整合)。re.MULTILINE の行頭 ^ は本文孤立行・フェンス内・
@@ -291,17 +302,52 @@ def _rotate_if_needed(path: str) -> None:
291
302
  pass
292
303
 
293
304
 
294
- def _os_lock(lock_f) -> None:
295
- """ロックファイルのバイト0に排他ロックを取得した(取得不能時は例外を送出)。"""
296
- if msvcrt is not None:
297
- lock_f.seek(0)
298
- msvcrt.locking(lock_f.fileno(), msvcrt.LK_LOCK, 1)
299
- elif fcntl is not None:
300
- fcntl.flock(lock_f.fileno(), fcntl.LOCK_EX)
305
+ def _try_os_lock(lock_f) -> bool:
306
+ """ロックファイルのバイト0に排他ロックを非ブロック 1 回試行した。
307
+
308
+ 取得成功時 True、競合失敗時 False。競合以外の OSError(EBADF 等)も False 扱い。
309
+ Windows は seek(0) の後 msvcrt.locking LK_NBLCK / POSIX は fcntl.flock LOCK_EX|LOCK_NB。
310
+ msvcrt / fcntl 両方不在の環境では取得成功扱いで True を返す(DC-AS-002・ADR-5)。
311
+ """
312
+ if msvcrt is None and fcntl is None:
313
+ # ロック機構が両方不在(理論上rare)の場合は取得成功とみなす
314
+ return True
315
+ try:
316
+ # 冒頭ガードにより、ここに到達する時点で msvcrt / fcntl の少なくとも一方は
317
+ # 非 None が保証されている(DC-AS-004・CR-Q-005)。if/else で全経路が bool を
318
+ # 返すことを構造から読めるようにし、到達不能な末尾 return は置かない。
319
+ if msvcrt is not None:
320
+ lock_f.seek(0)
321
+ msvcrt.locking(lock_f.fileno(), msvcrt.LK_NBLCK, 1)
322
+ return True
323
+ else:
324
+ fcntl.flock(lock_f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
325
+ return True
326
+ except OSError:
327
+ return False
328
+
329
+
330
+ def _acquire_lock(lock_f) -> bool:
331
+ """非ブロック試行+ms リトライループでロック取得を試行した。
332
+
333
+ time.monotonic() 基準の締切内に _try_os_lock が成功したら True、
334
+ 締切超過で失敗時は False。リトライ待ち時間はジッター付き。
335
+ """
336
+ deadline = time.monotonic() + _LOCK_DEADLINE_SEC
337
+ while True:
338
+ if _try_os_lock(lock_f):
339
+ return True
340
+ if time.monotonic() >= deadline:
341
+ return False
342
+ time.sleep(_LOCK_RETRY_INTERVAL_SEC + random.uniform(0, _LOCK_RETRY_JITTER_SEC))
301
343
 
302
344
 
303
345
  def _os_unlock(lock_f) -> None:
304
- """_os_lock で取得したロックを解放した(失敗時は無視)。"""
346
+ """_try_os_lock で取得したロックを解放した(失敗時は無視)。
347
+
348
+ 取得側と同一領域(バイト0の 1 バイト)を対象にするため、Windows は
349
+ _try_os_lock と同じく seek(0) を先行させる(DC-AS-003・非対称だと解放漏れになる)。
350
+ """
305
351
  try:
306
352
  if msvcrt is not None:
307
353
  lock_f.seek(0)
@@ -316,54 +362,72 @@ def _append_applied_state(row: dict) -> None:
316
362
  """applied-state(jsonl)へ 1 行を単一 write で追記した(§3-4・追記前にローテーション)。
317
363
 
318
364
  専用ロックファイル(`<jsonl>.lock`)の OS ロックで並行 append を直列化した。
319
- ロックはハンドルクローズ/プロセス終了時に OS が自動解放するため、
320
- ロックファイルが残っても後続の追記をブロックしない(stale-lock デッドロック回避)。
365
+ ロック取得は非ブロック試行+ms リトライ(ジッター付き・締切 `_LOCK_DEADLINE_SEC`)で、
366
+ 取得できたときだけ追記する。締切超過・ロックファイル open 失敗・mkdir 失敗は
367
+ 「追記せず stderr に固定文言」で断念し、無ロックのまま追記する経路は持たない(P1・ADR-1)。
368
+
369
+ 注入判定への影響はない(P5)。断念時も呼び出し側は stdout へ updatedInput を
370
+ 出力して注入を継続する。
321
371
 
322
- ロックファイル(`<jsonl>.lock`)の永続化について(CR F-6):
323
- このファイルは削除せず `.claude/state/*` の gitignore exclude パターンで
324
- 配布対象外にしている(_rotate_if_needed 同様の設計)。stale-lock 回避のため
325
- OS ハンドル解放に委ね、明示的な削除を行わない。
372
+ ロックファイルは削除せず残す(CR F-6)。`.claude/state/*` の gitignore exclude
373
+ パターンで配布対象外にしている(_rotate_if_needed 同様の設計)。残っていても
374
+ ロック自体は OS がハンドルクローズ/プロセス終了時に解放するため後続を妨げない。
326
375
  """
327
376
  line = json.dumps(row, ensure_ascii=False)
328
- lock_path = APPLIED_STATE_PATH + ".lock"
329
377
  # item2(SR-V-002・Low): jsonl 本体・ロックファイルのいずれかが symlink の場合は
330
378
  # 追記全体を沈黙 skip(リンク先への誘導書き込みを防ぐ・fail-safe)。open で
331
379
  # follow する前に検証する。Windows は O_NOFOLLOW 非対応のため islink で分岐する
332
380
  # (POSIX 慣行に合わせた可搬な検証)。tier_gap_check.py 読み取り側と同型。
333
381
  # [CR-NEW3] islink 検証→open 間の TOCTOU レースは構造的に残存するが既知・脅威モデル外
334
382
  # (Windows O_NOFOLLOW 非対応による設計選択。stale-lock TOCTOU と同種の回避不能パターン)。
335
- if os.path.islink(APPLIED_STATE_PATH) or os.path.islink(lock_path):
383
+ if os.path.islink(APPLIED_STATE_PATH) or os.path.islink(LOCK_FILE_PATH):
336
384
  return
337
385
  try:
338
386
  os.makedirs(os.path.dirname(APPLIED_STATE_PATH), exist_ok=True)
339
- except OSError as exc:
340
- print(f"[tier_autoapply] mkdir failed: {type(exc).__name__}", file=sys.stderr)
387
+ except OSError:
388
+ # mkdir 失敗(断念理由: mkdir-failed)。P3 に合わせ可観測性を確保。
389
+ print("[tier_autoapply] append skipped: reason=mkdir-failed", file=sys.stderr)
341
390
  return
342
391
 
343
392
  lock_f = None
344
393
  try:
345
- lock_f = open(lock_path, "a+", encoding="utf-8")
346
- except OSError:
347
- lock_f = None
348
-
349
- locked = False
350
- try:
351
- if lock_f is not None:
352
- try:
353
- _os_lock(lock_f)
354
- locked = True
355
- except OSError:
356
- locked = False # ロック不能でもベストエフォートで追記する。
357
- _rotate_if_needed(APPLIED_STATE_PATH)
358
- with open(APPLIED_STATE_PATH, "a", encoding="utf-8") as f:
359
- f.write(line + "\n")
360
- except OSError as exc:
361
- print(f"[tier_autoapply] append failed: {type(exc).__name__}", file=sys.stderr)
394
+ try:
395
+ lock_f = open(LOCK_FILE_PATH, "a+", encoding="utf-8")
396
+ except OSError:
397
+ # ロックファイル open 失敗(断念理由: lockfile-open-failed)
398
+ print("[tier_autoapply] append skipped: reason=lockfile-open-failed", file=sys.stderr)
399
+ return
400
+
401
+ locked = False
402
+ try:
403
+ locked = _acquire_lock(lock_f)
404
+ except OSError:
405
+ # リトライループ中の OSError は取得失敗扱いで断念(fail-safe)
406
+ locked = False
407
+
408
+ # 締切超過・ロック取得失敗時は追記せず断念した(P1)
409
+ if not locked:
410
+ print("[tier_autoapply] append skipped: reason=deadline", file=sys.stderr)
411
+ return
412
+
413
+ try:
414
+ _rotate_if_needed(APPLIED_STATE_PATH)
415
+ with open(APPLIED_STATE_PATH, "a", encoding="utf-8") as f:
416
+ f.write(line + "\n")
417
+ except OSError:
418
+ # 追記本体(rotate/write)失敗(断念理由: write-failed)。P3 に合わせ可観測性を
419
+ # 確保する(CR-E-002・改訂 2)。他 3 経路と同形式(固定文言のみ・外部由来文字列なし)。
420
+ print("[tier_autoapply] append skipped: reason=write-failed", file=sys.stderr)
362
421
  finally:
422
+ # open 成功後の全経路(追記完了・断念・例外)で解放とクローズを保証した。
423
+ # _os_unlock 自身が失敗を握るためここでの追加ガードは不要。
363
424
  if lock_f is not None:
364
425
  if locked:
365
426
  _os_unlock(lock_f)
366
- lock_f.close()
427
+ try:
428
+ lock_f.close()
429
+ except OSError:
430
+ pass
367
431
 
368
432
 
369
433
  def main() -> None:
@@ -1,5 +1,37 @@
1
1
  # Changelog
2
2
 
3
+ ## [2.69.0] - 2026-08-13
4
+
5
+ ### 修正
6
+
7
+ - **`tier_autoapply.py` のロック機構を非ブロック試行+ms リトライへ置換した**(フレーキー根治・
8
+ 学習記録の行消失の構造的排除)。従来の `msvcrt.locking(LK_LOCK)` は CRT 仕様で「1 秒間隔
9
+ リトライ・10 回で OSError」のため、複数 agent の同時起動時に待機側のリトライが 1 秒境界に
10
+ 同期するロックコンボイが発生し、リトライを枯渇した個体が無ロック追記フォールバックに落ちて
11
+ **他プロセスの追記行を上書き消失させる**実欠陥があった(`TestConcurrency` の非決定的失敗
12
+ 〔2026-08-04 起票〕の根本原因。実運用の parallel-agents wave 一斉起動でも発生しうる)。
13
+ 新実装は LK_NBLCK / `LOCK_EX|LOCK_NB` の非ブロック試行+ms 粒度リトライ(20ms 間隔+
14
+ 0〜20ms ジッターで脱同期・`time.monotonic()` 基準の締切 5 秒)で、実測でコンボイ・行消失とも
15
+ 消滅(42 回反復失敗 0・20 並列時の最大取得待ち 0.109 秒)
16
+
17
+ ### 変更
18
+
19
+ - **ロック取得失敗時の無ロック追記フォールバックを全廃し断念設計へ変更した**。ロック競合が
20
+ 締切 5 秒を超えた場合、当該 1 行の記録を断念して stderr に固定文言を出す(学習記録 1 行の
21
+ 欠落に留まり、他プロセスの行を壊さない)。記録処理到達後の断念 4 経路
22
+ (`reason=deadline` / `reason=lockfile-open-failed` / `reason=mkdir-failed` /
23
+ `reason=write-failed`)すべてが固定文言の stderr 証跡を持つ(沈黙断念ゼロ・外部由来文字列は
24
+ 含めない)。記録の断念は tier 機械適用(model 注入)に影響しない
25
+ - hook の最悪ブロック時間は従来の約 10 秒から締切 5 秒へ半減した
26
+
27
+ ### 内部
28
+
29
+ - `tests/hooks/test_tier_autoapply.py` に P1〜P5 の性質テスト群・断念 4 経路の完全一致固定・
30
+ 実競合下のジッター検証(jitter=0 対照で赤化する検知力を実証済み)・ADR-5 / mkdir / write の
31
+ 回帰網を追加(52→56 テスト)。`TestConcurrency` は判定コード不変
32
+ - `docs/spec/00-index.md` の凍結宣言に注記 1 行を追加(02-hooks.md / 05-state-db.md の
33
+ ロック記述は旧実装前提である旨)
34
+
3
35
  ## [2.68.0] - 2026-08-13
4
36
 
5
37
  ### 破壊的変更
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: claude-code-conductor
3
- Version: 2.68.0
3
+ Version: 2.69.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.68.0"
3
+ __version__ = "2.69.0"