Skip to content

workflow: a drag in the drawer's laid-out Edit plane commits panel coordinates into the stored graph, so the node also moves on the Settings canvas #1686

Closed

Description

@HugoXK

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:

  • :1191 the gesture starts with x: plane.wrapped ? spot.x : node.x, y: plane.wrapped ? spot.y : node.y — in a wrapped plane spot is the drawn position (scale: 1, offsetX: 0, :814), not the stored one.
  • :1105 movePointer computes gesture.x + (clientX - ox) / k with k = gesture.scale || 1 — straight delta on those drawn coordinates.
  • :1111 commit(nodes.map(node => node.id === gesture.id ? { ...node, ...ghost[gesture.id] } : node), edges) writes that ghost as the node's stored x/y.
  • :1120-1121 the 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, and flowLayout then 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

  1. (a) Laid-out (wrapped) plane, drag one card: that node's stored x/y in 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.
  2. (b) Palette drop onto a laid-out plane: the new node lands in its own flowLayout row and its stored coordinates are not derived from the panel drop point; state the documented stored position in the body and assert it.
  3. (c) The fitted (non-wrapped, scalable) plane keeps today's behaviour: the existing #1575 move 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.
  4. (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).
  5. docs/subsystems/workflow.md invariant 12 says in one sentence that layout is edited in the Settings canvas, not in the drawer's laid-out plane.
  6. TZ=UTC ARCH_DOCS_BASE=<live main> npm run verify green; patches/ds-bot/** unchanged (no core/ 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 by gesture.scale exactly as today.

Activity

  1. HugoXK commented on Oct 29, 2026

    @HugoXK
    ContributorAuthor

    Release

    Written-by: FlyBot Lead
    Released: c3d2ccf15b064855b4c2b182a5718336
    Reason: stood down
    At: 2026-10-29T13:49:05Z

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions