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
@@ -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' });
@@ -1,4 +1,9 @@
1
+ import { MATERIAL_LIMITS } from '../control-state/material-limits.js';
2
+ import { AUTHORING_TEXT_HANDOFF } from '../control-state/authoring-text-handoff.js';
3
+ import { approvalSummaryAuthoringFormat } from '../control-state/run-presentation-render.js';
4
+ import { resolveArtifactPresentationLanguages } from '../resources/context.js';
1
5
  import { runDocumentPath } from '../control-state/run-identity.js';
6
+ import { preparedCommandCall } from '../control-state/prepared-control-calls.js';
2
7
  import { inspectArtefactRecordingMode } from '../control-state/run-artefact-recording.js';
3
8
  import { readFileSync, statSync } from '../control-read/fs.js';
4
9
  import { captureControlScope } from '../control-read/snapshot.js';
@@ -14,6 +19,7 @@ import { evaluateGateCheck } from '../control-evaluation/gate-check.js';
14
19
  import { inspectPlannedEntry, inspectPlannedSelection } from '../control-state/planned-entry.js';
15
20
  import { assertPlannedNotTransferred } from '../control-state/planned-origin-reader.js';
16
21
  import { parseControlState } from '../control-state/run-state-parser.js';
22
+ import { CLOSEOUT_AUTHORING_SCOPE, isCompletedStructuredCloseout } from './selection.js';
17
23
 
18
24
  const templateId = gate => ({ UR: 'UR', PRD: 'PRD', SD: 'SD', TP: 'TP', QA: 'QA_REPORT', OR: 'OR',
19
25
  'Brownfield Review': 'BROWNFIELD_REVIEW', 'Brownfield Analysis': 'BROWNFIELD_REVIEW', 'Mode/Slice Decision': 'BROWNFIELD_REVIEW',
@@ -24,29 +30,37 @@ const templateId = gate => ({ UR: 'UR', PRD: 'PRD', SD: 'SD', TP: 'TP', QA: 'QA_
24
30
  export function inspectAuthoringInputs(root, input, { gitObservation } = {}) {
25
31
  const unavailable = reason => ({ available: false, reason, authorizes: false });
26
32
  try {
27
- const observeGit = () => !input.planning && gitObservation ? { head: gitObservation.gitValue(root, ['rev-parse', 'HEAD']),
33
+ const scopedCloseout = input.authoring_scope === CLOSEOUT_AUTHORING_SCOPE;
34
+ const observeGit = () => ({ head: gitObservation.gitValue(root, ['rev-parse', 'HEAD']),
28
35
  tracked: gitObservation.gitPathList(root, ['diff', 'HEAD', '--name-only']),
29
- untracked: gitObservation.gitPathList(root, ['ls-files', '--others', '--exclude-standard']) } : null;
30
- const git = observeGit(), observedGit = git ? { gitValue: () => git.head,
31
- gitPathList: (_root, args) => args[0] === 'diff' ? git.tracked : git.untracked } : undefined;
36
+ untracked: gitObservation.gitPathList(root, ['ls-files', '--others', '--exclude-standard']) });
37
+ let git;
38
+ const currentGit = () => git ??= observeGit();
39
+ const observedGit = !input.planning && gitObservation ? { gitValue: () => currentGit().head,
40
+ gitPathList: (_root, args) => args[0] === 'diff' ? currentGit().tracked : currentGit().untracked } : undefined;
32
41
  const captured = captureControlScope(root, () => {
42
+ const languages = resolveArtifactPresentationLanguages(root, input.presentation_language);
33
43
  if (input.planning) {
34
44
  inspectPlannedSelection(root, input.planning, { presentationLanguage: input.presentation_language });
35
45
  const creating = input.planning.expected_digest === null;
36
46
  const entry = creating ? null : inspectPlannedEntry(root, input.planning.plan_id, { presentationLanguage: input.presentation_language });
37
47
  if (!creating) assertPlannedNotTransferred(root, input.planning.plan_id);
38
48
  const kind = creating ? 'planned_ur.create' : 'planned_ur.replace';
39
- return { gate: null, authoring_owner: 'UR', mode: 'planning', recording: { mode: creating ? 'create_planned' : 'replace_planned', kind },
49
+ return { languages, gate: null, authoring_owner: 'UR', mode: 'planning', recording: { mode: creating ? 'create_planned' : 'replace_planned', kind },
40
50
  next_operation: { type: 'author_planned_ur', skill_id: 'ur-definition', kind }, status: 'draft', blocking_reason: null,
41
51
  sources: entry ? [{ type: 'UR', path: entry.path, status: 'draft', digest: entry.digest, content: entry.content }] : [] };
42
52
  }
43
53
  const state = readRunState(root, { runId: input.run_id, ignoreRunIdEnv: true });
44
54
  if (state.resolution_error || state.meta?.revision_id !== input.expected_revision_id || runSealState(root, state.content).status !== 'valid') throw Error('authoring_binding_stale_or_invalid');
45
55
  const evaluated = evaluateGateCheck(root, { runId: input.run_id, ignoreRunIdEnv: true, presentationLanguage: input.presentation_language }, observedGit);
56
+ const mode = state.mode_slice_decision?.decision;
57
+ if (scopedCloseout && !isCompletedStructuredCloseout(evaluated, mode)) throw Error('authoring_closeout_unavailable');
46
58
  const protectedSources = parseControlState(state.content, { closeoutArtefacts: ['Planned UR Snapshot', 'Planned UR Origin'] }).artefacts;
47
59
  const rows = [...new Map([...state.artefacts, ...protectedSources])].filter(([, r]) => r.path).map(([type, row]) => ({ type, ...row }));
48
60
  if (rows.length > 32) throw Error('authoring_source_limit');
49
- const sources = rows.map(row => {
61
+ const selected = scopedCloseout ? rows.filter(row => row.type === 'OR' || row.type === 'QA') : rows;
62
+ if (scopedCloseout && selected.length !== 2) throw Error('authoring_closeout_unavailable');
63
+ const sources = selected.map(row => {
50
64
  const path = row.path.replace(/^`|`$/gu, '');
51
65
  if (!path.startsWith(`${runDocumentPath(input.run_id, '')}/`) || hasSymlinkComponent(root, path)) throw Error('authoring_source_unavailable');
52
66
  const file = containedRegularFile(root, path);
@@ -54,17 +68,19 @@ export function inspectAuthoringInputs(root, input, { gitObservation } = {}) {
54
68
  const content = new TextDecoder('utf-8', { fatal: true }).decode(readFileSync(file.path));
55
69
  return { type: row.type, path, status: row.status, digest: artefactFileDigest(root, path), content };
56
70
  });
71
+ if (scopedCloseout) return { languages, gate: evaluated.current_gate, mode, status: evaluated.status,
72
+ blocking_reason: evaluated.blocking_reason, next_operation: evaluated.next_operation, sources };
57
73
  // Match dispatch's initial UX prerequisite route as well as source reassessment.
58
74
  // Reuse its eligibility and contained-source facts; inspection grants no repair permission.
59
75
  const prdEligible = prdDefinitionEligible(evaluated, { ...input, skill_id: 'prd-definition' });
60
76
  const uxRequired = prdEligible && inspectDefinitionSources(root, state, input.run_id, 'PRD', ['UR', 'Brownfield Review']).issue?.repairable;
61
77
  const nextOperation = uxRequired ? { type: 'reassess_source_analysis', skill_id: 'ux-intent-definition', analysis: 'UX Intent Definition' } : evaluated.next_operation;
62
- return { gate: evaluated.current_gate, authoring_owner: nextOperation?.type === 'record_closeout' ? 'OR'
63
- : nextOperation?.analysis ?? nextOperation?.gate ?? evaluated.current_gate,
64
- recording: inspectArtefactRecordingMode(state, evaluated.current_gate), mode: state.mode_slice_decision?.decision, next_operation: nextOperation, status: evaluated.status,
78
+ return { languages, gate: evaluated.current_gate, authoring_owner: nextOperation?.type === 'record_closeout' ? 'OR'
79
+ : nextOperation?.analysis ?? nextOperation?.internal_step ?? nextOperation?.gate ?? evaluated.current_gate,
80
+ recording: inspectArtefactRecordingMode(state, evaluated.current_gate), mode, next_operation: nextOperation, status: evaluated.status,
65
81
  blocking_reason: evaluated.blocking_reason, sources };
66
82
  });
67
- const data = captured.data, ids = [data.gate === 'OR' && data.mode === 'verified_change' ? 'VERIFIED_CHANGE' : templateId(data.authoring_owner),
83
+ const data = captured.data, ids = scopedCloseout ? [] : [data.gate === 'OR' && data.mode === 'verified_change' ? 'VERIFIED_CHANGE' : templateId(data.authoring_owner),
68
84
  ...(['Brownfield Review', 'Mode/Slice Decision'].includes(data.gate) ? ['VERIFIED_CHANGE'] : [])].filter(Boolean);
69
85
  const templates = ids.map(id => {
70
86
  const path = resolveArtefactTemplatePath(id);
@@ -72,39 +88,108 @@ export function inspectAuthoringInputs(root, input, { gitObservation } = {}) {
72
88
  const content = new TextDecoder('utf-8', { fatal: true }).decode(readFileSync(path));
73
89
  return { role: 'template', type: id, digest: digest(canonicalRunText(content)), content, source: 'version_matched_plugin' };
74
90
  });
75
- const documents = [...templates, ...data.sources.map(s => ({ role: 'source', ...s }))];
91
+ const sources = data.sources.map(s => ({ role: 'source', ...s }));
92
+ const currentDraft = sources.find(source => source.type === data.authoring_owner);
93
+ // The source being corrected must not move behind unrelated, growing sources.
94
+ // Keep the legacy template-first view; bundles put the current source first.
95
+ const documents = input.bundle && currentDraft
96
+ ? [currentDraft, ...templates, ...sources.filter(source => source !== currentDraft)]
97
+ : [...templates, ...sources];
76
98
  if (documents.length > 32) throw Error('authoring_source_limit');
77
99
  const manifest = digest(JSON.stringify({ target_id: resolveControlCommandTarget(root).target_id, run_id: input.run_id,
78
100
  ...(input.planning ? { planning: input.planning } : {}),
79
- revision_id: input.expected_revision_id, gate: data.gate, authoring_owner: data.authoring_owner, recording: data.recording, documents: documents.map(({ content, ...r }) => r) })).slice(7);
101
+ ...(scopedCloseout ? { authoring_scope: input.authoring_scope } : {}),
102
+ revision_id: input.expected_revision_id, languages: data.languages, ...(input.bundle ? { bundle: 2 } : {}), gate: data.gate, authoring_owner: data.authoring_owner, recording: data.recording, documents: documents.map(({ content, ...r }) => r) })).slice(7);
80
103
  const chunks = [];
81
104
  for (const document of documents) {
82
105
  const { content, ...metadata } = document, bytes = Buffer.from(content);
106
+ if (input.bundle && !bytes.length) chunks.push({ ...metadata, content: '', byte_start: 0, byte_end: 0, total_bytes: 0 });
83
107
  for (let start = 0; start < bytes.length;) {
84
108
  let end = Math.min(start + 16384, bytes.length);
85
109
  while (end < bytes.length && (bytes[end] & 0xc0) === 0x80) end--;
86
- chunks.push({ ...metadata, content: bytes.subarray(start, end).toString('utf8'), byte_start: start, byte_end: end, total_bytes: bytes.length });
110
+ let chunk;
111
+ for (;;) {
112
+ chunk = { ...metadata, content: bytes.subarray(start, end).toString('utf8'), byte_start: start, byte_end: end, total_bytes: bytes.length };
113
+ if (!input.bundle || Buffer.byteLength(JSON.stringify([chunk])) <= 48128) break;
114
+ end = start + Math.floor((end - start) / 2);
115
+ while (end > start && (bytes[end] & 0xc0) === 0x80) end--;
116
+ if (end <= start) throw Error('authoring_metadata_limit');
117
+ }
118
+ chunks.push(chunk);
87
119
  start = end;
88
120
  }
89
121
  }
122
+ const pages = [];
123
+ if (input.bundle) {
124
+ for (const chunk of chunks) {
125
+ const last = pages.at(-1);
126
+ if (!last || Buffer.byteLength(JSON.stringify([...last, chunk])) > 48128) pages.push([chunk]);
127
+ else last.push(chunk);
128
+ }
129
+ }
130
+ const selection = input.bundle ? pages : chunks;
90
131
  const prefix = `${manifest}:`;
91
132
  if (input.cursor !== undefined && (!input.cursor.startsWith(prefix) || !/^(0|[1-9][0-9]*)$/u.test(input.cursor.slice(prefix.length)))) throw Error('authoring_cursor_stale_or_invalid');
92
133
  const index = input.cursor === undefined ? 0 : Number(input.cursor.slice(prefix.length));
93
- if (!Number.isSafeInteger(index) || index < 0 || index >= Math.max(chunks.length, 1)) throw Error('authoring_cursor_stale_or_invalid');
134
+ if (!Number.isSafeInteger(index) || index < 0 || index >= Math.max(selection.length, 1)) throw Error('authoring_cursor_stale_or_invalid');
135
+ if (git && JSON.stringify(observeGit()) !== JSON.stringify(git)) throw Error('authoring_binding_stale_or_invalid');
94
136
  captured.view.revalidate();
95
- if (JSON.stringify(observeGit()) !== JSON.stringify(git)) throw Error('authoring_binding_stale_or_invalid');
96
- const formats = input.planning ? operationContract('agdf_record', data.recording.kind) : data.authoring_owner === 'OR' ? operationContract('agdf_closeout', 'closeout.record')
137
+ const grouped = new Map();
138
+ for (const part of pages[index] ?? []) {
139
+ const key = JSON.stringify([part.role, part.type, part.path, part.digest]);
140
+ const prior = grouped.get(key);
141
+ if (prior) {
142
+ if (prior.byte_end !== part.byte_start) throw Error('authoring_fragment_order_invalid');
143
+ prior.content += part.content; prior.byte_end = part.byte_end;
144
+ } else grouped.set(key, { ...part });
145
+ }
146
+ const documentRows = [...grouped.values()].map(row => ({ ...row, complete: row.byte_start === 0 && row.byte_end === row.total_bytes }));
147
+ const documentPage = { documents: documentRows.filter(row => row.complete), fragments: documentRows.filter(row => !row.complete) };
148
+ if (input.bundle && Buffer.byteLength(JSON.stringify(documentPage)) > 49152) throw Error('authoring_page_limit');
149
+ const pageCall = page => ({ tool: 'agdf_inspect', arguments: { operation: 'authoring-inputs',
150
+ ...Object.fromEntries(['presentation_language', 'working_directory', 'primary_target', 'target_source', 'target_id',
151
+ 'run_id', 'expected_revision_id', 'planning', 'bundle', 'authoring_scope'].filter(key => input[key] !== undefined).map(key => [key, input[key]])),
152
+ cursor: `${prefix}${page}` } });
153
+ const nextPage = index + 1 < selection.length ? pageCall(index + 1) : null;
154
+ if (scopedCloseout) return { available: true, ...data.languages, run_id: input.run_id, revision_id: input.expected_revision_id,
155
+ gate: data.gate, mode: data.mode, status: data.status, blocking_reason: data.blocking_reason, next_operation: data.next_operation,
156
+ authoring_scope: input.authoring_scope, manifest_digest: `sha256:${manifest}`,
157
+ document_manifest: documents.map(({ content, ...metadata }) => metadata), format: 'document_bundle_v2',
158
+ ...documentPage, page_bytes_limit: 49152, page_index: index, page_count: Math.max(selection.length, 1),
159
+ complete: !nextPage, next_cursor: nextPage?.arguments.cursor ?? null, next_calls: nextPage ? [nextPage] : [], authorizes: false };
160
+ const draftRow = currentDraft && documentRows.find(row => row.role === 'source' && row.type === currentDraft.type && row.path === currentDraft.path && row.digest === currentDraft.digest);
161
+ const draftPage = input.bundle && currentDraft ? pages.findIndex(page => page.some(row => row.role === 'source'
162
+ && row.type === currentDraft.type && row.path === currentDraft.path && row.digest === currentDraft.digest && row.byte_start === 0)) : -1;
163
+ const registeredUr = data.authoring_owner === 'UR' && data.sources.some(source => source.type === 'UR' && source.path);
164
+ const formats = input.planning ? operationContract('agdf_record', data.recording.kind)
165
+ : registeredUr ? operationContract('agdf_revise', 'ur_draft.replace', { gate: 'UR' }) : data.authoring_owner === 'OR' ? operationContract('agdf_closeout', 'closeout.record')
97
166
  : operationContract('agdf_record', ['PRD', 'SD', 'TP', 'QA'].includes(data.authoring_owner) ? 'artefact.record' : 'step.record', { gate: data.authoring_owner });
98
- return { available: true, run_id: input.run_id, revision_id: input.expected_revision_id, gate: data.gate, mode: data.mode,
167
+ const summaryFormat = approvalSummaryAuthoringFormat(data.authoring_owner, currentDraft?.content ?? '', data.languages);
168
+ return { available: true, ...data.languages, run_id: input.run_id, revision_id: input.expected_revision_id, gate: data.gate, mode: data.mode,
99
169
  ...(input.planning ? { planning: input.planning, canonical_skill: 'ur-definition' } : {}),
100
170
  authoring_owner: data.authoring_owner, recording: data.recording,
171
+ ...(summaryFormat ? { approval_summary_format: summaryFormat } : {}),
172
+ ...(!input.planning && index === 0 ? { material_call: preparedCommandCall('agdf_record', 'material.stage',
173
+ { ...input, target_id: resolveControlCommandTarget(root).target_id }, { gate: data.authoring_owner }) } : {}),
101
174
  status: data.status, blocking_reason: data.blocking_reason, next_operation: data.next_operation,
102
- manifest_digest: `sha256:${manifest}`, documents: documents.map(({ content, ...r }) => r),
103
- chunk: chunks[index] ?? null, complete: index + 1 >= chunks.length, next_cursor: index + 1 < chunks.length ? `${prefix}${index + 1}` : null,
175
+ manifest_digest: `sha256:${manifest}`, ...(input.bundle ? { document_manifest: documents.map(({ content, ...r }) => r) } : { documents: documents.map(({ content, ...r }) => r) }),
176
+ ...(input.bundle ? { format: 'document_bundle_v2', ...documentPage, page_bytes_limit: 49152,
177
+ page_index: index, page_count: Math.max(selection.length, 1),
178
+ first_page_call: pageCall(0),
179
+ current_draft: currentDraft ? { type: currentDraft.type, path: currentDraft.path, status: currentDraft.status, digest: currentDraft.digest,
180
+ content_state: draftRow?.complete ? 'complete' : draftRow ? 'fragment' : 'not_on_page',
181
+ ...(draftPage >= 0 && (!draftRow || draftRow.byte_start > 0) ? { read_call: pageCall(draftPage) } : {}),
182
+ instruction: 'Metadata only, never document text or edit permission. Use the matching complete report.documents row. For a fragment, join matching report.fragments by byte offsets across next_calls before editing. If not_on_page or earlier fragment bytes were not retained, copy read_call.arguments unchanged to read its first page.' } : null }
183
+ : { chunk: chunks[index] ?? null }), complete: index + 1 >= selection.length,
184
+ next_cursor: index + 1 < selection.length ? `${prefix}${index + 1}` : null,
185
+ next_calls: nextPage ? [{ ...nextPage, instruction: 'Copy arguments unchanged to read the next page of this manifest. Retain earlier bytes; repeat until complete before editing a fragmented source. No JavaScript cloning or source/path discovery is needed.' }] : [],
104
186
  // The writer contract is identical on every page of one manifest; later pages only name it.
105
- formats: index === 0 ? formats : { schema_version: formats.schema_version, available: formats.available, group: formats.group, kind: formats.kind,
187
+ formats: index === 0 ? input.bundle ? (({ schema, result_schema, ...authoring }) => authoring)(formats) : formats : { schema_version: formats.schema_version, available: formats.available, group: formats.group, kind: formats.kind,
106
188
  omitted: 'identical to the first page of this manifest' },
107
- material_transport: { tool: 'agdf_record', kind: input.planning ? 'planned_material.stage' : 'material.stage', limits: { request_bytes: 65536, part_bytes: 16384, source_bytes: 131072 },
108
- instructions: 'Read all chunks. Stage exact permitted material; seal to obtain identity. Record via the eligible typed writer with explicit cooperative review. No file/path discovery or shell hashing.' }, authorizes: false };
189
+ material_transport: { tool: 'agdf_record', kind: input.planning ? 'planned_material.stage' : 'material.stage', limits: { request_bytes: 65536, inline_file_bytes: MATERIAL_LIMITS.inline, part_bytes: MATERIAL_LIMITS.part, source_bytes: MATERIAL_LIMITS.file },
190
+ instructions: (input.bundle
191
+ ? 'MCP access: response.structuredContent.report (or JSON.parse(response.content[0].text).report). Read complete report.documents[].content; report.document_manifest and current_draft are metadata only. The registered current draft is prioritized; inspect current_draft.content_state before looking for its complete document. Join report.fragments by identity and byte offsets across all next_calls pages before editing. Absent content is an error, never the string undefined. Copy call.arguments unchanged and supply only authored content in the named fields; no JavaScript helper is required. Preserve bundle:true. '
192
+ : 'MCP access: response.structuredContent.report (or JSON.parse(response.content[0].text).report). This legacy view puts text in report.chunk.content; report.documents is metadata only. Follow every next_cursor with this exact binding, or request bundle:true for fewer round trips. ')
193
+ + 'The included formats and bound forms replace a second operation-contract read. Retain unchanged sources for this manifest. Prefer material_call: put takes exact UTF-8 <=48 KiB per file within the 64 KiB JSON request bound and seals once. Use returned recording_calls, adding only required author/review inputs. Larger files use multipart; each action has its own UUID. Follow next_calls exactly. No file/path discovery or shell hashing. ' + AUTHORING_TEXT_HANDOFF }, authorizes: false };
109
194
  } catch (e) { return unavailable(e.code ?? e.message); }
110
195
  }
@@ -8,14 +8,16 @@ export function hasConsistentWorkCounts(inventory) {
8
8
  && inventory.entries.every(row => row && COCKPIT_WORK_SECTIONS.includes(row.section));
9
9
  }
10
10
  export function projectCockpitList(inventory, { section = 'active', query = '' } = {}) {
11
- if (!COCKPIT_WORK_SECTIONS.includes(section)) throw Error('dto_invalid');
11
+ if (section !== 'runs' && !COCKPIT_WORK_SECTIONS.includes(section)) throw Error('dto_invalid');
12
12
  const normalized = query.trim().toLowerCase();
13
13
  if (!inventory) return { section, query: normalized, coverage: 'unavailable', diagnostics: [], sectionCount: null, matchCount: 0, rows: [] };
14
14
  if (!hasConsistentWorkCounts(inventory)) throw Error('dto_invalid');
15
- const diagnostics = inventory.diagnostics.filter(row => !row.section || row.section === section);
16
- if (diagnostics.some(row => row.code === 'work_section_unavailable')) return { section, query: normalized, coverage: 'unavailable', diagnostics, sectionCount: null, matchCount: null, rows: [] };
17
- const selected = inventory.entries.map((entry, index) => ({ entry, index })).filter(row => row.entry.section === section);
18
- const rows = selected.filter(({ entry }) => !normalized || [entry.title, entry.key, entry.stored_status]
15
+ const sections = section === 'runs' ? ['active', 'completed'] : [section];
16
+ const diagnostics = inventory.diagnostics.filter(row => !row.section || sections.includes(row.section));
17
+ const unavailable = sections.filter(s => diagnostics.some(row => row.code === 'work_section_unavailable' && (!row.section || row.section === s)));
18
+ if (unavailable.length === sections.length) return { section, query: normalized, coverage: 'unavailable', diagnostics, sectionCount: null, matchCount: null, rows: [] };
19
+ const selected = inventory.entries.map((entry, index) => ({ entry, index })).filter(row => sections.includes(row.entry.section) && !unavailable.includes(row.entry.section));
20
+ const rows = selected.filter(({ entry }) => !normalized || [entry.title, entry.key, entry.stored_status, entry.objective ?? '']
19
21
  .some(value => value.toLowerCase().includes(normalized))).map(({ entry, index }) => ({ entry, index,
20
22
  identity: JSON.stringify([entry.identity, entry.source.digest]), selectable: entry.selectable, displayTitle: entry.title.replace(/^\[(framework[-_]maintenance|external[-_]delivery)\]\s*/i, '') || entry.title,
21
23
  provenance: { path: entry.source.path, digest: entry.source.digest, originalTitle: entry.title } }));
@@ -25,10 +27,10 @@ export function projectCockpitList(inventory, { section = 'active', query = '' }
25
27
 
26
28
  // Presentation-only grouping/search over the shared inventory's already ordered entries.
27
29
  export function projectCockpitRuns(inventory, { section = 'active', query = '' } = {}) {
28
- if (!['active', 'completed'].includes(section)) throw Error('dto_invalid');
30
+ if (!['active', 'completed', 'runs'].includes(section)) throw Error('dto_invalid');
29
31
  const normalized = query.trim().toLowerCase();
30
- const entries = inventory.runs.filter(run => section === 'active'
31
- ? !run.valid || run.lifecycle === 'active' : run.valid && run.lifecycle !== 'active');
32
+ const entries = inventory.runs.filter(run => section === 'runs' || (section === 'active'
33
+ ? !run.valid || run.lifecycle === 'active' : run.valid && run.lifecycle !== 'active'));
32
34
  const rows = entries.filter(run => !normalized || [run.title, run.run_id, run.attention.label]
33
35
  .some(value => value.toLowerCase().includes(normalized)));
34
36
  return { rows, sectionCount: entries.length, matchCount: rows.length,
@@ -11,11 +11,11 @@ import { COCKPIT_LIMITS, parseCockpitArguments, parsePluginCockpitArguments } fr
11
11
  // One connection owns bounded independent read views. Retiring workers still occupy slots.
12
12
  export function createCockpitSessionService(root, {
13
13
  budget, poolFactory = viewRoot => new ReadWorkerPool(viewRoot, { limits: { total: COCKPIT_LIMITS.capture },
14
- maxOldGenerationSizeMb: COCKPIT_LIMITS.workerOldGeneration, budget }), now = Date.now, pluginMode = false,
14
+ maxOldGenerationSizeMb: COCKPIT_LIMITS.workerOldGeneration, budget }), now = Date.now, pluginMode = false, integrationSurface,
15
15
  } = {}) {
16
16
  const target = pluginMode ? null : { target_id: resolveControlCommandTarget(root).target_id, display_path: root };
17
17
  const sessions = new Map();
18
- let closed = false, renderGeneration = 0, publication = null;
18
+ let closed = false, renderGeneration = 0, publication = null, resourceIdentity = null;
19
19
  const failure = (code, viewTarget = target) => ({ schema_version: '2', target: viewTarget, snapshot_id: null, observed_as_of: null,
20
20
  source_digest: null, state: 'blocked', code, retryable: code !== 'session_expired', data: null, authorizes: false });
21
21
  function losePublication(session) {
@@ -59,6 +59,12 @@ export function createCockpitSessionService(root, {
59
59
  function touch(session) { session.touched = now(); schedule(session); }
60
60
  return Object.freeze({
61
61
  failure,
62
+ bindResourceIdentity({ digest, version } = {}) {
63
+ if (resourceIdentity || sessions.size || !/^[a-f0-9]{64}$/u.test(digest ?? '')
64
+ || typeof version !== 'string' || !/^[0-9A-Za-z.+-]{1,80}$/u.test(version)) throw Error('resource_identity_invalid');
65
+ resourceIdentity = Object.freeze({ schema_version: '1', version, resource_digest: `sha256:${digest}`,
66
+ resource_scope: 'server_validated', host_display: 'unconfirmed', candidate_match: 'unverified' });
67
+ },
62
68
  inspectOwnership() {
63
69
  return { views: sessions.size, active: [...sessions.values()].filter(row => !row.retired).length,
64
70
  uncertain: publication?.phase === 'uncertain' ? 1 : 0 };
@@ -99,6 +105,8 @@ export function createCockpitSessionService(root, {
99
105
  sessions.set(session.id, session); schedule(session);
100
106
  return { schema_version: '1', authorizes: false, target: viewTarget,
101
107
  _meta: { agdf_cockpit: { session_id: session.id, target: viewTarget, render_generation: ++renderGeneration,
108
+ ...(['codex', 'claude'].includes(integrationSurface) ? { integration_surface: integrationSurface } : {}),
109
+ ...(resourceIdentity ? { provenance: resourceIdentity } : {}),
102
110
  ...(input.run_id ? { initial_run_id: input.run_id } : {}),
103
111
  idle_timeout_ms: COCKPIT_LIMITS.idle, lifetime_ms: COCKPIT_LIMITS.lifetime } } };
104
112
  },
@@ -154,7 +162,7 @@ export function createCockpitSessionService(root, {
154
162
  touch(session); return result;
155
163
  }
156
164
  if (['planned', 'archive'].includes(input.operation) && !session.rows.has(input.row_id)) return fail('resource_denied');
157
- if (['document', 'prepare_context'].includes(input.operation)
165
+ if (['document', 'preview', 'prepare_context'].includes(input.operation)
158
166
  && session.documents.get(input.resource_id) !== `${input.snapshot_id}:${input.run_id}`) return fail('resource_denied');
159
167
  if (['context', 'artifact_readiness'].includes(input.operation) && input.run_id !== session.run_id) return fail('resource_denied');
160
168
  if (input.operation === 'artifact_readiness' && (!session.draft?.available || session.draft.gate !== input.gate
@@ -7,13 +7,15 @@ import { COCKPIT_WORK_SECTIONS as sections } from './cockpit-list.js';
7
7
  // discriminator changes policy: order and per-row source identity come from Core,
8
8
  // never a Markdown table, stored rank, or adapter-specific lifecycle database.
9
9
  export function projectCockpitWork(root) {
10
- const inventory = readWorkInventory(root, { language: 'de' });
10
+ const inventory = readWorkInventory(root, { language: 'de', includePresentation: true, cockpitAssessment: true });
11
11
  if (inventory.state === 'unavailable') return { state: 'error', code: 'work_inventory_unavailable', data: null };
12
12
  const entries = inventory.entries.map(row => {
13
13
  const planned = row.kind === 'planned';
14
14
  const section = planned ? sections[1] : row.lifecycle === 'active' || row.lifecycle === null ? sections[0] : sections[2];
15
15
  const key = planned ? row.plan_id : row.run_id;
16
- return { kind: row.kind, identity: row.identity, section, key, original_key: key, title: row.title,
16
+ return { kind: row.kind, identity: row.identity, section, key, original_key: key, title: planned ? row.title : row.presentation?.name || key,
17
+ ...(!planned ? { title_source: row.presentation?.name ? 'ur' : 'run_id', objective: row.objective ?? null,
18
+ last_activity: row.last_activity, seal: row.presentation?.seal ?? 'unconfirmed', lifecycle: row.lifecycle, attention_code: row.attention.code } : {}),
17
19
  stored_status: planned ? ({ ready: 'Bereit zur Übergabe', draft: 'UR in Klärung', recovery_required: 'Wiederherstellung erforderlich', unconfirmed: 'Zuordnung ungeklärt', unavailable: 'Quelle nicht verfügbar' })[row.coverage]
18
20
  : row.attention.label, scope: planned ? 'UR-Planung' : 'Run', priority: row.priority ?? null,
19
21
  stored_next_step: planned ? row.actions.join(' · ') : row.next_action ?? '', source_links: row.source.path,
@@ -1,5 +1,5 @@
1
1
  import { readCockpitArchive, readArchiveDocument } from './cockpit-archive.js';
2
- import { runDocumentPath } from '../control-state/run-identity.js';
2
+ import { runDocumentPath, runEvidencePath } from '../control-state/run-identity.js';
3
3
  import { existsSync } from '../control-read/fs.js';
4
4
  import { RUN_ID_PATTERN } from '../control-state/run-identity.js';
5
5
  import { join, posix, sep } from 'node:path';
@@ -11,8 +11,10 @@ import { readRunState, readArtefactHeading } from '../control-evaluation/run-sta
11
11
  import { evaluateGateCheck } from '../control-evaluation/gate-check.js';
12
12
  import { isSafeControlRelativePath } from '../control-state/contained-file.js';
13
13
  import { resolveControlCommandTarget } from '../control-state/approval-command-contract.js';
14
- import { localePack, resolveHumanRunTitle } from '../interaction-presentation.js';
15
- import { interactionLocales } from '../resources/context.js';
14
+ import { localePack } from '../interaction-presentation.js';
15
+ import { runIdentity } from '../control-state/run-title.js';
16
+ import { interactionLocales, resolveArtifactPresentationLanguages } from '../resources/context.js';
17
+ import { projectCockpitSummary } from '../control-state/run-presentation-render.js';
16
18
  import { projectCockpitContext, composeCockpitPacket } from './cockpit-context.js';
17
19
  import { projectCockpitWork } from './cockpit-work.js';
18
20
  import { readControlLayout } from '../control-state/control-layout.js';
@@ -22,7 +24,11 @@ import { runSealState } from '../control-state/run-seal.js';
22
24
  import { ARTIFACT_READINESS_GATES, projectArtifactReadiness, describeArtifactReadiness } from './artifact-readiness.js';
23
25
  import { artefactFileDigest } from '../control-state/run-seal-compute.js';
24
26
  import { inspectApprovedArtefact } from '../control-state/artefact-binding-proof.js';
25
- import { runClosure, ENDED_LIFECYCLES } from '../control-state/run-operations.js';
27
+ import { runClosure } from '../control-state/run-operations.js';
28
+ import { projectRunEntry } from '../companion/run-view.js';
29
+ // Shared with the companion run view, in a module every runtime profile carries.
30
+ import { boundedCode, projectCockpitAssessment } from './run-classification.js';
31
+ export { boundedCode, projectCockpitAssessment };
26
32
 
27
33
  const CONTROL = '.agdf/control/';
28
34
  const SUPPORTED = new Map([['md', 'markdown'], ['json', 'json'], ['txt', 'text'], ['log', 'text']]);
@@ -31,14 +37,7 @@ const DOCUMENT_GATES = new Set(['UR', 'PRD', 'SD', 'TP', 'QA', 'UAT']);
31
37
  const DESCRIPTION_LIMIT = 256 * 1024;
32
38
  const rawDigest = bytes => createHash('sha256').update(bytes).digest('hex');
33
39
  const assertDescriptionBound = value => { if (Buffer.byteLength(JSON.stringify(value)) > DESCRIPTION_LIMIT) fail('resource_limit'); };
34
- function boundedCode(error) {
35
- const code = error.code ?? error.message;
36
- if (code === 'AGDF_CONTROL_LAYOUT_UNSUPPORTED') return 'control_layout_unsupported';
37
- if (code === 'AGDF_RUN_VERSION_UNSUPPORTED') return 'run_version_unsupported';
38
- if (code === 'AGDF_CONTROL_LAYOUT_INVALID') return 'control_invalid';
39
- return ['resource_denied', 'source_changed', 'timeout', 'resource_limit', 'read_failed'].includes(error.code) ? error.code : 'read_failed';
40
- }
41
- const objective = content => content?.match(/(?:^|\n)## Objective\s*\n([\s\S]*?)(?=\n## |$)/)?.[1]?.trim() ?? null;
40
+ const storedObjective = content => content?.match(/(?:^|\n)## Objective\s*\n([\s\S]*?)(?=\n## |$)/)?.[1]?.trim() ?? null;
42
41
  // History of an ended Run, read only from its sealed closure receipt; null for every other Run.
43
42
  export function projectRunClosure(content) {
44
43
  const closure = runClosure(content);
@@ -46,18 +45,6 @@ export function projectRunClosure(content) {
46
45
  closed_at: closure.closed_at, operation_id: closure.operation_id, receipt: closure.receipt, authorizes: false };
47
46
  }
48
47
 
49
- // Read-only projection of the evaluated decision, never a second gate evaluator.
50
- // Doctor warnings are already considered by evaluateGateCheck; they are not a UI veto.
51
- export function projectCockpitAssessment(report, lifecycle) {
52
- const state = ENDED_LIFECYCLES.includes(lifecycle) ? 'ended'
53
- : lifecycle === 'completed' ? report.completion?.fulfilled === true ? 'completed' : 'unconfirmed'
54
- : lifecycle !== 'active' ? 'unconfirmed'
55
- : report.status === 'blocked' || (report.blocking_reason && report.blocking_reason !== 'none')
56
- || (report.missing_approval && report.missing_approval !== 'none') ? 'blocked'
57
- : report.status === 'open' && report.blocking_reason === 'none' && report.missing_approval === 'none' ? 'open'
58
- : 'unconfirmed';
59
- return { state, authorizes: false };
60
- }
61
48
 
62
49
  export function createCockpitReader(root, options = {}) {
63
50
  let view = null, details = new Map(), documents = new Map();
@@ -96,9 +83,16 @@ export function createCockpitReader(root, options = {}) {
96
83
  function manifest(runId, state) {
97
84
  const result = [];
98
85
  const paths = new Set();
99
- // The canonical state itself and each explicit Artefacts row are registrations.
100
- // The canonical state path is platform-native; registrations use POSIX separators.
86
+ // Keep Run State and artefact registrations ahead of standalone evidence reports.
101
87
  const rows = [{ type: 'Run State', path: state.path?.split(sep).join(posix.sep) }, ...[...state.artefacts].map(([type, row]) => ({ type, ...row }))];
88
+ const evidenceRoot = runEvidencePath(runId, '') + '/';
89
+ for (const row of state.evidence_applicability.current) {
90
+ const path = row.report?.path;
91
+ if (row.available !== true || !path?.startsWith(evidenceRoot) || !isSafeControlRelativePath(path)
92
+ || !SUPPORTED.has(path.split('.').at(-1)?.toLowerCase())) continue;
93
+ const { bytes } = view.readOptionalFileSync(join(root, path), READ_LIMITS.preview);
94
+ if (bytes && !bytes.includes(0)) rows.push({ type: 'Evidence', path });
95
+ }
102
96
  for (const row of rows) {
103
97
  const path = String(row.path ?? '').replace(/^`|`$/g, '').trim();
104
98
  if (!path || path === 'none' || paths.has(path)) continue;
@@ -133,17 +127,23 @@ export function createCockpitReader(root, options = {}) {
133
127
  const resources = manifest(run.run_id, state);
134
128
  const outside = resources.filter(r => r.status === 'blocked' && isSafeControlRelativePath(r.registered_reference)).map(r => r.registered_reference);
135
129
  const report = outside.length ? null : evaluateGateCheck(root, { runId: run.run_id, ignoreRunIdEnv: true });
130
+ const assessed = report ? evaluation(state, report, run.meta.lifecycle) : outOfScopeEvaluation(state, outside);
131
+ const figure = report?.status_card && assessed.control_assessment.state !== 'unconfirmed'
132
+ ? projectRunEntry({ run_id: run.run_id, lifecycle: run.meta.lifecycle }, report).figure
133
+ : undefined;
136
134
  const work_summary = outside.length ? null : runWorkSummary(root, run.content, state.path);
137
135
  const draft_check = draftDescriptor(run, state, report);
138
136
  const document_states = documentStates(run, state, report, resources, draft_check);
137
+ const urTitle = readArtefactHeading(root, state.artefacts.get('UR')).replace(/^UR:\s*/i, '').trim();
138
+ const identity = runIdentity({ runId: run.run_id, runContent: run.content, urHeading: urTitle });
139
139
  return { run_id: run.run_id, revision_id: run.meta.revision_id, lifecycle: run.meta.lifecycle,
140
140
  closure: projectRunClosure(run.content), work_summary,
141
+ ...(figure && { figure }),
141
142
  // The cockpit identifies the undertaking; the gate card can still name its current artefact.
142
- objective: objective(run.content), title: resolveHumanRunTitle({
143
- urHeading: readArtefactHeading(root, state.artefacts.get('UR')).replace(/^UR:\s*/i, ''),
144
- runContent: run.content, runId: run.run_id,
145
- }),
146
- evaluation: report ? evaluation(state, report, run.meta.lifecycle) : outOfScopeEvaluation(state, outside), persisted: { current_gate: state.current_gate, next_allowed_action: state.next_allowed_action,
143
+ // The detail shows the stored Objective as written, placeholders included (owner decision);
144
+ // the title follows the shared Run title rule.
145
+ objective: storedObjective(run.content), title_source: identity.title_source, title: identity.title,
146
+ evaluation: assessed, persisted: { current_gate: state.current_gate, next_allowed_action: state.next_allowed_action,
147
147
  decision: report?.status ?? 'unavailable', artefacts: [...state.artefacts].map(([type, value]) => ({ type, ...value })) },
148
148
  context_graph: { refs: state.context_graph.refs }, resources,
149
149
  draft_check, document_states, evidence_applicability: Object.fromEntries(['current', 'superseded', 'applicability_unknown'].map(group => [group,
@@ -218,7 +218,8 @@ export function createCockpitReader(root, options = {}) {
218
218
  view.revalidate();
219
219
  } catch (error) { checkedDraft = null; invalidate(); inspected = null; graph = null; throw error; }
220
220
  }
221
- function readDocument(resourceId) {
221
+ // Only the gate preview shows the authored summary; full document reads stay content-only.
222
+ function readDocument(resourceId, { withSummary = false } = {}) {
222
223
  const resource = documents.get(resourceId);
223
224
  if (!resource) fail('resource_denied');
224
225
  if (resource.status === 'blocked') return envelope({ resource }, 'blocked', 'resource_denied');
@@ -243,7 +244,12 @@ export function createCockpitReader(root, options = {}) {
243
244
  if (registered) links[href] = registered.resource_id;
244
245
  }
245
246
  const document_state = details.get(resource.run_id)?.data?.document_states?.find(row => row.resource_id === resourceId);
246
- return envelope({ resource, format, content, content_digest: rawDigest(bytes), links, ...(document_state ? { document_state } : {}) });
247
+ const summary = withSummary && format === 'markdown' && document_state && ['UR', 'PRD', 'SD', 'TP'].includes(resource.type)
248
+ ? projectCockpitSummary(resource.type, content, resolveArtifactPresentationLanguages(root, 'de'), { runId: resource.run_id,
249
+ revisionId: document_state.revision_id, artefactPath: resource.path }) : null;
250
+ const cockpit_summary = summary && { ...summary, run_id: resource.run_id, resource_id: resource.resource_id,
251
+ revision_id: document_state.revision_id, content_digest: rawDigest(bytes) };
252
+ return envelope({ resource, format, content, content_digest: rawDigest(bytes), links, ...(document_state ? { document_state } : {}), ...(cockpit_summary ? { cockpit_summary } : {}) });
247
253
  }
248
254
  function discardScope(retainCheck = false) {
249
255
  if (!retainCheck) checkedDraft = null;
@@ -371,6 +377,14 @@ export function createCockpitReader(root, options = {}) {
371
377
  return selected;
372
378
  });
373
379
  },
380
+ preview(resourceId, id, runId) {
381
+ const resource = documents.get(resourceId);
382
+ if (!resource || resource.run_id !== runId) fail('resource_denied');
383
+ assertSnapshot(id);
384
+ const result = readDocument(resourceId, { withSummary: true });
385
+ assertSnapshot(id);
386
+ return result;
387
+ },
374
388
  document(resourceId, id, runId) {
375
389
  // Check selectors before revalidation or replacing the legitimate view.
376
390
  const previous = documents.get(resourceId);