devague 0.17.2__tar.gz → 0.18.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. {devague-0.17.2 → devague-0.18.1}/.claude/skills/assign-to-workforce/SKILL.md +20 -4
  2. {devague-0.17.2 → devague-0.18.1}/.claude/skills/assign-to-workforce/scripts/assign-to-workforce.sh +80 -30
  3. devague-0.18.1/.claude/skills/deviate/SKILL.md +176 -0
  4. {devague-0.17.2 → devague-0.18.1}/.claude/skills/scope/SKILL.md +5 -3
  5. {devague-0.17.2 → devague-0.18.1}/.claude/skills/spec-to-plan/SKILL.md +1 -1
  6. {devague-0.17.2 → devague-0.18.1}/.claude/skills/spec-to-plan/scripts/spec-to-plan.sh +1 -1
  7. {devague-0.17.2 → devague-0.18.1}/.claude/skills/summarize-delivery/SKILL.md +113 -52
  8. {devague-0.17.2 → devague-0.18.1}/.claude/skills/think/SKILL.md +1 -1
  9. {devague-0.17.2 → devague-0.18.1}/.claude/skills/think/scripts/think.sh +1 -1
  10. devague-0.18.1/.devague/current_plan +1 -0
  11. devague-0.18.1/.devague/deliveries/execution-seam-and-deviate.json +32 -0
  12. devague-0.18.1/.devague/frames/execution-seam-and-deviate.json +491 -0
  13. devague-0.18.1/.devague/plans/execution-seam-and-deviate.json +419 -0
  14. {devague-0.17.2 → devague-0.18.1}/CHANGELOG.md +88 -0
  15. {devague-0.17.2 → devague-0.18.1}/CLAUDE.md +80 -18
  16. {devague-0.17.2 → devague-0.18.1}/LICENSE +1 -1
  17. {devague-0.17.2 → devague-0.18.1}/PKG-INFO +15 -6
  18. {devague-0.17.2 → devague-0.18.1}/README.md +14 -5
  19. {devague-0.17.2 → devague-0.18.1}/culture.yaml +1 -1
  20. {devague-0.17.2 → devague-0.18.1}/devague/cli/__init__.py +4 -0
  21. devague-0.18.1/devague/cli/_commands/deviate.py +248 -0
  22. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/learn.py +88 -21
  23. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/plan.py +256 -16
  24. devague-0.18.1/devague/cli/_commands/summary.py +66 -0
  25. devague-0.18.1/devague/cli/_deliveries.py +43 -0
  26. devague-0.18.1/devague/delivery.py +149 -0
  27. devague-0.18.1/devague/delivery_store.py +83 -0
  28. {devague-0.17.2 → devague-0.18.1}/devague/plan.py +78 -0
  29. devague-0.18.1/devague/render/deliverables_md.py +106 -0
  30. devague-0.18.1/devague/render/summary_md.py +357 -0
  31. devague-0.18.1/docs/deliveries/2026-07-14-execution-seam-and-deviate.md +142 -0
  32. devague-0.18.1/docs/plans/2026-07-14-execution-seam-and-deviate.md +117 -0
  33. {devague-0.17.2 → devague-0.18.1}/docs/skill-sources.md +13 -11
  34. {devague-0.17.2 → devague-0.18.1}/docs/skills.md +39 -4
  35. {devague-0.17.2 → devague-0.18.1}/docs/spec-contract.md +202 -1
  36. devague-0.18.1/docs/specs/2026-07-14-execution-seam-and-deviate.md +93 -0
  37. {devague-0.17.2 → devague-0.18.1}/pyproject.toml +1 -1
  38. devague-0.18.1/tests/test_assign_to_workforce_script.py +302 -0
  39. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_learn.py +67 -7
  40. devague-0.18.1/tests/test_deviate.py +829 -0
  41. devague-0.18.1/tests/test_plan_deliverables.py +357 -0
  42. devague-0.18.1/tests/test_plan_escape_hatches.py +390 -0
  43. devague-0.18.1/tests/test_summary.py +544 -0
  44. {devague-0.17.2 → devague-0.18.1}/tests/test_think_skill.py +1 -1
  45. {devague-0.17.2 → devague-0.18.1}/uv.lock +1 -1
  46. devague-0.17.2/.devague/current_plan +0 -1
  47. {devague-0.17.2 → devague-0.18.1}/.claude/skills/agent-config/SKILL.md +0 -0
  48. {devague-0.17.2 → devague-0.18.1}/.claude/skills/agent-config/data/backend-fingerprints.yaml +0 -0
  49. {devague-0.17.2 → devague-0.18.1}/.claude/skills/agent-config/scripts/show.sh +0 -0
  50. {devague-0.17.2 → devague-0.18.1}/.claude/skills/cicd/SKILL.md +0 -0
  51. {devague-0.17.2 → devague-0.18.1}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
  52. {devague-0.17.2 → devague-0.18.1}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
  53. {devague-0.17.2 → devague-0.18.1}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
  54. {devague-0.17.2 → devague-0.18.1}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
  55. {devague-0.17.2 → devague-0.18.1}/.claude/skills/cicd/scripts/workflow.sh +0 -0
  56. {devague-0.17.2 → devague-0.18.1}/.claude/skills/communicate/SKILL.md +0 -0
  57. {devague-0.17.2 → devague-0.18.1}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
  58. {devague-0.17.2 → devague-0.18.1}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
  59. {devague-0.17.2 → devague-0.18.1}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
  60. {devague-0.17.2 → devague-0.18.1}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
  61. {devague-0.17.2 → devague-0.18.1}/.claude/skills/communicate/scripts/templates/skill-new-brief.md +0 -0
  62. {devague-0.17.2 → devague-0.18.1}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
  63. {devague-0.17.2 → devague-0.18.1}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
  64. {devague-0.17.2 → devague-0.18.1}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
  65. {devague-0.17.2 → devague-0.18.1}/.claude/skills/pypi-maintainer/SKILL.md +0 -0
  66. {devague-0.17.2 → devague-0.18.1}/.claude/skills/pypi-maintainer/scripts/switch-source.sh +0 -0
  67. {devague-0.17.2 → devague-0.18.1}/.claude/skills/recall/SKILL.md +0 -0
  68. {devague-0.17.2 → devague-0.18.1}/.claude/skills/recall/scripts/recall.sh +0 -0
  69. {devague-0.17.2 → devague-0.18.1}/.claude/skills/remember/SKILL.md +0 -0
  70. {devague-0.17.2 → devague-0.18.1}/.claude/skills/remember/scripts/remember.sh +0 -0
  71. {devague-0.17.2 → devague-0.18.1}/.claude/skills/run-tests/SKILL.md +0 -0
  72. {devague-0.17.2 → devague-0.18.1}/.claude/skills/run-tests/scripts/test.sh +0 -0
  73. {devague-0.17.2 → devague-0.18.1}/.claude/skills/sonarclaude/SKILL.md +0 -0
  74. {devague-0.17.2 → devague-0.18.1}/.claude/skills/sonarclaude/scripts/sonar.sh +0 -0
  75. {devague-0.17.2 → devague-0.18.1}/.claude/skills/version-bump/SKILL.md +0 -0
  76. {devague-0.17.2 → devague-0.18.1}/.claude/skills/version-bump/scripts/bump.py +0 -0
  77. {devague-0.17.2 → devague-0.18.1}/.claude/skills.local.yaml.example +0 -0
  78. {devague-0.17.2 → devague-0.18.1}/.devague/frames/devague-0-6-0-ships-the-human-review-loop-devague.json +0 -0
  79. {devague-0.17.2 → devague-0.18.1}/.devague/frames/devague-now-ships-a-documented-spec-contract-every.json +0 -0
  80. {devague-0.17.2 → devague-0.18.1}/.devague/frames/devague-ships-a-sharper-end-to-end-method-a-guided.json +0 -0
  81. {devague-0.17.2 → devague-0.18.1}/.devague/frames/devague-turns-a-converged-plan-into-parallel-simpl.json +0 -0
  82. {devague-0.17.2 → devague-0.18.1}/.devague/frames/summarize-delivery-skill.json +0 -0
  83. {devague-0.17.2 → devague-0.18.1}/.devague/plans/devague-0-6-0-ships-the-human-review-loop-devague.json +0 -0
  84. {devague-0.17.2 → devague-0.18.1}/.devague/plans/devague-now-ships-a-documented-spec-contract-every.json +0 -0
  85. {devague-0.17.2 → devague-0.18.1}/.devague/plans/devague-ships-a-sharper-end-to-end-method-a-guided.json +0 -0
  86. {devague-0.17.2 → devague-0.18.1}/.devague/plans/devague-turns-a-converged-plan-into-parallel-simpl.json +0 -0
  87. {devague-0.17.2 → devague-0.18.1}/.devague/plans/summarize-delivery-skill.json +0 -0
  88. {devague-0.17.2 → devague-0.18.1}/.flake8 +0 -0
  89. {devague-0.17.2 → devague-0.18.1}/.github/workflows/publish.yml +0 -0
  90. {devague-0.17.2 → devague-0.18.1}/.github/workflows/security-checks.yml +0 -0
  91. {devague-0.17.2 → devague-0.18.1}/.github/workflows/tests.yml +0 -0
  92. {devague-0.17.2 → devague-0.18.1}/.gitignore +0 -0
  93. {devague-0.17.2 → devague-0.18.1}/.markdownlint-cli2.yaml +0 -0
  94. {devague-0.17.2 → devague-0.18.1}/.pre-commit-config.yaml +0 -0
  95. {devague-0.17.2 → devague-0.18.1}/LICENSES/MIT-guildmaster-skills.txt +0 -0
  96. {devague-0.17.2 → devague-0.18.1}/devague/__init__.py +0 -0
  97. {devague-0.17.2 → devague-0.18.1}/devague/__main__.py +0 -0
  98. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/__init__.py +0 -0
  99. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/capture.py +0 -0
  100. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/confirm.py +0 -0
  101. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/converge.py +0 -0
  102. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/explain.py +0 -0
  103. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/export.py +0 -0
  104. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/interrogate.py +0 -0
  105. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/list_frames.py +0 -0
  106. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/new.py +0 -0
  107. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/park.py +0 -0
  108. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/question.py +0 -0
  109. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/reject.py +0 -0
  110. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/review.py +0 -0
  111. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/scope.py +0 -0
  112. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/show.py +0 -0
  113. {devague-0.17.2 → devague-0.18.1}/devague/cli/_commands/status.py +0 -0
  114. {devague-0.17.2 → devague-0.18.1}/devague/cli/_errors.py +0 -0
  115. {devague-0.17.2 → devague-0.18.1}/devague/cli/_frames.py +0 -0
  116. {devague-0.17.2 → devague-0.18.1}/devague/cli/_output.py +0 -0
  117. {devague-0.17.2 → devague-0.18.1}/devague/cli/_paths.py +0 -0
  118. {devague-0.17.2 → devague-0.18.1}/devague/cli/_plans.py +0 -0
  119. {devague-0.17.2 → devague-0.18.1}/devague/cli/_status.py +0 -0
  120. {devague-0.17.2 → devague-0.18.1}/devague/convergence.py +0 -0
  121. {devague-0.17.2 → devague-0.18.1}/devague/frame.py +0 -0
  122. {devague-0.17.2 → devague-0.18.1}/devague/plan_convergence.py +0 -0
  123. {devague-0.17.2 → devague-0.18.1}/devague/plan_store.py +0 -0
  124. {devague-0.17.2 → devague-0.18.1}/devague/questions_io.py +0 -0
  125. {devague-0.17.2 → devague-0.18.1}/devague/render/__init__.py +0 -0
  126. {devague-0.17.2 → devague-0.18.1}/devague/render/_md_safety.py +0 -0
  127. {devague-0.17.2 → devague-0.18.1}/devague/render/frame_md.py +0 -0
  128. {devague-0.17.2 → devague-0.18.1}/devague/render/plan_md.py +0 -0
  129. {devague-0.17.2 → devague-0.18.1}/devague/render/review_md.py +0 -0
  130. {devague-0.17.2 → devague-0.18.1}/devague/render/spec_md.py +0 -0
  131. {devague-0.17.2 → devague-0.18.1}/devague/store.py +0 -0
  132. {devague-0.17.2 → devague-0.18.1}/docs/assign-to-workforce-worked-example.md +0 -0
  133. {devague-0.17.2 → devague-0.18.1}/docs/deliveries/2026-07-09-sharper-end-to-end-method.md +0 -0
  134. {devague-0.17.2 → devague-0.18.1}/docs/deliveries/2026-07-09-summarize-delivery-skill.md +0 -0
  135. {devague-0.17.2 → devague-0.18.1}/docs/examples/contract-example.json +0 -0
  136. {devague-0.17.2 → devague-0.18.1}/docs/llm-guidance.md +0 -0
  137. {devague-0.17.2 → devague-0.18.1}/docs/plans/2026-05-23-devague-0-6-0-ships-the-human-review-loop-devague.md +0 -0
  138. {devague-0.17.2 → devague-0.18.1}/docs/plans/2026-05-23-devague-now-ships-a-documented-spec-contract-every.md +0 -0
  139. {devague-0.17.2 → devague-0.18.1}/docs/plans/2026-05-23-devague-turns-a-converged-plan-into-parallel-simpl.md +0 -0
  140. {devague-0.17.2 → devague-0.18.1}/docs/plans/2026-07-01-devague-ships-a-sharper-end-to-end-method-a-guided.md +0 -0
  141. {devague-0.17.2 → devague-0.18.1}/docs/plans/2026-07-09-summarize-delivery-skill.md +0 -0
  142. {devague-0.17.2 → devague-0.18.1}/docs/reviews/spec-contract-frame-review.md +0 -0
  143. {devague-0.17.2 → devague-0.18.1}/docs/specs/2026-05-23-devague-0-6-0-ships-the-human-review-loop-devague.md +0 -0
  144. {devague-0.17.2 → devague-0.18.1}/docs/specs/2026-05-23-devague-now-ships-a-documented-spec-contract-every.md +0 -0
  145. {devague-0.17.2 → devague-0.18.1}/docs/specs/2026-05-23-devague-turns-a-converged-plan-into-parallel-simpl.md +0 -0
  146. {devague-0.17.2 → devague-0.18.1}/docs/specs/2026-07-01-devague-ships-a-sharper-end-to-end-method-a-guided.md +0 -0
  147. {devague-0.17.2 → devague-0.18.1}/docs/specs/2026-07-09-summarize-delivery-skill.md +0 -0
  148. {devague-0.17.2 → devague-0.18.1}/docs/superpowers/plans/2026-05-22-specifix-onboarding.md +0 -0
  149. {devague-0.17.2 → devague-0.18.1}/docs/superpowers/plans/2026-05-23-devague-rename.md +0 -0
  150. {devague-0.17.2 → devague-0.18.1}/docs/superpowers/plans/2026-05-23-devague-working-backwards-engine.md +0 -0
  151. {devague-0.17.2 → devague-0.18.1}/docs/superpowers/specs/2026-05-22-specifix-onboarding-design.md +0 -0
  152. {devague-0.17.2 → devague-0.18.1}/docs/superpowers/specs/2026-05-23-devague-spec-to-plan-design.md +0 -0
  153. {devague-0.17.2 → devague-0.18.1}/docs/superpowers/specs/2026-05-23-devague-working-backwards-design.md +0 -0
  154. {devague-0.17.2 → devague-0.18.1}/sonar-project.properties +0 -0
  155. {devague-0.17.2 → devague-0.18.1}/tests/__init__.py +0 -0
  156. {devague-0.17.2 → devague-0.18.1}/tests/goldens/sharper_frame.md +0 -0
  157. {devague-0.17.2 → devague-0.18.1}/tests/goldens/sharper_plan.md +0 -0
  158. {devague-0.17.2 → devague-0.18.1}/tests/goldens/sharper_spec.md +0 -0
  159. {devague-0.17.2 → devague-0.18.1}/tests/test_boundary_audit.py +0 -0
  160. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_affordances.py +0 -0
  161. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_chassis.py +0 -0
  162. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_converge_export.py +0 -0
  163. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_errors.py +0 -0
  164. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_instructions.py +0 -0
  165. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_moves.py +0 -0
  166. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_output.py +0 -0
  167. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_paths.py +0 -0
  168. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_plan.py +0 -0
  169. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_question.py +0 -0
  170. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_review.py +0 -0
  171. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_scope.py +0 -0
  172. {devague-0.17.2 → devague-0.18.1}/tests/test_cli_status.py +0 -0
  173. {devague-0.17.2 → devague-0.18.1}/tests/test_contract.py +0 -0
  174. {devague-0.17.2 → devague-0.18.1}/tests/test_convergence.py +0 -0
  175. {devague-0.17.2 → devague-0.18.1}/tests/test_convergence_sharper.py +0 -0
  176. {devague-0.17.2 → devague-0.18.1}/tests/test_e2e_sharper_method.py +0 -0
  177. {devague-0.17.2 → devague-0.18.1}/tests/test_export_markdownlint_integration.py +0 -0
  178. {devague-0.17.2 → devague-0.18.1}/tests/test_frame.py +0 -0
  179. {devague-0.17.2 → devague-0.18.1}/tests/test_frame_schema_v2.py +0 -0
  180. {devague-0.17.2 → devague-0.18.1}/tests/test_md_safety.py +0 -0
  181. {devague-0.17.2 → devague-0.18.1}/tests/test_offline.py +0 -0
  182. {devague-0.17.2 → devague-0.18.1}/tests/test_package.py +0 -0
  183. {devague-0.17.2 → devague-0.18.1}/tests/test_plan.py +0 -0
  184. {devague-0.17.2 → devague-0.18.1}/tests/test_plan_cli_instructions.py +0 -0
  185. {devague-0.17.2 → devague-0.18.1}/tests/test_plan_convergence.py +0 -0
  186. {devague-0.17.2 → devague-0.18.1}/tests/test_plan_convergence_sharper.py +0 -0
  187. {devague-0.17.2 → devague-0.18.1}/tests/test_plan_render_sharper.py +0 -0
  188. {devague-0.17.2 → devague-0.18.1}/tests/test_plan_store.py +0 -0
  189. {devague-0.17.2 → devague-0.18.1}/tests/test_render.py +0 -0
  190. {devague-0.17.2 → devague-0.18.1}/tests/test_render_plan.py +0 -0
  191. {devague-0.17.2 → devague-0.18.1}/tests/test_render_sharper.py +0 -0
  192. {devague-0.17.2 → devague-0.18.1}/tests/test_review_loop_integration.py +0 -0
  193. {devague-0.17.2 → devague-0.18.1}/tests/test_review_loop_invariants.py +0 -0
  194. {devague-0.17.2 → devague-0.18.1}/tests/test_spec_to_plan_skill.py +0 -0
  195. {devague-0.17.2 → devague-0.18.1}/tests/test_store.py +0 -0
  196. {devague-0.17.2 → devague-0.18.1}/tests/test_teaching_scope.py +0 -0
