pmx-canvas 0.8.2 → 0.9.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 (335) hide show
  1. package/.github/extensions/pmx-canvas/runtime.json +1 -1
  2. package/.github/extensions/pmx-canvas/tools.json +601 -22
  3. package/CHANGELOG.md +49 -0
  4. package/Readme.md +131 -532
  5. package/dist/canvas/global.css +2724 -476
  6. package/dist/canvas/index.js +168 -107
  7. package/dist/canvas/mcp-app.html +2899 -596
  8. package/dist/json-render/index.js +20 -20
  9. package/dist/types/client/canvas/BarHint.d.ts +12 -2
  10. package/dist/types/client/canvas/BoardLinkDialog.d.ts +3 -1
  11. package/dist/types/client/canvas/BoardPinButton.d.ts +10 -0
  12. package/dist/types/client/canvas/BoardSwitcher.d.ts +1 -1
  13. package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
  14. package/dist/types/client/canvas/CommandBar.d.ts +3 -4
  15. package/dist/types/client/canvas/ConnectionBanner.d.ts +2 -1
  16. package/dist/types/client/canvas/ContextChip.d.ts +3 -0
  17. package/dist/types/client/canvas/CrossBoardReferences.d.ts +5 -0
  18. package/dist/types/client/canvas/EdgeLayer.d.ts +14 -3
  19. package/dist/types/client/canvas/EmptyState.d.ts +4 -4
  20. package/dist/types/client/canvas/HomeGraphView.d.ts +2 -0
  21. package/dist/types/client/canvas/HomeMapView.d.ts +1 -0
  22. package/dist/types/client/canvas/HomeReviewView.d.ts +6 -0
  23. package/dist/types/client/canvas/HomeView.d.ts +9 -7
  24. package/dist/types/client/canvas/KnowledgeDialog.d.ts +4 -0
  25. package/dist/types/client/canvas/LifecycleChrome.d.ts +5 -0
  26. package/dist/types/client/canvas/LifecycleFields.d.ts +7 -0
  27. package/dist/types/client/canvas/LifecyclePanel.d.ts +1 -0
  28. package/dist/types/client/canvas/MemoryInspector.d.ts +7 -0
  29. package/dist/types/client/canvas/NearPinLayer.d.ts +14 -0
  30. package/dist/types/client/canvas/NodeContextMark.d.ts +40 -7
  31. package/dist/types/client/canvas/RelationPresetsDialog.d.ts +4 -0
  32. package/dist/types/client/canvas/RelationsPanel.d.ts +4 -0
  33. package/dist/types/client/canvas/SessionPanel.d.ts +2 -0
  34. package/dist/types/client/canvas/canvas-area.d.ts +1 -1
  35. package/dist/types/client/canvas/graph-geometry.d.ts +27 -0
  36. package/dist/types/client/canvas/graph-model.d.ts +37 -0
  37. package/dist/types/client/canvas/memory-layout.d.ts +23 -0
  38. package/dist/types/client/canvas/use-chrome-height.d.ts +2 -0
  39. package/dist/types/client/canvas/use-focus-trap.d.ts +1 -0
  40. package/dist/types/client/canvas/use-memory-graph.d.ts +8 -0
  41. package/dist/types/client/canvas/use-pan-zoom.d.ts +4 -1
  42. package/dist/types/client/icons.d.ts +0 -10
  43. package/dist/types/client/nodes/AxStepControls.d.ts +1 -1
  44. package/dist/types/client/nodes/InlineMarkdownEditor.d.ts +4 -4
  45. package/dist/types/client/nodes/MarkdownNode.d.ts +5 -1
  46. package/dist/types/client/nodes/McpAppNode.d.ts +4 -4
  47. package/dist/types/client/nodes/viewer-runtime-state.d.ts +1 -1
  48. package/dist/types/client/state/boards-store.d.ts +81 -9
  49. package/dist/types/client/state/canvas-store.d.ts +14 -1
  50. package/dist/types/client/state/context-chip-store.d.ts +22 -0
  51. package/dist/types/client/state/context-status-store.d.ts +35 -0
  52. package/dist/types/client/state/intent-bridge.d.ts +11 -8
  53. package/dist/types/client/state/knowledge-store.d.ts +22 -0
  54. package/dist/types/client/state/near-pin-store.d.ts +44 -1
  55. package/dist/types/client/state/presence-store.d.ts +4 -4
  56. package/dist/types/client/state/presentation.d.ts +28 -0
  57. package/dist/types/client/state/relation-store.d.ts +10 -0
  58. package/dist/types/client/state/session-store.d.ts +41 -2
  59. package/dist/types/client/state/workspace-settings.d.ts +7 -0
  60. package/dist/types/client/types.d.ts +13 -1
  61. package/dist/types/client/utils/keyboard.d.ts +2 -0
  62. package/dist/types/client/utils/time-ago.d.ts +4 -0
  63. package/dist/types/mcp/context-uri-template.d.ts +3 -1
  64. package/dist/types/server/agent-presence.d.ts +10 -3
  65. package/dist/types/server/ax-context.d.ts +1 -1
  66. package/dist/types/server/canvas-db.d.ts +30 -7
  67. package/dist/types/server/canvas-operations.d.ts +24 -2
  68. package/dist/types/server/canvas-provenance.d.ts +22 -2
  69. package/dist/types/server/canvas-serialization.d.ts +2 -0
  70. package/dist/types/server/canvas-state.d.ts +93 -15
  71. package/dist/types/server/canvas-validation.d.ts +1 -1
  72. package/dist/types/server/context-brief.d.ts +94 -6
  73. package/dist/types/server/context-reads.d.ts +33 -7
  74. package/dist/types/server/edit-summary.d.ts +20 -0
  75. package/dist/types/server/index.d.ts +71 -10
  76. package/dist/types/server/knowledge-lifecycle.d.ts +221 -0
  77. package/dist/types/server/lifecycle-status.d.ts +10 -0
  78. package/dist/types/server/memory-graph.d.ts +9 -0
  79. package/dist/types/server/mutation-history.d.ts +2 -0
  80. package/dist/types/server/operations/ops/ax-shared.d.ts +1 -1
  81. package/dist/types/server/operations/ops/boards.d.ts +2 -1
  82. package/dist/types/server/operations/ops/lifecycle.d.ts +2 -0
  83. package/dist/types/server/operations/ops/memory-graph.d.ts +2 -0
  84. package/dist/types/server/operations/ops/nodes.d.ts +5 -0
  85. package/dist/types/server/operations/ops/query.d.ts +23 -0
  86. package/dist/types/server/operations/registry.d.ts +1 -0
  87. package/dist/types/server/placement.d.ts +7 -0
  88. package/dist/types/server/scope-fence.d.ts +2 -1
  89. package/dist/types/server/spatial-analysis.d.ts +6 -3
  90. package/dist/types/server/tour-control.d.ts +32 -0
  91. package/dist/types/server/wiki-links.d.ts +14 -0
  92. package/dist/types/server/workbench-auth.d.ts +2 -0
  93. package/dist/types/shared/agent-context.d.ts +2 -0
  94. package/dist/types/shared/agent-presence.d.ts +15 -12
  95. package/dist/types/shared/auto-arrange.d.ts +1 -0
  96. package/dist/types/shared/boards.d.ts +4 -4
  97. package/dist/types/shared/knowledge-lifecycle.d.ts +41 -0
  98. package/dist/types/shared/knowledge-presets.d.ts +6 -0
  99. package/dist/types/shared/lifecycle-status.d.ts +24 -0
  100. package/dist/types/shared/memory-graph.d.ts +53 -0
  101. package/dist/types/shared/relations.d.ts +68 -0
  102. package/dist/types/shared/semantic-attention.d.ts +2 -0
  103. package/dist/types/shared/tour.d.ts +38 -0
  104. package/dist/types/shared/workspace-settings.d.ts +11 -0
  105. package/docs/RELEASE.md +21 -3
  106. package/docs/adr-001-bun-only-runtime.md +7 -1
  107. package/docs/adr-002-shared-product-separate-runtimes.md +93 -0
  108. package/docs/api-reference.md +109 -0
  109. package/docs/ax-host-adapter-contract.md +1 -1
  110. package/docs/ax-state-contract.md +5 -4
  111. package/docs/cli.md +153 -15
  112. package/docs/demos/pmx-canvas-demo.mp4 +0 -0
  113. package/docs/design/AgentContext.dc.html +3 -3
  114. package/docs/design/BoardPins.dc.html +37 -22
  115. package/docs/design/Categories.dc.html +208 -0
  116. package/docs/design/CategoryEditor.dc.html +33 -0
  117. package/docs/design/Chrome.dc.html +52 -9
  118. package/docs/design/ContextChip.dc.html +224 -0
  119. package/docs/design/ContextChip600.dc.html +136 -0
  120. package/docs/design/EmptyState.dc.html +45 -0
  121. package/docs/design/Flows.dc.html +23 -1
  122. package/docs/design/HeaderMarks.dc.html +183 -0
  123. package/docs/design/Home.dc.html +19 -1
  124. package/docs/design/HomeGraph.dc.html +86 -202
  125. package/docs/design/HomeMap.dc.html +23 -1
  126. package/docs/design/HomeTeam.dc.html +32 -14
  127. package/docs/design/Lifecycle.dc.html +22 -0
  128. package/docs/design/Lifecycle600.dc.html +18 -0
  129. package/docs/design/LifecycleVariants.dc.html +157 -0
  130. package/docs/design/LinkAuthorship.dc.html +139 -0
  131. package/docs/design/LinksChanged.dc.html +203 -0
  132. package/docs/design/LinksOptions.dc.html +137 -0
  133. package/docs/design/LinksOptions600.dc.html +134 -0
  134. package/docs/design/NearPin.dc.html +9 -10
  135. package/docs/design/Pane600.dc.html +4 -3
  136. package/docs/design/Relations.dc.html +3 -2
  137. package/docs/design/Restore.dc.html +152 -0
  138. package/docs/design/SeeChange.dc.html +267 -0
  139. package/docs/design/Uses.dc.html +12 -6
  140. package/docs/design/canvas.json +146 -19
  141. package/docs/design.md +449 -16
  142. package/docs/environment.md +0 -1
  143. package/docs/evals/curation-effect.md +128 -0
  144. package/docs/http-api.md +459 -37
  145. package/docs/mcp.md +146 -18
  146. package/docs/node-types.md +58 -3
  147. package/docs/plans/design-gaps-2026-10-08.md +53 -0
  148. package/docs/plans/plan-009-tech-debt-backlog.md +379 -0
  149. package/docs/plans/plan-016-context-made-visible-wave-1.md +150 -5
  150. package/docs/plans/plan-017-knowledge-categories-and-lifecycle.md +175 -0
  151. package/docs/plans/plan-018-connected-memory-wave-2.md +594 -0
  152. package/docs/plans/plan-019-post-0.9-roadmap.md +198 -0
  153. package/docs/product-context-vision-2026-09.md +17 -1
  154. package/docs/product-vision-2026-09.md +1082 -43
  155. package/docs/product-vision-review-2026-09.md +13 -1
  156. package/docs/screenshots/workbench-live-dark.png +0 -0
  157. package/docs/screenshots/workbench-live-light.png +0 -0
  158. package/docs/sdk.md +62 -2
  159. package/package.json +1 -1
  160. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +1 -1
  161. package/plugins/pmx-canvas/plugin.json +1 -1
  162. package/plugins/pmx-canvas/runtime.json +1 -1
  163. package/plugins/pmx-canvas/tools.json +601 -22
  164. package/skills/pmx-canvas/SKILL.md +216 -42
  165. package/skills/pmx-canvas/references/full-reference.md +120 -21
  166. package/skills/pmx-canvas/references/github-copilot-app-adapter.md +2 -2
  167. package/skills/pmx-canvas/references/importing-context.md +132 -0
  168. package/skills/pmx-canvas/references/installing-pmx-canvas.md +6 -6
  169. package/skills/pmx-canvas/references/tours-and-recording.md +16 -1
  170. package/skills/pmx-canvas-testing/SKILL.md +20 -0
  171. package/src/cli/agent.ts +2 -0
  172. package/src/cli/commands/ax.ts +12 -0
  173. package/src/cli/commands/boards.ts +87 -11
  174. package/src/cli/commands/edges.ts +28 -0
  175. package/src/cli/commands/groups.ts +7 -0
  176. package/src/cli/commands/nodes.ts +1 -0
  177. package/src/cli/commands/query.ts +34 -2
  178. package/src/cli/commands/record.ts +199 -48
  179. package/src/cli/index.ts +6 -1
  180. package/src/client/App.tsx +177 -70
  181. package/src/client/canvas/AttentionHistory.tsx +0 -2
  182. package/src/client/canvas/BarHint.tsx +40 -2
  183. package/src/client/canvas/BoardCopyDialog.tsx +1 -1
  184. package/src/client/canvas/BoardFolderDialog.tsx +7 -7
  185. package/src/client/canvas/BoardLinkDialog.tsx +138 -33
  186. package/src/client/canvas/BoardPinButton.tsx +33 -0
  187. package/src/client/canvas/BoardSwitcher.tsx +26 -40
  188. package/src/client/canvas/CanvasNode.tsx +360 -237
  189. package/src/client/canvas/CanvasViewport.tsx +45 -7
  190. package/src/client/canvas/CommandBar.tsx +29 -23
  191. package/src/client/canvas/CommandPalette.tsx +5 -12
  192. package/src/client/canvas/ConnectionBanner.tsx +3 -3
  193. package/src/client/canvas/ContextChip.tsx +296 -0
  194. package/src/client/canvas/ContextMenu.tsx +63 -5
  195. package/src/client/canvas/CrossBoardReferences.tsx +60 -0
  196. package/src/client/canvas/EdgeLayer.tsx +339 -76
  197. package/src/client/canvas/EmptyState.tsx +33 -18
  198. package/src/client/canvas/ExpandedNodeOverlay.tsx +72 -40
  199. package/src/client/canvas/ExternalWriters.tsx +57 -42
  200. package/src/client/canvas/HomeGraphView.tsx +942 -0
  201. package/src/client/canvas/HomeMapView.tsx +641 -0
  202. package/src/client/canvas/HomeReviewView.tsx +167 -0
  203. package/src/client/canvas/HomeView.tsx +687 -160
  204. package/src/client/canvas/IntentLayer.tsx +19 -12
  205. package/src/client/canvas/KnowledgeDialog.tsx +488 -0
  206. package/src/client/canvas/LifecycleChrome.tsx +133 -0
  207. package/src/client/canvas/LifecycleFields.tsx +91 -0
  208. package/src/client/canvas/LifecyclePanel.tsx +533 -0
  209. package/src/client/canvas/MemoryInspector.tsx +104 -0
  210. package/src/client/canvas/Minimap.tsx +3 -3
  211. package/src/client/canvas/NearPinLayer.tsx +187 -0
  212. package/src/client/canvas/NodeContextMark.tsx +175 -97
  213. package/src/client/canvas/Presentation.tsx +23 -57
  214. package/src/client/canvas/RelationPresetsDialog.tsx +413 -0
  215. package/src/client/canvas/RelationsPanel.tsx +82 -0
  216. package/src/client/canvas/SelectionBar.tsx +3 -6
  217. package/src/client/canvas/SessionPanel.tsx +90 -50
  218. package/src/client/canvas/SessionReceipt.tsx +311 -39
  219. package/src/client/canvas/ShortcutOverlay.tsx +1 -1
  220. package/src/client/canvas/SnapshotPanel.tsx +27 -36
  221. package/src/client/canvas/ToolRail.tsx +367 -192
  222. package/src/client/canvas/TopBar.tsx +354 -124
  223. package/src/client/canvas/canvas-area.ts +10 -3
  224. package/src/client/canvas/graph-geometry.ts +195 -0
  225. package/src/client/canvas/graph-model.ts +254 -0
  226. package/src/client/canvas/memory-layout.ts +106 -0
  227. package/src/client/canvas/use-chrome-height.ts +20 -0
  228. package/src/client/canvas/use-focus-trap.ts +31 -5
  229. package/src/client/canvas/use-memory-graph.ts +58 -0
  230. package/src/client/canvas/use-node-drag.ts +2 -1
  231. package/src/client/canvas/use-pan-zoom.ts +64 -7
  232. package/src/client/icons.tsx +0 -63
  233. package/src/client/mcp-app/style.css +0 -6
  234. package/src/client/nodes/AxStepControls.tsx +74 -50
  235. package/src/client/nodes/BoardNode.tsx +5 -1
  236. package/src/client/nodes/ContextNode.tsx +18 -11
  237. package/src/client/nodes/ExtAppFrame.tsx +0 -1
  238. package/src/client/nodes/FileNode.tsx +46 -42
  239. package/src/client/nodes/HtmlNode.tsx +32 -0
  240. package/src/client/nodes/ImageNode.tsx +1 -1
  241. package/src/client/nodes/InlineFormatBar.tsx +6 -9
  242. package/src/client/nodes/InlineMarkdownEditor.tsx +56 -17
  243. package/src/client/nodes/MarkdownNode.tsx +377 -109
  244. package/src/client/nodes/McpAppNode.tsx +50 -20
  245. package/src/client/nodes/MdFormatBar.tsx +21 -18
  246. package/src/client/nodes/PromptNode.tsx +1 -1
  247. package/src/client/nodes/ResponseNode.tsx +1 -1
  248. package/src/client/nodes/viewer-runtime-state.ts +54 -22
  249. package/src/client/state/attention-bridge.ts +64 -15
  250. package/src/client/state/boards-store.ts +193 -39
  251. package/src/client/state/canvas-store.ts +99 -12
  252. package/src/client/state/context-chip-store.ts +70 -0
  253. package/src/client/state/context-status-store.ts +53 -0
  254. package/src/client/state/intent-bridge.ts +51 -30
  255. package/src/client/state/knowledge-store.ts +43 -0
  256. package/src/client/state/near-pin-store.ts +115 -6
  257. package/src/client/state/presence-store.ts +7 -10
  258. package/src/client/state/presentation.ts +91 -0
  259. package/src/client/state/relation-store.ts +81 -0
  260. package/src/client/state/session-store.ts +144 -18
  261. package/src/client/state/sse-bridge.ts +206 -29
  262. package/src/client/state/workspace-settings.ts +11 -0
  263. package/src/client/theme/global.css +2724 -476
  264. package/src/client/types.ts +12 -0
  265. package/src/client/utils/keyboard.ts +10 -0
  266. package/src/client/utils/time-ago.ts +14 -0
  267. package/src/json-render/renderer/index.tsx +31 -0
  268. package/src/mcp/canvas-app.ts +12 -2
  269. package/src/mcp/context-uri-template.ts +7 -4
  270. package/src/mcp/server.ts +63 -41
  271. package/src/mcp/workbench-app.ts +39 -6
  272. package/src/server/agent-presence.ts +128 -28
  273. package/src/server/ax-context.ts +27 -13
  274. package/src/server/board-export.ts +12 -1
  275. package/src/server/canvas-db.ts +331 -42
  276. package/src/server/canvas-operations.ts +195 -83
  277. package/src/server/canvas-provenance.ts +53 -22
  278. package/src/server/canvas-serialization.ts +2 -0
  279. package/src/server/canvas-state.ts +950 -122
  280. package/src/server/canvas-validation.ts +9 -2
  281. package/src/server/context-brief.ts +345 -38
  282. package/src/server/context-reads.ts +178 -30
  283. package/src/server/demo-state.json +355 -24
  284. package/src/server/edit-summary.ts +74 -0
  285. package/src/server/html-surface.ts +8 -1
  286. package/src/server/index.ts +181 -11
  287. package/src/server/knowledge-lifecycle.ts +304 -0
  288. package/src/server/lifecycle-status.ts +232 -0
  289. package/src/server/memory-graph.ts +166 -0
  290. package/src/server/mutation-history.ts +18 -6
  291. package/src/server/operations/composites.ts +32 -11
  292. package/src/server/operations/http.ts +7 -2
  293. package/src/server/operations/index.ts +4 -0
  294. package/src/server/operations/mcp.ts +26 -1
  295. package/src/server/operations/ops/ax-presence.ts +1 -1
  296. package/src/server/operations/ops/ax-read.ts +57 -6
  297. package/src/server/operations/ops/ax-timeline.ts +28 -2
  298. package/src/server/operations/ops/backup.ts +5 -3
  299. package/src/server/operations/ops/batch.ts +35 -4
  300. package/src/server/operations/ops/boards.ts +188 -47
  301. package/src/server/operations/ops/canvas-wire.ts +31 -1
  302. package/src/server/operations/ops/edges.ts +36 -2
  303. package/src/server/operations/ops/groups.ts +6 -1
  304. package/src/server/operations/ops/lifecycle.ts +262 -0
  305. package/src/server/operations/ops/memory-graph.ts +45 -0
  306. package/src/server/operations/ops/nodes.ts +107 -24
  307. package/src/server/operations/ops/query.ts +281 -68
  308. package/src/server/operations/ops/snapshots.ts +73 -1
  309. package/src/server/operations/ops/validate.ts +5 -1
  310. package/src/server/operations/ops/viewport.ts +97 -3
  311. package/src/server/operations/registry.ts +74 -25
  312. package/src/server/placement.ts +29 -0
  313. package/src/server/scope-fence.ts +78 -6
  314. package/src/server/server.ts +115 -16
  315. package/src/server/spatial-analysis.ts +48 -23
  316. package/src/server/tour-control.ts +82 -0
  317. package/src/server/wiki-links.ts +137 -0
  318. package/src/server/workbench-auth.ts +11 -0
  319. package/src/shared/agent-context.ts +3 -0
  320. package/src/shared/agent-presence.ts +15 -15
  321. package/src/shared/auto-arrange.ts +2 -0
  322. package/src/shared/boards.ts +4 -4
  323. package/src/shared/knowledge-lifecycle.ts +22 -0
  324. package/src/shared/knowledge-presets.ts +80 -0
  325. package/src/shared/lifecycle-status.ts +26 -0
  326. package/src/shared/memory-graph.ts +74 -0
  327. package/src/shared/relations.ts +98 -0
  328. package/src/shared/semantic-attention.ts +15 -1
  329. package/src/shared/tour.ts +23 -5
  330. package/src/shared/workspace-settings.ts +13 -0
  331. package/dist/types/client/canvas/ContextPinBar.d.ts +0 -1
  332. package/dist/types/client/canvas/FocusFieldLayer.d.ts +0 -1
  333. package/dist/types/client/canvas/kind-colors.d.ts +0 -3
  334. package/dist/types/server/agent-context.d.ts +0 -22
  335. package/src/client/canvas/ContextPinBar.tsx +0 -25
@@ -8,6 +8,12 @@ Each item is tagged by shape: **project** (multi-day, own plan/PR), **decision**
8
8
 
9
9
  ## Decision analysis (2026-07-08, maintainer-approved)
10
10
 
11
+ **SDK clarification, 2026-10-15:** the historical "no further collapse" conclusion below is
12
+ superseded by [vision move 6b](../product-vision-2026-09.md#6b-generate-every-surface-from-the-registry-l-two-releases--pending-the-maintainers-decision).
13
+ The local SDK may remain synchronous while sharing mutation-policy checks. All supported
14
+ writers must converge on the relevant policy and commit guarantees; asynchronous durable
15
+ completion is a separate contract decision, not a prerequisite for fixing lock parity.
16
+
11
17
  The remaining items were re-analyzed with pros/cons and tiered; the maintainer approved this ordering:
12
18
 
13
19
  - **Tier 1 (do):** CLI raw fetches → operation invoker **together with** the H3 parser/module split (same file, one project); H7 test coverage **as a prerequisite** for any client refactor; M2 AX-bridge dedup (first client task after H7); the M8 flake subset (mock the Excalidraw network tests, share `getAvailablePort`, Playwright `retries`/`forbidOnly`, `e2e-cli` into CI). *C1b done (2026-07-08):* all 60 raw `api()` calls migrated onto the invoker (9-agent verified mapping; `webartifact.build` gained `errorBodyAsResult`; batch failure prints the envelope + exits 1; the `api()` helper is deleted; two deliberate raw `fetch` sites remain — binary screenshot, SSE watch). *H3 module split done (2026-07-09):* `agent.ts` is a 227-line entry over `src/cli/shared.ts` (cycle-free core: registry, parser, transport) + 11 `src/cli/commands/*` domain modules, moved byte-identically; ax-parity reads the whole cli tree. **Parser sub-item reshaped:** `parseFlags`/`BOOL_FLAGS` is now single-sited in shared.ts; `index.ts` keeps its intentionally tiny fixed-flag launcher reader (different domain — server launch, not agent commands). The spec-driven per-command flag parser (`defineCommand`) remains the ideal but is a redesign of all 83 command surfaces — deferred to a future CLI UX change, not worth manufactured churn now.
@@ -92,3 +98,376 @@ Recorded while the redesign's phases land so nothing rides in silently. The rede
92
98
  | Agents can resolve their own gates | Pre-existing design question surfaced by the session panel: `ax.approval.resolve` accepts any caller, so an agent could approve its own gate over HTTP/MCP. The panel and the `held` TTL path assume the human answers. Either gate `resolve` on the workbench marker (like the scope fence) or document it as a cooperating-agent contract; decide before the next adapter ships. |
93
99
  | Batch never carries `fromWorkbench` | `canvas.batch` inner dispatches are always agent writes (the browser never uses batch), so the scope fence and presence treat them as such. Holds by construction today; if the client ever adopts batch, the marker must thread through `ops/batch.ts`. Comment at the dispatch site. |
94
100
  | Presence registry is a second single-slot listener family | `setSessionStartListener` / `setSessionEndListener` / `setEmitter` on `agentPresence` follow architecture rule 8 (owned by `server.ts`). If a third consumer ever needs session lifecycle (e.g. an audit log), fan out inside the existing registration — do not add a competing one. |
101
+
102
+ ## Wave 3 maintainability review (2026-10-11)
103
+
104
+ Scope: remaining Wave 3 changes against the published foundation, the preceding
105
+ `Sweep tech debt before 0.9.0` commit, and the next stages in `docs/design.md` and
106
+ `docs/product-vision-2026-09.md`. This is a source/data-flow review with disposable
107
+ scale measurements, not an exhaustive re-audit of every historical row above.
108
+ The owner requested self-review, not Oracle. Stabilization evidence is in plan 018.
109
+
110
+ **Fixed in this batch:** AX context computed the same library qualification three times
111
+ for pins and focus. It now shares one request-local result. Fit also reuses its captured
112
+ layout rather than loading the whole layout again just to inspect edges. The initial
113
+ resetting preset menu and its orphaned highlight-menu state are gone. The vision's
114
+ “planned, not implemented” lifecycle status is corrected. No dependency or cache was added.
115
+
116
+ Measurement: Bun 1.4.2 in the Linux orb, nine warm samples per case, short Markdown cards,
117
+ no review history or dependencies. At 30 boards × 150 cards, AX context median falls from
118
+ 138.6 to 48.3 ms; at 10 × 150, from 44.0 to 13.6 ms. Single-card reads remain approximately
119
+ 46 ms at 4,500 cards. The qualification object is 1,302,961 JSON characters. These are
120
+ lower-bound server measurements, not browser latency or a supported capacity guarantee.
121
+ Logs: `/tmp/pmx-w3-debt-baseline.zPoaEM/log` and `/tmp/pmx-w3-debt-after.iXN2fq/log`.
122
+
123
+ | Priority / boundary | Evidence and disposition |
124
+ |---|---|
125
+ | Before larger-library scaling | `lifecycle-status.ts` reads every board and each card's full review history even for one-card requests. `KnowledgeSync` reloads workspace qualifications after board changes. Bound narrow reads to the dependency closure, batch/index review summaries, and separate folder aggregates from card detail when scaling this path. Measure populated review histories and long dependency chains as well as empty history. Avoid a TTL cache: cadence, sessions, retirement and source changes have different invalidation clocks. |
126
+ | Wave 4, frame host | `ExtAppFrame.tsx` still owns 1,597 lines of bridge/recovery behavior. Consolidate mount budget, theme delivery and visible fallback with the planned frame host, preserving working draft/refresh behavior. Do not start another recovery ladder or infer native WebKit paint from Chromium tests. |
127
+ | Wave 5, groups and agent output | Keep board-qualified relation/provenance identities when moving cards into or out of a board. Review records currently outlive snapshots and are keyed by board + card; define their move semantics before adding make-board/inline-board. Do not clone validation as if a new claim had been checked. |
128
+ | Journal and shared/hosted stages | The due evaluator still reads the local `canvasState` singleton. Separate runtime acquisition from qualification when a second runtime needs it, not by speculative package splitting now. Filter authorized sources before summaries, titles and lifecycle reasons are computed. Categories are not permissions. Keep validation audit distinct from an undoable content journal and finish the authoritative mutation-path decision before event sourcing. |
129
+ | Test maintenance | Large integration files remain (`server-api.test.ts`, `canvas.pw.ts`). Split by owning domain when those domains next change, preserving isolation and race cases. Do not replace human browser or real transport checks with source-string assertions to make the suite cheaper. |
130
+
131
+ The earlier gate-resolution question is superseded by vision move 7 and plan 010:
132
+ approvals are attributed coordination, not a human-only security boundary. Tour cleanup
133
+ remains explicitly deferred in vision move 12. Neither is reopened in this batch.
134
+ The codebase supports continued staged vision work; this review is not release approval.
135
+
136
+ ### Home acceptance integration review (2026-10-12)
137
+
138
+ The combined Home and acceptance review keeps one server graph projection and one set of
139
+ board-qualified writes. `memory-layout.ts` owns Map geometry and D3 view particles; the
140
+ simulation never changes saved board coordinates, content or validation. D3 is now a direct
141
+ dependency rather than an accidental transitive one. Live reads coalesce while a request is
142
+ running, discard responses from superseded views and preserve camera/selection. Library
143
+ browsing unmounts the canvas and gates board controls so a paste or shortcut cannot mutate
144
+ the agent's hidden active board.
145
+
146
+ Real transport review found the MCP node-type enum duplicated the canonical list and omitted
147
+ board portals. Both now use `NODE_TYPES`, with a discriminating MCP regression. Live visual
148
+ review also caught the library context chip omitting a pinned active board; it now lists all
149
+ board pins without exposing hidden-board card controls. Neither finding justifies another
150
+ adapter or graph store. Category deletion refuses explicit assignments even to empty folders;
151
+ the simplified review form retains captured content/source revision guards.
152
+
153
+ The live-library checkpoint in the vision records the next boundaries: explicit per-tab
154
+ editor ownership before concurrent board editing, and measured fetch/force/paint costs before
155
+ workers or culling. The 13-board/101-card browser fixture is acceptance evidence, not a large
156
+ library capacity claim. Map and Graph now have separate view owners, sharing discovery loading
157
+ and inspector docking only; the superseded combined view and Graph layouts are removed. The codebase is
158
+ healthy enough for staged vision work with these constraints, not debt-free or fully validated
159
+ in native hosts. The reported Amp embedded-portal context-pill opening failure is still
160
+ unverified and distinct from the fixed pin count.
161
+
162
+ ## Private wiki-import findings (2026-10-18, locally fixed and retested)
163
+
164
+ Source: [private import-test handoff](https://ampcode.com/threads/T-01a14f43-f513-7397-8ec4-f6a85551dff0).
165
+ Reported environment: PMX Canvas 0.8.2 at
166
+ [`92c2930`](https://github.com/pskoett/pmx-canvas/commit/92c293029e98a5fc1c04f43821470eb35fe500c6),
167
+ Bun 1.4.2, headed Chromium in a Linux orb. Synthetic MCP reproductions subsequently
168
+ confirmed the findings. Local fixes build on the pushed Graph candidate
169
+ [`150aeba`](https://github.com/pskoett/pmx-canvas/commit/150aebad08c03909a0170660d12bd33f558735a9).
170
+ After-fix checks use the official SDK Client and StdioClientTransport attached to a
171
+ disposable source daemon, plus headed Chromium for rendered effects. This is not a
172
+ native-host or published-package claim. The source database and private documents
173
+ were not imported; the owner's running workbench was not changed.
174
+
175
+ Private evidence remains in the source thread's workspace: `wiki-load-before.json`,
176
+ `wiki-load-after.json`, `wiki-backlog-cards.png` and `wiki-linkedin-cards.png` under
177
+ `.amp/in/artifacts/`, plus `.learnings/wiki-load-probe.js` and `.learnings/ERRORS.md`.
178
+ Screenshots and full notes contain private wiki content. Keep them within authorized private
179
+ work; use synthetic fixtures or redaction for any public reproduction or report.
180
+
181
+ ### WI-01, high: embedded base64 Markdown images make parsing and board loading slow
182
+
183
+ **Status:** locally fixed and retested with identical inline image content, not a data conversion.
184
+ Marked's long destination and unmatched setext scans caused the reproduced parser cost.
185
+ The wiki parser now avoids those scans while preserving reference and rendered-image output.
186
+ Controlled 1,106,157-character parser runs changed from 1245–1503 ms to 17–31 ms;
187
+ the short-reference control changed from 7–10 ms to 3–4 ms. These synthetic parser
188
+ measurements are not end-to-end load or universal speedup claims. MCP-created inline
189
+ and file-reference boards both render and decode the same SHA-256-checked 800×600 image.
190
+ Payload duplication, offscreen render requests and full-layout SSE remain possible
191
+ amplifiers, not solved or independently established causes of all loading outliers.
192
+
193
+ The source test measured board-open request through ready card bodies and loaded pictures
194
+ (including natural image dimensions), not just HTTP response time. Each cell lists three
195
+ runs in milliseconds. The workaround changed import data, not product code: seven embedded
196
+ images became file-backed image nodes on their owning boards, referenced through
197
+ `/api/canvas/image/<id>`. Served bytes matched the originals by SHA-256. The documents and
198
+ pictures were retained, with extra figure cards; this is not an identical-card-count comparison.
199
+
200
+ | Workload | Before workaround | After data-only workaround | State payload, before → after |
201
+ |---|---|---|---|
202
+ | 9 Markdown cards, 5 pictures originally | 5329 / 5609 / 5714 | 782 / 879 / 817 | 3,195,186 → 649,194 bytes |
203
+ | 12 cards, 2 pictures originally | 9364 / 4011 / 7403 | 710 / 904 / 759 | Not reported → 211,414 bytes |
204
+ | 29-card text-only control | 1566 / 1419 / 1643 | 1372 / 1021 / 1275 | Not reported |
205
+
206
+ Direct isolation on one 924,640-character card measured `wikiReferences` at
207
+ 1422 / 1194 / 1170 ms and `renderWikiMarkdown` at 1183 / 1187 / 1189 ms. Replacing only base64
208
+ URLs with short URLs reduced the source to 11,728 characters and parsing to 2–11 ms, retaining
209
+ 11 wiki references and four image tags. This isolates parsing cost, not image downloading.
210
+ The server was already running, caches were not cleared, and transport was local to the orb.
211
+ Small-board transitions also occasionally took about three seconds. No universal speedup or
212
+ single cause for every outlier is established. File-backed assets must accompany the database.
213
+
214
+ Reported amplifiers to inspect at reproduction: `src/server/wiki-links.ts`;
215
+ `handleRender` in `src/server/server.ts` lexing persisted Markdown twice and rendering again;
216
+ `src/server/canvas-serialization.ts` duplicating source at top level and `data.content`;
217
+ `MarkdownNode.tsx` posting each mounted card's entire source to `/api/render`, including
218
+ offscreen cards; and full-layout SSE payloads. These are investigation leads from the tested
219
+ revision, not independently verified causes on the candidate.
220
+
221
+ **Next:** measure remaining payload/paint costs separately if large real boards still stall.
222
+ Retain reference/image-preservation checks before changing parser or transport behavior again.
223
+
224
+ ### WI-02, medium: relative image creation ignores the configured workspace root
225
+
226
+ **Status:** locally fixed and retested through MCP. Relative paths now resolve against
227
+ the configured workspace root. A daemon launched outside that root creates the synthetic
228
+ relative-path image successfully, and served bytes match the original hash. The serving
229
+ route's realpath confinement is unchanged.
230
+
231
+ Launch from directory A with `PMX_CANVAS_WORKSPACE_ROOT=B`, with a valid picture at
232
+ `B/wiki/assets/diagram.png`. `POST /api/canvas/node` with
233
+ `{type:"image",content:"wiki/assets/diagram.png"}` returned 400,
234
+ `Invalid image node: diagram.png does not exist`. The absolute path succeeded, as did all
235
+ seven image imports using that workaround.
236
+
237
+ The source investigation identified `buildImageNodeData` in
238
+ `src/server/canvas-operations.ts` using `resolve(src)`, unlike file-node creation's
239
+ `resolve(canvasState.getWorkspaceRoot(), rawPath)`.
240
+
241
+ **Guardrail:** keep separate launch/workspace coverage and realpath confinement; relative
242
+ creation must not weaken the file-serving boundary.
243
+
244
+ ### WI-03, low: review/lifecycle badge protrudes beside grouped cards
245
+
246
+ **Status:** locally fixed and visually retested independently of freshness noise removal.
247
+ The group's sole body child was stretched by the content flex rule. Its footer now lives
248
+ in the bottom frame chrome. A deliberately due, zero-review group has a 22.44 CSS px footer
249
+ at 68% zoom, versus 259.76 px in the source reproduction. All 36 width/theme cases hit-test
250
+ the footer, and a real pointer click opens that group's Review drawer. Fresh children stay
251
+ unmarked. This does not resolve or identify the separately reported Updates badge.
252
+
253
+ With Knowledge lifecycle enabled, a dense group at 68% zoom showed a partly obscured amber
254
+ review badge beside a middle-left card; a similar artifact appeared on another board.
255
+ Capture conditions were 1600 × 1100 CSS pixels, DPR 2. All nine cards in the dense group fit
256
+ and rendered. This is not established as the separately reported floating Updates badge.
257
+
258
+ **Guardrail:** test explicit group due/source warnings as well as fresh content, so removing
259
+ inherited policy noise cannot conceal a broken badge layout.
260
+
261
+ **Not counted as product bugs:** source-draft chronology, poor initial import board
262
+ granularity, and unescaped wiki-alias pipes in Markdown tables. An unescaped table alias can
263
+ produce zero parsed references, so zero unresolved links alone is not a preservation check.
264
+ The initial handoff's wiki-import guidance was local-only. A later handoff reports it pushed
265
+ to `origin/main` in
266
+ [`48013e1`](https://github.com/pskoett/pmx-canvas/commit/48013e1346ea34f107c11f93dca3f4cace1f7a23).
267
+ It has not been integrated into this checkout.
268
+
269
+ ### WI-04, priority pending: incomplete provenance is silently discarded on node creation
270
+
271
+ **Status:** locally fixed and retested through MCP. Explicit incomplete/invalid provenance
272
+ is rejected with field-specific errors; valid source dependencies survive readback. Omitted
273
+ provenance still uses normal inference for sourced node types.
274
+
275
+ The source test submitted `data.provenance` with `sourceKind:'agent'`,
276
+ `snapshotContent:true`, `sources:[{boardId,cardId,contentRevision,availability:'cached'}]`
277
+ and `recipe:{tool,prompt}`, omitting `sourceUri` and `refreshStrategy`. Creation succeeded,
278
+ but a subsequent GET returned `provenance:null`, losing the submitted source dependencies.
279
+ The payload was incomplete and `agent` is not an advertised source kind. This does not claim
280
+ that valid provenance was rejected or lost.
281
+
282
+ The source investigation points to `normalizeExistingProvenance` in
283
+ `src/server/canvas-provenance.ts` returning null for missing required fields, after which
284
+ the ensure path deletes provenance. The data-only repair supplied `sourceKind:'recipe'`,
285
+ `sourceUri` and `refreshStrategy:'agent-request'`; the source thread verified all 20 repaired
286
+ cards, 54 source references/revisions and persistence after restart. That repair was data-only.
287
+
288
+ **Guardrail:** keep the rejected incomplete payload and valid source-preservation control.
289
+
290
+ ### WI-05, usability: short library queries rank picture filenames above content
291
+
292
+ **Status:** locally improved and retested through MCP. Exact and whole-term match tiers
293
+ precede embedded substrings; field weights only break ties within a tier. `V2 platform`
294
+ ranks above `TV2 pictures` for `V2`, while the latter remains discoverable. Search scope,
295
+ filters and stable tie ordering are covered by regression tests.
296
+
297
+ A short query ranked picture filenames containing the token ahead of the intended platform
298
+ content. No private content is needed to investigate this. Use synthetic titles, body content
299
+ and overlapping filename tokens to assess relevance; establish the intended ranking before
300
+ calling matching results incorrect.
301
+
302
+ ### WI-06, product requirement: schedule new content's first review by type and decay
303
+
304
+ **Status:** locally implemented and retested through MCP and browser. New authored content
305
+ starts fresh without a review record. Medium first expires at creation plus cadence;
306
+ Fast/Slow at a later use/resumed session. Imports and existing undated content gain no
307
+ synthetic freshness. Edits preserve the baseline. Group/portal nodes skip inherited factual
308
+ decay unless explicitly assigned a card override; source/dependency warnings still apply.
309
+
310
+ The source inspection used local and remote `main` at
311
+ [`676fd1d`](https://github.com/pskoett/pmx-canvas/commit/676fd1d37727e0e4cc8d393b450500ef658ac052).
312
+ A new work overview inherited a fast category policy and returned `records:[]`,
313
+ `lastValidation:null`, `unknown:false`, `due:true`, with reason "Fast: check at use."
314
+ A new planning overview inherited medium/90 days and reported
315
+ "Review every 90 days; never validated." The snapshot contained 258 review-queue items,
316
+ including group frames. The importing agent assigned the broad policy, amplifying the noise;
317
+ this is not a measurement of the current candidate's queue.
318
+
319
+ The source investigation reports that `src/server/lifecycle-status.ts` evaluates all node
320
+ types: medium cadence treats `checked === null` as immediately due, while fast cadence
321
+ requires current-session validation on the active board. `LifecycleChrome.tsx` presents both
322
+ as the same amber review-due badge. Null per-card lifecycle inherits policy, rather than
323
+ opting out. Source log: `ERR-20261018-005`, pattern `canvas.review_policy_import_noise`.
324
+
325
+ **Required behavior, superseding the earlier emphasis on badge distinctions:** newly authored
326
+ content must not enter the review queue solely because it has no validation record. Schedule
327
+ its first review later according to its effective content type/decay policy, including the
328
+ new work overview. Relabeling an immediate warning alone does not satisfy this requirement.
329
+ Freshness and evidence validation remain distinct; creation does not establish validation.
330
+ Imported historical content and edit-reset semantics need separate treatment, not a blanket
331
+ reset that treats every import or edit as freshly established evidence.
332
+
333
+ **Guardrail:** server-owned initial freshness is persisted independently of validation.
334
+ Tests cover cadence boundaries, inherited policies, later sessions, imports, edits,
335
+ undo/redo and snapshot restore. Historical text creation must declare
336
+ `data.contentOrigin: "imported"`; origin is immutable. Do not fabricate review records or
337
+ blanket-reclassify facts as durable. This remains separate from WI-03's layout fix.
338
+
339
+ ### WI-07, capability: create on an inactive board without switching the human's board
340
+
341
+ **Status:** static node creation is delivered; the follow-up extends destination creation to
342
+ groups and edges, completing the multi-card + frame + relations import workflow. Explicit
343
+ board/folder search filters now intersect before ranking/limits. `destinationBoardId` selects
344
+ the stored owner; `expectedBoardId` remains an active-board guard and `toBoardId` is an
345
+ independent foreign endpoint. The singleton commits without temporarily opening the
346
+ destination, altering active undo or creating ghosts. Scope fences and human edit locks
347
+ remain enforced. Runtime-backed node creation, generated primitives, intents and inactive
348
+ update/remove operations remain unsupported, not silently redirected. The two new
349
+ capabilities require independent validation of this follow-up candidate.
350
+
351
+ ### WI-08, retry safety: distinguish retries from intentional identical creations
352
+
353
+ **Status:** locally implemented and MCP-retested. Optional `requestId` persists an atomic
354
+ creation receipt with the node, group or edge. Same input/destination replays the original receipt; mismatched
355
+ reuse conflicts. New ids preserve intentional identical creations. Regression tests exercise
356
+ restart, removal, rollback at receipt failure, endpoint clocks and named batch references.
357
+ Receipts survive individual node deletion but are deleted with the owning board. Existing
358
+ named batch edge/group references already worked and remain a passing control.
359
+
360
+ ### WI-09, high: many cross-board reference footers obstruct Markdown body links
361
+
362
+ **Status:** reproduced with disposable synthetic cards and fixed after the
363
+ completed review of pushed
364
+ [`706f989b`](https://github.com/pskoett/pmx-canvas/commit/706f989befcc2277bfbf607598040c59cb5a80c7).
365
+ The unchanged implementation failed the body-link hit test. One bounded, focusable
366
+ scroll region now retains all reference rows without covering the document or actions.
367
+ This is separate from WI-03's fixed group lifecycle footer.
368
+
369
+ A strict-size 640 × 480 Markdown index card with 103 outgoing cross-board references
370
+ rendered reference rows over its body. A real pointer click on a rendered Markdown link
371
+ was intercepted by `div.node-memory-link`. The source thread inspected its screenshot at
372
+ `.amp/in/artifacts/knowledge-rerun/reference-footer-overflow.png`. That evidence remains in
373
+ the [source thread's workspace](https://ampcode.com/threads/T-01a14f43-f513-7397-8ec4-f6a85551dff0),
374
+ not this checkout; do not publish private import content.
375
+
376
+ The synthetic reproduction confirmed that every outgoing remote edge became a
377
+ nonshrinking `.node-memory-link` row inside `.node-body`. The wrapper now caps the
378
+ list at 40% of the body and 132 world pixels. Wheel and navigation keys scroll that
379
+ region rather than the canvas. The design source and contract are updated together.
380
+ Browser checks cover body-link hit testing, actions, all 103 references and navigation;
381
+ the nine-theme, 600/1024/1920 px matrix also passes. WI-11 separately fixes untouched
382
+ expanded Markdown source preservation rather than treating focus mode as a workaround.
383
+
384
+ Independent acceptance on the frozen 13-file candidate also passes actual source stdio
385
+ MCP, headed browser and restart checks. All 103 rows remain reachable in the 132 px
386
+ scroll region. The full local browser run remains 312/313; the unchanged failing
387
+ external-steering case and three affected/control cases pass in isolation. This split
388
+ evidence is not an entirely green full-suite run.
389
+
390
+ After integrating the right-click/pan change and updated import skills, the combined
391
+ build, typecheck, 1,484 unit tests, 318 client tests and 20 targeted headed checks pass.
392
+ The browser run repeats ten affected/control scenarios twice, not the full suite.
393
+ A fresh source stdio MCP/browser fixture retains all 103 references in a 132 px region
394
+ with hit-testable body links at desktop and 600 px. Exact Markdown and revision 1 survive
395
+ read-only expanded navigation and an actual disposable-daemon restart. The served bundle
396
+ matches the rebuilt distribution; screenshots and a pointer recording were inspected.
397
+
398
+ **Acceptance:** create a fictional 640 × 480 Markdown card with roughly 100 remote
399
+ references, including a body link. Assert that the body link remains hit-testable and a
400
+ real pointer click navigates correctly, without enlarging the card to hide the defect.
401
+ Keep references accessible and verify the destination card is visible. Retain an expanded
402
+ focus-mode control and test independently of lifecycle warnings.
403
+
404
+ The source assessment also reports 508 background static card creations plus background
405
+ groups/edges across 38 boards, 518 Markdown cards, seven byte-identical images and 783
406
+ rendered internal anchors, with no validation collisions. These are corpus-specific
407
+ observations from the source thread, not a local rerun or a claim that all UI/loading
408
+ friction is cleared.
409
+
410
+ ### WI-10, documentation: import skill guidance lags delivered path and destination behavior
411
+
412
+ **Status:** fixed in the bundled `skills/pmx-canvas/SKILL.md` and
413
+ `skills/pmx-canvas/references/importing-context.md` after explicit owner approval.
414
+ The two files were checked against the current HTTP/MCP contracts and image-path
415
+ implementation. Bundled-skill checks pass. No installed copies or pipeline skills
416
+ were changed.
417
+
418
+ The source thread found launch-directory relative-image resolution and foreground-only
419
+ creation guidance. The refresh documents workspace-root-relative image paths and
420
+ background static card/group/edge creation using
421
+ `destinationBoardId`, while retaining active-board stale guards, retry identities and the
422
+ documented runtime/intents/background-update restrictions. This describes the bundled
423
+ source, not every installed copy, and does not advertise general inactive-board CRUD.
424
+
425
+ The update also documents intersecting `boardId`/`folder` search filters, opening a
426
+ suitable board when Home is active, and placing task/item content before retained
427
+ ancestor/source context. This layout advice applies to folders, repositories and
428
+ documents generally, not only one source corpus. Library discovery and background static
429
+ creation do not require leaving Home. The main skill's existing oversized-body issue is
430
+ not resolved by this scoped contract refresh.
431
+
432
+ ### WI-11, high: expanded Markdown link navigation rewrites untouched source
433
+
434
+ **Status:** independently reproduced here with fictional Markdown, then fixed.
435
+ The original implementation failed exact-content/revision checks after read-only link
436
+ navigation. Untouched rich editors now flush the exact caller draft, and unchanged
437
+ clean drafts do not persist. Actual rich edits still serialize and finish before
438
+ navigation, including pending drafts carried from Source mode.
439
+
440
+ Expanding a Markdown card and following a wiki link without typing changed its persisted
441
+ source from 32,873 to 33,160 characters. The reported differences include `- ` becoming
442
+ `- `, normalized table delimiter spacing and removal of the trailing newline. A full
443
+ post-restart comparison detected the changes, but the browser had already saved the
444
+ normalized source before restart. This is an unintended write during navigation, not
445
+ restart-related persistence loss.
446
+
447
+ The [source thread](https://ampcode.com/threads/T-01a14f43-f513-7397-8ec4-f6a85551dff0)
448
+ reports `browser-mutated-state.json` in its sibling fresh workspace and an inspected
449
+ `.amp/in/artifacts/knowledge-rerun/navigation.mp4`. Those files have not been transferred
450
+ here; preserve private source content. Only the source thread's test-created index was
451
+ restored from its import manifest; its subsequent exact restart comparison passed.
452
+ No original wiki or owner service was changed.
453
+
454
+ The local red test confirmed the reported path: blur serialized an untouched rich DOM,
455
+ then `handleInlineSave` marked it dirty and persisted. The disconnected/empty DOM guard
456
+ remains. The updated editor distinguishes input from reading; a save without input uses
457
+ the exact caller draft so a genuine pending Source-mode edit can still flush. Synthetic
458
+ source MCP checks confirm exact content/revision after reading and a real daemon restart,
459
+ and a separate real edit persists before link navigation. Browser regression checks also
460
+ cover close, Ctrl+S and navigation without input. Evidence is under
461
+ `.amp/in/artifacts/review-fixes/`; native-host and published-package checks are not claimed.
462
+
463
+ Independent acceptance on the exact candidate confirms byte-identical Markdown and
464
+ revision 1 after no-input close, Ctrl+S, body/expanded wiki navigation and daemon restart.
465
+ A genuine heading edit persists before navigation and advances the revision. Its
466
+ 318 client tests and four isolated headed browser cases pass; the full-run qualification
467
+ recorded under WI-09 remains unchanged.
468
+
469
+ **Acceptance:** use fictional Markdown containing list spacing, a table, a trailing newline
470
+ and an internal link. Mount/expand and follow that link without input; assert exact source
471
+ content and `contentRevision` remain unchanged before and after navigation/restart. In a
472
+ separate control, make a real edit and immediately follow the link; the edit must persist
473
+ before navigation. Do not fix the unintended write by dropping genuine pending saves.
@@ -1,6 +1,85 @@
1
1
  # Plan 016 — Context made visible (wave 1)
2
2
 
3
- **Status:** Slices 1–3 and 4a done (2026-10-05); 4b (tethers, drag preview, Updates entry) next.
3
+ **Status (2026-10-10):** built on `main`, not released. Slices 1–5 and 7 are done, with the
4
+ receipt extras, edit descriptions and the live session lens (slice 3) and Home (slice 7). Slice 6
5
+ (the curation evaluation) moved to [plan 019](plan-019-post-0.9-roadmap.md) step 6 on 2026-10-19. Suggested cards were dropped
6
+ (2026-10-10: the agent changes the canvas directly; asks and suggestions go through the composer).
7
+
8
+ **Handoff (2026-10-10, end of session).**
9
+ - **Drag performance, done:** on a 306-card board every card re-rendered on every drag frame. Cards
10
+ now render through a memoised `WorldNode` (CanvasViewport.tsx), `useHeaderFold` measures only
11
+ when its key changes, and `App` subscribes to "board is empty" instead of the node map. Profiled
12
+ (Chrome CPU profile, 90-frame drag): Preact diff ~700 → ~70 ms, GC 385 → 20 ms, p95 frame 37 →
13
+ 21 ms; long tasks 4 → 2.
14
+ - **Next, drag:** the two remaining long tasks (~50–65 ms) are at pickup and drop, not per frame.
15
+ Suspects to profile: pickup — `bringToFront`, `buildSnapCache` (O(n)), `reportHumanGrab`,
16
+ `takeOverNode`, `noteNearAtGrab`; drop — `persistLayout`, `settleNearAfterDrop`, attention
17
+ entries. Profiler script approach: Playwright + CDP `Profiler` on an unminified
18
+ `bun build src/client/index.tsx --outdir dist/canvas` (rebuild minified after).
19
+ - **Next, design:** build to [`SeeChange.dc.html`](../design/SeeChange.dc.html) (drawn 2026-10-10,
20
+ 33a853d8): stack Before/After; mark removed (line-through, muted) and added (violet tint +
21
+ underline) words with a word-level diff; captions under Undo ("puts back the text from before",
22
+ "the card shows Before again", "undo would lose your edit"); "Open its board to undo" becomes a
23
+ button naming the board; the row Undo's "Kept your edits" caption; one change open at a time.
24
+ At ≤ 760 px the live counts move into the agent avatar's popover (with the dim switch and "Open
25
+ session panel"), and the avatar gets a violet ring and phase dot (ContextChip600 wins over
26
+ Pane600).
27
+ - **Not run this session:** the curation evaluation (maintainer, later); a full browser suite on
28
+ a quiet machine (the presentation-record tests failed under load at 261e7c0f and its parent).
29
+
30
+ **Resumed (2026-10-10; not released).**
31
+ - **See change built:** stacked Before/After with Unicode word marks, one change open, the
32
+ drawing's Undo captions and shared per-card/bulk restored state. Long scroll boxes start at
33
+ the first marked word. The receipt is opaque so underlying violet marks do not bleed through.
34
+ The ≤ 760 px avatar has its ring, phase dot, counts, dim switch and Open session panel.
35
+ - **Board safety:** receipt touches carry their board ID, and merge/row identities use board +
36
+ card. Direct board switches retain the receipt, with a working Open <board> to undo button;
37
+ Home still dismisses it. Undo/Unpin cannot affect another board, and receipt marks/lens only
38
+ apply to the active board. Later human edits are retained on per-card and bulk Undo.
39
+ - **Pickup/drop profiled and one cost removed:** headed Chromium, 1440×960 at 100%, 306 Markdown
40
+ cards (230×150, 260×190 pitch), 90 moves per drag, three runs with 20 pins and three without.
41
+ Hit-tested titlebars and visible card displacement verify actual drags. An initial 25% probe
42
+ hit a port instead and was discarded. The named pickup/drop helpers were not the dominant
43
+ sampled cost; a timeline trace found page-wide style recalculation from the universal drag
44
+ cursor/selection selector. A single transparent drag curtain preserves pointer delivery across
45
+ frames without changing every descendant. It belongs to the canvas so collaborator cursors
46
+ still follow the pointer, and intercepts only after the 4 px threshold so double-click menus
47
+ keep working. In the no-pin trace, UpdateLayoutTree totals fell from 120/75 ms at pickup/drop
48
+ to 12/5 ms with the final built source. These are individual measured runs,
49
+ not a device-independent latency guarantee. Layerization/GC still produce occasional long
50
+ tasks (the final pickup had a 157 ms task including GC); do not claim all drag pauses are fixed.
51
+ - **Design checks:** all nine themes at 600/1024/1920; inspected Harbor, narrow Daylight,
52
+ avatar popover, long change, human-protected change, other-board and restored/bulk-kept states.
53
+ - **Still deferred:** the maintainer's curation evaluation. Relation-label spacing feedback is
54
+ separate guidance work; this change does not alter auto-arrange or validation.
55
+ - **Baseline gates:** the four presentation/tour cases also fail on a fresh unmodified
56
+ [26dc70a](https://github.com/pskoett/pmx-canvas/commit/26dc70ac46490d567750aa46b3449263b520613d)
57
+ build (1 passed / 4 failed in `presentation-record.pw.ts`). Repo-wide lint also failed there
58
+ with two formatting errors (`context-chip-store.ts`, `ax-timeline.ts`); the maintainer then
59
+ requested those fixes. Biome formatted only those two lines, and `bun run lint` now exits 0
60
+ (62 warnings, 12 infos). The presentation failures remain acknowledged, not described as green.
61
+ - **Review completed:** the requested review found short-window clipping, a retained receipt's
62
+ foreign-board comparison action, and row Undo still enabled after every individual restore.
63
+ Each was reproduced and fixed; the follow-up review found no remaining findings in that scope.
64
+ Final visual inspection also caught History's invisible tooltip widening the receipt; aligning
65
+ it to the end removed horizontal overflow, with a regression assertion shown red then green.
66
+ - **Final verification:** full build and typecheck pass; 1,379 unit tests and 247 client tests
67
+ pass. The final headed browser rerun has 232 passed and the same four baseline presentation
68
+ failures. The first run's three double-click regressions were fixed by gating the drag curtain
69
+ at the movement threshold; targeted interactions and the final full rerun pass those cases.
70
+ All five receipt browser cases pass, including short-window scrolling and created-only
71
+ cross-board comparison. Final DOM checks cover all nine themes at 600/1024/1920, with no
72
+ horizontal overflow. One interim client rerun caught a leaked debounced brief request in the
73
+ iframe test's fetch spy; that test passed alone and the full unchanged rerun passed 247/247.
74
+ First-failure evidence, rerun results and the unchanged-baseline reproduction are retained.
75
+
76
+ **Later combined checkpoint (2026-10-11; not released).** Wave 2 and the Wave 3 foundation
77
+ now pass 1,437 unit, 302 client and all 266 headed browser cases, including the presentation
78
+ and receipt cases. Live human/agent checks and final focused Oracle review are complete;
79
+ the earlier red runs above remain historical evidence, not relabelled passes. See the
80
+ [combined stabilization record](plan-018-connected-memory-wave-2.md#combined-stabilization).
81
+ The maintainer's curation evaluation remains deferred.
82
+
4
83
  **Date:** 2026-10-05
5
84
  **Source:** [design.md](../design.md#build-plan) wave 1; vision Part 1 bet (item 4), moves 0a, 2, 7.
6
85
  Drawings: [`AgentContext`](../design/AgentContext.dc.html), [`Context`](../design/Context.dc.html),
@@ -88,8 +167,20 @@ with their actions (Unpin, Undo). Data from presence activity, revisions and sli
88
167
  on a board with two agents at once, each receipt includes the other's reads.
89
168
  The receipt also reads the board open when the session ends; a session whose board the person
90
169
  switched away from mid-session reports the newly open board (known limit, 0.8.0 review).
91
- - **Not built:** per-row Undo of an edit (needs stored previous content); the pre-session snapshot
92
- restore still undoes the whole session. The drawn bottom-bar placement of the lens is folded into
170
+ - **Receipt extras, done (2026-10-10, gap 18).** A single session's receipt reads "What <agent>
171
+ did" with "This session · start–end · saved as a snapshot · ended by …"; the amber line has
172
+ "Tell <agent>" (a steering message to reread the changed pins); the Edited row has Undo, which
173
+ puts each edited card back to its pre-session content through the new
174
+ `snapshot.restore-node` operation (`canvas_snapshot { action: "restore-node" }`,
175
+ `POST /api/canvas/snapshots/:id/restore-node`) — one undoable edit per card, position, links
176
+ and pins kept.
177
+ - **Edits and the live lens, done (2026-10-10).** Each Edited line says what the edit did
178
+ (`describeEdit`: "rewrote the second paragraph", "added 2 paragraphs", "renamed it …"), from the
179
+ pre-session snapshot against the card now; "See change" shows Before / Now with Undo for that
180
+ card. Cards the session edited carry the violet title-bar bar while it is live or its receipt is
181
+ up. Presence carries the session's touches (`session`: read, created, edited, pinned ids), shown
182
+ as "2 read · 1 edited" in the agent chip; pressing it dims untouched cards, and that lens carries
183
+ on as the receipt's when the session ends. The drawn bottom-bar placement of the lens is folded into
93
184
  the receipt card, which already sits where session results appear.
94
185
 
95
186
  ### 4. Near a pin: neighbours in the brief, and the near mark
@@ -105,7 +196,17 @@ with their actions (Unpin, Undo). Data from presence activity, revisions and sli
105
196
  that changed since the cursor arrives in full as `changed` instead; a first read delivers every
106
197
  node in full, so it has no near entries. The client computes the same `findNeighborhoods` and
107
198
  shows the dotted "near" / "near N" chip on unpinned nodes, with the pins and distances on hover.
108
- - **4b, next.** Tethers and the 600 px radius when hovering a pin, the drag preview, the single
199
+ - **4b, done (2026-10-10).** Hovering, selecting or dragging a pin, or "Show pins" in a near
200
+ chip's card, draws numbered tethers (nearest first) and the 600 px radius in one screen-space
201
+ layer; dragging an unpinned card rings its nearest pin and previews its chip; a drop inside
202
+ pulses the chip once, a drop outside fades it; one Updates entry names the card and the pin
203
+ ("out of the agent's brief" only when it is near no pin). The near chip's card lists the pins
204
+ with distances and offers "Pin to put it first" (the drawing's wording, replacing "Pin to send
205
+ content") and "Show pins"; it draws over the canvas because a card paints contained. Perf
206
+ check (2026-10-10, 306 nodes / 20 pins, in-app pane): drag frames showed long tasks with and
207
+ without pins (8 vs 13), so none are attributable to near-a-pin; the drag itself is slow at
208
+ that size.
209
+ - **4b, as planned.** Tethers and the 600 px radius when hovering a pin, the drag preview, the single
109
210
  Updates entry that replaces "Neighborhood changed", the context chip's "N cards · M near" count,
110
211
  and "Pin to send content" in the chip's hover. The maintainer agreed the design (2026-10-06) on
111
212
  the condition that performance stays good:
@@ -120,19 +221,63 @@ with their actions (Unpin, Undo). Data from presence activity, revisions and sli
120
221
  - **Check.** A headed drag on a 300-node board with 20 pins records no long task (> 50 ms)
121
222
  attributable to near-a-pin.
122
223
 
224
+ ### 4c. Links changed in the brief (LinksChanged.dc.html, gap 15)
225
+
226
+ - **Done (2026-10-10).** On a later read, `changed` and `pinned` entries carry `changes`
227
+ (`["text"]`, `["links"]` or both; a pinned card stays `pinned`), and each relation drawn or
228
+ changed since the cursor ends "(new, by codex)" / "(changed, by a person)". First and reset
229
+ reads mark nothing; generated code-graph and board-map links are never stamped, so never
230
+ marked. A removed link writes one Updates entry naming both cards. Deviation: a person is
231
+ "by a person", not by name — edges record no human name until shared boards (hosted version, vision Part 4).
232
+
123
233
  ### 5. Board pins
124
234
 
235
+ **5a done, 2026-10-07.** `board_pins` table (who, when, why; removed with its board),
236
+ `board.pin` / `board.unpin` across `canvas_board`, HTTP `POST /api/canvas/boards/:id/pin|unpin`,
237
+ `pmx-canvas board pin|unpin` and `pinBoard()` / `unpinBoard()`; every board carries `pin`.
238
+ The brief adds pinned boards after the open board's pins (README and pinned cards in full,
239
+ else a discovery summary, reported in `delivery.pinnedBoards`), and a full delivery records a
240
+ read on that board. `canvas://pinned-context` lists `pinnedBoards`. **5b next:** the pin on
241
+ Home cards, the board switcher, portal cards and the top bar; Home's pinned section; the
242
+ context chip's "N cards · M boards" and its fallback note.
243
+
244
+ **5b, part 1 done, 2026-10-07.** One `BoardPinButton` (the card pin's mark on a 22 px target)
245
+ on Home rows (blue edge and "in context" when pinned), board switcher rows, portal cards and
246
+ the top bar; human pins carry the workbench marker. Left for part 2: Home's pinned-boards
247
+ panel and preview cards (`Home.dc.html`, a Home redesign), and the context chip shared with
248
+ 4b. Open: a portal shows both its card pin (header) and its board pin (body).
249
+
125
250
  Per vision move 0a and `BoardPins.dc.html`: `board_pins` table (board, who, when); `canvas_board`
126
251
  `pin`/`unpin` across PmxCanvas, HTTP, MCP and CLI; the tiered brief (active board's pins, then each
127
252
  pinned board's README + pinned cards, then discovery); the context chip counts "N cards · M boards";
128
253
  Home's pinned-boards section per `Home.dc.html`. Read status per board from slice 1.
129
254
 
255
+ ### 7. Home (Folders) — Home.dc.html, Pane600.dc.html (gaps 19, 20)
256
+
257
+ - **Done (2026-10-10).** Home is a library: a folder tree (counts, a pin dot on folders holding a
258
+ pinned board, "+ New folder"), the pinned boards with their ≈ token cost, the open folder's
259
+ breadcrumb, subfolder cards and board cards (thumbnail from the board list's new `preview`,
260
+ README line, cards, ↔ links, last opened), and a details pane for the selected board
261
+ (in-context switch, README, pinned cards, links, Open board, ⋯ move / rename / create from /
262
+ delete). A card selects; Open board (or a double-click) opens. At ≤ 760 px the tree is a folder
263
+ picker, pins a banner, subfolders chips, boards rows and details a bottom sheet.
264
+ - **Deviations:** folders carry no colour (decided 2026-10-07, superseding the drawing's hues); the
265
+ folder's README line is left out until folders have a README; the Map and Graph tabs wait for
266
+ wave 2; links are board portals only ("wiki link" has no data yet). The ≈ token cost per pinned
267
+ board is the board list's `mapChars` (README + pinned card summaries) / 4, an estimate.
268
+
130
269
  ### 6. The curation evaluation
131
270
 
271
+ **Ready, 2026-10-07.** Board, seed script, protocol, rubric and how results are used are in
272
+ [`docs/evals/curation-effect.md`](../evals/curation-effect.md); the fixture test guards that
273
+ pins change delivery at the default budget. Building it found that a first read larger than
274
+ the budget returned one clipped card forever; fixed so a first read pages (pins first, then
275
+ whole cards oldest first). Runs need the maintainer's agent sessions.
276
+
132
277
  `docs/evals/curation-effect.md`: one fixed task, run with the brief delivered on a curated and an
133
278
  uncurated board, scored on criteria written before the first run (vision Part 1, item 4). It reads
134
279
  the same `context_reads` data as slice 1 to confirm delivery before scoring effect. Running it
135
- needs the maintainer's real agent sessions; the decision rule is the vision's.
280
+ needs the maintainer's real agent sessions; from plan 019 step 6 onward it is a benchmark rerun per release (vision Part 1, item 4).
136
281
 
137
282
  ## Out of wave 1
138
283