Skip to content

Conversation

@Irev-Dev
Copy link
Contributor

@Irev-Dev Irev-Dev commented Jan 8, 2026

Ostensibly trying to show colours in sketch mode,
image

Resolves #9281

but did a fair bit in rust:

  1. I decided to cache previous freedom_analysis on the rust side, so that I could make them non-nullable for the TS side. Jon you might disagree so let me know
  2. There seemed to be a bug, I don't think conflict variables from Ezpz were being handled correctly (only unsatisfied), and so the values that came back when ever there was a single conflict in the sketch made many of the colours for segments etc wrong. I added freedom_analysis_tests which were failing before I added the fix.

On the TS side I revamp the colors a little to give clear prirotiy of what status wins out for colors, it's the following order now:
draft colour
hover colour
select colour
conflict colour
free colour
fixed colour

Also I added the following logic for deriving the freedom of segment bodies

  • If a single point or more on a segment is conflicted, consider the whole segment conflicted
  • else if a single point or more on a segment is free consider the whole segment free
  • else (implicitly if all points on the segment are fixed) conisder the whole segment fixed

Note

Improves solver output and sketch freedom visualization while making Freedom non-null and cached.

  • Rust: build variables_in_conflicts from unsatisfied constraints by scanning all constraints; use it to mark conflicts (replacing unsatisfied checks), and pass combined constraints to Solved::from_ezpz_outcome; add robust helpers for extracting IDs and fallback parsing; default missing freedom analysis to Free for points.
  • Frontend (Rust): add point_freedom_cache and update_state_after_exec(outcome, freedom_analysis_ran) to preserve/merge point freedoms when analysis isn’t run; optionally force analysis when cache empty and all points appear Free; make Point.freedom non-optional in API and wire freedom flags through execution paths; add freedom_analysis_tests (feature-gated).
  • Frontend (TS): introduce segmentsUtils with deriveSegmentFreedom (segment = Conflict if any point conflicts, else Free if any free, else Fixed) and getSegmentColor with precedence: draft > hover > select > conflict > free > fixed; refactor segment rendering to use these and propagate freedom through groups/hover.
  • Tests: add comprehensive TS tests for freedom derivation and color logic.

Written by Cursor Bugbot for commit 39b6b00. This will update automatically on new commits. Configure here.

@Irev-Dev Irev-Dev added the sketch-solve PRs changing sketch-solve functionality only. label Jan 8, 2026
@vercel
Copy link

vercel bot commented Jan 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
modeling-app Ready Ready Preview, Comment Jan 9, 2026 1:56am

@codspeed-hq
Copy link

codspeed-hq bot commented Jan 8, 2026

Merging this PR will degrade performance by 14.19%

Summary

❌ 1 regressed benchmark
✅ 151 untouched benchmarks
⏩ 92 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation mock_execute_mike_stress_test_program 328 ms 382.3 ms -14.19%

Comparing kurt-9281 (39b6b00) with main (891bdb8)2

Open in CodSpeed

Footnotes

  1. 92 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (8c30452) during the generation of this report, so 891bdb8 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@Irev-Dev Irev-Dev changed the title [SOLVE WIP]: constraint freedom visualisation [SOLVE]: constraint freedom visualisation Jan 8, 2026
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added these tests failing before I started working on a fix, now they pass.

Comment on lines 83 to 88
(ObjectId(1), Freedom::Fixed), // line1.start
(ObjectId(2), Freedom::Fixed), // line1.end
(ObjectId(4), Freedom::Fixed), // line2.start
(ObjectId(5), Freedom::Free), // line2.end (currently bug shows Conflict)
(ObjectId(7), Freedom::Conflict), // line3.start (currently bug shows Free)
(ObjectId(8), Freedom::Conflict), // line3.end (currently bug shows Free)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The kcl for this is
line1 with both ends fixed
line2 with one end fixed
line3 with two conflicting distance constraint

But before the fix, point_freedoms would come back as fixed, fixed, fixed, conflict, free, free.

@Irev-Dev Irev-Dev marked this pull request as ready for review January 8, 2026 10:53
@Irev-Dev Irev-Dev requested review from a team as code owners January 8, 2026 10:53
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the final PR Bugbot will review for you during this billing cycle

Your free Bugbot reviews will reset on February 3

Details

You are on the Bugbot Free tier. On this plan, Bugbot will review limited PRs each billing cycle.

To receive Bugbot reviews on all of your PRs, visit the Cursor dashboard to activate Pro and start your 14-day free trial.

Updated should_force_freedom_analysis to only return true if:
The cache is empty (analysis hasn't run yet)
AND all points are Free (likely default values)
If the cache has values (even if all Free), it means analysis has already run, so we don't force another run. This prevents the repeated retries that led to incorrect results.
What This Fixes
Prevents the infinite loop of retries after each edit
Stops forcing analysis when it has already run
Reduces the chance of hitting the bug where freedom analysis returns incorrect results
The underlying issue (freedom analysis sometimes returning 2 instead of 18 underconstrained) may still occur, but it will happen less often since we're not repeatedly retrying.
Test this and see if segments still turn white. If the issue persists, we may need to investigate why kcl-ezpz freedom analysis returns inconsistent results with the same constraint counts.
expect(freeColor).toBe(UNCONSTRAINED_COLOR)
expect(fixedColor).toBe(TEXT_COLOR)
})
})
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate test files with nearly identical content

Low Severity

Both segments.spec.ts and segments.test.ts are new files with nearly identical test content for deriveSegmentFreedom and getSegmentColor. The .test.ts file has one additional test case (should return null when all points are missing) and slightly different test naming. If the test runner picks up both *.spec.ts and *.test.ts patterns, the same tests will run twice. One of these files should likely be removed.

Additional Locations (1)

Fix in Cursor Fix in Web

const darkerRgb = `${Math.round(r * 0.7)}, ${Math.round(g * 0.7)}, ${Math.round(b * 0.7)}`
innerCircle.style.backgroundColor = `rgb(${darkerRgb})`
innerCircle.style.border = `1px solid rgba(${darkerRgb}, 0.5)`
return // Hover styles take precedence
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Point hover color is doubly darkened causing visual inconsistency

Medium Severity

In updatePointColors, when isHovered is true, getSegmentColor already returns the hover color at 70% brightness. Then the code at lines 135-141 darkens it again by 70%, resulting in 49% brightness (0.7 × 0.7 = 0.49). In contrast, updateLineColors and updateArcColors use the color from getSegmentColor directly without additional darkening. This causes hovered points to appear significantly darker than hovered lines and arcs, creating a visual inconsistency. The hover branch either shouldn't darken the color again, or isHovered shouldn't be passed to getSegmentColor if the intent is to darken a base color.

Fix in Cursor Fix in Web

point_ids.push(arc.end);
point_ids.push(arc.center);
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Circle segments not handled in freedom analysis check

Low Severity

The should_force_freedom_analysis function handles Point, Line, and Arc segment types when collecting point IDs, but does not handle Circle segments. The Circle struct has a start field (the center point's ObjectId) that should be included. For sketches containing only circles, point_ids would be empty, causing the function to return false at line 2161 and skip forcing freedom analysis. This could result in circle center points showing incorrect freedom colors until analysis runs for another reason. The TypeScript equivalent in segmentsUtils.ts correctly handles circles.

Fix in Cursor Fix in Web

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

Labels

sketch-solve PRs changing sketch-solve functionality only.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Segment freedom visualisation

2 participants