Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
eee4063
feat(graph): define shared geometry for item wire paths
mvalancy Oct 28, 2026
1d2d9f8
fix(graph): keep offset labels on their routed leg
mvalancy Oct 28, 2026
d9a0a58
refactor(graph): share item wire paths across render consumers
mvalancy Oct 28, 2026
9931b3c
fix(graph): preserve hidden label sizing and opposite wire lanes
mvalancy Oct 28, 2026
93fe6d2
test(graph): require stable camera and painted item wires
mvalancy Oct 28, 2026
6ac0f48
test(graph): exercise empty hidden-label measurements explicitly
mvalancy Oct 28, 2026
351749f
feat(graph): reserve readable adaptive card and label geometry
mvalancy Oct 28, 2026
e4f654a
test(graph): gate readable symbols and 2000-item zoom journeys
mvalancy Oct 28, 2026
6d81752
fix(graph): bound label work and preserve visible interactions
mvalancy Oct 28, 2026
5d1aef8
feat(graph): strengthen typography and reconcile revealed cards
mvalancy Oct 28, 2026
5b16ce9
Place labels in visible route spans and verify painted zoom readiness
mvalancy Oct 28, 2026
9c564ac
Keep diagonal labels clear and trace controls readable
mvalancy Oct 28, 2026
a378dce
Plan relationship priority levels with per-pair fallback
mvalancy Oct 28, 2026
bcc0b91
Strengthen graph wires and workspace visual hierarchy
mvalancy Oct 28, 2026
aaa2913
Preserve focused icon labels across pointer hover
mvalancy Oct 28, 2026
b33febb
Exercise visible card editing in adaptive graph journeys
mvalancy Oct 28, 2026
fe84973
fix: keep graph status and connection controls in shared flow
mvalancy Oct 28, 2026
38a5e02
fix: preserve native scrolling over graph status controls
mvalancy Oct 28, 2026
69d0493
fix: give active radar charts the workspace typography baseline
mvalancy Oct 28, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .agents/inbox/2026-10-28-graph-controls-need-shared-flow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Graph controls need shared flow and explicit event boundaries

2026-10-28, PR #223 / issue #222. CI 40731080444 tested merge
`7eb3b6085282c53b5a48ce806bd1e35bf21424c8` from source `b33febb`.
Its durable-layout report contains four actual passes and five actual failures,
plus the execution-failure record. All five failures show the connection Browse
button intercepting pointer clicks intended for layout Retry/Discard controls.
The independently verified smoke artifact SHA-256 is
`c52d20e7` (prefix; complete digest retained in the GitHub artifact metadata).
Screenshots and traces are retained in the failed run. Four downstream browser
stages were skipped; this run is not acceptance.

Cause: status and connection controls independently occupied bottom-left space
at the same z-index. Increasing text size exposed an existing ownership problem.
A second headed regression at 1440/390 opened the relationship browser's Edit
button, but the parent document outside-click handler immediately cleared the
selected edge, changing the new dialog into Create relationship.

Corrective rule: put status, trace and connection controls in one responsive,
scrollable flow dock in both item and group views. Include each control's actual
footprint in routing/label obstacles. Do not fix overlapping controls by changing
paint order or forcing test clicks. Keep browser-panel clicks inside its event
boundary so opening an editor cannot also trigger outside dismissal.

Validation commands use one headed Chrome, one worker and zero retries:
- `playwright test item-wire-consumers.spec.ts layout-recovery.spec.ts --grep
'item wire paths|reload|unavailable storage'`: three passed in 36.7s. Exact
browser Edit now checks original source, target and type without data writes.
- `playwright test layout-recovery.spec.ts --grep
'quota-failed|retry after real|pending layout keeps'`: three passed in 42.2s.
The pending-layout journey also checks disjoint status/Connections bounds,
normal Retry/Browse/Discard clicks at 1440 and 390px, and actual API/receipt
state. Existing durability and camera assertions remain unchanged.
- Web `tsc --noEmit` passed using the owned dependency fixture. This is scoped
evidence, not a pinned clean-install or complete CI result.

Limits: the dock reserves control space, not arbitrary card-to-overlay clearance.
Full exact-source CI, actual artifact review and final dev checks remain required.
The separate priority feature has additional desktop/phone browser coverage;
its success does not establish this PR's full acceptance.

