create-agdf 0.30.0 → 0.32.0

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 (366) hide show
  1. package/generated/.agdf/control/README.md +5 -0
  2. package/generated/.agdf/control/templates/BRAND.md +28 -0
  3. package/generated/.agdf/control/templates/artefacts/PRD.md +11 -0
  4. package/generated/.agdf/control/templates/artefacts/SD.md +4 -0
  5. package/generated/.agdf/control/templates/artefacts/UX_INTENT_DEFINITION.md +1 -1
  6. package/generated/.opencode/agdf-interaction-locales.json +436 -2
  7. package/generated/.opencode/contracts/gate-artifact-preparation.md +9 -3
  8. package/generated/.opencode/contracts/interaction.md +10 -4
  9. package/generated/.opencode/contracts/modes.md +5 -0
  10. package/generated/.opencode/contracts/prd-definition.md +40 -1
  11. package/generated/.opencode/contracts/quality.md +35 -0
  12. package/generated/.opencode/contracts/request-activation.md +6 -3
  13. package/generated/.opencode/contracts/sd-definition.md +46 -0
  14. package/generated/.opencode/contracts/tp-definition.md +8 -0
  15. package/generated/.opencode/contracts/ur-definition.md +9 -5
  16. package/generated/.opencode/skills/agdf-ux-intent-definition/SKILL.md +31 -2
  17. package/generated/plugins/agdf/.claude-plugin/plugin.json +1 -1
  18. package/generated/plugins/agdf/.codex-plugin/plugin.json +1 -1
  19. package/generated/plugins/agdf/companion/events.mjs +119 -0
  20. package/generated/plugins/agdf/companion/figure.mjs +242 -111
  21. package/generated/plugins/agdf/companion/gate-bar.mjs +10 -28
  22. package/generated/plugins/agdf/companion/localization.mjs +15 -32
  23. package/generated/plugins/agdf/companion/notice.mjs +20 -10
  24. package/generated/plugins/agdf/companion/register.mjs +310 -66
  25. package/generated/plugins/agdf/companion/run-state.mjs +89 -90
  26. package/generated/plugins/agdf/companion/state.mjs +6 -32
  27. package/generated/plugins/agdf/companion/view.mjs +199 -24
  28. package/generated/plugins/agdf/control/README.md +5 -0
  29. package/generated/plugins/agdf/control/templates/BRAND.md +28 -0
  30. package/generated/plugins/agdf/control/templates/artefacts/PRD.md +11 -0
  31. package/generated/plugins/agdf/control/templates/artefacts/SD.md +4 -0
  32. package/generated/plugins/agdf/control/templates/artefacts/UX_INTENT_DEFINITION.md +1 -1
  33. package/generated/plugins/agdf/mcp/server/README.md +26 -2
  34. package/generated/plugins/agdf/mcp/server/package.json +3 -3
  35. package/generated/plugins/agdf/mcp/server/src/generation-runtime.js +14 -3
  36. package/generated/plugins/agdf/mcp/server/src/generation.js +8 -2
  37. package/generated/plugins/agdf/mcp/server/src/main.js +5 -1
  38. package/generated/plugins/agdf/mcp/server/src/next-action.js +227 -0
  39. package/generated/plugins/agdf/mcp/server/src/prepared-call-transport.js +306 -0
  40. package/generated/plugins/agdf/mcp/server/src/safe-read-continuation.js +62 -0
  41. package/generated/plugins/agdf/mcp/server/src/server.js +155 -37
  42. package/generated/plugins/agdf/mcp/server/ui/cockpit.html +130 -33
  43. package/generated/plugins/agdf/mcp/server/ui/decision-manifest.json +3 -3
  44. package/generated/plugins/agdf/mcp/server/ui/decision.html +3 -3
  45. package/generated/plugins/agdf/mcp/server/ui/manifest.json +3 -3
  46. package/generated/plugins/agdf/meta/agdf-interaction-locales.json +436 -2
  47. package/generated/plugins/agdf/meta/agdf-mcp-capability.json +1 -1
  48. package/generated/plugins/agdf/meta/agdf-plugin.definition.json +1 -1
  49. package/generated/plugins/agdf/meta/contracts/gate-artifact-preparation.md +9 -3
  50. package/generated/plugins/agdf/meta/contracts/interaction.md +10 -4
  51. package/generated/plugins/agdf/meta/contracts/modes.md +5 -0
  52. package/generated/plugins/agdf/meta/contracts/prd-definition.md +40 -1
  53. package/generated/plugins/agdf/meta/contracts/quality.md +35 -0
  54. package/generated/plugins/agdf/meta/contracts/request-activation.md +6 -3
  55. package/generated/plugins/agdf/meta/contracts/sd-definition.md +46 -0
  56. package/generated/plugins/agdf/meta/contracts/tp-definition.md +8 -0
  57. package/generated/plugins/agdf/meta/contracts/ur-definition.md +9 -5
  58. package/generated/plugins/agdf/meta/copilot-payload-baseline.json +3 -3
  59. package/generated/plugins/agdf/meta/distribution-profile-history.json +14 -0
  60. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-interaction-locales.json +436 -2
  61. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-plugin.definition.json +1 -1
  62. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/gate-artifact-preparation.md +9 -3
  63. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/interaction.md +10 -4
  64. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/modes.md +5 -0
  65. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/prd-definition.md +40 -1
  66. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/quality.md +35 -0
  67. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/request-activation.md +6 -3
  68. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/sd-definition.md +46 -0
  69. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/tp-definition.md +8 -0
  70. package/generated/plugins/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/ur-definition.md +9 -5
  71. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/command-registry.js +2 -1
  72. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/parse-args.js +7 -4
  73. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/project-read-command.js +29 -0
  74. package/generated/plugins/agdf/runtime/create-agdf/lib/cli/validation-handlers.js +2 -1
  75. package/generated/plugins/agdf/runtime/create-agdf/lib/mcp-dispatch-runtime.js +36 -7
  76. package/generated/plugins/agdf/runtime/create-agdf/lib/mcp-lifecycle/package.js +7 -0
  77. package/generated/plugins/agdf/runtime/create-agdf/lib/mcp-lifecycle/plugin-runtime.js +34 -6
  78. package/generated/plugins/agdf/runtime/create-agdf/lib/mcp-lifecycle/prepared-call-journal.js +269 -0
  79. package/generated/plugins/agdf/runtime/create-agdf/lib/mcp-worker-runtime.js +86 -83
  80. package/generated/plugins/agdf/runtime/create-agdf/lib/runtime/validator-application.js +2 -2
  81. package/generated/plugins/agdf/runtime/create-agdf/package.json +1 -1
  82. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/companion/events.js +157 -0
  83. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/companion/figure-state.js +38 -0
  84. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/companion/journal.js +186 -0
  85. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/companion/run-view.js +227 -0
  86. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/acceptance-criteria.js +2 -0
  87. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/closeout-readiness.js +24 -6
  88. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/decision-content-placeholder.js +4 -1
  89. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/gate-check.js +49 -7
  90. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/gate-policy-inputs.js +2 -0
  91. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/gate-policy-pure.js +7 -3
  92. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/prd-readiness.js +7 -2
  93. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/report-decision.js +9 -0
  94. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/traceability-readiness.js +57 -8
  95. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/ur-readiness.js +15 -2
  96. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/artifact-readiness.js +5 -3
  97. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/authoring-inputs.js +107 -22
  98. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/cockpit-list.js +10 -8
  99. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/cockpit-session.js +11 -3
  100. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/cockpit-work.js +4 -2
  101. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/cockpit.js +47 -33
  102. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/contract.js +64 -24
  103. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/material-recording-calls.js +54 -0
  104. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/project-state.js +2 -1
  105. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/run-classification.js +31 -0
  106. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/selection.js +6 -0
  107. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/service.js +32 -5
  108. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/work-situation.js +25 -0
  109. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-read/cockpit-worker.js +1 -0
  110. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/authoring-text-handoff.js +3 -0
  111. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/input-resolution.js +7 -5
  112. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/material-limits.js +4 -0
  113. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/prepared-control-calls.js +137 -0
  114. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/presentation-delivery.js +4 -1
  115. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-command-contract.js +10 -4
  116. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-command-schema.js +9 -3
  117. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-command-service.js +35 -11
  118. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-create-command.js +6 -1
  119. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-identity.js +2 -0
  120. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-inventory-reader.js +54 -5
  121. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-inventory.js +12 -27
  122. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-material.js +25 -7
  123. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-presentation-render.js +113 -28
  124. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-revision.js +38 -20
  125. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-source-revisions.js +37 -17
  126. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-state-reader.js +10 -3
  127. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-steps.js +8 -5
  128. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-title.js +43 -0
  129. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/index.js +3 -1
  130. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/interaction-catalog-validation.js +7 -1
  131. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/interaction-catalog.js +8 -0
  132. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/interaction-presentation.js +31 -10
  133. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/mcp-input-hints.js +30 -1
  134. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/mcp-tool-errors.js +5 -3
  135. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/resources/canonical-init-plan.js +1 -1
  136. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/runtime/plugin-provenance.js +9 -2
  137. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/contract.js +6 -4
  138. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/delivery-intake.js +3 -1
  139. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/mcp-continuation.js +25 -2
  140. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/prd-definition.js +3 -2
  141. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/readiness-findings.js +7 -0
  142. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/sd-definition.js +4 -2
  143. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/service.js +17 -4
  144. package/generated/plugins/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/tp-definition.js +4 -2
  145. package/generated/plugins/agdf/runtime/runtime-manifest.json +2 -2
  146. package/generated/plugins/agdf/scripts/check-runtime-integrity.mjs +4 -3
  147. package/generated/plugins/agdf/skills/ux-intent-definition/SKILL.md +31 -2
  148. package/generated/plugins/agdf/skills/ux-intent-definition/help.md +8 -1
  149. package/generated/plugins/agdf/submission/openai/availability.md +1 -1
  150. package/generated/plugins/agdf/submission/openai/capability-matrix.json +1 -1
  151. package/generated/plugins/agdf/submission/openai/release-notes.md +5 -8
  152. package/generated/plugins/agdf/submission/openai/reviewer-cases.json +1 -1
  153. package/generated/plugins/agdf-planning/.codex-plugin/plugin.json +1 -1
  154. package/generated/plugins/agdf-planning/plugin.json +1 -1
  155. package/generated/plugins/copilot/agdf/.agdf-payload-inventory.json +358 -203
  156. package/generated/plugins/copilot/agdf/control/README.md +5 -0
  157. package/generated/plugins/copilot/agdf/control/templates/BRAND.md +28 -0
  158. package/generated/plugins/copilot/agdf/control/templates/artefacts/PRD.md +11 -0
  159. package/generated/plugins/copilot/agdf/control/templates/artefacts/SD.md +4 -0
  160. package/generated/plugins/copilot/agdf/control/templates/artefacts/UX_INTENT_DEFINITION.md +1 -1
  161. package/generated/plugins/copilot/agdf/mcp/server/README.md +26 -2
  162. package/generated/plugins/copilot/agdf/mcp/server/package.json +3 -3
  163. package/generated/plugins/copilot/agdf/mcp/server/src/generation-runtime.js +14 -3
  164. package/generated/plugins/copilot/agdf/mcp/server/src/generation.js +8 -2
  165. package/generated/plugins/copilot/agdf/mcp/server/src/main.js +5 -1
  166. package/generated/plugins/copilot/agdf/mcp/server/src/next-action.js +227 -0
  167. package/generated/plugins/copilot/agdf/mcp/server/src/prepared-call-transport.js +306 -0
  168. package/generated/plugins/copilot/agdf/mcp/server/src/safe-read-continuation.js +62 -0
  169. package/generated/plugins/copilot/agdf/mcp/server/src/server.js +155 -37
  170. package/generated/plugins/copilot/agdf/meta/agdf-plugin.definition.json +1 -1
  171. package/generated/plugins/copilot/agdf/meta/distribution-profile-history.json +14 -0
  172. package/generated/plugins/copilot/agdf/plugin.json +1 -1
  173. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-interaction-locales.json +436 -2
  174. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/agdf-plugin.definition.json +1 -1
  175. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/gate-artifact-preparation.md +9 -3
  176. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/interaction.md +10 -4
  177. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/modes.md +5 -0
  178. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/prd-definition.md +40 -1
  179. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/quality.md +35 -0
  180. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/request-activation.md +6 -3
  181. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/sd-definition.md +46 -0
  182. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/tp-definition.md +8 -0
  183. package/generated/plugins/copilot/agdf/runtime/create-agdf/generated/plugins/agdf/meta/contracts/ur-definition.md +9 -5
  184. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/command-registry.js +2 -1
  185. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/parse-args.js +7 -4
  186. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/project-read-command.js +29 -0
  187. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/cli/validation-handlers.js +2 -1
  188. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/mcp-dispatch-runtime.js +36 -7
  189. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/mcp-lifecycle/package.js +7 -0
  190. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/mcp-lifecycle/plugin-runtime.js +34 -6
  191. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/mcp-lifecycle/prepared-call-journal.js +269 -0
  192. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/mcp-worker-runtime.js +81 -78
  193. package/generated/plugins/copilot/agdf/runtime/create-agdf/lib/runtime/validator-application.js +2 -2
  194. package/generated/plugins/copilot/agdf/runtime/create-agdf/package.json +1 -1
  195. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/companion/events.js +157 -0
  196. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/companion/figure-state.js +38 -0
  197. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/companion/journal.js +186 -0
  198. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/companion/run-view.js +227 -0
  199. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/acceptance-criteria.js +2 -0
  200. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/closeout-readiness.js +24 -6
  201. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/decision-content-placeholder.js +4 -1
  202. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/gate-check.js +49 -7
  203. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/gate-policy-inputs.js +2 -0
  204. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/gate-policy-pure.js +7 -3
  205. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/prd-readiness.js +7 -2
  206. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/report-decision.js +9 -0
  207. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/traceability-readiness.js +57 -8
  208. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-evaluation/ur-readiness.js +15 -2
  209. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/artifact-readiness.js +5 -3
  210. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/authoring-inputs.js +107 -22
  211. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/contract.js +64 -24
  212. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/material-recording-calls.js +54 -0
  213. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/project-state.js +2 -1
  214. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/run-classification.js +31 -0
  215. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/selection.js +6 -0
  216. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/service.js +32 -5
  217. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-inspect/work-situation.js +25 -0
  218. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/authoring-text-handoff.js +3 -0
  219. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/input-resolution.js +7 -5
  220. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/material-limits.js +4 -0
  221. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/prepared-control-calls.js +137 -0
  222. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/presentation-delivery.js +4 -1
  223. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-command-contract.js +10 -4
  224. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-command-schema.js +9 -3
  225. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-command-service.js +35 -11
  226. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-create-command.js +6 -1
  227. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-identity.js +2 -0
  228. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-inventory-reader.js +54 -5
  229. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-inventory.js +12 -27
  230. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-material.js +25 -7
  231. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-presentation-render.js +113 -28
  232. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-revision.js +38 -20
  233. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-source-revisions.js +37 -17
  234. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-state-reader.js +10 -3
  235. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-steps.js +8 -5
  236. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/control-state/run-title.js +43 -0
  237. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/index.js +3 -1
  238. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/interaction-catalog-validation.js +7 -1
  239. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/interaction-catalog.js +8 -0
  240. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/interaction-presentation.js +31 -10
  241. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/mcp-input-hints.js +30 -1
  242. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/mcp-tool-errors.js +5 -3
  243. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/resources/canonical-init-plan.js +1 -1
  244. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/runtime/plugin-provenance.js +9 -2
  245. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/contract.js +6 -4
  246. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/delivery-intake.js +3 -1
  247. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/mcp-continuation.js +25 -2
  248. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/prd-definition.js +3 -2
  249. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/readiness-findings.js +7 -0
  250. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/sd-definition.js +4 -2
  251. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/service.js +17 -4
  252. package/generated/plugins/copilot/agdf/runtime/create-agdf/runtime/core/lib/skill-dispatch/tp-definition.js +4 -2
  253. package/generated/plugins/copilot/agdf/runtime/runtime-manifest.json +2 -2
  254. package/generated/plugins/copilot/agdf/skills/agdf-interaction-locales.json +1 -1
  255. package/generated/plugins/copilot/agdf/skills/agdf-ux-intent-definition/SKILL.md +31 -2
  256. package/generated/plugins/copilot/agdf/skills/contracts/gate-artifact-preparation.md +9 -3
  257. package/generated/plugins/copilot/agdf/skills/contracts/interaction.md +10 -4
  258. package/generated/plugins/copilot/agdf/skills/contracts/modes.md +5 -0
  259. package/generated/plugins/copilot/agdf/skills/contracts/prd-definition.md +40 -1
  260. package/generated/plugins/copilot/agdf/skills/contracts/quality.md +35 -0
  261. package/generated/plugins/copilot/agdf/skills/contracts/request-activation.md +6 -3
  262. package/generated/plugins/copilot/agdf/skills/contracts/sd-definition.md +46 -0
  263. package/generated/plugins/copilot/agdf/skills/contracts/tp-definition.md +8 -0
  264. package/generated/plugins/copilot/agdf/skills/contracts/ur-definition.md +9 -5
  265. package/generated/submissions/openai/agdf/.codex-plugin/plugin.json +1 -1
  266. package/generated/submissions/openai/agdf/meta/agdf-interaction-locales.json +436 -2
  267. package/generated/submissions/openai/agdf/meta/agdf-plugin.definition.json +1 -1
  268. package/generated/submissions/openai/agdf/meta/contracts/gate-artifact-preparation.md +9 -3
  269. package/generated/submissions/openai/agdf/meta/contracts/interaction.md +10 -4
  270. package/generated/submissions/openai/agdf/meta/contracts/modes.md +5 -0
  271. package/generated/submissions/openai/agdf/meta/contracts/prd-definition.md +40 -1
  272. package/generated/submissions/openai/agdf/meta/contracts/quality.md +35 -0
  273. package/generated/submissions/openai/agdf/meta/contracts/request-activation.md +6 -3
  274. package/generated/submissions/openai/agdf/meta/contracts/sd-definition.md +46 -0
  275. package/generated/submissions/openai/agdf/meta/contracts/tp-definition.md +8 -0
  276. package/generated/submissions/openai/agdf/meta/contracts/ur-definition.md +9 -5
  277. package/generated/submissions/openai/agdf/meta/copilot-payload-baseline.json +3 -3
  278. package/generated/submissions/openai/agdf/meta/distribution-profile-history.json +14 -0
  279. package/generated/submissions/openai/agdf/plugin.json +1 -1
  280. package/generated/submissions/openai/agdf/skills/ux-intent-definition/SKILL.md +31 -2
  281. package/generated/submissions/openai/agdf/skills/ux-intent-definition/help.md +8 -1
  282. package/generated/submissions/openai/agdf/submission/openai/availability.md +1 -1
  283. package/generated/submissions/openai/agdf/submission/openai/capability-matrix.json +1 -1
  284. package/generated/submissions/openai/agdf/submission/openai/inventory.json +24 -24
  285. package/generated/submissions/openai/agdf/submission/openai/listing.json +1 -1
  286. package/generated/submissions/openai/agdf/submission/openai/readiness.json +2 -2
  287. package/generated/submissions/openai/agdf/submission/openai/readiness.md +2 -2
  288. package/generated/submissions/openai/agdf/submission/openai/release-notes.md +5 -8
  289. package/generated/submissions/openai/agdf/submission/openai/reviewer-cases.json +1 -1
  290. package/lib/cli/command-registry.js +2 -1
  291. package/lib/cli/parse-args.js +7 -4
  292. package/lib/cli/project-read-command.js +29 -0
  293. package/lib/cli/validation-handlers.js +2 -1
  294. package/lib/mcp-dispatch-runtime.js +36 -7
  295. package/lib/mcp-lifecycle/package.js +7 -0
  296. package/lib/mcp-lifecycle/plugin-runtime.js +34 -6
  297. package/lib/mcp-lifecycle/prepared-call-journal.js +269 -0
  298. package/lib/mcp-worker-runtime.js +86 -83
  299. package/lib/runtime/validator-application.js +2 -2
  300. package/lib/scaffold/plan.js +2 -0
  301. package/package.json +1 -1
  302. package/runtime/core/lib/companion/events.js +157 -0
  303. package/runtime/core/lib/companion/figure-state.js +38 -0
  304. package/runtime/core/lib/companion/journal.js +186 -0
  305. package/runtime/core/lib/companion/run-view.js +227 -0
  306. package/runtime/core/lib/control-evaluation/acceptance-criteria.js +2 -0
  307. package/runtime/core/lib/control-evaluation/closeout-readiness.js +24 -6
  308. package/runtime/core/lib/control-evaluation/decision-content-placeholder.js +4 -1
  309. package/runtime/core/lib/control-evaluation/gate-check.js +49 -7
  310. package/runtime/core/lib/control-evaluation/gate-policy-inputs.js +2 -0
  311. package/runtime/core/lib/control-evaluation/gate-policy-pure.js +7 -3
  312. package/runtime/core/lib/control-evaluation/prd-readiness.js +7 -2
  313. package/runtime/core/lib/control-evaluation/report-decision.js +9 -0
  314. package/runtime/core/lib/control-evaluation/traceability-readiness.js +57 -8
  315. package/runtime/core/lib/control-evaluation/ur-readiness.js +15 -2
  316. package/runtime/core/lib/control-inspect/artifact-readiness.js +5 -3
  317. package/runtime/core/lib/control-inspect/authoring-inputs.js +107 -22
  318. package/runtime/core/lib/control-inspect/cockpit-list.js +10 -8
  319. package/runtime/core/lib/control-inspect/cockpit-session.js +11 -3
  320. package/runtime/core/lib/control-inspect/cockpit-work.js +4 -2
  321. package/runtime/core/lib/control-inspect/cockpit.js +47 -33
  322. package/runtime/core/lib/control-inspect/contract.js +64 -24
  323. package/runtime/core/lib/control-inspect/material-recording-calls.js +54 -0
  324. package/runtime/core/lib/control-inspect/project-state.js +2 -1
  325. package/runtime/core/lib/control-inspect/run-classification.js +31 -0
  326. package/runtime/core/lib/control-inspect/selection.js +6 -0
  327. package/runtime/core/lib/control-inspect/service.js +32 -5
  328. package/runtime/core/lib/control-inspect/work-situation.js +25 -0
  329. package/runtime/core/lib/control-read/cockpit-worker.js +1 -0
  330. package/runtime/core/lib/control-state/authoring-text-handoff.js +3 -0
  331. package/runtime/core/lib/control-state/input-resolution.js +7 -5
  332. package/runtime/core/lib/control-state/material-limits.js +4 -0
  333. package/runtime/core/lib/control-state/prepared-control-calls.js +137 -0
  334. package/runtime/core/lib/control-state/presentation-delivery.js +4 -1
  335. package/runtime/core/lib/control-state/run-command-contract.js +10 -4
  336. package/runtime/core/lib/control-state/run-command-schema.js +9 -3
  337. package/runtime/core/lib/control-state/run-command-service.js +35 -11
  338. package/runtime/core/lib/control-state/run-create-command.js +6 -1
  339. package/runtime/core/lib/control-state/run-identity.js +2 -0
  340. package/runtime/core/lib/control-state/run-inventory-reader.js +54 -5
  341. package/runtime/core/lib/control-state/run-inventory.js +12 -27
  342. package/runtime/core/lib/control-state/run-material.js +25 -7
  343. package/runtime/core/lib/control-state/run-presentation-render.js +113 -28
  344. package/runtime/core/lib/control-state/run-revision.js +38 -20
  345. package/runtime/core/lib/control-state/run-source-revisions.js +37 -17
  346. package/runtime/core/lib/control-state/run-state-reader.js +10 -3
  347. package/runtime/core/lib/control-state/run-steps.js +8 -5
  348. package/runtime/core/lib/control-state/run-title.js +43 -0
  349. package/runtime/core/lib/index.js +3 -1
  350. package/runtime/core/lib/interaction-catalog-validation.js +7 -1
  351. package/runtime/core/lib/interaction-catalog.js +8 -0
  352. package/runtime/core/lib/interaction-presentation.js +31 -10
  353. package/runtime/core/lib/mcp-input-hints.js +30 -1
  354. package/runtime/core/lib/mcp-tool-errors.js +5 -3
  355. package/runtime/core/lib/resources/canonical-init-plan.js +1 -1
  356. package/runtime/core/lib/runtime/plugin-provenance.js +9 -2
  357. package/runtime/core/lib/skill-dispatch/contract.js +6 -4
  358. package/runtime/core/lib/skill-dispatch/delivery-intake.js +3 -1
  359. package/runtime/core/lib/skill-dispatch/mcp-continuation.js +25 -2
  360. package/runtime/core/lib/skill-dispatch/prd-definition.js +3 -2
  361. package/runtime/core/lib/skill-dispatch/readiness-findings.js +7 -0
  362. package/runtime/core/lib/skill-dispatch/sd-definition.js +4 -2
  363. package/runtime/core/lib/skill-dispatch/service.js +17 -4
  364. package/runtime/core/lib/skill-dispatch/tp-definition.js +4 -2
  365. package/generated/plugins/agdf/companion/core.mjs +0 -16
  366. package/generated/plugins/agdf/companion/locales.json +0 -200
@@ -24,6 +24,24 @@ export function closeoutContext(text) {
24
24
  }
25
25
  export const closeoutContextDigest = text => digest(`agdf-closeout-context/1\0${canonicalJson(closeoutContext(text))}`);
26
26
 
27
+ // Bindings a structured OR states; the same tables drive the check and the
28
+ // expectations returned with a refusal.
29
+ const OR_SOURCE_FIELDS = Object.freeze({ related_ur: 'UR', related_prd: 'PRD', related_sd: 'SD', related_tp: 'TP', related_qa_report: 'QA' });
30
+ const OR_GATE_ROWS = Object.freeze(['UR', 'PRD', 'SD', 'TP', 'Brownfield Review', 'Brownfield Analysis', 'CD+Tests', 'CR', 'QA', 'UAT']);
31
+ const OR_MEMORY_TARGETS = Object.freeze(['context_graph', 'sot_registry', 'scope_artifact', 'open_questions', 'none']);
32
+ const gateRowExpectation = (state, type) => ({
33
+ status: state.approvals.has(type) ? state.approvals.get(type).status : state.artefacts.get(type)?.status,
34
+ reference: state.artefacts.get(type)?.path || state.approvals.get(type)?.evidence,
35
+ });
36
+ function structuredOrExpectations(state, route) {
37
+ return {
38
+ fields: { ...Object.fromEntries(Object.entries(OR_SOURCE_FIELDS).map(([field, type]) => [field, state.artefacts.get(type)?.path ?? null])),
39
+ mode_slice_decision: route, current_gate: 'OR', decision: 'pass', required_approval: 'none' },
40
+ gate_state_rows: Object.fromEntries(OR_GATE_ROWS.map(type => [type, gateRowExpectation(state, type)])),
41
+ memory_target: OR_MEMORY_TARGETS, memory_fields: 'memory_reason and memory_refs need concrete text',
42
+ };
43
+ }
44
+
27
45
  // Shared observation of registered OR and prepared OR candidates. Legacy reports retain
