openova/products
e3mrah 7acd7d720d
fix(catalyst-ui): hard-clamp Flow node positions inside viewBox (Closes #481) (#521)
Live failure on otech17/cluster-bootstrap (2026-05-01): the JobDetail
flow canvas rendered as yellow horizontal lines with zero visible
bubbles. Investigation showed nodes drifted to x=30,400+ in viewBox
coordinates because the dependency graph had longest-path depth ~190
(bp-* leaves chained through "applications"). At PER_DEPTH_X=160 that
placed nodes far outside the MAX_VBOX_W=1200 ceiling. The viewBox
captured only a 1200px slice of a 30,000px cluster, so 99% of bubbles
rendered off-canvas. The few yellow lines visible were edges from the
selection job (openJobId) that happened to cross the visible window.

Pre-existing bounded tests modelled depth=0/1 stars only (#486 #499) so
this pathology slipped through.

Operator's two explicit asks for this fix:

  1. "No single bubble could be outside of the canvas."
  2. "Max distance of a line cannot be longer than a percentage of canvas."

Implementation — Constraint A + Constraint B as a render-time projection:

* Compute the natural cluster bbox from livePos as before, clamp to
  MIN/MAX viewBox.
* When natural bbox exceeds the viewBox, anchor vbX/vbY at the
  left-most / top-most cluster point (instead of centring on the
  cluster centroid which placed depth 0 at x=-15,000).
* Linear-scale every render position so the cluster fits inside an
  inset rectangle (vbX+CLAMP_INSET .. vbX+vbW-CLAMP_INSET).
  Pathological depth=190 chains compress to fit; sparse graphs with
  scale=1 are unchanged.
* Hard-clamp every position into the inset rectangle as a final safety
  net (FP drift, partial-tick frames). No bubble can ever sit outside.
* Edges read renderPos so they're drawn between already-clamped
  endpoints — line length is bounded by the viewBox diagonal, no
  "kilometers of edges" possible regardless of what the simulation
  produces.

Test:

* New `keeps every bubble inside the viewBox for a deep dependency
  chain` — 50-node depth chain (each at depth=i, mirroring production
  shape). Asserts every centroid inside [vbX, vbX+vbW] × [vbY, vbY+vbH]
  AND every line length <= viewBox diagonal. Strict — no overshoot
  tolerance. Fails on main, passes after the fix.
* All 11 pre-existing bounded tests still pass; tsc clean.

Live verification + Playwright screenshot to follow on the deployed SHA.

Co-authored-by: alierenbaysal <alierenbaysal@noreply.github.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 09:04:37 +04:00
..
axon feat(axon): make qwen3-coder thinking mode toggleable via request parameter 2026-04-26 09:20:33 +02:00
catalyst fix(catalyst-ui): hard-clamp Flow node positions inside viewBox (Closes #481) (#521) 2026-05-02 09:04:37 +04:00
cortex docs(pass-52): bundled date-sweep + cross-component namespace clean; knative clean 2026-04-28 00:37:21 +02:00
fabric docs(seaweedfs+guacamole): replace MinIO with SeaweedFS as unified S3 encapsulation; add Guacamole to bp-relay 2026-04-28 10:23:46 +02:00
fingate docs(pass-52): bundled date-sweep + cross-component namespace clean; knative clean 2026-04-28 00:37:21 +02:00
relay docs(seaweedfs+guacamole): replace MinIO with SeaweedFS as unified S3 encapsulation; add Guacamole to bp-relay 2026-04-28 10:23:46 +02:00