@@ -11,7 +11,7 @@ description: >
11
11
  "fan out the plan", "parallel subagents", or after /spec-to-plan exports a
12
12
  plan. Authored and maintained in agentculture/devague (origin = devague);
13
13
  guildmaster pulls this skill from here and broadcasts it to the AgentCulture
14
- mesh — it is NOT vendored from guildmaster like the other skills here.
14
+ mesh — it is NOT vendored from guildmaster like the inbound skills here.
15
15
  type: command
16
16
  ---
17
17
 
@@ -53,14 +53,16 @@ carries every active task's summary, instruction, acceptance criteria, and
53
53
  covered targets keyed by task id — and renders the human-facing
54
54
  implementation split plan: task map (task id, wave, summary verbatim, whether
55
55
  an instruction is present, acceptance-criteria count), proposed per-task
56
- agent + model assignment, and the go/no-go question. The `waves` subcommand
57
- forwards to `devague plan waves` verbatim.
56
+ agent + model assignment, the go/no-go question, and — last — an End state
57
+ section that is the verbatim output of `devague plan deliverables` (#70),
58
+ degrading to a one-line hint on a `devague` too old to have the verb. The
59
+ `waves` subcommand forwards to `devague plan waves` verbatim.
58
60
 
59
61
  ### Usage
60
62
 
61
63
  | Subcommand | What it does |
62
64
  |------------|--------------|
63
- | `split-plan [--plan S]` | Read `devague plan waves --json` and print the implementation split plan — task map (summary/instruction/acceptance-criteria count, verbatim) with per-task agent + model proposal — ready for human go/no-go review. |
65
+ | `split-plan [--plan S]` | Read `devague plan waves --json` and print the implementation split plan — task map (summary/instruction/acceptance-criteria count, verbatim) with per-task agent + model proposal, go/no-go, and a trailing End state section quoting `devague plan deliverables` verbatim (one-line hint on an older devague) — ready for human go/no-go review. |
64
66
  | `waves [--plan S] [--json]` | Forward to `devague plan waves [--json]`. Read-only; lists wave batches. On a converged plan exits 0 listing the waves. |
65
67
  | `help` | Print usage. |
66
68
 
@@ -92,6 +94,13 @@ The split plan contains:
92
94
  safe to delegate).
93
95
  3. **Go/no-go question** — explicit human decision: "Approve this split and
94
96
  assign the plan to the workforce, or edit it first?"
97
+ 4. **End state** — the verbatim output of `devague plan deliverables` (#70):
98
+ what the plan actually produces — confirmed after-state claims, terminal
99
+ tasks with acceptance criteria, and surviving open items. Present this to
100
+ the human alongside the go/no-go question, not just the task map — approving
101
+ a fan-out without seeing the world it produces is the gap this closes. On a
102
+ `devague` too old to have the verb, this degrades to a one-line hint naming
103
+ the minimum version instead of failing the split plan.
95
104
 
96
105
  The human may edit any row (agent type, model, scope) before approving. The
97
106
  plan is model-agnostic — devague does not pick a backend (#20).
@@ -253,6 +262,13 @@ plan is found. On error (no plan, cyclic graph) it exits non-zero with a
253
262
  `hint:` line on stderr. The `waves` subcommand forwards the CLI's own output
254
263
  contract (stdout, `--json` for structured output, exit 0 on success).
255
264
 
265
+ The trailing End state section (#70) never fails `split-plan`: on a `devague`
266
+ new enough to have `plan deliverables`, it quotes that command's stdout
267
+ verbatim under an `End state (from \`devague plan deliverables\`):` header; on
268
+ an older `devague`, it prints exactly one hint line naming the minimum version
269
+ (e.g. `hint: End state view requires devague >= 0.18.0 (devague plan
270
+ deliverables)`) and `split-plan` still exits 0.
271
+
256
272
  ## Worked example
257
273
 
258
274
  Picking up after `/spec-to-plan` exported a plan for the frame `my-feature`:
@@ -4,17 +4,24 @@
4
4
  # The skill is named `assign-to-workforce`; it reads `devague plan waves --json`
5
5
  # — the enriched payload (devague#53 t9: {"plan", "waves", "tasks"}, the latter
6
6
  # keyed by task id with summary/instruction/acceptance_criteria/covers) — and
7
- # renders the implementation split plan: task map (summary, instruction
8
- # marker, acceptance-criteria count — all verbatim from the payload) +
9
- # per-task agent/model proposal + a go/no-go prompt for the human. The actual
10
- # fan-out (worktree creation, spawning, TDD-gated merges) is performed by the
11
- # operator/main agent once the human approves the split plan.
7
+ # renders the implementation split plan: a wave listing (each task id carries
8
+ # an `[instruction: yes|no, accept: N]` marker, verbatim from the payload) plus
9
+ # a single four-column per-task table — Wave, Task, Model, Task summary (#69)
10
+ # — and a go/no-go prompt for the human. The Model cell is a presentation-only
11
+ # default (`sonnet`); the devague CLI stays model-agnostic (#20) and the human
12
+ # is expected to edit it to a real model token (and harness, when it matters)
13
+ # before approving. The actual fan-out (worktree creation, spawning, TDD-gated
14
+ # merges) is performed by the operator/main agent once the human approves the
15
+ # split plan. Output ends with an End state section (devague#70 t6) — the
16
+ # verbatim output of `devague plan deliverables` — so the human can see what
17
+ # the plan actually produces before saying go; on an older devague lacking
18
+ # that verb the section degrades to a one-line hint instead of failing.
12
19
  #
13
20
  # The devague CLI is non-orchestrating (#20): `devague plan waves` describes
14
21
  # the dependency graph; it does not spawn agents, manage worktrees, or pick
15
22
  # a backend. This wrapper is the operator-facing helper.
16
23
  #
17
- # Origin: authored and maintained in agentculture/devague. steward pulls this
24
+ # Origin: authored and maintained in agentculture/devague. guildmaster pulls this
18
25
  # skill from here and broadcasts it to the rest of the AgentCulture mesh, so
19
26
  # it is written to run anywhere — portable bash, no devague-checkout assumptions.
20
27
  #
@@ -63,11 +70,14 @@ Usage:
63
70
 
64
71
  Commands:
65
72
  split-plan Read `devague plan waves --json` and render the human-facing
66
- implementation split plan: task map (summary, instruction
67
- marker, acceptance-criteria count — all verbatim from the
68
- payload) + per-task agent/model proposal + go/no-go. Present
69
- this to the human before any fan-out; do not proceed without
70
- approval.
73
+ implementation split plan: a wave listing (with per-task
74
+ instruction/acceptance-count markers, verbatim from the
75
+ payload) + a four-column Wave/Task/Model/Task-summary table
76
+ (Model defaults to `sonnet`; edit it before approving) +
77
+ go/no-go, ending with an End state section — the verbatim
78
+ output of `devague plan deliverables` (degrades to a one-line
79
+ hint on an older devague lacking that verb). Present this to
80
+ the human before any fan-out; do not proceed without approval.
71
81
  waves Forward `devague plan waves` (and any extra flags) verbatim.
72
82
  On a converged plan exits 0 and lists the dependency waves.
73
83
 
@@ -143,36 +153,49 @@ waves = data.get("waves") or []
143
153
  # contract, keyed by id — summary, instruction, acceptance criteria, covers.
144
154
  tasks_meta = data.get("tasks") or {}
145
155
 
156
+ # Presentation-only default (issue #69): the devague CLI itself stays
157
+ # model-agnostic (#20) — this is just what the table proposes before a human
158
+ # edits it.
159
+ DEFAULT_MODEL = "sonnet"
160
+ MAX_SUMMARY_LEN = 72
161
+ ELLIPSIS = "..."
162
+
163
+
164
+ def marker(task_id):
165
+ """`[instruction: yes|no, accept: N]`, verbatim from the payload (#53 t13,
166
+ c12/h5) — no operator paraphrasing of the underlying summary/instruction."""
167
+ meta = tasks_meta.get(task_id) or {}
168
+ has_instruction = "yes" if meta.get("instruction") else "no"
169
+ accept_count = len(meta.get("acceptance_criteria") or [])
170
+ return f"{task_id} [instruction: {has_instruction}, accept: {accept_count}]"
171
+
172
+
173
+ def truncate(summary):
174
+ if len(summary) > MAX_SUMMARY_LEN:
175
+ return summary[:MAX_SUMMARY_LEN] + ELLIPSIS
176
+ return summary
177
+
178
+
146
179
  print(f"Implementation split plan — plan: {plan_slug}")
147
180
  print()
148
181
  print("Dependency waves (from `devague plan waves`):")
149
182
  for i, wave in enumerate(waves, 1):
150
- tasks = ", ".join(wave)
151
- print(f" Wave {i}: [{tasks}]")
183
+ markers = ", ".join(marker(task_id) for task_id in wave)
184
+ print(f" Wave {i}: [{markers}]")
152
185
 
153
186
  print()
154
- print("Task assignments (proposed — edit before approving):")
187
+ print("Task assignments (proposed — edit the Model column before approving):")
155
188
  print()
156
189
 
157
- headers = ("Task", "Wave", "Summary", "Instruction", "Accept.", "Agent type", "Model", "Scope note")
190
+ headers = ("Wave", "Task", "Model", "Task summary")
158
191
  rows = []
159
192
  for i, wave in enumerate(waves, 1):
160
193
  for task_id in wave:
161
194
  meta = tasks_meta.get(task_id) or {}
162
- # Verbatim from the payload — no operator paraphrasing (#53 t13, c12/h5).
195
+ # Verbatim from the payload — no operator paraphrasing (#53 t13, c12/h5) —
196
+ # never a placeholder unless the payload truly has no summary recorded.
163
197
  summary = meta.get("summary") or "(no summary recorded)"
164
- has_instruction = "yes" if meta.get("instruction") else "no"
165
- accept_count = str(len(meta.get("acceptance_criteria") or []))
166
- rows.append((
167
- task_id,
168
- str(i),
169
- summary,
170
- has_instruction,
171
- accept_count,
172
- "subagent",
173
- "cheaper/faster",
174
- "TDD-scoped task; isolated worktree; tests gate merge",
175
- ))
198
+ rows.append((str(i), task_id, DEFAULT_MODEL, truncate(summary)))
176
199
 
177
200
  col_widths = [max(len(h), max((len(r[j]) for r in rows), default=0))
178
201
  for j, h in enumerate(headers)]
@@ -187,8 +210,13 @@ for row in rows:
187
210
  print(row_str(row))
188
211
 
189
212
  print()
190
- print("Go/no-go: review the table above, edit agent type / model / scope as needed,")
191
- print("then confirm: \"Approved — assign to workforce\" or \"Edit first\".")
213
+ print("Model column: edit each row to a real model token (e.g. haiku, sonnet,")
214
+ print("opus, fable), optionally qualified with the harness when it matters")
215
+ print("(e.g. colleague, codex) — the default above is a starting proposal, not")
216
+ print("a recommendation.")
217
+ print()
218
+ print("Go/no-go: review the table above, edit the Model column as needed, then")
219
+ print("confirm: \"Approved — assign to workforce\" or \"Edit first\".")
192
220
  print()
193
221
  print("Once approved, fan out wave by wave:")
194
222
  print(" 1. Create one git worktree per task in the wave.")
@@ -199,6 +227,28 @@ print(" 3. Await all tasks in the wave; then TDD-gate each merge (tests before
199
227
  print(" 4. Advance to the next wave.")
200
228
  print(" 5. Open the final PR (human gate 3) after all waves merge and tests pass.")
201
229
  PY
230
+
231
+ # ── End state: quote `devague plan deliverables` verbatim (#70 t6) ───────
232
+ # Never composed freehand — it is the single synthesized "what do we have
233
+ # in the end?" view (confirmed after-state claims, terminal tasks, and
234
+ # surviving open items). Forward the same --plan args used for waves.
235
+ # Degrades gracefully on an older devague that predates the verb: print
236
+ # one hint line naming the minimum version and keep exiting 0 — this
237
+ # section must never fail the script.
238
+ local deliverables_out deliverables_rc
239
+ set +e
240
+ deliverables_out="$("${DEVAGUE[@]}" plan deliverables "${extra_args[@]}" 2>/dev/null)"
241
+ deliverables_rc=$?
242
+ set -e
243
+
244
+ echo
245
+ if [ "$deliverables_rc" -eq 0 ]; then
246
+ echo 'End state (from `devague plan deliverables`):'
247
+ echo
248
+ printf '%s\n' "$deliverables_out"
249
+ else
250
+ echo 'hint: End state view requires devague >= 0.18.0 (devague plan deliverables)'
251
+ fi
202
252
  }
203
253
 
204
254
  main() {
@@ -0,0 +1,176 @@
1
+ ---
2
+ name: deviate
3
+ description: >
4
+ Stop an in-flight assign-to-workforce run the moment execution must diverge
5
+ from the confirmed plan, get explicit human approval for the divergence, and
6
+ record it as a first-class, append-only deviation record via `devague
7
+ deviate` before resuming — never fold a deviation silently into drift after
8
+ the fact. Use when the user says "deviate from the plan", "we need to change
9
+ the plan mid-run", "record a deviation", "this isn't matching the plan
10
+ anymore", or when a task agent discovers the confirmed plan no longer
11
+ matches reality partway through a workforce run. Authored and maintained in
12
+ agentculture/devague (origin = devague); guildmaster pulls this skill from
13
+ here and broadcasts it to the AgentCulture mesh — it is NOT vendored from
14
+ guildmaster like the inbound skills here.
15
+ type: command
16
+ ---
17
+
18
+ # deviate — record an approved mid-run departure from the confirmed plan
19
+
20
+ The skill is named **`deviate`**; it is the **execution-time leg** of the
21
+ devague method — the *sixth* leg, sitting between the two execution skills:
22
+
23
+ ```text
24
+ scope -> think -> spec-to-plan -> assign-to-workforce -> deviate -> summarize-delivery
25
+ ```
26
+
27
+ Where `/assign-to-workforce` fans out a converged plan's waves and
28
+ `/summarize-delivery` closes the loop afterward, `/deviate` runs **during**
29
+ the fan-out, at the exact moment reality stops matching the plan the human
30
+ approved at gate 2 (the implementation split plan). It is not a new standing
31
+ gate — it is the human owner of gate 2 **amending** the approved split
32
+ mid-flight, scoped to the one deviation in front of them.
33
+
34
+ The plan the user confirmed is a contract. Task agents hit constraints,
35
+ discover a dependency was wrong, or find the acceptance criteria no longer
36
+ make sense once code is in front of them. Until this skill existed, that
37
+ reality either silently reshaped what got built (undocumented drift) or the
38
+ run stalled with no recorded path forward. `/deviate` is that path: the
39
+ departure is named, approved, and recorded **before** anyone keeps building
40
+ against it.
41
+
42
+ ## The method
43
+
44
+ 1. **STOP the run.** The moment a task agent (or the main agent) discovers
45
+ the confirmed plan no longer matches what needs to happen, halt — do not
46
+ keep implementing against the stale contract and do not let the fan-out
47
+ continue past this task.
48
+ 2. **Present what, why, and what it affects.** Lay out, for the human:
49
+ - **what** is diverging — the specific change from the confirmed task(s);
50
+ - **why** — the constraint or discovery that forced it;
51
+ - **what it affects** — the plan item ref(s) involved (`--task`), any
52
+ other task ids or coverage targets it touches (`--affects`), and which
53
+ acceptance criteria are no longer accurate.
54
+ 3. **Get explicit human approval.** This is the one non-negotiable step. A
55
+ deviation is not real until a human says yes to *this specific* departure
56
+ — not a standing blanket permission, not an inference from silence.
57
+ 4. **Record it via `devague deviate`.** Once approved, record the deviation
58
+ as a first-class ledger entry (never edit the plan itself — the plan
59
+ stays the untouched historical contract; see `devague/delivery.py`). An
60
+ `--origin llm` record lands `proposed` and still needs the user's
61
+ `--confirm` — recording is not the same as approval landing as final.
62
+ 5. **Adjust the affected task briefs.** Update the working instructions the
63
+ task agent(s) are building against so they reflect the approved
64
+ departure, not the stale plan text.
65
+ 6. **Resume.** Only after the record exists (and, for an `llm`-origin record,
66
+ only after it is confirmed) does the fan-out continue.
67
+
68
+ Deviations are never silently folded into drift after the fact — by the time
69
+ `/summarize-delivery` runs, every departure from the plan already has a
70
+ `dN` record with a reason, an approval, and an optional classification. The
71
+ delivery summary quotes these records; it does not reconstruct drift from
72
+ memory.
73
+
74
+ ## The shipped CLI surface
75
+
76
+ This skill invokes the CLI directly and stays self-contained (if `devague`
77
+ isn't on your PATH: `uv tool install devague`). Deviation state persists
78
+ under `.devague/deliveries/<plan-slug>.json` — a peer of the plan store, keyed
79
+ by the plan slug, and never touches the plan JSON itself.
80
+
81
+ | Move | What it does |
82
+ |------|---------------|
83
+ | `devague deviate "<what>" --task <tN> --reason "<text>"` | Record a deviation against plan item `<tN>`. User-origin (the default) auto-approves. |
84
+ | `devague deviate "<what>" --task <tN> --reason "<text>" --affects <ref> [<ref> ...]` | Same, also naming every other plan item ref or coverage target the deviation touches (repeatable). |
85
+ | `devague deviate "<what>" --task <tN> --reason "<text>" --classification acceptable\|risky\|needs-follow-up` | Same, tagging the deviation with the classification the drift-entry contract consumes downstream. |
86
+ | `devague deviate "<what>" --task <tN> --reason "<text>" --origin llm` | An LLM-proposed record; lands `proposed`, not `approved`. |
87
+ | `devague deviate --confirm <dN>` | User-only: approve a `proposed` deviation. |
88
+ | `devague deviate --reject <dN>` | User-only: reject a `proposed` (or any) deviation. |
89
+ | `devague deviate --list [--json]` | Read every recorded deviation back (also the default action with no positional/flag). |
90
+ | `devague deviate ... --plan <slug>` | Target a plan other than the current one. |
91
+
92
+ `--reason` is required on every record — omitting it is refused with a hint.
93
+ `--task` naming the plan item ref is likewise required.
94
+
95
+ ## Hard rules (do not violate)
96
+
97
+ - **Never record a deviation the human did not approve.** `devague deviate`
98
+ without `--origin llm` auto-approves the instant it is run — so a
99
+ user-origin record IS the approval. Only run it after the human has said
100
+ yes to this specific departure, never preemptively "to be safe."
101
+ - **Never continue past a refused approval.** If the human does not approve,
102
+ the run stays stopped on that task. Do not record the deviation anyway, do
103
+ not quietly implement the diverging approach, and do not advance the wave.
104
+ - **LLM-origin records stay proposed until the user confirms.** `--origin
105
+ llm` lands `proposed`; only `devague deviate --confirm <dN>` (user-only)
106
+ makes it `approved`. Same anti-fabrication contract as every other origin
107
+ in the method — an agent's own proposal never self-confirms.
108
+ - **Deviations are never silently folded into drift after the fact.** Every
109
+ departure from the confirmed plan gets a `dN` record at the moment it
110
+ happens — not reconstructed from memory when `/summarize-delivery` runs
111
+ later.
112
+ - **The CLI stays non-orchestrating (issue #20).** `devague deviate` records
113
+ a decision the human already made; it does not spawn agents, gate merges,
114
+ mark tasks done, or make the approval decision itself. Recording is
115
+ deterministic — no LLM calls inside the CLI.
116
+ - **This is not a fourth standing gate.** `/assign-to-workforce`'s three
117
+ human gates are the exported spec, the implementation split plan, and the
118
+ final PR. `/deviate` does not add a fourth — it is the human owner of gate
119
+ 2 amending the approved split for one scoped, in-flight decision.
120
+
121
+ ## Worked example
122
+
123
+ Mid-fan-out on task `t4`, the task agent discovers the acceptance criteria
124
+ assumed a helper that task `t2` never actually shipped:
125
+
126
+ ```bash
127
+ # 1. STOP — the main agent halts t4's worktree before more code lands
128
+ # against a criterion that can't be met as written.
129
+
130
+ # 2. Present what/why/what-it-affects to the human:
131
+ # what: t4's acceptance criterion 2 assumes a `--json` flag on a
132
+ # helper that t2 shipped without one
133
+ # why: t2's scope was cut to land its wave on time
134
+ # affects: t4 (this task), and coverage target c9 (the criterion in
135
+ # question)
136
+
137
+ # --- HUMAN: approves dropping the --json assumption from t4's criterion ---
138
+
139
+ # 3. Record the approved deviation
140
+ devague deviate "drop the --json assumption from t4's acceptance criterion" \
141
+ --task t4 --reason "t2 shipped its helper without --json to land its wave on time" \
142
+ --affects t2 --affects c9 --classification acceptable
143
+
144
+ # 4. Adjust t4's working brief to match what was approved, then resume the
145
+ # task agent against the corrected instruction.
146
+
147
+ # Read the ledger back at any point:
148
+ devague deviate --list
149
+ devague deviate --list --json
150
+ ```
151
+
152
+ If the agent had proposed the record itself (`--origin llm`), the same
153
+ record would land `proposed` and need an explicit
154
+ `devague deviate --confirm d1` from the user before `/summarize-delivery`
155
+ could cite it as approved.
156
+
157
+ ## After recording — resume, then hand off to /summarize-delivery
158
+
159
+ Once the affected task briefs are adjusted and the fan-out resumes, nothing
160
+ further is needed from this skill — the record already lives in the delivery
161
+ store. When the run reaches `/summarize-delivery`, that skill's Drift From
162
+ Plan and Mid-work Decisions sections quote these records by their `dN` id
163
+ instead of reconstructing drift from memory, so the connective tissue between
164
+ the confirmed plan and the delivery summary is the ledger this skill wrote,
165
+ not anyone's recollection of the run.
166
+
167
+ ## Provenance
168
+
169
+ This is a **first-party** skill — its origin is `agentculture/devague`, the
170
+ *sixth* in the outbound family after `/scope`, `/think`, `/spec-to-plan`,
171
+ `/assign-to-workforce`, and `/summarize-delivery`, covering the execution-time
172
+ leg that runs inside an `/assign-to-workforce` fan-out. guildmaster pulls it
173
+ from here and broadcasts it to the AgentCulture mesh; because devague is
174
+ upstream, it is **never re-vendored back** from guildmaster's re-broadcast
175
+ copy. The `cite, don't import` policy still holds: downstream repos copy it,
176
+ they don't symlink or depend on it. See `docs/skill-sources.md`.
@@ -158,8 +158,10 @@ LLM-proposed claims there, as always.
158
158
  ## Provenance
159
159
 
160
160
  This is a **first-party** skill — its origin is `agentculture/devague`, the
161
- *fourth* in the outbound family after `/think`, `/spec-to-plan`, and
162
- `/assign-to-workforce`, covering the pre-frame exploration leg. guildmaster
163
- pulls it from here and broadcasts it to the AgentCulture mesh. The
161
+ *fourth* authored in the outbound family (after `/think`, `/spec-to-plan`, and
162
+ `/assign-to-workforce`) but the **opening leg** of the flow, covering the
163
+ pre-frame exploration that runs before `/think`. guildmaster pulls it from here
164
+ and broadcasts it to the AgentCulture mesh; because devague is upstream, it is
165
+ **never re-vendored back** from guildmaster's re-broadcast copy. The
164
166
  `cite, don't import` policy still holds: downstream repos copy it, they don't
165
167
  symlink or depend on it. See `docs/skill-sources.md`.
@@ -11,7 +11,7 @@ description: >
11
11
  build plan", or after the /think skill exports a spec. Authored and maintained
12
12
  in agentculture/devague (origin = devague); guildmaster pulls this skill from
13
13
  here and broadcasts it to the AgentCulture mesh — it is NOT vendored from
14
- guildmaster like the other skills here.
14
+ guildmaster like the inbound skills here.
15
15
  type: command
16
16
  ---
17
17
 
@@ -8,7 +8,7 @@
8
8
  # and names the recommended next move. It is the forward leg: seed a plan from a
9
9
  # *converged* frame, then work it into a buildable plan.
10
10
  #
11
- # Origin: authored and maintained in agentculture/devague. steward pulls this
11
+ # Origin: authored and maintained in agentculture/devague. guildmaster pulls this
12
12
  # skill from here and broadcasts it to the rest of the AgentCulture mesh, so it
13
13
  # is written to run anywhere — portable bash, no devague-checkout assumptions.
14
14
  #