Skip to content

SOF-8024: workflow designer UX — review, plan, and portions 1, 3, 6 (plus 4 and 5 started) - #12

Open
timurbazhirov wants to merge 36 commits into
mainfrom
claude/ux-improvements-msn5h2
Open

SOF-8024: workflow designer UX — review, plan, and portions 1, 3, 6 (plus 4 and 5 started)#12
timurbazhirov wants to merge 36 commits into
mainfrom
claude/ux-improvements-msn5h2

Conversation

@timurbazhirov

@timurbazhirov timurbazhirov commented Aug 16, 2026

Copy link
Copy Markdown
Member

Ticket: SOF-8024.

A UX review of the workflow designer, an implementation plan cut into six portions, and the portions that are built. Everything was verified in the standalone demo with Playwright rather than by inspection; each portion document carries its own Status section with what was found and what is still open.

Review and plan

  • docs/ux/README.md — the review: twelve findings (W1–W12), quick-win table, and an After section pointing at captures of what is now built.
  • docs/ux/mockups.html — self-contained interactive mockups A–E.
  • plan/upcoming/2026-08-16-ux-0-overview.md — the main plan document, with a §0 progress table; one detailed document per portion.
  • AGENTS.md — imported conventions, plus local sections on Git LFS and on managing docs/ux assets.

What is built

Portion 1 — quick wins. All ten, here and in wove#12: field labels, undo on removals, tab renames (Units / Settings / Outputs / Compute), dirty tracking, humanized property names, a zoom floor so nodes stay readable.

Portion 3 — Settings tab. Complete. Scoped cards per provider with a "modified" badge and per-group Reset, a sticky unit index with per-unit modified counts, a filter matching titles, unit names, field names and engine keywords (ecutwfc finds Planewave Cutoffs), per-field "default X · reset field", and a compute summary reading "Requests N cores · up to T · queue Q · on <cluster>".

The k-path is now a chain of chips — Γ 10→ X 10→ W — instead of eleven identical rows, with the leg count and the k-point total the array form never showed. The path is drawn inside the Brillouin zone, labelled at each high-symmetry point, and redraws as you edit it.

Portion 6 — add flows. "Add step" opens a library of the 76 standata subworkflows, searchable across step name, application and unit names, with a preview of the exact units to be inserted; pasting JSON survives as a second tab. The unit picker lists described cards instead of raw enum strings.

Portion 5 — shell (started). layoutVariant: "classic" | "studio", defaulting to classic, so every host renders what it renders today until it opts in. The studio shell replaces the duplicated flowchart column with a steps rail (01 · CP-MD · espresso · 1 unit) and stops the panel header repeating the name the rail carries. The shared editing surface moved into WorkflowUnitPanel so the two shells cannot drift.

Portion 4 — input editor (started). The redundant FlowchartId box is gone; ave#8 moves Next into an Advanced section so the dialog opens on the input template.

