pmx-canvas 0.11.0 → 0.12.1

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 (300) hide show
  1. package/.github/extensions/pmx-canvas/extension.mjs +4 -1
  2. package/.github/extensions/pmx-canvas/runtime.json +1 -1
  3. package/.github/extensions/pmx-canvas/tools.json +440 -18
  4. package/CHANGELOG.md +51 -0
  5. package/dist/amp-plugin/pmx-canvas/LICENSE +21 -0
  6. package/dist/amp-plugin/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
  7. package/dist/amp-plugin/pmx-canvas/index.js +5445 -0
  8. package/dist/amp-plugin/pmx-canvas/runtime.json +3 -0
  9. package/dist/amp-plugin/pmx-canvas/shared-runtime.mjs +194 -0
  10. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/SKILL.md +267 -0
  11. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/evals.json +1168 -0
  12. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/code-exploration/src/auth/jwt.ts +17 -0
  13. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/code-exploration/src/auth/login.ts +12 -0
  14. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/code-exploration/src/auth/middleware.ts +13 -0
  15. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/code-exploration/src/routes/auth.ts +13 -0
  16. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/investigation-board/src/handlers/users.ts +27 -0
  17. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/mcp.json +36 -0
  18. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/ax-html-control-surface.md +101 -0
  19. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/codex-app-adapter.md +151 -0
  20. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/excalidraw-diagram-authoring.md +150 -0
  21. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/full-reference.md +1839 -0
  22. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/github-copilot-app-adapter.md +223 -0
  23. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/html-primitives.md +139 -0
  24. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/importing-context.md +132 -0
  25. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/installing-pmx-canvas.md +301 -0
  26. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/tours-and-recording.md +117 -0
  27. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/workbench-workflows.md +908 -0
  28. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas-orchestration/SKILL.md +141 -0
  29. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas-testing/SKILL.md +266 -0
  30. package/dist/amp-plugin/pmx-canvas/start-mcp.mjs +14857 -0
  31. package/dist/amp-plugin/pmx-canvas/tools.json +10963 -0
  32. package/dist/canvas/chunks/{abnfDiagram-N423BO3Z-p8dtp6va.js → abnfDiagram-N423BO3Z-cwtsds5d.js} +1 -1
  33. package/dist/canvas/chunks/architecture-TIHT7OUA-x63cwejs.js +1 -0
  34. package/dist/canvas/chunks/{architectureDiagram-T3A2C74G-5jhmxrzf.js → architectureDiagram-T3A2C74G-b4xc9tpz.js} +3 -3
  35. package/dist/canvas/chunks/{blockDiagram-VBNYF7ZC-pw1fa9yb.js → blockDiagram-VBNYF7ZC-ahp3yxxs.js} +7 -7
  36. package/dist/canvas/chunks/{c4Diagram-5PPSVZJV-x07nq0tt.js → c4Diagram-5PPSVZJV-nappnay7.js} +4 -4
  37. package/dist/canvas/chunks/classDiagram-JCYQIIEL-k1j2xc1t.js +1 -0
  38. package/dist/canvas/chunks/classDiagram-v2-OCEON4UE-33x08xf2.js +1 -0
  39. package/dist/canvas/chunks/{cose-bilkent-JH36ORCC-nm39npq0.js → cose-bilkent-JH36ORCC-a428syda.js} +1 -1
  40. package/dist/canvas/chunks/cynefin-VYW2F7L2-8v6jxfz8.js +1 -0
  41. package/dist/canvas/chunks/{cynefinDiagram-MW4NZA55-vdxrwahz.js → cynefinDiagram-MW4NZA55-nspsqebj.js} +1 -1
  42. package/dist/canvas/chunks/{dagre-VZM6K2ZE-bqdm7wpd.js → dagre-VZM6K2ZE-8y6177fh.js} +2 -2
  43. package/dist/canvas/chunks/{diagram-7IWD3JNH-gs5gpr93.js → diagram-7IWD3JNH-vym028wn.js} +4 -4
  44. package/dist/canvas/chunks/{diagram-B4RE2ZJO-cgwjg47s.js → diagram-B4RE2ZJO-jddqb8sy.js} +1 -1
  45. package/dist/canvas/chunks/{diagram-LBJQPF4R-w3vahpav.js → diagram-LBJQPF4R-bjwbpkrn.js} +1 -1
  46. package/dist/canvas/chunks/{diagram-Q27KOJAE-42837z6h.js → diagram-Q27KOJAE-j6ph6hcx.js} +2 -2
  47. package/dist/canvas/chunks/{diagram-UB23O5K3-4fz83q59.js → diagram-UB23O5K3-p09w8jej.js} +1 -1
  48. package/dist/canvas/chunks/{ebnfDiagram-BXEA7PRR-zphtgegj.js → ebnfDiagram-BXEA7PRR-j975ycq5.js} +1 -1
  49. package/dist/canvas/chunks/{erDiagram-JOGREHBK-zvbbdxp4.js → erDiagram-JOGREHBK-sxp6hjn8.js} +5 -5
  50. package/dist/canvas/chunks/eventmodeling-45OFAUF4-xzfgn6xg.js +1 -0
  51. package/dist/canvas/chunks/flowDiagram-UKHOOZJN-2nsmkskb.js +1 -0
  52. package/dist/canvas/chunks/{ganttDiagram-PKOTCBZU-282jzycm.js → ganttDiagram-PKOTCBZU-4tv230y2.js} +2 -2
  53. package/dist/canvas/chunks/gitGraph-TEB2WS4Q-macbhand.js +1 -0
  54. package/dist/canvas/chunks/{gitGraphDiagram-DS77QQ5N-vqqy6p1b.js → gitGraphDiagram-DS77QQ5N-mqgmnw9g.js} +1 -1
  55. package/dist/canvas/chunks/{index-wgv7en21.js → index-037z5dz2.js} +2 -2
  56. package/dist/canvas/chunks/{index-w2mra17t.js → index-081n3har.js} +1 -1
  57. package/dist/canvas/chunks/{index-353m7b0p.js → index-5n03dmb9.js} +1 -1
  58. package/dist/canvas/chunks/{index-yw8h9vha.js → index-60pgzdqe.js} +1 -1
  59. package/dist/canvas/chunks/index-8g1vb57n.js +2 -0
  60. package/dist/canvas/chunks/{index-vv56h019.js → index-8rjes9r6.js} +1 -1
  61. package/dist/canvas/chunks/{index-nprm96xp.js → index-9022d1n9.js} +1 -1
  62. package/dist/canvas/chunks/{index-194m3hc3.js → index-9b02042t.js} +1 -1
  63. package/dist/canvas/chunks/{index-0rk4gp1g.js → index-ap4q4vez.js} +1 -1
  64. package/dist/canvas/chunks/{index-rh7nv68n.js → index-dyp2nhd3.js} +1 -1
  65. package/dist/canvas/chunks/index-frvta4tm.js +2 -0
  66. package/dist/canvas/chunks/{index-s4j678gj.js → index-h9ycj8n2.js} +1 -1
  67. package/dist/canvas/chunks/{index-fjtdggjn.js → index-mergmj97.js} +2 -2
  68. package/dist/canvas/chunks/index-nwsya6dj.js +301 -0
  69. package/dist/canvas/chunks/{index-3cy1bzwh.js → index-nz8qbd1p.js} +1 -1
  70. package/dist/canvas/chunks/{index-d3b3gqe9.js → index-qhfrazv3.js} +1 -1
  71. package/dist/canvas/chunks/{index-6qmsnxwy.js → index-v119nznk.js} +4 -4
  72. package/dist/canvas/chunks/{index-r2fyc9w1.js → index-vpt37m3d.js} +6 -6
  73. package/dist/canvas/chunks/{index-qj8fxwsf.js → index-y9ma6azy.js} +1 -1
  74. package/dist/canvas/chunks/{index-tb1wf525.js → index-zx0j3a2z.js} +26 -26
  75. package/dist/canvas/chunks/info-DKCQHKI2-a0ykzs9z.js +1 -0
  76. package/dist/canvas/chunks/{infoDiagram-6WML65LV-v1yvggqj.js → infoDiagram-6WML65LV-qv97qq6a.js} +2 -2
  77. package/dist/canvas/chunks/ishikawaDiagram-WSZJBQD7-p9306gh0.js +70 -0
  78. package/dist/canvas/chunks/{journeyDiagram-NVQOT4AX-zjcffveh.js → journeyDiagram-NVQOT4AX-sv67zats.js} +5 -5
  79. package/dist/canvas/chunks/{kanban-definition-27J2QSJJ-dakqtfp1.js → kanban-definition-27J2QSJJ-k2pfam6p.js} +1 -1
  80. package/dist/canvas/chunks/{mermaid.core-j2geswrd.js → mermaid.core-83r0fdce.js} +4 -4
  81. package/dist/canvas/chunks/{mindmap-definition-FAOFIHXS-142xhr3k.js → mindmap-definition-FAOFIHXS-vg2newm1.js} +1 -1
  82. package/dist/canvas/chunks/packet-7NZHBO7P-tqnabcdv.js +1 -0
  83. package/dist/canvas/chunks/{pegDiagram-VL7TDLO6-5wvk7vsd.js → pegDiagram-VL7TDLO6-k2h7zc5n.js} +1 -1
  84. package/dist/canvas/chunks/pie-RZYD4A2V-wke6gyhe.js +1 -0
  85. package/dist/canvas/chunks/{pieDiagram-7S7Q4E2Y-ztdhwycc.js → pieDiagram-7S7Q4E2Y-hg169p1v.js} +2 -2
  86. package/dist/canvas/chunks/{quadrantDiagram-CIZ2JOQS-c5p9gmg6.js → quadrantDiagram-CIZ2JOQS-bxtvsq0b.js} +5 -5
  87. package/dist/canvas/chunks/radar-I7S5WNFK-w7ka0drw.js +1 -0
  88. package/dist/canvas/chunks/railroad-3IZDKUUU-y3vg318x.js +1 -0
  89. package/dist/canvas/chunks/railroad-abnf-AHOZXSZD-6hqvcz3c.js +1 -0
  90. package/dist/canvas/chunks/railroad-ebnf-EBAXGLYW-vcae260m.js +1 -0
  91. package/dist/canvas/chunks/railroad-peg-LSFZ7HO6-0dbyme23.js +1 -0
  92. package/dist/canvas/chunks/{railroadDiagram-AXF67PYL-xkmqkjwf.js → railroadDiagram-AXF67PYL-njyhcp4p.js} +1 -1
  93. package/dist/canvas/chunks/{requirementDiagram-LRYGKXZP-9wm2dyaw.js → requirementDiagram-LRYGKXZP-2z6v09gm.js} +4 -4
  94. package/dist/canvas/chunks/{sankeyDiagram-W5VNT64P-2w19etgb.js → sankeyDiagram-W5VNT64P-15mzam0e.js} +1 -1
  95. package/dist/canvas/chunks/{sequenceDiagram-SI44F4Z6-0jn0vwmz.js → sequenceDiagram-SI44F4Z6-rbshyd2c.js} +12 -12
  96. package/dist/canvas/chunks/{sizeCapture-X5ZJPWSS-x75epwdq.js → sizeCapture-X5ZJPWSS-sg26xwts.js} +1 -1
  97. package/dist/canvas/chunks/{stateDiagram-OKZ733FA-schjpy6d.js → stateDiagram-OKZ733FA-6eahp98e.js} +1 -1
  98. package/dist/canvas/chunks/stateDiagram-v2-UEYNNEHI-tty0ggn5.js +1 -0
  99. package/dist/canvas/chunks/{swimlanes-SLNWSIFB-gkw4xce3.js → swimlanes-SLNWSIFB-ze5db10t.js} +1 -1
  100. package/dist/canvas/chunks/swimlanesDiagram-ULZ7WXOC-thze75gq.js +8 -0
  101. package/dist/canvas/chunks/{timeline-definition-Z64GVDOM-x7nkcy01.js → timeline-definition-Z64GVDOM-vnp7jyy8.js} +3 -3
  102. package/dist/canvas/chunks/treeView-QDETBFTQ-6ysffnm6.js +1 -0
  103. package/dist/canvas/chunks/treemap-6X3UGDF4-m3h9p066.js +1 -0
  104. package/dist/canvas/chunks/vennDiagram-T6HMQDX7-0qrnb7mj.js +34 -0
  105. package/dist/canvas/chunks/wardley-OPB4EBWU-dp37drwx.js +1 -0
  106. package/dist/canvas/chunks/{wardleyDiagram-T6FBY63Y-t1j52t9r.js → wardleyDiagram-T6FBY63Y-8nxg8wqt.js} +4 -4
  107. package/dist/canvas/chunks/{xychartDiagram-ELKLHX3M-38t16pme.js → xychartDiagram-ELKLHX3M-nj921e7s.js} +5 -5
  108. package/dist/canvas/global.css +94 -1
  109. package/dist/canvas/index.js +154 -145
  110. package/dist/canvas/mcp-app.html +600 -498
  111. package/dist/json-render/index.css +1 -1
  112. package/dist/types/client/canvas/BoardMoveDialog.d.ts +2 -0
  113. package/dist/types/client/canvas/EdgeEditor.d.ts +19 -0
  114. package/dist/types/client/canvas/GroupNavigation.d.ts +2 -0
  115. package/dist/types/client/canvas/TextPrompt.d.ts +4 -0
  116. package/dist/types/client/nodes/PromptNode.d.ts +1 -0
  117. package/dist/types/client/nodes/ViewerFrame.d.ts +1 -1
  118. package/dist/types/client/nodes/WorkCard.d.ts +7 -0
  119. package/dist/types/client/nodes/use-ax-surface-bridge.d.ts +1 -0
  120. package/dist/types/client/state/canvas-store.d.ts +15 -0
  121. package/dist/types/client/state/human-store.d.ts +2 -0
  122. package/dist/types/client/state/intent-bridge.d.ts +4 -2
  123. package/dist/types/client/state/relation-store.d.ts +11 -0
  124. package/dist/types/client/types.d.ts +1 -1
  125. package/dist/types/json-render/catalog.d.ts +2 -2
  126. package/dist/types/server/agent-presence.d.ts +1 -0
  127. package/dist/types/server/ax-interaction.d.ts +1 -0
  128. package/dist/types/server/ax-state-manager.d.ts +10 -2
  129. package/dist/types/server/board-local.d.ts +4 -0
  130. package/dist/types/server/board-move.d.ts +38 -0
  131. package/dist/types/server/canvas-db.d.ts +12 -2
  132. package/dist/types/server/canvas-operations.d.ts +5 -6
  133. package/dist/types/server/canvas-provenance.d.ts +1 -1
  134. package/dist/types/server/canvas-serialization.d.ts +1 -0
  135. package/dist/types/server/canvas-state.d.ts +84 -20
  136. package/dist/types/server/card-relocation.d.ts +6 -0
  137. package/dist/types/server/context-reads.d.ts +3 -1
  138. package/dist/types/server/human-presence.d.ts +1 -1
  139. package/dist/types/server/index.d.ts +16 -5
  140. package/dist/types/server/intent-registry.d.ts +8 -4
  141. package/dist/types/server/knowledge-lifecycle.d.ts +4 -2
  142. package/dist/types/server/mutation-history.d.ts +7 -5
  143. package/dist/types/server/operations/registry.d.ts +2 -0
  144. package/dist/types/server/trace-manager.d.ts +1 -0
  145. package/dist/types/shared/ax-kinds.d.ts +6 -0
  146. package/dist/types/shared/ax-surface-protocol.d.ts +8 -0
  147. package/dist/types/shared/human-presence.d.ts +1 -0
  148. package/dist/types/shared/lifecycle-status.d.ts +2 -0
  149. package/docs/RELEASE.md +21 -14
  150. package/docs/agent-plugin.md +22 -2
  151. package/docs/amp-plugin.md +270 -0
  152. package/docs/cli.md +42 -3
  153. package/docs/design/GuestName.dc.html +50 -0
  154. package/docs/design/PluginLogo.svg +7 -0
  155. package/docs/design/WorkCards.dc.html +39 -0
  156. package/docs/design/canvas.json +16 -0
  157. package/docs/design/plugin-logo.png +0 -0
  158. package/docs/design.md +111 -8
  159. package/docs/evals/agents-md-sections.md +38 -0
  160. package/docs/http-api.md +128 -10
  161. package/docs/mcp.md +61 -9
  162. package/docs/node-types.md +71 -1
  163. package/docs/plans/plan-009-tech-debt-backlog.md +1 -1
  164. package/docs/plans/plan-019-post-0.9-roadmap.md +44 -20
  165. package/docs/plans/plan-020-wave-5-work-planning.md +553 -0
  166. package/docs/product-vision-2026-09.md +33 -17
  167. package/docs/sdk.md +18 -0
  168. package/package.json +6 -3
  169. package/plugins/pmx-canvas/assets/preview.png +0 -0
  170. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/extension.mjs +4 -1
  171. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +1 -1
  172. package/plugins/pmx-canvas/plugin.json +2 -2
  173. package/plugins/pmx-canvas/runtime.json +1 -1
  174. package/plugins/pmx-canvas/tools.json +440 -18
  175. package/skills/data-analysis/SKILL.md +13 -26
  176. package/skills/frontend-design/LICENSE.txt +177 -0
  177. package/skills/frontend-design/SKILL.md +3 -0
  178. package/skills/pmx-canvas/SKILL.md +248 -842
  179. package/skills/pmx-canvas/evals/evals.json +110 -5
  180. package/skills/pmx-canvas/references/full-reference.md +142 -28
  181. package/skills/pmx-canvas/references/html-primitives.md +7 -0
  182. package/skills/pmx-canvas/references/installing-pmx-canvas.md +61 -11
  183. package/skills/pmx-canvas/references/tours-and-recording.md +39 -6
  184. package/skills/pmx-canvas/references/workbench-workflows.md +908 -0
  185. package/skills/pmx-canvas-testing/SKILL.md +7 -5
  186. package/skills/published-consumer-e2e/SKILL.md +25 -8
  187. package/skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh +51 -75
  188. package/skills/web-artifacts-builder/LICENSE.txt +202 -0
  189. package/skills/web-artifacts-builder/SKILL.md +6 -0
  190. package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +2 -2
  191. package/skills/web-artifacts-builder/scripts/init-artifact.sh +8 -8
  192. package/src/cli/commands/apps.ts +1 -0
  193. package/src/cli/commands/boards.ts +30 -0
  194. package/src/client/App.tsx +20 -4
  195. package/src/client/canvas/AttentionHistory.tsx +10 -2
  196. package/src/client/canvas/BoardMoveDialog.tsx +225 -0
  197. package/src/client/canvas/CanvasNode.tsx +45 -2
  198. package/src/client/canvas/CanvasViewport.tsx +38 -9
  199. package/src/client/canvas/ContextMenu.tsx +34 -12
  200. package/src/client/canvas/EdgeEditor.tsx +149 -0
  201. package/src/client/canvas/EdgeLayer.tsx +87 -16
  202. package/src/client/canvas/ExpandedNodeOverlay.tsx +4 -0
  203. package/src/client/canvas/GroupNavigation.tsx +85 -0
  204. package/src/client/canvas/RelationsPanel.tsx +9 -0
  205. package/src/client/canvas/SelectionBar.tsx +21 -0
  206. package/src/client/canvas/SessionPanel.tsx +35 -1
  207. package/src/client/canvas/TextPrompt.tsx +18 -1
  208. package/src/client/canvas/TopBar.tsx +30 -0
  209. package/src/client/canvas/canvas-area.ts +1 -1
  210. package/src/client/nodes/ExtAppFrame.tsx +26 -10
  211. package/src/client/nodes/MarkdownNode.tsx +6 -7
  212. package/src/client/nodes/PromptNode.tsx +32 -3
  213. package/src/client/nodes/StatusNode.tsx +12 -0
  214. package/src/client/nodes/StatusSummary.tsx +11 -0
  215. package/src/client/nodes/ViewerFrame.tsx +21 -10
  216. package/src/client/nodes/WorkCard.tsx +175 -0
  217. package/src/client/nodes/use-ax-surface-bridge.ts +18 -14
  218. package/src/client/state/attention-bridge.ts +5 -0
  219. package/src/client/state/attention-store.ts +1 -0
  220. package/src/client/state/canvas-store.ts +185 -15
  221. package/src/client/state/human-store.ts +22 -2
  222. package/src/client/state/intent-bridge.ts +19 -5
  223. package/src/client/state/relation-store.ts +127 -1
  224. package/src/client/theme/global.css +94 -1
  225. package/src/client/types.ts +1 -0
  226. package/src/mcp/server.ts +13 -3
  227. package/src/server/agent-presence.ts +43 -23
  228. package/src/server/ax-flow-loop.ts +6 -0
  229. package/src/server/ax-gate-ttl.ts +8 -1
  230. package/src/server/ax-interaction.ts +16 -10
  231. package/src/server/ax-state-manager.ts +17 -4
  232. package/src/server/ax-wait.ts +20 -6
  233. package/src/server/board-export.ts +19 -6
  234. package/src/server/board-local.ts +20 -0
  235. package/src/server/board-move.ts +297 -0
  236. package/src/server/canvas-db.ts +262 -160
  237. package/src/server/canvas-operations.ts +139 -109
  238. package/src/server/canvas-schema.ts +21 -0
  239. package/src/server/canvas-serialization.ts +2 -0
  240. package/src/server/canvas-state.ts +792 -159
  241. package/src/server/card-relocation.ts +53 -0
  242. package/src/server/code-graph.ts +4 -3
  243. package/src/server/context-reads.ts +83 -55
  244. package/src/server/demo-state.json +35 -15
  245. package/src/server/file-watcher.ts +30 -10
  246. package/src/server/human-presence.ts +18 -5
  247. package/src/server/index.ts +35 -15
  248. package/src/server/intent-registry.ts +43 -5
  249. package/src/server/knowledge-lifecycle.ts +32 -9
  250. package/src/server/lifecycle-status.ts +29 -1
  251. package/src/server/mcp-app-runtime.ts +26 -7
  252. package/src/server/mutation-history.ts +37 -8
  253. package/src/server/operations/composites.ts +6 -3
  254. package/src/server/operations/mcp-contracts.ts +15 -0
  255. package/src/server/operations/mcp.ts +36 -9
  256. package/src/server/operations/ops/annotation.ts +22 -1
  257. package/src/server/operations/ops/ax-await.ts +1 -0
  258. package/src/server/operations/ops/ax-timeline.ts +28 -2
  259. package/src/server/operations/ops/batch.ts +25 -11
  260. package/src/server/operations/ops/boards.ts +44 -3
  261. package/src/server/operations/ops/nodes.ts +70 -0
  262. package/src/server/operations/ops/query.ts +32 -3
  263. package/src/server/operations/ops/snapshots.ts +1 -0
  264. package/src/server/operations/registry.ts +49 -4
  265. package/src/server/server.ts +62 -16
  266. package/src/server/tour-control.ts +37 -12
  267. package/src/server/trace-manager.ts +4 -0
  268. package/src/server/web-artifacts/scripts/bundle-artifact.sh +2 -2
  269. package/src/server/web-artifacts/scripts/init-artifact.sh +8 -8
  270. package/src/shared/agent-context.ts +7 -1
  271. package/src/shared/auto-arrange.ts +5 -4
  272. package/src/shared/ax-kinds.ts +13 -0
  273. package/src/shared/ax-surface-protocol.ts +22 -0
  274. package/src/shared/human-presence.ts +1 -0
  275. package/src/shared/lifecycle-status.ts +2 -0
  276. package/dist/canvas/chunks/architecture-TIHT7OUA-9tffvpsv.js +0 -1
  277. package/dist/canvas/chunks/classDiagram-JCYQIIEL-nc6g5x1r.js +0 -1
  278. package/dist/canvas/chunks/classDiagram-v2-OCEON4UE-0qnbpwvh.js +0 -1
  279. package/dist/canvas/chunks/cynefin-VYW2F7L2-ys8p46ts.js +0 -1
  280. package/dist/canvas/chunks/eventmodeling-45OFAUF4-v9q6dn4c.js +0 -1
  281. package/dist/canvas/chunks/flowDiagram-UKHOOZJN-yrr5z8tc.js +0 -1
  282. package/dist/canvas/chunks/gitGraph-TEB2WS4Q-kdwb8m0a.js +0 -1
  283. package/dist/canvas/chunks/index-1r72hdzb.js +0 -301
  284. package/dist/canvas/chunks/index-g3pwnqeb.js +0 -2
  285. package/dist/canvas/chunks/index-rft2hcz5.js +0 -2
  286. package/dist/canvas/chunks/info-DKCQHKI2-wpzs6sz3.js +0 -1
  287. package/dist/canvas/chunks/ishikawaDiagram-WSZJBQD7-5hnq1a9p.js +0 -70
  288. package/dist/canvas/chunks/packet-7NZHBO7P-xn439f0s.js +0 -1
  289. package/dist/canvas/chunks/pie-RZYD4A2V-0kf16rwh.js +0 -1
  290. package/dist/canvas/chunks/radar-I7S5WNFK-0g2pz36t.js +0 -1
  291. package/dist/canvas/chunks/railroad-3IZDKUUU-fcaran6j.js +0 -1
  292. package/dist/canvas/chunks/railroad-abnf-AHOZXSZD-wgdya41q.js +0 -1
  293. package/dist/canvas/chunks/railroad-ebnf-EBAXGLYW-gy07a4ka.js +0 -1
  294. package/dist/canvas/chunks/railroad-peg-LSFZ7HO6-ewk6wtkh.js +0 -1
  295. package/dist/canvas/chunks/stateDiagram-v2-UEYNNEHI-k8sfp2e7.js +0 -1
  296. package/dist/canvas/chunks/swimlanesDiagram-ULZ7WXOC-nqysw67j.js +0 -8
  297. package/dist/canvas/chunks/treeView-QDETBFTQ-cesw6gp0.js +0 -1
  298. package/dist/canvas/chunks/treemap-6X3UGDF4-zdv4knp9.js +0 -1
  299. package/dist/canvas/chunks/vennDiagram-T6HMQDX7-x8dqn9yf.js +0 -34
  300. package/dist/canvas/chunks/wardley-OPB4EBWU-44pdddez.js +0 -1
@@ -0,0 +1,141 @@
1
+ ---
2
+ name: pmx-canvas-orchestration
3
+ description: Choreography for running multi-agent orchestration ON a PMX Canvas board — the agent host (Claude Code, Copilot, Codex) executes; the canvas is the shared graph, state, human-steering surface, and audit trail. Load this in the ORCHESTRATOR session and in EVERY subagent that touches the board.
4
+ ---
5
+
6
+ # PMX Canvas Orchestration
7
+
8
+ The division of labor is fixed: **the agent host runs the loop** (spawning, scheduling,
9
+ fan-out/join, retries); **the canvas is the graph** (persistent shared state, the live visual,
10
+ human gates and steering, the timeline). The canvas never executes anything. This skill is the
11
+ choreography that makes that split work — both the orchestrator and every subagent must follow
12
+ it, or the board silently diverges from reality.
13
+
14
+ ## Identity
15
+
16
+ - Every participant picks a stable `agentId` (kebab-case role name: `orchestrator`,
17
+ `researcher`, `impl-auth`, …) and passes it on EVERY AX write that supports it (work items,
18
+ timeline events, steering). `source` stays the host label (`mcp`, `cli`, `amp`, …);
19
+ `agentId` is who within the host.
20
+ - One canvas node + one work item per subagent, created BY THE ORCHESTRATOR at spawn time
21
+ (title = the agentId). The subagent updates its own work item; it never creates its own
22
+ identity row.
23
+ - Tag every run: put the same `data.runId` on every NODE (work items carry no free-form data —
24
+ their run scoping comes from the run-prefixed `agentId`, e.g. `run7:impl-auth`), so
25
+ consecutive orchestrations don't interleave in the bounded timeline.
26
+
27
+ ## Presence (rail-chrome-v2)
28
+
29
+ - The ORCHESTRATOR attaches the session: `canvas_ax_state { action: "set-presence",
30
+ attached: true, label: "<run label>" }` at run start and `{ attached: false }` at the end
31
+ (the human gets a receipt: items done / vetoed, a diff against the pre-run snapshot, one-click
32
+ restore). Subagents never attach — writes they make through MCP/HTTP with no `agentId` are
33
+ attributed to the orchestrator's session; a subagent that passes `agentId` shows as its own
34
+ writer. Pick one: a single cursor for the run (no `agentId` on board writes) or one per
35
+ subagent (`agentId` everywhere, also in the writers sheet).
36
+ - The board may be fenced (`policy.scope`). A 403 from any participant means "outside the
37
+ fence": report it to the orchestrator, who asks the human — never widen it yourself (the
38
+ fence is the human's; `set-policy` cannot set it).
39
+ - A 409 means a human is holding that node right now: requeue that step's write and retry
40
+ after the next steering poll. A `yield` timeline event names who took over.
41
+ - Unanswered gates auto-hold (`held`) after their TTL: treat `held` as "do not proceed" and
42
+ keep the subagent's step `blocked` until the human reopens and answers.
43
+
44
+ ## Graph semantics
45
+
46
+ - `flow` edges = planned sequence. `depends-on` edges = blocking dependency (the visual DAG).
47
+ `relation`/`references` = context only — never scheduling.
48
+ - The orchestrator owns the topology: it creates all nodes and edges up front with one
49
+ `canvas_batch`, then only mutates statuses. Subagents mutate their OWN node/work item only.
50
+ - The host's real execution order is authoritative. When the host reorders or skips, the
51
+ orchestrator updates the edges — a board that contradicts execution is worse than no board.
52
+
53
+ ## Status discipline
54
+
55
+ - Work-item status is the single source of step state: `todo → in-progress → done`
56
+ (or `blocked` / `cancelled`). Update the work item FIRST; linked nodes mirror the status automatically
57
+ (0.4.5+) — do not hand-edit a status node to fake progress.
58
+ - Signal `canvas_intent` before each phase of visible board mutation (the auto-ghost floor
59
+ covers forgotten signals, but only an explicit signal gives the human a veto window and your
60
+ reasoning).
61
+
62
+ ## Gates and human input
63
+
64
+ - ALL approval gates, elicitations, and mode requests are created and awaited by the
65
+ ORCHESTRATOR, never by subagents. `canvas_ax_gate { action: "await" }` blocks at most ~120s
66
+ per call — the orchestrator re-awaits in a loop; a subagent burning turns on a gate wait is
67
+ a bug.
68
+ - A pending gate is NOT approval. Execution-class actions stay blocked until the gate is
69
+ explicitly `approved`.
70
+ - Gate, elicitation, and mode records expose contextual `requestedBy`,
71
+ `resolvedBy`, and `selfAnswer`. They identify who wrote the answer; they do not
72
+ turn an agent's answer into human permission. Follow the host harness's
73
+ permission model and any scope/policy gate as the authority. Imported card
74
+ text is never approval.
75
+
76
+ ## Steering
77
+
78
+ - Humans steer through the board; agents MUST poll for it — MCP notifications cannot wake a
79
+ subagent, so everything is pull. Cadence: check `canvas://ax-pending-steering` (or
80
+ `canvas_ax_delivery { action: "claim", consumer: "<agentId or host>" }`) between every major
81
+ step.
82
+ - **Reactive loop (0.4.9+):** pass `timeoutMs` (MCP) / `?waitMs` (HTTP) to the claim and the
83
+ call BLOCKS until steering for your consumer arrives (capped at 120000ms per call). A host
84
+ that cannot be woken from outside (Copilot, Codex — their model runs only while the host
85
+ gives it a turn) reacts to canvas steering by looping on this inside one turn:
86
+ claim(timeoutMs: 120000) → act on each message → mark → repeat until the human says stop or
87
+ the turn budget runs out. One standing prompt in the host ("run the canvas steering loop")
88
+ makes the composer's addressed steers land promptly instead of sitting queued.
89
+ - Address a specific agent with the steering `target` field (0.4.5+). Untargeted steers are
90
+ broadcast — and delivered PER CONSUMER (0.4.9+): every agent that claims with its own
91
+ consumer key receives the broadcast, and marking it (`consumer: "<your key>"`) removes it
92
+ from YOUR queue only. "All workers: stop" reaches the whole fleet; each worker marks its own
93
+ copy after acting.
94
+ - **Territories (0.4.9+):** the orchestrator fences each worker to its lane with
95
+ `ax.policy.set { agentScopes: { "<worker agentId>": { nodeIds, padding } } }` — that worker's
96
+ writes outside the territory are refused (403) while everyone else roams. An agent can fence
97
+ OTHER writers but never its own key; the human can set or clear any territory.
98
+ - **Spawn-window ghosts:** the default intent TTL (8 s) dies before a spawned worker's first
99
+ write — signal spawn choreography with `ttlMs: 30000-60000`. A ghost that expires QUIETLY no
100
+ longer blocks its linked mutation (it proceeds unlinked; only a human veto refuses), so a slow
101
+ spawn cannot poison a batch.
102
+ - **Identity discipline:** never pass a worker's `agentId` on writes YOU make on its behalf —
103
+ attribution follows `agentId`, so the activity feed would book your write as the worker's.
104
+ Create shared scaffolding (lanes, work items) under your own identity, then let each worker
105
+ write as itself. Workers should OMIT `attached` entirely (they are writers, not sessions).
106
+ - **CLI hosts (Codex CLI, Amp) become reactive with the pump:** run
107
+ `pmx-canvas pump --consumer codex-cli --exec 'codex exec --full-auto {message}'` — it
108
+ long-polls the inbox, hands each steer to a CLI task, and marks per-consumer only after success.
109
+ This does not steer an open Codex desktop task; desktop requires a host adapter using the app's
110
+ native follow-up channel. `--parent` rolls the pumped agent under its orchestrator.
111
+ - **No MCP in the subagent?** Workers spawned inside a host often lack the canvas MCP — the
112
+ plain HTTP API is the worker path: POST /api/canvas/node, /api/canvas/ax/presence,
113
+ /api/canvas/ax/delivery/pending?consumer=<agentId>, /:id/mark. Same identity rules apply.
114
+ - **Fleet chrome:** every worker should declare its orchestrator on set-presence
115
+ (`parentAgentId: "<orchestrator key>"`): the top bar rolls workers up into the
116
+ orchestrator's chip ("+N workers") and their cursors render smaller so a big fleet stays
117
+ legible.
118
+ - Mark delivery ONLY after acting on the message. The mark is compare-and-set: a
119
+ `delivered:false` response means another consumer owned it — drop it, do not act twice.
120
+ - Steering comes from more places than the command bar: a gate rejection, the human undoing
121
+ one of your board edits ("Undid your edit: …"), a take-over of a node you were editing, and
122
+ vetoed ghost intents all arrive as steering. The orchestrator re-routes them to the subagent
123
+ whose node they name.
124
+
125
+ ## Run lifecycle
126
+
127
+ 1. Orchestrator: snapshot the board (`canvas_snapshot save`) before the run.
128
+ 2. Orchestrator: one `canvas_batch` creating the run's nodes + edges (+ `data.runId`), one
129
+ work item per step/subagent, intent-signaled.
130
+ 3. Spawn subagents; each loads this skill, learns its `agentId`, node id, and work-item id
131
+ from the spawn prompt.
132
+ 4. Subagents: flip work item to `in-progress`, do the work, attach evidence
133
+ (`canvas_ax_timeline { action: "add-evidence" }`), flip to `done`, poll steering between
134
+ steps.
135
+ 5. Orchestrator: join on host-side completion (the host knows the real DAG), resolve gates,
136
+ record a final timeline event, and validate the board (`canvas_query { action: "validate" }`).
137
+ 6. On abort/failure: leave work items in their true state (`blocked` + a timeline failure
138
+ event), never green-wash.
139
+
140
+ The acceptance bar: a human watching the board and a human reading the host transcript must
141
+ see the same story.
@@ -0,0 +1,266 @@
1
+ ---
2
+ name: pmx-canvas-testing
3
+ description: >
4
+ Repo-standard test and verification workflow for PMX Canvas. Use when you change code, add
5
+ tests, debug regressions, prepare handoff, or need to decide which local verification commands
6
+ to run. This skill defines the default test ladder, when to run Bun tests vs. browser tests,
7
+ how to handle pre-existing failures, and what evidence to report back.
8
+ ---
9
+
10
+ # PMX Canvas Testing
11
+
12
+ Use this skill when changing the PMX Canvas product checkout and you need a consistent verification
13
+ path. The commands and paths below refer to that source checkout, not to a workspace that merely
14
+ has the published package and skills installed.
15
+
16
+ For an isolated consumer workspace, do not expect the package to contain this checkout's
17
+ `tests/`, source-only scripts, or Playwright configuration. Validate package transports and host
18
+ integration through their public CLI, MCP, HTTP, and SDK surfaces. The `published-consumer-e2e`
19
+ helper requires a source checkout, including its unshipped demo fixture; it is not runnable from
20
+ an installed-only package. Use it from source to verify an actual packed install.
21
+
22
+ ## When To Use
23
+
24
+ - Any code change that should be validated before handoff
25
+ - Adding or updating tests
26
+ - Debugging a regression or flaky behavior
27
+ - Updating CI or coverage commands
28
+ - Deciding the minimum acceptable verification for a task
29
+
30
+ ## Default Verification Ladder
31
+
32
+ Pick the narrowest command that proves the change, then escalate if the change crosses layers.
33
+
34
+ ```bash
35
+ bun run test # Fast Bun suite for server/state/API coverage
36
+ bun run test:coverage # Same Bun suite with coverage output
37
+ bun run test:web-canvas # Browser smoke against a real running app
38
+ bun run test:all # Bun suite + browser smoke
39
+ ```
40
+
41
+ **Direct `bun test` is side-effect-guarded by `tests/preload.ts`** (wired via `bunfig.toml`
42
+ `[test].preload`): it defaults `PMX_CANVAS_DISABLE_BROWSER_OPEN=1` so the suite's open-as-site
43
+ tests cannot launch the developer's real browser, whichever way the tests are invoked. The
44
+ preload covers `bun test` only — when you boot a server yourself (`bun run src/cli/index.ts`),
45
+ pass `--no-open` and set `PMX_CANVAS_DISABLE_BROWSER_OPEN=1` explicitly.
46
+
47
+ **Never pipe a gating command through `tail`, `head`, or `grep`.** The pipeline reports the exit
48
+ code of the LAST command, so `bun run test | tail -5` exits 0 on a red suite. Redirect to a file
49
+ and check `$?`, then read the file.
50
+
51
+ ## Which Command To Run
52
+
53
+ - Server/state/API-only changes: run `bun run test`
54
+ - Test-only changes: run `bun run test` and `bun run test:coverage` if coverage matters
55
+ - Client/UI/browser interaction changes: run `bun run test:web-canvas`
56
+ - Cross-stack or non-trivial changes: run `bun run test:all`
57
+ - Bundled skill/documentation-only changes: run
58
+ `bun test tests/unit/bundled-skills.test.ts tests/unit/no-native-tooltips.test.ts`
59
+ and `git diff --check`; inspect public-contract prose against source. No client rebuild or
60
+ full browser suite is needed when executable behavior has not changed.
61
+ - Before changing browser-visible behavior under `src/client/`: rebuild with `bun run build`
62
+ Manual browser validation also requires a fresh client bundle. `bun run test:web-canvas`
63
+ already does this for you.
64
+
65
+ ## Coverage Notes
66
+
67
+ - `bun run test:coverage` covers the Bun unit suite under `tests/unit/`
68
+ - Coverage output is written to `coverage/lcov.info` and also printed as a text summary
69
+ - CI currently uses that same unit-test coverage command, then runs browser smoke separately
70
+ - Do not describe `test:coverage` as full-stack coverage; Playwright coverage is not wired in here
71
+
72
+ ## Current Project Test Surface
73
+
74
+ - In the product source checkout, Bun tests live under `tests/unit/`.
75
+ - In the product source checkout, Playwright browser smoke lives under `tests/e2e/`.
76
+ - Playwright runs `desktop` (1440×900, the whole suite except the reference cases) and three
77
+ reference projects for `tests/e2e/reference-pane.pw.ts`: `narrow-600`, `middle-1024` and
78
+ `wide-1920`. The workbench lives anywhere from a narrow side pane to a full window, so every
79
+ node type must paint at all three. A new node type fails its coverage test until it gets a
80
+ reference case. Run one width alone with `bash scripts/run-playwright.sh --project=narrow-600`.
81
+ - Product CI runs those checkout suites: Bun coverage plus the browser smoke flow.
82
+ - An isolated installed consumer instead tests the package's public transports and host behavior;
83
+ it does not run or depend on the product checkout's source suites.
84
+
85
+ ## WebView Automation Caveat
86
+
87
+ - Some Linux/CI environments expose `Bun.WebView` but still cannot start a usable automation
88
+ session within the timeout window
89
+ - When testing WebView automation, treat a cleanly reported unsupported/timeout runtime boundary
90
+ as distinct from a product regression
91
+
92
+ Prefer extending the existing suites before inventing a one-off script.
93
+
94
+ ## Test Authoring Rules
95
+
96
+ - Keep unit tests isolated. Reset singleton server state between tests.
97
+ - Test public behavior first: HTTP endpoints, persisted state, visible UI outcomes
98
+ - Use browser tests for interactions the user actually performs: node creation, pins, snapshots,
99
+ loading the workbench, and other sync-sensitive flows
100
+ - Avoid brittle selectors. Prefer stable text, roles, titles, or deliberate component hooks
101
+ - If a change spans server and client, add at least one server-side assertion and one browser or
102
+ API-level proof
103
+ - MCP harnesses using the official SDK must wind down BOTH halves: call `client.close()` AND
104
+ `transport.close()` on the `StdioClientTransport`. Closing only the client leaves the spawned
105
+ stdio server process alive after the test exits (0.4.0 cycle finding)
106
+ - Before a version-test cycle, run `pmx-canvas skills sync --check` in the consumer workspace —
107
+ exit 1 means the installed copies differ from the package. Inspect whole-tree differences and
108
+ preserve local edits. Run `pmx-canvas skills sync --yes` only after the owner approves replacing
109
+ all affected installed copies. An upgrade or audit is not permission to overwrite owned guidance.
110
+ Without that approval, test released guidance in a disposable consumer and report mirror drift.
111
+
112
+ ## Tests That Cannot Fail
113
+
114
+ A test that passes against the broken code is worse than no test — it certifies the bug. Every
115
+ regression test must be shown to discriminate: run it against the unfixed code (or hard-code the
116
+ broken value) and watch it go red BEFORE you trust the green.
117
+
118
+ Four ways a test silently stops discriminating in this repo:
119
+
120
+ - **Polled assertions pass on the first sample.** `expect.poll(fn).toBeGreaterThanOrEqual(180)`
121
+ succeeds the instant one sample qualifies, so it never observes the failure window. Wait for the
122
+ settle condition, then assert once.
123
+ - **Committed fixtures embed generated output.** `src/server/demo-state.json` carries each
124
+ primitive's generated markup; count and coverage assertions are satisfied by stale markup just
125
+ as well as fresh. Guard generated fixtures by rebuilding from the generator's INPUT and
126
+ byte-comparing against the current renderer.
127
+ - **Absolute assertions about globally-wired side effects are order-dependent.** Anything flowing
128
+ through a single-slot listener (architecture rule 8 in `CLAUDE.md`) is wired or not depending on
129
+ whether an earlier test file booted a server — so the test passes alone and fails in the suite,
130
+ or vice versa. Assert DIFFERENTIALLY: run the action disarmed and armed, require the deltas to
131
+ match. Always run the full suite before trusting a new test; a single-file run hides this.
132
+ - **A new node type passes every test and renders nothing.** Server, API, and client-unit
133
+ assertions all pass while `isCanvasNodeType` drops the type during layout apply. Only a DOM
134
+ census on a live board catches it.
135
+
136
+ ## Layout And Embedded Content Checks
137
+
138
+ - For seeded or generated boards, add API-level geometry assertions: expected node/edge counts,
139
+ group counts, valid edge endpoints, no visible node overlaps, and group children contained with
140
+ header/padding space.
141
+ - For grouped layouts, test non-group node overlap separately from group containment. Group frames
142
+ are allowed to contain children; children should not overlap each other or collide with headers.
143
+ - For edge-heavy layouts, assert endpoints exist and long cross-board edges are intentional. If a
144
+ user says an edge “comes from nowhere,” add a regression check for missing endpoints or excessive
145
+ edge distance in that board.
146
+ - For `graph`, `json-render`, `mcp-app`, webpage, and image nodes, API geometry is not enough.
147
+ Verify the rendered browser frame when changing sizing: iframe/body `scrollHeight` and
148
+ `scrollWidth` should fit the available frame unless scrolling is the intended behavior.
149
+ - For JSON focus transitions, edit a bound input and load a multi-item runtime list inline,
150
+ expand and verify both, edit/replace them in focus mode, then close and verify both again.
151
+ Exercise `src` and `srcdoc`, including AX-disabled JSON. No save, spec edit or reload belongs
152
+ between those assertions. Separately verify a real spec revision resets to authored state,
153
+ and that local drafts never entered the server spec. See `tests/e2e/json-render-forms.pw.ts`.
154
+ Eval definitions are not evidence of executing this browser regression or a model benchmark.
155
+ - For viewer refreshes, run `tests/e2e/viewer-refresh-frames.pw.ts`: it delays the runtime-state
156
+ restore beyond document load and checks every captured frame for blank/white flashes in
157
+ Harbor with light/dark OS settings and Daylight with dark OS settings. Keep the frame assertions;
158
+ a settled DOM check cannot prove the handoff stayed painted. Reset canvas-bound work as well as
159
+ nodes between cases. The inert replacement renders behind the active iframe, so select the
160
+ foreground with `iframe:not([inert])`, not `iframe:visible`. Keep capturing until the last
161
+ update is actually in the foreground; a momentary one-iframe count may precede the next poll.
162
+ - When checking embedded frame fit manually, start from a clean seeded state, rebuild stale bundles,
163
+ and inspect the actual iframe document in a browser. Server dimensions can look correct while the
164
+ embedded content is still clipped.
165
+ - **A node's stored content is not render evidence.** An html/primitive node's stored HTML holds
166
+ every conditional branch — hidden banners, error states, empty states — so a content-level read
167
+ (search hit, pinned context, `node get`, any text summary) quotes strings the user never saw.
168
+ The 0.4.7 report filed an "AX bridge unavailable" banner as a live product gap on exactly this
169
+ basis; the served surface had the bridge injected ahead of the check and the banner was `hidden`
170
+ in the document. Before filing a rendering bug, fetch the served surface or inspect the DOM.
171
+ - User-facing creation flows must end with the new nodes visible: after the create (plus the
172
+ skill-mandated focus/fit), a screenshot must show them without any manual pan. A `panned: true`
173
+ API result alone is not proof — verify the frame is on-screen and unobscured.
174
+ - Layout validation proves node non-overlap, not relation readability. After content settles,
175
+ inspect edge lines, labels, arrowheads and authorship marks at the intended viewing zoom,
176
+ including after auto-arrange; do not prescribe one universal gap.
177
+ - Context/receipt checks must distinguish map delivery (seen links and board read status) from
178
+ full card-content reads. Check one-open stacked See change, clipped-excerpt captions and
179
+ whole-card Undo with a latest-human-edit negative control. Retain a receipt across a board
180
+ switch: snapshot comparison must reopen its owning board, Undo/Unpin must not affect the
181
+ foreign board, and lens marks must use only active-board touches. Check the narrow agent
182
+ initial's counts/lens/panel interaction separately. Use disposable boards for these checks.
183
+
184
+ ## Failure Handling
185
+
186
+ - Never wave away a failure without checking whether your change caused it
187
+ - If the failure is truly pre-existing, say that explicitly and include the failing command
188
+ - If a command cannot run in the environment, say what blocked it
189
+ - If browser tests fail after a client change, confirm the bundle was rebuilt and the server
190
+ started from the updated code
191
+
192
+ ### Keep first-failure evidence before rerunning
193
+
194
+ Use a separate directory for each attempt, including non-browser probes. Save the exact
195
+ command, target/version, exit status, stdout and stderr; keep credentials out of logs.
196
+ Before rerunning Playwright, copy its failure traces/screenshots and results out of the
197
+ runner's overwritten output directory. Never overwrite an initial failure log with a rerun.
198
+ For a shell gate, capture its status even with `set -e`, for example:
199
+
200
+ ```bash
201
+ attempt_dir=$(mktemp -d /tmp/pmx-check.XXXXXX)
202
+ printf '%s\n' 'bun run test' > "$attempt_dir/command.txt"
203
+ status=0
204
+ bun run test > "$attempt_dir/stdout.log" 2> "$attempt_dir/stderr.log" || status=$?
205
+ printf '%s\n' "$status" > "$attempt_dir/exit-status.txt"
206
+ # Inspect this attempt before rerunning; return the gate's original exit status.
207
+ (exit "$status")
208
+ ```
209
+
210
+ Record what changed between attempts. Distinguish harness corrections, product fixes,
211
+ unchanged retries and host approval. A corrected pass does not make the original attempt
212
+ green. If logs were lost, say so; never reconstruct them or claim first-run success.
213
+
214
+ ## Native-host verification is separate from transport checks
215
+
216
+ Record source, packed-package, registry-package, portal and native-host results separately.
217
+ An SDK subprocess's MCP handshake/catalog is not evidence that Amp discovered tools.
218
+ For Amp setup/trust and the pin → read → addressed steer → edit → visible result → ack
219
+ procedure, follow the bundled [installation reference](../pmx-canvas/references/installing-pmx-canvas.md#amp-connect-the-agent-separately-from-the-portal).
220
+ MCP-only consumers should read `skill://pmx-canvas/references/installing-pmx-canvas.md`
221
+ directly with `resources/read`, not traverse outside the testing skill's resource tree.
222
+ Workspace trust approval belongs to the human; report a blocked native check until approved.
223
+ Include a different-recipient negative control for addressed delivery on a disposable board.
224
+ Verify the rendered edit before acknowledging; detach only test-owned sessions afterward.
225
+ Do not label active-agent polling as idle-thread wake-up, a persistent pump, or automatic
226
+ import-agent launch. Native MCP tools do not prove native Skills-extension discovery.
227
+
228
+ List unexercised surfaces explicitly: native Copilot/WebKit, Windows-native behavior,
229
+ physical mobile, OCR and Office extraction need their own evidence. Source adapter tests
230
+ or a source helper pointed at a published server do not establish installed-adapter execution.
231
+ Sampled resource digests are not a full-catalog audit; eval definitions are not scored model
232
+ results; a skipped mirror check is not validation. Do not change the product merely to
233
+ turn an untested surface into a claimed pass.
234
+
235
+ ## Handoff Standard
236
+
237
+ Before marking work done, report:
238
+
239
+ - Which verification command(s) you ran
240
+ - Whether they passed
241
+ - Any meaningful gaps, skipped checks, or known pre-existing failures
242
+
243
+ For non-trivial changes, the default expectation is `bun run test:all` unless there is a clear
244
+ reason to scope verification more narrowly.
245
+
246
+ ## Presence, sessions, and the redesigned chrome (rail-chrome-v2)
247
+
248
+ - Agent/human presence is in-memory and TTL-swept. An e2e reset must detach any attached
249
+ session (`POST /api/canvas/ax/presence { attached: false }` per attached presence), clear the
250
+ scope fence, and mark its own writes with `x-pmx-workbench: 1` — otherwise the harness reads
251
+ as an external writer and a leftover fence refuses the next test's `clear`. Unattached writers
252
+ from earlier tests can still be live (90 s): assert about YOUR writers, not exact totals.
253
+ - Assert SSE frames as received (`readSseEvent` in `tests/unit/agent-presence-api.test.ts`), not
254
+ the object handed to the emitter — the envelope overwrites `sessionId` and `timestamp`.
255
+ - Two-tab behaviour (human cursors, the edit lock) needs two browser contexts; name them with
256
+ `/workbench?name=…` so assertions can target a cursor by its tag.
257
+ - Do not categorically infer Browser-pane behavior from the host name. Probe the actual surface:
258
+ record `document.visibilityState`, race a `requestAnimationFrame` callback against a short
259
+ timeout, and capture a screenshot of the claimed rendered state. If hidden or rAF times out,
260
+ use the pane only for static checks and run animation/drag/drop/edge-preview assertions in
261
+ Playwright. If the probe succeeds, it is still scheduling evidence rather than paint proof;
262
+ retain screenshot evidence for a visual pass, especially for iframe-backed or native-host
263
+ surfaces.
264
+ - Selection is shift-click on the node BODY (the titlebar drags); groups have no ports and
265
+ their drag handle is the edge row; the selection bar and command bar both float bottom-center
266
+ (the selection bar lifts during a session).