deviatdd 2.22.1__tar.gz → 2.23.1__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 (475) hide show
  1. deviatdd-2.23.1/.deviate/config.toml +20 -0
  2. {deviatdd-2.22.1 → deviatdd-2.23.1}/CHANGELOG.md +9 -0
  3. {deviatdd-2.22.1 → deviatdd-2.23.1}/PKG-INFO +6 -6
  4. {deviatdd-2.22.1 → deviatdd-2.23.1}/README.md +5 -5
  5. {deviatdd-2.22.1 → deviatdd-2.23.1}/pyproject.toml +1 -1
  6. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/DeviaTDD-api.md +56 -36
  7. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/DeviaTDD-architecture.md +40 -25
  8. deviatdd-2.23.1/specs/adhoc/031-judge-revert-boundary-no-failing-test/plan.md +149 -0
  9. deviatdd-2.23.1/specs/adhoc/031-judge-revert-boundary-no-failing-test/tasks.jsonl +5 -0
  10. deviatdd-2.23.1/specs/adhoc/031-judge-revert-boundary-no-failing-test/tasks.md +118 -0
  11. deviatdd-2.23.1/specs/adhoc/issues/029-ponytail-pruning-in-review.md +126 -0
  12. deviatdd-2.23.1/specs/adhoc/issues/030-config-rework.md +87 -0
  13. deviatdd-2.23.1/specs/adhoc/issues/031-judge-revert-boundary-no-failing-test.md +78 -0
  14. deviatdd-2.23.1/specs/adhoc/issues/032-judge-feedback-injection-fail-close.md +75 -0
  15. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/prd.md +55 -0
  16. deviatdd-2.23.1/specs/explore/config-rework.md +134 -0
  17. deviatdd-2.23.1/specs/explore/ponytail-pruning.md +136 -0
  18. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/issues.jsonl +17 -0
  19. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/__init__.py +96 -31
  20. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/meso.py +25 -10
  21. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/micro.py +46 -4
  22. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/agent.py +85 -5
  23. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/commands.py +7 -4
  24. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/issues.py +6 -5
  25. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/worktree.py +4 -2
  26. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/judge.md +1 -1
  27. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/skills/deviatdd/SKILL.md +22 -5
  28. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/state/config.py +3 -3
  29. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/state/ledger.py +18 -3
  30. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/conftest.py +6 -1
  31. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_init.py +28 -83
  32. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_meso.py +5 -4
  33. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_micro.py +131 -2
  34. deviatdd-2.23.1/tests/test_cli/test_setup.py +104 -0
  35. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_agent.py +138 -1
  36. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_issues.py +29 -0
  37. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_worktree.py +45 -0
  38. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_meso_orchestration.py +51 -0
  39. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_judge.py +278 -0
  40. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_state/test_ledger.py +69 -0
  41. {deviatdd-2.22.1 → deviatdd-2.23.1}/uv.lock +1 -1
  42. deviatdd-2.22.1/.deviate/config.toml +0 -16
  43. {deviatdd-2.22.1 → deviatdd-2.23.1}/.deviate/.gitignore +0 -0
  44. {deviatdd-2.22.1 → deviatdd-2.23.1}/.deviate/evaluations/deviate-flows-skill-2026-06-26.json +0 -0
  45. {deviatdd-2.22.1 → deviatdd-2.23.1}/.env.example +0 -0
  46. {deviatdd-2.22.1 → deviatdd-2.23.1}/.gitattributes +0 -0
  47. {deviatdd-2.22.1 → deviatdd-2.23.1}/.githooks/pre-commit +0 -0
  48. {deviatdd-2.22.1 → deviatdd-2.23.1}/.githooks/pre-push +0 -0
  49. {deviatdd-2.22.1 → deviatdd-2.23.1}/.github/ISSUE_TEMPLATE/bug.md +0 -0
  50. {deviatdd-2.22.1 → deviatdd-2.23.1}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  51. {deviatdd-2.22.1 → deviatdd-2.23.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  52. {deviatdd-2.22.1 → deviatdd-2.23.1}/.github/workflows/ci.yml +0 -0
  53. {deviatdd-2.22.1 → deviatdd-2.23.1}/.github/workflows/release.yml +0 -0
  54. {deviatdd-2.22.1 → deviatdd-2.23.1}/.gitignore +0 -0
  55. {deviatdd-2.22.1 → deviatdd-2.23.1}/.opencode/opencode.json +0 -0
  56. {deviatdd-2.22.1 → deviatdd-2.23.1}/AGENTS.md +0 -0
  57. {deviatdd-2.22.1 → deviatdd-2.23.1}/CLAUDE.md +0 -0
  58. {deviatdd-2.22.1 → deviatdd-2.23.1}/CODE_OF_CONDUCT.md +0 -0
  59. {deviatdd-2.22.1 → deviatdd-2.23.1}/CONTRIBUTING.md +0 -0
  60. {deviatdd-2.22.1 → deviatdd-2.23.1}/LICENSE +0 -0
  61. {deviatdd-2.22.1 → deviatdd-2.23.1}/SECURITY.md +0 -0
  62. {deviatdd-2.22.1 → deviatdd-2.23.1}/deviatdd.png +0 -0
  63. {deviatdd-2.22.1 → deviatdd-2.23.1}/mise.toml +0 -0
  64. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat/001-deviate-cli-python/008-meso-macro-automated-orchestration.md +0 -0
  65. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat/adhoc/006-context-cli-integration.md +0 -0
  66. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat/adhoc/017-optional-push-as-lock.md +0 -0
  67. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-001-deviate-cli-python-001-cli-initialization-governance-provisioning-pr-11.md +0 -0
  68. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-001-deviate-cli-python-003-meso-layer-specification-task-decomposition.md +0 -0
  69. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-001-deviate-cli-python-004-micro-layer-tdd-sandbox-execution.md +0 -0
  70. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-001-deviate-cli-python-005-cli-architecture-realignment-skill-integration.md +0 -0
  71. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-001-deviate-cli-python-007-macro-meso-parity-backward-compatibility.md +0 -0
  72. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-002-deviatdd-gap-analysis-001-foundation-cli-infrastructure.md +0 -0
  73. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-002-deviatdd-gap-analysis-003-fast-path-commands.md +0 -0
  74. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-002-deviatdd-gap-analysis-004-governance-inspection.md +0 -0
  75. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-adhoc-001-streaming-pipeline-monitor.md +0 -0
  76. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-adhoc-008-ast-phase-prioritization.md +0 -0
  77. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat-adhoc-017-two-counter-tdd-retry.md +0 -0
  78. {deviatdd-2.22.1 → deviatdd-2.23.1}/pr_descriptions/feat_002-deviatdd-gap-analysis_001-foundation-cli-infrastructure.md +0 -0
  79. {deviatdd-2.22.1 → deviatdd-2.23.1}/scripts/benchmark_lmstudio.py +0 -0
  80. {deviatdd-2.22.1 → deviatdd-2.23.1}/scripts/next_version.py +0 -0
  81. {deviatdd-2.22.1 → deviatdd-2.23.1}/scripts/verify_install.py +0 -0
  82. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/manifest-t001.json +0 -0
  83. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/manifest-t002.json +0 -0
  84. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/manifest-t004.json +0 -0
  85. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/spec.md +0 -0
  86. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/tasks.md +0 -0
  87. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/002-macro-layer-state-ledger-management/spec.md +0 -0
  88. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/002-macro-layer-state-ledger-management/tasks.md +0 -0
  89. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/003-meso-layer-specification-task-decomposition/spec.md +0 -0
  90. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/003-meso-layer-specification-task-decomposition/tasks.md +0 -0
  91. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/004-micro-layer-tdd-sandbox-execution/spec.md +0 -0
  92. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/004-micro-layer-tdd-sandbox-execution/tasks.jsonl +0 -0
  93. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/004-micro-layer-tdd-sandbox-execution/tasks.md +0 -0
  94. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/005-cli-architecture-realignment-skill-integration/spec.md +0 -0
  95. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/005-cli-architecture-realignment-skill-integration/tasks.md +0 -0
  96. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/007-macro-meso-parity-backward-compatibility/spec.md +0 -0
  97. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/007-macro-meso-parity-backward-compatibility/tasks.md +0 -0
  98. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/008-meso-macro-automated-orchestration/spec.md +0 -0
  99. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/008-meso-macro-automated-orchestration/tasks.jsonl +0 -0
  100. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/008-meso-macro-automated-orchestration/tasks.md +0 -0
  101. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/data-model.md +0 -0
  102. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/design.md +0 -0
  103. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/explore.md +0 -0
  104. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/issues/001-cli-initialization-governance-provisioning.md +0 -0
  105. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/issues/002-macro-layer-state-ledger-management.md +0 -0
  106. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/issues/003-meso-layer-specification-task-decomposition.md +0 -0
  107. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/issues/004-micro-layer-tdd-sandbox-execution.md +0 -0
  108. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/issues/005-cli-architecture-realignment-skill-integration.md +0 -0
  109. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/issues/006-state-persistence-concurrency-safety.md +0 -0
  110. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/issues/007-macro-meso-parity-backward-compatibility.md +0 -0
  111. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/issues/008-meso-macro-automated-orchestration.md +0 -0
  112. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/001-deviate-cli-python/prd.md +0 -0
  113. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/001-foundation-cli-infrastructure/spec.md +0 -0
  114. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/001-foundation-cli-infrastructure/tasks.jsonl +0 -0
  115. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/001-foundation-cli-infrastructure/tasks.md +0 -0
  116. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/003-fast-path-commands/spec.md +0 -0
  117. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/003-fast-path-commands/tasks.jsonl +0 -0
  118. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/003-fast-path-commands/tasks.md +0 -0
  119. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/004-governance-inspection/spec.md +0 -0
  120. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/004-governance-inspection/tasks.jsonl +0 -0
  121. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/004-governance-inspection/tasks.md +0 -0
  122. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/005-micro-layer-integrity/spec.md +0 -0
  123. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/005-micro-layer-integrity/tasks.jsonl +0 -0
  124. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/005-micro-layer-integrity/tasks.md +0 -0
  125. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/data-model.md +0 -0
  126. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/design.md +0 -0
  127. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/explore.md +0 -0
  128. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/issues/001-foundation-cli-infrastructure.md +0 -0
  129. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/issues/002-context-pipeline.md +0 -0
  130. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/issues/003-fast-path-commands.md +0 -0
  131. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/issues/004-governance-inspection.md +0 -0
  132. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/issues/005-micro-layer-integrity.md +0 -0
  133. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/plan-tdd-integration-gap.md +0 -0
  134. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/002-deviatdd-gap-analysis/prd.md +0 -0
  135. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/003-graphite-cli-integration/explore.md +0 -0
  136. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/004-per-task-security-profile/issues/001-security-profile-and-judge-checks.md +0 -0
  137. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/001-verification-mode-metadata/plan.md +0 -0
  138. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/001-verification-mode-metadata/tasks.jsonl +0 -0
  139. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/001-verification-mode-metadata/tasks.md +0 -0
  140. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/002-task-acceptance-traceability/plan.md +0 -0
  141. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/002-task-acceptance-traceability/tasks.jsonl +0 -0
  142. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/002-task-acceptance-traceability/tasks.md +0 -0
  143. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/data-model.md +0 -0
  144. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/design.md +0 -0
  145. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/explore.md +0 -0
  146. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/issues/001-verification-mode-metadata.md +0 -0
  147. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/issues/002-task-acceptance-traceability.md +0 -0
  148. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/issues/003-micro-phase-gates-red-green.md +0 -0
  149. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/issues/004-refactor-regression-gate.md +0 -0
  150. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/issues/005-prompt-spec-alignment.md +0 -0
  151. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/005-acceptance-gates/prd.md +0 -0
  152. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/architecture.md +0 -0
  153. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/domain-model.md +0 -0
  154. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/flows/flows-product.md +0 -0
  155. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/flows/flows-streaming.md +0 -0
  156. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/flows/index.md +0 -0
  157. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/flows.jsonl +0 -0
  158. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/guildwright-current-system.md +0 -0
  159. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/guildwright-gap-register.md +0 -0
  160. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/guildwright-git-state-model.md +0 -0
  161. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/guildwright-rewrite.md +0 -0
  162. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/guildwright-rust-tui-requirements.md +0 -0
  163. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/_product/release-next.md +0 -0
  164. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/001-streaming-pipeline-monitor/spec.md +0 -0
  165. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/001-streaming-pipeline-monitor/tasks.jsonl +0 -0
  166. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/001-streaming-pipeline-monitor/tasks.md +0 -0
  167. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/003-meso-layer-restructuring/spec.md +0 -0
  168. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/003-meso-layer-restructuring/tasks.jsonl +0 -0
  169. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/003-meso-layer-restructuring/tasks.md +0 -0
  170. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/004-deviate-review-skill/spec.md +0 -0
  171. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/004-deviate-review-skill/tasks.jsonl +0 -0
  172. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/004-deviate-review-skill/tasks.md +0 -0
  173. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/005-per-phase-model-configuration/plan.md +0 -0
  174. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/005-per-phase-model-configuration/tasks.jsonl +0 -0
  175. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/005-per-phase-model-configuration/tasks.md +0 -0
  176. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/006-context-cli-integration/plan.md +0 -0
  177. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/006-context-cli-integration/tasks.jsonl +0 -0
  178. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/006-context-cli-integration/tasks.md +0 -0
  179. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/007-graphite-cli/plan.md +0 -0
  180. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/007-graphite-cli/tasks.jsonl +0 -0
  181. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/007-graphite-cli/tasks.md +0 -0
  182. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/008-ast-phase-prioritization/plan.md +0 -0
  183. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/008-ast-phase-prioritization/tasks.jsonl +0 -0
  184. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/008-ast-phase-prioritization/tasks.md +0 -0
  185. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/009-pi-agent-backend-integration/plan.md +0 -0
  186. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/009-pi-agent-backend-integration/tasks.jsonl +0 -0
  187. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/009-pi-agent-backend-integration/tasks.md +0 -0
  188. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/010-deviate-setup-product-layer/plan.md +0 -0
  189. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/010-deviate-setup-product-layer/tasks.jsonl +0 -0
  190. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/010-deviate-setup-product-layer/tasks.md +0 -0
  191. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/013-flow-ledger-canonical-source-of-truth/plan.md +0 -0
  192. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/013-flow-ledger-canonical-source-of-truth/tasks.jsonl +0 -0
  193. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/013-flow-ledger-canonical-source-of-truth/tasks.md +0 -0
  194. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/015-narrow-product-flow-scope/plan.md +0 -0
  195. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/015-narrow-product-flow-scope/tasks.md +0 -0
  196. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/016-single-source-prompt-templates/plan.md +0 -0
  197. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/016-single-source-prompt-templates/tasks.jsonl +0 -0
  198. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/016-single-source-prompt-templates/tasks.md +0 -0
  199. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/017-optional-push-as-lock/plan.md +0 -0
  200. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/017-optional-push-as-lock/tasks.jsonl +0 -0
  201. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/017-optional-push-as-lock/tasks.md +0 -0
  202. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/017-two-counter-tdd-retry/plan.md +0 -0
  203. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/017-two-counter-tdd-retry/tasks.jsonl +0 -0
  204. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/017-two-counter-tdd-retry/tasks.md +0 -0
  205. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/018-one-behavior-rgr-granularity/plan.md +0 -0
  206. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/018-one-behavior-rgr-granularity/tasks.md +0 -0
  207. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/019-remote-aware-ordinal-allocation/plan.md +0 -0
  208. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/019-remote-aware-ordinal-allocation/tasks.jsonl +0 -0
  209. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/019-remote-aware-ordinal-allocation/tasks.md +0 -0
  210. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/020-judge-compliance-pass-evidence/plan.md +0 -0
  211. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/020-judge-compliance-pass-evidence/tasks.jsonl +0 -0
  212. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/020-judge-compliance-pass-evidence/tasks.md +0 -0
  213. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/021-no-failing-test-escalate-invokes-green/plan.md +0 -0
  214. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/021-no-failing-test-escalate-invokes-green/tasks.jsonl +0 -0
  215. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/021-no-failing-test-escalate-invokes-green/tasks.md +0 -0
  216. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/022-already-satisfied-red-requires-tests/plan.md +0 -0
  217. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/022-already-satisfied-red-requires-tests/tasks.jsonl +0 -0
  218. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/022-already-satisfied-red-requires-tests/tasks.md +0 -0
  219. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/023-pinned-micro-run-issue-scoped/plan.md +0 -0
  220. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/023-pinned-micro-run-issue-scoped/tasks.jsonl +0 -0
  221. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/023-pinned-micro-run-issue-scoped/tasks.md +0 -0
  222. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/024-worktree-session-stale-issue-id/plan.md +0 -0
  223. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/024-worktree-session-stale-issue-id/tasks.jsonl +0 -0
  224. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/024-worktree-session-stale-issue-id/tasks.md +0 -0
  225. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/025-green-stderr-noise-stall-detector/plan.md +0 -0
  226. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/025-green-stderr-noise-stall-detector/tasks.jsonl +0 -0
  227. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/025-green-stderr-noise-stall-detector/tasks.md +0 -0
  228. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/026-pi-spawn-lean-tool-schema/plan.md +0 -0
  229. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/026-pi-spawn-lean-tool-schema/tasks.jsonl +0 -0
  230. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/026-pi-spawn-lean-tool-schema/tasks.md +0 -0
  231. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/027-red-hang-timeout-rollback/plan.md +0 -0
  232. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/027-red-hang-timeout-rollback/tasks.jsonl +0 -0
  233. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/027-red-hang-timeout-rollback/tasks.md +0 -0
  234. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/028-task-scoped-judge-review-coverage/plan.md +0 -0
  235. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/028-task-scoped-judge-review-coverage/tasks.jsonl +0 -0
  236. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/028-task-scoped-judge-review-coverage/tasks.md +0 -0
  237. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/001-streaming-pipeline-monitor.md +0 -0
  238. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/002-aider-agent-backend-integration.md +0 -0
  239. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/003-meso-layer-restructuring.md +0 -0
  240. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/004-deviate-review-skill.md +0 -0
  241. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/005-per-phase-model-configuration.md +0 -0
  242. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/006-context-cli-integration.md +0 -0
  243. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/007-graphite-cli.md +0 -0
  244. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/008-ast-phase-prioritization.md +0 -0
  245. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/009-pi-agent-backend-integration.md +0 -0
  246. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/010-deviate-setup-product-layer.md +0 -0
  247. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/012-rpc-streaming-tui-renderer.md +0 -0
  248. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/013-flow-ledger-canonical-source-of-truth.md +0 -0
  249. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/014-cwe-mapping-security-findings.md +0 -0
  250. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/015-narrow-product-flow-scope.md +0 -0
  251. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/016-single-source-prompt-templates.md +0 -0
  252. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/017-optional-push-as-lock.md +0 -0
  253. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/017-two-counter-tdd-retry.md +0 -0
  254. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/018-one-behavior-rgr-granularity.md +0 -0
  255. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/019-remote-aware-ordinal-allocation.md +0 -0
  256. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/020-judge-compliance-pass-evidence.md +0 -0
  257. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/021-no-failing-test-escalate-invokes-green.md +0 -0
  258. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/022-already-satisfied-red-requires-tests.md +0 -0
  259. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/023-pinned-micro-run-issue-scoped.md +0 -0
  260. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/024-worktree-session-stale-issue-id.md +0 -0
  261. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/025-green-stderr-noise-stall-detector.md +0 -0
  262. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/026-pi-spawn-lean-tool-schema.md +0 -0
  263. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/027-red-hang-timeout-rollback.md +0 -0
  264. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc/issues/028-task-scoped-judge-review-coverage.md +0 -0
  265. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/adhoc.jsonl +0 -0
  266. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/constitution.md +0 -0
  267. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/explore/ast-tree-sitter.md +0 -0
  268. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/explore/flow-ledger.md +0 -0
  269. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/explore/graphite-cli.md +0 -0
  270. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/explore/pi-agent-backend.md +0 -0
  271. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/explore/product-layer.md +0 -0
  272. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/explore/rpc-streaming-tui.md +0 -0
  273. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/explore/rpc-streaming.md +0 -0
  274. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/explore/security-hardening-cwe.md +0 -0
  275. {deviatdd-2.22.1 → deviatdd-2.23.1}/specs/implementation-gap.md +0 -0
  276. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/__init__.py +0 -0
  277. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/_common.py +0 -0
  278. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/_html.py +0 -0
  279. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/_safe_commands.py +0 -0
  280. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/adhoc.py +0 -0
  281. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/constitution.py +0 -0
  282. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/feature.py +0 -0
  283. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/flow_commands.py +0 -0
  284. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/init.py +0 -0
  285. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/inspect.py +0 -0
  286. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/macro.py +0 -0
  287. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/review.py +0 -0
  288. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/cli/walkthrough.py +0 -0
  289. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/__init__.py +0 -0
  290. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/_shared.py +0 -0
  291. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/cache_discipline.py +0 -0
  292. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/commit.py +0 -0
  293. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/complexity.py +0 -0
  294. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/constitution.py +0 -0
  295. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/contract.py +0 -0
  296. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/convention.py +0 -0
  297. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/epic.py +0 -0
  298. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/judge_evidence.py +0 -0
  299. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/prd.py +0 -0
  300. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/profile.py +0 -0
  301. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/repo.py +0 -0
  302. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/review_coverage.py +0 -0
  303. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/run_logger.py +0 -0
  304. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/tasks_ledger.py +0 -0
  305. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/core/validation.py +0 -0
  306. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/html_templates/__init__.py +0 -0
  307. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/html_templates/architecture.html.tmpl +0 -0
  308. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/html_templates/domain-model.html.tmpl +0 -0
  309. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/html_templates/flows.html.tmpl +0 -0
  310. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/html_templates/plan.html.tmpl +0 -0
  311. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/html_templates/prd.html.tmpl +0 -0
  312. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/main.py +0 -0
  313. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/__init__.py +0 -0
  314. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/assembly.py +0 -0
  315. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/__init__.py +0 -0
  316. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/execute.md +0 -0
  317. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/explore.md +0 -0
  318. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/green.md +0 -0
  319. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/plan.md +0 -0
  320. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/prd.md +0 -0
  321. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/red.md +0 -0
  322. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/refactor.md +0 -0
  323. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/research.md +0 -0
  324. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/shard.md +0 -0
  325. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/specify.md +0 -0
  326. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/auto/tasks.md +0 -0
  327. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-adhoc.md +0 -0
  328. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-architecture.md +0 -0
  329. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-constitution.md +0 -0
  330. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-e2e.md +0 -0
  331. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-execute.md +0 -0
  332. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-explore.md +0 -0
  333. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-flows.md +0 -0
  334. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-green.md +0 -0
  335. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-hotfix.md +0 -0
  336. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-html.md +0 -0
  337. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-init.md +0 -0
  338. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-judge.md +0 -0
  339. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-merge.md +0 -0
  340. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-plan.md +0 -0
  341. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-pr.md +0 -0
  342. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-prd.md +0 -0
  343. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-prune.md +0 -0
  344. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-red.md +0 -0
  345. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-refactor.md +0 -0
  346. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-release.md +0 -0
  347. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-research.md +0 -0
  348. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-review.md +0 -0
  349. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-shard.md +0 -0
  350. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-tasks.md +0 -0
  351. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-triage.md +0 -0
  352. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/commands/deviate-walkthrough.md +0 -0
  353. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/constitution_seed.md +0 -0
  354. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/core/core.md +0 -0
  355. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/core/lifecycle-auto.md +0 -0
  356. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/core/lifecycle-manual.md +0 -0
  357. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/core/macro-shared.md +0 -0
  358. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/core/meso-shared.md +0 -0
  359. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/core/micro-shared.md +0 -0
  360. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/core/product-shared.md +0 -0
  361. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/core/style-ste.md +0 -0
  362. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/governance/__init__.py +0 -0
  363. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/governance/agents_seed.md +0 -0
  364. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/governance/claudemd_seed.md +0 -0
  365. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/prompts/governance/libref_seed.md +0 -0
  366. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/state/__init__.py +0 -0
  367. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/ui/__init__.py +0 -0
  368. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/ui/monitor.py +0 -0
  369. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/ui/pipeline.py +0 -0
  370. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/ui/render.py +0 -0
  371. {deviatdd-2.22.1 → deviatdd-2.23.1}/src/deviate/visual/__init__.py +0 -0
  372. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/__init__.py +0 -0
  373. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/core/__init__.py +0 -0
  374. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/core/test_agent.py +0 -0
  375. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/core/test_smart_stall.py +0 -0
  376. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/e2e/test_derived_command_install.bats +0 -0
  377. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/e2e/test_green_stderr_stall.bats +0 -0
  378. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/e2e/test_macro_workflow.bats +0 -0
  379. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/e2e/test_optional_push_as_lock.bats +0 -0
  380. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/e2e/test_pi_spawn_lean_tool_schema.bats +0 -0
  381. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/e2e/test_red_hang_timeout_rollback.bats +0 -0
  382. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/e2e/test_review_plan_ac_coverage.bats +0 -0
  383. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/e2e/test_worktree_session_stale_issue.bats +0 -0
  384. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/__init__.py +0 -0
  385. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_adhoc.py +0 -0
  386. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_common.py +0 -0
  387. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_constitution.py +0 -0
  388. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_feature.py +0 -0
  389. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_flows_sync.py +0 -0
  390. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_help.py +0 -0
  391. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_html.py +0 -0
  392. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_inspect.py +0 -0
  393. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_macro_contracts.py +0 -0
  394. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_main_entrypoint.py +0 -0
  395. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_merge.py +0 -0
  396. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_meso_contracts.py +0 -0
  397. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_real_descendant_kill.py +0 -0
  398. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_review.py +0 -0
  399. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_safe_commands.py +0 -0
  400. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_test_command_resolution.py +0 -0
  401. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_timeout_safe_command.py +0 -0
  402. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_cli/test_top_level_run.py +0 -0
  403. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_cache_discipline.py +0 -0
  404. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_commands.py +0 -0
  405. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_commit.py +0 -0
  406. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_complexity.py +0 -0
  407. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_constitution.py +0 -0
  408. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_contract.py +0 -0
  409. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_convention.py +0 -0
  410. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_epic.py +0 -0
  411. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_flow_confirmation.py +0 -0
  412. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_judge_evidence.py +0 -0
  413. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_ledger.py +0 -0
  414. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_prd.py +0 -0
  415. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_profile.py +0 -0
  416. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_repo.py +0 -0
  417. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_run_logger.py +0 -0
  418. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_tasks_ledger.py +0 -0
  419. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_core/test_validation.py +0 -0
  420. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_init.py +0 -0
  421. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/__init__.py +0 -0
  422. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/conftest.py +0 -0
  423. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_command_installation.py +0 -0
  424. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_init_export_cycle.py +0 -0
  425. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_macro_full_cycle.py +0 -0
  426. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_macro_layer.py +0 -0
  427. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_macro_orchestration.py +0 -0
  428. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_meso_layer.py +0 -0
  429. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_meso_orchestration.py +0 -0
  430. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_meso_task_ledger.py +0 -0
  431. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_parity.py +0 -0
  432. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_integration/test_skill_installation.py +0 -0
  433. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_macro/__init__.py +0 -0
  434. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_macro/test_explore.py +0 -0
  435. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_macro/test_macro_model_routing.py +0 -0
  436. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_macro/test_macro_orchestration.py +0 -0
  437. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_macro/test_prd.py +0 -0
  438. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_macro/test_research.py +0 -0
  439. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_macro/test_shard.py +0 -0
  440. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/__init__.py +0 -0
  441. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_auto_prompt_templates.py +0 -0
  442. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_meso_model_routing.py +0 -0
  443. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_meso_resume.py +0 -0
  444. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_plan_structure_injection.py +0 -0
  445. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_pr_platform.py +0 -0
  446. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_prompt_assembly.py +0 -0
  447. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_specify.py +0 -0
  448. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_meso/test_tasks.py +0 -0
  449. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/__init__.py +0 -0
  450. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/conftest.py +0 -0
  451. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_commit_failure.py +0 -0
  452. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_completed_evidence.py +0 -0
  453. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_e2e.py +0 -0
  454. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_execute.py +0 -0
  455. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_green.py +0 -0
  456. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_hotfix.py +0 -0
  457. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_orchestration.py +0 -0
  458. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_output_filter.py +0 -0
  459. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_red.py +0 -0
  460. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_refactor.py +0 -0
  461. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_review_pause.py +0 -0
  462. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_rollback_safety.py +0 -0
  463. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_run.py +0 -0
  464. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_task_label.py +0 -0
  465. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_micro/test_two_counter_retry.py +0 -0
  466. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_release/test_next_version.py +0 -0
  467. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_state/__init__.py +0 -0
  468. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_state/test_config.py +0 -0
  469. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_state/test_security_profile.py +0 -0
  470. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_state/test_session.py +0 -0
  471. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_ui/__init__.py +0 -0
  472. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_ui/test_monitor.py +0 -0
  473. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_ui/test_pipeline.py +0 -0
  474. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_ui/test_render.py +0 -0
  475. {deviatdd-2.22.1 → deviatdd-2.23.1}/tests/test_visual_demo/test_tsk_001_01.py +0 -0
@@ -0,0 +1,20 @@
1
+ # Preset config group: "default", "full", "fast", or "secure"
2
+ profile = "default"
3
+ # CLI inactivity timeout in seconds (must be > 0)
4
+ timeout_seconds = 1800
5
+ # Agent export mode: "local" (project) or "global" (~/.claude/)
6
+ agent_export_mode = "local"
7
+ # Enable the libref CLI for offline documentation lookups
8
+ use_libref = true
9
+ # Trunk branch for worktrees, PR base, and review diffs
10
+ base_branch = "main"
11
+ # Push the claim branch as a distributed lock (default true)
12
+ claim_remote = true
13
+
14
+ # Agent backend configuration
15
+
16
+ [agent]
17
+ backend = "pi"
18
+ timeout = 600
19
+ pi_rpc = false
20
+ transport = "rpc"
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  ## [Unreleased]
9
9
 
10
10
  ### Added
11
+ - **ChatGPT Codex is a first-class setup + meso/micro backend.** `--agent codex` (and the interactive prompt) is a valid install target. Setup writes packaged skills to `.agents/skills/deviatdd/SKILL.md` plus one `.agents/skills/<command>/SKILL.md` per slash command (Codex CLI 0.117+ dropped `.codex/prompts`). `[agent].backend = "codex"` is persisted. Dispatch uses `codex exec --sandbox workspace-write --ask-for-approval never` with the existing stdin prompt path and `--model` injection. Transport stays `cli`. Pinned by `tests/test_cli/test_setup.py::TestSetupCodex` and `tests/test_core/test_agent.py::TestCodexBackendRegistration`.
11
12
  - **On-demand GitHub Actions Release workflow (`workflow_dispatch`).** A maintainer runs Actions → Release → Run workflow. The job computes the next SemVer from conventional commits since the current `pyproject.toml` version (`feat` → minor, `fix` → patch, `BREAKING CHANGE` / `feat!` / `fix!` → major; chore/docs/test/ci/style/refactor still bump patch), writes `pyproject.toml` + the `deviatdd` version in `uv.lock`, commits `chore(release): version X.Y.Z` on the default branch, tags `vX.Y.Z`, and publishes with `uv build` / `uv publish --trusted-publishing always` (PyPI trusted publishing via GitHub OIDC; `contents: write` + `id-token: write`; no `PYPI_API_TOKEN` and no GitHub secret). Optional inputs: `bump` (`auto` / `patch` / `minor` / `major`) and `dry_run` (print the version; skip commit/tag/publish). Refuses a non-default branch unless `dry_run` is true. Does not rewrite `CHANGELOG.md` (stays `[Unreleased]`). Operator adds a pending PyPI trusted publisher for `wernerbisschoff/deviatdd` workflow `release.yml` (no environment). Local fallback remains `mise run publish`. Pinned by `tests/test_release/test_next_version.py`.
12
13
  - **COMPLETED `tasks.jsonl` rows now persist runner-validated JUDGE evidence (GH-84).** After the #65 mechanical gate accepts a TDD completion path (`skip_refactor` / bare `COMPLIANCE_PASS` / post-REFACTOR complete / adjudicated already-exists), `_append_status_transition(..., "COMPLETED")` copies `HandoverManifest.evidence` (`ac`, `test_path`, `test_quote`, `impl_path`, `impl_quote`) onto an optional `TaskRecord.evidence` bundle and stamps `red` (`session.red_commit_sha`) plus `green`/`head` (`HEAD` at the write). TDD complete fail-closes when the plan contract has `AC-PLAN-NNN` tokens and the bundle is missing or does not cover them (`evaluate_judge_evidence`, no new matcher). EXECUTE / IMMEDIATE / DIRECT stay ungated; enabling/infra plans with no AC tokens may complete with empty evidence. `deviate inspect tasks show` prints the field when present. Session files are not the proof store. Pinned by `tests/test_micro/test_completed_evidence.py`, `tests/test_state/test_ledger.py`, and `tests/test_cli/test_inspect.py`.
13
14
  - **`deviate micro run --review` pauses before each phase commit (GH-101).** After the agent finishes a phase and tests/lint have run, `--review` (and `--all --review`) halt before `_commit_phase` / `_commit_phase_with_recovery` (`git add -A`), print `REVIEW_PAUSE <phase> <task_id>`, leave the worktree dirty for herdr/hunk, and wait for TTY confirmation (`Enter` / yes). Then the runner commits as today and continues. Pause applies to RED, GREEN, REFACTOR, and EXECUTE — not JUDGE feedback commits. RED is still committed before GREEN so `session.red_commit_sha` remains available for JUDGE `revert_to_red`. Non-TTY / `--json` / missing stdin fail closed with `REVIEW_REQUIRES_TTY` and never auto-commit past the flag. Off by default; no config key. The pause is one helper (`_maybe_review_pause`) in front of `_commit_phase`, not a copy in each phase. Pinned by `tests/test_micro/test_review_pause.py`.
@@ -31,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
31
32
  - **`deviate html prd --bucket <slug>` targets a specific epic when more than one owns a `prd.md`.** Previously the command hard-failed with `HTML_AMBIGUOUS_PRD` whenever multiple numbered epics had a `prd.md` and offered no flag to disambiguate — the agent was told to "run from within the epic's worktree", which silently yielded `HTML_NO_PRD` because the resolver reads `specs/` from the repo root. The new option resolves `specs/<bucket>/prd.md` directly and bypasses ambiguity detection; the plain form keeps its existing behavior but its ambiguity banner now points at the flag. An unknown/absent bucket exits `PRD_NOT_FOUND`. The `/deviate-html` prompt (`src/deviate/prompts/commands/deviate-html.md`) and spec docs now reference `--bucket` instead of the broken cwd fallback. Pinned by `tests/test_cli/test_html.py::test_html_prd_bucket_targets_specific_epic`, `::test_html_prd_bucket_targets_unnumbered_dir`, and `::test_html_prd_bucket_missing_file_exits_cleanly`.
32
33
  - **Optional push-as-lock: `claim_remote` config plus `--local` on `meso run` and `run`.** Standing `.deviate/config.toml` key `claim_remote` defaults to `true` (absent file or absent key still push). `deviate setup --no-claim-remote` writes `claim_remote = false` without dropping `[models]`, `timeout_seconds`, or `[agent]`. Fresh setup without the flag writes `true`. Effective local mode is `--local` OR `claim_remote = false`; explicit `--local` always wins. Local mode still creates `.worktrees/feat/{epic}/{issue}/`, writes SPECIFIED, and commits the claim, and skips `branch_exists_on_remote` plus `git push`. `deviate specify --local` stays; omitted `--local` now honors config. `deviate meso run --local` and `deviate run --local` share that meaning. `--no-setup` remains a distinct skip of worktree plus claim. Local discovery does not treat an origin branch as claimed-elsewhere. Specs: `specs/DeviaTDD-api.md`, `specs/DeviaTDD-architecture.md` (Atomic Concurrency Protocol: push-as-lock is the default, not mandatory). Pinned by `tests/test_state/test_config.py`, `tests/test_cli/test_meso.py`, `tests/test_meso/test_specify.py`, `tests/test_meso/test_meso_orchestration.py`, `tests/test_cli/test_init.py`, and `tests/test_cli/test_top_level_run.py`.
33
34
  ### Changed
35
+ - **The `deviatdd` skill checks for an existing OPEN GitHub issue before filing a harness-bug issue.** The "Filing deviatdd issues" section now runs `gh issue list --repo wernerbisschoff/deviatdd --state open --search` first; when an open issue already matches the same harness failure, it directs commenting the new evidence/task context onto that issue (`gh issue comment`) instead of `gh issue create`, and only creates a new issue when no match exists. Prompt-only change to the packaged skill (`src/deviate/prompts/skills/deviatdd/SKILL.md`), re-installed to all agent skill dirs.
34
36
  - **`deviate refactor pre` now scopes `files_to_refactor` to the RED+GREEN production set (GH-98).** The command no longer glob()s every `src/**/*.py` or discards `_resolve_task_context`. It lists production files from `HEAD~2..HEAD`, falling back to the task `Files:` list minus tests when that git range is empty or unavailable. Test files are never included. The JSON contract now emits the documented handover fields (`status`, `task_id`, `task_title`, `task_type`, `test_command`, `lint_command`, `spec_dir`, `verification`, `repo_root`, `git_branch`, `timestamp`) alongside `files_to_refactor`. Auto `_build_auto_prompt("refactor")` injects the same scoped list and keeps the `git log -2` / `git diff HEAD~2..HEAD` inspect step. Pinned by `tests/test_micro/test_refactor.py`.
35
37
  - **GREEN / REFACTOR / review prompts fold smallest-change into existing lines** (reuse stdlib or an already-installed dep; in-place refactor; Opportunities do not extract helpers). Prompt-only. Pinned by `tests/test_meso/test_auto_prompt_templates.py::TestSmallestChangeFoldedIntoExistingPrompts`.
36
38
  - **JUDGE evidence is task-scoped; `deviate review` fail-closes on an unclaimed plan AC.** TDD `_run_judge_phase` resolves required `AC-PLAN-NNN` tokens via `resolve_task_ac_tokens` (non-empty `acceptance_criteria` `criterion_id`s, else this task's `tasks.md` card, else none) and does not fall back to every token in `plan.md`. ISS-ADH-020 exact-substring, path-in-diff, and uniqueness-floor checks still apply to that set. EXECUTE, IMMEDIATE, and DIRECT stay ungated. `deviate review pre` / `post` run a runner-owned Gate 3 scan (`evaluate_review_coverage`) and exit non-zero with `COVERAGE_INCOMPLETE` when any this-issue plan token has no COMPLETED claim. Missing `plan.md` or missing plan tokens stay vacuously READY. PENDING, FAILED, and sibling-issue rows do not claim. Pinned by `tests/test_core/test_judge_evidence.py`, `tests/test_micro/test_judge.py`, and `tests/test_cli/test_review.py`.
@@ -54,6 +56,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
54
56
  - **`/deviate-merge` no longer auto-pushes after the squash-merge commit; the push gate runs inline and the network push is opt-in.** The slash command previously ran `git push` as its final step. As of v2.4.0 the squash-merge commit lands on `main`, then a new `push_gate` step inlines the body of `.githooks/pre-push` (lint + format-check + testmon-driven affected tests with the warm-cache / full-suite fallback — bash 3.2 portable, `GIT_DIR` reset + trap preserved) so the safety net fires even though no `git push` happens yet. After the gate passes the skill asks the operator whether to `git push` (which fires the real `pre-push` hook and re-runs the same gate) or stop and push manually. The squash-merge commit and the ledger transition inside it are durable on `main` regardless of the push outcome — only the network push is deferred. New failure states: `Push_Gate_Failed` (inline gate non-zero), `Push_Failed` (`git push` non-zero, raw stderr surfaced), `Push_Deferred` (user chose "Stop — I'll push manually"). Inline gate body and `.githooks/pre-push` body must stay byte-equivalent; divergence is pinned by `tests/test_meso/test_auto_prompt_templates.py::TestMergePromptPushGate::test_hook_and_prompt_agree_on_gate_body` (which compares non-blank non-comment lines in both bodies and fails on drift in either direction) plus 3 supporting assertions on the upstream-first logic, the testmon fallback, and the prompt structure. Prompt: `src/deviate/prompts/commands/deviate-merge.md` (v2.3.0 → v2.4.0). Spec mirrors updated: `specs/DeviaTDD-architecture.md` (Merge bullet, new `**Push gate + opt-in push (v2.4.0)**` sub-bullet) and `specs/DeviaTDD-api.md` (new `**/deviate-merge push behavior (v2.4.0)**` entry under the `deviate merge` reference).
55
57
 
56
58
  ### Fixed
59
+ - **`deviate setup --agent X` now installs slash commands and the packaged `deviatdd` skill only for X.** Previously setup wrote into all five of `.claude/`, `.opencode/`, `.factory/`, `.pi/`, and `.omp/` regardless of `--agent`; the flag only persisted `[agent].backend`. `droid` still writes `.factory/` only. Unknown `--agent` values stay fail-closed. Pinned by `tests/test_cli/test_setup.py::TestSetupSelectedAgentIsolation`.
60
+ - **JUDGE prompt injection now uses the Judge-Feedback-stripped task card (GH-118).** `_build_auto_prompt("judge")` still reads the raw card via `_task_card_text`, then applies the same `_strip_judge_feedback` pass that `resolve_task_ac_tokens` already used for token resolution (#89). Prior-round `**Judge Feedback**` bullets and their continuation lines (including false ownership claims such as "AC-PLAN-003 belongs to a later task") no longer appear in `<task_card>`. Token resolution, `_append_judge_feedback`, and the COMPLETED evidence gate are unchanged. Specs: `specs/DeviaTDD-api.md`, `specs/DeviaTDD-architecture.md`. Pinned by `tests/test_micro/test_judge.py::TestJudgePromptStripsJudgeFeedback`.
61
+ - **Ledger appenders no longer concatenate a new JSONL record onto a last line that lacks a trailing newline (GH-117).** `_append_record` and `_append_with_compound_key` insert a leading `\n` when the file is non-empty and does not already end in a newline, so `_read_ledger` cannot skip a fused BACKLOG+SPECIFIED line. `claim_issue` now writes through `append_issue_transition` instead of a raw `"a"` append. Pinned by `tests/test_state/test_ledger.py` and `tests/test_core/test_issues.py`.
62
+ - **JUDGE handover parse now recovers unescaped `"` inside evidence quote fields (GH-116).** `AgentBackend.parse_output` retries `yaml.safe_load` after rewriting broken `quote` / `test_quote` / `impl_quote` double-quoted scalars as `|` block scalars, so citations such as `assert "YAGNI" in text` and `== ["AC-PLAN-002"]` no longer raise `MalformedHandoverManifestError`. Well-formed YAML is unchanged. The auto judge prompt also prefers `|` block scalars when a quote contains `"`. Pinned by `tests/test_core/test_agent.py`.
63
+ - **A `no_failing_test` already-exists JUDGE `COMPLIANCE_PASS` now completes via `skip_refactor` instead of hard-crashing with `ROLLBACK_BOUNDARY_MISSING`.** On the RED `no_failing_test` adjudication route (`session.failure_kind == "no_failing_test"`, `session.red_commit_sha == ""`), `_apply_judge_verdict` coerces any PASS `next_action` to `skip_refactor` through `_NO_FAILING_TEST_FORWARD_ROUTES`, skips the unmatched-PASS AC-token citation rewrite, and relaxes only the `COMPLETED_EVIDENCE_MISSING` token check for that route — the declared-regression-files gate (`_require_tdd_declared_regression_files`) stays fail-closed, a wrong test still routes to `revert_before` for RED re-author, and a genuine test-bearing RED with a real RED commit still rolls back via `revert_to_red`. Previously every retry crashed because the mechanical gate rewrote the pass to `revert_to_red` with no RED commit to roll back to. Specs updated: `specs/DeviaTDD-api.md`, `specs/DeviaTDD-architecture.md`. Pinned by `tests/test_micro/test_judge.py` and `tests/test_cli/test_micro.py`.
64
+ - **Feature worktrees now base on the local trunk, so locally-authored (unpushed) issues plan without failing.** `resolve_start_point` (`src/deviate/core/worktree.py`) previously preferred `origin/<base>` over local `<base>`, so a `deviate meso run` that discovered an issue committed only to local `main` created its worktree from a stale `origin/main` that lacked the issue's `specs/issues.jsonl` row and source file — the plan agent wrote `plan.md`, then `deviate plan post` failed with `ISSUE_NOT_FOUND <IDS>` and exited 1. Meso reads the issue ledger from the local trunk, so the worktree base now comes from local `<base>` first (falling back to `origin/<base>`, then `HEAD`). Pinned by `tests/test_core/test_worktree.py::TestCreateWorktree::test_resolve_start_point_prefers_local_base_over_stale_origin`.
65
+ - **`deviate meso run` / `deviate specify` auto-discovery now skips issues already claimed locally.** A claim writes the issue's `BACKLOG → SPECIFIED` ledger row in the new worktree and commits it on the `feat/{epic}/{issue}` feature branch, so the main checkout's `specs/issues.jsonl` still shows the issue as `BACKLOG`. `_discover_claimable_issue` therefore re-returned the same first issue to a second terminal on the same checkout (parallel run) instead of claiming a different one; the origin-branch lock only caught issues whose claim branch had been `git push`-ed. Discovery now also skips a candidate whose `feat/{epic}/{issue}` branch already has a local worktree (treated as claimed here), in both local and default mode, mirroring the signal `_try_claim_issue` already uses for `ALREADY_CLAIMED_LOCAL`. Two terminals on one checkout can now claim two different BACKLOG issues in parallel. Pinned by `tests/test_meso/test_meso_orchestration.py::TestDiscoverClaimableIssue::test_skips_issues_with_local_worktree`.
57
66
  - **`_append_judge_feedback` writes under the rejected task card, and the evidence gate keeps judge `train_feedback` / `violations` (GH-102).** The appender locates the card with `_TASK_BULLET_HEAD_RE` exact-id match (same regex as `_read_judge_feedback_from_tasks_md`) and stops at the next task or a `##` / `###` phase heading, so a Phase 1 `TSK-004-01` rejection no longer drops `**Judge Feedback**` under the next phase `### Tasks` / `TSK-004-02`. When the evidence gate rewrites unmatched PASS, persist the judge's own `train_feedback` / `violations` (after the GH-103 citation strip) instead of replacing them with the generic `JUDGE evidence is missing...` string. Pinned by `tests/test_micro/test_judge.py::TestJudgeFeedbackLogging::test_append_judge_feedback_stays_under_rejected_card_across_phase_header` and `TestTddJudgeEvidenceGate::test_rewritten_pass_keeps_judge_train_feedback` / `::test_rewritten_pass_keeps_judge_violations`.
58
67
  - **JUDGE injected diff walks past docs-feedback `red_commit_sha` to the real RED commit (GH-88, GH-90).** `_maybe_advance_red_sha_past_feedback` still advances the session SHA onto `docs(...): add judge feedback for retry` so GREEN entry and `revert_to_red` keep a valid TRAIN boundary. `_assemble_judge_injected_diff` now resolves the diff base via `_resolve_judge_diff_base`, walking back through those feedback subjects to the RED-phase failing-test commit and running `git diff {red_sha}^..HEAD`. The evidence gate no longer false-rejects with `test_path is not in the injected diff` or missing AC tokens solely because the RED test dropped out of a docs-only range. Pinned by `tests/test_micro/test_judge.py::TestJudgeDiffBaseWalksPastFeedback`.
59
68
  - **`resolve_task_ac_tokens` no longer treats runner-appended `**Judge Feedback**` as required AC tokens (GH-89).** Card-text fallback still follows first-hit order (`acceptance_criteria` `criterion_id`s, else the task card, else none) but now drops `**Judge Feedback**` bullets and their continuation lines before scanning for `AC-PLAN-NNN`. A feedback line quoting `AC-PLAN-001` does not add that token when the card body does not name it. `_task_card_text` still returns the full card. Pinned by `tests/test_core/test_judge_evidence.py::TestResolveTaskAcTokens::test_judge_feedback_quote_does_not_add_token`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: deviatdd
3
- Version: 2.22.1
3
+ Version: 2.23.1
4
4
  Summary: DeviaTDD CLI — agent orchestration framework
5
5
  Project-URL: Homepage, https://github.com/wernerbisschoff/deviatdd
6
6
  Project-URL: Repository, https://github.com/wernerbisschoff/deviatdd
@@ -74,11 +74,11 @@ deviate --version # confirm install
74
74
 
75
75
  # Bootstrap a new project + install slash commands into your agent of
76
76
  # choice. Does it all in one shot: scaffolds .deviate/, specs/constitution.md,
77
- # governance blocks, and installs /deviate-* slash commands for every
78
- # supported agent. The --agent flag picks the default backend persisted
79
- # to .deviate/config.toml (slash commands themselves are installed to all
80
- # supported agent directories regardless).
81
- deviate setup --agent claude # or: opencode | pi | droid | factory | omp
77
+ # governance blocks, and installs /deviate-* slash commands for the
78
+ # selected agent only. The --agent flag picks the backend persisted to
79
+ # .deviate/config.toml and is the only install target (`droid` writes
80
+ # `.factory/`; `codex` writes `.agents/skills/`).
81
+ deviate setup --agent claude # or: opencode | pi | droid | factory | omp | codex
82
82
  ```
83
83
 
84
84
  Once setup is done, drive the entire lifecycle from inside your agent. Each phase emits a single artifact, commits it, and (at the two gates) pauses for human review.
@@ -41,11 +41,11 @@ deviate --version # confirm install
41
41
 
42
42
  # Bootstrap a new project + install slash commands into your agent of
43
43
  # choice. Does it all in one shot: scaffolds .deviate/, specs/constitution.md,
44
- # governance blocks, and installs /deviate-* slash commands for every
45
- # supported agent. The --agent flag picks the default backend persisted
46
- # to .deviate/config.toml (slash commands themselves are installed to all
47
- # supported agent directories regardless).
48
- deviate setup --agent claude # or: opencode | pi | droid | factory | omp
44
+ # governance blocks, and installs /deviate-* slash commands for the
45
+ # selected agent only. The --agent flag picks the backend persisted to
46
+ # .deviate/config.toml and is the only install target (`droid` writes
47
+ # `.factory/`; `codex` writes `.agents/skills/`).
48
+ deviate setup --agent claude # or: opencode | pi | droid | factory | omp | codex
49
49
  ```
50
50
 
51
51
  Once setup is done, drive the entire lifecycle from inside your agent. Each phase emits a single artifact, commits it, and (at the two gates) pauses for human review.
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "deviatdd"
3
- version = "2.22.1"
3
+ version = "2.23.1"
4
4
  description = "DeviaTDD CLI — agent orchestration framework"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -31,14 +31,15 @@ scripts. All commands are registered in `src/deviate/cli/__init__.py` using Type
31
31
  constitution. `deviate init pre` continues to scaffold the constitution independently.
32
32
  slash commands + 1 standalone `tools-mcp-servers` command (for Factory Droid)
33
33
  — 25 flat `.md` files total in the Factory install; 24 in every other agent
34
- `.{agent}/prompts/` for Pi) during `deviate setup`. Commands land in all agent
35
- directories — `.claude/commands/`, `.opencode/commands/`,
36
- `.factory/commands/`, `.pi/prompts/`, `.omp/prompts/` — in a single invocation, regardless of which agent was passed
37
- via `--agent`. Each command is a flat `<name>.md` file with a minimal YAML
38
- frontmatter (`name:` + `description:`). The agent backend selected via `--agent`
39
- (`opencode`, `claude`, `droid`, `factory`, `pi`, `omp`) is persisted to `[agent].backend` in
40
- `config.toml` for use by the meso/micro layers; it does **not** gate which agent
41
- directories receive commands.
34
+ `.{agent}/prompts/` for Pi) during `deviate setup`. Commands land only in the
35
+ selected agent's directory — `.claude/commands/`, `.opencode/commands/`,
36
+ `.factory/commands/` (`--agent factory` and `--agent droid`), `.pi/prompts/`,
37
+ `.omp/prompts/`, or Codex skills under `.agents/skills/<name>/SKILL.md`.
38
+ Each command is a flat `<name>.md` file (or a Codex `SKILL.md`) with a
39
+ minimal YAML frontmatter (`name:` + `description:`). The agent selected via
40
+ `--agent` (`opencode`, `claude`, `droid`, `factory`, `pi`, `omp`, `codex`)
41
+ is persisted to `[agent].backend` in `config.toml` and is the only install
42
+ target.
42
43
 
43
44
  **Single-source prompt derivation:** for each of the 11 overlapping phases
44
45
  (`explore`, `research`, `prd`, `shard`, `plan`, `tasks`, `red`, `green`,
@@ -84,8 +85,8 @@ scripts. All commands are registered in `src/deviate/cli/__init__.py` using Type
84
85
  duplicates rules), preserves user-authored `.gitattributes` content,
85
86
  and stages the file via `deviate init post` alongside the other
86
87
  scaffolded artifacts.
87
- * **Agent Selection:** Accepts `--agent [claude|opencode|droid|factory|pi]` to override
88
- auto-detect. If omitted, the persisted value is reused; if no persisted value exists and
88
+ * **Agent Selection:** Accepts `--agent [claude|opencode|droid|factory|pi|omp|codex]` to override
89
+ the persisted backend. If omitted, the persisted value is reused; if no persisted value exists and
89
90
  the session is interactive, a Rich `Prompt.ask` menu is shown. In non-interactive mode
90
91
  the command halts with `NO_AGENT_SELECTED` and a directive to re-run with `--agent`.
91
92
  * **Execution Modes:**
@@ -106,7 +107,7 @@ scripts. All commands are registered in `src/deviate/cli/__init__.py` using Type
106
107
  `${VARIABLE}` resolver described in earlier revisions of this spec has been removed.
107
108
  * **Input Parameters:**
108
109
  * `--agent-export-mode [local|global]` (Defaults to `local`)
109
- * `--agent [claude|opencode|droid|factory|pi]` (Override auto-detect)
110
+ * `--agent [claude|opencode|droid|factory|pi|omp|codex]` (Override persisted backend)
110
111
  * `--no-claim-remote` (Disable push-as-lock; merges `claim_remote = false` into
111
112
  * `--libref` (Force-enable `libref` CLI integration; merges `use_libref = true` into
112
113
  `config.toml`)
@@ -134,9 +135,10 @@ scripts. All commands are registered in `src/deviate/cli/__init__.py` using Type
134
135
  * `specs/constitution.md` — Resolved boilerplate constitution
135
136
  * `AGENTS.md` — Symlink to `CLAUDE.md` (or vice-versa if only `AGENTS.md`
136
137
  existed pre-setup). Created by `_linkify_governance_files`; idempotent.
137
- * `.claude/commands/`, `.opencode/commands/`, `.factory/commands/`,
138
- supported agent (24 `deviate-*` + 1 standalone `tools-mcp-servers`
139
- for Factory = 25 flat `.md` files total in that one directory)
138
+ * Selected-agent command install only: `.claude/commands/`,
139
+ `.opencode/commands/`, `.factory/commands/`, `.pi/prompts/`,
140
+ `.omp/prompts/`, or `.agents/skills/<name>/SKILL.md` for Codex.
141
+ Factory also receives the standalone `tools-mcp-servers` command.
140
142
 
141
143
  #### `deviatdd` Skill (Project-Local Single Skill)
142
144
 
@@ -147,21 +149,19 @@ scripts. All commands are registered in `src/deviate/cli/__init__.py` using Type
147
149
  `src/deviate/cli/__init__.py`, called from `setup()` after
148
150
  `_install_commands_to_agents(...)`. Idempotent (content-equality skip
149
151
  mirrors `install_command`'s contract).
150
- * **Install targets (all five `active_agents`):** the skill is written
151
- to `<workdir>/.<agent>/skills/deviatdd/SKILL.md` for every agent
152
- platform that `setup` provisions commands for, regardless of whether
153
- each platform documents a project-local skills convention. Mirrors
154
- `_install_commands_to_agents`'s write-everywhere policy — every
155
- operator using `--agent <platform>` gets the skill at the canonical
156
- skills directory for their platform, ready to be picked up if/when
157
- that platform ships a discovery convention.
152
+ * **Install target (selected agent only):** the skill is written to
153
+ `<workdir>/.<agent>/skills/deviatdd/SKILL.md` for the agent passed to
154
+ `--agent` (or the persisted backend / interactive prompt). `droid`
155
+ normalizes to `factory`. Codex writes
156
+ `<workdir>/.agents/skills/deviatdd/SKILL.md` and does **not** write
157
+ `.codex/prompts` or `.codex/commands`.
158
158
  * `claude` -> `<workdir>/.claude/skills/deviatdd/SKILL.md`
159
159
  (verified — same form as user-level `~/.claude/skills/<name>/SKILL.md`).
160
160
  * `opencode` -> `<workdir>/.opencode/skills/deviatdd/SKILL.md`
161
161
  (no documented project-local skills convention; file on disk for
162
162
  forward-compat).
163
163
  * `factory` -> `<workdir>/.factory/skills/deviatdd/SKILL.md`
164
- (same as opencode).
164
+ (same as opencode; `--agent droid` uses this path).
165
165
  * `pi` -> `<workdir>/.pi/skills/deviatdd/SKILL.md`
166
166
  (verified — `pi@latest` docs at
167
167
  `packages/coding-agent/docs/skills.md` list `.pi/skills/` as a
@@ -171,6 +171,9 @@ scripts. All commands are registered in `src/deviate/cli/__init__.py` using Type
171
171
  `~/.omp/agent/managed-skills/<name>/SKILL.md` and via a
172
172
  settings-driven `skills` array; operators can register the
173
173
  project-local file via OMP's settings).
174
+ * `codex` -> `<workdir>/.agents/skills/deviatdd/SKILL.md`
175
+ (Codex CLI 0.117+ official project-local discovery). Each packaged
176
+ slash command is also installed as `.agents/skills/<name>/SKILL.md`.
174
177
  * **Scope:** Unified Meso and Micro orchestration. The skill first runs
175
178
  `deviate meso run`. In an existing feature worktree, the runner validates
176
179
  `plan.md` and `tasks.md`, skips completed phases, and resumes at Tasks when
@@ -218,14 +221,17 @@ scripts. All commands are registered in `src/deviate/cli/__init__.py` using Type
218
221
  * **`.gitignore` exclusions:** `_ensure_root_gitignore` adds
219
222
  `*/skills/deviatdd/` to the entries tuple alongside
220
223
  `*/commands/deviate-*.md` and `*/prompts/deviate-*.md`. The
221
- single-level wildcard covers all five agent platforms
222
- (`.claude/`, `.opencode/`, `.factory/`, `.pi/`, `.omp/`) with one
223
- pattern. The single-level prefix (`*/`, not `**/`) is critical: it
224
+ single-level wildcard covers every selected-agent skill install
225
+ (`.claude/`, `.opencode/`, `.factory/`, `.pi/`, `.omp/`, `.agents/`)
226
+ with one pattern. `*/skills/deviate-*/` covers Codex per-command
227
+ skill dirs. The single-level prefix (`*/`, not `**/`) is critical: it
224
228
  scopes the pattern to the project root, never matching the
225
229
  source-of-truth at `src/deviate/prompts/skills/deviatdd/` (three
226
230
  directories deep).
227
- * **Tests:** `TestInstallDeviatddSkill` (8 tests) in
228
- `tests/test_cli/test_init.py` covers install-to-all-five-agents,
231
+ * **Tests:** `TestInstallDeviatddSkill` in
232
+ `tests/test_cli/test_init.py` and `TestSetupSelectedAgentIsolation` /
233
+ `TestSetupCodex` in `tests/test_cli/test_setup.py` cover
234
+ selected-agent-only install, Codex skills + `backend = "codex"`,
229
235
  idempotence, gitignore entry presence + idempotence, safety-gate
230
236
  fragments in the SKILL.md body, well-formed frontmatter, and the
231
237
  dispatch table's canonical slash-command references.
@@ -257,7 +263,7 @@ scripts. All commands are registered in `src/deviate/cli/__init__.py` using Type
257
263
 
258
264
  ### 1.5 Product Layer *(optional, sits above Macro)*
259
265
 
260
- The Product layer ships as **agent skills** (no dedicated CLI subcommands) — the prompts live at `src/deviate/prompts/commands/deviate-{flows,architecture,release}.md` and are installed to all four agent directories alongside the rest. They are **not** wired into the `deviate` CLI's `pre`/`post` subcommand pattern: the agent invokes them directly as `/deviate-flows`, `/deviate-architecture`, `/deviate-release`, and the conversation produces the artifact. The CLI's only involvement is installing the skill files during `deviate setup` and (via `deviate-shard` / `deviate-adhoc`) consuming the `flow_refs:` frontmatter those artifacts emit.
266
+ The Product layer ships as **agent skills** (no dedicated CLI subcommands) — the prompts live at `src/deviate/prompts/commands/deviate-{flows,architecture,release}.md` and are installed to the selected agent directory alongside the rest. They are **not** wired into the `deviate` CLI's `pre`/`post` subcommand pattern: the agent invokes them directly as `/deviate-flows`, `/deviate-architecture`, `/deviate-release`, and the conversation produces the artifact. The CLI's only involvement is installing the skill files during `deviate setup` and (via `deviate-shard` / `deviate-adhoc`) consuming the `flow_refs:` frontmatter those artifacts emit.
261
267
 
262
268
  | Command | Source skill | Artifact committed | Notes |
263
269
  |---------|--------------|--------------------|-------|
@@ -436,7 +442,10 @@ accepts `--json` (emit JSON contract to stdout) and `--quiet` (suppress output).
436
442
  claims that specific issue. With **no argument**, auto-discovers the next claimable
437
443
  BACKLOG issue via `_discover_claimable_issue()` (the same discovery `deviate meso run`
438
444
  uses) and claims it. Default discovery skips issues whose `feat/{epic}/{issue}` branch
439
- already exists on remote (treated as claimed elsewhere). Local mode does not skip those
445
+ already exists on remote (treated as claimed elsewhere). In any mode it also skips
446
+ issues whose `feat/{epic}/{issue}` branch already has a local worktree (treated as claimed
447
+ here) — that local-worktree guard is what lets two parallel terminals claim two different
448
+ BACKLOG issues without re-claiming the same one. Local mode does not skip those
440
449
  origin branches. Stops after the worktree is created and the claim is committed — does
441
450
  NOT advance session state and does NOT run plan or tasks. To continue, run
442
451
  ``deviate plan pre`` or invoke the ``/deviate-plan`` slash command inside the new
@@ -594,9 +603,16 @@ accepts `--json` and `--quiet`. `pre` emits a JSON contract describing the envir
594
603
  in the injected ``<diff>`` or HEAD (constitution §3 Testing Protocols; §5 Definition of Done).
595
604
  Empty ``files`` / ``test_file`` is a RED defect (``PhaseFailedError``); the ledger writes no
596
605
  COMPLETED row. JUDGE ``skip_refactor`` / bare ``COMPLIANCE_PASS`` keeps those declared tests
597
- on disk via ``_restore_worktree_to_baseline(..., keep_paths=declared)``. A declared path
598
- missing from the snapshot rewrites PASS to ``revert_before`` / ``revert_to_red``. JUDGE still
599
- rules a wrong test as ``revert_before`` so RED re-authors a genuinely failing test. EXECUTE,
606
+ on disk via ``_restore_worktree_to_baseline(..., keep_paths=declared)``. On the already-exists
607
+ route (``session.red_commit_sha == ''``), a ``no_failing_test`` ``COMPLIANCE_PASS`` with any
608
+ ``next_action`` completes via ``skip_refactor`` even when the evidence cites only part of the
609
+ task's ``AC-PLAN-NNN`` tokens: ``_apply_judge_verdict`` skips the unmatched-PASS rewrite for
610
+ this route, and ``_require_tdd_completed_evidence`` relaxes the AC-token citation check while
611
+ keeping the declared regression-path presence gate. ``ROLLBACK_BOUNDARY_MISSING`` applies only
612
+ to a genuine TDD ``revert_to_red`` with an empty ``red_commit_sha`` — never on the
613
+ already-exists pass path. A declared path missing from the snapshot rewrites PASS to
614
+ ``revert_before`` / ``revert_to_red``. JUDGE still rules a wrong test as ``revert_before`` so
615
+ RED re-authors a genuinely failing test. EXECUTE,
600
616
  IMMEDIATE, and DIRECT stay ungated by this files rule. After ``revert_before`` / cycle
601
617
  ``no_failing_test_adjudicated``, the next ``INVOKE_AGENT`` is RED, or the loop raises
602
618
  ``TRAIN_EXHAUSTED`` / ``PhaseFailedError``. It never invokes GREEN while
@@ -946,7 +962,7 @@ accepts `--json` and `--quiet`. `pre` emits a JSON contract describing the envir
946
962
  populated `parse_errors` list and
947
963
  `HandoverManifest.is_success` returns `False` so existing
948
964
  `manifest.status.upper() in (...)` success gates keep rejecting them.
949
- (6) **Stricter mapping fallback** — the `_YAML_MAPPING_START_RE` fallback (`src/deviate/core/agent.py`) routes the candidate text through a `_looks_like_manifest` helper that requires `yaml.safe_load(candidate)` to return a `dict` with at least 2 keys before accepting. Single-key dicts (e.g. a stray `Status: complete` line in a JUDGE verdict with a verification matrix) look like prose, not manifests; the fallback now rejects them and the parser raises `MalformedHandoverManifestError` with the existing "No YAML handover manifest detected in agent output" hint. Multi-key partial dicts still flow through to schema recovery unchanged, so the existing `test_missing_phase_and_status_recover_as_unknown` contract is preserved.
965
+ (6) **Stricter mapping fallback** — the `_YAML_MAPPING_START_RE` fallback (`src/deviate/core/agent.py`) routes the candidate text through a `_looks_like_manifest` helper that requires `yaml.safe_load(candidate)` to return a `dict` with at least 2 keys before accepting. Single-key dicts (e.g. a stray `Status: complete` line in a JUDGE verdict with a verification matrix) look like prose, not manifests; the fallback now rejects them and the parser raises `MalformedHandoverManifestError` with the existing "No YAML handover manifest detected in agent output" hint. Multi-key partial dicts still flow through to schema recovery unchanged, so the existing `test_missing_phase_and_status_recover_as_unknown` contract is preserved. (6b) **Unescaped evidence-quote recovery (GH-116)** — when `yaml.safe_load` rejects a handover because an evidence `quote` / `test_quote` / `impl_quote` double-quoted scalar embeds raw `"`, `parse_output` rewrites those lines as `|` block scalars and reloads. Well-formed YAML is unchanged. Truly malformed YAML still raises `MalformedHandoverManifestError`. Verdict and evidence semantics are unchanged.
950
966
  (7) **Lean Pi spawn** — `AgentBackend.invoke` appends a lean tool policy after the existing Pi transport prefix. Print mode keeps `BACKEND_COMMANDS["pi"]` as `pi -p` (AC-009-07). RPC keeps `PI_RPC_COMMAND` as `pi --mode rpc --no-session` (AC-009-10). The helper `_pi_lean_flags` then adds `--no-extensions`, `--tools read,bash,edit,write`, and `--no-skills`. When `.pi/skills/deviatdd/SKILL.md` exists under the invoke `cwd` (or `Path.cwd()`), it also adds `--skill` to that relative path. A missing skill file keeps the four coding tools. The argv omits `--no-tools` and `--no-builtin-tools`. Non-Pi backends skip these flags.
951
967
  (8) **Schema-rejection fail-fast** — `_invoke_streaming`, `_invoke_blocking`, and `_invoke_rpc_blocking` scan each stderr and stdout line. The first line that contains `tool_count_limit` or `unsupported_tool_schema` kills the child. The helper raises `AgentSubprocessError` whose message carries those tokens. This path does not wait for `STREAM_STALL_TIMEOUT_SECONDS` (900s). It does not start the 30s timeout retry. It does not start the `EmptyOutputError` manifest retry. Schema tokens do not reset the stall clock. Stderr stays diagnostic for stall liveness (ISS-ADH-025). `_invoke_agent` logs `AGENT_ERROR` with the exception text. `_raise_schema_limit_phase_error` then raises `PhaseFailedError` so `deviate micro run` RED, GREEN, and REFACTOR include the tokens. The operator does not see only `agent returned no manifest`. EXECUTE stall stays 3600s (GH-53).
952
968
  * **GREEN Stub-PASS Guard (REMOVED):** An earlier revision of this spec
@@ -1483,7 +1499,11 @@ All state transitions are append-only. No existing line is ever modified or over
1483
1499
  - `append_issue_transition()`: Idempotent on `(issue_id, status)` compound key
1484
1500
  - `append_task_transition()`: Idempotent on `(id, status)` compound key
1485
1501
  - `_append_record()` / `_append_with_compound_key()`: Use `fcntl.flock` for file-level
1486
- locking on platforms that support it
1502
+ locking on platforms that support it. If the ledger is non-empty and the last
1503
+ line has no trailing newline, a leading `\n` is written before the new record
1504
+ so two JSON objects never share a line. Every successful write leaves a trailing
1505
+ newline. `claim_issue` writes through `append_issue_transition` (not a raw `"a"`
1506
+ append).
1487
1507
  - Canonical state: Issues derived bottom-up (latest entry per `issue_id`); tasks derived
1488
1508
  sequentially (latest entry per `(id, status)` compound key)
1489
1509
 
@@ -1540,7 +1560,7 @@ the action. EXECUTE `_run_execute_phase` and IMMEDIATE judge stay ungated.
1540
1560
 
1541
1561
  **Empty-diff sign-off:** `proceed_to_refactor_no_diff` (`src/deviate/cli/micro.py::_run_judge_phase`) is the forward-route escape for slices whose production-code scope is intrinsically nil — RED-only deliverable, fixture file, generated types, doc-only slice, or any task whose `failure_kind: mechanical` rationale asserts "no production code expected." The TDD evidence gate still requires a dirty-diff `test_quote` and omits `impl_quote`. The JUDGE-side responsibility is to emit the action on a `COMPLIANCE_PASS` verdict when the in-scope rationale is valid but the production diff cannot grow. The action lands the task at REFACTOR's no-op commit + COMPLETED transition in one step; unmatched empty-GREEN PASS does not COMPLETE.
1542
1562
 
1543
- **TDD mechanical evidence gate:** `HandoverManifest.evidence` is a first-class list of nested citations (`ac`, `test_path`, `test_quote`, `impl_path`, `impl_quote`) in `src/deviate/core/agent.py`. After `_coerce_judge_action`, TDD `_run_judge_phase` (`src/deviate/cli/micro.py`) resolves this task's required `AC-PLAN-NNN` tokens via `resolve_task_ac_tokens` (`src/deviate/core/judge_evidence.py`) and passes that list as `required_tokens` to `evaluate_judge_evidence`. First hit wins: non-empty `TaskRecord.acceptance_criteria` `criterion_id`s; else `AC-PLAN-NNN` tokens named in this task's `tasks.md` card after dropping `**Judge Feedback**` bullets and their continuation lines; else no AC tokens. The gate does not fall back to every token in `<authoritative_acceptance_contract source="plan.md">`. Omitting a later-shard plan token is legal at JUDGE. Auto and manual judge prompts require `evidence` only for the resolved task tokens. Quotes must copy from the already-built `<diff>` (`git diff <red>^..HEAD` where `<red>` is `_resolve_judge_diff_base(session.red_commit_sha)` — the RED-phase failing-test commit after walking back through `docs(...): add judge feedback for retry` subjects — plus dirty `git diff HEAD` and untracked `--no-index` hunks) or allowed HEAD files. ISS-ADH-020 quote checks still apply to that task set: missing this-task tokens, empty quotes, hallucinated paths, quotes below the uniqueness floor (≥ 12 non-whitespace characters, or the full added line if shorter), or quotes that are not exact substrings of the named file hunk rewrite the action to `revert_to_red` with runner-authored feedback in the `JUDGE_AGENT_NO_FEEDBACK` family. When the judge already emitted `train_feedback` or `violations`, persist that text (after the GH-103 citation strip) instead of replacing it with the generic missing-evidence string (GH-102). The task does not COMPLETE. `skip_refactor` on the already-exists path may quote HEAD file contents for this-task tokens; a named test file absent on disk fails. On a test-bearing TDD already-exists claim, every declared `files` / `test_file` path (and evidence `test_path`) must appear in `_assemble_judge_injected_diff` or `_evidence_head_contents`. The membership check runs even when the resolved set has no `AC-PLAN-*` tokens. Empty declared files remain a RED defect, not a COMPLETE. Tasks with no resolved `AC-PLAN-*` tokens may emit empty evidence quotes, but they still need named present test paths. `COMPLIANCE_VIOLATION` skips the quote gate. After the gate returns no feedback and the action is a completion path (`skip_refactor` / bare `COMPLIANCE_PASS` / post-REFACTOR complete / adjudicated already-exists), `_append_status_transition(..., "COMPLETED")` copies the validated `HandoverManifest.evidence` onto that COMPLETED `TaskRecord` as `evidence.items` and stamps `red` / `green` / `head` from `session.red_commit_sha` and `HEAD` (GH-84). TDD complete fail-closes when the injected plan contract has `AC-PLAN-NNN` tokens and the persisted bundle is missing or does not cover them — the same `evaluate_judge_evidence` matcher, with `use_head=True` so quotes resolve against HEAD at the COMPLETED write. Plans with no `AC-PLAN-*` tokens may complete with empty evidence. EXECUTE, IMMEDIATE, and DIRECT judge paths stay ungated.
1563
+ **TDD mechanical evidence gate:** `HandoverManifest.evidence` is a first-class list of nested citations (`ac`, `test_path`, `test_quote`, `impl_path`, `impl_quote`) in `src/deviate/core/agent.py`. After `_coerce_judge_action`, TDD `_run_judge_phase` (`src/deviate/cli/micro.py`) resolves this task's required `AC-PLAN-NNN` tokens via `resolve_task_ac_tokens` (`src/deviate/core/judge_evidence.py`) and passes that list as `required_tokens` to `evaluate_judge_evidence`. First hit wins: non-empty `TaskRecord.acceptance_criteria` `criterion_id`s; else `AC-PLAN-NNN` tokens named in this task's `tasks.md` card after dropping `**Judge Feedback**` bullets and their continuation lines; else no AC tokens. Auto `_build_auto_prompt("judge")` injects that same stripped card as `<task_card source="tasks.md">` (GH-118); `_task_card_text` still returns the raw card for token resolution, GREEN `<persisted_judge_feedback>`, and file-list parsing. The gate does not fall back to every token in `<authoritative_acceptance_contract source="plan.md">`. Omitting a later-shard plan token is legal at JUDGE. Auto and manual judge prompts require `evidence` only for the resolved task tokens. Quotes must copy from the already-built `<diff>` (`git diff <red>^..HEAD` where `<red>` is `_resolve_judge_diff_base(session.red_commit_sha)` — the RED-phase failing-test commit after walking back through `docs(...): add judge feedback for retry` subjects — plus dirty `git diff HEAD` and untracked `--no-index` hunks) or allowed HEAD files. ISS-ADH-020 quote checks still apply to that task set: missing this-task tokens, empty quotes, hallucinated paths, quotes below the uniqueness floor (≥ 12 non-whitespace characters, or the full added line if shorter), or quotes that are not exact substrings of the named file hunk rewrite the action to `revert_to_red` with runner-authored feedback in the `JUDGE_AGENT_NO_FEEDBACK` family. When the judge already emitted `train_feedback` or `violations`, persist that text (after the GH-103 citation strip) instead of replacing it with the generic missing-evidence string (GH-102). The task does not COMPLETE. `skip_refactor` on the already-exists path may quote HEAD file contents for this-task tokens; a named test file absent on disk fails. On a test-bearing TDD already-exists claim, every declared `files` / `test_file` path (and evidence `test_path`) must appear in `_assemble_judge_injected_diff` or `_evidence_head_contents`. The membership check runs even when the resolved set has no `AC-PLAN-*` tokens. Empty declared files remain a RED defect, not a COMPLETE. Tasks with no resolved `AC-PLAN-*` tokens may emit empty evidence quotes, but they still need named present test paths. `COMPLIANCE_VIOLATION` skips the quote gate. After the gate returns no feedback and the action is a completion path (`skip_refactor` / bare `COMPLIANCE_PASS` / post-REFACTOR complete / adjudicated already-exists), `_append_status_transition(..., "COMPLETED")` copies the validated `HandoverManifest.evidence` onto that COMPLETED `TaskRecord` as `evidence.items` and stamps `red` / `green` / `head` from `session.red_commit_sha` and `HEAD` (GH-84). TDD complete fail-closes when the injected plan contract has `AC-PLAN-NNN` tokens and the persisted bundle is missing or does not cover them — the same `evaluate_judge_evidence` matcher, with `use_head=True` so quotes resolve against HEAD at the COMPLETED write. Plans with no `AC-PLAN-*` tokens may complete with empty evidence. EXECUTE, IMMEDIATE, and DIRECT judge paths stay ungated.
1544
1564
 
1545
1565
  **Feedback-commit timeout:** The `revert_to_red` step's "append a feedback
1546
1566
  commit past RED" runs `_commit_judge_feedback_and_advance`
@@ -285,9 +285,9 @@ to invoke, but model selection is delegated to the calling environment.
285
285
  * **Layer discipline:** GREEN's only invariant is "make the RED test pass via the library/API surface declared in scope." It does NOT make scope, spec-drift, or HITL-routing judgments — those belong to JUDGE. When a RED test cannot be satisfied within GREEN's mechanical scope, GREEN emits `status: FAILURE` with a concrete `rationale:` naming the test path and why; `status: "ERROR"` is reserved strictly for tool/orchestration failure. The runner's `_is_hitl_escalation` is a narrow defensive fallback that ONLY promotes structured `contract_drift` / `escalates_to` / `hitl_options` dict keys to `HITL_PENDING` — loose-string `error_kind` discriminators and free-form scope-conflict text do NOT trigger HITL escalation.
286
286
  * **Mechanical Failure → JUDGE Routing:** When GREEN emits `status: FAILURE` with a concrete `rationale:` (the mechanical scope-boundary case above), the runner routes control to JUDGE instead of raising `PhaseFailedError`. `_run_green_phase` sets `session.train_feedback = rationale` + `session.failure_kind = "mechanical"` and returns the session; `_run_judge_phase` injects a `<failure_kind>mechanical</failure_kind>` discriminator block into the JUDGE prompt that instructs the agent to emit `verdict: COMPLIANCE_PASS` + `next_action: proceed_to_refactor_no_diff` (when the slice is intrinsically RED-only and REFACTOR's no-op commit + COMPLETED transition is the right termination) OR `verdict: COMPLIANCE_VIOLATION` + one of three `next_action` values (`revert_before` / `revert_to_red` / `skip_refactor`) instead of attempting to satisfy the test itself. This closes the loop where mechanical FAILURE (e.g. slice-scope conflict, CLI-surface-out-of-sco…
287
287
  * **Test-Defect Failure → JUDGE Routing:** A second routable failure class, parallel to mechanical but pre-decided. When GREEN observes that the RED test itself is wrong (it asserts behavior the spec does not require, exercises the wrong abstraction, or encodes an assumption that contradicts spec/data-model), GREEN emits `status: FAILURE` with a concrete `rationale:` citing the FR/AC the test contradicts, plus `failure_kind: test_defect` on the manifest (`HandoverManifest.failure_kind: Literal["mechanical", "test_defect", "already_satisfied"] | None` in `src/deviate/core/agent.py` — session mirrors the discriminator as `SessionState.failure_kind: Literal["", "mechanical", "test_defect", "no_failing_test"]` in `src/deviate/state/config.py`). `_run_green_phase` reads the manifest's discriminator, sets `session.failure_kind = "test_defect"`, and routes to JUDGE. `_run_judge_phase` injects a `<failure_kind>test_defect</failure_kind>` discriminator block that pre-decides the routing — `verdict: COMPLIANCE_VIOLATION` + `next_action: revert_before` (re-run RED with the GREEN rationale as feedback) — because test defect has only one sensible outcome: the test itself must be re-authored. The discriminator intentionally narrows the JUDGE routing vocabulary compared to mechanical (`revert_to_red` / `skip_refactor` / `proceed_to_refactor_no_diff` are NOT options in the test_defect block). Default `manifest.failure_kind = None` falls through to `"mechanical"` in the runner to preserve prior behavior.
288
- * **RED No-Failing-Test → JUDGE Adjudication (RED → JUDGE direct route):** When RED completes but its test command exits 0 (all tests passed), collects no tests (pytest exit 5), or resolves to no command at all (returncode 127 from `_run_test_cmd`), `_run_red_phase` does NOT raise a raw `PhaseFailedError` and does NOT let GREEN run against a vacuous test. It calls `_adjudicate_red_no_failing_test` (`src/deviate/cli/micro.py`), which sets `session.failure_kind = "no_failing_test"`, injects a `<failure_kind>no_failing_test</failure_kind>` discriminator block into the JUDGE prompt, and dispatches `_run_judge_phase(...)`. The judge diff spans the uncommitted RED test (the `red_baseline` parameter makes `_run_judge_phase` skip the `RED→HEAD` committed diff and surface the agent's uncommitted test through the dirty-parts scan) so JUDGE reviews what the agent actually wrote. On a test-bearing TDD task, `_require_tdd_declared_regression_files` requires a non-empty `files` set and/or `test_file` before this COMPLETE route (constitution §3 Testing Protocols; §5 Definition of Done). Empty declared files raise `PhaseFailedError`. JUDGE decides between two outcomes: `verdict: COMPLIANCE_PASS` + `next_action: skip_refactor` (or a bare PASS verdict) when the required behavior already exists and every declared regression path sits in the injected `<diff>` or `_evidence_head_contents` — the runner then calls `_restore_worktree_to_baseline(..., keep_paths=declared)` so those tests stay on disk, and marks the task COMPLETED; a declared path missing from that snapshot rewrites PASS to `revert_before` / `revert_to_red` with runner-authored feedback and writes no COMPLETED row; or `verdict: COMPLIANCE_VIOLATION` + `next_action: revert_before` (forced by the `_coerce_judge_action` runner-level override for `failure_kind` `no_failing_test`/`test_defect`) when the test is wrong — the runner resets to the RED baseline and re-dispatches RED so a fresh genuinely-failing test is authored. EXECUTE, IMMEDIATE, and DIRECT stay ungated by the files rule. The next `INVOKE_AGENT` is RED, or the loop raises `TRAIN_EXHAUSTED` / `PhaseFailedError`. It never invokes GREEN while `session.red_commit_sha` is empty. `--no-judge` makes the no-failing-test outcome a hard failure (adjudication disabled). Test discovery is language-agnostic: the RED gate no longer globs Python `tests/**/test_*.py` (`_find_test_files`); the project's own convention is honored through the resolved test command (e.g. `mix test` collecting `test/**/*_test.exs` for Elixir/Phoenix), so a correctly authored non-Python test is neither rejected up front nor silently conflated with "no test framework" — a project with no resolvable test command routes to the same JUDGE adjudication instead of failing. This closes the prior stall where an empty `_find_test_files` let RED silently commit a vacuous 'failing test' and GREEN die in `TRAIN_EXHAUSTED`. The RED agent may steer the adjudication by declaring `failure_kind: already_satisfied` (behavior exists) with a non-empty `files` set and/or `test_file`, or `failure_kind: test_defect` (test wrong) with a `rationale` on its handover manifest. A passing suite with no named test files is not a COMPLETE.
288
+ * **RED No-Failing-Test → JUDGE Adjudication (RED → JUDGE direct route):** When RED completes but its test command exits 0 (all tests passed), collects no tests (pytest exit 5), or resolves to no command at all (returncode 127 from `_run_test_cmd`), `_run_red_phase` does NOT raise a raw `PhaseFailedError` and does NOT let GREEN run against a vacuous test. It calls `_adjudicate_red_no_failing_test` (`src/deviate/cli/micro.py`), which sets `session.failure_kind = "no_failing_test"`, injects a `<failure_kind>no_failing_test</failure_kind>` discriminator block into the JUDGE prompt, and dispatches `_run_judge_phase(...)`. The judge diff spans the uncommitted RED test (the `red_baseline` parameter makes `_run_judge_phase` skip the `RED→HEAD` committed diff and surface the agent's uncommitted test through the dirty-parts scan) so JUDGE reviews what the agent actually wrote. On a test-bearing TDD task, `_require_tdd_declared_regression_files` requires a non-empty `files` set and/or `test_file` before this COMPLETE route (constitution §3 Testing Protocols; §5 Definition of Done). Empty declared files raise `PhaseFailedError`. JUDGE decides between two outcomes: `verdict: COMPLIANCE_PASS` + `next_action: skip_refactor` (or a bare PASS verdict, or any `next_action` on the already-exists route) when the required behavior already exists and every declared regression path sits in the injected `<diff>` or `_evidence_head_contents` — `_apply_judge_verdict` then coerces the action to `skip_refactor`, skips the `_rewrite_unmatched_tdd_pass` AC-token citation rewrite for this route, and `_require_tdd_completed_evidence` relaxes the AC-token citation check while retaining the declared-path presence gate, so partial evidence completes instead of rewriting to `revert_to_red`; the runner then calls `_restore_worktree_to_baseline(..., keep_paths=declared)` so those tests stay on disk, and marks the task COMPLETED. `_require_revert_to_red_boundary` is never invoked on this already-exists pass path, so `ROLLBACK_BOUNDARY_MISSING` applies only to a genuine TDD `revert_to_red` with an empty `red_commit_sha`. A declared path missing from that snapshot still fails closed via `_require_tdd_declared_regression_files` (rewriting PASS to `revert_before` / `revert_to_red` with runner-authored feedback and writing no COMPLETED row); or `verdict: COMPLIANCE_VIOLATION` + `next_action: revert_before` (forced by the `_coerce_judge_action` runner-level override for `failure_kind` `no_failing_test`/`test_defect`) when the test is wrong — the runner resets to the RED baseline and re-dispatches RED so a fresh genuinely-failing test is authored. EXECUTE, IMMEDIATE, and DIRECT stay ungated by the files rule. The next `INVOKE_AGENT` is RED, or the loop raises `TRAIN_EXHAUSTED` / `PhaseFailedError`. It never invokes GREEN while `session.red_commit_sha` is empty. `--no-judge` makes the no-failing-test outcome a hard failure (adjudication disabled). Test discovery is language-agnostic: the RED gate no longer globs Python `tests/**/test_*.py` (`_find_test_files`); the project's own convention is honored through the resolved test command (e.g. `mix test` collecting `test/**/*_test.exs` for Elixir/Phoenix), so a correctly authored non-Python test is neither rejected up front nor silently conflated with "no test framework" — a project with no resolvable test command routes to the same JUDGE adjudication instead of failing. This closes the prior stall where an empty `_find_test_files` let RED silently commit a vacuous 'failing test' and GREEN die in `TRAIN_EXHAUSTED`. The RED agent may steer the adjudication by declaring `failure_kind: already_satisfied` (behavior exists) with a non-empty `files` set and/or `test_file`, or `failure_kind: test_defect` (test wrong) with a `rationale` on its handover manifest. A passing suite with no named test files is not a COMPLETE.
289
289
  * **JUDGE / TRAIN (The Compliance Gate) — with Green → Judge → Green loop:**
290
- * **The Judge:** The CLI evaluates the committed RED-parent-to-HEAD diff against `spec.md` for invariant/security violations. When `session.red_commit_sha` has advanced onto a `docs(...): add judge feedback for retry` commit, `_assemble_judge_injected_diff` calls `_resolve_judge_diff_base` to walk back to the RED-phase failing-test commit before running `git diff {red_sha}^..HEAD`, so RED tests stay visible to the evidence gate (GH-88 / GH-90). If GREEN tests failed before the implementation commit, `_run_judge_phase` also appends staged/unstaged `git diff HEAD` output and per-file `git diff --no-index /dev/null <path>` output for untracked files, so JUDGE assesses the retained implementation rather than a false RED-only snapshot. This judge operates in a clean, zero-shared-history session to break recursive subjectivity. A `deviate-judge` skill (loaded from `_SKILL_NAMES["JUDGE"]`) guides the agent through supplementary compliance evaluation. TDD JUDGE evidence is task-scoped: `_run_judge_phase` resolves required `AC-PLAN-NNN` tokens via `resolve_task_ac_tokens` (non-empty `acceptance_criteria` `criterion_id`s, else this task's `tasks.md` card minus `**Judge Feedback**` bullets and their continuation lines, else none) and does not fall back to every token in `plan.md`. TDD `_run_judge_phase` then rejects `COMPLIANCE_PASS` unless `HandoverManifest.evidence` quotes for those task tokens match the injected diff (or HEAD file contents on the already-exists `skip_refactor` edge) and every declared `files` / `test_file` path exists in that snapshot. Unmatched PASS rewrites to `revert_to_red` / `revert_before`. On a forward PASS the runner stashes those citations on `SessionState.validated_evidence` (transient only) and writes them onto the COMPLETED `tasks.jsonl` row as `TaskRecord.evidence` (`items` plus `red` / `green` / `head` SHAs) so `deviate inspect tasks show` can display the proof after the session is gone (GH-84). TDD COMPLETE with `AC-PLAN-NNN` tokens refuse when that bundle is missing or does not cover the tokens (`evaluate_judge_evidence`). `.deviate/` session files are not the proof store. Earlier RED/GREEN/JUDGE rows stay lean. Persist the judge's own `train_feedback` / `violations` when present (GH-103 citation strip still applies); attach the generic missing-evidence string only when the judge emitted none (GH-102). `_append_judge_feedback` keys the card with `_TASK_BULLET_HEAD_RE` exact-id match and inserts under that card only (does not walk past a later phase heading). Gate 3 review (`deviate review`) owns plan-wide AC coverage. EXECUTE, IMMEDIATE, and DIRECT judge paths stay ungated.
290
+ * **The Judge:** The CLI evaluates the committed RED-parent-to-HEAD diff against `spec.md` for invariant/security violations. When `session.red_commit_sha` has advanced onto a `docs(...): add judge feedback for retry` commit, `_assemble_judge_injected_diff` calls `_resolve_judge_diff_base` to walk back to the RED-phase failing-test commit before running `git diff {red_sha}^..HEAD`, so RED tests stay visible to the evidence gate (GH-88 / GH-90). If GREEN tests failed before the implementation commit, `_run_judge_phase` also appends staged/unstaged `git diff HEAD` output and per-file `git diff --no-index /dev/null <path>` output for untracked files, so JUDGE assesses the retained implementation rather than a false RED-only snapshot. This judge operates in a clean, zero-shared-history session to break recursive subjectivity. A `deviate-judge` skill (loaded from `_SKILL_NAMES["JUDGE"]`) guides the agent through supplementary compliance evaluation. TDD JUDGE evidence is task-scoped: `_run_judge_phase` resolves required `AC-PLAN-NNN` tokens via `resolve_task_ac_tokens` (non-empty `acceptance_criteria` `criterion_id`s, else this task's `tasks.md` card minus `**Judge Feedback**` bullets and their continuation lines, else none) and does not fall back to every token in `plan.md`. Auto `_build_auto_prompt("judge")` injects that same stripped card as `<task_card source="tasks.md">` so prior-round Judge-Feedback prose cannot bias the next judge (GH-118); `_task_card_text` remains raw. TDD `_run_judge_phase` then rejects `COMPLIANCE_PASS` unless `HandoverManifest.evidence` quotes for those task tokens match the injected diff (or HEAD file contents on the already-exists `skip_refactor` edge) and every declared `files` / `test_file` path exists in that snapshot. Unmatched PASS rewrites to `revert_to_red` / `revert_before`. On a forward PASS the runner stashes those citations on `SessionState.validated_evidence` (transient only) and writes them onto the COMPLETED `tasks.jsonl` row as `TaskRecord.evidence` (`items` plus `red` / `green` / `head` SHAs) so `deviate inspect tasks show` can display the proof after the session is gone (GH-84). TDD COMPLETE with `AC-PLAN-NNN` tokens refuse when that bundle is missing or does not cover the tokens (`evaluate_judge_evidence`). `.deviate/` session files are not the proof store. Earlier RED/GREEN/JUDGE rows stay lean. Persist the judge's own `train_feedback` / `violations` when present (GH-103 citation strip still applies); attach the generic missing-evidence string only when the judge emitted none (GH-102). `_append_judge_feedback` keys the card with `_TASK_BULLET_HEAD_RE` exact-id match and inserts under that card only (does not walk past a later phase heading). Gate 3 review (`deviate review`) owns plan-wide AC coverage. EXECUTE, IMMEDIATE, and DIRECT judge paths stay ungated.
291
291
  * **The Train (Green → Judge → Green loop):** On `COMPLIANCE_VIOLATION` or test failure, the CLI safely resets without destroying task progress. The JUDGE phase honors `HandoverManifest.next_action` (see [specs/DeviaTDD-api.md](./DeviaTDD-api.md) for the routing table). The five routes:
292
292
  1. **`revert_before`** — discard this task's GREEN **and** its RED. `_resolve_pre_red_sha()` derives the SHA from `red_commit_sha^` (defended by a subject-match regex on the parent's commit message; logs `PRE_RED_AMBIGUOUS` when the parent isn't a RED-phase convention). The pre-RED anchor is threaded into `_execute_rollback(boundary_sha=<pre_red>, task_id=<tid>, attempt=<rollback_attempts>)`; the agent's pre-reset HEAD is captured on the per-attempt recovery ref `tmp/deviate-agent-work/<sanitized-task-id>/attempt-<rollback_attempts>` so a parent SIGTERM between `git reset` and `git clean` doesn't strand the discarded commit. `session.red_commit_sha` is cleared (the boundary was discarded) and `pending_judge_action = "revert_before"`. `force_transition_to("RED")` so the task retries from scratch. `_escalate_to_new_red` consumes `revert_before` only after a RED-phase `red_commit_sha` lands. While that SHA is empty, the next `INVOKE_AGENT` stays RED (or the loop raises `TRAIN_EXHAUSTED` / `PhaseFailedError`). **No implicit fallback**: if `_resolve_pre_red_sha` returns empty AND `session.red_commit_sha` is empty, the runner raises `PhaseFailedError("ROLLBACK_BOUNDARY_MISSING ...")` rather than fall back to `HEAD~1`. When `pre_red` is unresolvable but `session.red_commit_sha` is known, that cached SHA is used as the explicit boundary.
293
293
  **Runner-level override on `failure_kind=test_defect`:** when `session.failure_kind == "test_defect"` and JUDGE emits `COMPLIANCE_VIOLATION`, `_coerce_judge_action` (`src/deviate/cli/micro.py`) forces `next_action="revert_before"` regardless of what the JUDGE manifest declared or omitted. The override reflects a contract invariant: when the RED test itself is wrong, looping back to GREEN with the same test is futile. `_run_tdd_cycle` honours the resulting `pending_judge_action == "revert_before"` by escalating now. It resets `green_attempts` to 0, increments `red_attempts`, and persists both on `.deviate/session.json`. It then dispatches `_run_red_phase(task, ..., bypass_phase_done=True)` so a fresh RED record appends to the append-only ledger (never rewriting prior entries). The retry RED prompt receives a short `previous cycle failed because …` note, not the raw GREEN dump. `TRAIN_EXHAUSTED` prints only after three RED escalates. The override is silenced on `COMPLIANCE_PASS` verdicts; JUDGE's outcome remains authoritative when the implementation is sound. The override preserves the legacy resolution for `revert_to_red`, `continue_refactor`, `proceed_to_refactor_no_diff`, and `skip_refactor` — only the test_defect case is forced.
@@ -689,7 +689,7 @@ The orchestrator must maintain and enforce these structural constraints across a
689
689
 
690
690
  2. **The Scope Audit Law:** When entering or running the `GREEN` execution phase, the system checks for unauthorized changes to test, spec, and config directories. Protected files are reverted via `git restore <filepath>`. The JUDGE phase (`deviate judge pre`) additionally performs compliance verification by detecting changes to protected modules declared in `spec.md` `Module:` lines. Complements the GREEN stub-PASS guard in `_run_green_phase` (see `DeviaTDD-api.md` § GREEN Stub-PASS Guard): scope rejects writes the agent shouldn't have made; the stub-PASS guard rejects passes the agent shouldn't have emitted.
691
691
 
692
- 3. **Append-Only Ledger Protocol (issues.jsonl + tasks.jsonl):** All state transitions are append-only. The global `specs/issues.jsonl` serves as the authoritative issue registry. Issue-scoped micro-task ledgers live at `specs/{FEATURE_SLUG}/{ISSUE_ID}/tasks.jsonl` — the bucket directory (`{FEATURE_SLUG}`) is the epic scope (e.g. `001-…`, `002-…`, or `adhoc`); `{ISSUE_ID}` is the per-epic ordinal matching the issue markdown filename. The `source_file` recorded in `specs/issues.jsonl` follows `specs/{FEATURE_SLUG}/issues/{ISSUE_ID}.md` and the CLI strips the `issues/` segment when mapping to the tasks directory. Agents cannot edit any status fields directly — only the CLI may append events via `append_issue_transition()` and `append_task_transition()`. No existing line is ever modified or overwritten. Canonical state is derived by parsing each ledger using compound-key idempotency (bottom-up for `issues.jsonl`; `(id, status)` compound key for `tasks.jsonl`). For per-issue task ledgers, `COMPLETED` is terminal: once captured, no later non-`COMPLETED` transition may override it; among non-terminal entries, the last by file position wins. Ad-hoc issues bypass macro planning and route directly to isolated execution workspaces.
692
+ 3. **Append-Only Ledger Protocol (issues.jsonl + tasks.jsonl):** All state transitions are append-only. Append helpers (`_append_record`, `_append_with_compound_key`) insert a leading newline when a non-empty ledger does not already end in `\n`, so a missing trailing newline cannot fuse two records onto one line; every successful write leaves a trailing newline. `claim_issue` writes through `append_issue_transition`. The global `specs/issues.jsonl` serves as the authoritative issue registry. Issue-scoped micro-task ledgers live at `specs/{FEATURE_SLUG}/{ISSUE_ID}/tasks.jsonl` — the bucket directory (`{FEATURE_SLUG}`) is the epic scope (e.g. `001-…`, `002-…`, or `adhoc`); `{ISSUE_ID}` is the per-epic ordinal matching the issue markdown filename. The `source_file` recorded in `specs/issues.jsonl` follows `specs/{FEATURE_SLUG}/issues/{ISSUE_ID}.md` and the CLI strips the `issues/` segment when mapping to the tasks directory. Agents cannot edit any status fields directly — only the CLI may append events via `append_issue_transition()` and `append_task_transition()`. No existing line is ever modified or overwritten. Canonical state is derived by parsing each ledger using compound-key idempotency (bottom-up for `issues.jsonl`; `(id, status)` compound key for `tasks.jsonl`). For per-issue task ledgers, `COMPLETED` is terminal: once captured, no later non-`COMPLETED` transition may override it; among non-terminal entries, the last by file position wins. Ad-hoc issues bypass macro planning and route directly to isolated execution workspaces.
693
693
 
694
694
  4. **Deterministic Test Failure Check:** For a `RED` phase to be valid (`deviate red post`), `_classify_pytest_outcome()` must return `ASSERTION_FAILURE`. Return codes of `PASS` or `SYNTAX_ERROR` (SyntaxError, IndentationError, TabError, ImportError, ModuleNotFoundError) are rejected. Current implementation uses string-based parsing of `pytest -v` output; `pytest --json-report` migration is specified but not yet implemented.
695
695
 
@@ -704,7 +704,7 @@ The orchestrator must maintain and enforce these structural constraints across a
704
704
  composable overrides that take precedence over profile defaults. Execution
705
705
  profiles and agent backends are configured via `DeviateConfig.agent.backend`.
706
706
 
707
- 7. **Atomic Concurrency Protocol (Git Reference Locks):** To eliminate TOCTOU race conditions across distributed terminal instances, the issue claim workflow (formerly `deviate specify pre`, now part of the Plan phase orchestration) uses try-claim semantics. `select_unblocked_candidates()` returns all available BACKLOG issues. The worker iterates through them and attempts `claim_issue()` combined with `create_worktree()`. Next `NNN` is max(origin ledger, current ledger, remote `feat/<epic>/<NNN>-*` / `feat/adhoc/<NNN>-*`) + 1. Unmerged remote feat refs feed that max. Local-only unpushed feat branches do not reserve. The default serialization is push-as-lock: `git push -u <remote> <branch>`. The server serializes concurrent pushes. The first successful push wins. When `git push` of `feat/.../NNN-*` is rejected because the name exists, the claim path increments the ordinal and retries (cap 3). Collision retry does not set `--local`. Push-as-lock is the default, not a mandatory step. Local mode (`--local` on `deviate specify`, `deviate meso run`, or `deviate run`, or `claim_remote = false` in `.deviate/config.toml`) keeps the worktree and the ledger claim and skips the remote lock. Local mode is the explicit skip. It is not a collision winner. The `tasks.jsonl` ledger records the authoritative outcome.
707
+ 7. **Atomic Concurrency Protocol (Git Reference Locks):** To eliminate TOCTOU race conditions across distributed terminal instances, the issue claim workflow (formerly `deviate specify pre`, now part of the Plan phase orchestration) uses try-claim semantics. `select_unblocked_candidates()` returns all available BACKLOG issues. The worker iterates through them and attempts `claim_issue()` combined with `create_worktree()`. `_discover_claimable_issue` skips a candidate both when its `feat/<epic>/<slug>` branch already exists on origin (claimed elsewhere) and when that branch already has a local worktree (claimed here) — the local-worktree guard is what lets two parallel terminals on the same checkout claim two different BACKLOG issues even though each claim's SPECIFIED row lives on the feature branch and stays invisible to the main checkout's ledger. Next `NNN` is max(origin ledger, current ledger, remote `feat/<epic>/<NNN>-*` / `feat/adhoc/<NNN>-*`) + 1. Unmerged remote feat refs feed that max. Local-only unpushed feat branches do not reserve. The default serialization is push-as-lock: `git push -u <remote> <branch>`. The server serializes concurrent pushes. The first successful push wins. When `git push` of `feat/.../NNN-*` is rejected because the name exists, the claim path increments the ordinal and retries (cap 3). Collision retry does not set `--local`. Push-as-lock is the default, not a mandatory step. Local mode (`--local` on `deviate specify`, `deviate meso run`, or `deviate run`, or `claim_remote = false` in `.deviate/config.toml`) keeps the worktree and the ledger claim and skips the remote lock. Local mode is the explicit skip. It is not a collision winner. The `tasks.jsonl` ledger records the authoritative outcome.
708
708
 
709
709
  8. **The Session Continuity Principle:** Session state is persisted to `.deviate/session.json` after each CLI command. The `SessionState` class tracks `current_phase`, `active_issue_id`, and `last_command`. Macro and meso phases transition through `transition_to()` with validation from `_MACRO_TRANSITION_MAP`. Micro phases use `force_transition_to()`. The `_run_single()` function checks `session.current_phase` and supports resume from JUDGE/REFACTOR via optional `start_phase` parameter. Model continuity and KV cache management are delegated to the calling environment.
710
710
 
@@ -863,7 +863,15 @@ handing the manifest to the rest of the pipeline:
863
863
  pass a recovered manifest. `HandoverManifest` is imported by
864
864
  `scripts/verify_install.py` (the post-install smoke verifier)
865
865
  which checks the new constants and the recovery behaviour.
866
- 6. **Schema-rejection fail-fast** — the first stderr or stdout line
866
+ 6. **Unescaped evidence-quote recovery (GH-116)** — when
867
+ `yaml.safe_load` fails because an evidence `quote` /
868
+ `test_quote` / `impl_quote` double-quoted scalar embeds raw
869
+ `"`, `_safe_load_handover_yaml` rewrites those lines as `|`
870
+ block scalars and reloads. Well-formed YAML is unchanged.
871
+ Truly malformed YAML still raises
872
+ `MalformedHandoverManifestError`. Verdict and evidence
873
+ semantics are unchanged.
874
+ 7. **Schema-rejection fail-fast** — the first stderr or stdout line
867
875
  that contains `tool_count_limit` or `unsupported_tool_schema`
868
876
  kills the child. `invoke` raises `AgentSubprocessError` with those
869
877
  tokens. This path does not wait for the 900s stall clock. It does
@@ -879,6 +887,7 @@ handing the manifest to the rest of the pipeline:
879
887
  | `claude` | `claude -p --permission-mode auto` | Commands copied into `.claude/commands/` (flat `.md`) | `--model <id>` flag (may be ignored by host env) | Print mode, auto permission |
880
888
  | `droid` | `droid exec` | Commands copied into `.factory/commands/` (flat `.md`) | `--model <id>` flag | Factory Droid IDE-owned commands dir |
881
889
  | `pi` | `pi -p` | Commands file-copied into `<workdir>/.pi/prompts/<name>.md` (project-local; flat top-level only per Pi's documented slash-command convention) | `--model <id>` flag (accepts `provider/model` shorthand) | Lean spawn after `pi -p` / RPC `--no-session`: `--no-extensions`, `--tools read,bash,edit,write`, `--no-skills`, optional `--skill`; schema-limit tokens abort as `AGENT_ERROR` |
890
+ | `codex` | `codex exec --sandbox workspace-write --ask-for-approval never` | Skills written to `<workdir>/.agents/skills/<name>/SKILL.md` (Codex CLI 0.117+ dropped `.codex/prompts`). Packaged `deviatdd` skill plus one skill folder per slash command. | `--model <id>` flag | CLI transport only (no Codex RPC). Prompt via stdin. Do not use `--full-auto` or `--dangerously-bypass-approvals-and-sandbox`. |
882
891
 
883
892
  Pi implements slash-command discovery natively — `pi -p` loads commands from
884
893
  `~/.pi/agent/`, `.pi/prompts/`, and `.agents/` on startup, parses the
@@ -950,18 +959,18 @@ standard `AgentBackend.invoke()` contract with these customisations:
950
959
  the tokens. This path does not wait 900s. It does not treat those
951
960
  tokens as stall liveness. EXECUTE stall stays 3600s.
952
961
 
953
- ### 10.2.5 Project-Local `deviatdd` Skill (Single Skill, Write-Everywhere)
962
+ ### 10.2.5 Project-Local `deviatdd` Skill (Single Skill, Selected Agent)
954
963
 
955
964
  In addition to the 25 `deviate-*` slash commands under
956
965
  `<workdir>/.<agent>/commands/` and `<workdir>/.pi/prompts/`, `deviate setup`
957
966
  provisions exactly **one** project-local skill named `deviatdd` at
958
- `<workdir>/.<agent>/skills/deviatdd/SKILL.md` for every agent platform
959
- in `active_agents` (`claude`, `opencode`, `factory`, `pi`, `omp`).
960
- This mirrors `_install_commands_to_agents`'s write-everywhere policy:
961
- the skill body is identical across platforms, only the destination
962
- directory differs, and the write is unconditional — every operator
963
- using `--agent <platform>` gets the skill at the canonical skills
964
- directory for their platform.
967
+ `<workdir>/.<agent>/skills/deviatdd/SKILL.md` for the selected agent
968
+ only (`claude`, `opencode`, `factory`/`droid`, `pi`, `omp`). Codex
969
+ receives the same skill at `<workdir>/.agents/skills/deviatdd/SKILL.md`
970
+ plus one `.agents/skills/<command>/SKILL.md` per packaged slash command.
971
+ `--agent` gates both command and skill install; `droid` normalizes to
972
+ `.factory/`. The skill body is identical across platforms — only the
973
+ destination directory differs.
965
974
 
966
975
  **Auto-discovery status per platform (informational, does not gate the
967
976
  write):**
@@ -979,6 +988,9 @@ write):**
979
988
  `~/.omp/agent/managed-skills/<name>/SKILL.md` and via a
980
989
  settings-driven `skills` array. Operators register the
981
990
  project-local file via OMP's `skills` array in settings.
991
+ - `codex` — official project-local discovery is
992
+ `.agents/skills/<name>/SKILL.md`. Codex CLI 0.117+ dropped
993
+ `.codex/prompts` and `/prompts:`.
982
994
 
983
995
  **Source of truth:** `src/deviate/prompts/skills/deviatdd/SKILL.md`
984
996
  (package resource, loaded via `importlib.resources`).
@@ -1036,18 +1048,21 @@ field schemas live in `micro.py` itself, not duplicated here.
1036
1048
  **`.gitignore` exclusions:** `_ensure_root_gitignore` adds
1037
1049
  `*/skills/deviatdd/` to the entries tuple alongside
1038
1050
  `*/commands/deviate-*.md` and `*/prompts/deviate-*.md`. The
1039
- single-level wildcard covers all five agent platforms (`.claude/`,
1040
- `.opencode/`, `.factory/`, `.pi/`, `.omp/`) with one pattern. The
1041
- single-level prefix (`*/`, not `**/`) is critical: it scopes the
1042
- pattern to the project root, never matching the deviatdd project's
1043
- own source at `src/deviate/prompts/skills/deviatdd/` (three
1044
- directories deep).
1045
-
1046
- **Tests:** `TestInstallDeviatddSkill` (8 tests) in
1047
- `tests/test_cli/test_init.py` covers install-to-all-five-agents,
1048
- idempotence, gitignore entry presence + idempotence, the safety-gate
1049
- fragments in the SKILL.md body, well-formed frontmatter, and the
1050
- dispatch table's canonical slash-command references.
1051
+ single-level wildcard covers every selected-agent skill install
1052
+ (`.claude/`, `.opencode/`, `.factory/`, `.pi/`, `.omp/`, `.agents/`)
1053
+ with one pattern. `*/skills/deviate-*/` covers Codex per-command
1054
+ skill dirs. The single-level prefix (`*/`, not `**/`) is critical: it
1055
+ scopes the pattern to the project root, never matching the
1056
+ deviatdd project's own source at
1057
+ `src/deviate/prompts/skills/deviatdd/` (three directories deep).
1058
+
1059
+ **Tests:** `TestInstallDeviatddSkill` in `tests/test_cli/test_init.py`
1060
+ and `TestSetupSelectedAgentIsolation` / `TestSetupCodex` in
1061
+ `tests/test_cli/test_setup.py` cover selected-agent-only install,
1062
+ Codex skills + `backend = "codex"`, idempotence, gitignore entry
1063
+ presence + idempotence, the safety-gate fragments in the SKILL.md
1064
+ body, well-formed frontmatter, and the dispatch table's canonical
1065
+ slash-command references.
1051
1066
 
1052
1067
 
1053
1068
  ### 10.3 Pi Sandbox Boundary