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
@@ -1,106 +1,105 @@
1
- import { projectStoredRun } from './core.mjs';
2
- // Bounded, read-only current-Run projection. Typed records and display policy come
3
- // from the canonical pure Core modules. This does not qualify seals or file evidence
4
- // and never authorizes a gate or command. File access remains injected by the host.
1
+ // Run view reader (SD SDD-010): obtains the Core run view through the plugin runtime's read-only
2
+ // `run-view` command and maps it to the companion's runs. The companion derives no run semantics of
3
+ // its own: status, gate path, missing approval, next step and figure come from the status card's
4
+ // evaluator. Process access is injected by the host ({ run(argv, init) }, as `$.process` provides).
5
5
 
6
- export const GATES = Object.freeze(['UR', 'PRD', 'SD', 'TP', 'QA', 'UAT', 'OR']);
7
- // The internal steps between an approved TP and QA, shown as the build phase (SDD-02, SDD-03).
6
+ export const RUN_VIEW_SCHEMA = 'run-view/1';
7
+ export const RUN_VIEW_TIMEOUT_MS = 10_000;
8
+ // Why a run-view read failed; each has a catalog text under `unreadable` (shown with the failure).
9
+ export const READ_FAILURE_REASONS = Object.freeze(['timeout', 'unavailable', 'exit', 'malformed', 'source_changed']);
10
+ // Store reasons of a read that may succeed on the next attempt (a write during the read, the read
11
+ // budget); they keep the last good view, marked stale, like a failed read (CR delta review RV-1).
12
+ export const TRANSIENT_STORE_REASONS = Object.freeze(['source_changed', 'timeout']);
13
+ // Evaluation errors of a single run that make the whole view incomplete (a write during its read).
14
+ export const TRANSIENT_RUN_REASONS = Object.freeze(['source_changed']);
15
+ // The internal steps between an approved TP and QA, shown as the build phase in the gate bar.
8
16
  export const BUILD_GATES = Object.freeze(['Brownfield Analysis', 'CD+Tests', 'CR']);
9
17
  export const isStructured = route => route === 'structured_delivery' || route === 'structured_slice';
10
- // The host rejects reads over 4 MiB; the largest observed run state is about 280 KB.
11
- export const MAX_RUN_STATE_BYTES = 1024 * 1024;
12
18
  const TEXT_LIMIT = 240;
19
+ const clip = text => { const value = String(text ?? ''); return value.length > TEXT_LIMIT ? `${value.slice(0, TEXT_LIMIT - 1)}…` : value; };
13
20
 
14
- // The run lifecycles the core reader accepts (`LIFECYCLES` in run-state-parser.js); the logic suite
15
- // asserts that both sets are equal, so a new core lifecycle fails it instead of reading unreadable.
16
- export const LIFECYCLES = Object.freeze(['active', 'completed', 'superseded', 'abandoned']);
17
- const KNOWN_LIFECYCLES = new Set(LIFECYCLES);
18
- const plain = value => String(value ?? '').replace(/`/gu, '').trim();
19
- const clip = text => (text.length > TEXT_LIMIT ? `${text.slice(0, TEXT_LIMIT - 1)}…` : text);
20
-
21
- // Body of a level-two section, without its heading; '' when absent.
22
- export function section(text, heading) {
23
- const lines = text.split('\n');
24
- const start = lines.findIndex(line => line.trimEnd() === `## ${heading}`);
25
- if (start < 0) return '';
26
- const rest = lines.slice(start + 1);
27
- const end = rest.findIndex(line => line.startsWith('## '));
28
- return (end < 0 ? rest : rest.slice(0, end)).join('\n');
21
+ // The only command the companion runs: the read-only run view of one project root.
22
+ export function runViewArgv({ pluginRoot, root, language, runIds = [] }) {
23
+ return ['node', `${pluginRoot}/runtime/agdf-local.js`, 'run-view', '--dir', root, '--json', '--language', language,
24
+ ...runIds.flatMap(runId => ['--run', runId])];
29
25
  }
30
26
 
31
- const field = (body, key) => plain(body.match(new RegExp(`^- ${key}:[ \\t]*(.*)$`, 'mu'))?.[1]);
32
-
33
- // Canonical writers keep a review or gate result in the Artefacts row of the step that produced it
34
- // (`CR | … | revise`, `QA | … | block`); a Quick Task's Code Review is the CR row. The Run Meta
35
- // `decision` stays `in_progress` (CR-F02).
36
- const RESULT_ROWS = Object.freeze({ 'Quick Task Execution': ['CR'] });
37
- const RESULTS = new Set(['revise', 'block', 'blocked']);
38
- // The core's decision-content placeholder rule (`isDecisionContentPlaceholder`,
39
- // decision-content-readiness.js), so a template objective is never shown as the run's goal.
40
- const PROMPTS = new Set(['describe the trustworthy outcome.', 'what outcome should become possible?',
41
- 'which tp tasks are fully done, partially done or not done?', 'what remains unverified?', 'which risks remain and what is their impact?']);
42
- export function isPlaceholderText(value) {
43
- if (typeof value !== 'string') return true;
44
- const text = value.trim().replace(/^`([^`]+)`$/u, '$1').replace(/\s+/gu, ' ').toLowerCase();
45
- return !text || PROMPTS.has(text)
46
- || /^(?:todo|tbd|<[^>]+>|(?:draft|done|ready|blocked|pass|revise|block)(?:\s*\|\s*(?:draft|done|ready|blocked|pass|revise|block))+)$/u.test(text);
27
+ // One run-view entry as the companion's run.
28
+ export function companionRun(entry) {
29
+ return Object.freeze({
30
+ id: entry.run_id,
31
+ lifecycle: entry.lifecycle,
32
+ evaluated: entry.evaluated === true,
33
+ gate: entry.current_gate ?? null,
34
+ route: entry.mode ?? null,
35
+ updatedAt: entry.last_activity ?? '',
36
+ missing: entry.missing_approval ?? 'none',
37
+ next: entry.next_step ?? '',
38
+ nextText: entry.next_step_text ?? '',
39
+ blockingText: entry.blocking_text ?? '',
40
+ path: Object.freeze((entry.path ?? []).map(({ gate, status }) => Object.freeze({ gate, status }))),
41
+ figure: entry.figure,
42
+ // Bound documents changed after recording (SDD-008), as the run view reports them.
43
+ drift: Object.freeze((entry.drift ?? []).map(item => Object.freeze({ ...item }))),
44
+ // The authored objective, never the status card's run title or a template text.
45
+ objective: clip(entry.objective ?? ''),
46
+ // The run's stable human title (registered UR heading, else the authored objective); empty while
47
+ // only the run id could name it. The goal is the objective in the display language where the UR
48
+ // states one.
49
+ title: clip(entry.run_title ?? ''),
50
+ goal: clip(entry.goal ?? entry.objective ?? ''),
51
+ });
47
52
  }
48
53
 
49
- // Returns { ok: true, run } or { ok: false, id, reason } with reason missing | too_large | format.
50
- // Only version 4 typed records are accepted; retired persisted derived tables are refused.
51
- export function parseRunState(id, text) {
52
- if (typeof text !== 'string') return { ok: false, id, reason: 'missing' };
53
- if (text.length > MAX_RUN_STATE_BYTES) return { ok: false, id, reason: 'too_large' };
54
- const normalized = text.replace(/^/u, '').replace(/\r\n?/gu, '\n');
55
- const meta = section(normalized, 'Run Meta');
56
- let projection; try { projection = projectStoredRun(normalized); } catch { return { ok: false, id, reason: 'format' }; }
57
- const control = projection.control;
58
- const runId = field(meta, 'run_id');
59
- const lifecycle = field(meta, 'lifecycle');
60
- const gate = control.current_gate;
61
- const decision = lifecycle === 'completed' ? 'completed' : 'in_progress';
62
- const updatedAt = Number.isNaN(Date.parse(field(meta, 'updated_at'))) ? '' : field(meta, 'updated_at');
63
- if (!meta || runId !== id || !KNOWN_LIFECYCLES.has(lifecycle) || !gate) return { ok: false, id, reason: 'format' };
64
- const objective = section(normalized, 'Objective').split('\n').map(line => line.trim()).find(Boolean) ?? '';
65
- const statuses = new Map([...projection.facts.artefacts].map(([name, row]) => [name, row.status]));
66
- const gateResult = (RESULT_ROWS[gate] ?? [gate]).map(type => statuses.get(type)).find(status => RESULTS.has(status)) ?? null;
67
- return { ok: true, run: Object.freeze({
68
- id,
69
- lifecycle,
70
- gate,
71
- decision,
72
- route: projection.route,
73
- gateResult,
74
- gateDecision: control.presentation_decision?.action ?? null,
75
- updatedAt,
76
- missing: clip(projection.facts.artefacts.get(gate)?.path || gate === 'UAT' ? control.missing_approval ?? '' : 'none'),
77
- next: clip(control.next_allowed_action ?? ''),
78
- approved: Object.freeze([...projection.facts.approvals].filter(([, row]) => row.status === 'approved').map(([name]) => name)),
79
- objective: isPlaceholderText(objective) ? '' : clip(objective),
80
- }) };
54
+ // stdout of the command as a snapshot: { status, root, runs, unreadable, diagnosis, readAt }.
55
+ // status is ok, no_control, unavailable (store diagnosis with reason) or failed (no usable view).
56
+ export function snapshotFromRunView(stdout, { now }) {
57
+ let view;
58
+ try { view = JSON.parse(stdout); } catch { return { status: 'failed', runs: [], unreadable: [], readAt: now, error: 'malformed' }; }
59
+ if (view?.schema_version !== RUN_VIEW_SCHEMA || !Array.isArray(view.runs) || !view.store) {
60
+ return { status: 'failed', runs: [], unreadable: [], readAt: now, error: 'malformed' };
61
+ }
62
+ if (view.store.status === 'unavailable' && TRANSIENT_STORE_REASONS.includes(view.store.reason)) {
63
+ return { status: 'failed', runs: [], unreadable: [], readAt: now, error: view.store.reason };
64
+ }
65
+ // A run read while its files changed (after the run view's bounded retries) makes the view incomplete;
66
+ // like a transient store failure it keeps the last good view instead of showing that run as blocked.
67
+ // A single run that ran into the read budget is not transient: it stays that run's own reason, so the
68
+ // other runs are still shown.
69
+ const changedRun = view.runs.find(run => TRANSIENT_RUN_REASONS.includes(run?.evaluation_error));
70
+ if (changedRun) return { status: 'failed', runs: [], unreadable: [], readAt: now, error: changedRun.evaluation_error };
71
+ const status = view.store.status === 'ok' ? 'ok' : view.store.status === 'no_control' ? 'no_control' : 'unavailable';
72
+ return {
73
+ status,
74
+ root: view.root,
75
+ reason: view.store.reason ?? null,
76
+ // The run folders of an unsupported store, which the run view counts without reading them (AC-002).
77
+ runFolders: Number.isSafeInteger(view.store.run_folders) && view.store.run_folders > 0 ? view.store.run_folders : null,
78
+ runs: view.runs.filter(entry => entry.valid !== false && entry.listed !== false).map(companionRun),
79
+ unreadable: (view.diagnosis?.unreadable ?? []).map(({ run_id, reason }) => ({ id: run_id, reason })),
80
+ diagnosis: view.diagnosis ?? null,
81
+ // A run that ran into the read budget may read on the next attempt: the adapter keeps no
82
+ // fingerprint for such a view, so the next check reads again instead of waiting for a file change.
83
+ retry: view.runs.some(run => run?.evaluation_error === 'timeout'),
84
+ readAt: now,
85
+ };
81
86
  }
82
87
 
83
- // Reads every run state below <projectRoot>/.agdf/control/runs through the injected file access
84
- // ({ exists, list, read }, as `$.fs` provides). Never writes. A failing directory read is
85
- // transient (status 'failed'); a single unreadable run state is reported per run. Without a
86
- // control folder the snapshot names the checked project root, so the panel can say where it looked.
87
- export async function readSnapshot(fs, projectRoot, { now }) {
88
- const runsDir = `${projectRoot}/.agdf/control/runs`;
88
+ // Runs the command through the host and never throws: a process failure, a timeout or malformed
89
+ // output is a failed snapshot with its cause, which the adapter settles as stale.
90
+ export async function readSnapshot(processes, { pluginRoot, root, language, runIds = [], now, clock = () => Date.now() }) {
91
+ let ran;
92
+ const started = await clock();
89
93
  try {
90
- if (!(await fs.exists(`${projectRoot}/.agdf/control`))) return { status: 'no_control', root: projectRoot, runs: [], unreadable: [], readAt: now };
91
- if (!(await fs.exists(runsDir))) return { status: 'ok', runs: [], unreadable: [], readAt: now };
92
- const folders = (await fs.list(runsDir)).filter(entry => entry.kind === 'dir' && !entry.isLink);
93
- const results = await Promise.all(folders.map(folder => fs.read(`${runsDir}/${folder.name}/RUN_STATE.md`)
94
- .then(text => parseRunState(folder.name, text), () => ({ ok: false, id: folder.name, reason: 'missing' }))));
95
- return {
96
- status: 'ok',
97
- runs: results.filter(result => result.ok).map(result => result.run),
98
- unreadable: results.filter(result => !result.ok).map(({ id, reason }) => ({ id, reason })),
99
- readAt: now,
100
- };
101
- } catch (error) {
102
- return { status: 'failed', runs: [], unreadable: [], readAt: now, error: String(error?.message ?? error).slice(0, TEXT_LIMIT) };
94
+ ran = await processes.run(runViewArgv({ pluginRoot, root, language, runIds }), { timeoutMs: RUN_VIEW_TIMEOUT_MS });
95
+ } catch {
96
+ // `$.process.run` rejects when the command cannot start or is still running at the timeout; its
97
+ // message format is not specified, so the elapsed time tells the two apart (CR finding CIR-06).
98
+ const elapsed = (await clock()) - started;
99
+ return { status: 'failed', runs: [], unreadable: [], readAt: now, error: elapsed >= RUN_VIEW_TIMEOUT_MS ? 'timeout' : 'unavailable' };
103
100
  }
101
+ if (ran.exitCode !== 0 && ran.exitCode !== 2) return { status: 'failed', runs: [], unreadable: [], readAt: now, error: 'exit' };
102
+ return snapshotFromRunView(ran.stdout, { now });
104
103
  }
105
104
 
106
105
  // A transient failure keeps the last good snapshot, marked stale with the failed read time (AC-006).
@@ -1,37 +1,11 @@
1
- // State rules (AC-003, AC-002 of the follow-up): which of the five moods a run shows and why, as a
2
- // reason descriptor the view localizes. A run matching no rule is reported unreadable rather than
3
- // guessed (SDD-04).
1
+ // Figure state of a run (SD SDD-004): the Core run view carries the derived mood and reason, so the
2
+ // companion only overlays its own turn activity. It derives no run semantics itself.
4
3
 
5
- import { BUILD_GATES, isStructured } from './run-state.mjs';
4
+ export const MOODS = Object.freeze(['laeuft', 'baut', 'wartet', 'blockiert', 'fertig', 'bereit']);
6
5
 
7
- export const MOODS = Object.freeze(['laeuft', 'baut', 'wartet', 'blockiert', 'fertig']);
8
- const BLOCKING = new Set(['revise', 'block', 'blocked', 'decline']);
9
- const AWAITING = new Set(['pending', 'awaiting_uat']);
10
- const WORKING = new Set(['in_progress', 'pass', 'qa_approved', 'completed']);
11
-
12
- // The gate a pending approval names, as in "Exact Approval: QA." or "Exact Approval: PRD for the new revision."
13
- export const pendingApproval = missing => String(missing ?? '').match(/\bApproval: (UR|PRD|SD|TP|QA|UAT|OR)\b/u)?.[1] ?? null;
14
-
15
- // The blocking outcome of a run: a legacy Run Meta decision, the current gate's recorded result
16
- // (`revise`, `block`, `blocked`) or a deliberate decision on its presented material.
17
- function blockingOutcome(run) {
18
- if (BLOCKING.has(run.decision)) return run.decision;
19
- if (run.gateResult) return run.gateResult;
20
- return { reject: 'decline', request_change: 'revise' }[run.gateDecision] ?? null;
21
- }
22
-
23
- // { mood, reason: { key, gate?, decision? } } or { mood: null, reason: { key: 'unknownState' } }.
24
- // A structured run between an approved TP and QA (Brownfield Analysis, CD+Tests, CR) is being built.
6
+ // { mood, reason: { key, gate?, decision?, reason? } } as the run view derived it.
25
7
  export function runState(run) {
26
- if (run.lifecycle === 'completed') return { mood: 'fertig', reason: { key: 'done' } };
27
- const outcome = blockingOutcome(run);
28
- if (outcome) return { mood: 'blockiert', reason: { key: 'blocked', gate: run.gate, decision: outcome } };
29
- const approval = pendingApproval(run.missing);
30
- if (approval) return { mood: 'wartet', reason: { key: 'waitingApproval', gate: approval } };
31
- if (AWAITING.has(run.decision)) return { mood: 'wartet', reason: { key: 'waitingDecision', gate: run.gate } };
32
- if (WORKING.has(run.decision) && isStructured(run.route) && BUILD_GATES.includes(run.gate)) return { mood: 'baut', reason: { key: 'building', gate: run.gate } };
33
- if (WORKING.has(run.decision)) return { mood: 'laeuft', reason: { key: 'working', gate: run.gate } };
34
- return { mood: null, reason: { key: 'unknownState' } };
8
+ return run?.figure ?? { mood: 'bereit', reason: { key: 'idle' } };
35
9
  }
36
10
 
37
11
  // Moods a main-loop turn does not cover: a run being built stays baut, and a run waiting for an
@@ -43,6 +17,6 @@ const THROUGH_TURN = new Set(['baut', 'wartet']);
43
17
  // the turn.
44
18
  export function displayState(run, { isTurnActive = false } = {}) {
45
19
  const derived = runState(run);
46
- if (isTurnActive && derived.mood !== null && !THROUGH_TURN.has(derived.mood)) return { mood: 'laeuft', reason: { key: 'turnActive' } };
20
+ if (isTurnActive && !THROUGH_TURN.has(derived.mood)) return { mood: 'laeuft', reason: { key: 'turnActive' } };
47
21
  return derived;
48
22
  }
@@ -3,81 +3,256 @@
3
3
  // host-independent; the adapter draws it on desktop or as text in the terminal.
4
4
 
5
5
  import { assignRun } from './assignment.mjs';
6
- import { FIGURE_TEXT } from './figure.mjs';
6
+ import { FIGURE_TEXT, INVITE_TEXT } from './figure.mjs';
7
7
  import { condensedGateBar, gateBar, gateMarks } from './gate-bar.mjs';
8
- import { gateTitle, label, localizeNextStep } from './localization.mjs';
9
- import { displayState } from './state.mjs';
8
+ import { gateRationale, gateTitle, label } from './localization.mjs';
9
+ import { displayState, runState } from './state.mjs';
10
+ import { isStructured, READ_FAILURE_REASONS } from './run-state.mjs';
11
+ import { eventText, latestReview, PANE_EVENTS, shortDigest, shortRunId } from './events.mjs';
10
12
 
11
13
  const two = value => String(value).padStart(2, '0');
14
+ // Preview lines the terminal text shows beneath the material line.
15
+ export const TERMINAL_PREVIEW_LINES = 3;
12
16
  // Last part of a project root in either path form ("C:\Work\app\" → "app").
13
17
  const folderName = root => String(root ?? '').replace(/[\\/]+$/u, '').split(/[\\/]/u).pop() || String(root ?? '');
14
18
  // Host-local wall-clock time, HH:MM.
15
19
  export const clockText = ms => { const at = new Date(ms); return `${two(at.getHours())}:${two(at.getMinutes())}`; };
16
20
 
21
+ // The name a person reads for the shown run: its stable title, else the catalog's "new run". The run
22
+ // id never names a run; it stays a reference line at the panel's end.
23
+ export const runName = (run, t) => run.title || t('fields.newRun');
24
+ // A listed run needs a name that tells it from its neighbours, so an untitled one adds its short id.
25
+ export const listedRunName = (run, t) => run.title || `${t('fields.newRun')} · ${shortRunId(run.id)}`;
26
+
27
+ // Whose move it is (owner request of 2026-11-11): read from the figure state Core derived, so the
28
+ // block never decides anything itself. `tone` is you (an approval or decision is yours), claude (the
29
+ // agent works on the gate), next (the step is up next and nobody works on it) or halt (the run is
30
+ // blocked). This function words the moves that are yours and the block; activityOf below words the work.
31
+ // A state that concerns no gate work has no such block, and neither has the terminal's turn overlay
32
+ // beside a run that is not working: its reason already says that Claude works.
33
+ export function turnOf(state, run, t, gateName) {
34
+ const { key, gate, decision } = state.reason;
35
+ const at = gate ?? run.gate;
36
+ if (!at) return null;
37
+ if (key === 'waitingApproval') {
38
+ return { tone: 'you', who: t('turn.you'), what: t('turn.approve', { gate: gateName(at) }),
39
+ how: run.missing && run.missing !== 'none' ? t('turn.inChat', { approval: run.missing }) : null, gate: at };
40
+ }
41
+ if (key === 'waitingDecision') return { tone: 'you', who: t('turn.you'), what: t('turn.decide', { gate: gateName(at) }), how: null, gate: at };
42
+ if (key === 'blocked') {
43
+ return { tone: 'halt', who: t('turn.blocked'), what: t('reasons.blocked', { gate: gateName(at), decision: run.blockingText || decision || '' }), how: null, gate: at };
44
+ }
45
+ return null;
46
+ }
47
+
48
+ // Which kind of work a step is; the catalog's `activity` section words each kind once. A step the
49
+ // table does not know is worded by its name.
50
+ export const ACTIVITY_KINDS = Object.freeze({ UR: 'draft', PRD: 'draft', SD: 'draft', TP: 'draft',
51
+ 'Brownfield Review': 'analysis', 'Brownfield Analysis': 'analysis', 'Mode/Slice Decision': 'route',
52
+ 'CD+Tests': 'build', 'Quick Task Execution': 'build', 'Verified Change Execution': 'build',
53
+ CR: 'review', QA: 'quality', UAT: 'acceptance', OR: 'closeout' });
54
+
55
+ // What a run is busy with (owner request of 2026-11-12: "läuft" named no activity). Read from the run's
56
+ // own state, a step Claude works on or builds, never from the turn overlay. While a main-loop turn runs,
57
+ // the line says what is being done and the block asks for a moment. Otherwise the run rests: the line
58
+ // says what is up next and the block how to carry on. Returns { label, turn, resting } or null.
59
+ export function activityOf(derived, run, isTurnActive, t, title) {
60
+ const { key, gate } = derived.reason;
61
+ const at = gate ?? run.gate;
62
+ if ((key !== 'working' && key !== 'building') || !at) return null;
63
+ const kind = ACTIVITY_KINDS[at] ?? 'other';
64
+ const named = title(at);
65
+ // A document or approval gate keeps its short name beside its title; an internal step has only a title.
66
+ const step = named !== at && /^[A-Z]{2,3}$/u.test(at) ? `${named} (${at})` : named;
67
+ const label = t(`activity.${kind}.${isTurnActive ? 'working' : 'idle'}`, { gate: at, step: named });
68
+ const drafting = kind === 'draft';
69
+ const turn = isTurnActive
70
+ ? { tone: 'claude', who: t('turn.moment'), what: drafting ? t('turn.drafting', { step }) : t('turn.workingOn', { step }), how: null, gate: at }
71
+ : { tone: 'next', who: t('turn.next'), what: drafting ? t('turn.draft', { step }) : step, how: t('turn.resume'), gate: at };
72
+ return { label, turn, resting: !isTurnActive };
73
+ }
74
+
75
+ // About two pane lines of the goal, cut at a word, so the block that asks for a move stays in sight.
76
+ const GOAL_LINES = 2;
77
+ export function goalLine(goal, columns) {
78
+ const room = Math.max(40, (Number.isFinite(columns) ? columns : 60) * GOAL_LINES);
79
+ if (goal.length <= room) return goal;
80
+ const cut = goal.slice(0, room - 1), at = cut.lastIndexOf(' ');
81
+ return `${(at > room / 2 ? cut.slice(0, at) : cut).replace(/[\s,;:.–-]+$/u, '')}…`;
82
+ }
83
+
84
+ // The delivery path and the position on it, e.g. "Strukturierte Lieferung · Schritt 2 von 8". Before
85
+ // the path is decided only that is said; a path that names no current entry gives no position.
86
+ export function routeLine(run, marks, t) {
87
+ const key = isStructured(run.route) ? 'structured' : run.route === 'quick_task' || run.route === 'verified_change' ? run.route
88
+ : (run.route === 'undecided' || run.route == null) && run.evaluated && run.lifecycle === 'active' ? 'undecided' : null;
89
+ if (!key) return null;
90
+ const at = marks.findIndex(({ mark }) => mark === 'current');
91
+ return key === 'undecided' || at < 0 ? t(`routes.${key}`) : `${t(`routes.${key}`)} · ${t('fields.step', { position: at + 1, count: marks.length })}`;
92
+ }
93
+
17
94
  // input: { snapshot, sessionStartedAt, selection, mention, isBrowsing, isTurnActive, registry, labels,
18
- // locale, columns, isObjectiveExpanded }. Display only: the adapter persists selection changes.
95
+ // locale, columns, isInfoExpanded, events, eventsAvailable }. Display only: the adapter persists
96
+ // selection changes. `events` are this root's journal events since the last main-loop turn, newest first.
19
97
  export function buildPanelView(input) {
20
98
  const { snapshot, registry, labels, locale } = input;
21
99
  const t = (path, params) => label(labels, locale, path, params);
22
- const base = { title: t('title'), locale, mood: 'neutral', stateLabel: t('states.neutral'),
100
+ const base = { title: t('title'), locale, mood: 'bereit', stateLabel: t('states.bereit'),
23
101
  readAt: snapshot ? t('fields.lastRead', { time: clockText(snapshot.readAt) }) : null,
24
102
  stale: snapshot?.stale ? t('messages.stale', { time: clockText(snapshot.stale.failedAt), readAt: clockText(snapshot.readAt) }) : null,
25
103
  canRetry: true, openRuns: [] };
26
- const neutral = (message, extra = {}) => ({ ...base, message, ...extra });
104
+ // Event lines name only runs other than the shown one (owner request of 2026-11-06, T-013).
105
+ const events = shownRunId => eventFields(input, t, { shownRunId, runs: snapshot?.runs ?? [] });
106
+ const neutral = (message, extra = {}) => ({ ...base, ...events(null), message, ...extra });
27
107
  const unreadable = reason => neutral(t('messages.unreadable', { reason: t(`unreadable.${reason}`) }));
28
108
 
29
109
  if (!snapshot) return neutral(t('messages.reading'), { readAt: null });
30
- if (snapshot.status === 'failed') return unreadable('failed');
110
+ if (snapshot.status === 'failed') {
111
+ const reason = READ_FAILURE_REASONS.includes(snapshot.error) ? snapshot.error : 'unavailable';
112
+ return neutral(t('messages.runViewUnavailable', { reason: t(`unreadable.${reason}`) }));
113
+ }
114
+ if (snapshot.status === 'unavailable') {
115
+ // An unsupported store names how many run folders it holds and why none is readable (AC-002).
116
+ const reason = snapshot.reason ?? 'read_failed';
117
+ return snapshot.runFolders
118
+ ? neutral(t('messages.unreadableRuns', { count: snapshot.runFolders, reasons: t(`unreadable.${reason}`) }))
119
+ : unreadable(reason);
120
+ }
31
121
  if (snapshot.status === 'no_control') {
32
- return neutral(t('messages.noControl', { folder: folderName(snapshot.root) }), { hint: t('messages.noControlHint', { path: snapshot.root ?? '' }) });
122
+ // A project without AGDF is invited to start, not told about a missing folder (owner request of
123
+ // 2026-11-12): the figure holds the start sign, and the checked path and the finding sit behind the (i).
124
+ return neutral(t('messages.notSetUp'), { hint: t('messages.notSetUpHint'), invite: true, idle: true,
125
+ isInfoExpanded: Boolean(input.isInfoExpanded), info: [
126
+ { label: t('fields.checkedFolder'), text: snapshot.root ?? '' },
127
+ { label: t('fields.finding'), text: t('messages.noControl', { folder: folderName(snapshot.root) }) }] });
33
128
  }
34
129
 
35
130
  const { run, origin, open, chatRunId } = assignRun({ runs: snapshot.runs, sessionStartedAt: input.sessionStartedAt, selection: input.selection,
36
131
  mention: input.mention ?? null, isBrowsing: Boolean(input.isBrowsing) });
132
+ // Unreadable runs stay visible as a count with their reasons beside the readable ones (AC-002, AC-003).
133
+ const reasons = [...new Set(snapshot.unreadable.map(item => t(`unreadable.${item.reason}`)))].join(', ');
134
+ const unreadableHint = snapshot.unreadable.length ? t('messages.unreadableRuns', { count: snapshot.unreadable.length, reasons }) : null;
37
135
  // Each open run carries its condensed gate bar for the list (owner request of 2026-10-28).
38
- const openRuns = open.map(item => ({ id: item.id, objective: item.objective, bar: condensedGateBar(gateMarks(item)) }));
136
+ const openRuns = open.map(item => ({ id: item.id, name: listedRunName(item, t), objective: item.objective, bar: condensedGateBar(gateMarks(item)) }));
39
137
  if (!run) {
40
138
  const broken = input.selection && snapshot.unreadable.find(item => item.id === input.selection);
41
- if (broken) return { ...unreadable(broken.reason), openRuns, chatRunId };
42
- if (!open.length) return neutral(t('messages.noOpenRuns'));
43
- return neutral(t('messages.noRunAssigned'), { hint: t('messages.noRunAssignedHint'), openRuns, chatRunId,
139
+ if (broken) return { ...unreadable(broken.reason), openRuns, chatRunId, unreadableHint };
140
+ // A readable project without an assigned run idles: the figure blinks but shows no run state.
141
+ if (!open.length) {
142
+ if (unreadableHint) return neutral(unreadableHint, { idle: false });
143
+ const runs = snapshot.runs ?? [];
144
+ // "All done" only when every run completed; superseded or abandoned runs did not finish.
145
+ if (!runs.length) return neutral(t('messages.noRunsYet'), { idle: true, hint: t('messages.noRunsYetHint') });
146
+ if (runs.every(item => item.lifecycle === 'completed')) return neutral(t('messages.allRunsDone'), { idle: true, allDone: true, hint: t('messages.allRunsDoneHint') });
147
+ return neutral(t('messages.noOpenRuns'), { idle: true });
148
+ }
149
+ return neutral(t('messages.noRunAssigned'), { idle: true, hint: t('messages.noRunAssignedHint'), openRuns, chatRunId, unreadableHint,
44
150
  openCount: t('fields.openRuns', { count: open.length }) });
45
151
  }
46
152
 
47
153
  const position = open.findIndex(item => item.id === run.id);
48
154
  const openCount = position >= 0 ? t('fields.position', { position: position + 1, count: open.length }) : t('fields.openRuns', { count: open.length });
49
- const state = displayState(run, { isTurnActive: input.isTurnActive });
50
- // A run in an unknown state keeps stepping and the way back to the chat's run (CR-F01).
51
- if (state.mood === null) return { ...unreadable('unknownState'), runId: run.id, openRuns, chatRunId, openCount };
52
- const reasonParams = { gate: gateTitle(registry, locale, state.reason.gate), decision: t(`decisions.${state.reason.decision}`) };
155
+ const derived = runState(run);
156
+ const state = input.showRunState ? derived : displayState(run, { isTurnActive: input.isTurnActive });
157
+ const reasonParams = { gate: gateTitle(registry, locale, state.reason.gate), decision: run.blockingText || state.reason.decision,
158
+ reason: state.reason.reason ? t(`unreadable.${state.reason.reason}`) : '' };
159
+ // A gate by its localized title with its short name, e.g. "Produktanforderungen (PRD)".
160
+ const gateName = gate => { const title = gateTitle(registry, locale, gate); return title === gate ? gate : `${title} (${gate})`; };
161
+ const marks = gateMarks(run);
162
+ const name = runName(run, t);
163
+ const activity = activityOf(derived, run, Boolean(input.isTurnActive), t, gate => gateTitle(registry, locale, gate));
164
+ const turn = activity?.turn ?? turnOf(state, run, t, gateName);
165
+ // The goal in the display language; a goal that only repeats the name is not said twice.
166
+ const goal = run.goal || run.objective;
167
+ const objective = goal && goal !== name ? goal : '';
168
+ // What the gate in question decides; a blocked run names its block instead.
169
+ const rationale = turn && turn.tone !== 'halt' ? gateRationale(registry, locale, turn.gate) : null;
170
+ // A completed run names no next step, unless it is blocked: then the step says what to do about it.
171
+ const step = run.lifecycle === 'completed' && run.figure?.reason?.key !== 'blocked' ? null : run.nextText || null;
172
+ // For an approval the turn block already says what to do and how, so the next step only repeats it.
173
+ const stepRepeats = Boolean(step) && state.reason.key === 'waitingApproval' && Boolean(turn);
174
+ // The goal stands under the run's name, before whose move it is: it is what an approval is measured
175
+ // against (owner request of 2026-11-12). About two pane lines of it; the rest is behind the (i).
176
+ const goalShown = objective ? goalLine(objective, input.columns) : '';
177
+ // Details a person opens on purpose behind the (i): a goal that was cut, what the gate decides, and
178
+ // a next step that only repeats the approval. Closed by default.
179
+ const info = [
180
+ objective && goalShown !== objective ? { label: t('fields.objective'), text: objective } : null,
181
+ rationale ? { label: t('fields.gatePurpose'), text: rationale } : null,
182
+ stepRepeats ? { label: t('fields.nextStep'), text: step } : null,
183
+ ].filter(Boolean);
53
184
  return {
54
185
  ...base,
186
+ ...events(run.id),
187
+ ...(input.showRunState ? { figure: state } : {}),
55
188
  mood: state.mood,
56
- stateLabel: t(`states.${state.mood}`),
189
+ workGate: input.showRunState && run.evaluated && !snapshot.stale ? run.gate : undefined,
190
+ // A working run names its activity; every other state keeps its word.
191
+ stateLabel: activity?.label ?? t(`states.${state.mood}`),
192
+ // The run rests: the step is up next and no main-loop turn works on it.
193
+ resting: activity?.resting === true,
57
194
  reason: t(`reasons.${state.reason.key}`, reasonParams),
58
- gateBar: gateBar(gateMarks(run), input.columns),
195
+ gateBar: gateBar(marks, input.columns),
59
196
  runId: run.id,
60
- objective: run.objective,
61
- isObjectiveExpanded: Boolean(input.isObjectiveExpanded),
62
- nextStep: run.lifecycle === 'completed' ? null : localizeNextStep(registry, locale, run.next).text,
197
+ name,
198
+ route: routeLine(run, marks, t),
199
+ turn,
200
+ rationale,
201
+ objective,
202
+ goal: goalShown,
203
+ info,
204
+ isInfoExpanded: Boolean(input.isInfoExpanded),
205
+ // The next step stays in sight where it says something the turn block does not.
206
+ nextStep: stepRepeats ? null : step,
207
+ unreadableHint,
63
208
  origin: t(`origin.${origin}`),
64
209
  originKind: origin,
65
210
  chatRunId,
66
211
  openRuns,
67
212
  openCount,
213
+ drift: run.drift?.length ? run.drift.map(item => t('messages.drift', { document: item.document,
214
+ recorded: shortDigest(item.recorded_digest), current: shortDigest(item.current_digest) })) : null,
215
+ };
216
+ }
217
+
218
+ // Pane entries of the journal (decision P1) and the review facts of the newest staging or recording
219
+ // (decision P2); without a readable journal the pane says so and invents nothing. `naming` is
220
+ // { shownRunId, runs }: the shown run's events name no run.
221
+ function eventFields(input, t, naming) {
222
+ const events = (input.events ?? []).slice(0, PANE_EVENTS);
223
+ const gate = value => gateTitle(input.registry, input.locale, value);
224
+ return {
225
+ events: events.length ? events.map(event => `${clockText(Date.parse(event.at))} ${eventText(event, t, { gateTitle: gate, ...naming })}`) : null,
226
+ review: latestReview(events, t),
227
+ eventsHint: input.eventsAvailable === false ? t('messages.eventsUnavailable') : null,
68
228
  };
69
229
  }
70
230
 
71
231
  // Text fallback for surfaces without Svg: state, gate bar and next step on separate lines.
72
232
  export function terminalText(view, { labels, locale }) {
73
233
  const t = path => label(labels, locale, path);
74
- const lines = [view.title, `${FIGURE_TEXT[view.mood]} ${view.stateLabel}${view.reason ? ` · ${view.reason}` : ''}`];
234
+ // The turn line says what the reason would; without one the reason stays beside the state.
235
+ const lines = [view.title, `${view.invite ? INVITE_TEXT : FIGURE_TEXT[view.mood]} ${view.stateLabel}${view.reason && !view.turn ? ` · ${view.reason}` : ''}`];
75
236
  if (view.message) lines.push(view.message);
76
237
  if (view.hint) lines.push(view.hint);
238
+ if (view.unreadableHint && view.unreadableHint !== view.message) lines.push(view.unreadableHint);
239
+ if (view.name) lines.push(view.route ? `${view.name} · ${view.route}` : view.name);
240
+ if (view.goal) lines.push(`${t('fields.objective')}: ${view.goal}`);
241
+ if (view.turn) lines.push(`${view.turn.who}: ${view.turn.what}${view.turn.how ? ` · ${view.turn.how}` : ''}`);
77
242
  if (view.gateBar) lines.push(view.gateBar);
78
- if (view.runId) lines.push(view.origin ? `${view.runId} · ${view.origin}` : view.runId);
79
- if (view.objective) lines.push(`${t('fields.objective')}: ${view.objective}`);
80
243
  if (view.nextStep) lines.push(`${t('fields.nextStep')}: ${view.nextStep}`);
244
+ // The (i) details appear only once opened; its button is drawn beside this text.
245
+ if (view.isInfoExpanded) for (const item of view.info ?? []) lines.push(`${item.label}: ${item.text}`);
246
+ for (const warning of view.drift ?? []) lines.push(warning);
247
+ if (view.events) lines.push(`${t('fields.events')}:`, ...view.events);
248
+ if (view.review) {
249
+ lines.push(`${t('fields.material')}: ${view.review.summary} · ${view.review.match}${view.review.truncated ? ` · ${view.review.truncated}` : ''}`);
250
+ // The terminal shows the start of the preview too (PRD M1, AC-007; CR finding B10).
251
+ if (view.review.preview) lines.push(...view.review.preview.split('\n').slice(0, TERMINAL_PREVIEW_LINES).map(line => ` ${line}`));
252
+ }
253
+ if (view.eventsHint) lines.push(view.eventsHint);
254
+ // The run id is a reference, so it stands after what a person reads.
255
+ if (view.runId) lines.push(view.origin ? `${view.runId} · ${view.origin}` : view.runId);
81
256
  if (view.stale) lines.push(view.stale);
82
257
  if (view.readAt) lines.push(view.readAt);
83
258
  return lines.join('\n');
@@ -11,6 +11,7 @@ Explicit initialization creates `control_layout: "run-folders-v1"`. This is the
11
11
  SOT_REGISTRY.md
12
12
  CONTEXT_GRAPH.md
13
13
  AGENT_QUALITY_CONTRACTS.json
14
+ BRAND.md
14
15
  templates/
15
16
  planned/<plan_id>/UR.md
16
17
  runs/<run_id>/
@@ -28,6 +29,10 @@ Explicit initialization creates `control_layout: "run-folders-v1"`. This is the
28
29
 
29
30
  Configuration, templates and curated project context stay project-wide. A multi-Run closure preview is a target-wide decision proposal under `closure-previews/`; it changes no Run until deliberately applied. Run-owned outputs never use a separate top-level artefacts directory.
30
31
 
32
+ `BRAND.md` starts as a neutral English worksheet. Complete it with the project's
33
+ own design intent and declare the finished source in `SOT_REGISTRY.md` when it is
34
+ authoritative for design work.
35
+
31
36
  `RUN_STATE.md` keeps identity, objective, mode and typed decisions, source bindings and operations. Approval status, current gate, current document references, relationship chains, evidence summaries and inventory are derived when read. They are not separately writable tables or a second state file. A binding embeds its reviewer attestation; no separate RECORD/REVIEW JSON repeats its mapping. A planned handoff records its source in the creation receipt and immutable planning snapshot, without an origin JSON copy.
32
37
 
33
38
  Create a fresh scaffold in an explicitly confirmed existing Git repository:
@@ -0,0 +1,28 @@
1
+ # Brand and Design Intent
2
+
3
+ Complete this worksheet with confirmed project decisions. Declare the completed
4
+ profile in `SOT_REGISTRY.md` when it is the project's authoritative design source.
5
+
6
+ ## Owner and scope
7
+
8
+ Name the accountable owner, the product, and the surfaces and audiences covered.
9
+
10
+ ## Design intent
11
+
12
+ Describe what people should understand, feel, or be able to do when using the
13
+ product. Tie each priority to a concrete user task or situation.
14
+
15
+ ## Information and visual priorities
16
+
17
+ Explain what deserves emphasis in relevant states and how the project balances
18
+ competing priorities. Record any confirmed constraints and their sources.
19
+
20
+ ## Observable checks
21
+
22
+ For each applicable priority, name the scenario, the expected observable outcome,
23
+ and the evidence that would verify it. Record open decisions with their owners.
24
+
25
+ ## Related sources
26
+
27
+ Link the project's design system, implementation values, and brand usage policy
28
+ where applicable.
@@ -69,6 +69,17 @@ visible feedback, blocker/failure behavior, recovery/next action, observable suc
69
69
  evidence. Specify observable behavior, not implementation. Do not leave the section empty or retain
70
70
  placeholders when requesting approval.
71
71
 
72
+ Use separate field names; never combine them (for example,
73
+ `observable_success_required_evidence` is not `observable_success`). For same-language approval,
74
+ each criterion needs at least one nonempty `observable_success`, `visible_feedback` or
75
+ `expected_effective_state`. Keep applicable UX fields separate as well. Example:
76
+
77
+ ```markdown
78
+ - criterion_id: AC-001
79
+ - observable_success: A later list command shows the saved task unchanged.
80
+ - required_evidence: A real CLI test across separate processes.
81
+ ```
82
+
72
83
  ## 6. Non-Goals
73
84
 
74
85
  What remains out of scope?