Bugs found and fixed along the way

  • The Brillouin zone illustration never rendered outside the web app. wove derived /images/brillouin_zone/<lattice>.png, an asset no package ships, at an absolute path that cannot resolve under a non-root base. Fixed by computing the zone from the material's own reciprocal lattice — validated against known polyhedra, and correct where a per-type PNG is not (a graphene monolayer and bulk GaN are both HEX with very different zones).
  • Provider defaults never reach their schemas. esse's applyPatchWithDotNotation silently skips patch paths it cannot resolve, so PlanewaveCutoffDataManager's 40/200 and the whole dependencies block of PointsGridFormDataProvider are dropped. Worked around locally; worth fixing in wode.
  • The step library could not actually insert. Standata stores a subworkflow's application as a {name} stub while its units carry the full record, so wode's validation blanked the designer; and the position argument was inverted against UnitPaste's convention.
  • Two of five points-path providers got no zone (wove's allowlist omitted ipath and explicitKPath2PIBA) — fixed in wove#12.

Unrelated and pre-existing: selecting "Valence Band Offset (2D)" blanks the demo with (unknown path), reproduced with these changes stashed.

What is not built

Portion 2 (design language) is not started: its token definition is unblocked, but adoption waits on confirming the canonical brand palette with design/marketing — the platform says purple #7c5fcd, the marketing site leans dark-navy + green, and success #72E128 fails WCAG AA on white regardless. Portion 5's canvas and inspector, and portion 4's render check and variables panel, remain; both need released wove/ave.

Upstream

made#295 · move#5 · wove#12 · ave#8 · agents#3

Once made and move land, this repo drops its local copy of the zone geometry and renderer.

claude added 7 commits August 15, 2026 21:01
Same exercise as the materials-designer UX pass: current-state captures
from the standalone demo, a W1-W12 issue inventory, five HTML mockups
(shell relayout, Important Settings rebuild, add-unit palette and step
library, input editor, labeled Compute form), quick wins, and phasing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Adds AGENTS.md from mat3ra/agents, introduces the plan/ folder per its
section 6 conventions, and files a phased implementation plan for the
UX review (quick wins, settings/editing depth, shell relayout) with
per-item touchpoints, dependencies, and acceptance criteria. Updates
branch references after the rename to claude/ux-improvements-msn5h2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Splits the single plan into a main overview (WFD-UX-0) and six portion
documents, each independently executable and movable through the plan/
lifecycle. Adds a new design-language portion (WFD-UX-2) grounded in an
audit of the current @mat3ra/cove theme: brand palette confirmation,
semantic and designer-specific tokens (unit types, canvas, states),
a real dark palette, typography roles, and adoption steps replacing the
pinned legacy theme and hardcoded colors.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
…dd LFS attributes

Renames the plan set to sof-8024-ux-<n>-<title>.md per the Jira tracker
SOF-8024, adds created/updated timestamps to each document, updates
cross-links, and introduces .gitattributes tracking raster images with
Git LFS.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
… note

Public repositories reference a private tracker, so ticket keys move out
of filenames into document headers and filenames carry the creation date
instead (yyyy-mm-dd-short-title.md). Adds a docs/ux management section
(self-contained mockups, LFS-tracked captures, refresh workflow) and
syncs AGENTS.md with the updated conventions (LFS rule, docs/ux assets,
plan naming).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
…ty state

SOF-8024 portion 1, local items:
- Label planewave cutoff fields (Wavefunction/Charge density cutoff)
  via provider field labels in importantSettingsFormUtils
- Title the unit dialog with the unit name and type; stop showing the
  flowchartId in the dialog header
- Replace instant unit/subworkflow deletion with snackbar-undo (10 s
  snapshot restore) at both workflow and subworkflow levels
- Rename subworkflow tabs to Units / Settings / Outputs / Compute and
  render the units flowchart above the Details accordion
- Label the compute override switch with behavior text
- Track unsaved changes in the container (post-render baseline, reset
  on save), expose onDirtyChange, surface an Unsaved changes chip in
  the standalone demo

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
@timurbazhirov timurbazhirov changed the title SOF-8024: workflow designer UX review, mockups, and implementation plan SOF-8024: workflow designer UX review, plan, and phase-1 quick wins Aug 16, 2026
claude added 2 commits August 16, 2026 18:08
wove derives /images/brillouin_zone/<lattice>.png from the material and
renders it via an injectable component, but that asset ships in no npm
package — only the web app serves it — so every other consumer showed a
broken image, and the absolute path cannot resolve under a non-root
deployment base.

The lattice type is already known there, so compute the zone instead:
brillouinZoneGeometry builds the first Brillouin zone as the
Wigner-Seitz cell of the reciprocal lattice, and BrillouinZone renders
it as inline SVG. ImportantSettings uses it only as the default when no
component is injected, so hosts with their own artwork are unaffected;
unmodelled lattice types still fall back to the image.

Validated against known crystallography: FCC gives a truncated
octahedron, BCC a rhombic dodecahedron, CUB a cube, HEX a hexagonal
prism, all closed (V - E + F = 2).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The lattice type alone underdetermines the cell: non-cubic systems have
c/a and angle freedom, so the per-type table was standing in
representative ratios. The context provider carries the material, so
read its reciprocal vectors via made's ReciprocalLattice and build the
zone from those instead — a graphene monolayer and bulk GaN are both
HEX but now render with their real proportions.

The per-type table remains only as a fallback for callers with no
material. Records in the plan where this code should actually live:
geometry in @mat3ra/made next to ReciprocalLattice, renderer in
@mat3ra/move next to BrillouinZoneImage, with wove passing the lattice
through instead of a type string and a dead image path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
claude added 9 commits August 16, 2026 22:31
The tab scientists touch most was a flat scroll of unlabelled forms:
nothing said which unit a setting belonged to, whether it still held
its default, or how to get back to that default, and finding one meant
scrolling past the rest.

Settings are now grouped into cards carrying a real title, the scope
they apply to (whole subworkflow vs a named unit), a modified badge and
a Reset control. A sticky index lists the units that carry settings
with a count of how many are modified, and a filter matches titles,
unit names, field names and engine keywords, so searching ecutwfc finds
the planewave cutoffs.

Reset reads defaults from the provider's schema where they are declared
and falls back to getDefaultData(): providers try to publish defaults
onto the schema through getPatchedSchemaById, but the patch addresses
<field>.default while the schema keeps fields under properties.<field>,
and esse skips paths it cannot resolve — so those defaults never land.

Subworkflow-scoped panels keep the compact field styles; unit-scoped
providers keep RJSF's labelled layout, as before.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Field-level (1.3): a changed field now says what its default was and
offers to put that one field back, via an RJSF FieldTemplate reading the
provider's defaults through context. Resetting a field leaves the
group's other edits alone, and the group's modified badge clears only
once every field is back to its default.

Compute (1.6): the tab restates the selection in the units people
reason about — total cores, wall time, queue, cluster — instead of
leaving nodes times cores-per-node to be multiplied by eye.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Adding to a workflow required knowing what you were adding. The unit picker listed
the bare enum strings and hid their meaning behind an info popover; the header offered
"Add subworkflow", which made an empty one, and "Paste subworkflow", a JSON textarea
that failed silently on a typo.

The unit picker now lists described cards — unitTypeCatalog.ts carries a one-line
description, colour and glyph per type. "Add step" opens StepLibrary: the 76 standata
subworkflows, searchable across step name, application and unit names, filtered by
application, with a preview of the exact units to be inserted. Pasting JSON survives
as the second tab and now reports parse errors. Adding an empty unit stays available.

Search and entry shaping sit in stepLibraryEntries.ts so tests/stepLibrary.tests.ts
covers them without a DOM. The demo's header stub renders the actions dropdown, so
these flows are reachable outside the web app.

Part of SOF-8024 portion 6.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The generated array form gave a routine FCC path eleven identical point/steps rows —
over 600px of form for one line of physics — while leaving two things unsaid: a
point's `steps` describes the leg leaving it, so the last one is read by nobody, and
nothing totalled the k-points the path costs, which is what sets the runtime.

The path is now a chain of chips, Γ 10→ X 10→ W, with the count on each leg, insert on
a leg, remove on a chip, and a line reading "10 legs · 101 k-points along the path".
Points are chips rather than a select plus a bare ✕, because "Γ ✕ 10" reads as
multiplication; the chip label keeps a minimum width so the delete icon does not own
the spot a pointer lands on first. Bound through ui:field at the schema root, which
also drops the schema's own title and "coordinates are derived at render time" note.
Matched by schema shape, so q-path and i-path providers get the same editor.

The path is also drawn inside the Brillouin zone and labelled at each high-symmetry
point — what a per-lattice PNG could never do. BrillouinZone now exposes the projection
it fits the solid with so the path lands in the same view, and the call site resolves
point names through ReciprocalLattice.symmetryPoints, reading the path at render time
so editing a leg redraws the picture. Labels are offset radially from the zone centre,
since high-symmetry points sit in one irreducible wedge and a fixed offset stacks them.

Also titles `ipath` and `igrid`, which had been rendering as "Ipath".

Swept all 55 standata workflows: 12 show the chain editor, 8 draw the path, no new
page errors. Editing rules are covered by tests/kPath.tests.ts.

Part of SOF-8024 portion 3, item 1.5.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The k/q/i-grid cards rendered "gridMetricValue" and "preferGridMetric" verbatim.
PointsGridFormDataProvider does title them, but through a dependencies.gridMetricType
.oneOf branch of its jsonSchemaPatchConfig, and esse's applyPatchWithDotNotation drops
the whole dependencies key — verified directly against getPatchedSchemaById, which
discards the sibling gridMetricType.default from the same patch config too. It is the
same silent skip that hides the planewave cutoff defaults.

withFieldTitles adds titles to named fields without disturbing the layout the
unit-scoped forms rely on, so dimensions, shifts and the ratios get sentence case as
well. preferGridMetric reads "Derive dimensions from the metric" rather than wode's
intended "prefer KPPRA", because that is what setting it does: the dimensions are
computed from the metric and their inputs go read-only.

Part of SOF-8024 portion 3, which this completes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The classic layout gives four twelfths of the screen to a flowchart of the same steps
the right-hand panel already has open, so a three-step workflow needs a wide screen and
its name renders three times. The studio shell replaces that column with a rail that
says what each step is — "01 · CP-MD · espresso · 1 unit" — and hands the rest of the
width to the work. Status chips appear only when a step is not idle, so a workflow being
designed spends no pixels on job runtime state.

Rollout first: layoutVariant ("classic" | "studio") is plumbed from the container
through Workflow to the layout, defaulting to classic, so every host renders what it
renders today until it opts in; anything unrecognized resolves to classic rather than to
a broken layout. The demo gets a Layout selector, which is also how the two get compared.
To stop the shells drifting, the editing surface they share — validation alert, header,
and the subworkflow / map / error content — moved into WorkflowUnitPanel, rendered with
identical props by both. Classic was re-checked after the extraction and is unchanged.

Select, rename, remove and Add step all go through the container callbacks the classic
layout already used, so no new container surface. Not pinning the legacy theme, the
studio shell also picks up the ambient one.

Also fixes two defects in the step library from the previous commit, which rendered but
could never insert: standata stores a subworkflow's application as a bare {name} stub
while its units carry the full record, so wode's validation blanked the designer on
insert; and the position argument was inverted against UnitPaste's 0-append/1-prepend
convention, landing every insert before the current step.

Part of SOF-8024 portion 5, items 1.1 and 1.5.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Four LFS captures at 1440×900: classic vs studio layout, the rebuilt Settings tab with
the k-path chain and the path drawn on the zone, and the step library. The review text
gains an "After" table pointing at them, so a reader can compare against the original
findings without running the demo.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
With the rail naming every step and switching between them, the panel header rendered
the same name a third time, plus a step pager the rail makes redundant.

SubworkflowHeader takes showStepIdentity, default true so the classic layout renders
exactly what it did. The studio layout passes false and gets a compact header: the
step's actions, and in the space the name freed, what the step actually computes with —
espresso · DFT/GGA/PBE · pseudopotential/us, which nothing showed before.

Part of SOF-8024 portion 5, item 1.4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The unit form showed a "Next" selector and, beside it, a disabled FlowchartId box
holding the same value spelled as a UUID — half the width of the form spent restating
the field next to it. UnitPointerField takes showFlowchartId, off by default.

Pairs with ave#8, which moves the selector itself into an Advanced section so the
dialog opens on the input template.

Part of SOF-8024 portion 4, item 1.5.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
@timurbazhirov timurbazhirov changed the title SOF-8024: workflow designer UX review, plan, and phase-1 quick wins SOF-8024: workflow designer UX — review, plan, and portions 1, 3, 6 (plus 4 and 5 started) Aug 17, 2026
claude added 3 commits August 17, 2026 06:51
Portion 4 items 1.3 and 1.4 landed in ave#8. Notes what the plan got wrong about the
failure mode — nunjucks renders an unknown variable as the empty string, so a typo
leaves nothing to notice rather than a visible `{{ }}` — what the check deliberately
does not flag, and the one item not built: insertion at the cursor, which needs cove to
expose the editor's EditorView.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
They were written at the repo root to run the parser over every standata template and
against injected typos; the results are recorded in the portion-4 plan document, and the
scripts themselves do not belong in the tree.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The audit in §1 claimed the light and dark palettes were identical. They are not — dark
deliberately uses the lighter brand purple. The real defect was that the dark palette
omitted the border, icon and unitTypes groups entirely, so keys cove declares on the
palette were undefined in dark mode and three styled components threw on them.

Contrast was also worse than §2 estimated: three of the four semantic contrastText
values were unreadable on their own main, the worst at 1.49, hidden behind alpha that
looks fine when read as a hex.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
claude added 4 commits August 17, 2026 07:09
Two hardcoded colours were wrong on a dark canvas regardless of which brand palette wins,
so they did not need the sign-off the rest of adoption waits on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Part of portion 5 item 1.2: cards state the engine and flavor they run, with the unit
type's icon beside the accent. The edge "+" from the same item still needs the canvas
work the portion owes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The zone labelled only the points the path goes through. For FCC, HEX, CUB, TET, BCC,
TRI and ORC that happens to be all of them — the default path reaches every point made
knows — so the gap was invisible on the common materials. It is not true lower down:
rhombohedral misses L1 and P2, monoclinic four, base-centred monoclinic six. Those
points existed, were selectable in the path editor, and appeared nowhere in the picture.

Unvisited points now draw as small faint markers with quiet labels; the path's own stay
solid and bold, so the picture answers both where the path goes and where it could.

Checked across FCC silicon, HEX graphene and RHL sapphire: the first two show no extras,
as expected, and sapphire shows exactly L1 and P2.

Part of SOF-8024 portion 3, item 1.5.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The GitHub Pages job only runs on `main`, so there is no way to try a branch
before it merges. Netlify builds a URL per pull request once the repo is
linked, and `netlify.toml` gives it the build without a token needing to live
anywhere.

Netlify serves the demo from the domain root while GitHub Pages serves it under
/workflow-designer/, so vite's `base` reads VITE_BASE_PATH and keeps the Pages
subpath as its default.

Verified by building with VITE_BASE_PATH=/ and loading the bundle from a static
server: assets resolve at the root, and the page renders the workflow tree, the
renamed tabs, and the k-path drawn on the Brillouin zone with no console or
request errors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
@netlify

netlify Bot commented Aug 23, 2026

Copy link
Copy Markdown

Deploy Preview for mat3ra-workflow-designer ready!

Name Link
🔨 Latest commit 4003e96
🔍 Latest deploy log https://app.netlify.com/projects/mat3ra-workflow-designer/deploys/6a8fec032602100008538ac8
😎 Deploy Preview https://deploy-preview-12--mat3ra-workflow-designer.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

claude added 9 commits August 23, 2026 01:50
The repo is already linked to the mat3ra-workflow-designer Netlify site, so the
previous wording asking someone to link it was wrong; previews build per pull
request at deploy-preview-<number>--mat3ra-workflow-designer.netlify.app.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Direction for separating the pure view capability (owned by wove) from the
designer's load/edit/save: one graph model and measurement-free layout feeding a
static SVG renderer, a read-only WorkflowViewer, and a steps list, with the
designer re-based on the viewer plus injected actions. Covers the Jupyter story
(SVG for saved notebooks, iframe viewer for live ones, shared golden fixtures
against a Python layout mirror) and cuts the work into five portions across
wove, this repo, and api-examples.

Grounded in the current code: editable is a flag threaded through the full
designer rather than a capability; the cards already read plain JSON fields;
layout is the one DOM-coupled step (reactflow-measured sizes feeding d3).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The first draft was written without seeing wove#14, which had already built
the JSON boundary (createWorkflowFromConfig, with a plain-JSON fallback when
the wode entity rejects a config), the read-only WorkflowViewer, the
window.renderWorkflow global on the wave.js contract, and the notebook recipe
using the same helpers that embed wave.js. Planning a static-SVG foundation on
top of that was proposing to redo settled work.

What the plan now says instead: keep that interactive path as the default where
JavaScript runs, and add the measurement-free layout underneath it so the same
graph can also be drawn as static SVG — which is what makes a *saved* notebook
show anything, since GitHub and nbviewer never execute the Javascript display
the bundle arrives through. The notebook helper emits both as one mimebundle.

Also records what wove#14 leaves open: the designer still mounts the whole
designer to show a workflow, layout still needs a live DOM, there is no compact
rendering for linear workflows, no size budget, and the config-rejected
fallback only warns to a console nobody reads in a notebook.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Both were snapshots taken before agents#4, #5 and #6 merged, so this repo's
agents were working without the section that matters most right now: §1.8.1,
which says @mat3ra/* packages do not commit dist/ and that a not-yet-merged
commit is consumed through a `[release]`-triggered wip-<sha> tarball rather
than a hand-built one. That is the convention the rest of this branch was just
brought in line with.

Also picks up the Python docstring guidance and the plan/context durability
split — tracked files are durable reference, `plan/context/session/` is
gitignored working notes, hence the .gitignore entry.

Nothing in the old copies was repo-specific; canonical was strictly newer in
every hunk, so both are taken wholesale.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Two things made the picture hard to read.

The projection yawed about y and put y on screen-vertical, but the lattice
data puts the c axis along z — HEX's six-fold axis is [0,0,1.6], TET's long
axis is [0,0,1.4]. So every uniaxial zone was drawn lying on its side: the
hexagonal prism balanced on a corner rather than standing on its hexagon.
Yaw now turns the zone about c, and c projects straight up.

The faces were also all drawn, translucent, sorted far-to-near — so back faces
showed through the front and a cube read as a wireframe with two possible
orientations. The zone is convex, so the faces it can show are exactly those
whose outward normal points at the viewer; the rest are now culled. The
viewport fit still measures every face, so nothing shifts as faces turn away.

Verified by rendering all fourteen lattice types, and end-to-end in the demo:
Si (FCC) and Bi (HEX) both draw their k-path on a zone that now reads as a
solid. Tests cover the invariants the change rests on — c vertical, depth
growing toward the viewer, three distinct axis directions, outward normals,
and exactly half the faces visible, which is what a centrosymmetric zone owes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
The layout gave its two columns `md` and `lg` widths but no `xs`. A MUI Grid
item with no breakpoint at or below the current one falls back to auto sizing,
so under `md` (900px) the columns stopped filling the row and shrank to their
content: the tabs and the flowchart sat in a ~470px column with empty space
beside them, while the subworkflow list above still spanned the full width.

Measured before and after at six viewport widths; the right column now tracks
the viewport (800px viewport → 800px column, was 468px) and the 4/8 split above
1200px is unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Clicking Edit under Outputs → unit → Properties unmounted the whole page.
`buildNamedEntitySchema` points `items` at `#/definitions/Property` but omits
the `definitions` block entirely when handed nothing to choose from, so for an
executable that declares no results RJSF got a dangling `$ref`, threw
"Could not find a definition for #/definitions/Property" during render, and —
with nothing catching it — React tore down the tree.

The schema is now checked before a form is built from it: `isSchemaResolvable`
walks it for local `$ref`s that no definition answers, and
`buildUnitPropertiesSchema` returns null rather than something RJSF will throw
on. With no properties to choose from there was never a form worth offering, so
the panel says that instead of showing an Edit button that breaks the page.

A `RenderErrorBoundary` around the form is the second layer: schemas here come
from application registries and user JSON, so the panel that fails should be
the only thing lost. Note the demo has no executable declaring results, so the
boundary is defence-in-depth that its data cannot exercise; the schema check
that actually fixes the reported crash is covered by tests.

Verified across all 57 standata workflows: Edit no longer appears where it
would break, and no click blanks the page.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Three things were working against the path, which is the whole point of the
picture.

It rendered in `secondary.main` — a mid grey in this theme, and the least
visible thing on screen. Measured against every ground it crosses (the halo
under it, the page, and the faces at the <=0.5 opacity they drop to whenever a
path is drawn), grey bottoms out at 1.87:1. No single colour clears 3:1 on
both light and dark, so the path now follows the theme the way the edge colour
already does: #8d3200 on light (worst 3.30), #f5a623 on dark (worst 4.45).

Labels sat on top of each other. High-symmetry points crowd into one
irreducible wedge — a base-centred monoclinic lattice puts seventeen of them in
a corner — so a radial offset alone still stacked them. They are now separated
in the plane, path and unvisited points together since they share that wedge,
each staying within 14 units of its own marker so it remains attributable.

The drawing was a fixed 240px inside a 655px panel; it now scales to the width
it is given, up to 420px, which is where the room to separate comes from.

Also stops cropping: the viewport was fit to the zone's faces, so a marker
outside them was silently clipped at the edge. The window now widens to hold
whatever is drawn. That matters because points *do* land outside the zone for
the monoclinic lattices (MCL 3 of 18, MCLC 10 of 21; FCC, HEX, RHL and TET have
none), which is not physically expected and wants showing, not hiding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FFFpkKD3zHysJXgAbT2uYV
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants