deviatdd 2.20.1__tar.gz → 2.20.2__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 (400) hide show
  1. deviatdd-2.20.2/.worktrees/work/.env.example +8 -0
  2. {deviatdd-2.20.1 → deviatdd-2.20.2}/CHANGELOG.md +2 -0
  3. {deviatdd-2.20.1 → deviatdd-2.20.2}/PKG-INFO +1 -1
  4. {deviatdd-2.20.1 → deviatdd-2.20.2}/pyproject.toml +1 -1
  5. deviatdd-2.20.2/specs/005-acceptance-gates/002-task-acceptance-traceability/plan.md +150 -0
  6. deviatdd-2.20.2/specs/005-acceptance-gates/002-task-acceptance-traceability/tasks.jsonl +9 -0
  7. deviatdd-2.20.2/specs/005-acceptance-gates/002-task-acceptance-traceability/tasks.md +113 -0
  8. deviatdd-2.20.2/specs/adhoc/issues/016-single-source-prompt-templates.md +139 -0
  9. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/prd.md +16 -0
  10. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/issues.jsonl +3 -0
  11. deviatdd-2.20.2/src/deviate/core/tasks_ledger.py +125 -0
  12. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-adhoc.md +3 -2
  13. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-tasks.md +3 -3
  14. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/state/ledger.py +36 -0
  15. deviatdd-2.20.2/tests/test_core/test_tasks_ledger.py +404 -0
  16. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_state/test_ledger.py +182 -0
  17. {deviatdd-2.20.1 → deviatdd-2.20.2}/uv.lock +1 -1
  18. deviatdd-2.20.1/src/deviate/core/tasks_ledger.py +0 -69
  19. deviatdd-2.20.1/tests/test_core/test_tasks_ledger.py +0 -145
  20. {deviatdd-2.20.1 → deviatdd-2.20.2}/.deviate/.gitignore +0 -0
  21. {deviatdd-2.20.1 → deviatdd-2.20.2}/.deviate/config.toml +0 -0
  22. {deviatdd-2.20.1 → deviatdd-2.20.2}/.deviate/evaluations/deviate-flows-skill-2026-06-26.json +0 -0
  23. {deviatdd-2.20.1 → deviatdd-2.20.2}/.env.example +0 -0
  24. {deviatdd-2.20.1 → deviatdd-2.20.2}/.gitattributes +0 -0
  25. {deviatdd-2.20.1 → deviatdd-2.20.2}/.githooks/pre-commit +0 -0
  26. {deviatdd-2.20.1 → deviatdd-2.20.2}/.githooks/pre-push +0 -0
  27. {deviatdd-2.20.1 → deviatdd-2.20.2}/.github/ISSUE_TEMPLATE/bug.md +0 -0
  28. {deviatdd-2.20.1 → deviatdd-2.20.2}/.github/ISSUE_TEMPLATE/feature.md +0 -0
  29. {deviatdd-2.20.1 → deviatdd-2.20.2}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  30. {deviatdd-2.20.1 → deviatdd-2.20.2}/.github/workflows/ci.yml +0 -0
  31. {deviatdd-2.20.1 → deviatdd-2.20.2}/.gitignore +0 -0
  32. {deviatdd-2.20.1 → deviatdd-2.20.2}/.opencode/.gitignore +0 -0
  33. {deviatdd-2.20.1 → deviatdd-2.20.2}/.opencode/opencode.json +0 -0
  34. {deviatdd-2.20.1/.worktrees/feat/005-acceptance-gates/002-task-acceptance-traceability → deviatdd-2.20.2/.worktrees/feat/005-acceptance-gates/003-micro-phase-gates-red-green}/.env.example +0 -0
  35. {deviatdd-2.20.1 → deviatdd-2.20.2}/.worktrees/feat/adhoc/012-rpc-streaming-tui-renderer/.env.example +0 -0
  36. {deviatdd-2.20.1 → deviatdd-2.20.2}/.worktrees/feat/adhoc/014-cwe-mapping-security-findings/.env.example +0 -0
  37. {deviatdd-2.20.1/.worktrees/work → deviatdd-2.20.2/.worktrees/feat/adhoc/016-single-source-prompt-templates}/.env.example +0 -0
  38. {deviatdd-2.20.1 → deviatdd-2.20.2}/AGENTS.md +0 -0
  39. {deviatdd-2.20.1 → deviatdd-2.20.2}/CLAUDE.md +0 -0
  40. {deviatdd-2.20.1 → deviatdd-2.20.2}/CODE_OF_CONDUCT.md +0 -0
  41. {deviatdd-2.20.1 → deviatdd-2.20.2}/CONTRIBUTING.md +0 -0
  42. {deviatdd-2.20.1 → deviatdd-2.20.2}/LICENSE +0 -0
  43. {deviatdd-2.20.1 → deviatdd-2.20.2}/README.md +0 -0
  44. {deviatdd-2.20.1 → deviatdd-2.20.2}/SECURITY.md +0 -0
  45. {deviatdd-2.20.1 → deviatdd-2.20.2}/deviatdd.png +0 -0
  46. {deviatdd-2.20.1 → deviatdd-2.20.2}/mise.toml +0 -0
  47. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat/001-deviate-cli-python/008-meso-macro-automated-orchestration.md +0 -0
  48. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat/adhoc/006-context-cli-integration.md +0 -0
  49. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-001-deviate-cli-python-001-cli-initialization-governance-provisioning-pr-11.md +0 -0
  50. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-001-deviate-cli-python-003-meso-layer-specification-task-decomposition.md +0 -0
  51. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-001-deviate-cli-python-004-micro-layer-tdd-sandbox-execution.md +0 -0
  52. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-001-deviate-cli-python-005-cli-architecture-realignment-skill-integration.md +0 -0
  53. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-001-deviate-cli-python-007-macro-meso-parity-backward-compatibility.md +0 -0
  54. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-002-deviatdd-gap-analysis-001-foundation-cli-infrastructure.md +0 -0
  55. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-002-deviatdd-gap-analysis-003-fast-path-commands.md +0 -0
  56. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-002-deviatdd-gap-analysis-004-governance-inspection.md +0 -0
  57. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-adhoc-001-streaming-pipeline-monitor.md +0 -0
  58. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat-adhoc-008-ast-phase-prioritization.md +0 -0
  59. {deviatdd-2.20.1 → deviatdd-2.20.2}/pr_descriptions/feat_002-deviatdd-gap-analysis_001-foundation-cli-infrastructure.md +0 -0
  60. {deviatdd-2.20.1 → deviatdd-2.20.2}/scripts/benchmark_lmstudio.py +0 -0
  61. {deviatdd-2.20.1 → deviatdd-2.20.2}/scripts/verify_install.py +0 -0
  62. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/manifest-t001.json +0 -0
  63. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/manifest-t002.json +0 -0
  64. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/manifest-t004.json +0 -0
  65. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/spec.md +0 -0
  66. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/001-cli-initialization-governance-provisioning/tasks.md +0 -0
  67. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/002-macro-layer-state-ledger-management/spec.md +0 -0
  68. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/002-macro-layer-state-ledger-management/tasks.md +0 -0
  69. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/003-meso-layer-specification-task-decomposition/spec.md +0 -0
  70. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/003-meso-layer-specification-task-decomposition/tasks.md +0 -0
  71. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/004-micro-layer-tdd-sandbox-execution/spec.md +0 -0
  72. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/004-micro-layer-tdd-sandbox-execution/tasks.jsonl +0 -0
  73. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/004-micro-layer-tdd-sandbox-execution/tasks.md +0 -0
  74. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/005-cli-architecture-realignment-skill-integration/spec.md +0 -0
  75. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/005-cli-architecture-realignment-skill-integration/tasks.md +0 -0
  76. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/007-macro-meso-parity-backward-compatibility/spec.md +0 -0
  77. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/007-macro-meso-parity-backward-compatibility/tasks.md +0 -0
  78. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/008-meso-macro-automated-orchestration/spec.md +0 -0
  79. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/008-meso-macro-automated-orchestration/tasks.jsonl +0 -0
  80. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/008-meso-macro-automated-orchestration/tasks.md +0 -0
  81. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/data-model.md +0 -0
  82. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/design.md +0 -0
  83. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/explore.md +0 -0
  84. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/issues/001-cli-initialization-governance-provisioning.md +0 -0
  85. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/issues/002-macro-layer-state-ledger-management.md +0 -0
  86. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/issues/003-meso-layer-specification-task-decomposition.md +0 -0
  87. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/issues/004-micro-layer-tdd-sandbox-execution.md +0 -0
  88. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/issues/005-cli-architecture-realignment-skill-integration.md +0 -0
  89. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/issues/006-state-persistence-concurrency-safety.md +0 -0
  90. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/issues/007-macro-meso-parity-backward-compatibility.md +0 -0
  91. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/issues/008-meso-macro-automated-orchestration.md +0 -0
  92. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/001-deviate-cli-python/prd.md +0 -0
  93. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/001-foundation-cli-infrastructure/spec.md +0 -0
  94. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/001-foundation-cli-infrastructure/tasks.jsonl +0 -0
  95. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/001-foundation-cli-infrastructure/tasks.md +0 -0
  96. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/003-fast-path-commands/spec.md +0 -0
  97. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/003-fast-path-commands/tasks.jsonl +0 -0
  98. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/003-fast-path-commands/tasks.md +0 -0
  99. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/004-governance-inspection/spec.md +0 -0
  100. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/004-governance-inspection/tasks.jsonl +0 -0
  101. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/004-governance-inspection/tasks.md +0 -0
  102. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/005-micro-layer-integrity/spec.md +0 -0
  103. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/005-micro-layer-integrity/tasks.jsonl +0 -0
  104. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/005-micro-layer-integrity/tasks.md +0 -0
  105. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/data-model.md +0 -0
  106. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/design.md +0 -0
  107. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/explore.md +0 -0
  108. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/issues/001-foundation-cli-infrastructure.md +0 -0
  109. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/issues/002-context-pipeline.md +0 -0
  110. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/issues/003-fast-path-commands.md +0 -0
  111. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/issues/004-governance-inspection.md +0 -0
  112. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/issues/005-micro-layer-integrity.md +0 -0
  113. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/plan-tdd-integration-gap.md +0 -0
  114. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/002-deviatdd-gap-analysis/prd.md +0 -0
  115. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/003-graphite-cli-integration/explore.md +0 -0
  116. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/004-per-task-security-profile/issues/001-security-profile-and-judge-checks.md +0 -0
  117. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/001-verification-mode-metadata/plan.md +0 -0
  118. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/001-verification-mode-metadata/tasks.jsonl +0 -0
  119. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/001-verification-mode-metadata/tasks.md +0 -0
  120. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/data-model.md +0 -0
  121. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/design.md +0 -0
  122. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/explore.md +0 -0
  123. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/issues/001-verification-mode-metadata.md +0 -0
  124. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/issues/002-task-acceptance-traceability.md +0 -0
  125. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/issues/003-micro-phase-gates-red-green.md +0 -0
  126. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/issues/004-refactor-regression-gate.md +0 -0
  127. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/issues/005-prompt-spec-alignment.md +0 -0
  128. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/005-acceptance-gates/prd.md +0 -0
  129. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/DeviaTDD-api.md +0 -0
  130. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/DeviaTDD-architecture.md +0 -0
  131. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/architecture.md +0 -0
  132. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/domain-model.md +0 -0
  133. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/flows/flows-product.md +0 -0
  134. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/flows/flows-streaming.md +0 -0
  135. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/flows/index.md +0 -0
  136. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/flows.jsonl +0 -0
  137. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/guildwright-current-system.md +0 -0
  138. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/guildwright-gap-register.md +0 -0
  139. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/guildwright-git-state-model.md +0 -0
  140. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/guildwright-rewrite.md +0 -0
  141. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/guildwright-rust-tui-requirements.md +0 -0
  142. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/_product/release-next.md +0 -0
  143. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/001-streaming-pipeline-monitor/spec.md +0 -0
  144. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/001-streaming-pipeline-monitor/tasks.jsonl +0 -0
  145. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/001-streaming-pipeline-monitor/tasks.md +0 -0
  146. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/003-meso-layer-restructuring/spec.md +0 -0
  147. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/003-meso-layer-restructuring/tasks.jsonl +0 -0
  148. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/003-meso-layer-restructuring/tasks.md +0 -0
  149. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/004-deviate-review-skill/spec.md +0 -0
  150. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/004-deviate-review-skill/tasks.jsonl +0 -0
  151. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/004-deviate-review-skill/tasks.md +0 -0
  152. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/005-per-phase-model-configuration/plan.md +0 -0
  153. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/005-per-phase-model-configuration/tasks.jsonl +0 -0
  154. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/005-per-phase-model-configuration/tasks.md +0 -0
  155. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/006-context-cli-integration/plan.md +0 -0
  156. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/006-context-cli-integration/tasks.jsonl +0 -0
  157. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/006-context-cli-integration/tasks.md +0 -0
  158. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/007-graphite-cli/plan.md +0 -0
  159. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/007-graphite-cli/tasks.jsonl +0 -0
  160. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/007-graphite-cli/tasks.md +0 -0
  161. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/008-ast-phase-prioritization/plan.md +0 -0
  162. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/008-ast-phase-prioritization/tasks.jsonl +0 -0
  163. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/008-ast-phase-prioritization/tasks.md +0 -0
  164. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/009-pi-agent-backend-integration/plan.md +0 -0
  165. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/009-pi-agent-backend-integration/tasks.jsonl +0 -0
  166. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/009-pi-agent-backend-integration/tasks.md +0 -0
  167. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/010-deviate-setup-product-layer/plan.md +0 -0
  168. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/010-deviate-setup-product-layer/tasks.jsonl +0 -0
  169. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/010-deviate-setup-product-layer/tasks.md +0 -0
  170. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/013-flow-ledger-canonical-source-of-truth/plan.md +0 -0
  171. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/013-flow-ledger-canonical-source-of-truth/tasks.jsonl +0 -0
  172. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/013-flow-ledger-canonical-source-of-truth/tasks.md +0 -0
  173. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/015-narrow-product-flow-scope/plan.md +0 -0
  174. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/015-narrow-product-flow-scope/tasks.md +0 -0
  175. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/001-streaming-pipeline-monitor.md +0 -0
  176. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/002-aider-agent-backend-integration.md +0 -0
  177. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/003-meso-layer-restructuring.md +0 -0
  178. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/004-deviate-review-skill.md +0 -0
  179. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/005-per-phase-model-configuration.md +0 -0
  180. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/006-context-cli-integration.md +0 -0
  181. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/007-graphite-cli.md +0 -0
  182. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/008-ast-phase-prioritization.md +0 -0
  183. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/009-pi-agent-backend-integration.md +0 -0
  184. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/010-deviate-setup-product-layer.md +0 -0
  185. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/012-rpc-streaming-tui-renderer.md +0 -0
  186. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/013-flow-ledger-canonical-source-of-truth.md +0 -0
  187. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/014-cwe-mapping-security-findings.md +0 -0
  188. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/adhoc/issues/015-narrow-product-flow-scope.md +0 -0
  189. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/constitution.md +0 -0
  190. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/explore/ast-tree-sitter.md +0 -0
  191. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/explore/flow-ledger.md +0 -0
  192. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/explore/graphite-cli.md +0 -0
  193. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/explore/pi-agent-backend.md +0 -0
  194. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/explore/product-layer.md +0 -0
  195. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/explore/rpc-streaming-tui.md +0 -0
  196. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/explore/rpc-streaming.md +0 -0
  197. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/explore/security-hardening-cwe.md +0 -0
  198. {deviatdd-2.20.1 → deviatdd-2.20.2}/specs/implementation-gap.md +0 -0
  199. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/__init__.py +0 -0
  200. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/__init__.py +0 -0
  201. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/_common.py +0 -0
  202. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/_html.py +0 -0
  203. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/_safe_commands.py +0 -0
  204. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/adhoc.py +0 -0
  205. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/constitution.py +0 -0
  206. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/feature.py +0 -0
  207. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/flow_commands.py +0 -0
  208. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/init.py +0 -0
  209. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/inspect.py +0 -0
  210. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/macro.py +0 -0
  211. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/meso.py +0 -0
  212. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/micro.py +0 -0
  213. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/review.py +0 -0
  214. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/cli/walkthrough.py +0 -0
  215. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/__init__.py +0 -0
  216. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/_shared.py +0 -0
  217. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/agent.py +0 -0
  218. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/cache_discipline.py +0 -0
  219. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/commands.py +0 -0
  220. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/commit.py +0 -0
  221. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/complexity.py +0 -0
  222. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/constitution.py +0 -0
  223. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/contract.py +0 -0
  224. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/convention.py +0 -0
  225. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/epic.py +0 -0
  226. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/issues.py +0 -0
  227. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/prd.py +0 -0
  228. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/profile.py +0 -0
  229. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/repo.py +0 -0
  230. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/run_logger.py +0 -0
  231. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/validation.py +0 -0
  232. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/core/worktree.py +0 -0
  233. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/html_templates/__init__.py +0 -0
  234. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/html_templates/architecture.html.tmpl +0 -0
  235. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/html_templates/domain-model.html.tmpl +0 -0
  236. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/html_templates/flows.html.tmpl +0 -0
  237. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/html_templates/plan.html.tmpl +0 -0
  238. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/html_templates/prd.html.tmpl +0 -0
  239. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/main.py +0 -0
  240. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/__init__.py +0 -0
  241. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/assembly.py +0 -0
  242. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/__init__.py +0 -0
  243. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/execute.md +0 -0
  244. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/explore.md +0 -0
  245. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/green.md +0 -0
  246. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/judge.md +0 -0
  247. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/plan.md +0 -0
  248. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/prd.md +0 -0
  249. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/red.md +0 -0
  250. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/refactor.md +0 -0
  251. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/research.md +0 -0
  252. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/shard.md +0 -0
  253. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/specify.md +0 -0
  254. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/auto/tasks.md +0 -0
  255. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-architecture.md +0 -0
  256. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-constitution.md +0 -0
  257. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-e2e.md +0 -0
  258. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-execute.md +0 -0
  259. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-explore.md +0 -0
  260. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-flows.md +0 -0
  261. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-green.md +0 -0
  262. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-hotfix.md +0 -0
  263. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-html.md +0 -0
  264. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-init.md +0 -0
  265. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-judge.md +0 -0
  266. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-merge.md +0 -0
  267. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-plan.md +0 -0
  268. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-pr.md +0 -0
  269. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-prd.md +0 -0
  270. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-prune.md +0 -0
  271. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-red.md +0 -0
  272. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-refactor.md +0 -0
  273. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-release.md +0 -0
  274. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-research.md +0 -0
  275. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-review.md +0 -0
  276. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-shard.md +0 -0
  277. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-triage.md +0 -0
  278. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/commands/deviate-walkthrough.md +0 -0
  279. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/constitution_seed.md +0 -0
  280. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/core/core.md +0 -0
  281. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/core/lifecycle-auto.md +0 -0
  282. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/core/lifecycle-manual.md +0 -0
  283. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/core/macro-shared.md +0 -0
  284. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/core/meso-shared.md +0 -0
  285. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/core/micro-shared.md +0 -0
  286. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/core/product-shared.md +0 -0
  287. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/core/style-ste.md +0 -0
  288. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/extras/deviate-pr-graphite-routing.md +0 -0
  289. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/governance/__init__.py +0 -0
  290. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/governance/agents_seed.md +0 -0
  291. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/governance/claudemd_seed.md +0 -0
  292. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/governance/graphite_seed.md +0 -0
  293. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/governance/libref_seed.md +0 -0
  294. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/prompts/skills/deviatdd/SKILL.md +0 -0
  295. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/state/__init__.py +0 -0
  296. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/state/config.py +0 -0
  297. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/ui/__init__.py +0 -0
  298. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/ui/monitor.py +0 -0
  299. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/ui/pipeline.py +0 -0
  300. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/ui/render.py +0 -0
  301. {deviatdd-2.20.1 → deviatdd-2.20.2}/src/deviate/visual/__init__.py +0 -0
  302. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/__init__.py +0 -0
  303. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/conftest.py +0 -0
  304. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/core/__init__.py +0 -0
  305. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/core/test_agent.py +0 -0
  306. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/core/test_smart_stall.py +0 -0
  307. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/e2e/test_macro_workflow.bats +0 -0
  308. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/__init__.py +0 -0
  309. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_adhoc.py +0 -0
  310. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_common.py +0 -0
  311. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_constitution.py +0 -0
  312. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_feature.py +0 -0
  313. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_flows_sync.py +0 -0
  314. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_help.py +0 -0
  315. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_html.py +0 -0
  316. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_init.py +0 -0
  317. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_inspect.py +0 -0
  318. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_macro_contracts.py +0 -0
  319. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_main_entrypoint.py +0 -0
  320. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_merge.py +0 -0
  321. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_meso.py +0 -0
  322. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_meso_contracts.py +0 -0
  323. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_micro.py +0 -0
  324. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_real_descendant_kill.py +0 -0
  325. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_review.py +0 -0
  326. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_safe_commands.py +0 -0
  327. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_test_command_resolution.py +0 -0
  328. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_timeout_safe_command.py +0 -0
  329. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_cli/test_top_level_run.py +0 -0
  330. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_agent.py +0 -0
  331. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_cache_discipline.py +0 -0
  332. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_commands.py +0 -0
  333. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_commit.py +0 -0
  334. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_complexity.py +0 -0
  335. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_constitution.py +0 -0
  336. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_contract.py +0 -0
  337. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_convention.py +0 -0
  338. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_epic.py +0 -0
  339. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_flow_confirmation.py +0 -0
  340. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_issues.py +0 -0
  341. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_ledger.py +0 -0
  342. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_prd.py +0 -0
  343. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_profile.py +0 -0
  344. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_repo.py +0 -0
  345. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_run_logger.py +0 -0
  346. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_validation.py +0 -0
  347. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_core/test_worktree.py +0 -0
  348. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_init.py +0 -0
  349. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/__init__.py +0 -0
  350. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/conftest.py +0 -0
  351. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_command_installation.py +0 -0
  352. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_init_export_cycle.py +0 -0
  353. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_macro_full_cycle.py +0 -0
  354. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_macro_layer.py +0 -0
  355. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_macro_orchestration.py +0 -0
  356. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_meso_layer.py +0 -0
  357. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_meso_orchestration.py +0 -0
  358. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_meso_task_ledger.py +0 -0
  359. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_parity.py +0 -0
  360. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_integration/test_skill_installation.py +0 -0
  361. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_macro/__init__.py +0 -0
  362. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_macro/test_explore.py +0 -0
  363. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_macro/test_macro_model_routing.py +0 -0
  364. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_macro/test_macro_orchestration.py +0 -0
  365. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_macro/test_prd.py +0 -0
  366. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_macro/test_research.py +0 -0
  367. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_macro/test_shard.py +0 -0
  368. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/__init__.py +0 -0
  369. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/test_auto_prompt_templates.py +0 -0
  370. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/test_meso_model_routing.py +0 -0
  371. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/test_meso_orchestration.py +0 -0
  372. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/test_meso_resume.py +0 -0
  373. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/test_plan_structure_injection.py +0 -0
  374. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/test_prompt_assembly.py +0 -0
  375. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/test_specify.py +0 -0
  376. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_meso/test_tasks.py +0 -0
  377. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/__init__.py +0 -0
  378. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/conftest.py +0 -0
  379. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_commit_failure.py +0 -0
  380. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_e2e.py +0 -0
  381. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_execute.py +0 -0
  382. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_green.py +0 -0
  383. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_hotfix.py +0 -0
  384. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_judge.py +0 -0
  385. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_orchestration.py +0 -0
  386. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_output_filter.py +0 -0
  387. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_red.py +0 -0
  388. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_refactor.py +0 -0
  389. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_rollback_safety.py +0 -0
  390. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_run.py +0 -0
  391. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_micro/test_task_label.py +0 -0
  392. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_state/__init__.py +0 -0
  393. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_state/test_config.py +0 -0
  394. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_state/test_security_profile.py +0 -0
  395. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_state/test_session.py +0 -0
  396. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_ui/__init__.py +0 -0
  397. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_ui/test_monitor.py +0 -0
  398. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_ui/test_pipeline.py +0 -0
  399. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_ui/test_render.py +0 -0
  400. {deviatdd-2.20.1 → deviatdd-2.20.2}/tests/test_visual_demo/test_tsk_001_01.py +0 -0
@@ -0,0 +1,8 @@
1
+ # PyPI API token for `mise run publish`.
2
+ #
3
+ # Generate at https://pypi.org/manage/account/token/
4
+ # - Scope the token to the `deviatdd` project only (not account-wide)
5
+ # - Copy this file to `.env` and paste your real token
6
+ # - `.env` is gitignored; never commit secrets
7
+
8
+ PYPI_API_TOKEN=
@@ -23,6 +23,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
23
23
  - **`deviate flows sync` — sole owner of `specs/_product/flows.jsonl` creation.** New top-level `flows` Typer group exposes a single `sync` subcommand that parses `specs/_product/flows/index.md` and appends one ``FlowRecord`` identity row plus ``FLOW_DISCOVERED`` and ``FLOW_DOCUMENTED`` events per flow. Re-running on a populated ledger is a no-op (compound-key idempotency on the underlying append helpers). Exits non-zero with ``FLOWS_INDEX_MISSING`` on stderr when the canonical index is absent, and ``FLOWS_INDEX_EMPTY`` when the index parses to zero rows — surfaces authoring defects instead of silently committing a half-baked catalog. New public service `seed_flow_ledger(flows_index, ledger_path)` in `src/deviate/state/ledger.py` plus `FlowIndexEmptyError` for the empty-index contract. `deviate explore post` no longer seeds identity or documentation events; it only renders the coverage report. ``flows.jsonl`` never receives ``FLOW_REFERENCED_BY_ISSUE`` events — the referenced-by relationship is derived read-only from ``specs/issues.jsonl::flow_refs`` at coverage time.
24
24
  - **`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`.
25
25
  ### Changed
26
+ - **Ad-hoc issue creation no longer marks the record COMPLETED at creation time.** `/deviate-adhoc` step 7 previously instructed the agent to “mark the record as completed” via `deviate adhoc post` — but that CLI reads a different ledger (`specs/adhoc.jsonl`) than the `specs/issues.jsonl` ledger the prompt populates, so agents instead appended a raw `COMPLETED` transition to `specs/issues.jsonl` immediately, before any plan/tasks/red-green work ran (visible as instant `BACKLOG → SPECIFIED → COMPLETED` sequences for `ISS-ADH-003/004/013`). Step 7 now commits artifacts with a plain `git commit`, leaves the record at `BACKLOG`, and forbids appending any `COMPLETED` transition at creation — completion is written only by later phase post-scripts. The re-installed mirrors (`.opencode/`, `.claude/`, `.omp/`, `.factory/`) carry the fix via `deviate setup`. Prompt-only change in `src/deviate/prompts/commands/deviate-adhoc.md`; pinned by the existing `TestConsumerRepositoryPromptBoundaries` prompt tests.
27
+ - **`/deviate-tasks` no longer waits for the removed Gate 2 approval.** The prompt still said the workflow “stops for joint human review” and that “TDD begins only after explicit artifact-bound Gate 2 approval” — but constitution 0.8.0 removed Gate 2, so the agent was being told to wait for an approval that no longer exists. The Meso Workflow Position line and the Tasks/TDD bullets now state that no human-approval gate sits between Tasks and Micro and that `deviate run` chains meso into micro end-to-end. Prompt-only change in `src/deviate/prompts/commands/deviate-tasks.md`, consistent with the constitution's Automated Advance invariant.
26
28
  - **RED phase now hard-fails when it produces no test files (`RED phase produced no test files`), instead of silently committing a vacuous 'failing test' commit.** Previously `_run_red_phase` skipped its test run entirely when `_find_test_files` returned empty, letting GREEN run against nothing and die in `TRAIN_EXHAUSTED` — a real stall. It now raises a `PhaseFailedError` naming `/deviate-execute` (DIRECT) or `/deviate-meso` re-sharding for tasks that legitimately need no code. It also treats a pytest-style exit code 5 (no tests collected) as a RED defect rather than a passing RED. The manual `deviate red post` `RedMustPassError` message now points the agent at the `failure_kind: already_satisfied` escape hatch instead of leading to an opaque crash. Pinned by the updated `_find_test_files`-mocked RED unit tests.
27
29
  - **Bare `deviate specify` now skips issues already claimed on a remote branch during auto-discovery.** Previously it auto-discovered the next unblocked BACKLOG issue via `select_next_unblocked_issue()` without checking the remote, so it could pick an issue whose `feat/{epic}/{issue}` branch already existed on `origin` (claimed elsewhere) and then hard-fail with `CLAIM_FAILED`. It now uses `_discover_claimable_issue()` — the same discovery `deviate meso run` uses — which skips issues whose branch is on the remote (or already COMPLETED) and reaches the next genuinely claimable one. When none remain it exits `NO_CLAIMABLE_ISSUES`. `deviate specify <id>` / `--local` explicit-claim behavior is unchanged. Pinned by `tests/test_meso/test_specify.py::TestSpecifySetup::test_specify_bare_arg_skips_remote_claimed_issue`.
28
30
  - **`deviate explore post` no longer writes ``FLOW_REFERENCED_BY_ISSUE`` events into ``specs/_product/flows.jsonl``.** The flows ledger never records issue-flow references — the referenced-by relationship is derived read-only at coverage time from ``specs/issues.jsonl::flow_refs`` (via ``load_flow_coverage``/``_latest_issue_reference``). `deviate explore post` (``_run_flow_ledger_cycle``) now renders the coverage report only; the macro-layer reverse-index helper ``_reverse_index_issue_flow_refs`` was removed. ``flows.jsonl`` still carries ``FLOW_DISCOVERED`` / ``FLOW_DOCUMENTED`` (from `deviate flows sync`), confirmation/evidence/release events (from merge/release), and deprecated events. Pinned by `tests/test_macro/test_explore.py::test_explore_post_never_writes_referenced_by_events`.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: deviatdd
3
- Version: 2.20.1
3
+ Version: 2.20.2
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "deviatdd"
3
- version = "2.20.1"
3
+ version = "2.20.2"
4
4
  description = "DeviaTDD CLI — agent orchestration framework"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -0,0 +1,150 @@
1
+ # Plan — Task Acceptance Traceability via acceptance_criteria Links
2
+
3
+ ## Plan Summary
4
+
5
+ - **Issue**: 005-002 — Task Acceptance Traceability via `acceptance_criteria` Links
6
+ - **Implementation Strategy**: This is a re-plan: prior `plan.md` was reviewed and refreshed against the completed issue `005-001`, whose `validate_acceptance_contract` (`src/deviate/core/validation.py:162`) now enforces one `**Verification Mode**` line per `AC-PLAN-NNN` scenario. Add a `CriterionLink` Pydantic model and an optional `acceptance_criteria: list[CriterionLink] | None` field to `TaskRecord` in `src/deviate/state/ledger.py`. Extend `generate_jsonl_from_md` and `_build_task_record` in `src/deviate/core/tasks_ledger.py` to parse per-task `**Acceptance Criteria**:` bullets from `tasks.md` and propagate the parsed links into each generated row. `CriterionLink` enforces the `AC-PLAN-\d{3}` id format, the three verification-mode literals, and the automated-link `test_ref` invariant, so malformed links fail generation with named errors. The field stays optional with default `None`, so legacy rows without the field parse under `model_config = {"extra": "forbid"}`.
7
+ - **Estimated Complexity**: Medium
8
+ - **Estimated Effort**: 2-4 hours
9
+
10
+ ## Product Layer Anchors
11
+
12
+ - **Flow References**: `[]`
13
+ - **Source**: `specs/005-acceptance-gates/issues/002-task-acceptance-traceability.md` (frontmatter field: `flow_refs`)
14
+ - **Release Context**: `specs/_product/release-next.md` Goal ships FLOW-04 (live-stream agent progress via subprocess RPC and a Rich TUI renderer capped at 10 lines). This issue is orthogonal; it hardens meso task-generation traceability, not the RPC/TUI transport.
15
+ - **Architecture Components Touched**: `C1` (the existing `deviate` CLI component; the `## Components` table C1 entry states it owns phase state, JSONL ledgers, and TOML config, which covers `src/deviate/state/ledger.py` and `src/deviate/core/tasks_ledger.py`)
16
+
17
+ ## Acceptance Contract
18
+
19
+ **Scenario AC-PLAN-001: Tasks.md criterion references propagate into generated task rows as acceptance_criteria links**
20
+ - **Source Outline**: `AO-002`
21
+ - **Upstream Traceability**: `US-005-03`, `FR-005-02`, `AC-005-02-01`
22
+ - **Current-Code Evidence**: `src/deviate/core/tasks_ledger.py:15`
23
+ - **Given**: a `tasks.md` whose task `TSK-005-01` carries an `**Acceptance Criteria**:` bullet that declares `AC-PLAN-001 (automated, tests/test_core/test_tasks_ledger.py)` and `AC-PLAN-002 (manual)`
24
+ - **When**: `generate_jsonl_from_md` runs on that `tasks.md`
25
+ - **Then**: the returned `TSK-005-01` `TaskRecord` carries an `acceptance_criteria` list whose two `CriterionLink` entries match the declared `criterion_id`, `verification_mode`, and `test_ref` values
26
+ - **Verification Mode**: automated
27
+
28
+ **Scenario AC-PLAN-002: A malformed criterion id or a missing test_ref on an automated link fails generation with a named error**
29
+ - **Source Outline**: `AO-002`
30
+ - **Upstream Traceability**: `US-005-03`, `FR-005-02`, `AC-005-02-01`
31
+ - **Current-Code Evidence**: `src/deviate/core/tasks_ledger.py:45`
32
+ - **Given**: a `tasks.md` whose task declares an `**Acceptance Criteria**:` bullet with a `criterion_id` outside the `AC-PLAN-\d{3}` pattern (for example `AC-PLAN-99`), or with an `automated` link whose `test_ref` is empty
33
+ - **When**: `generate_jsonl_from_md` runs on that `tasks.md`
34
+ - **Then**: generation raises a validation error whose message names the invalid `criterion_id` or the missing `test_ref`
35
+ - **Verification Mode**: automated
36
+
37
+ **Scenario AC-PLAN-003: A legacy task row without the acceptance_criteria field parses with the field absent under extra="forbid"**
38
+ - **Source Outline**: `AO-002`
39
+ - **Upstream Traceability**: `US-005-04`, `FR-005-02`, `AC-005-02-01`
40
+ - **Current-Code Evidence**: `src/deviate/state/ledger.py:81`
41
+ - **Given**: a `tasks.jsonl` row written by an older CLI version that carries `id`, `issue_id`, `description`, `status`, `execution_mode`, and `created_at` but no `acceptance_criteria` field
42
+ - **When**: `TaskRecord.model_validate` parses that row
43
+ - **Then**: the record parses with `acceptance_criteria` equal to `None`, and a row that carries a genuinely unknown field still fails validation
44
+ - **Verification Mode**: automated
45
+
46
+ **Scenario AC-PLAN-004: A task with no criterion references carries a null acceptance_criteria field, never an empty list**
47
+ - **Source Outline**: `AO-002`
48
+ - **Upstream Traceability**: `US-005-03`, `FR-005-02`, `AC-005-02-01`
49
+ - **Current-Code Evidence**: `src/deviate/state/ledger.py:97`
50
+ - **Given**: a `tasks.md` whose task `TSK-005-04` contains no `**Acceptance Criteria**:` bullet while a sibling task declares one
51
+ - **When**: `generate_jsonl_from_md` runs on that `tasks.md` and serializes the returned records
52
+ - **Then**: the record for `TSK-005-04` serializes `acceptance_criteria` as `null`, never as an empty list
53
+ - **Verification Mode**: automated
54
+
55
+ ## Workstation Mapping
56
+
57
+ - **`src/deviate/state/ledger.py:81-98`**: MODIFY — add the optional `acceptance_criteria: list[CriterionLink] | None = None` field to `TaskRecord`.
58
+ - **Current State**: `TaskRecord` (line 81) declares `id`, `issue_id`, `description`, `status` (seven-value `Literal`), `execution_mode`, `created_at`, and `security_profile`; `model_config = {"extra": "forbid"}` is at line 98. No `acceptance_criteria` field exists.
59
+ - **Changes Required**: Insert `acceptance_criteria: list[CriterionLink] | None = None` after the `security_profile` field, before `model_config`. Preserve `model_config = {"extra": "forbid"}` and the seven-value `status` `Literal` unchanged (PRD `RESOLVED-Q-004`).
60
+ - **Integration Surface**: `_build_task_record` (`src/deviate/core/tasks_ledger.py:45`) constructs the model; generated JSONL rows serialize via `append_task_record` (`src/deviate/state/ledger.py:181`); micro-phase runners parse rows via `TaskRecord.model_validate` (`src/deviate/cli/micro.py:1154,1259,1336,2524,3113,4437,4533,4806`).
61
+ - **`src/deviate/state/ledger.py`**: ADD — the `CriterionLink` Pydantic model.
62
+ - **Current State**: No `CriterionLink` type exists anywhere in the ledger module; `CriterionLink` appears only in the PRD/data-model schemas.
63
+ - **Changes Required**: Define `CriterionLink(BaseModel)` before `TaskRecord` with `criterion_id: str`, `verification_mode: Literal["automated", "manual", "deferred"]`, `test_ref: str | None = None`, and `model_config = {"extra": "forbid"}` (the ledger-family pattern; `SecurityProfile` at line 61-78 is the precedent). Add a `field_validator("criterion_id")` that rejects values that do not match `^AC-PLAN-\d{3}$`. Add a `model_validator(mode="after")` that raises when `verification_mode == "automated"` and `test_ref is None`. The data-model schema sketch (`specs/005-acceptance-gates/data-model.md:86-96`) shows the same field validator. `re` is already imported at line 4, so no new dependency is needed.
64
+ - **Integration Surface**: Embedded in `TaskRecord.acceptance_criteria`; validated per-link at model construction and at row parse.
65
+ - **`src/deviate/core/tasks_ledger.py:15`**: MODIFY — `generate_jsonl_from_md` propagates task-to-criterion and criterion-to-test links from `tasks.md` into each generated `TaskRecord`.
66
+ - **Current State**: The function scans task lines with `_TASK_LINE_PATTERN` (line 11), tracks `current_mode` from `**Mode**:` bullets, and appends `_build_task_record(current_id, issue_id, current_desc, current_mode)` per task. It has no awareness of criterion references.
67
+ - **Changes Required**: Add a `_CRITERIA_LINE_PATTERN` that matches `- **Acceptance Criteria**: <entries>` inside a task block and a `_LINK_PATTERN` that parses each comma-separated entry of the form `AC-PLAN-NNN (mode[, test_ref])`. Track `current_criteria` per task, reset on each new task line, and pass the collected entries to `_build_task_record`. The parse stays linear over the line list and adds no new dependencies (stdlib `re` only).
68
+ - **Integration Surface**: Consumed by `validate_tasks_jsonl` (`src/deviate/core/tasks_ledger.py:60`) and by the meso task-generation flow; the emitted rows serialize through `TaskRecord.model_dump_json`.
69
+ - **`src/deviate/core/tasks_ledger.py:45`**: MODIFY — `_build_task_record` carries the parsed links into the record.
70
+ - **Current State**: The helper builds `TaskRecord(id=..., issue_id=..., description=..., status="PENDING", execution_mode=...)` and returns it; no link handling exists.
71
+ - **Changes Required**: Accept the collected criteria entries (default empty), parse each entry with `_LINK_PATTERN`, and construct `CriterionLink` instances. An entry that fails `_LINK_PATTERN` raises a `ValueError` that names the offending text and the task id. A `criterion_id` outside `AC-PLAN-\d{3}`, a `verification_mode` outside the three literals, or an `automated` link with a null `test_ref` raises a `pydantic.ValidationError` from the `CriterionLink` validators, with the offending id or mode in the message. Pass `None` to `TaskRecord` when no links exist so the field serializes as `null`, never as `[]`.
72
+ - **Integration Surface**: `generate_jsonl_from_md` calls this helper once per task; `validate_tasks_jsonl` (line 60) stays the row-level validator and needs no structural change because `TaskRecord.model_validate` now owns the new field.
73
+ - **`src/deviate/core/tasks_ledger.py:60`**: REFERENCE — `validate_tasks_jsonl` stays the row-level validator.
74
+ - **Current State**: The function runs `TaskRecord.model_validate` per row and formats `Record {i}: {loc}: {msg}` errors; existing tests cover valid rows, invalid ids, missing fields, invalid status, and extra fields.
75
+ - **Changes Required**: None structurally. The new field flows through the existing validator because `TaskRecord` owns it; new tests assert that rows with valid links pass, rows with a malformed `criterion_id` or an `automated`-with-null-`test_ref` link produce errors whose `loc` names the link, and legacy rows pass unchanged.
76
+ - **Integration Surface**: Called by meso task-validation flows; error strings feed task-ledger inspection.
77
+ - **`specs/005-acceptance-gates/002-task-acceptance-traceability/tasks.md`**: TARGET — per-task criterion references (input artifact).
78
+ - **Current State**: The file does not exist yet; the tasks phase authors it. The sibling slice `specs/005-acceptance-gates/001-verification-mode-metadata/tasks.md` shows the bullet convention (per-task `**Mode**:`, `**Files**:`, `**Verification**:` bullets); no `tasks.md` anywhere in `specs/` carries an `**Acceptance Criteria**:` bullet today, so this plan pins the syntax.
79
+ - **Changes Required**: Each task that implements or verifies an `AC-PLAN-NNN` scenario declares one `- **Acceptance Criteria**:` bullet with comma-separated entries of the form `AC-PLAN-NNN (mode[, test_ref])`, where `mode` is `automated`, `manual`, or `deferred`. An `automated` entry includes the test path as `test_ref` (for example `AC-PLAN-001 (automated, tests/test_core/test_tasks_ledger.py)`). A task with no criterion references omits the bullet.
80
+ - **Integration Surface**: Parsed by `generate_jsonl_from_md`; the ids name `AC-PLAN-NNN` scenarios in this plan's `## Acceptance Contract`.
81
+ - **`deviate meso tasks pre`** (`src/deviate/cli/meso.py:939-1037`): GATE — emits the traced rows through the generation path and blocks on invalid links.
82
+ - **Current State**: `_tasks_pre` (line 939) validates the plan contract via `validate_acceptance_contract` at line 1004 (the 005-001 behavior, now at `src/deviate/core/validation.py:162`) and blocks on `PLAN_ACCEPTANCE_CONTRACT_INVALID` / `PLAN_ACCEPTANCE_CONTRACT_MISSING`; it does not itself rewrite rows. `_tasks_post` (line 1040) commits `tasks.md`. The meso flow consumes the generator in `src/deviate/core/tasks_ledger.py`.
83
+ - **Changes Required**: None in this issue. The defensive exclusion in the issue scope (`005-002` §Defensive Exclusions) forbids gate-behavior work here; gate behavior belongs to issues `005-003` and `005-004`. Invalid links fail inside `CriterionLink` construction, so any consumer of `generate_jsonl_from_md` raises before a row is appended.
84
+ - **Integration Surface**: The gate validates the contract whose ids `CriterionLink` references; the integration tier of this issue drives a fixture `tasks.md` through `generate_jsonl_from_md` and `validate_tasks_jsonl`, the exact code path `specs/005-acceptance-gates/data-model.md:190` documents (Flow: Acceptance Traceability, step 3).
85
+ - **`tests/test_core/test_tasks_ledger.py`**: TARGET — extend generation tests with link propagation and rejection.
86
+ - **Current State**: `TestGenerateJsonlFromMd` covers basic parsing (ids, issue ids, descriptions, modes, empty files); `TestValidateTasksJsonl` covers row-level rejections including the `extra="forbid"` case.
87
+ - **Changes Required**: Add propagation cases (single link, multiple links, mixed modes, `manual` without `test_ref`, `automated` with `test_ref`, a task without a bullet), rejection cases (malformed `criterion_id`, `automated` link with null `test_ref`, a `verification_mode` outside the literals, an unparseable entry), and the null-never-empty-list assertion. Extend `TestValidateTasksJsonl` with a valid-links row, a malformed-link row, and a legacy row without the field.
88
+ - **Integration Surface**: The functions under test are the same generator and row validator the meso flow consumes.
89
+ - **`tests/test_state/test_ledger.py`**: TARGET — extend `TaskRecord` parse tests; legacy rows without the field still parse.
90
+ - **Current State**: `TestTaskRecord` (line 150) covers creation, explicit status/mode, invalid status/mode, extra-field rejection, id format, empty description, and serialization round-trip; `TestAppendTaskRecord` covers append behavior.
91
+ - **Changes Required**: Add a round-trip test with a populated `acceptance_criteria` list, a legacy-row parse test (dict without the field yields `None`), a `CriterionLink` accept/reject set, and an `extra="forbid"` regression that a genuinely unknown field still fails. Keep append-only semantics intact (no rewrite of existing rows).
92
+ - **Integration Surface**: The model under test is the same `TaskRecord` the micro phase runners validate at `src/deviate/cli/micro.py:1154` and later.
93
+
94
+ ## Implementation Strategy
95
+
96
+ - **Phase 1**: `CriterionLink` model and the additive `TaskRecord` field
97
+ - **Files**: `src/deviate/state/ledger.py`, `tests/test_state/test_ledger.py`
98
+ - **Approach**: Add `CriterionLink(BaseModel)` before `TaskRecord` with `criterion_id`, `verification_mode: Literal["automated", "manual", "deferred"]`, `test_ref: str | None = None`, and `model_config = {"extra": "forbid"}`. Add a `field_validator("criterion_id")` matching `^AC-PLAN-\d{3}$` and a `model_validator(mode="after")` rejecting an `automated` link with a null `test_ref`. Add `acceptance_criteria: list[CriterionLink] | None = None` to `TaskRecord` after `security_profile`, before `model_config`. RED writes the round-trip, legacy-parse, extra-forbid, and `CriterionLink` accept/reject tests first.
99
+ - **Verification**: `uv run pytest tests/test_state/test_ledger.py -v`
100
+ - **Phase 2**: Link parsing and propagation in the generator
101
+ - **Files**: `src/deviate/core/tasks_ledger.py`, `tests/test_core/test_tasks_ledger.py`
102
+ - **Approach**: Add `_CRITERIA_LINE_PATTERN` for the `**Acceptance Criteria**:` bullet and `_LINK_PATTERN` for `AC-PLAN-NNN (mode[, test_ref])` entries. Track `current_criteria` inside `generate_jsonl_from_md`, reset per task, and pass it to `_build_task_record`. In `_build_task_record`, parse entries into `CriterionLink` instances; raise a named `ValueError` for unparseable entries and let the `CriterionLink` validators raise `pydantic.ValidationError` for malformed ids, illegal modes, and automated links without `test_ref`. Pass `None` when no links exist. RED writes the propagation and rejection tests first.
103
+ - **Verification**: `uv run pytest tests/test_core/test_tasks_ledger.py -v`
104
+ - **Phase 3**: Row-validator coverage and full check bundle
105
+ - **Files**: `tests/test_core/test_tasks_ledger.py`, `tests/test_state/test_ledger.py`
106
+ - **Approach**: Extend `TestValidateTasksJsonl` with valid-link, malformed-link, and legacy-row cases so `validate_tasks_jsonl` behavior is pinned without any structural change to it. Confirm the change touches only `ledger.py`, `tasks_ledger.py`, and their tests; run the full bundle. No CLI command in the new tests hits `_run_pytest`, so no `subprocess.CompletedProcess` mock is needed and the suite stays under 30 seconds.
107
+ - **Verification**: `uv run pytest tests/test_core/test_tasks_ledger.py tests/test_state/test_ledger.py -v`, then `mise run check`
108
+
109
+ ## Data Flow Analysis
110
+
111
+ 1. **Input**: `tasks.md` content is read by `generate_jsonl_from_md` (`src/deviate/core/tasks_ledger.py:16` via `Path.read_text`).
112
+ 2. **Extraction**: The scanner splits the content into lines; `_TASK_LINE_PATTERN` recognizes `TSK-\d{3}-\d{2}` task bullets; per-task `**Mode**:` and `**Acceptance Criteria**:` bullets accumulate on the current task.
113
+ 3. **Transformation**: `_build_task_record` converts each `**Acceptance Criteria**:` entry into a `CriterionLink` (`criterion_id`, `verification_mode`, optional `test_ref`) and constructs the `TaskRecord`; invalid entries raise `ValueError` or `pydantic.ValidationError` before any row is produced.
114
+ 4. **Output**: `TaskRecord.model_dump_json` serializes rows that carry `acceptance_criteria` when links exist and `"acceptance_criteria": null` when they do not; `append_task_record` (`src/deviate/state/ledger.py:181`) appends rows to `specs/**/tasks.jsonl` per the append-only protocol (`specs/constitution.md` §1).
115
+ 5. **Storage and consumption**: Micro-phase runners parse rows with `TaskRecord.model_validate` (`src/deviate/cli/micro.py:1154,1259,1336,2524,3113,4437,4533,4806`); rows without the field default to `None`, so mixed-version ledgers parse fully. `_read_ledger` (`src/deviate/state/ledger.py:41`) guards malformed JSONL lines with a warning instead of a crash.
116
+ 6. **Upstream constraint**: The `AC-PLAN-NNN` ids in `tasks.md` name scenarios in the owning slice's validated plan contract (`src/deviate/core/validation.py:162` `validate_acceptance_contract`, mode-enforced by `_validate_verification_mode` at `validation.py:139`); `deviate meso tasks pre` validates that contract at `src/deviate/cli/meso.py:1004` before generation, and this issue consumes the validated contract without re-checking (defensive exclusion).
117
+
118
+ ## Risk Assessment
119
+
120
+ | Risk | Impact | Likelihood | Mitigation |
121
+ |------|--------|------------|------------|
122
+ | `extra="forbid"` rejects older JSONL rows that lack the new field | High | Medium | Declare the field optional with default `None`; pin a legacy-row parse test; the design register mirrors this as `RSK-001` (`specs/005-acceptance-gates/design.md:63`). |
123
+ | Ambiguous or drifted `tasks.md` criterion syntax silently drops links | Medium | Medium | Pin the `**Acceptance Criteria**: AC-PLAN-NNN (mode[, test_ref])` syntax in this plan; the generator raises on unparseable entries instead of skipping them. |
124
+ | A `criterion_id` that matches `AC-PLAN-\d{3}` but names a criterion absent from the owning plan's contract escapes generation | Medium | Low | Documented boundary: `CriterionLink` validates the id pattern only; contract-level verification belongs to issue `005-001` and the micro/gate issues `005-003`/`005-004` (issue scope §Defensive Exclusions). No plan.md cross-check is added to the generator. |
125
+ | Generation-time error messages omit the offending link details | Low | Medium | Pydantic field/model validators pin named messages that include `criterion_id` and mode; tests assert the message substrings. |
126
+ | FLOW_CONTEXT_UNAVAILABLE — no existing flow mapping is available | Medium | Low | Preserve empty flow references and plan the application's requested behavior without creating flow or DeviaTDD setup work. |
127
+
128
+ ## Security Profile
129
+
130
+ Risk surfaces: file paths (reads `tasks.md` via `Path.read_text` — local read only), deserialization (`json.loads` on ledger rows in `_read_ledger`, already guarded by a try/except with a warning), and string fields (`criterion_id` and `test_ref` are plain strings; `test_ref` is never resolved or executed — existence checks are explicitly out of scope per the issue's Edge Cases).
131
+
132
+ Negative tests: a row with a genuinely unknown field still fails under `extra="forbid"`; a legacy row without the field parses with `acceptance_criteria` equal to `None`; an `automated` link without a `test_ref` fails generation; a `verification_mode` outside the three literals fails generation; an unparseable `**Acceptance Criteria**:` entry fails generation with a named error; a malformed JSONL line is skipped with a warning, never a crash.
133
+
134
+ Constraints: no new dependencies (stdlib `re` only); no hardcoded secrets; no changes to `src/deviate/core/validation.py`, `src/deviate/cli/micro.py`, `src/deviate/prompts/`, `specs/DeviaTDD-api.md`, `specs/DeviaTDD-architecture.md`, or `CHANGELOG.md` (defensive exclusions); no subprocess in the new tests; the full suite stays under 30 seconds.
135
+
136
+ ## Integration Points
137
+
138
+ - **`src/deviate/cli/meso.py:1004`** (`_tasks_pre` contract gate): validates the plan `## Acceptance Contract` via `validate_acceptance_contract` (`src/deviate/core/validation.py:162`) before task generation; the `AC-PLAN-NNN` ids this issue propagates refer to that contract. No change here (gate behavior belongs to issues `005-003`/`005-004`).
139
+ - **`src/deviate/cli/micro.py` phase runners** (`TaskRecord.model_validate` at lines 1154, 1259, 1336, 2524, 3113, 4437, 4533, 4806): parse new and legacy task rows; the additive field must not break any runner. `src/deviate/prompts/auto/red.md:64` already instructs RED to trace `{TASK_ID}` to its `AC-PLAN-NNN` references in `tasks.md`.
140
+ - **`src/deviate/cli/inspect.py:244`**: reads `tasks.jsonl` for task inspection; rows carrying the new field render without a schema change.
141
+ - **`src/deviate/core/validation.py:166`** (`contract_pattern`, `AC-PLAN-\d{3}`) and **`:162`** (`validate_acceptance_contract`): provide and enforce the id vocabulary `CriterionLink` references; this issue consumes the validated contract and does not modify it (defensive exclusion).
142
+ - **`specs/005-acceptance-gates/data-model.md`** (`TaskRecord` and `CriterionLink` entity tables, lines 84-110): the authoritative schema this issue implements; `acceptance_criteria` is additive with default `None` and `CriterionLink` embeds per the relationship table (line 77).
143
+ - **`src/deviate/prompts/commands/deviate-tasks.md:47`** and **`src/deviate/prompts/auto/tasks.md:70`**: tasks-phase prompts require every task to cite its `AC-PLAN-NNN` scenarios; the new bullet syntax aligns with that requirement (prompt-template alignment itself belongs to issue `005-005`).
144
+
145
+ ## Constitutional Alignment
146
+
147
+ - **Architecture**: The change sits in the Meso layer (task generation carries criteria traceability into `specs/**/tasks.jsonl` rows) and feeds the Micro layer (phase runners parse the additive field). It implements the `acceptance_criteria` field and `CriterionLink` schema from `specs/005-acceptance-gates/data-model.md` and satisfies the append-only ledger protocol of `specs/constitution.md` §1 — the field is additive, and no existing JSONL line is ever modified.
148
+ - **Testing**: pytest unit tests in `tests/test_core/test_tasks_ledger.py` and `tests/test_state/test_ledger.py`; coverage target stays at or above 80%; the new tests are pure unit tests that make no CLI and no git calls, so the full suite stays under the 30-second contract (`AGENTS.md` test-performance pointer). `mise run check` (lint, format-check, types, full suite) is the final gate.
149
+ - **Git Isolation**: The orchestrator commits at phase boundaries; this plan's tests use only `tmp_path` fixtures and make zero branch-mutating or `git` calls, so the git-isolation invariants and the append-only ledger protocol remain intact.
150
+ - **Product Layer**: `flow_refs` is `[]` per the issue frontmatter, mirrored verbatim in `## Product Layer Anchors`; the release Goal (FLOW-04, subprocess RPC/TUI) is orthogonal and untouched. This plan adds no Product-layer, DeviaTDD setup, skill, flow-authoring, or workflow-ledger work; it only hardens the requested application behavior (task-to-criterion and criterion-to-test traceability) that the meso generation path delivers.
@@ -0,0 +1,9 @@
1
+ {"id":"TSK-005-01","issue_id":"005-002","description":"`CriterionLink` model plus the additive `TaskRecord.acceptance_criteria` field, with model-level accept/reject tests","status":"RED","execution_mode":"TDD","created_at":"2026-08-16T09:30:50.760884Z","security_profile":null}
2
+ {"id":"TSK-005-01","issue_id":"005-002","description":"`CriterionLink` model plus the additive `TaskRecord.acceptance_criteria` field, with model-level accept/reject tests","status":"GREEN","execution_mode":"TDD","created_at":"2026-08-16T09:41:57.012207Z","security_profile":null}
3
+ {"id":"TSK-005-01","issue_id":"005-002","description":"`CriterionLink` model plus the additive `TaskRecord.acceptance_criteria` field, with model-level accept/reject tests","status":"JUDGE","execution_mode":"TDD","created_at":"2026-08-16T09:44:26.864774Z","security_profile":null}
4
+ {"id":"TSK-005-01","issue_id":"005-002","description":"`CriterionLink` model plus the additive `TaskRecord.acceptance_criteria` field, with model-level accept/reject tests","status":"COMPLETED","execution_mode":"TDD","created_at":"2026-08-16T09:44:26.864774Z","security_profile":null}
5
+ {"id":"TSK-005-02","issue_id":"005-002","description":"Criterion-link parsing and propagation inside `generate_jsonl_from_md` and `_build_task_record`","status":"RED","execution_mode":"TDD","created_at":"2026-08-16T10:45:30.117531Z","security_profile":null}
6
+ {"id":"TSK-005-02","issue_id":"005-002","description":"Criterion-link parsing and propagation inside `generate_jsonl_from_md` and `_build_task_record`","status":"GREEN","execution_mode":"TDD","created_at":"2026-08-16T10:56:18.114404Z","security_profile":null}
7
+ {"id":"TSK-005-02","issue_id":"005-002","description":"Criterion-link parsing and propagation inside `generate_jsonl_from_md` and `_build_task_record`","status":"JUDGE","execution_mode":"TDD","created_at":"2026-08-16T11:01:16.110814Z","security_profile":null}
8
+ {"id":"TSK-005-02","issue_id":"005-002","description":"Criterion-link parsing and propagation inside `generate_jsonl_from_md` and `_build_task_record`","status":"COMPLETED","execution_mode":"TDD","created_at":"2026-08-16T11:13:02.162546Z","security_profile":null}
9
+ {"id":"TSK-005-03","issue_id":"005-002","description":"Row-validator accept/reject cases for link rows plus the mixed-version append regression","status":"COMPLETED","execution_mode":"IMMEDIATE","created_at":"2026-08-16T13:06:59.617574Z","security_profile":null}
@@ -0,0 +1,113 @@
1
+ # Implementation Tasks: feat/005-acceptance-gates/002-task-acceptance-traceability
2
+
3
+ ## Phase 1: CriterionLink Model and Additive TaskRecord Field
4
+ **Goal**: `CriterionLink` exists as a pydantic model with the `AC-PLAN-\d{3}` id format, the three verification-mode literals, and the automated-link `test_ref` invariant. `TaskRecord` gains the optional `acceptance_criteria: list[CriterionLink] | None = None` field while preserving `model_config = {"extra": "forbid"}` and the seven-value `status` Literal.
5
+
6
+ ### Tasks
7
+
8
+ - TSK-005-01: `CriterionLink` model plus the additive `TaskRecord.acceptance_criteria` field, with model-level accept/reject tests
9
+ - **Type**: Feature_Batch
10
+ - **Mode**: TDD
11
+ - **Test Strategy**: Sociable_Unit
12
+ - **Verification**: `uv run pytest tests/test_state/test_ledger.py -v`
13
+ - **Estimated Time**: 60 minutes
14
+ - **Flow References**: []
15
+ - **Acceptance Criteria**: AC-PLAN-002 (automated, tests/test_state/test_ledger.py), AC-PLAN-003 (automated, tests/test_state/test_ledger.py), AC-PLAN-004 (automated, tests/test_state/test_ledger.py)
16
+ - **Files**:
17
+ - `src/deviate/state/ledger.py`
18
+ - `tests/test_state/test_ledger.py`
19
+ - **Rationale**: US-005-04 requires legacy task rows without the new field to parse under `extra="forbid"`; US-005-03 requires each emitted row to carry valid links. This task owns the model layer: `CriterionLink` (new) and `TaskRecord.acceptance_criteria` (additive) in `src/deviate/state/ledger.py`, the single schema that `generate_jsonl_from_md` and the micro-phase runners (`src/deviate/cli/micro.py` `TaskRecord.model_validate` sites) share. `tests/test_state/test_ledger.py` pins AC-PLAN-003 (legacy row parses with `acceptance_criteria` equal to `None`), AC-PLAN-004 (serialization emits `null`, never `[]`), and the AC-PLAN-002 rejection half that lives at model construction (malformed `criterion_id`, `automated` without `test_ref`).
20
+ - **Details**:
21
+ - **Red**: Add `TestCriterionLink` to `tests/test_state/test_ledger.py` covering: accept a `manual` link with `test_ref` absent; accept a `deferred` link with `test_ref` absent; accept `manual` or `deferred` with `test_ref` present; reject `automated` without `test_ref` asserting the message names the missing `test_ref`; reject `criterion_id` `AC-PLAN-99` asserting the message names the id; reject `verification_mode` `soon`; reject an unknown field on the link under `extra="forbid"`. Extend `TestTaskRecord` with: the field defaults to `None` when omitted; a populated `acceptance_criteria` list round-trips through `model_dump_json` and `model_validate`; a legacy dict carrying `id`, `issue_id`, `description`, `status`, `execution_mode`, `created_at` and no `acceptance_criteria` parses with the field equal to `None`; `json.loads(record.model_dump_json())["acceptance_criteria"] is None` (never `[]`) when no links exist; a genuinely unknown field such as `unknown_field` still raises under `extra="forbid"`.
22
+ - **Green**: In `src/deviate/state/ledger.py`, define `CriterionLink(BaseModel)` before `TaskRecord` and after `SecurityProfile`, matching the ledger-family pattern, with `criterion_id: str`, `verification_mode: Literal["automated", "manual", "deferred"]`, `test_ref: str | None = None`, and `model_config = {"extra": "forbid"}`. Add a `field_validator("criterion_id")` that raises `ValueError(f"Invalid criterion ID format: {v}")` unless `re.match(r"^AC-PLAN-\d{3}$", v)`; `re` is already imported at ledger.py line 4. Add a `model_validator(mode="after")` that raises when `verification_mode == "automated"` and `test_ref is None`. Add `acceptance_criteria: list[CriterionLink] | None = None` to `TaskRecord` after the `security_profile` field and before `model_config`; preserve the seven-value `status` Literal and `model_config = {"extra": "forbid"}` unchanged (PRD `RESOLVED-Q-004`).
23
+ - **Refactor**: Follow the `SecurityProfile` precedent (lines 61-78) for the validator and config pattern. Keep the validator messages named so tests can assert message substrings. Preserve deterministic field order.
24
+ - **Edge Cases**: An `automated` link with `test_ref=""` fails — treat the empty string as missing. A `manual` or `deferred` link with `test_ref` present passes. Extra fields on the link or on the record fail under `extra="forbid"`.
25
+ - **Acceptance**: `uv run pytest tests/test_state/test_ledger.py -v` passes. Rows generated by later phases serialize `"acceptance_criteria": null` when a task declares no links, and a populated list otherwise.
26
+
27
+ ## Phase 2: Link Parsing and Propagation in the Generator
28
+ **Goal**: `generate_jsonl_from_md` reads per-task `- **Acceptance Criteria**:` bullets from `tasks.md`, parses each `AC-PLAN-NNN (mode[, test_ref])` entry, and emits every generated `TaskRecord` with its `acceptance_criteria` links. Malformed entries, illegal modes, and `automated` links without `test_ref` fail generation with named errors.
29
+
30
+ ### Tasks
31
+
32
+ - TSK-005-02: Criterion-link parsing and propagation inside `generate_jsonl_from_md` and `_build_task_record`
33
+ - **Type**: Feature_Batch
34
+ - **Mode**: TDD
35
+ - **Test Strategy**: Sociable_Unit
36
+ - **Verification**: `uv run pytest tests/test_core/test_tasks_ledger.py -v`
37
+ - **Estimated Time**: 90 minutes
38
+ - **Flow References**: []
39
+ - **Acceptance Criteria**: AC-PLAN-001 (automated, tests/test_core/test_tasks_ledger.py), AC-PLAN-002 (automated, tests/test_core/test_tasks_ledger.py), AC-PLAN-004 (automated, tests/test_core/test_tasks_ledger.py)
40
+ - **Dependency**: TSK-005-01
41
+ - **Files**:
42
+ - `src/deviate/core/tasks_ledger.py`
43
+ - `tests/test_core/test_tasks_ledger.py`
44
+ - **Rationale**: US-005-03 requires the generator to emit each task row with its `acceptance_criteria` links so the task points at the criteria it satisfies and the tests that verify them. AC-PLAN-001 pins the propagation (its Given names task `TSK-005-01` carrying two links, which is this slice's own first task), AC-PLAN-002 pins generation-time rejection of malformed `criterion_id` values and of `automated` links with a missing `test_ref`, and AC-PLAN-004 pins the null-never-empty-list behavior at the generation boundary. `src/deviate/core/tasks_ledger.py` is the generator that `deviate meso tasks pre` and `validate_tasks_jsonl` consume; `tests/test_core/test_tasks_ledger.py` is its unit-level contract.
45
+ - **Details**:
46
+ - **Red**: In `tests/test_core/test_tasks_ledger.py`, extend `TestGenerateJsonlFromMd` with `tmp_path` fixtures. Propagation: a task line followed by `- **Acceptance Criteria**: AC-PLAN-001 (automated, tests/test_core/test_tasks_ledger.py), AC-PLAN-002 (manual)` yields a record whose `acceptance_criteria` list holds two `CriterionLink` entries matching the declared `criterion_id`, `verification_mode`, and `test_ref` values, with `test_ref` equal to `None` for the `manual` entry. Null-never-empty: a sibling task with no bullet carries `acceptance_criteria is None`. Rejection: `AC-PLAN-99 (automated, tests/test_core/test_tasks_ledger.py)` raises with the invalid id named; `AC-PLAN-001 (automated)` without `test_ref` raises with the missing `test_ref` named; `AC-PLAN-001 (soon)` raises; an unparseable entry such as `AC-PLAN-001 automated` raises a `ValueError` that names the offending text and the task id. Assert the propagated ids reference `AC-PLAN-NNN` scenarios from this plan's `## Acceptance Contract`.
47
+ - **Green**: In `src/deviate/core/tasks_ledger.py`, add `_CRITERIA_LINE_PATTERN` matching `- **Acceptance Criteria**: <entries>` within a task block and `_LINK_PATTERN` matching `AC-PLAN-\d{3} \((automated|manual|deferred)(?:,\s*(\S+))?\)`. Track `current_criteria: list[str]` in `generate_jsonl_from_md`, reset it to `[]` on each new `_TASK_LINE_PATTERN` match, accumulate the entries text on a criteria-line match, and pass the collected entries to `_build_task_record` at both append sites (line 27 and line 39). In `_build_task_record`, accept the criteria entries (default empty), split them on top-level commas — commas inside the parenthesized entry must not split — and construct `CriterionLink` instances per entry; a fragment that fails `_LINK_PATTERN` raises `ValueError` naming the fragment and the task id; malformed ids, illegal modes, and `automated` links with a null `test_ref` raise `pydantic.ValidationError` from the `CriterionLink` validators. Pass `None` to `TaskRecord` when no links exist so the field serializes as `null`, never as `[]`. Add no new dependencies (stdlib `re` only).
48
+ - **Refactor**: Keep the scan linear over the line list exactly as today. Reuse the existing `current_id` / `current_desc` / `current_mode` accumulation pattern for `current_criteria`.
49
+ - **Edge Cases**: A criteria bullet that appears before the task's `**Mode**:` bullet still attaches to the current task. An `automated` entry with an empty `test_ref` (`AC-PLAN-001 (automated, )`) fails. `manual` and `deferred` entries with `test_ref` present pass. Whitespace around ids and modes is tolerated by the pattern. A `criterion_id` that matches `AC-PLAN-\d{3}` but names a criterion absent from the owning plan's contract is a documented boundary — no plan.md cross-check is added here (defensive exclusion).
50
+ - **Acceptance**: `uv run pytest tests/test_core/test_tasks_ledger.py -v` passes. Generation error messages name the invalid `criterion_id` or the missing `test_ref`. A row with links serializes `"acceptance_criteria": [{"criterion_id": ..., "verification_mode": ..., "test_ref": ...}]`.
51
+
52
+ ## Phase 3: Row-Validator Coverage and Full Check Bundle
53
+ **Goal**: `validate_tasks_jsonl` behavior with link rows is pinned with no structural change to it, mixed-version ledgers append and parse intact, and the full check bundle exits green.
54
+
55
+ ### Tasks
56
+
57
+ - TSK-005-03: Row-validator accept/reject cases for link rows plus the mixed-version append regression
58
+ - **Type**: Verification_Batch
59
+ - **Mode**: IMMEDIATE
60
+ - **Test Strategy**: Sociable_Unit
61
+ - **Verification**: `uv run pytest tests/test_core/test_tasks_ledger.py tests/test_state/test_ledger.py -v` then `mise run check`
62
+ - **Estimated Time**: 60 minutes
63
+ - **Flow References**: []
64
+ - **Acceptance Criteria**: AC-PLAN-001 (automated, tests/test_core/test_tasks_ledger.py), AC-PLAN-002 (automated, tests/test_core/test_tasks_ledger.py), AC-PLAN-003 (automated, tests/test_state/test_ledger.py)
65
+ - **Dependency**: TSK-005-02
66
+ - **Files**:
67
+ - `tests/test_core/test_tasks_ledger.py`
68
+ - `tests/test_state/test_ledger.py`
69
+ - **Rationale**: US-005-03 and US-005-04 both terminate in the row-level validator and ledger consumption. `validate_tasks_jsonl` (`src/deviate/core/tasks_ledger.py:60`) stays structurally unchanged — `TaskRecord.model_validate` owns the new field — but its behavior with link rows must be pinned so mixed-version ledgers never break the micro-phase runners. AC-PLAN-001 (a row with valid links passes), AC-PLAN-002 (a row whose link is malformed produces an error whose `loc` names the link), AC-PLAN-003 (a legacy row without the field passes). `tests/test_state/test_ledger.py` receives the mixed-version append case proving append-only semantics with the new field.
70
+ - **Details**:
71
+ - **Red**: Extend `TestValidateTasksJsonl` in `tests/test_core/test_tasks_ledger.py`: a row with a valid `acceptance_criteria` list passes with `errors == []`; a row whose link carries `criterion_id: "AC-PLAN-99"` returns an error whose `loc` names `acceptance_criteria`; a row whose `automated` link lacks `test_ref` returns an error naming `acceptance_criteria`; a legacy row without the field passes; a row that carries `acceptance_criteria` plus a genuinely unknown field still fails. In `tests/test_state/test_ledger.py`, extend `TestAppendTaskRecord`: append a legacy task row, then append a task record carrying links, then read the file back — both rows are present and unchanged, each line is appended (append-only protocol, constitution §1), and each parsed row carries the field respectively as `None` and as the populated list.
72
+ - **Green**: No production change. `CriterionLink` (TSK-005-01) and the generator (TSK-005-02) already produce the rows these tests exercise; `validate_tasks_jsonl` and `append_task_record` pass them through. Run the new tests against the committed implementation and confirm `git status` shows no modification to `src/deviate/cli/meso.py` or `src/deviate/core/validation.py`.
73
+ - **Refactor**: Reuse the dict-based record style of the existing `TestValidateTasksJsonl` cases. Keep fixture records minimal. Assert on `loc` substrings rather than full message text.
74
+ - **Edge Cases**: A malformed JSONL line in the append-read path is skipped with a warning, never a crash (existing `_read_ledger` guard). Mixed-version rows parse fully with the field present or absent. The append stays idempotent on the `(id, status)` compound key.
75
+ - **Acceptance**: `uv run pytest tests/test_core/test_tasks_ledger.py tests/test_state/test_ledger.py -v` passes, then `mise run check` (lint, format-check, types, full suite) exits 0. The complete diff touches only `src/deviate/state/ledger.py`, `src/deviate/core/tasks_ledger.py`, `tests/test_core/test_tasks_ledger.py`, and `tests/test_state/test_ledger.py`.
76
+
77
+ ---
78
+
79
+ ## Implementation Strategy
80
+ **Execution Order**:
81
+ 1. Phase 1 -> Phase 2 -> Phase 3 (logical dependency order)
82
+
83
+ **Critical Dependency Chains**:
84
+ - TSK-005-01 must precede TSK-005-02 (`_build_task_record` constructs `CriterionLink` instances and sets `TaskRecord.acceptance_criteria`, both defined by TSK-005-01 in `src/deviate/state/ledger.py`)
85
+ - TSK-005-02 must precede TSK-005-03 (TSK-005-03 pins row-validator behavior that exists only after the model field and the generator propagation land)
86
+
87
+ **Risk Hotspots**:
88
+ - `extra="forbid"` rejects older JSONL rows that lack the new field. The field is optional with default `None`, and a legacy-row parse test pins the behavior; the design register mirrors this as `RSK-001` (`specs/005-acceptance-gates/design.md:63`).
89
+ - Ambiguous or drifted `tasks.md` criterion syntax silently drops links. The `**Acceptance Criteria**: AC-PLAN-NNN (mode[, test_ref])` syntax is pinned in this plan, and the generator raises on unparseable entries instead of skipping them.
90
+ - `_LINK_PATTERN` entry splitting must respect parentheses: the `test_ref` comma sits inside `(...)`, so splitting the bullet on bare commas would break entries.
91
+ - A `criterion_id` that matches `AC-PLAN-\d{3}` but names a criterion absent from the owning plan's contract escapes generation by design; contract-level verification belongs to issues `005-001`, `005-003`, and `005-004` (issue scope Defensive Exclusions).
92
+
93
+ **Merge Conflict Boundaries**:
94
+ - `tests/test_core/test_tasks_ledger.py` is touched by TSK-005-02 (extends `TestGenerateJsonlFromMd`) and TSK-005-03 (extends `TestValidateTasksJsonl`). The edits target different classes; the tasks run sequentially.
95
+ - `tests/test_state/test_ledger.py` is touched by TSK-005-01 (adds `TestCriterionLink`, extends `TestTaskRecord`) and TSK-005-03 (extends `TestAppendTaskRecord`). The edits do not overlap.
96
+ - `src/deviate/state/ledger.py` is touched only by TSK-005-01.
97
+
98
+ **Product-Layer Anchors** (mirrored from plan.md):
99
+ - **Flow References**: `[]`
100
+ - **Source**: `specs/005-acceptance-gates/002-task-acceptance-traceability/plan.md`
101
+ - Downstream micro phases inherit this list per-task. Empty references mean no matching existing flow, not permission for enabling, setup, tooling, skill, release, or workflow-ledger tasks.
102
+
103
+ ---
104
+
105
+ ## Universal Test Constraints (ALL TASKS)
106
+
107
+ - **Git Isolation Mandatory**: Any test that invokes git operations MUST operate on a temporary directory initialized as a fresh git repo. Tests MUST NOT run git commands within the real repository's working tree.
108
+ - **Implementation Pattern**: Use a shared `tmp_git_repo` fixture from `tests/conftest.py`. Pass `repo=tmp_git_repo` to all git-interacting functions. Never reference `Path.cwd()` or the real repo root.
109
+ - **Rationale**: Prevent accidental commits, branch creation, or state mutation in the actual project repo during test execution.
110
+
111
+ ## Universal API Design Constraint (ALL CORE MODULES)
112
+
113
+ Every git-interacting function in core modules MUST accept an optional `repo_path: Path | None = None` parameter. When `None`, default to `Path.cwd()`.
@@ -0,0 +1,139 @@
1
+ ---
2
+ title: "Single-Source Prompt Templates — Auto Canonical, Manual Derived at Install"
3
+ labels: [refactor, adhoc, vertical-slice, prompts, single-source]
4
+ blocked_by: []
5
+ coordinates_with: ["ISS-ADH-013"]
6
+ issue_id: ISS-ADH-016
7
+ flow_refs: []
8
+ ---
9
+
10
+ ## System Topology Mapping
11
+
12
+ - **Epic Target Domain**: `specs/adhoc/`
13
+ - **Local Issue File**: `specs/adhoc/issues/016-single-source-prompt-templates.md`
14
+ - **Primary Architectural Workstations**:
15
+ - `src/deviate/prompts/assembly.py:48-107` — TARGET: `load_template` composes the auto prompt from `core/core.md` + `core/{layer}-shared.md` + `core/lifecycle-auto.md` + `core/style-ste.md` + `auto/{phase}.md`. The canonical per-phase body already lives in `auto/`; `load_template` is the auto derivation path and must keep emitting the core body only.
16
+ - `src/deviate/core/commands.py:55-133` — TARGET: `compose_command_body` prepends core/layer/lifecycle-manual/style to a manual command body. This is the manual derivation path. Rewire so the manual slash-command body is derived from the canonical `auto/{phase}.md` + a per-phase manual overlay instead of a hand-maintained duplicate file.
17
+ - `src/deviate/core/commands.py:189-243` — TARGET: `install_command` reads `commands/deviate-{phase}.md` source, composes, and writes to the agent command dir. Must instead read the canonical `auto/{phase}.md` and derive the manual body.
18
+ - `src/deviate/prompts/auto/{red,green,refactor,judge,execute,plan,tasks,explore,research,prd,shard}.md` — CANONICAL SOURCE: the 11 overlapping phase bodies. These hold the single source of truth; reconcile the drifted middle to the auto semantics.
19
+ - `src/deviate/prompts/commands/deviate-{red,green,refactor,judge,execute,plan,tasks,explore,research,prd,shard}.md` — STALE DUPLICATES: hand-maintained manual copies that drift from auto (17-68% identical-line rate). Their manual-only content (pre/post-script steps, rich handover manifest, `<context><user_input>`) becomes a derivation overlay; the duplicated middle body is removed from these files.
20
+ - `src/deviate/prompts/core/lifecycle-auto.md` — REFERENCE: the auto lifecycle block ("orchestrator handles all lifecycle").
21
+ - `src/deviate/prompts/core/lifecycle-manual.md` — REFERENCE: the manual lifecycle block ("run `deviate <phase> pre/post`").
22
+ - `tests/test_meso/test_auto_prompt_templates.py` — TARGET: pin canonical auto semantics; add drift-guard coverage.
23
+ - `tests/test_meso/test_prompt_assembly.py` — TARGET: verify auto composition still emits core only.
24
+ - `tests/test_core/test_commands.py` — TARGET: rework `install_command`/`compose_command_body` assertions to the derived-manual output; add a drift-guard asserting the derived manual equals the committed behavior and the middle stays identical across modes.
25
+ - `CHANGELOG.md` — TARGET: append a bullet under `[Unreleased]` for the user-visible template-derivation change.
26
+ - `specs/DeviaTDD-api.md`, `specs/DeviaTDD-architecture.md` — TARGET: reflect the single-source prompt architecture and the derivation mechanism (spec-alignment mandate).
27
+ - **Upstream Evidence**:
28
+ - Git `420f65f` (2026-08-18) — redesigned auto/red only: `status:"PASS"` + `failure_kind` discriminator routed to JUDGE; the manual `status:"FAIL"` never back-ported. Proves auto is the living behavior.
29
+ - Git `64f9957` — per-epic issue-id change landed on `deviate-shard.md` only; auto/shard retained global ISS-NNN.
30
+ - `src/deviate/cli/micro.py:211` — RED task state sourced from `tasks.jsonl` (`status == "PENDING"`), confirming ledger-authoritative wording.
31
+ - `src/deviate/cli/meso.py:938`, `src/deviate/core/validation.py:260` — task-id validator enforces `TSK-\d{3}-\d{2}`, confirming the auto format over the manual's `T001`.
32
+ - `src/deviate/prompts/commands/deviate-red.md` vs `src/deviate/prompts/auto/red.md` — representative pair showing the drift.
33
+
34
+ ## The Problem Contract
35
+
36
+ DeviaTDD maintains two parallel prompt copies per phase (`auto/<phase>.md` for the CLI-orchestrated micro runner, `commands/deviate-<phase>.md` for manual slash commands). A drift audit found the copies disagree on 17%-68% of lines, including contradictory handover manifests (RED `status:"PASS"` vs `status:"FAIL"`) and contradictory role instructions (GREEN "write only production code" vs "maintain existing functional signatures"). The intended design is a shared middle body with only start/end lifecycle differing, but the copies have diverged badly because contributors edit both by hand. The micro runner is the only path the operator runs (manual phases are long-unused), so **auto is the living behavior**. This issue makes `auto/<phase>.md` the single canonical body, derives the manual slash-command from it at install time, reconciles the drifted middle to auto semantics, deletes the duplicated manual bodies, and adds a drift guard so the middle can never diverge again.
37
+
38
+ ## Scope Boundaries
39
+
40
+ ### Hard Inclusions
41
+ - **Auto is canonical** for all 11 overlapping phases. Reconcile each pair's drifted middle to the auto semantics. GREEN role language resolves to auto: "write ONLY production code (minimal change so that RED works)" — not "maintain existing functional signatures".
42
+ - Rewire `install_command`/`compose_command_body` so the manual slash-command body is derived from `auto/{phase}.md` + a per-phase manual overlay (pre/post-script lifecycle steps, rich handover manifest, `<context><user_input>` block), not from a hand-maintained duplicate.
43
+ - `load_template` keeps emitting the auto core body only (unchanged middle).
44
+ - Delete the 11 duplicated middle bodies from `commands/deviate-{phase}.md` (the overlapping set). Retain only the frontmatter + manual overlay, or remove the files if the overlay lives elsewhere.
45
+ - Add a drift-guard test asserting: (a) the derived manual command equals the committed manual behavior, and (b) the shared middle body is identical between auto and manual composition.
46
+ - Update `specs/DeviaTDD-api.md` and `specs/DeviaTDD-architecture.md` in the same commit (spec-alignment mandate).
47
+ - Append a `CHANGELOG.md` `[Unreleased]` bullet for the user-visible template-derivation change.
48
+
49
+ ### Defensive Exclusions
50
+ - Do NOT change the 15 commands-only prompts (adhoc, architecture, constitution, e2e, flows, hotfix, html, init, merge, pr, prune, release, review, triage, walkthrough). They have no auto counterpart and stay hand-maintained.
51
+ - Do NOT change the micro-runner behavior in `src/deviate/cli/micro.py` — the runner already consumes `auto/` templates.
52
+ - Do NOT modify `core/{layer}-shared.md`, `core/core.md`, or `core/style-ste.md` shared preambles.
53
+ - Do NOT regenerate `specs/_product/` flow artifacts; `flow_refs: []` (no existing flow covers prompt templating).
54
+ - Do NOT touch `~/.config/opencode/skills/` or any consumer-installed command directory (read-only install mirrors).
55
+ - Do NOT upgrade the product/governance command bodies or Graphite integration.
56
+ - Do NOT add tests that invoke `deviate.cli.micro._run_pytest` without mocking it (AGENTS.md test-performance mandate).
57
+ - Do NOT add `prompt`- or LLM-backed content generation during derivation — the manual overlay is static text, deterministic string composition only.
58
+
59
+ ## Upstream Requirement Tracing
60
+
61
+ - **Requirements Tokens**: `FR-ADHOC-016`
62
+ - **Acceptance Criteria Tokens**: `AC-ADHOC-016-01` through `AC-ADHOC-016-04`
63
+ - **Data Model Entities**: none (no new persistent ledger models)
64
+ - **Spec Source Anchors**:
65
+ - `specs/constitution.md:10` — Append-Only Ledger Protocol (unaffected)
66
+ - `src/deviate/cli/micro.py:211` — RED task state sourced from `tasks.jsonl`
67
+ - `src/deviate/cli/meso.py:938`, `src/deviate/core/validation.py:260` — `TSK-\d{3}-\d{2}` task-id validator
68
+
69
+ ## User Stories Ledger
70
+
71
+ - **US-016-01**: As a DeviaTDD maintainer, I want a single canonical per-phase prompt body (auto) with the manual slash-command derived at install time, so I edit the middle body once instead of maintaining two drift-prone copies. *(Ref: FR-ADHOC-016)*
72
+ - **US-016-02**: As a DeviaTDD maintainer, I want the drifted middle reconciled to auto semantics (including GREEN "write only production code" and the PASS/failure_kind RED handover), so both modes no longer instruct contradictory behavior. *(Ref: FR-ADHOC-016)*
73
+ - **US-016-03**: As a DeviaTDD maintainer, I want a drift-guard test that fails when the auto and manual middle bodies diverge, so the identical-middle invariant is enforced rather than trusted. *(Ref: FR-ADHOC-016)*
74
+
75
+ ## Acceptance Outline
76
+
77
+ - **AO-016** *(Ref: AC-ADHOC-016-01, US-016-01)*: For every one of the 11 overlapping phases, `install_command` derives the manual slash-command body from `auto/{phase}.md` plus the manual overlay, with a middle body identical to the auto core.
78
+ - **Happy Path**: `deviate setup` produces a `deviate-{phase}.md` whose middle (role, mandates, execution steps, edge cases) matches `auto/{phase}.md`; only the lifecycle start/end (pre/post scripts), the contract-input substitution, and the rich handover manifest differ.
79
+ - **Error Category**: A phase pair whose middle diverges fails the drift-guard test with a diff.
80
+ - **Boundary Category**: The derivation composes static text deterministically; no LLM or `prompt` content generation.
81
+ - **AO-016** *(Ref: AC-ADHOC-016-02)*: The drifted middle is reconciled to auto semantics.
82
+ - **Happy Path**: RED manual no longer states `status:"FAIL"`/abort-on-passing-test; it matches auto's `status:"PASS"` + `failure_kind`. GREEN manual matches auto's "write only production code".
83
+ - **Error Category**: Any residual contradictory role instruction or handover status fails review.
84
+ - **AO-016** *(Ref: AC-ADHOC-016-03)*: The drift-guard test exists and fails on divergence.
85
+ - **Happy Path**: Adding an unrelated line to an auto middle body makes the drift-guard test fail until the manual derivation is updated.
86
+ - **Boundary Category**: The 15 commands-only prompts are exempt from the identical-middle invariant.
87
+
88
+ ## Edge Cases and Boundaries
89
+
90
+ - **Manual-only phase steps**: The manual overlay (pre/post-script, rich manifest, `<context><user_input>`) must live outside the shared middle so it does not leak into the auto core.
91
+ - **Meso/macro structural divergence**: plan/tasks use `<step>` structure in auto but numbered steps in manual; research manual has `reduce_phase`/`interactive_hitl_gate_1`/`constitution_bootstrap`/`html_artifact` steps auto lacks. Reconcile per-phase before deriving — do not uniform-inject.
92
+ - **Field-name drift**: plan auto `{plan_path}` vs manual `plan_target`; tasks auto `TSK-{NNN}-{NN}` vs manual `T001`. Resolve to the runner-enforced format (`TSK-\d{3}-\d{2}` per `meso.py:938`).
93
+ - **Command-only frontmatter**: the manual files carry `name`/`description`/`layer` frontmatter the auto files lack. Preserve frontmatter in the derived manual output.
94
+ - **Idempotent install**: `install_command` must return `False` when the on-disk derived command already matches, preserving the existing idempotency contract (`test_install...` graphite suite).
95
+ - **Greenfield constitution absence**: derivation must tolerate a missing `specs/constitution.md` exactly as today (non-fatal).
96
+
97
+ ## Performance Constraints
98
+
99
+ - **L_max (`deviate setup` install)**: ≤ 500ms above existing `deviate setup` init (matches AGENTS.md L_max ≤ 500ms init gate). Derivation is deterministic string composition — no I/O beyond reading the canonical template and writing the derived command.
100
+ - **Full test suite**: `mise run test` remains < 30s per AGENTS.md performance mandate. New drift-guard test must read the two source files + invoke `install_command` against a `tmp_path` (no `_run_pytest`).
101
+ - **File size impact**: net reduction — the 11 duplicated middle bodies (each 5-30KB) shrink to overlays.
102
+
103
+ ## Multi-Tiered Verification Targets
104
+
105
+ - **Unit Sandbox Targets**:
106
+ - `tests/test_core/test_commands.py` — rework `install_command`/`compose_command_body` tests to assert the *derived* manual output (middle equals auto core + overlay), and that the on-disk idempotency contract (`False` on unchanged reinstall) still holds.
107
+ - `tests/test_meso/test_auto_prompt_templates.py` — extend with: `test_auto_and_manual_middle_identical` (drift guard) asserting the shared middle body is byte-identical between the auto core and the derived manual; `test_auto_red_uses_pass_failure_kind` asserting auto red's `failure_kind` semantics; `test_manual_red_matches_auto_semantics` asserting the derived red no longer emits `status:"FAIL"`/abort-on-passing-test.
108
+ - `tests/test_meso/test_prompt_assembly.py` — verify `load_template` still emits the auto core body only (core + layer + lifecycle-auto + style + phase), no manual overlay leakage.
109
+ - **Integration Sandbox Targets**:
110
+ - `tests/cli/test_setup.py` (if present) — verify `deviate setup` installs a derived `deviate-red.md` matching the expected composed body.
111
+ - `tests/e2e/` (bats) — optional smoke test: run install, assert derived manual middle equals auto core.
112
+
113
+ ## Demonstration Path
114
+ ```bash
115
+ # 1. Run the drift audit on the current pair (before migration requires auto canonical)
116
+ diff <(tr -s ' \n' < src/deviate/prompts/auto/red.md) \
117
+ <(sed '1,/^---$/d' src/deviate/prompts/commands/deviate-red.md | tr -s ' \n') | head
118
+
119
+ # 2. After wiring, prove the derived manual middle equals the auto core
120
+ uv run python -c "
121
+ from deviate.core.commands import install_command
122
+ import tempfile, pathlib
123
+ d = tempfile.mkdtemp()
124
+ install_command('deviate-red', pathlib.Path(d))
125
+ print((pathlib.Path(d)/'deviate-red.md').exists())
126
+ "
127
+
128
+ # 3. Run the drift-guard and loader tests
129
+ mise run test tests/test_core/test_commands.py -v
130
+ mise run test tests/test_meso/test_auto_prompt_templates.py -v
131
+ mise run test tests/test_meso/test_prompt_assembly.py -v
132
+
133
+ # 4. Lint and format
134
+ mise run lint
135
+ mise run format-check
136
+
137
+ # 5. Full suite
138
+ mise run test
139
+ ```
@@ -248,3 +248,19 @@
248
248
  6. AC-NARROW-06 / AO-015-06: Pydantic `FlowEvent.model_validate` rejects `FLOW_DEPRECATED` and `FLOW_IMPLEMENTATION_EVIDENCE_ADDED` event types.
249
249
  7. AC-NARROW-07 / AO-015-07: `_derive_impl_status` returns only `"CONFIRMED_IMPLEMENTED"` or `"UNCONFIRMED"`; `PARTIALLY_IMPLEMENTED` branch removed.
250
250
  8. AC-NARROW-08 / AO-015-08: Full test suite (`mise run test`), lint (`mise run lint`), format check (`mise run format-check`), and type check (`mise run check-types`) all exit 0.
251
+
252
+ ## FR-ADHOC-016: Single-Source Prompt Templates — Auto Canonical, Manual Derived at Install
253
+
254
+ - **Description**: Make `src/deviate/prompts/auto/<phase>.md` the single canonical per-phase prompt body for the 11 overlapping phases (red, green, refactor, judge, execute, plan, tasks, explore, research, prd, shard). Derive the manual slash-command (`commands/deviate-<phase>.md`) from the auto core plus a per-phase manual overlay (pre/post-script lifecycle, contract-input substitution, rich handover manifest) at `install_command` time. Reconcile the drifted middle to auto semantics (GREEN "write only production code"; RED `status:"PASS"` + `failure_kind`). Delete the duplicated manual middle bodies. Add a drift-guard test enforcing the identical-middle invariant.
255
+ - **Preconditions**: `src/deviate/prompts/assembly.py:48-107` (`load_template`) composes the auto prompt. `src/deviate/core/commands.py:55-133,189-243` (`compose_command_body`, `install_command`) compose and install manual slash-commands. The 11 overlapping phase pairs under `src/deviate/prompts/auto/` and `commands/` share 17-68% identical lines and contradict each other (RED `status:"PASS"` vs `"FAIL"`; GREEN role language). The micro runner (`src/deviate/cli/micro.py`) is the only actively used path and consumes `auto/` templates.
256
+ - **Inputs/Outputs**: Input — the 11 auto phase bodies (canonical), the 11 stale manual command bodies, the shared core/lifecycle blocks, the manual overlay content. Output — a single-source `auto/<phase>.md` per phase, a derived manual command at install, the 11 duplicated manual middles removed, a drift-guard test, and updated `specs/DeviaTDD-api.md` / `specs/DeviaTDD-architecture.md`.
257
+ - **Flow Refs**: `[]`
258
+ - **User Stories**:
259
+ 1. US-016-01: As a DeviaTDD maintainer, I want a single canonical per-phase prompt body so I edit the middle once instead of maintaining two drift-prone copies. *(Ref: FR-ADHOC-016)*
260
+ 2. US-016-02: As a DeviaTDD maintainer, I want the drifted middle reconciled to auto semantics so both modes stop instructing contradictory behavior. *(Ref: FR-ADHOC-016)*
261
+ 3. US-016-03: As a DeviaTDD maintainer, I want a drift-guard test that fails when auto and manual middles diverge so the identical-middle invariant is enforced. *(Ref: FR-ADHOC-016)*
262
+ - **Acceptance Outline** (implementation-independent; final Gherkin owned by `/deviate-plan`):
263
+ 1. AC-ADHOC-016-01 / AO-016-01: For each of the 11 overlapping phases, `install_command` derives the manual slash-command body from `auto/<phase>.md` plus the manual overlay; the middle is identical to the auto core.
264
+ 2. AC-ADHOC-016-02 / AO-016-02: The drifted middle is reconciled to auto semantics; RED manual no longer emits `status:"FAIL"`/abort-on-passing-test, and GREEN manual matches "write only production code".
265
+ 3. AC-ADHOC-016-03 / AO-016-03: A drift-guard test fails when an auto middle body diverges from the derived manual middle.
266
+ 4. AC-ADHOC-016-04 / AO-016-04: The 15 commands-only prompts (no auto counterpart) are unchanged; `specs/DeviaTDD-api.md` and `specs/DeviaTDD-architecture.md` are updated in the same commit; CHANGELOG gains an `[Unreleased]` bullet.
@@ -68,3 +68,6 @@
68
68
  {"issue_id":"005-005","type":"feature","title":"Prompt Template and Specification Alignment","status":"BACKLOG","source_file":"specs/005-acceptance-gates/issues/005-prompt-spec-alignment.md","blocked_by":["005-004"],"coordinates_with":["005-003"],"timestamp":"2026-08-14T12:28:47.899927Z","created_at":"2026-08-14T12:28:47.899930Z","flow_refs":[]}
69
69
  {"issue_id":"005-001","type":"feature","title":"Acceptance Contract Verification-Mode Metadata","status":"SPECIFIED","source_file":"specs/005-acceptance-gates/issues/001-verification-mode-metadata.md","blocked_by":[],"coordinates_with":[],"timestamp":"2026-08-14T12:30:53.080655Z","created_at":"2026-08-14T12:28:47.895924Z","flow_refs":[]}
70
70
  {"issue_id":"005-001","type":"feature","title":"Acceptance Contract Verification-Mode Metadata","status":"COMPLETED","source_file":"specs/005-acceptance-gates/issues/001-verification-mode-metadata.md","blocked_by":[],"coordinates_with":[],"timestamp":"2026-08-16T08:30:18.539420Z","created_at":"2026-08-14T12:28:47.895924Z","flow_refs":[]}
71
+ {"issue_id":"005-002","type":"feature","title":"Task Acceptance Traceability via acceptance_criteria Links","status":"SPECIFIED","source_file":"specs/005-acceptance-gates/issues/002-task-acceptance-traceability.md","blocked_by":["005-001"],"coordinates_with":["005-001"],"timestamp":"2026-08-16T08:45:53.295510Z","created_at":"2026-08-14T12:28:47.898898Z","flow_refs":[]}
72
+ {"issue_id":"005-002","type":"feature","title":"Task Acceptance Traceability via acceptance_criteria Links","status":"COMPLETED","source_file":"specs/005-acceptance-gates/issues/002-task-acceptance-traceability.md","blocked_by":["005-001"],"coordinates_with":["005-001"],"timestamp":"2026-08-19T06:29:00.116916Z","created_at":"2026-08-14T12:28:47.898898Z","flow_refs":[]}
73
+ {"issue_id": "ISS-ADH-016", "type": "adhoc", "title": "Single-Source Prompt Templates \u2014 Auto Canonical, Manual Derived at Install", "status": "BACKLOG", "source_file": "specs/adhoc/issues/016-single-source-prompt-templates.md", "blocked_by": [], "coordinates_with": ["ISS-ADH-013"], "timestamp": "2026-08-20T06:56:22.594714+00:00", "created_at": "2026-08-20T06:56:22.594714+00:00", "flow_refs": []}