Skip to content

fix(class): keep every multiplicity and role at its own end - #593

Merged
anandpant merged 1 commit into
mainfrom
fix/issue-589
Oct 31, 2026
Merged

anandpant merged 1 commit into
mainfrom
fix/issue-589

Conversation

@anandpant

@anandpant anandpant commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

What

Class diagrams keep every multiplicity and role at its own end. After #588, Sol's library-system-class-v2 build put the reservations role at the Member end of Member → Reservation instead of the Reservation end. The judge failed 2 of 5 samples on data accuracy, and 3 failed the class-drawn check (relationship-12 to role).

Why it happened

Member → Reservation is a single vertical run, so the end's "first run" is the whole line. At the Reservation end, no spot was clearly attributed to that line, so the role walked down the run until it found one. That spot sat just above Member: 185 px from its own tip, 62 px from the other. The same walk misplaced end labels before #588 (23 in the full fuzz run); #588 changed which models hit it.

Change

  • Renderer (class-diagram.ts): a multiplicity or role only takes a spot beside its own end. Its middle must be within 110 units of the end's tip (the same reach as the class-drawn check), and the line's other tip must stand at least half again as far off, and 8 units further, by fix(class): set every class label clearly on its own line #588's attribution rule. This also keeps a self-loop's labels out of the space between its two runs. When no spot is both beside its end and clearly on its own line, the label stays beside its end and fix(class): set every class label clearly on its own line #588's label-room retry runs. That retry may now take over when it reads up to 5% longer than the placement it replaces; before, it could not read longer at all. Without that, retries that cleared every label at equal routing quality were rejected for aspect changes like 2.78 → 2.79.
  • Class fuzz: a new end invariant checks every end label: middle within 110 of its tip, and the far tip clearly further off.
  • Renderer test: the same end rule runs on every class fixture, plus a check that reservations stays at Reservation.
  • Fixture and story: classStressFixtures.memberReservations holds Sol's actual build, shown in Storybook as Diagram Types/Class › Roles At Their Ends.

Evidence

main this PR
Full class fuzz (240 models, seed 20261019): end misplacements 17 0
Same invariant on seeds 1–8 (240 models each): all findings / end misplacements 81 / 74 12 / 0
100 saved class builds from the eval inputs: class-drawn failures 3 0
  • Trade-off: on seeds 1–8, 8 labels whose room would cost crossings now sit at their end but nearer a neighbouring line. Main placed those beyond their end's reach instead. The other 4 findings fail on main too.
  • Scene changes: across the 100 saved builds, exactly 3 scenes change, and in each only relationship-12's two end labels move.
  • Pins and render time: routing pins are unchanged. On the real specs, render time is unchanged within noise (two runs: 331 vs 337 ms, then 454 vs 398 ms). Across the fuzz seeds it is about 20% higher on average, from extra label-room retries on random models.

Preview replay (pr-593-sketchi-studio): I replayed all 40 round-30 class builds (Sol and Sonnet, every v2 class scenario) against prod and against this preview.

  • Acceptance: all 40 builds were accepted on both.
  • Returned scenes: on prod, the 3 Sol library samples (4tdt, ihie, e899) misplace reservations, 167 px from its own tip and 14 px from Member's. The preview misplaces none, and neither has a label nearer another line.
  • Scenario-CLI grades: 37 are identical to the evals' grades. The other 3 are those Sol library samples, which lose only their class-drawn failure.

Before/after PNGs are in /home/anandpant/Development/shpitdev/sketchi/.memory/r30-slices/589-png/:

  • before/, after/: local headless resvg exports of main and this branch, for Sol's r30 build (sol-library-c7ac.png), the new fixture, and the three changed corpus builds.
  • prod-replay/, preview-replay/: real PNGs from prod and from the preview for the three affected Sol samples, plus one Sol observer and one Sonnet library build, with the grade and end-check outputs.

Verification

  • pnpm ci:local passes.
  • pnpm nx run diagram-excalidraw:class-fuzz (full: 240 models, 120 text-fit rounds) passes.
  • pnpm nx affected -t test-browser passes.

Fixes #589

Sol's library build lost two of five samples on data accuracy, and three on
the class-drawn check, after #588: Member to Reservation runs straight up in
one run, the "reservations" role found no spot clearly its own line's at
Reservation, and walked down that run until it stood just above Member.

A multiplicity or role now only takes a spot beside its own end: its middle
within 110 units of the end's tip (the class-drawn check's reach) and the
line's other tip half again as far off as its own, and 8 units further. That
also keeps a self-loop's labels out from between its two runs. With no spot
both beside its end and clearly its own line's, it stays beside its end, and
the placements run again keeping room for labels; one that reads at most 5%
longer than the placement it replaces may now take over.

The class fuzz gains the end invariant: main misplaced 17 end labels across
the 240-model full run and 74 across eight more seeds, none now. On those
eight seeds, 8 labels whose room would cost crossings now stand at their end
but nearer a neighboring line (81 findings on main, 12 now). Across the
100 saved class builds from the evals, three scenes change, each only in that
one end's labels, and each now passes the class-drawn check. The renderer
test checks every class fixture, and a new fixture and story carry Sol's
build.

Fixes #589

Copy link
Copy Markdown
Collaborator Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@anandpant anandpant added the preview Deploy PR previews for the affected apps label Oct 31, 2026
@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Sketchi Excalidraw Workspace Preview

Status: deleted

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Sketchi Eval Harness Preview

Status: deleted

@github-actions

github-actions Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Sketchi Playground / Studio Preview

Status: deleted

@anandpant
anandpant marked this pull request as ready for review October 31, 2026 07:55
@anandpant
anandpant merged commit 4bb1d23 into main Oct 31, 2026
15 checks passed
@anandpant
anandpant deleted the fix/issue-589 branch October 31, 2026 07:56
@github-actions

Copy link
Copy Markdown
Contributor

Sketchi Icons Preview

Status: deleted

@github-actions

Copy link
Copy Markdown
Contributor

Sketchi Web Preview

Status: deleted

This branch was successfully deployed

1 active deployment
staging — 1c229230 Deployed Oct 31, 2026 by anandpant via cleanup-preview (web) #1106
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Deploy PR previews for the affected apps

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Class diagrams: #588 can put an association role at the wrong end

1 participant