Row order is RATIFIED (charter 4.1, 2026-07-31) and this is the first working implementation of it: right-click in the Design viewport and a vertical list opens at the pointer with the eight families in their fixed order, the verbs that apply live, and the ones that do not disabled IN PLACE carrying their reason. THE MAP EXISTS ONCE. DesignOffer.hpp is GENERATED from docs/ux/tool_atlas.json by docs/ux/mockups/gen_offer_table.py — the same file the 113 mockups are drawn from. A drawing and the product therefore cannot drift apart, which is the only way row constancy survives contact with a codebase. Never hand-edit the header. NOTHING IS RE-IMPLEMENTED. Each row routes to the code that already runs that verb: "key:S+E" through m_keys_feature, "key:L" through m_keys_sketch, "fly:material#4" through the feature flyout's own action, "btn:colour" through the standalone button. The offer is a second door onto the same room, so the toolbar, the shortcuts and the menu cannot drift into three behaviours. The 8 verbs with kernel support but no GUI path show disabled, which is honest and matches section 10 of the charter. Right-click only fires the offer when the canvas is IDLE. Right-click already ends a polyline chain and finishes the move gizmo; taking those over would break two working interactions to add a third. Two things the running build corrected, both found by looking at screenshots: - THE REASON MUST BE TRUE FOR WHAT IS IN FRONT OF THE USER. Taking the first refusal in a family printed "Transform needs a body — add or import one first" on a document that HAS a body, because the real obstacle was that nothing was selected. Now the reason comes from a verb that accepts the current selection and fails only on document state; if no verb in the family accepts this selection at all, it says "select something first" or says nothing. A menu whose whole value is telling the truth cannot ship a lie. - Classification follows the level the pick cycle has REACHED, not the face the ray happened to hit, so the header cannot name a face while the whole body is lit. Sketching on the face you merely clicked is untouched — that path is sketch_plane_from_selection (snaporca-3a2). Verified on :11 end to end: nothing selected shows Sketch live with Shift+S and seven greyed rows each explaining itself; a selected solid shows Move directly with Shift+Y (one applicable verb, so no submenu and no extra click) and five families as submenus. Both forks compile and link. Fork parity re-checked after the port: DesignPanel.cpp 30 divergent lines, DesignCanvas.cpp 16, every other CAD file byte-identical — the invariant exactly. snaporca-96r.
38 KiB
Orca-CAD — UX guidelines and design charter
Status: proposed, v1. Owner: design working group. Applies to the Design tab — the parametric CAD environment inside OrcaSlicer.
This document is a review instrument, not an essay. Sections 3–9 are written so that a reviewer can hold a pull request against them and get a yes or a no. If a rule here cannot be failed, it is badly written and should be rewritten.
1. Why this exists
A CAD tool acquires its interface by accretion. Every feature arrives needing "just one more field", the side panel is the cheapest place to put it, and after forty features the product is FreeCAD: complete, respected, and abandoned by almost everyone who opens it once. That end state is not a failure of any single decision. It is the sum of forty locally reasonable ones taken without a written rule to violate.
So we write the rule down first, and we make additions argue against it.
2. Product thesis
Orca-CAD is a modelling space for people who want a part, inside the tool that prints it.
Three audiences, one interface:
- The fourteen-year-old on a school laptop. Free software, on the machine they already have, with no account, no subscription, no licence and no tutorial. They open the tab because they want a bracket for a bike light, and an hour later it is printing. This is not the charity case at the bottom of the list — it is the reason the project is worth doing. A CAD tool that only the equipped can run is a tool for people who were already going to design something; this one has to be a creative instrument in the hands of someone who did not yet know they could make things. Everything in §6.1 exists to keep that door open, and nothing gets to close it for the convenience of the other two audiences.
- The maker who has an idea and a printer, and who has bounced off FreeCAD. They should be modelling something real within ten minutes of first opening the tab, without a tutorial, without knowing the word "constraint".
- The mechanical designer who needs assemblies, mates, exploded views, variables, and a feature history they can edit six months later. They should not have to leave for SolidWorks the moment the work gets serious.
The order matters. When a decision helps one audience and hurts another, the earlier one wins unless there is a written argument for why not.
The reference for how it feels is Shapr3D: direct, gestural, quiet, almost no chrome, depth revealed by what you touch rather than by what is on screen. The anti-references are Blender (a modal keyboard language you must learn before the first success) and FreeCAD (a workbench-and-dialog architecture where the geometry is a preview of a form you fill in elsewhere).
We are not cloning Shapr3D's feature set. We are adopting its interaction economy: the smallest number of visible controls that still makes an expert fast.
And one thing neither reference has: Orca-CAD lives inside a slicer. The plate, the nozzle, the material and the print constraints are known to the application at design time. Designing for print is not a plugin here, it is the home advantage. Where a rule below trades generality for print-awareness, it trades in favour of print-awareness.
3. The laws
Non-negotiable. A change that breaks one of these does not get merged on the grounds that it was easier, that the alternative is more work, or that another CAD does it that way. Each law carries a test — the question a reviewer asks.
L1 — Geometry first: you point, then you act
Controls live on the geometry: handles, arrows, points, small circles and boxes, with an inline label tab for typed values. Not in a side panel of combos and spin fields.
The canonical gesture: select a face or plane in the viewport, then click the sketch tool. Never: click the sketch tool, then choose a plane from a list. The tool consumes what you pointed at — and, better still, the thing you pointed at offers the tool itself (§4).
Test. Can the operation be performed start to finish without the pointer leaving the viewport, except to press the tool itself? If a control had to be added to a panel to make it work, the design is not finished.
This is the law the others serve. It was stated after two proposals in a row reached for a dropdown, and the failure mode it names is real and recurrent: a fix that "adds a row to the plane combo" is the side-panel pattern wearing a different hat.
L2 — Everything draggable is typable, and everything typable is draggable
Any value produced by direct manipulation (a fillet radius, an extrude depth, a pattern spacing, a plane offset) shows a live label on the geometry, and that label is an editable field. Any value entered numerically has a corresponding handle in the viewport.
Dragging is for finding the answer. Typing is for committing to it. A tool that offers only one of the two is half a tool.
Test. Point at the number the tool produces. Can you drag it? Can you click it and type? Both must be yes.
L3 — Noun then verb, always the same way round
Selection precedes action, without exception, across sketch tools, features, dress-up, booleans and mates. There is no tool in the product that is armed first and asks for its input afterwards.
Test. Does this tool work if the user has already selected the thing they want it applied to? Does it work only that way?
L4 — No modal dialog in the modelling loop
Dialogs belong to document-level actions: open, save, import, export, preferences. Modelling never opens one. A feature that needs three values gets three labels on the geometry, not a form; a feature that needs confirming gets a ghost preview and a confirm/cancel puck in the scene beside it (§4.2) — an object, not a window: the camera still orbits, the values are still editable, nothing is blocked.
Test. Between starting an operation and seeing its result, does a window appear that must be dismissed? If yes, redesign.
L5 — One click, one visible change
Every click either changes what is on screen or tells the user why it did not. A click that opens something invisible, arms an invisible state, or requires a second identical click to have any effect is a defect, not a design.
This law exists because we shipped its violation twice. Sketch-tool family buttons were flyouts whose first click only rendered a pressed state — three separate sessions filed bugs against tools that were working. Solid picking used a click cycle (first click selects the body, second refines to the face), so sketching on a face appeared broken to anyone who clicked a face once, the way every human does.
Test. Perform the gesture exactly once, as a first-time user would. Take a screenshot. Is the state visibly different, and is the difference the one the user intended?
L6 — The default is the answer four times out of five
Every option that has a default must have the common answer as its default, measured against real parts, not against generality. "New body" as the default result of an extrude is wrong: most extrudes join. Radius as the input for a circle is wrong: drawings give diameter.
Test. Take ten real parts. In how many is the default correct? Below eight, change the default or infer it from context.
L7 — Errors are caught before the commit, in the user's words
A self-intersecting profile, a cut that removes no material, a wall thinner than the nozzle: these are reported at the moment they become knowable, on the geometry that is wrong, phrased as what happened and what to do — not as a kernel exception after the fact, and never silently.
Test. Is the failure detectable before the user commits? Then it must be reported before the user commits. Read the message aloud: does it name a thing the user can see and an action they can take?
L8 — The camera is the application's job
Selecting a sketch plane orients the view to it. Committing a feature does not throw the camera away. Zoom-to-fit exists and is one keystroke. The user is never required to fight the view in order to reach the geometry, and orbit is bound to the gesture people actually try.
Test. Count camera manipulations in a representative modelling session. Any camera action the application could have performed for the user is a bug.
L9 — Accessible by construction, not by retrofit
The floor, applied to every new interaction (details in §6.2): full keyboard reach, no meaning carried by colour alone, hit targets that survive a shaky hand and a HiDPI screen, legible labels over an arbitrary 3D background, no gesture that depends on timing.
Test. Drive the whole interaction from the keyboard. Then drive it in greyscale. Both must work.
L10 — Vocabulary from the drawing office
Names come from the language of people who make parts: fillet, chamfer, boss, rib, counterbore, mate, exploded view. Not from the kernel (no "boolean subtract", no "B-rep"), not from invented product-speak. Where the drawing-office word and the beginner's word differ, use the drawing-office word and make the tooltip teach it — an approachable tool that leaves the user unable to talk to a machinist has failed them.
Test. Would a shop-floor engineer recognise this word? Would a first-time user be able to look it up and find a real definition?
L11 — The floor is a school laptop, and nothing is behind a door
The product runs, completely, on a low-end laptop with integrated graphics and a small screen, offline, with no account, no subscription and no feature withheld. No capability in this document is reserved for a paid tier, a cloud service, a plugin, or a machine with a discrete GPU — there is one product and everybody gets all of it.
Test. On the reference low-end machine (§6.1), at 1366×768, with the network cable pulled and no account ever created: does this feature work, and is it usable at an honest frame rate? Any "no" is a defect, not a limitation.
4. Interaction grammar — object-driven
The rules above compose into one sentence the whole product obeys:
Point at geometry → the geometry offers what can be done to it → choose the tool → manipulate handles and type exact values → confirm or cancel.
The selection does not merely feed the tool. The selection determines which tools exist. Pick a planar face and the product shows you the small set of things a planar face can become — sketch on it, extrude it, hole it, shell it, put a datum on it. Pick an edge and that set is fillet, chamfer, and the sketch tools that can use it as a reference. Nothing else is offered, because nothing else is possible.
This is the single largest thing we can do for a first-time user, and it is worth stating as the reason: a beginner's difficulty is not operating a tool, it is not knowing which tools apply to what they are looking at. A palette of sixty icons answers a question they cannot yet ask. A face that offers its own five verbs teaches the model of the product by using it. It also removes an entire class of failure — a tool that silently does nothing because the selection was wrong can no longer be reached.
4.1 The offer, and the one thing that makes it work
The flow, in full:
left-click the geometry to select it → right-click to open the offer → a vertical list, always in the same order, each row an icon, a name and its keyboard shortcut → click.
- Selecting and acting are separate gestures. Left-click only ever selects, so pointing at things is quiet — nothing pops up while you look around. Right-click on the selection opens the offer, at the pointer, over the geometry it acts on.
- Order is fixed and it is the whole point. A verb occupies one permanent row, and that row is the same in every selection where the verb appears. Dress-up is the fourth row on an edge, on a face, on a body, on the day the product ships and two years later. The hand learns the position; the eye stops being needed.
- What does not apply is DISABLED IN PLACE, never removed. This is the single strongest thing the list does, and it is why it beat the radial we drew first: a greyed row still carries its name and the reason it is grey — "Create a sketch, or pick a solid face, first", "Create a solid body to pattern first" — in the words the product already ships. On a first-run document the offer is therefore not a mostly-empty control but a map of what the product does and what you have to do first.
- It is an accelerator, not a toll gate. The toolbar and the single-letter shortcuts keep working exactly as they do now, and pressing a tool directly consumes the same selection (L3). An expert never has to open the offer; a beginner never has to know the toolbar exists. Both routes land in the same place — this is the only way one interface serves §2's three audiences.
- Every row shows its keyboard shortcut, right-aligned so the keys stack into a column the eye learns without trying, beside the icon and the drawing-office word (L10). This is deliberate: the offer is the path by which a user stops needing the offer. You reach for fillet in its row, the row says "F", and one day your hand types F before the menu has finished opening. A menu that teaches its own shortcut is how a beginner becomes the power user who never opens it — the same interface at two speeds, with no "advanced mode" between them (§7).
- A family with more than one applicable verb opens a submenu to the side, in its own fixed order. A family with exactly one shows that verb directly, so the common path is never one click longer than it needs to be.
- It never blocks the view of what it acts on: it opens beside the pick, never over it, with a thin leader back to the point it belongs to, and it dismisses the moment the selection changes.
- The header names what is selected ("Top face · Body 1"), because a user who mis-picked should find that out before choosing a verb, not after.
Opening the offer on every machine
Right-click is the primary gesture and every platform must have a first-class equivalent — this is a reach requirement (L11), not a nicety:
| Input | Gesture |
|---|---|
| Two-button mouse | right-click |
| Trackpad | two-finger tap (the OS-standard secondary click) |
| macOS, one-button mouse | long-press, and Ctrl-click, which is the platform convention |
| Keyboard | the Menu key, or Shift+F10, on the current selection |
| Touch / pen | long-press |
The long-press is an additional route, never the only one — §6.2 forbids press-and-hold as a sole path to a function, and it stays forbidden. Every opening gesture is reachable at least two ways on every platform, and the keyboard route exists everywhere. A long-press must show that it is charging (a growing ring under the finger) so a user who holds too briefly learns why nothing happened rather than concluding the product is broken (L5).
The row-constancy invariant
This is the rule that has to survive every future feature, so it is written as an invariant rather than as advice:
Every verb has exactly one row index in the offer. That index is identical for every selection type in which the verb appears. Verbs that do not apply to the current selection are DISABLED IN PLACE, with their reason — the offer is never compacted, re-sorted or re-ordered. Adding a verb never changes the index of an existing one.
Two consequences the group must accept together with the invariant:
- No adaptive ordering. Ever. Not most-used-first, not recently-used-first, not per-selection frequency. An offer that rearranges itself to be helpful destroys the only thing that made it fast, and it does so precisely for the user who has just started to learn it. (Office 2000's adaptive menus are the textbook case; they were removed.)
- Greyed rows are the price, and they are cheap. A compacted menu is shorter and unlearnable. A constant one is a few rows longer, teaches while it waits, and is memorised in a week.
The map — RATIFIED 2026-07-31
The invariant is not negotiable, and as of 2026-07-31 neither is the assignment: the row order below is ratified. It was argued once; it is not argued again. Changing an index from here on is a breaking change to every user's muscle memory and needs the group, not a pull request (§9 q12).
Eight families, ordered so the sequence itself has a logic: material is created, grows, is taken away, is refined, is repeated, is moved, is referred to, is edited.
| Row | Family | On a face | On an edge | On a body | On text/art |
|---|---|---|---|---|---|
| 1 | Create | Sketch on it | — | — | Edit text |
| 2 | Add material | Extrude, thicken | — | Combine, thicken | Extrude |
| 3 | Remove | Hole, shell | Thread | Shell, cut, split | — |
| 4 | Dress-up | Draft | Fillet, chamfer | Fillet, chamfer | — |
| 5 | Repeat | Pattern | Pattern along it | Pattern, mirror | Pattern |
| 6 | Transform | Align to, mate | — | Move, mate | Move, size |
| 7 | Reference | Plane, axis, measure | Axis, measure | Project, measure, mass | — |
| 8 | Modify | Delete face, edit | — | Edit, colour, delete | Replace art |
A dash means the row is drawn greyed for that selection, with its reason.
The authoritative version of this table is docs/ux/tool_atlas.json, which
carries all 52 verbs with their preconditions and their refusal strings, taken
from the code rather than from memory. Every state it produces — 20 selection
kinds × 2 document states, 40 primary menus and 73 submenus — is rendered by
docs/ux/mockups/gen_offer_mockups.py into docs/ux/offer_atlas.html. Read the
atlas before proposing a change to the map; the generator refuses to render an
address collision, so the map cannot silently rot.
Rejected: the radial ring
The first design put the eight families at eight compass points around the pick. It is recorded here because it is a good idea that loses on evidence, and someone will propose it again:
- an inapplicable slot could only be drawn empty, and an empty slot says nothing — the reason text above has nowhere to live;
- the measured fill was 3.45 of 8 slots, so most of the control was blank most of the time, and on a fresh document only two of eight were live;
- sketch-mode Create needs nine addresses; eight forced two primitives behind a "More" slot, and a ninth position costs the 45° spacing that made the ring worth having;
- long translated names do not fit around a circle, and screen readers and arrow keys need bespoke handling a list gets for free;
- a 380 px disc over the model costs more on a 1366×768 screen than a 324 px list beside it (§6.1).
What it kept — equidistant targets and a future flick gesture — buys little in a product whose experts live on the keyboard by design.
4.2 Confirm and cancel are objects, not gestures
The old rule — click empty space to commit — is withdrawn. It was an invisible gesture with a destructive meaning: nothing on screen said it, and a stray click committed a feature the user was still adjusting. That is exactly what L5 forbids, and it is hostile to the audience §6.1 exists for.
- A pending feature carries a confirm/cancel puck, attached to the geometry it is editing, next to its handles: ✓ commits, ✗ discards. Enter and Escape mirror them for the keyboard (L9). It is drawn where the user's attention already is, and it is the only thing in the viewport that commits.
- Empty space now means "clear the selection" — the safe meaning, and the same meaning everywhere.
- This is not a dialog (L4). It is two objects in the scene, on the geometry, non-modal: the camera still orbits, the tree is still there, the values are still editable while it waits.
- Continuous tools do not ask. Drawing a line, a rectangle, a circle commits each entity as its own gesture completes — a ✓ per line would destroy the inner loop. The puck belongs to features (extrude, fillet, hole, pattern, mate) and to sketch edits that hold a pending state. Enter/Escape end a continuous tool rather than confirming an entity.
- Ambiguity resolves toward keeping work, never toward losing it. Starting another operation while a valid feature is pending commits it rather than discarding it; if it is not valid, the product says why (L7) and keeps it pending. Since undo reaches everything (§6.1), the recoverable direction is always the right default.
4.3 The rest of the grammar
- The status line is one imperative sentence naming what the tool wants next, and it names the target when the target came from a selection ("Circle — click centre, then radius · on the picked face"). It is the authoritative feedback surface for the armed tool; the toolbar is not.
- Hover previews, click commits. A hover shows the ghost of what a click would do wherever this is cheap to compute.
- Selection is persistent and visible until consumed or cleared. A tool that consumes a selection clears it, so the next feature cannot silently inherit it.
- Every gesture is undoable, and the feature tree is editable history, not a log. Re-editing a feature re-enters the same on-geometry interaction that created it — including its offer and its puck.
5. Layout and screen budget
The viewport is the application. Chrome is a tax on it.
- One toolbar, contextual to the mode (model / sketch). Tools are grouped by what they make, not by which subsystem implements them.
- A left rail for the document, not for parameters: feature tree, bodies, variables. It answers "what exists", never "what value should this be".
- No parameter panel. Where one exists today it is technical debt with a scheduled removal (§10).
- Print context is ambient, not a panel: the plate is visible in the design space, and print-domain warnings appear on the geometry that will fail.
- Nothing is added to permanent chrome without removing something, or demonstrating that the addition is used in the majority of sessions.
- The budget is set by the smallest screen we serve, 1366×768 (§6.1) — not by the reviewer's monitor. Chrome that fits a 27-inch display and swallows a laptop's has not fitted, it has just failed somewhere the author cannot see.
6. Accessibility — reach first, then the assistive floor
"Accessible" means two different things and the product owes both. §6.1 is about who can get in at all; §6.2 is about who can operate it once inside. Neither is a phase. Both are merge requirements.
6.1 Reach — the door has to be open
The premise of the whole project: someone with no money, no licence, no account, no fast machine and no teacher can open this and make a real thing. Free software on a school laptop is the only path to a CAD tool that reaches people who were never going to be handed one. If a design decision quietly raises the cost of entry, it has broken the premise, however elegant it is.
- The reference machine. A 5-year-old laptop: dual/quad-core CPU, integrated graphics, 8 GB RAM, 1366×768 screen, no discrete GPU. The Design tab must be usable there, and any interaction that needs more is a design failure to be solved, not a requirement to be documented. The GPU path degrades gracefully to software rendering rather than refusing to start; the viewport stays interactive while the kernel thinks.
- 1366×768 is the layout target, not the stretch case. A form-heavy side panel is not merely inelegant on that screen — it takes the model off it. This is the second, independent argument for the whole of L1 and §5.
- No account, no cloud, no connection. The product works forever with the network unplugged. Nothing is uploaded, no sign-in gates any feature, no telemetry is required to use it. A school network that blocks everything must not be able to block this.
- No tier, no plugin wall, no "pro". Every feature named in this document is in the product everyone downloads. Assemblies and exploded views are not the paid half.
- Files belong to the user, on their disk, in a format that outlives the project: the design travels inside the ordinary project file, and the geometry exports to STEP and mesh formats anyone can open.
- Learnable without instruction. The first solid comes with no documentation, no video and no tutorial mode — from noticing that a face can be clicked. Tooltips teach the vocabulary (L10) at the moment it is needed; nothing is explained in a manual the user will never open.
- Plain language at the entry tier. The Make tier speaks in words a thirteen-year-old reads without stopping. Precision comes with the tier that needs it, and everything is translated, because "accessible" in English only is not accessible.
- Exploration must be free. Undo reaches everything, work is never lost to a wrong click, and no dialog ever asks the user to be sure. A tool that punishes experiments teaches people to stop experimenting, which is the one thing this audience cannot afford to learn.
- The product never blames the user. Failures are stated as what happened and what to do (L7). "Invalid input" is not an acceptable sentence anywhere.
6.2 Assistive floor
- Keyboard: every operation reachable and completable without a pointer. Single-letter shortcuts for sketch tools, shown in the offer itself (§4.1) as well as in the tooltip. The offer opens from the keyboard (Menu key or Shift+F10) and walks by arrow key and by type-ahead, so the row map works for someone who never touches the pointer. A visible focus state on every focusable element. No shortcut that only works while the pointer happens to be over the canvas.
- Colour: never the sole carrier of meaning. Selection is colour and outline; an error is colour and an icon and text. Verify in greyscale.
- Contrast: labels over the 3D viewport get a scrim or halo so 4.5:1 holds against any background the model can produce, including a white body under a white plate.
- Targets: handles and grips no smaller than 32 px at 100 % scale, scaling with the OS factor; the grab tolerance is larger than the drawn glyph.
- Timing: no double-click-to-mean-something-else, no press-and-hold as the only route to a function, no cycle that depends on repeated clicks (see L5). The long-press that opens the offer on a one-button Mac and on touch (§4.1) is explicitly an additional route — Ctrl-click, two-finger tap and the keyboard all reach the same place — and it shows its own progress while charging, so it never fails silently.
- Motion: animation is functional (showing where a thing went), never decorative, and it respects the reduced-motion preference.
- Text: no fixed-width assumptions; the UI holds together in German and in Chinese, at 125 % and 200 % scale. Every string routed through the normal translation path.
7. Depth without clutter — the three tiers
Power for experts is delivered by progressive disclosure of tools, never by relocation of tools. A tool that appears in a later tier is in the same place it will always be; it is simply not shown yet.
| Tier | Who | What appears |
|---|---|---|
| Make | first hour | Sketch, extrude, revolve, hole, fillet/chamfer, move, commit to plate |
| Model | competent user | Patterns, shell, draft, sweep/loft, booleans, reference geometry, variables, import/export |
| Mechanism | mechanical designer | Assemblies and mates, exploded views, interference detection, surfaces, feature-level editing of imported solids |
Rules that keep this honest:
- Tiers are non-modal. No mode switch, no workbench selector, no "advanced mode" toggle that changes the meaning of anything. The tier only governs what is offered.
- A tier reveals itself by use. Using a body reveals boolean tools; adding a second body reveals assembly tools. The product notices what you are doing.
- Nothing moves when a tier appears. A user who learned where fillet lives finds it in the same place forever.
- An expert tool obeys the same grammar as a beginner tool. Mates are picked in 3D like everything else, not configured in a table.
- Exploded views are a view state, not a document mode — reversible, draggable along mate axes, and never a separate file.
8. Designing for print — the home advantage
Design-time knowledge the application already has, and must use:
- The plate is present in the design space, at the real size, with the real origin. Committing a body to the plate is one action and preserves placement.
- Print-domain checks run on the model, on the geometry, before slicing: walls thinner than the nozzle, unsupported overhangs beyond the material's angle, features smaller than the layer height, a part that does not fit the build volume.
- These are warnings on the geometry, never a report. The thin wall glows; the tooltip says how thin and what the nozzle is.
- Material and machine context is inherited from the active slicer profile, not re-entered in the Design tab.
- The round trip is preserved: editing a design after slicing returns to the feature history, not to a mesh.
9. The review gate
Every pull request that touches the Design tab UI answers these, in the PR body. A "no" that is not accompanied by an argument is a request for changes.
- Which law (L1–L11) does the change most directly serve?
- Can the whole operation be completed without the pointer leaving the viewport? If not, why is this the exception? And: does the relevant selection offer this tool (§4.1), or must the user already know it exists?
- Are the values draggable and typable?
- Screenshot of the state after exactly one click of the new gesture, performed as a first-time user.
- Keyboard-only walkthrough: does it complete?
- Greyscale screenshot: is every state still distinguishable?
- What was removed? (Net additions to permanent chrome require an argument.)
- Which tier does it belong to, and does it appear without moving anything else?
- What does it do when the geometry is invalid, and is that reported before the commit?
- Interaction cost: actions required for the canonical task it addresses, before and after.
- Reach (L11): screenshot at 1366×768 with the panel open — is the model still on screen? Does it run on integrated graphics? Does it need the network, an account, or a file the user cannot keep?
- If the change adds or moves a verb in the offer: which row, and is it that
verb's row in every selection where it appears? Did any existing verb's
index change? (If yes, this is not a UI change, it is a breaking change to
every user's muscle memory, and it needs the group — see §4.1.) Was
docs/ux/tool_atlas.jsonupdated and the atlas regenerated? - If the change adds a pointer gesture: what is its keyboard equivalent, and what does a one-button Mac, a trackpad and a touch screen do (§4.1)?
10. Where we stand today — honest inventory
Complying with the laws already:
- Sketch inline editors — draw an entity and its dimension tab opens on the geometry; Tab walks Length → Width → Angle.
- Fillet/chamfer draggable radius arrow with an editable value label.
- Extrude depth arrow; move-body three-axis arrows.
- Datum-plane resize handles and offset arrow; ghost reference planes picked in 3D.
- Imported-art place/size gizmo.
- Sketch plane taken from the picked face, with the target named in the status line, and the sketch-plane dropdown deleted outright.
Violating them, with removal scheduled:
- Every tool card is a two-column form of combos and spin fields in the left panel. This is the single largest debt in the product and the reason this document exists. Tracked as an epic; each card is replaced by its on-geometry equivalent, not improved in place. It fails L1 and it fails L11 twice over — on a 1366×768 screen the cards leave the model a strip.
- Seven remaining plane pickers still populate a combo instead of consuming a viewport selection.
- Pattern has no on-geometry spacing arrow or count badge.
- Hole is positioned by X/Y fields rather than by a point on a face.
- Booleans and cuts pick their operands from lists rather than in 3D.
- Fillet/chamfer edge selection still requires the click cycle L5 forbids.
- Selecting geometry offers nothing. There is no contextual offer (§4.1):
the user faces the full toolbar whatever they have picked, and finds out that
a tool did not apply by it doing nothing. This is the largest single item of
new work the charter asks for. The map and every state of it are already
drawn (
docs/ux/offer_atlas.html); what the group owes itself before the code is ratifying the row order, since every verb built before that lands has to be addressed afterwards anyway. - Committing is an invisible click in empty space rather than the confirm/cancel puck of §4.2 — the exact gesture that rule withdraws.
Nothing on the violating list is defended. The only open question for each is what its on-geometry replacement should be.
11. How the group works
Roles. Product/UX lead (owns this document and casts the tie-break vote on interaction questions); kernel maintainer; GUI maintainer; a print-domain reviewer; a mechanical-design reviewer who uses the product on real work; an accessibility reviewer covering both senses of §6 — reach and assistive — who owns the reference machine and actually runs on it. One person may hold more than one role; the UX lead and the mechanical-design reviewer should not be the same person, and nobody reviews reach from a workstation.
The absent audience needs a seat. The fourteen-year-old is not in the room and cannot file an issue. Someone in the group is accountable for B5 and B6, and the group watches real first-timers use the product on the reference machine at least once a quarter — school, makerspace, or a friend's kid. Everything else in this document can be argued from principle; approachability can only be observed.
Cadence. A short weekly review of open interaction proposals. A monthly pass over the violating inventory in §10 — anything that has not moved in two months is either scheduled or explicitly accepted as permanent, with a reason written into this document.
How a change moves.
- Problem — a described user difficulty, ideally with an interaction-cost measurement, never a solution in disguise.
- Sketch — one or two on-geometry interaction proposals, drawn or described as a gesture sequence. Reviewed against §3 before any code.
- Prototype — built behind whatever the smallest safe path is, driven end to end on a real display, and screenshotted at each state.
- Gate — §9 answered in the PR.
- Merge, then update §10.
Decisions are written down. Any resolution that constrains future work is appended to this document as a numbered law or as an accepted exception with its reasoning. A decision that lives only in a call is not a decision.
How disagreements resolve. Against the laws first. If the laws do not decide it, the tie-break is the interaction cost measured on the canonical tasks in §12; if that does not decide it, the UX lead chooses and records why.
12. Canonical tasks — the benchmark
The measure of every UX change is the cost of these five tasks. Each is timed and counted (clicks, keystrokes, camera actions, mode switches) on the headless rig and, periodically, with real users who have not seen the product.
| # | Task | What it exercises |
|---|---|---|
| B1 | Bracket: sketch an L, extrude, two holes, fillet the inside corner, send to plate | The inner loop |
| B2 | Change a hole diameter and the plate thickness, six features deep, and rebuild | Parametric editability |
| B3 | Take an imported STEP, delete a boss, close the face, thicken a wall to nozzle width | Direct editing + print awareness |
| B4 | Two parts, one revolute mate, check interference, produce an exploded view | The Mechanism tier |
| B5 | First-run: from opening the Design tab to a print-ready solid, no documentation | Approachability |
| B6 | B1 again, on the reference machine at 1366×768, offline, on a fresh account-less install | Reach (L11) |
Every task is run on the reference machine of §6.1, not on a workstation — a number measured on a fast desktop describes an experience most of our users will never have. B6 repeats the inner loop under the full entry conditions so that reach is a measured quantity and not an intention.
Targets are set once each task has been measured on the current build. B5's target is expressed in minutes-to-first-solid by someone who has never seen a CAD program, and it is the number this project is ultimately judged by.
Appendix — anti-patterns we have already paid for
Kept because each cost real time and each is easy to reintroduce.
- The dropdown that grew a row. Fixing "cannot sketch on a face" by adding a "Face of Body 1" entry to a plane combo. It reads as a small fix and it is the side-panel architecture reproducing itself.
- The invisible first click. Flyout buttons and pick cycles whose first click changes nothing meaningful. Filed as bugs three separate times against working code, and made a real bug look fixed when it was not.
- The fix verified through a path the user will never take. A face-sketch fix confirmed by double-clicking to reach face level. Users click once. A fix reachable only by an undiscoverable gesture is indistinguishable from no fix.
- The wrong feedback surface. Measuring an armed tool by the toolbar, which never renders keyboard-armed state. The status line is the surface that answers.
- The silent success. A cut that removed no material, reported as done. Now an error naming the likely cause.