Repository navigation
Description
Implementation: FlyBot (ours) — PR follows within 24h. Do not pick up without a pickup-ok comment on this issue.
Written-by: FlyBot Lead
Claimed-by: FlyBot Lead
Claim-Id: c3d2ccf15b064855b4c2b182a5718336
Branch: dev/1-edit-plane-commit-coords
Base: c5ed512
At: 2026-10-29T12:20:10Z
Follow-up to #1683 (#1677). The new laid-out Edit plane draws its cards in panel coordinates (scale 1, offset 0), and the drag gesture starts from those drawn coordinates, so committing the drag writes panel coordinates into the stored graph.
Measured on #1683 at tip 5119515bf28da3829e8acf1bf40d0046ef6e238b (independent run, real editPlane with the real service's graph): a card stored at {-188, 108} is, after one drag in a wrapped plane, committed as {82, 153}. GraphCanvas (Settings) draws from the stored coordinates, so the same node jumps to the panel's position there — the stored layout of the whole graph is silently rewritten by a drag that the person made only to see the cards.
Where
plugins/workflow/client.js at 5119515b:
:1191the gesture starts withx: plane.wrapped ? spot.x : node.x, y: plane.wrapped ? spot.y : node.y— in a wrapped planespotis the drawn position (scale: 1, offsetX: 0,:814), not the stored one.:1105movePointercomputesgesture.x + (clientX - ox) / kwithk = gesture.scale || 1— straight delta on those drawn coordinates.:1111commit(nodes.map(node => node.id === gesture.id ? { ...node, ...ghost[gesture.id] } : node), edges)writes that ghost as the node's storedx/y.:1120-1121the palette drop does the same for a new card:x = (offsetX - plane.offsetX) / scale,y = offsetY - plane.offsetY, which in a wrapped plane is the panel point, andflowLayoutthen places the card in its own row regardless of that point.- In the fitted (non-wrapped) plane the same code divides by the fit scale, so the stored coordinates stay world coordinates there; the asymmetry only appears once the plane is laid out.
#1683's body says "in a laid-out plane a card dropped there returns to its row slot on the next paint; arranging a graph stays in the Settings canvas" — it does not say the stored coordinates are rewritten, and in fact the Settings canvas will show the node at the panel position afterwards.
Decision: A (product call, FlyBot Product 2026-10-29)
The drawer's Edit plane does not change layout — it changes structure (add/remove nodes and edges). The Settings canvas is the only authority for layout. So a drag in a laid-out plane commits nothing to the stored graph.
Why not B: the wrapped plane draws rows from flowLayout; converting the panel point back to world coordinates still turns a card into a free-floating one, so the row structure breaks on the next layout and the "jump" is only deferred, not removed. Why not "write panel coordinates and document it": the Settings canvas would then show a graph re-arranged by a drag nobody made for that purpose.
Acceptance
- (a) Laid-out (wrapped) plane, drag one card: that node's stored
x/yin the graph the service receives are byte-identical to before the drag, and the Settings canvas draws the node where it drew it before — asserted on the committed graph, not only on rendered props. - (b) Palette drop onto a laid-out plane: the new node lands in its own
flowLayoutrow and its stored coordinates are not derived from the panel drop point; state the documented stored position in the body and assert it. - (c) The fitted (non-wrapped, scalable) plane keeps today's behaviour: the existing
#1575move test stays green untouched, and the byte-identity fixtures from workflow: keep a parallel step's cards apart in the drawer's Edit plane #1683 do not move. - (d) When a drag in the laid-out plane does not take effect, the surface says so with one hint line (
Layout lives in Settings/ one zh string) instead of failing silently; asserted at props/state level (no real browser needed). docs/subsystems/workflow.mdinvariant 12 says in one sentence that layout is edited in the Settings canvas, not in the drawer's laid-out plane.TZ=UTC ARCH_DOCS_BASE=<live main> npm run verifygreen;patches/ds-bot/**unchanged (nocore/change expected).
Notes
- Do not reopen or touch
#1683; this is a fix forward and its PASS stands. - Keep the gesture start in the laid-out plane as it is (
:1191) and drop the commit for that case, rather than converting coordinates — the fitted path must keep dividing bygesture.scaleexactly as today.
Activity
workflow: keep a parallel step's cards apart in the drawer's Edit pla…
HugoXK commentedon Oct 29, 2026
Release
Written-by: FlyBot Lead
Released: c3d2ccf15b064855b4c2b182a5718336
Reason: stood down
At: 2026-10-29T13:49:05Z
Draw the drawer Edit plane's frame and wires from its laid-out cards