585 Commits
Author SHA1 Message Date
NilsBriggen ec0b2f2891 feat(ui): improve text readability and add VernierCAD identity
ci / check (push) Failing after 4s
Agent: codex
2026-09-15 21:39:11 +02:00
NilsBriggen 100c112c7a test: update persisted format expectations
ci / check (push) Failing after 5s
2026-09-15 20:42:15 +02:00
NilsBriggen b8ddcad721 test: carry saved views through format 42 2026-09-15 20:30:00 +02:00
NilsBriggen 33ef0787e9 test: update forged loft fixture for mode 2026-09-15 20:26:30 +02:00
NilsBriggen 573d7cd5b5 test: align loft edit gate coverage 2026-09-15 20:23:13 +02:00
NilsBriggen e23ce64e59 test: satisfy release clippy policy 2026-09-15 20:20:19 +02:00
NilsBriggen d29895991e fix: close smooth loft release blockers 2026-09-15 20:18:21 +02:00
NilsBriggen 2626c78387 docs: record smooth loft and performance evidence 2026-09-15 20:00:54 +02:00
NilsBriggen 218e42ac49 gate smooth ergonomic handle workflow 2026-09-15 19:56:26 +02:00
NilsBriggen bb2e1fdcd5 test: drive the handle through smooth loft 2026-09-15 19:25:57 +02:00
NilsBriggen 82937f4706 fix: sign workflow preview before meshing 2026-09-15 19:25:57 +02:00
NilsBriggen 45c659ed45 feat: edit loft section order in the shell 2026-09-15 19:23:29 +02:00
NilsBriggen ffc1fdb1ee perf: split workflow preview latency phases 2026-09-15 19:23:07 +02:00
NilsBriggen b797675479 test: pin existing loft fixtures to ruled 2026-09-15 19:22:58 +02:00
NilsBriggen 6a1202f8fd test: add ergonomic handle acceptance
Agent: handle_drive_map
2026-09-15 19:18:17 +02:00
NilsBriggen 5d07c9b215 feat: build exact smooth loft columns
Agent: smooth_loft_map
2026-09-15 19:15:43 +02:00
NilsBriggen fe4ac93b05 feat: persist loft interpolation mode
Agent: loft_ui_map
2026-09-15 19:15:18 +02:00
NilsBriggen af47d6b867 docs: sequence handle and smooth loft work
Agent: root
2026-09-15 19:04:11 +02:00
NilsBriggen b0232f41ee test: align gate contract with OCCT feature 2026-09-15 10:31:38 +02:00
NilsBriggen 579f812406 docs: restore selftest count contract 2026-09-15 10:23:33 +02:00
NilsBriggen 08c998c216 fix: satisfy release gate clippy policy 2026-09-15 10:19:41 +02:00
NilsBriggen cca037d937 style: format acceptance gate changes 2026-09-15 10:18:24 +02:00
NilsBriggen 1468a774c6 docs: record phased release verification 2026-09-15 10:17:03 +02:00
NilsBriggen ff210cd5e4 docs: record AppImage certification 2026-09-15 10:12:35 +02:00
NilsBriggen 2d3169838c fix: harden AppImage certification checks 2026-09-15 10:00:14 +02:00
NilsBriggen 0fb96da266 release: add reproducible VernierCAD AppImage packaging 2026-09-15 09:46:39 +02:00
NilsBriggen 9eae00278f build: vendor OCCT for static releases 2026-09-15 09:21:25 +02:00
NilsBriggen 3370872e66 build: document C++ warnings with sanitizer evidence 2026-09-15 08:53:28 +02:00
NilsBriggen 064e6b7606 ci: align acceptance with the local driven gate 2026-09-15 08:41:08 +02:00
NilsBriggen 582ee82ed7 perf: measure representative modeling workflows 2026-09-15 08:13:49 +02:00
NilsBriggen 069660ca9f test: gate L3 rod holder and historical edits 2026-09-15 07:39:42 +02:00
NilsBriggen 64cb55e5cd feat: loft exact spline sections with history naming 2026-09-15 05:52:03 +02:00
NilsBriggen 2c33a63664 feat: sweep closed cubic spline profiles 2026-09-15 04:40:34 +02:00
NilsBriggen a32e5398cc feat: preview and edit spline sweeps in the shell 2026-09-15 02:52:32 +02:00
NilsBriggen 5750792e19 feat: sweep exact profiles along spline paths 2026-09-14 22:54:54 +02:00
NilsBriggen 1fffed1ddd fix: restore saved views and sections atomically 2026-09-14 21:59:44 +02:00
NilsBriggen 1105adc3cd fix: refuse unsupported imported geometry edits early 2026-09-14 19:34:01 +02:00
NilsBriggen d0cadf0f69 fix: make previews generation-safe and disposable 2026-09-14 14:30:35 +02:00
NilsBriggen c6856c1fa7 docs: reconcile phased execution plan 2026-09-14 13:14:04 +02:00
NilsBriggen 584bf303e9 docs: set daily reliability and spline roadmap 2026-09-14 13:04:26 +02:00
NilsBriggen c111f85692 fix: repair and accelerate full gate 2026-09-14 12:18:45 +02:00
NilsBriggen 5c52b79d32 fix(app): close audit findings and speed up checks
ci / check (push) Failing after 5s
Harden save overwrite handling, make disjoint join intent explicit, improve command reachability and feedback, and add focused driven regressions.