28
46
  // their documented formats; the new writer additionally requires the complete template.
29
47
  export function evaluateCloseoutReadiness(state, report, readArtefact, { prepared = false } = {}) {
@@ -85,14 +103,13 @@ export function evaluateCloseoutReadiness(state, report, readArtefact, { prepare
85
103
  ...Object.keys(context), 'next_allowed_action', 'required_approval', 'forbidden_until_then']) {
86
104
  if ([...report.matchAll(new RegExp(`^- ${field}:[ \\t]*(.*)$`, 'gmu'))].length !== 1) fail('or_field_ambiguous:' + field);
87
105
  }
88
- for (const [field, type] of Object.entries({ related_ur: 'UR', related_prd: 'PRD', related_sd: 'SD', related_tp: 'TP', related_qa_report: 'QA' })) {
106
+ for (const [field, type] of Object.entries(OR_SOURCE_FIELDS)) {
89
107
  if (value(report, field) !== state.artefacts.get(type)?.path) fail('or_source_reference_invalid:' + field);
90
108
  }
91
109
  if (value(report, 'mode_slice_decision') !== route || value(report, 'current_gate') !== 'OR' || value(report, 'decision') !== 'pass') fail('or_control_binding_invalid');
92
110
  const gateRows = tableRows(markdownSection(report, 'Gate State')).filter(row => row[0] !== 'Gate or step');
93
- for (const type of ['UR', 'PRD', 'SD', 'TP', 'Brownfield Review', 'Brownfield Analysis', 'CD+Tests', 'CR', 'QA', 'UAT']) {
94
- const rows = gateRows.filter(row => row[0] === type), expected = state.approvals.has(type) ? state.approvals.get(type).status : state.artefacts.get(type)?.status;
95
- const reference = state.artefacts.get(type)?.path || state.approvals.get(type)?.evidence;
111
+ for (const type of OR_GATE_ROWS) {
112
+ const rows = gateRows.filter(row => row[0] === type), { status: expected, reference } = gateRowExpectation(state, type);
96
113
  if (rows.length !== 1 || rows[0][1] !== expected || !concrete(rows[0][2])
97
114
  || cleanStatusCell(rows[0][2]) !== cleanStatusCell(reference)) fail('or_gate_state_unconfirmed:' + type);
98
115
  }
@@ -101,11 +118,12 @@ export function evaluateCloseoutReadiness(state, report, readArtefact, { prepare
101
118
  if (!concrete(text) || /<[^>]+>|\|[ \t]*\|/u.test(text)) fail('or_section_incomplete:' + section);
102
119
  }
103
120
  for (const section of ['Missing Evidence', 'Risks And Open Items']) if (/\|\s*(?:revise|block)\s*\|/u.test(markdownSection(report, section))) fail('or_required_obligation_open:' + section);
104
- if (!['context_graph', 'sot_registry', 'scope_artifact', 'open_questions', 'none'].includes(context.memory_target)
121
+ if (!OR_MEMORY_TARGETS.includes(context.memory_target)
105
122
  || !concrete(context.memory_reason) || !concrete(context.memory_refs)) fail('or_knowledge_decision_incomplete');
106
123
  if (value(report, 'required_approval') !== 'none') fail('or_required_approval_open');
107
124
  }
108
125
  }
109
126
  return { ready: findings.length === 0, findings, route, context_digest: closeoutContextDigest(report),
110
- parent_reconciliation: parent ?? null, programme_aggregation: programme ?? null };
127
+ parent_reconciliation: parent ?? null, programme_aggregation: programme ?? null,
128
+ ...(prepared && structured && findings.length ? { expected: structuredOrExpectations(state, route) } : {}) };
111
129
  }
@@ -2,8 +2,11 @@
2
2
  // run inventory and other `node:`-free readers share the same rule.
3
3
  const prompts = new Set(['describe the trustworthy outcome.', 'what outcome should become possible?',
4
4
  'which tp tasks are fully done, partially done or not done?', 'what remains unverified?', 'which risks remain and what is their impact?']);
5
+ // A bare generated Run ID (`run-<operation uuid>`) names the Run but states no outcome.
6
+ const generatedRunId = /^run-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/u;
5
7
  export function isDecisionContentPlaceholder(value) {
6
8
  if (typeof value !== 'string') return true;
7
9
  const text = value.trim().replace(/^`([^`]+)`$/u, '$1').replace(/\s+/gu, ' ').toLowerCase();
8
- return !text || prompts.has(text) || /^(?:todo|tbd|<[^>]+>|(?:draft|done|ready|blocked|pass|revise|block)(?:\s*\|\s*(?:draft|done|ready|blocked|pass|revise|block))+)$/.test(text);
10
+ return !text || prompts.has(text) || generatedRunId.test(text)
11
+ || /^(?:todo|tbd|<[^>]+>|(?:draft|done|ready|blocked|pass|revise|block)(?:\s*\|\s*(?:draft|done|ready|blocked|pass|revise|block))+)$/.test(text);
9
12
  }
@@ -9,7 +9,8 @@ import { isGateSatisfied, transitionDecisionForRunState } from "./gate-policy.js
9
9
  import { effectiveNextAllowedAction } from "./next-action.js";
10
10
  import { evaluateVerifiedChange, extractField, verifiedChangeEscalationTargets } from "./verified-change.js";
11
11
  import { gateApprovalStatus, isInternalStepSatisfied, modeSliceDecision, readArtefactHeading, readRunState, resolvedArtefactFile } from "./run-state.js";
12
- import { renderReviewableApproval } from "../control-state/run-presentation-render.js";
12
+ import { evaluateApprovalSummaryReadiness, renderApprovalSummaryIssue, renderReviewableApproval } from "../control-state/run-presentation-render.js";
13
+ import { readFileSync } from "../control-read/fs.js";
13
14
  import { evaluateUrReadiness } from "./ur-readiness.js";
14
15
  import { inspectDefinitionSources } from "./definition-sources.js";
15
16
  import { evaluatePrdReadiness } from "./prd-readiness.js";
@@ -158,7 +159,7 @@ export function isReadyUserGateApproval({ status, currentGate, missingApproval }
158
159
 
159
160
  function buildBreadcrumbPath(modeSliceDecision, currentGate, runState) {
160
161
  const gates = BREADCRUMB_PATH_TEMPLATES[modeSliceDecision] ?? ["UR"];
161
- return gates.map((gate) => {
162
+ return gates.map((gate, index) => {
162
163
  if (BREADCRUMB_STANDARD_GATES.includes(gate)) {
163
164
  if (gateApprovalStatus(runState, gate) === "approved") return { gate, status: "fulfilled" };
164
165
  if (gate === currentGate) return { gate, status: "current" };
@@ -169,6 +170,10 @@ function buildBreadcrumbPath(modeSliceDecision, currentGate, runState) {
169
170
  if (gate === currentGate) return { gate, status: "current" };
170
171
  if ((gate === "Verified Change" || gate === "Compact Delivery") && currentGate === "OR")
171
172
  return { gate, status: "fulfilled" };
173
+ // A path has one current entry: while an earlier gate is still the current one (a stored route
174
+ // with an unapproved UR), the route entry after it is open, not current by its route.
175
+ if (gates.slice(0, index).some((earlier) => earlier === currentGate && gateApprovalStatus(runState, earlier) !== "approved"))
176
+ return { gate, status: "open" };
172
177
  if (gate === "Verified Change" && modeSliceDecision === "verified_change")
173
178
  return { gate, status: "current" };
174
179
  if (gate === "Compact Delivery" && modeSliceDecision === "quick_task")
@@ -427,31 +432,58 @@ export function evaluateGateCheck(targetDir, selection = {}, dependencies = {})
427
432
  if (status === "open" && prdReadiness && transitionDecision.next_operation?.type !== "reassess_source_analysis" && isGateSatisfied(runState, "UR") && isInternalStepSatisfied(runState, "Brownfield Review")
428
433
  && ["structured_delivery", "structured_slice"].includes(modeSliceDecision(runState))) {
429
434
  const inputFacts = inspectDefinitionSources(targetDir, runState, extractField(runState.content, "run_id"), "PRD", ["UR", "Brownfield Review"]);
430
- if (inputFacts.issue) prdReadiness = { ready: false, open_decisions: [...prdReadiness.open_decisions,
435
+ if (inputFacts.issue) prdReadiness = { ...prdReadiness, ready: false, source_issue: inputFacts.issue, open_decisions: [...prdReadiness.open_decisions,
431
436
  renderDefinitionSourceRecovery(inputFacts.issue, { registry: interactionLocales, requestedLocale: presentationLocale })] };
432
437
  }
433
438
  if (status === "open" && currentGate === "PRD" && prdReadiness && !prdReadiness.ready) {
434
439
  status = "blocked";
440
+ const checks = prdReadiness.readiness_checks;
435
441
  blockingReason = "AGDF_PRD_DECISIONS_OPEN";
442
+ if (checks?.decisions_ready) {
443
+ const sourceCriteriaIncomplete = !checks.approval_summary.ready && [
444
+ "approval_summary_criterion_content_missing", "approval_summary_source_criteria_invalid",
445
+ "approval_summary_source_criteria_duplicate", "approval_summary_criteria_missing",
446
+ ].includes(checks.approval_summary.reason);
447
+ blockingReason = prdReadiness.source_issue || !checks.preview_ready || !checks.criteria_ready || sourceCriteriaIncomplete
448
+ ? "AGDF_PRD_READINESS_INCOMPLETE" : "AGDF_APPROVAL_SUMMARY_INCOMPLETE";
449
+ }
436
450
  allowed = ["complete the listed PRD readiness items together and record a new run revision"];
437
451
  forbidden = [...forbidden, "present or approve PRD before required decisions and acceptance criteria are ready"];
438
452
  // Fixed text keeps the card localizable; detailed gaps travel separately in prd_readiness.open_decisions.
439
453
  nextAllowedAction = "complete the open PRD readiness items together, then record the revision through the inspected current recording operation";
440
454
  }
441
- const sdReadiness = currentGate === "SD" && approvalArtefactReady ? evaluateSdReadiness(targetDir, runState) : null;
442
- const traceabilityReadiness = status === "open" && approvalArtefactReady && currentGate === "SD"
455
+ let sdReadiness = currentGate === "SD" && approvalArtefactReady ? evaluateSdReadiness(targetDir, runState) : null;
456
+ let traceabilityReadiness = status === "open" && approvalArtefactReady && currentGate === "SD"
443
457
  ? evaluateSdTraceability(targetDir, runState)
444
458
  : status === "open" && approvalArtefactReady && currentGate === "TP"
445
459
  ? evaluateTpTraceability(targetDir, runState)
446
460
  : null;
447
- if (status === "open" && sdReadiness && !sdReadiness.ready) {
461
+ // Presentation readiness belongs to the existing authoring gate, not to the
462
+ // traceability grammar. Use the same summary owner as preflight and rendering
463
+ // before a registered SD/TP draft can bypass its author and request approval.
464
+ let approvalSummaryReadiness = null;
465
+ if (status === "open" && approvalArtefactReady && ["SD", "TP"].includes(currentGate)) {
466
+ const path = runState.artefacts.get(currentGate).path;
467
+ const file = resolvedArtefactFile(targetDir, path);
468
+ const languages = resolveArtifactPresentationLanguages(targetDir, presentationLocale);
469
+ const summary = evaluateApprovalSummaryReadiness(currentGate, readFileSync(file, "utf8"), languages, { path });
470
+ if (!summary.ready) {
471
+ approvalSummaryReadiness = summary;
472
+ const issue = renderApprovalSummaryIssue(summary, { path, presentationLanguage: presentationLocale });
473
+ if (currentGate === "SD") sdReadiness = { ...sdReadiness, ready: false, decisions_ready: sdReadiness.ready,
474
+ open_decisions: [...sdReadiness.open_decisions, issue] };
475
+ else traceabilityReadiness = { ...traceabilityReadiness, ready: false, traceability_ready: traceabilityReadiness.ready,
476
+ open_items: [...traceabilityReadiness.open_items, issue] };
477
+ }
478
+ }
479
+ if (status === "open" && sdReadiness && !sdReadiness.ready && sdReadiness.decisions_ready !== true) {
448
480
  status = "blocked";
449
481
  blockingReason = "AGDF_SD_DECISIONS_OPEN";
450
482
  allowed = ["complete the listed SD readiness items together and record a new run revision"];
451
483
  forbidden = [...forbidden, "present or approve SD before required design decisions are ready"];
452
484
  nextAllowedAction = "complete the open SD readiness items together, then record the revision with the shared artefact writer";
453
485
  }
454
- if (status === "open" && traceabilityReadiness && !traceabilityReadiness.ready) {
486
+ if (status === "open" && traceabilityReadiness && !traceabilityReadiness.ready && traceabilityReadiness.traceability_ready !== true) {
455
487
  status = "blocked";
456
488
  blockingReason = currentGate === "SD" ? "AGDF_SD_TRACEABILITY_INCOMPLETE" : "AGDF_TP_TRACEABILITY_INCOMPLETE";
457
489
  allowed = [currentGate === "SD"
@@ -462,6 +494,15 @@ export function evaluateGateCheck(targetDir, selection = {}, dependencies = {})
462
494
  ? "complete the listed SD traceability rows, then record the revision through the inspected current recording operation"
463
495
  : "complete the listed TP traceability rows, then record the revision through the inspected current recording operation";
464
496
  }
497
+ if (status === "open" && approvalSummaryReadiness) {
498
+ status = "blocked";
499
+ blockingReason = "AGDF_APPROVAL_SUMMARY_INCOMPLETE";
500
+ }
501
+ if (blockingReason === "AGDF_APPROVAL_SUMMARY_INCOMPLETE") {
502
+ allowed = ["complete the current artefact approval summary and record a new run revision"];
503
+ forbidden = [...forbidden, "present or approve the current artefact before its required approval summary is ready"];
504
+ nextAllowedAction = "complete the current artefact approval summary, then record the revision through the inspected current recording operation";
505
+ }
465
506
  if (status === "open" && /^Approval: /u.test(missingApproval) && !approvalArtefactReady) {
466
507
  allowed = allowed.filter((action) => !/^request exact .* approval$/iu.test(action));
467
508
  if (/request exact approval: Approval: /iu.test(nextAllowedAction)) {
@@ -662,6 +703,7 @@ export function evaluateGateCheck(targetDir, selection = {}, dependencies = {})
662
703
  ...(prdReadiness ? { prd_readiness: prdReadiness } : {}),
663
704
  ...(sdReadiness ? { sd_readiness: sdReadiness } : {}),
664
705
  ...(traceabilityReadiness ? { traceability_readiness: traceabilityReadiness } : {}),
706
+ ...(approvalSummaryReadiness ? { approval_summary_readiness: approvalSummaryReadiness } : {}),
665
707
  next_gate_after_approval: postApproval.next_gate_after_approval,
666
708
  allowed_after_approval: postApproval.allowed_after_approval,
667
709
  allowed,
@@ -6,6 +6,8 @@ export function extractField(content, field) {
6
6
 
7
7
  export const verifiedChangeEscalationTargets = new Set(["structured_slice", "structured_delivery"]);
8
8
  export const STRUCTURED_REQUIRED_REVIEWS = Object.freeze(['TP Review', 'Clean Implementation Review']);
9
+ // The skill that owns each required review report.
10
+ export const REVIEW_SKILLS = Object.freeze({ 'TP Review': 'task-plan-review', 'Clean Implementation Review': 'clean-implementation-review' });
9
11
  // `Clean Review` is the supported legacy name of the Clean Implementation Review row.
10
12
  export const reviewArtefactType = (state, step) => step === 'Clean Implementation Review' && !state.artefacts.get(step)?.path
11
13
  && state.artefacts.get('Clean Review')?.path ? 'Clean Review' : step;
@@ -1,6 +1,6 @@
1
1
  import { extractField, verifiedChangeEscalationTargets } from "./gate-policy-inputs.js";
2
2
  import { gateApprovalStatus, gateArtefactStatus, isDurableGateArtefactSatisfied, isInternalStepSatisfied, modeSliceDecision } from "./run-state-policy.js";
3
- import { STRUCTURED_REQUIRED_REVIEWS, reviewArtefactType } from "./gate-policy-inputs.js";
3
+ import { REVIEW_SKILLS, STRUCTURED_REQUIRED_REVIEWS, reviewArtefactType } from "./gate-policy-inputs.js";
4
4
 
5
5
 
6
6
  // Shared policy over prepared facts. The Core supplies its validated receipt reader;
@@ -310,8 +310,9 @@ function gateDecisionForRunState(runState, verifiedChange = null) {
310
310
  const acceptedPlanDeviation = runState.qa_acceptance?.eligible || runState.qa_acceptance?.accepted;
311
311
  const structuredBeforeQaApproval = ["structured_slice", "structured_delivery"].includes(modeSliceDecision(runState))
312
312
  && gateApprovalStatus(runState, "QA") !== "approved";
313
- if (structuredBeforeQaApproval && STRUCTURED_REQUIRED_REVIEWS.some(step => !isInternalStepSatisfied(runState, reviewArtefactType(runState, step))
314
- && !(step === "TP Review" && acceptedPlanDeviation && runState.artefacts.get(step)?.status === "revise"))) {
313
+ const pendingReview = structuredBeforeQaApproval && STRUCTURED_REQUIRED_REVIEWS.find(step => !isInternalStepSatisfied(runState, reviewArtefactType(runState, step))
314
+ && !(step === "TP Review" && acceptedPlanDeviation && runState.artefacts.get(step)?.status === "revise"));
315
+ if (pendingReview) {
315
316
  return {
316
317
  status: "open",
317
318
  current_gate: "QA",
@@ -320,6 +321,9 @@ function gateDecisionForRunState(runState, verifiedChange = null) {
320
321
  allowed: ["record TP Review and Clean Implementation Review", "run QA gate"],
321
322
  forbidden: ["request QA approval", "request UAT approval", "release", "claim delivery readiness"],
322
323
  next_allowed_action: "Record TP Review and Clean Implementation Review before requesting Approval: QA.",
324
+ // Names the review owed next so authoring offers that report's forms, not the QA report's.
325
+ next_operation: { type: "record_required_review", skill_id: REVIEW_SKILLS[pendingReview], operation_key: "review.record",
326
+ actor: "agent", effect: "preparation", gate: "QA", internal_step: pendingReview },
323
327
  };
324
328
  }
325
329
  // A QA report recorded before current evidence (for example reviews recorded after it)
@@ -22,7 +22,8 @@ export function evaluatePrdReadiness(targetDir, runState, { presentationLanguage
22
22
  return { ready: false, open_decisions: ["Approval Decisions table is empty or malformed"] };
23
23
  }
24
24
  const open = [];
25
- try { previewForState(targetDir, runState); } catch (error) { open.push(error.message); }
25
+ let previewReady = true, previewIssue;
26
+ try { previewForState(targetDir, runState); } catch (error) { previewReady = false; previewIssue = error.message; }
26
27
  const seen = new Set();
27
28
  const incomplete = (value) => !value || /^(?:<|tbd\b|to confirm\b)/iu.test(value);
28
29
  for (const [decision, timing, status, resolution, owner, ...extra] of rows.slice(2)) {
@@ -38,6 +39,8 @@ export function evaluatePrdReadiness(targetDir, runState, { presentationLanguage
38
39
  // [ \t] rather than \s: an empty Owner line must not capture the following line.
39
40
  const owner = content.match(/^Owner:[ \t]*(.*)$/mu)?.[1]?.trim();
40
41
  if (incomplete(owner) || /\bto confirm\b|named individual/iu.test(owner)) open.unshift("Named PRD owner");
42
+ const decisionsReady = open.length === 0;
43
+ if (!previewReady) open.unshift(previewIssue);
41
44
  const criteria = evaluatePrdCriteriaReadiness(content);
42
45
  open.push(...criteria.open_items);
43
46
  // Use the presentation owner's validator before a registered draft can take the ready route.
@@ -47,5 +50,7 @@ export function evaluatePrdReadiness(targetDir, runState, { presentationLanguage
47
50
  if (!summary.ready) open.push(renderApprovalSummaryIssue(summary, {
48
51
  path, presentationLanguage: languages.presentation_language,
49
52
  }));
50
- return { ready: open.length === 0, open_decisions: open };
53
+ return { ready: open.length === 0, open_decisions: open,
54
+ readiness_checks: { decisions_ready: decisionsReady, preview_ready: previewReady, criteria_ready: criteria.ready,
55
+ approval_summary: summary } };
51
56
  }
@@ -222,6 +222,15 @@ export function readAuthoredContent(text, profile, { locale, sourceLanguage } =
222
222
  return sections === 1 && (spec.paragraph ? lines.length : Object.keys(fields).length) ? spec.paragraph ? lines.join(' ') : fields : null;
223
223
  }
224
224
 
225
+ // Authoring guidance owned next to the parser that enforces it. Only a level-1
226
+ // title's metadata or a level-2 "Decision" section carries the result; a
227
+ // "## Code Review" style heading closes the readable metadata block.
228
+ export const REPORT_DECISION_FORMAT = Object.freeze({
229
+ section: '## Decision',
230
+ field: '- decision: <pass|revise|block>',
231
+ instruction: 'State the result in a level-2 "## Decision" section whose first line is "- decision: <value>". The value must equal the decision supplied when recording. A result under any other heading is not read.',
232
+ });
233
+
225
234
  // Observe an authored technical result, never decide or approve QA. The closed
226
235
  // internal opt-in preserves analysis not_applicable; QA's domain stays unchanged.
227
236
  export function readReportDecision(text, { allowNotApplicable = false } = {}) {
@@ -45,6 +45,49 @@ function designDecisionIds(value) {
45
45
  return text.split(",").map((item) => item.trim().toUpperCase());
46
46
  }
47
47
 
48
+ const JSON_TYPE_METAVARIABLE = /^<(?:uuid|string|non-empty string|number|integer|(?:positive|non-negative) (?:integer|number)|boolean|null|object|array)>$/iu;
49
+
50
+ // Only typed JSON string values in an explicitly labelled schema/example are
51
+ // metavariables. Literal JSON keys may name words such as "todo"; angle-bracket
52
+ // key prompts, unknown values, arbitrary code and author fields stay checked.
53
+ function schemaExampleText(code) {
54
+ let parsed;
55
+ try { parsed = JSON.parse(code); } catch { return code; }
56
+ if (parsed === null || typeof parsed !== 'object') return code;
57
+ return code.replace(/"(?:\\.|[^"\\])*"/gu, (quoted, offset) => {
58
+ const key = /^[ \t]*:/u.test(code.slice(offset + quoted.length));
59
+ const value = JSON.parse(quoted);
60
+ if (key && !/<[^>]+>/u.test(value)) return '"literal-key"';
61
+ return JSON.stringify(!key && JSON_TYPE_METAVARIABLE.test(value) ? value.slice(1, -1) : value);
62
+ });
63
+ }
64
+
65
+ // A quoted command such as `done <id>` is concrete CLI syntax. Schema examples
66
+ // are permitted only in the decision clause, never instead of its rationale or
67
+ // consequence. The source text itself is never changed.
68
+ function unfinishedDecisionPrompts(value, { schemaExamples = false } = {}) {
69
+ const text = value.replace(/`([^`\n]+)`/gu, (span, code, offset) => {
70
+ if (/^[a-z][a-z0-9._/-]*(?:[ \t]+(?:--?[a-z0-9][a-z0-9_-]*|[a-z0-9._/-]+|<[a-z][a-z0-9_-]*>))+$/iu.test(code))
71
+ return code.replace(/<([a-z][a-z0-9_-]*)>/giu, '$1');
72
+ if (schemaExamples && /\b(?:(?:json[ \t]+)?schema(?:[ \t]+example)?|json[ \t]+example)[ \t]*[:=]?[ \t]*$/iu.test(value.slice(0, offset)))
73
+ return schemaExampleText(code);
74
+ return span;
75
+ });
76
+ // Preserve the original unfinished-field prefix guard even when an author
77
+ // has not closed its opening angle bracket yet.
78
+ return [...new Set(text.match(/<[^>]+>|^<[^>\s;]*|\b(?:tbd|to confirm|todo)\b/giu) ?? [])];
79
+ }
80
+
81
+ function decisionClauses(detail) {
82
+ // Semicolons or field-looking strings inside literal examples cannot declare
83
+ // the required author fields. Keep character offsets into the original text.
84
+ const labels = [...detail.replace(/`[^`\n]+`/gu, span => '_'.repeat(span.length))
85
+ .matchAll(/(?:^|;[ \t]*)(rationale|consequence|trade-off):[ \t]*/giu)];
86
+ return [{ field: 'decision', text: detail.slice(0, labels[0]?.index ?? detail.length).trim() },
87
+ ...labels.map((label, index) => ({ field: label[1].toLowerCase() === 'rationale' ? 'rationale' : 'consequence',
88
+ text: detail.slice(label.index + label[0].length, labels[index + 1]?.index ?? detail.length).trim() }))];
89
+ }
90
+
48
91
  function architectureDecisionIds(markdown) {
49
92
  const body = section(markdown, "Architecture Decisions");
50
93
  const openItems = [];
@@ -54,7 +97,7 @@ function architectureDecisionIds(markdown) {
54
97
  for (const line of body.split("\n").map((item) => item.trim()).filter((item) => /^[-*]\s+/u.test(item))) {
55
98
  const decision = line.replace(/^[-*]\s+/u, "").trim();
56
99
  if (/^none\b/iu.test(decision)) {
57
- if (!reasonedNone(decision) || /<[^>]+>|\b(?:tbd|to confirm|todo)\b/iu.test(decision)) {
100
+ if (!reasonedNone(decision) || unfinishedDecisionPrompts(decision).length) {
58
101
  openItems.push("State why no binding SD decision is needed after 'none'");
59
102
  }
60
103
  if (none || ids.length) openItems.push("SD cannot combine 'none' with binding design decisions");
@@ -70,12 +113,18 @@ function architectureDecisionIds(markdown) {
70
113
  if (none) openItems.push("SD cannot combine 'none' with binding design decisions");
71
114
  if (ids.includes(id)) openItems.push(`Duplicate SD design decision ID: ${id}`);
72
115
  ids.push(id);
73
- const detail = match[2];
74
- const rationale = detail.match(/(?:^|;\s*)rationale:\s*([^;]+)/iu)?.[1]?.trim();
75
- const consequence = detail.match(/(?:^|;\s*)(?:consequence|trade-off):\s*([^;]+)/iu)?.[1]?.trim();
76
- if (unfinished(detail) || /<[^>]+>|\b(?:tbd|to confirm|todo)\b/iu.test(detail)
77
- || unfinished(rationale) || unfinished(consequence)) {
78
- openItems.push(`SD design decision ${id} needs a concrete rationale and consequence`);
116
+ const clauses = decisionClauses(match[2]);
117
+ for (const field of ['decision', 'rationale', 'consequence']) {
118
+ const declarations = clauses.filter(clause => clause.field === field);
119
+ if (declarations.length > 1)
120
+ openItems.push(`SD design decision ${id} needs exactly one nonempty ${field}: field; found ${declarations.length} declarations`);
121
+ else if (!declarations.length || !declarations[0].text)
122
+ openItems.push(field === 'decision' ? `SD design decision ${id} needs a concrete decision statement`
123
+ : `SD design decision ${id} is missing a nonempty ${field}: field`);
124
+ }
125
+ for (const clause of clauses) {
126
+ const prompts = unfinishedDecisionPrompts(clause.text, { schemaExamples: clause.field === 'decision' });
127
+ if (prompts.length) openItems.push(`SD design decision ${id} contains unresolved author prompts in ${clause.field}: ${prompts.slice(0, 8).map(token => JSON.stringify(token)).join(', ')}${prompts.length > 8 ? ` (${prompts.length - 8} more)` : ''}`);
79
128
  }
80
129
  }
81
130
  if (!ids.length && !none) openItems.push("List binding SD decisions by SDD ID, or record a reasoned none");
@@ -192,7 +241,7 @@ export function evaluateTpTraceability(targetDir, runState) {
192
241
  for (const column of ["expected_result", "evidence"]) if (unfinished(row[column])) openItems.push(`TP scenario ${scenario || "without id"} needs ${column}`);
193
242
  const expectedDecisions = decisionsByCriterion.get(criterion) ?? [];
194
243
  if (expectedDecisions.length) {
195
- if (!expectedDecisions.includes(decision)) openItems.push(`TP scenario ${scenario || "without id"} must reference an SD decision for ${criterion}`);
244
+ if (!expectedDecisions.includes(decision)) openItems.push(`TP scenario ${scenario || "without id"} for ${criterion} has design_decision_id ${decision || "empty"}; set that table column to one of the mapped SD IDs: ${expectedDecisions.join(", ")}. Scenario prose cannot replace this cell.`);
196
245
  else {
197
246
  if (!verifiedDecisions.has(criterion)) verifiedDecisions.set(criterion, new Set());
198
247
  verifiedDecisions.get(criterion).add(decision);
@@ -37,10 +37,13 @@ export function evaluateUrContentReadiness(content, { languages, path = 'UR.md',
37
37
  const [heading, ...body] = block.split(/\r?\n/u);
38
38
  return { heading: heading.replace(/^\d+\.[ \t]*/u, "").trim(), body: body.join("\n").trim() };
39
39
  });
40
+ const placeholders = {};
40
41
  for (const section of sections) {
41
42
  const matches = blocks.filter(block => block.heading === section);
42
43
  const body = matches[0]?.body ?? "";
43
- if (matches.length !== 1 || !body || templatePrompts.has(body) || /<[^>]+>|^(?:tbd|todo|to confirm)[ \t]*$/imu.test(body)) open.push(section);
44
+ const unfinished = unfinishedPlaceholders(body);
45
+ if (unfinished.length) placeholders[section] = unfinished;
46
+ if (matches.length !== 1 || !body || templatePrompts.has(body) || unfinished.length || /^(?:tbd|todo|to confirm)[ \t]*$/imu.test(body)) open.push(section);
44
47
  }
45
48
  const summary = evaluateApprovalSummaryReadiness("UR", content, languages);
46
49
  if (!summary.ready) open.push(summary.required_heading);
@@ -48,5 +51,15 @@ export function evaluateUrContentReadiness(content, { languages, path = 'UR.md',
48
51
  if (summary.reason === "approval_summary_field_unreadable") open.push(renderApprovalSummaryIssue(summary, {
49
52
  path, presentationLanguage: languages.presentation_language,
50
53
  }));
51
- return { ready: open.length === 0, legacy: false, open_items: open, approval_summary: summary };
54
+ return { ready: open.length === 0, legacy: false, open_items: open, approval_summary: summary,
55
+ ...(Object.keys(placeholders).length ? { unfinished_placeholders: placeholders } : {}) };
56
+ }
57
+
58
+ // Inline code may name syntax metavariables, as in `node wordfreq.js <file>` or
59
+ // `<word> <count>`. A single identifier in angle brackets inside a code span is
60
+ // literal notation; prose placeholders and spaced prompts such as `<why ...>`
61
+ // stay unfinished. The UR template carries no code-span prompts to hide.
62
+ function unfinishedPlaceholders(body) {
63
+ const notation = body.replace(/`([^`\n]+)`/gu, (_span, code) => code.replace(/<[\p{L}][\p{L}\p{N}_-]*>/gu, ""));
64
+ return [...new Set(notation.match(/<[^>]+>/gu) ?? [])];
52
65
  }
@@ -9,7 +9,7 @@ import { evaluateUrReadiness } from '../control-evaluation/ur-readiness.js';
9
9
  import { evaluateSdReadiness } from '../control-evaluation/sd-readiness.js';
10
10
  import { evaluateSdTraceability, evaluateTpTraceability } from '../control-evaluation/traceability-readiness.js';
11
11
  import { resolveArtifactPresentationLanguages } from '../resources/context.js';
12
- import { evaluateApprovalSummaryReadiness } from '../control-state/run-presentation-render.js';
12
+ import { evaluateApprovalSummaryReadiness, renderApprovalSummaryIssue } from '../control-state/run-presentation-render.js';
13
13
  import { artefactFileDigest, runSealState } from '../control-state/run-seal.js';
14
14
  import { containedRegularFile, hasSymlinkComponent } from '../control-state/contained-file.js';
15
15
  import { extractField } from '../control-evaluation/verified-change.js';
@@ -26,7 +26,8 @@ export function describeArtifactReadiness(result) {
26
26
  'approval_summary_criteria_incomplete', 'approval_summary_user_goal_missing', 'approval_summary_scope_missing',
27
27
  'approval_summary_decisions_missing', 'approval_summary_criterion_content_missing', 'approval_summary_content_missing']);
28
28
  let findings = result.diagnostics.filter(row => names.has(row.code));
29
- const readinessOwner = { AGDF_UR_REQUIREMENTS_INCOMPLETE: 'ur', AGDF_PRD_DECISIONS_OPEN: 'prd',
29
+ const readinessOwner = { AGDF_UR_REQUIREMENTS_INCOMPLETE: 'ur', AGDF_PRD_DECISIONS_OPEN: 'prd', AGDF_PRD_READINESS_INCOMPLETE: 'prd',
30
+ AGDF_APPROVAL_SUMMARY_INCOMPLETE: { PRD: 'prd', SD: 'sd', TP: 'traceability' }[result.gate],
30
31
  AGDF_SD_DECISIONS_OPEN: 'sd', AGDF_SD_TRACEABILITY_INCOMPLETE: 'traceability', AGDF_TP_TRACEABILITY_INCOMPLETE: 'traceability' };
31
32
  const key = readinessOwner[result.blocking_reason];
32
33
  const details = key && result.current_gate === result.gate && result.readiness_details?.[key];
@@ -88,7 +89,8 @@ export function projectArtifactReadiness(root, { runId, gate, expectedRevisionId
88
89
  const languages = resolveArtifactPresentationLanguages(targetRoot, presentationLanguage);
89
90
  const summary = evaluateApprovalSummaryReadiness(gate, content, languages);
90
91
  checks.push({ name: 'approval_summary', ...summary });
91
- if (!summary.ready) diagnostics.push({ code: summary.reason, message: `Prepare ${summary.required_heading} using the existing summary rules.` });
92
+ if (!summary.ready) diagnostics.push({ code: summary.reason,
93
+ message: renderApprovalSummaryIssue(summary, { path, presentationLanguage: languages.presentation_language }) });
92
94
  // Supply only an in-memory draft pointer; no Run, approval or binding is written.
93
95
  const candidate = { ...state, artefacts: new Map(state.artefacts) };
94
96
  candidate.artefacts.set(gate, { path, status: 'draft' });