The first phone trace run rejected the dock container as overlapping its own
trace child. The transparent layout container no longer declares itself as a
second obstacle; status, trace and connection controls each retain their actual
measured obstacle. The oracle and its overlap assertions are unchanged. The
failed `dock-trace-phone1` artifacts are retained.
The corrected phone hierarchy/trace journey passed in 25.3s in
`dock-trace-phone2`, including its original overlap/readability checks and the
8px trace-text negative. No oracle assertion was relaxed.

Independent review of `fe84973` used the actual dock/status components and the
production D3 zoom filter. A wheel over status prevented native scrolling and
changed camera scale from 1 to 0.8705505633. Marking the shared dock with the
existing `data-lod-controls` boundary leaves the wheel default intact and scale
at 1. The pending-layout browser case now adds a 390×500 viewport, requires
actual dock overflow, wheels over its status area, and verifies native scrolling
with an unchanged camera before discarding the owned receipt.
The complete amended pending-layout journey passed in 15.7s on 2026-10-28,
with one headed Chrome, one worker and zero retries (`dock-native-scroll1`).
87 changes: 87 additions & 0 deletions .agents/inbox/2026-10-28-hidden-labels-need-valid-measurement.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Keep conservative label geometry when hidden SVG measurement is empty

2026-10-28 UTC, independent review of item-wire source
`d9a0a5855612290b7c765999440b0d1d55b36333` for #220 / PR #221. Existing
guidance was searched in the symptom index and the offset-label lesson. This
was a source-review finding, not a reproduced deployed/browser incident.

The first placement pass can hide an edge-label group before its delayed
150ms sizing callback runs. Accepting an empty `getBBox()` then replaces a
conservative text estimate with padding alone (36 units), allowing a long
label to be admitted using an undersized obstacle/background. Initialize text,
icon and background from one conservative cache, and replace that cache only
when both measured dimensions are positive. Hidden labels must not become
small merely because they are not currently measurable.

The same review found a line-only diagnostic reading `x1.baseVal` after the
renderer changed to SVG paths. Read actual path endpoints through
`getPointAtLength` and transform them through `getScreenCTM`. Searching for
remaining `SVGLineElement` / `x1.baseVal` consumers found this one diagnostic.

A separate source audit found that directed perpendicular offsets put reverse
edges on the same lane: reversing both the direction and lane sign cancels the
separation. Use a canonical unordered endpoint direction to define lane sides,
while preserving the original route direction for arrows and editing.

Dated local commands used supported Node22.18, nice10, one worker, in the
existing clean-installed partial probe (not full-tree acceptance):

```sh
node node_modules/vitest/vitest.mjs run --root packages/web \
src/lib/__tests__/edgeRouteGeometry.test.ts --maxWorkers=1 --no-file-parallelism
node node_modules/typescript/bin/tsc --noEmit -p packages/web/tsconfig.json
node node_modules/@playwright/test/cli.js test tests/e2e/graph/item-wire-consumers.spec.ts --list
node --test --test-concurrency=1 tests/lib/runner/unified-cli.test.mjs
```

Results: 11 geometry cases passed in0.722s (9ms bodies); scoped web types passed
in3.72s; two browser cases discovered, **not executed locally**; 32 CLI harness
cases passed in4.56s without a browser. Scoped flat-config lint over both
components/helper/test passed with0 errors and314 warnings. An initial lint
invocation from the uninstalled worktree failed to resolve a legacy config;
the corrected command ran from the probe's web package with
`ESLINT_USE_FLAT_CONFIG=true`. That setup error is not a source lint result.

The new blocking `item-wires` sequence is enrolled in PR/full profiles and CI
after smoke, before longer suites, with one browser worker and zero retries.
It exercises actual SVG paint/hitboxes/arrows, pointer dragging, wire/label
editing and initially hidden label sizing, retains PNG/JSON, rejects writes,
compares original graph data and uses owned fixture cleanup. CI execution and
artifact review remain required. The route is still straight; these changes
do not establish bounded obstacle routing, visible detail budgets, complete
spaghetti detection or closure of #220.