Add the two-and-a-half-minute fast gate plus the expanded audit report and captured evidence.

Agent: Codex
2026-09-14 10:17:19 +02:00
NilsBriggenandClaude Opus 5 bcd7c29355 fix(ui,app): batch 3 of the GUI audit — routes and words
Sixteen findings: where a pick sends you, what the ribbon can show at a given
width, and what the shell says after it acts.

CL-08, the headline: the collapse plan kept an expanded PREFIX of groups, so
one group the row could not afford collapsed every group behind it — at 1280
the Solid tab was seven chevrons with neither sketch nor extrude visible
anywhere. It is now a greedy that skips a group it cannot afford and keeps
spending, priced in pixels per command revealed rather than pixels; that
pricing was measured, because ranking on bare cost hid the Sketch tab's
seventeen constraint tiles to buy one button. Solid's create group declares
sketch and extrude essential and the row paints them ahead of its chevron
wherever it can afford them. At 1600 the tab also paints push/pull, draft,
join, cut and intersect — five buttons the prefix rule had hidden all along.

FC-01, the root of the reported fillet complaint: picking an edge followed
the tab to Solid, which has no fillet or chamfer button on it, so the gesture
a person makes to fillet an edge landed them where they could not. Edge
finishing routes to Modify now.

Also: a pinned tab lets go when the mode changes; a picked face can become
its body; Delete and Backspace reach the delete routes that already existed;
a refusal survives the next click and "geometry has not been rebuilt" goes
when the rebuild arrives instead of standing while the block is rendered,
picked and exported; history refusals stop speaking in internal ids; Fit pick
frames the picked face; a profile keeps its holes, so a washer is one extrude
again; a region pick needs an open sketch; one crossing curve no longer
erases every other region; the pill counts the picked region; a ready ribbon
button carries its own needs sentence; and the status strip leads with a
count and the newest warning rather than the oldest truncated.

Fourteen new gate scripts, each red at aad1d5f with a message naming its
defect. 120 drive scripts, 114 exit 0 — no regressions against the same set.

One batch-2 gate was re-anchored: roomy-status-line-fits used the readout
sentence as its middle column and HV-03 now clears that sentence. It asserts
the readout is empty instead, and was re-checked by mutation to still catch
R2A-04. Three ribbon tests moved from 1200 px to 1040 px because CL-08 paints
sketch on the row at 1200; each asserts its own premise, which is how they
caught it, and each keeps that self-check.

