The trusted runs' test archive is still built on GitHub's ubuntu-24.04
runners; minisforum's newer glibc runs it unchanged, so shards 3-4 can join
1-2 on the self-hosted runners.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Fork pull requests now run on the untrusted self-hosted runners, which start
every job empty. Let them restore main's rust-cache like GitHub's runners do
(save-if stays main only, so a fork job never writes a cache).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Lists and Packaging lint each took their own runner slot on every PR push. The list checks now run
in the existing checks job; Lists stays on main. Packaging lint skips PRs that only touch icons.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
With Windows off pull requests, GitHub's 20 runners sat idle while every
fork job queued for the self-hosted pool. Select checks, repository
checks, Clippy, doc tests and the summary go back to GitHub's runners;
Build tests and the test shards stay on the isolated self-hosted pool.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Pull requests now run the repository checks, Clippy, the affected
crates' tests in 2 shards, and the doc tests. Windows, the reference
tests and the robustness goldens run on pushes to main and in the
nightly, where a break is fixed forward. This is the split Bevy, Zed
and Ruff use, and it cuts each pull request's CI to about a third.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Blacksmith isn't provisioning runners: its dashboard says the account
"requires additional verification", so every job labelled blacksmith-*
stays queued with no runner. Fork PRs' Linux jobs go back to the
self-hosted-untrusted pool (#2249/#2252) and the rest to GitHub's runners
until Blacksmith verifies the account; then #2237 can be re-applied.
This reverts commit dc40f051b1.
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Fork pull requests, the nightly run, Run workflow, the test archive and
test shards 3-4 move from ubuntu-24.04 to blacksmith-<N>vcpu-ubuntu-2404
(16 vCPU for Clippy and the test archive, 8 for test shards, doc tests,
reference tests and cross-compiles). Trusted runs keep the self-hosted
routing. Blacksmith runners count as self-hosted to GitHub, so steps now
tell our own machines apart by runner name.
TEMPORARY: this branch routes its own run like a fork pull request.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Every fork run waited in GitHub's shared queue just to start. The gate
and summary jobs now run on the isolated runners as well; the local
output stays false for forks so later jobs never pick the trusted pool.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Fork PRs were waiting hours for GitHub's shared runners. Their Linux
jobs (checks, Clippy, Build tests, the test shards, Doc tests, Reference
tests) now run on the ephemeral, network-jailed self-hosted-untrusted
runners, without the trusted runners' warm build directories.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Pull requests from branches of this repository share the work with the self-hosted runners like main does; fork pull requests stay on GitHub's runners. Select checks and ci run on a light self-hosted runner; the repository checks, Clippy, doc tests, reference tests and test shards 1-2 on the fast ones. The test archive is still built on GitHub's runners (glibc).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The merge queue runs the full suite on exactly the commit it then puts on
main, and main's push run then ran the full suite again on the same files.
Select checks now asks the Actions API whether a passing merge_group CI run
exists for the pushed commit; if so the push runs only the repository checks.
A push that skipped the queue, or an API that cannot answer, still runs
everything. The nightly still runs the whole suite.
Pull requests also run less: the reference tests only when solidcraft-cli (or
anything it depends on) is affected, and doc tests only for the affected
packages that have a library. The ci check requires the reference tests only
when they were selected.
Claude-Session: https://claude.ai/code/session_01LGeCa5jWWdroMWvXxN3LLM
Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Clippy, the doc tests and test shards 1-2 of pushes to main and merge-queue
groups run on the self-hosted runner, alongside GitHub's runners for
everything else. Pull requests, the nightly run and Run workflow stay on
GitHub's runners. Clippy and the doc tests keep warm build directories
outside the checkout (scripts/ci/warm-target.sh).
The test archive is still built on GitHub's runners: the self-hosted
machine has a newer glibc, so binaries built there don't start on
ubuntu-24.04.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Only the Windows jobs still wait for GitHub's runners on main and in the
merge queue. The Vulkan packages are preinstalled on the self-hosted
runner (no sudo), so that step runs only on GitHub-hosted runners.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Pushes to main skip boolean_props (random inputs); the nightly property-tests job runs it. The three shrunk cases are ignored tests with their issues (#1647, #1648, #1649), and proptest's failure file is named outright.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment /claim on an issue to be assigned and get the in progress label; /unclaim releases it. A daily sweep frees claims with no PR after 72 h or with a PR idle for 14 days.
Clippy, the test archive and the test shards cover the packages a PR changes plus their dependents. Main, nightly and manual runs stay full.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
* Windows: resize border from the first frame, DPI-correct window moves (#1381)
- The egui resize zones were laid out after the start page's early return, so a launch without
a design had no resize edges at all. They now run on every page.
- Windows: the main window's procedure answers WM_NCHITTEST with the resize edges and corners,
Windows' own border width at the window's DPI (8 px at 100 %), so the OS shows its resize
cursors and runs its own resize (snap included) from the first message; no egui zones there.
- Windows: WM_GETDPISCALEDSIZE returns the size winit then applies (same logical size), so the
rect the OS suggests while the title bar is dragged onto a monitor with another scale is the
rect the window gets.
- Zone sizes and hit test shared in titlebar.rs and unit-tested; Windows CI checks the hit test
right after launch and a real edge drag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Windows resize smoke: find the main window by its title
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Windows resize smoke: probe the maximized window at the screen's edge
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Action matrix: nightly shards cut by measured cost, heavy designs in slices, and a determinism check
The full matrix ran as four fixed quarters of the corpus and two of them hit the 60-minute
job limit. Now action_matrix_shard runs shard k of n (ACTION_MATRIX_SHARD=k/n), planned from
tests/action_matrix/costs.json: designs that take more than five minutes are split into slices,
and the pieces go largest first to the least loaded shard. The nightly runs 12 shards and uploads
each one's outcomes and timings; cargo xtask action-matrix --from DIR --bless records them in the
baseline and costs.json without running the matrix again. action_matrix_determinism runs a sample
twice and lists any action whose outcome changed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Action matrix: costs measured on runners, 10 shards, determinism on the lighter designs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Action matrix: baseline and costs from a full run on main, 16 shards, timeouts listed
The baseline is regenerated from the 10 shards' results of a full run on 01b1b705
(cargo xtask action-matrix --from DIR --bless): 8 new designs, 302 actions that pass now,
names that changed, and 40 actions that passed before and fail now, each listed in #1255
(22 fillets refused since #949, 4 hinge blends since #1101, 9 on the loft cut, 5 single).
costs.json now holds every design's measured time, and the nightly runs 16 shards of about
17 minutes. An action that passes in the baseline and times out is listed but not judged,
and stays passing when blessed: two runs of the same build differed only on 10 actions that
took 50-84 s against the 90 s limit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Action matrix: slice heavy designs by a hash of each action's name
Slicing by index gave some slices only fillets on oracle 41 (28 slices, a multiple of the
actions per edge), three times the planned time; two shards ran past their limit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
A crash inside a graphics driver left only "an unclean exit between
commands": no backtrace, no module, no hint that it was at startup.
- The crash journal now keeps the startup step the app is in (window,
graphics instance, surface, adapter request, adapter chosen, device
creation, renderer and viewport shader compiles, surface configure,
first frame and its present, running) and the renderer as soon as the
adapter is picked. egui-wgpu tells the app about its steps through a
small hook. An unclean exit before the first frame names the step.
- Windows: an unhandled-exception filter (src/native_crash.rs, the one
Windows-only module allowed unsafe) writes the exception code, the
faulting module and offset, and a minidump next to the journal; the
next start puts them into the report.
- The Windows CI job runs a child that faults on purpose and checks the
report.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Windows: start Direct3D 12 first, and Vulkan only without a D3D12 GPU
wgpu started Vulkan, D3D12 and OpenGL together and preferred Vulkan, so
every Windows start loaded all installed Vulkan drivers. An old Intel
Vulkan driver (igvk64.dll) crashed 0.10.1 at startup inside the driver.
The app now probes D3D12, then Vulkan, then OpenGL, one backend at a
time, and starts only the first with a hardware adapter (WARP when none
has one). WGPU_BACKEND still wins; graphics.json's "backend" sets the
order by hand; the software renderer (safe mode, the retry) uses D3D12
alone. A new Windows CI job starts the real app under several settings.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* CI: a test filter YAML parses
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* CI: the startup smoke test writes graphics.json where the app reads it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* CI: run the WARP shader tests one at a time
WARP's shader JIT (d3d10warp.dll) crashed twice in 124 runs of the gpu
tests with four test threads, with a null read inside its own optimizer
while several devices compiled compute pipelines at once. Serial runs
did not crash.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* GPU tessellation: a pipeline the device cannot build falls back to CPU meshing instead of crashing (#1098)
Build the tessellation compute pipeline inside error scopes; TessGpu::new returns an error,
and the viewport logs it and meshes bodies on the CPU. A Windows CI job builds the pipeline
with D3D12's FXC on the WARP adapter.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Tessellation shader: basis functions in one-dimensional local arrays, so D3D12's FXC compiles it (#1098)
FXC has to unroll loops that write an array inside a struct (Basis.n0/n1) or a 2-D array
(ndu) by a counter, and cannot with run-time trip counts (X3511). A2.2 basis functions in a
local 1-D array returned whole; derivatives from the degree p-1 functions; the pole step
offsets computed rather than indexed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Only one run per concurrency group can wait. On a busy main each push replaced the waiting run, so the nightly and Run workflow runs on main were cancelled before they started. The group now includes the event.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tests/robustness/goldens.json records what each of seeds 0-95 builds: its steps, how it ended (ok, or the kind and the start of the error it was refused with) and, for the design it left, the bodies' total volume and area (within a relative 1e-6) and their face, edge and shell counts. tests::robustness_goldens fails on any change; ROBUSTNESS_GOLDENS_BLESS="why" records one, with the reason and the seeds it moved. Pull requests that touch crates/kernel run every 8th seed; pushes to main and the nightly run every seed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A scheduled/manual CI job scans locked dependencies for advisories, bans and unknown sources with cargo-deny 0.20.2 (never on pull requests, contents: read, no secrets). The first scan flagged quick-xml 0.38.4 (RUSTSEC-2026-0194/0195), so the workspace moves to quick-xml 0.41. Fixes#468.
Co-authored-by: lillith <35337584+0xlillith@users.noreply.github.com>
apps/solidcraft-cli/tests/action_matrix.rs tries sketch, offset/angle/mid planes, press pull, extrude from a face, hole, draft, shell, fillet, chamfer, axes, points, planes, projection, move, copy, mirror and pattern on the final bodies of 104 designs (the old design files, the examples, the 76 reference recipes, the enclosure demos, the Pi case built through the UI, eight typical parts), through the commands and picks the desktop sends, each design in its own process, with an edit round on a sample of passes. tests/action_matrix/baseline.json is a ratchet: an action that passed there and fails now fails the test; newly passing ones are reported for cargo xtask action-matrix --bless. Every CI run checks a fixed sample; the nightly Action matrix job runs the whole matrix in four parts. 30,567 of 35,576 actions pass (85.9%); results and causes in docs/action-matrix.md, one ignored reproduction per open cause (#556-#568).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* Release under the SolidCraft name: binaries, assets and installers
The desktop binary is now `solidcraft` and the CLI `solidcraft-cli` (the two app packages
are renamed; their folders move with the rest of the rename later). Every release asset is
named solidcraft-<ver>-… / SolidCraft-<ver>-windows-x64.exe, and the installers show the
SolidCraft product name.
Kept so existing installs keep updating (docs/compatibility.md):
- `solvecraft-cli` alias binary in every package, forwarding to solidcraft-cli with a
deprecation note on stderr (tests/legacy_alias.rs).
- Linux app ID ai.storyteller.solvecraft (Flatpak ID, desktop entry, Wayland app_id).
- MSI UpgradeCode, so the MSI upgrades in place.
- deb Replaces/Conflicts/Provides and rpm Obsoletes/Provides solvecraft.
- An old-named .zsync copy so earlier AppImages find updates; a legacy .flatpakrepo copy.
- .solvecraft file associations; SOLVECRAFT_* fallbacks in the packaging scripts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
* MSI: register the legacy .solvecraft extension without a duplicate open verb
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The oracle no longer uses Fusion measurements. tests/oracle/<case>/ now holds the 76 recipes
(our own format, with recorded measurements and tool-specific fields removed) and an
expected.json per case:
- 55 analytic cases: closed-form values from tools/oracle-analytic/ (stdlib Python, formulas
in each case's "method").
- 21 FreeCAD cases: the same recipe built with FreeCAD's public scripting API by
tools/freecad-oracle/ (an external program, not a dependency), with a reference.stl for 20.
solvecraft-cli oracle compares body count, volume, area, centre of mass, bbox, face counts
where the geometry fixes them, and, against reference.stl, the sampled Hausdorff distance and
the principal moments (spatial.rs from #301). cargo xtask oracle reads tests/oracle, writes
docs/oracle.md with the source of each value, and supports known_failure marks for tracked
bugs. CI runs it on every PR; a manual workflow regenerates the FreeCAD values. step-corpus,
seam normalisation and the through-all emulation, which only existed to compare with Fusion,
are removed.
75/76 pass; 75-sm-bracket-holes is a known failure (#296).
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
Co-authored-by: bherbruck <bherbruck@herbrucks.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Pins actions/checkout v7.0.1, actions/upload-artifact v7.0.2, actions/download-artifact v8.0.2 and
Swatinem/rust-cache v2.9.2 by commit. Re-applied onto current main by the maintainer (the workflows
changed since the PR was opened); dtolnay/rust-toolchain stays on @stable, because pinned to a commit
it needs an explicit toolchain input, and it is a composite action with no Node runtime.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
Light optimisation (deps at 2), line tables only, no LTO, debug assertions off (truck's debug-only
checks reject valid geometry, the only reason tests used --release). Cold full `cargo xtask ci`: 14 min
with all 647 tests passing; the oracle, step-corpus and app builds stay on --release.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RjGw4gA5ZvKrU8MQP6sBgT
An mdBook under docs/book: a user guide (getting started, UI tour, sketching, features,
parameters, components and joints, sheet metal, plastic, files, shortcuts, MCP) and a developer
guide (CONTRIBUTING, architecture, command engine, kernel boundary, persistent naming, test
harnesses, and the existing docs/*.md pages). `cargo xtask book` generates the command reference
from `solvecraft-cli commands` and renders the screenshots with `solvecraft-cli snapshot`, then
runs mdbook. .github/workflows/pages.yml publishes the book at /solvecraft/ and the web app at
/solvecraft/app/ (skipped while the repository is private). .github/workflows/ci.yml runs
`cargo xtask ci` on pull requests. README and Help → Documentation link to the book.
Fixes#28Fixes#8
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>