Independent review of `9931b3c` required stronger browser oracles before
acceptance: pinned physics can be at rest while the450ms Fit transition is
still moving the camera, and paint checks must inspect ancestors and actual
stroke/fill. The correction waits for both `atRest` and `cameraReady`, rejects
hidden ancestors/absent paint, and deliberately hides wire and arrow groups or
removes a wire stroke to prove rejection. It also compares route endpoints to
the original API-directed cards and checks the editor's original direction and
selected type. Relationship type buttons expose their selected state through
`aria-pressed`. Local discovery still finds2 cases and scoped web types pass;
actual browser acceptance is pending. These were source-review findings,
not locally executed browser negatives.

On2026-10-28, exact source `93fe6d2` CI40646515194 failed the hidden-size case:
expected at least104, received94.90625. The other item-wire case passed,
including paint negatives and actual dragging/editing. Chromium had returned
valid measured text dimensions smaller than the conservative estimate; the
assertion incorrectly assumed hidden SVG always measures zero. This is a test
precondition defect, not evidence that valid94.90625-unit geometry clips text.
The amended case deliberately returns an empty box only for hidden edge text,
counts that branch and retains the full-size/background/visibility assertions.

The owner then requested a visible headed browser. A single installed Chrome,
one worker, zero retries, on isolated preview28917/API28918 and the previously
owned Neo4j28687 exercised the regression. With only the positive-measurement
production guard removed from the disposable preview, the actual case failed
with width36 versus104, after confirming an empty measurement. Restoring the
unchanged production guard made both item-wire cases pass in21.9s. Traces,
screenshots and logs are retained under `item-hidden-negative` and
`item-wires-headed-positive` in the20261027 evidence directory. This reused a
matching dependency installation for scoped preview evidence; it is not a
clean-install/full-tree acceptance run. The source PR remains subject to fresh
CI and independent review. The owner's further feedback about clipping,
overlap, tiny text and wasteful cards requires broader visual acceptance;
passing these two interaction cases does not resolve that feedback.
47 changes: 47 additions & 0 deletions .agents/inbox/2026-10-28-offset-label-drag-needs-offset-path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Project dragged labels onto their displayed offset path

2026-10-28 UTC, detailed item-wiring preparation for #220. Existing guidance
was searched through `.agents/issues/INDEX.md`, `edgeLabelLayout.ts` and the
schematic lessons. This is a controlled helper regression found before D3
integration, not an observed failure in a deployed item router.

The independent review of `eee4063c43e619a33c48fd0408bb9dc2dd45cc92` asked for
an offset-label drag case beside a close return wire. The helper initially
projected the pointer onto the wire centerline. On a U-shaped route whose
horizontal legs are 40 units apart, the lower leg's upright label is offset22
units upward. Its center is18 units from the upper wire and22 from its own.
Nearest-wire projection therefore selects the wrong leg even with the prior
fraction available as a tie-breaker: the distances are not tied.

Command, supported Node22.18, existing clean-installed partial probe, one worker:

```sh
node node_modules/vitest/vitest.mjs run --root packages/web \
src/lib/__tests__/edgeRouteGeometry.test.ts --maxWorkers=1 --no-file-parallelism
```

Before correction: 9 passed, 1 failed, exit1, 0.713s. The executed new assertion
expected `340 / 440 = 0.772727...` but received `100 / 440 = 0.227272...`.
It passed a requested offset22 while the earlier helper ignored that extra
argument. The production API was then extended explicitly, not the assertion
relaxed. After correction: 10 passed, no skips, exit0, 0.691s (8ms test bodies).
Scoped strict ES2020 TypeScript checking of helper and test also passed. Source
and test were copied unchanged into the probe; this is not full-tree acceptance.

Corrective rule: use the same upright perpendicular displacement for pointer
projection and label painting. At D3 drag start, retain where inside the label
the pointer grabbed it, then project the adjusted label center onto the offset
route. Preserve icon rotation around the icon's own center. Keep the direct
wire projection available for wire hit testing; it has different geometry.

The review also found repeated route scans and candidate sorting in placement.
Interpolate each candidate directly on its current segment and retain the best
candidate in one pass. Placement now has O(segments × obstacles + segments)
work with at most four candidates per segment. Runtime callers still need
explicit bounds and a suitable update cadence. A null sampled placement means
no tested slot was clear, not that every mathematical position is obstructed.

The regression lives in `edgeRouteGeometry.test.ts`. No browser/database/image
suite ran locally, no canonical positions changed, and no item-renderer
acceptance is claimed. Carry this finding with the D3 consumer fix and its
actual pointer/browser gates through normal review.
Loading
Loading