docs/FIXES_2026-09-13_audit-batch-3.md records what was left and why.

Agent: claude-opus-5
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-13 13:04:44 +02:00
NilsBriggenandClaude Opus 5 aad1d5fb89 fix(ui): batch 2 of the GUI audit — covering and layout, plus SF-03
Sixteen findings: the whole of batch 2 (the audit's answer to "the UI
sometimes covers itself") and SF-03, which belonged to batch 1 — the audit
lists twelve findings there and f86b74a landed eleven.

SF-03: a plain timeline click now drops a picked body edge or vertex as well
as the face, curve, point and dimension picks. It used to hold two selections
at once — the row lit while the chip read "1 edge" and the ribbon offered
fillet — so the next Enter put a 1 mm fillet on an edge the user believed
they had dropped. It also clears picked_chain, which means nothing without
the edge list and would otherwise make the next single-edge pick read as a
chain.

The card (value_card.rs): its height is bounded, not only its top, and its
body scrolls — a 553 px thin-wall editor climbed 53 px into the ribbon and
covered the status line, the only place a refusal is explained. It is placed
clear of the gizmo handle's reach, so a drag on the handle is no longer taken
by the card. It is withheld while a drawing tool is armed, so draw clicks
reach the sketch, and Cancel keeps it away. A picked body no longer floats a
section card, and the hole card's Enter hint takes its own row rather than
painting over the last chip.

The chrome (mod.rs, view_controls.rs): the View panel's "relocate below the
card" rule had never once run — show() reset the rect the panel reads before
the card, which paints last, could write it; the rect now ages by one frame.
The viewport chip is non-interactable, so it stops eating the Text and Emboss
buttons underneath it. The title bar measures its right-hand group before
laying out the pills, so "sketching · esc leaves" no longer paints under
"settings".

The ribbon (ribbon.rs, sketch_mode.rs, theme.rs): the readout chip is
reserved last and spent first, so it can never be painted over the commands;
the armed sketch tool is a floor rather than a member of the leading prefix,
so it is always visible; the palette dodges the View panel's measured rect;
and the status band's height follows the density, which stops "roomy"
clipping the status line in half.

The windows (six openers) open inside the viewport and stay there, and the
timeline column is one scroll area, so the feature rows always have height.

Two goldens moved and both were read as images before regenerating:
ux-live-line.png in the title bar only (3537 px; viewport, ribbon, tabs,
history and status pixel-identical) and m1-smoke.png in a 242x107 region
where the card moved off the gizmo handle.

Two tests changed because this batch removed their premise, not to make them
pass: the busy-barrier test arms Select (SketchTool::default() is Line, and a
closed profile now withholds its editor while a drawing tool is armed), and
the m5 negative control re-pins its step index 144 -> 148. Twenty-two
committed scripts gained an "arm Select" step for the same reason; nothing
was removed from any of them.

106 drive scripts, 101 exit 0 — the five that do not are the four negative
controls and planar-lettering, the same five as before this batch measured
against the same script set at f86b74a. Every gate was re-verified red with
its own file reverted. docs/FIXES_2026-09-11_audit-batch-2.md has the
measurements, what was left, and the pre-existing failures this does not
take credit for.

Agent: claude-opus-5
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 19:41:02 +02:00
NilsBriggenandClaude Opus 5 2cecd64baf feat(drive): expect_rect — the instrument the covering findings need
Every expectation the driver has reads the shell's STATE. A covering defect
leaves the state entirely correct and puts the wrong pixels on screen, so
`expect_readout` passes over a sentence painted underneath the value card
and `expect_feature_count` passes over a timeline whose rows have no
height. That is why the 2026-09-10 audit could only reproduce its
covering findings by dumping rects and reading screenshots by eye — there
was nothing to gate them with.

expect_rect asserts the geometry directly: `of` a rect ref, `within`
another, `clear_of` another. The refs are things the harness already
measures for its own reasons — the card's area, the painted galleys, the
ribbon band a `ribbon:` target is looked up in — plus the viewport, which
the shell now publishes beside value_card_rect for the same instrumentation
reason. Touching is not covering: overlap needs half a pixel in both axes,
because galley bounds are inclusive and neighbouring labels abut.

Measured on the unfixed build, the CL-03 case the audit reported by hand:
  the value card at [[552 87] - [778.2 640]] overlaps the ribbon band at
  [[0 74] - [1000 140]] by 226.2 x 53.0 px

Agent: claude-opus-5
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 17:55:14 +02:00
NilsBriggenandClaude Opus 5 f86b74a059 fix(ui,app,occt): batch 1 of the GUI audit — the five P1s and the P2s that share their causes
Eleven findings from docs/GUI_AUDIT_2026-09-10.md, each proved by driving the real
shell rather than by a unit test alone. That distinction is the point: three of these
first landed with passing egui tests and did nothing at all in the app, because the
tests asked a question the shell never asks.

THE VALUE CARD COULD NOT SEE WHO OWNED THE KEYBOARD (HV-01, R2B-01, R2B-05). egui's
single-line TextEdit surrenders focus the instant it reads an Enter, and the card is
painted last so it floats — so the card asked who was focused, was told "nobody", and
committed a keystroke meant for the Variables field, the title-bar path box or the
Items new-folder field. shell::show now records focus once before any widget paints,
and the card takes Enter only when neither that snapshot nor the live answer names an
id the card did not paint itself. It is additionally deaf while the discard prompt
stands.

A TYPED EXPRESSION NEVER CARRIED ITS UNIT INTO THE DOCUMENT (R2A-02). A field whose
text is not a bare number is stored as text and re-evaluated by the server at a bare
scale of 1.0, so in inches the card computed 25.4 mm for "0.5+0.5" and the document
computed 1.0 mm from the same string, for ever. The stored text now says what the
field meant, and the rewrite is verified by evaluation rather than trusted.

OCCT WRITES ONE ASSEMBLY ROW PER EDGE OF THE ASSEMBLY TREE (MB-01). The determinism
guard compared those rows against the body count; the audit proposed the leaf-solid
count; both are wrong, measured. A second defect fired first: the product-name
normaliser accepted one positional level and refused two, which is what a sub-assembly
writes. STEP export of a compound body beside another body works again and is still
byte-identical across two exports.

Also: a delete no longer leaves a stale pending point that kills every later drawing
click (STC-02); a bare second Enter after a dispatch does nothing (PV-07); a typed
value outside a descriptor's range is refused by name instead of silently clamped to
0.001 (SF-07, FC-05, SB-10); a zero-length push/pull is refused at the card instead of
by the kernel (DISC-08); Escape out of a Create session disarms its Cut target (SF-01);
undo during a compile is refused with a readout instead of silently undoing the
operation being built (SF-10); and an export onto any document's storage name is
refused by shape rather than only against the open document (FPR-06).

Five drive scripts are promoted into the gate, each mutation-checked against the
pre-fix binary. What this batch deliberately leaves undone, and three pre-existing
failures it is careful not to claim credit for, are in
docs/FIXES_2026-09-11_audit-batch-1.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 09:10:27 +02:00
NilsBriggenandClaude Fable 5.1 688279d09f docs(audit): the 2026-09-10 driven-GUI audit of 4dcbd33 — 242 verified findings, five complaints answered, fix order
Nineteen probe cells (thirteen from the coverage matrix, six from a completeness
critic) drove the merged shell headlessly through vernier-drive on RADV, wrote
750 probe scripts, and returned 277 findings. Thirty duplicates were merged and
every remaining finding was handed to an independent verifier that re-examined
the screenshots and dumps, read the cited code, and re-ran the script when the
evidence did not settle the claim: 5 P1, 123 P2 and 87 P3 findings stand, 24
behaviours are recorded as deliberate design that still trips a new user, and
3 reports were rejected as harness artefacts. Every finding's script was also
re-run mechanically and compared with the original report. The probe corpus,
run directories and screenshots stay under target/audit-2026-09-10/claude/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 22:57:10 +02:00
NilsBriggenandClaude Fable 5.1 4dcbd33315 docs(release): record the 2026-09-10 local install of 8dfd8a4
The merged tree installed as 0.0.2-alpha through scripts/install-local.sh,
with the unmanaged ux-feedback copy that had been sitting under current set
aside and previous kept at 1beb15d.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 11:32:09 +02:00
NilsBriggenandClaude Fable 5.1 8dfd8a4309 Merge main into the reliability branch: port the UX work, repair the gate
Merges c0d74cb (the 2026-09-08 audit docs and Codex's UX commit: live sketch
drawing preview, gamma-space UI compositing, HiDPI viewport scale, gizmo axis
latch, tab-pin release) onto the reliability branch's structure, and repairs
what the branch's own drive suite had been silently failing since the
mechanical-modelling batches. docs/MERGE_2026-09-10_main-into-reliability.md
is the full record; the short form:

Ported: DrawingState (serialised across the process codec, snapping with the
click's own camera-derived radius, None under Alt), gamma-space compositing in
the window and the offscreen harness, the HiDPI scale, the axis latch, the tab
pin, distance_mm at 0, main's headless and shell tests.

Dropped: Edit::ReplacePushPull (the branch's acknowledgement barrier already
makes a preview replacement atomic) and the rule hiding the extrude card when
a profile closes (sixty accepted steps type into the branch's editor card,
which sits bottom-right; an open UX question for the audit).

Fixed, each measured through the harness first:
- every value card shares one egui Area id, so a card that changed size was
  placed with the previous card's height and jumped 25 px a frame later; a
  click aimed from that frame missed the field and the typed number was lost,
  and an Enter with no focused field ended the sketch. The card redoes its
  frame (quiet frames only) and the driver waits for a stable rect.
- a picked line floated the extrude editor instead of its length card:
  extrude is Ready for a line and registered before length. Demoted for
  dimension selections only.
- hiding a body, undoing metadata or previewing a boolean sent a support-face
  list the face metadata contradicted; the codec abandons the worker on that.
  Built from one source and aligned at the reply exit.
- a boss drawn on a face after a cut went into the body: the card's defaults
  kept the cut's direction. Defaults keep numbers, not modes.
- the shell-thickness card painted no field: the thin-wall row rule matched
  every "thickness" key.
- the derived extrude editor floated for picked sets no profile route accepts
  (a construction curve, a degenerate pair); it now floats only for a set the
  closed or thin-wall route takes, a ribbon press still aims it.
- thirteen tests the batches had left stale (one-field extrude cards, the
  arc's offers, the role count, the clipped-row message, the README's check
  count, the hole refusal's layer) repaired to the batches' own behaviour.
- seven scripts asserted document format 35 (the code is at 40), two asserted
  a pre-extents extrude payload; all five PNG goldens regenerated on RADV.

Gate: 81 of 86 drive scripts pass on RADV, all 81 deterministic across two
processes; the other five are the four negative controls at their designed
steps and the unfinished planar-lettering (batch 5, still unregistered).
Workspace tests, clippy and fmt green.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 11:30:38 +02:00
NilsBriggenandClaude Fable 5.1 29dcdf671a feat(doc,ui,app): planar emboss/engrave of sketch text (batch 5, in flight)
Commits the uncommitted batch 5 of the mechanical-modelling programme as it
stood at 2026-09-09 23:16: an Emboss feature over authored sketch text with
height/depth, one target, one Apply/Undo, its document command, compile arm
and shell card, plus the planar-lettering drive script. The batch builds, its
two focused document tests pass, and the drive script is not yet registered
in scripts/check.fish; the merged gate decides whether it is.

Recorded here so the merge of main into this branch starts from a committed
tree rather than a dirty one.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-10 09:30:53 +02:00