Back up before upgrading to 0.15.0. Every model file will be re-derived in
the background; a large library on a 4 GB NAS can keep the CPU busy for hours.
DBOS 3.3.0 and application database migrations require restoring the pre-upgrade
backup to roll back.
Release notes: PrintStash 0.15.0
Stop all API and worker processes before upgrading them together. Source
installations require Python 3.14 or newer; Docker images include the runtime.
See 0.15.0 upgrade notes.
-
The Unraid template starts again with the GPU field left blank. Unraid
passes an empty Device field to Docker as--device='', which stopped every
install without a GPU before it started. The Intel or AMD GPU is now an
optional GPU: Intel or AMD (optional) field shown with the main
settings: enter/dev/drior leave it blank for the CPU. Existing installs
that entered/dev/driin the old field keep working; to switch to the new
field, update the template, enter/dev/drithere and remove the old
Device entry. -
A GPU mapped as
/dev/driis now usable without naming its group. The
container used to drop every supplementary group when it switched to
PUID/PGID, including the host's render group and any--group-add, so
Intel and AMD GPUs were visible but could not be opened and work stayed on
the CPU. It now runs in the group that owns each/dev/drinode and keeps
groups granted with--group-add. -
Thumbnails drawn without a GPU take less CPU: the renderer now tests only
the pixels each row of a triangle covers instead of its whole bounding box,
most of which a long thin triangle leaves empty. The thumbnails are
byte-for-byte the same, so nothing is regenerated. -
STEP parts in the Docker image get their exact B-rep volume and similarity
fingerprints again. The image lackedlibgl1, which OpenCASCADE's binding
loads even without a display, so every B-rep read reported STEP as
unavailable. The image build now fails if that binding cannot load. -
Thumbnails, measurements and previews of a ZIP's Models now start while the
rest of the ZIP is still being imported, instead of after its last file. The
import still shows every Model almost as soon as before, because the derived
work looks for new Models every two seconds
(VAULT_JOBS_PACED_DISCOVERY_SECONDS) rather than after each file. Search
indexing still waits for the import to finish. -
Importing a ZIP no longer wakes the derivative passes after every file. They
would only wait for the import to end, so they now stay asleep until it does,
leaving the database to the import, so large ZIPs import and finish
processing sooner. -
A ZIP prepared while the server's clock stepped back (an NTP or virtual
machine time resync) no longer stays at Queued forever: the Task Center
now offers Choose files as soon as the preparation ends, whatever time the
server stamped on it. -
Administrators choose how many models are processed at once on Settings →
Background work → Worker settings. Automatic keeps the CPU-and-memory
default; a chosen count may go up to what the native memory pool fits,
overridesVAULT_MAX_RENDER_JOBS, and applies without a restart (separate
worker processes apply it when they restart). Use default clears it. -
The default number of simultaneous mesh jobs now follows CPUs and memory:
one per usable CPU plus one, no more than fit the native memory pool, up to
eight. Two- and three-CPU installs used to process one file at a time and now
run three or four, so large imports finish in about half the time.
VAULT_MAX_RENDER_JOBSstill overrides it; local AI inference keeps its own
default of one job per two CPUs unless that variable is set. -
STEP measurements and previews no longer reserve the whole native memory
pool. Each part is first admitted under 1 GiB, so STEP files are derived
alongside other work instead of one at a time; a part that does not fit runs
once more with the whole pool, and nothing is published twice. A new
mesh_escalationlog andprintstash_mesh_escalations_totalcounter report
those reruns. -
STEP files are tessellated at 0.05 mm instead of 0.01 mm, the precision the
similarity fingerprints already used: about a quarter of the triangles, so
STEP measurements, previews and viewer models are made roughly four times
faster in half the memory. Dimensions change by under 0.1% and previews are
visually unchanged. A STEP whose mesh exceeds the memory allowance is now
reported as a resource limit rather than an invalid file. Existing STEP
outputs are re-derived once; other formats are not. -
3MF packages are read through lib3mf, the 3MF Consortium's reference
library, instead of an XML tree: large plates read two to three times faster
in a fraction of the memory, and packages that ran out of memory before now
get their dimensions and volume. Coordinates are read in single precision.
Packages lib3mf cannot read with the same meaning (extensions beyond
production, mixed units, production parts without a build, geometry far from
the origin) and arm64 installs keep the XML reader. 3MF memory claims and
loader ceilings follow the reader that will run, and existing 3MF
measurements, thumbnails and viewer previews are re-derived once; other mesh
formats are not. -
3MF thumbnails and measurements no longer reserve the whole native memory
pool. The supervisor bounds each package's placed faces and parsed XML
without parsing it, so small and medium 3MF files are derived side by side
instead of one at a time. Fingerprint analysis, packages that cannot be
bounded, and very large packages keep the whole-pool claim. A new
mesh_estimatelog andprintstash_mesh_estimate_duration_secondshistogram
report each claim. -
Library Back and Forward keep the same visible reading position when a
revision notice changes the page height. -
Refresh library now recovers an initial read rejected by concurrent changes,
even before the first page has loaded. -
Ingestion qualification returns idle capacity credits during drain instead of
depending on the work heartbeat's timing. Active reservations remain protected. -
PrintStash now keeps a manifest for the Cosmos Cloud market
(azukaar/cosmos-servapps-official) next to the other store catalogues, with the
install dialog creating the first administrator and the same memory budgets the
other stores pass. Nothing changes for existing installations; the store
submission is a separate step, described incatalogues/README.md. -
SQLite installations temporarily poll interactive derivative work and its
discovery passes more frequently after accepting a submission. Duplicate,
delayed and backfill submissions keep the ordinary polling policy; the
temporary interval expires after activity stops. -
The Model filters panel lists G-code below a divider, after the source formats
it is sliced from, and writes formats as STL, 3MF, OBJ, STEP, DXF and G-code.
Active-filter chips use the panel's names and values ("File type: G-code",
"Revision: Needs test"), and material or printer names show as written. -
An upload into a library folder on a network or automounted share no longer
fails withstorage_root_changedwhen the share briefly reports a different
identity while it reconnects. PrintStash re-checks the folder and retries the
write once; a folder that was really replaced, or that disagrees again, is
still refused (#210). -
Bambu LAN printers reporting zero or missing task IDs reuse their external
print job across status updates instead of adding a row on every tick.
Repeated completion reports no longer queue duplicate notifications, while
an observed new run of the same file still creates a separate history row. -
An idle server uses about half the CPU again: only the ingest lane, where an
upload or import waits to start, is still polled four times a second
(VAULT_JOBS_INTERACTIVE_QUEUE_POLL_INTERVAL_SECONDS, 0.25). Derive, network,
printing and reconcile lanes go back to once a second
(VAULT_JOBS_QUEUE_POLL_INTERVAL_SECONDS, now 1.0). On a 4-core test server
with 300 Models, idle CPU fell from 11.4% to 6.1% of one core (0.14.0: 6.1%),
and uploads start as soon as before. -
Interactive background work can prepare its next queued job while the
current job runs, using the existing queue and admission limits. -
Search projection waits for an import to finish while previews can start
during the import. Its writes competed with the import for SQLite's single writer. A 300-file ZIP
import on a 4-core test server took 60 s instead of 121 s (0.14.0: 55–67 s).
Library browsing and filters do not depend on it. -
A valid 3MF too large to read within the preview memory budget is reported
as too large to preview, not as a damaged file. Its XML parser running out
of memory was recorded asinvalid_source. Theinvalid_sourcemessage now
says the file may be damaged or incomplete instead of asking you to check
its storage. -
A ZIP over the upload limit says so, with its size and the settings that
raise the limit, and the message stays in Tasks. The image's proxy refused it
with its own page, which the app reported as a server it could not reach. -
Library titles and controls adapt to the available pane width. Cards use the
full grid width, collection tags and description actions share a compact row,
and description editing stays visible and usable on phones. -
Library filters keep their position while facet counts load, so a response
arriving during a click does not lose the selected filter. -
Uploads wait for newly created tags to be saved, so a quick submission keeps
every selected tag. Cancelling a draft ignores late tag acknowledgements. -
Restoring large unfiltered collection trees reuses subtree counts instead of
repeating the same lookup for every descendant. -
Model metadata stays current when derivative updates arrive during an in-flight
detail read, including revision comparison fields. Confirmed edit receipts
with a different derivative snapshot trigger a fresh authorized read. -
Preparing-preview activity waits until the Library is ready before reading
the background queue. Opening Notifications can still request activity early. -
Interrupted uploads remain in Notifications after reloading the page, so you
can select the same file and resume the existing upload session. -
Mesh previews and geometry processing continue to work when a busy server has
more than 1,024 files open. Compute connections also wait for replies and detect
disconnected peers without the same descriptor limit. Warm workers preserve
high-numbered resource permits and close every unrelated descriptor before
processing a model. -
Native mesh processing now chooses a bounded concurrency default from the CPUs
available to PrintStash. Explicit concurrency settings and shared memory
admission continue to apply. -
An idle server on SQLite no longer uses more CPU the longer it runs. Each
background-work lane keeps checking for queued work on a short interval, and on
SQLite every check read the engine's entire workflow history, which the
default 7-day retention grows into tens of thousands of rows. On a low-power
mini PC that kept the server near 30% CPU with nothing to do. The checks now
use an index (DBOS 3.3). PostgreSQL was not affected. -
Background work no longer gets stuck after a restart. Stopping or
restarting PrintStash while a long job ran (a mesh, a backup, an import)
could leave that job "running" forever. On lanes that run one job at a time,
such as backups and maintenance, nothing else on the lane ran again until the
next upgrade. Such jobs are now picked up and rerun after the restart. With
separate worker processes, a worker that started after the backup being
restored now registers itself again instead of having its jobs rerun. -
A job whose work had finished is no longer marked failed because the
database was briefly busy (a locked SQLite file, a PostgreSQL restart) while
its result was being saved. Saving the result is retried. -
Cancelling a running job no longer lets its lane start another job before the
cancelled one has actually stopped, so lanes sized to the server's memory stay
within their limit. A cancelled job whose work never stops still frees its
lane afterVAULT_JOBS_EXECUTOR_STALE_SECONDS(2 minutes by default). -
The admin Background work page and each reconcile pass read lane depth
and active work without scanning the engine's whole history on SQLite (137 ms
per read at 200,000 history rows, now under a millisecond). -
With a pinned executor id, a job that crashes the server is retried as many
times asVAULT_JOBS_MAX_RESUBMITSallows (3 by default), instead of up to
100 restarts. -
Background work does less redundant database work: submitting a job no
longer reads the engine first, creating one no longer reads it back, the
periodic check skips the 12 kinds of requested work that have nothing to
repair (a third of its engine runs, and of the history they leave behind), and
its two sweeps share one read. Per job that is about 10% fewer database
statements on each of the engine and application databases. -
A reconcile interval that does not divide evenly into a minute, hour or day
(for example 90 seconds) now runs at an even cadence rounded down, instead of
firing twice in quick succession. -
Settings no longer re-measures Storage insights or re-checks Server
GPU every time you open them. Both took several seconds to load; each
answer is now kept for the session. Storage insights are measured again after
the library changes or when you choose Refresh measurement, and the GPU
status when you choose Check again. The last figures stay on screen while
a new measurement runs. -
Adding a G-code revision to a model you uploaded no longer fails with "This
model's source is remote and read-only" when a remote library source (S3,
WebDAV, SFTP) has also indexed the same file. The revision is stored in the
vault with the rest of the model. A model that only a remote source holds
still gets that message. -
AI Search can run a second local text model: all-MiniLM-L6-v2 (English,
90 MB). It embeds a query in about half the time BGE takes and needs less
memory, at slightly lower recall. BGE stays the recommended default; the
model choice in guided setup now shows each model's size, languages and which
one is recommended. -
AI Search preparation now shows its four steps (check library content, index
passages, catch up on recent changes, verify the index), which one is running
and what it does, and how many passages are waiting for a retry. A prepared or
active index shows an Index check: entries indexed out of searchable
entries, entries waiting for a retry or shortened to fit the model, the model,
and when verification last passed. -
Local AI models use less memory: each worker now loads a model's weights once
instead of twice and keeps a single tokenizer. Loading bge-small-en-v1.5
peaks near 290 MB instead of 375 MB. Graphs still load only after
their digest and structure checks pass, now through a pinned file
descriptor, so a file swapped in after the check is never loaded. -
A local AI model worker may now use up to 4 GB (
VAULT_EMBEDDING_WORKER_MEMORY_MB
default 4096, was 1024), still capped by the model memory share (a quarter of
RAM, so 2 GB on an 8 GB host). At 1 GB, indexing eight full-length passages
with bge-small-en-v1.5 failed withembedding_inference_failed. -
Upgrading from 0.13.0 or 0.14.0 no longer requires draining derivation work
first. Work still waiting under the old ordering is re-ranked on start instead
of stopping the container in a restart loop with
derivation_queue_requires_drain. Checked on real 0.13.0 and 0.14.0 data
directories, including one with old-rank work queued. -
AI Search can run multilingual-e5-small locally: one model for about 93
languages, including Spanish, with the best recall on the search regression
corpus. It needs about 1.15 GB of worker memory (hosts with 6 GB of RAM or
more). Guided setup shows a language count for multilingual models. -
A background-work engine database that DBOS cannot migrate (workflow rows but
no migration record, left by an earlier failed first start) is now reported at
startup with what to do, instead of looping ontable workflow_status already exists. -
Upgrading an existing install no longer stops at startup with
derivation_queue_requires_drainand "no such column: queue_partition_key".
The check that waits for old derivation work to drain read the previous
version's engine database with a client that expects the new schema, so it
failed on every existing install, even with nothing queued. It now reads only
the columns every version has; waiting work from the old ordering is
re-ranked on startup. -
Adding a G-code revision to a Model that comes from a remote Library source no
longer ends in "[500] internal_server_error". PrintStash never writes back to a
remote source, so it now says so (409) and the dialog shows a readable
explanation. In the same dialog, "Mark as recommended" is a star you fill
instead of a checkbox next to one. -
Deleted models can be selected in Settings, Trash: tick several (or all) and
restore or permanently delete them in one step. -
Large slicer 3MF files get a 3D view. A 20 MB Bambu Studio 3MF holds over
100 MB of model XML, which hit a fixed 64 MB limit and showed "3D preview
omitted due to memory limits". The limit is nowVAULT_MESH_3MF_MAX_XML_MB
(256 by default). A model with more triangles than the memory budget allows
still needsVAULT_MESH_MEMORY_BUDGET_FRACTIONraised; seedocs/compute.md. -
There is a single PrintStash image, and it can use the GPU. The separate GPU
image variants are gone: the one image on GHCR uses an NVIDIA, Intel or AMD
GPU, or the WSL2 GPU, whenever the container is handed one, and runs on the
CPU otherwise. Docker Compose, Unraid and the other app stores can now pass a
GPU and set the GPU and system memory budgets
(VAULT_COMPUTE_MEMORY_MB,VAULT_MESH_MEMORY_BUDGET_FRACTION,
VAULT_EMBEDDING_MEMORY_BUDGET_FRACTION); seedocs/compute.md. -
A model's 3D view opens straight away, even for a large mesh; the
"Load 3D preview" button is gone from the model page. -
The library loads the next page as you scroll, so there is no "Load more"
button to press. Loading starts a little before you reach the end, shows a
spinner while it reads, and the button only comes back if a read fails or the
browser cannot watch scrolling. -
Storage insights now show where your files live: the vault on this computer,
and each library source with its type and connection, with the total held on
this computer apart from what sits in remote storage such as R2. Library
sources stay where they are, so only their previews and catalog count against
the vault. -
Thumbnail and 3D-view generation now shows in Tasks. After an import or a scan,
administrators see one "Preparing previews" task counting what is left, which
completes when the queue empties instead of the work being invisible. -
The library no longer asks you to refresh when it changes. In a view that is a
single page, a new Model or folder eases in where it belongs and a change in
another folder only updates the counts; the notice remains only deeper in a
long list, where reloading every page read so far would move your place.
Changes are noticed within about ten seconds. -
A 3D preview that cannot be made now says why. A model over the preview size
limit, a file that is not a valid 3D model, a STEP file that will not convert
and a source that cannot be read each have their own message, instead of
"Something went wrong reaching the server". -
A scan of a remote source reports its progress while it lists the bucket: the
task shows how many files it has found and which folder it is in, instead of
a bare "running" for minutes. -
Filters work in a folder that only holds folders. The filter options and
their counts now describe the whole folder tree below you, and applying a
filter searches that tree, so the root of a library no longer offers nothing
to filter. An unfiltered folder still lists only its own Models. Print
history and Uploaded now look and behave like the other filter groups. -
A remote scan that finds no model file now says so on the source card, naming
where it looked (S3 paths are case-sensitive) and linking to the connection,
instead of ending quietly at "+0 added". -
Library sources can be edited. Each source card has an Edit button to rename
it and change how it maps to collections. A mounted folder can be pointed at
another folder, and a remote source at another path inside its connection
while it has indexed nothing. A remote source now shows its connection and the bucket or
host it reads (for exampleR2Test · test/PrintStash/) instead of the
internalsource://1/. -
Applying a filter no longer rebuilds the collection tree. Its rows stay put,
the counts dim while they reload, and each count that changes ticks toward
its new value. -
Picking a filter value no longer hides the other values of its group, so you
can add a second file type (or any other value) without clearing the first.
While a filter is on, the view lists the matching Models only, without the
open folder's subfolders beside them. -
Starring a Model, or regenerating covers, no longer shows "The library has
changed" on every open library. Only edits that can change a listing do.
Reloading reopens the path to the open folder and the six folders you opened
last, not every folder of the session. -
Cards now ease in one after another when you open a folder, even when
everything is already cached. -
Settings → GPU shows what the server can reach. Administrators get a
Server GPU card saying whether a GPU is accessible from the API, with its
device, backend, driver, memory budget, capabilities and recent activity, or
the reason there is none. -
Saving a collection description no longer reloads the collection tree or the
library, and the Tags, Upload and New multipart set dialogs no longer open on
an empty frame the first time: their code is fetched once the library is
usable. -
Opening a folder now has a little motion. Its contents ease in from the right
when you go deeper and from the left when you go back up, and fade in when
you jump somewhere unrelated. It is a short, small nudge that keeps scroll
positions intact, and reduced motion keeps only the fade. -
Models first, then thumbnails. While an upload, an import or a library
scan is still adding Models, thumbnails and other derived previews wait; they
start as soon as the last one finishes. A large import shows all its Models
sooner, and the library can be browsed while the previews catch up. Opening
a Model in 3D is not held back. -
The library no longer starts over while an import runs. Every imported file,
and every folder an import or a library scan created, told open library
views that access might have changed, so they discarded what they showed and
loaded again. A new Model is now created in its Collection instead of being
moved there afterwards (it was also briefly visible at the root), and only a
change that can affect access (a role, a disabled account, a moved or deleted
Collection) advances the access revision. The upgrade replaces two database
triggers; no rows change. -
Importing costs the database less. Steps that are only waiting share one
cancellation read instead of making one each, a finished upload no longer
queues a reconcile pass that has nothing to find, and several reads that ran
as their own transaction now ride on one that was already open. -
Opening a collection no longer makes the page jump. Its tags and description
appeared only once the folder and its description had loaded, pushing the
models down; their place is now held by a skeleton of the same shape. -
A multi-material G-code now shows the filament weight and length of the whole
plate. A two-filament plate (; total filament weight [g] : 70.97,16.48) was
shown as 70.97 g, its first filament only, and was costed accordingly. Files
already in the library are re-read in the background (#453). -
Multi-material prints now route to printers with several filaments. A G-code
using two or more materials wasunknownon every Bambu AMS printer, because
all its trays share one tool; it now fits when the printer holds a distinct
tray for each material, and is a proven mismatch when it does not (two PLA
colours on one PLA spool). Colour advice is given per material instead of per
last-seen tray (#453). -
Importing a reviewed archive shows how far along it is. The task used to say
"Discovering total…" with an empty bar until the last file was done, although
the selection was known from the start. -
A multi-material G-code now shows the material it actually prints with. A
plate sliced on AMS slot 3 of aPETG;PLA;PLA;PETGsetup was shown as PETG,
the first slot; the slicer's; filament: 3header is now read, and only the
slots the plate uses are required of a printer. Files already in the library
are re-read in the background (#445, #453). -
G-code exported by BambuStudio 2.x now shows its slicer, estimated print time,
filament weight and filament length. Its header block writes
; BambuStudio 02.08.02.61,; total estimated time: 17m 21sand
; total filament weight [g] : 6.15, none of which the parser recognised.
Files already in the library are re-read in the background. -
View a Model from underneath. The 3D preview now orbits all the way
around a mesh, so the underside can be inspected; it previously stopped at
the horizon (#427). -
Start with only the selected language. Each translation catalog is now its
own asset, loaded when its language is shown, which removes about a fifth of
the JavaScript downloaded at startup. -
Read a Model's details once when opening it. The page no longer repeats the
read just to confirm that nothing changed while it was connecting to live
updates. -
Keep one events connection and one setup admission while moving between
application pages. Opening a Model and returning no longer hides the app
behind a setup probe, reopens the events socket or refetches every view. -
Compress 3D preview meshes between the server and the browser. Binary STL
previews transfer at about half their size and ASCII STL at about an eighth,
and a slow connection no longer makes the proxy spool a large mesh to disk. -
Keep folder descriptions and model cards together when navigating, clamp long descriptions before the first paint, and avoid fading cached library thumbnails on every visit.
-
Open large Models on their thumbnail. A 3D preview whose source file is over
16 MB is no longer downloaded just by opening the Model; the page shows its
size and a "Load 3D preview" action instead. Shared links and the similar
Models comparison follow the same rule.
Performance
-
A 3MF's slicer picture appears as soon as the file is committed. It used to wait until the mesh had been read and measured, although it needs nothing from the mesh.
-
Do about 45% less database writing per uploaded file on SQLite (write transactions per file 57 → 32):
- a Job attempt ends in one write that also carries its staging release and the notices to the work that follows it, instead of five to eight;
- progress a Job reports in its first second is written with its next write (
VAULT_JOBS_PROGRESS_HOLD_SECONDS); - scratch space for a file is admitted against the same free-space budget without a database write of its own;
- the search index reads a changed Model before it takes the database's writer, not while holding it.
-
An accepted upload starts sooner. The request hands its Job straight to the job engine instead of queuing a pass to find it, and the lane it was handed to is polled faster for a few seconds (
VAULT_JOBS_BOOSTED_QUEUE_POLL_INTERVAL_SECONDS,VAULT_JOBS_QUEUE_BOOST_SECONDS). Median wait before an upload's import starts: 0.37 s → 0.13 s. -
Geometry and thumbnail workers start from a process that has already loaded the application and its geometry libraries (Linux), instead of a fresh interpreter per file: about half a second of CPU less per file. Each worker keeps its own session, memory ceiling and deadline.
VAULT_MESH_WORKER_TEMPLATE_ENABLED=falserestores a fresh interpreter per file. -
A file in a bulk upload now waits when the server is busy instead of failing. Session creation was limited to 30 per minute, which held a 200-file drop to one file every two seconds and failed files that arrived faster; that limit now bounds a runaway client (600 per minute) and staging admission paces real uploads.
-
Halve the CPU an idle installation spends polling its job queues: lanes nobody waits on (search, maintenance, notifications, similarity, captions, expansion) are looked at every two seconds (
VAULT_JOBS_RELAXED_QUEUE_POLL_INTERVAL_SECONDS) instead of four times a second. -
Do less database work per uploaded file on SQLite: keep connections pooled instead of reopening them under load (
VAULT_SQLITE_POOL_SIZE), open the job engine's own SQLite file in write-ahead mode, stop writing a row-level audit entry for every job, reconciler-cursor and capacity-claim heartbeat, check a step's ownership without taking the write lock, and report commit stages only for files slow enough to watch. Cancellation is noticed within half a second and worker memory is sampled ten times a second. -
Release prepared thumbnail parsers before GPU eligibility/dispatch instead of repeating broker status inside each disposable process. Keep model publication ahead of background DBOS captures, preserve guarded recovery from the same geometry packet, use compact exact OBJ corner keys, and skip STL preflight scans that cannot change the minimum memory claim.
-
Simplify source geometry preparation and native supervision: load qualified OBJ directly, bound text admission without parsing coordinates twice, avoid redundant vertex/edge sorting, and reuse a narrow cancellation query with fresh results. Keep native settings minimal and sample each staged worker's RAM once. A fixed 250-source WSL GPU comparison improves from 497.090 to 358.937 seconds (27.79%, using the longer of the two recorded clocks in the final repeat; first candidate: 357.279 seconds), preserving all metadata, 238 byte-identical images and the same 12 invalid-source outcomes; CPU-only geometry uses the same preparation path.
-
Decode ASCII STL geometry once for both CPU-only and GPU-enabled ingestion, retaining bounded source blocks instead of reparsing for allocation. Preserve exact source measurements, validation and output images. The fresh 250-source GPU comparison reduces elapsed time by 2.77%; a repeated three-source CPU-only probe improves by 29.02%.
-
Share a single bounded source-worker execution between measurements and previews. Basic STL measurements use source-precision arrays without importing Trimesh, preserving topology and signed-volume evidence; OBJ/CAD and optional fingerprints retain their specialized analysis. Eligible small previews now prepare normals on GPU while analytic views keep their canonical policy. Preserve identical metadata and original-file integrity.
-
Reduce repeated compute fingerprinting and admission-ticket decoding, give cold GPU ownership its bounded startup allowance, retain canonical STL bounds without gathering another vertex array, and compile worker application bytecode during image builds. Count bounded OBJ sources under separate CPU/wall budgets so scheduling contention does not unnecessarily serialize the RAM pool.
-
Render compact indexed triangles with GPU bounds/framing and visual position welding, grouping model uploads and drawing into one bounded submission per batch. Retain multiple geometries in VRAM and repair degenerate normal neighborhoods locally. Release an eligible disposable parser after clean reap, then render prepared geometry and encode final pixels in the owning Job without another encoder process. Retain explicit host/CPU credit through completion; GPU refusal uses a guarded renderer without reparsing. Unready devices, unmatched qualification, insufficient headroom and optional fingerprint work retain the combined worker. Preserve publication fences and reject empty GPU frames through the existing CPU recovery path. Assemble immutable geometry packets without repeated full-buffer copies. Avoid repeated framing/encoding of validated renderer output and use quality-85/method-2 lossy WebP with exact alpha and a codec completion slot independent of parser admission; thumbnail/visual recipes track the changed rendering semantics.
-
Prepare large render meshes with portable GPU normal accumulation and indexed packing, using guarded per-model CPU fallback and shared RAM/VRAM accounting. Keep canonical analytic preparation separate, reuse resident GPU state, and encode accelerated WebP through the same canonical preview encoder. Version changed thumbnail and visual recipes while preserving authoritative measurements and source bytes.
-
Coalesce independently admitted thumbnail work across Models, preserve per-item cancellation and deadlines, and report actual model/frame batch sizes. Keep disposable worker priorities across process startup, bound OBJ/ASCII STL admission preflight, avoid redundant mesh copies, topology work and unused worker imports, and reduce durable queue dispatch latency without changing concurrency or backfill ownership.
-
Drive native OpenDAL source reads through its asynchronous API so slow remote storage does not retain the Python GIL. Preserve bounded streaming and conditional reads, and interrupt waits at the existing cancellation and scan deadlines.
-
Keep GPU thumbnail resampling, alpha conversion and vignette on the device after an exact canonical canary. Download only final pixels, avoid timeout-mode socket polling delays, and reuse validated geometry through bounded binary references instead of repeated base64 transfers. Retire completed broker references so evicted geometry can release host RAM while the owner remains idle.
-
GPU thumbnail evaluation can use Mesa OpenGL/D3D12 entirely inside Docker/WSL, with hardware verification independent of GPU brand. A persistent render owner reuses geometry and shaders, batches up to eight ready frames per readback, and caches repeated shaded views. Evaluation remains distinct from automatic performance qualification and operator visual acceptance; CPU fallback stays available.
-
Correct shared-edge opacity in portable GPU rendering; document physical RTX 5060 probes and the remaining WSL Dozen/ONNX compatibility blocker.
-
Optional portable compute broker for qualified WebGPU rendering and ONNX inference, resident geometry/model reuse, bounded tensor batching and administrator diagnostics. CPU-only installations retain normal ingestion. Physical GPU combinations remain unqualified pending quality, end-to-end performance and recovery gates.
-
Enable mesh preview readiness after its first rendered frame; verify overlay alignment, display-mode pixels, and repeated resource cleanup on WebGL/WebGPU.
-
Extend native mesh preview checks for camera movement, screenshot scales, capture failures, and disposal; retain WebGPU as experimental after baseline comparison.
-
Open Models faster from the Library: resting the pointer or keyboard focus on
a Model card reads its details ahead of the click. -
Release the mesh preview GPU device when renderer construction or initialization cleanup fails.
-
Parse mesh previews in a cancellable worker and add an experimental WebGPU
preference with camera-preserving WebGL recovery and asynchronous screenshots.
WebGL remains the default; GPU performance qualification is still pending. -
Request the platform-preferred GPU before enumerating other graphics backends in the optional research adapter. Preserve capability fallback, software exclusion and explicit adapter selection.
-
Retain expanded NVIDIA quality rejection, real-model browser comparisons and fresh-worker failure evidence; document an isolated experimental WSL/Docker diagnostic without changing production eligibility.
-
Automate fresh-worker GPU benchmark campaigns with retained failures and immutable output directories; add ASCII/binary STL and overlapping geometry controls.
-
Report native GPU readback separately from CPU face resolution and canonical shading in qualification measurements.
-
Record revised RTX 5060 control evidence: exact CPU/GPU images across 60 observations after precision and native cleanup fixes; production qualification remains gated.
-
PRI-16: preserve canonical interpolation precision in the optional WebGPU
adapter, bound retained geometry, and reject invalid face readback before publication. -
Add an optional Python 3.14 WebGPU raster qualification adapter, adapter diagnostics,
frozen benchmark manifests and statistical reports. Production rendering remains CPU. -
Avoid deep-cloning lexical search queries for each page; keep rank materialization
local to each query and reuse immutable current-recipe predicates. Measure tab
indicators after native layout instead of forcing layout during React commit. -
Reuse bounded subtree count query structure with current roots and permissions.
Decode admitted thumbnails without a second native visibility wait. -
Start selected collection reads before rendering their destination, cancel abandoned
reads, and keep pointer prefetch scheduling outside the grid's rendering path. -
Optimize the restored tree's rendering with explicit locale dependencies, preserving
live language changes, drag-and-drop and pagination. Reuse immutable card projection
statements with fresh page/user parameters; avoid constructing unused tree ancestry. -
Reuse immutable ancestry and similarity query structure while reading current
permissions on every request. Avoid rerendering an unselected departing grid
before starting a collection navigation. -
Reuse HTTP-cached content-hashed assets during reload without weakening HTML
or bootstrap revalidation, offline fallback, or private-response isolation. -
Keep scheduled upload recovery outside an active verification or Job handoff,
avoiding spurious upload conflicts while retaining recovery after interruption. -
Reuse the current locale's card-date formatters without caching timestamps.
-
Preserve visible nesting at every collection-tree depth and align Model leaves
beneath their parent, keeping deep rows selectable on narrow screens. -
Ignore system-only maintenance notices in Task Center instead of repeatedly
downloading an unchanged Jobs list. -
Serialize search-preference writes before reading SQLite state, avoiding failures
when background processing commits concurrently. -
Reduce thumbnail transfer size with quality-85 WebP color and lossless transparency,
preserving resolution and regenerating existing mesh/G-code previews through Jobs. -
Restore remembered Library branches in bounded batches, prioritize visible thumbnails,
and keep deeply nested folders selectable on narrow screens. Load the multipart
editor separately from Library cards, reuse restoration counts and permission scopes,
and avoid repeated thumbnail access lookups and image decoding. Reuse immutable
similarity SQL construction while checking current permissions on every read.
Reuse authorized empty child levels and defer the initial event connection until
critical content is ready, retaining immediate permission checks. Opening the mobile
tree no longer competes with filter catalogs below the visible area. -
Keep the first visit intact when the service worker installs, while still refreshing
an existing installation after a worker update. -
Measure each Library destination through restored tree rows and decoded viewport
images, with a reproducible reference-host acceptance command and explicit failures.
Tie timings to committed history entries and actual input events. -
Keep the collection tree visible when selecting folders, preserving open branches
and downloaded sibling pages without reloading them on every click. -
Finish Settings cache and audit ownership: preserve pending edits during refresh,
reject obsolete cache-policy changes, share audit reads, and retire commands
when leaving a view or changing session. -
Keep manual printer-material drafts after rejected saves and offer explicit review
before adoption; cancel obsolete reads when switching printers. -
Preserve first-run storage drafts across locale changes, retire setup requests
on navigation, and recover one initial Library read conflict without mixing snapshots. -
Keep Library view metadata out of AI Search filter requests, so filtered and saved searches remain usable.
-
Offer Everything and Multipart Sets as the two Library views. Filter and order
mixed results on the server before pagination so later matching results remain
reachable. Reject stale continuation pages instead of mixing catalog revisions. -
Preserve each Library history entry's filters and reading position through
detail navigation. Bound restoration after cache eviction, explain missing
anchors, keep rapid folder transitions coherent and retire private snapshots
when the session or access changes. -
Detect competing edits to Models, Multipart Sets, Documents, printer settings,
Profiles, Search, Vault settings, browser names, notifications, storage connections,
Library sources and Spoolman. Preserve drafts for explicit review after conflicts
or uncertain responses. Bind edits to database history so restored backups cannot
authorize obsolete drafts. Legacy clients retain unversioned compatibility. -
Keep confirmed changes authoritative during refetch and pagination races. Remove
the duplicate transport GET cache and transport-owned invalidation. Feature owners
coordinate reads, receipts and recovery; session changes retire private requests,
cached results, local secrets and pending confirmations. -
Retain protected thumbnail URLs while displayed, admit nearby images under a
four-download limit and cancel abandoned work. Bound idle encoded image data
without evicting mounted consumers. Preserve Shift selection after page append
and the reading position after removing a confirmed favorite. -
Share Inbox and durable Job state across consumers. Preserve accepted uploads
and scans after their forms close, recover missed events and prevent disposed
printer subscriptions from reconnecting. Retire bulk transfers with their session. -
Give settings, storage migration, backup, source management, manufacturing and
ZIP review explicit loading, error and recovery states. Preserve unsaved input,
require the reviewed destination for destructive actions and avoid replaying
commands after an uncertain acknowledgement. Save compound Vault configuration
in one transaction; retain omitted credentials and independent edit counters. -
Bind browser-extension captures to the selected connection throughout download
and upload. Retire revoked credentials, cancelled pairing and obsolete callbacks;
clean up malformed upload receipts and unnecessary host permissions. -
Keep route-chunk recovery bounded and localized, restrict the offline cache to
public static resources and recover online navigation when Cache Storage fails.
Retain React Router and the static Vite deployment; enforce app/package dependency
directions and remove obsolete navigation and invalidation compatibility APIs. -
Load the Library route immediately and defer upload, tag, multipart creation
and ZIP review forms until opened. Prioritize cards and the bounded tree,
release auxiliary reads after paint or explicit interaction, and share the
initial Jobs snapshot with the event handshake and a one-second fallback.
Deliver bootstrap and hashed assets without waiting for Cache Storage, keep
an offline shell fallback, and bound Model pages to 24 cards. Add production
startup measurements against a disposable real SQLite library in Deep CI.
Discard reads from previous sessions, prevent late GET/blob results from
refilling invalidated caches, and recognize session changes across tabs. -
Add storage publication authority boundary tests for incompatible receipts and stale reconciliation.
-
Add import download contracts for staging names, redirect and window ceilings, stream cleanup and ZIP CRC refusal.
-
Add thumbnail engine contracts for unavailable allocation, source files and RSS telemetry, preserving publication errors.
-
Add real database contracts for mesh continuation recovery, cache lease deferral and current Job withdrawal authority.
-
Add authenticated HTTP contracts for outliner printer-filter authority and contradictory query scopes.
-
Add real ZIP preview contracts for embedded 3MF budgets, unsafe member names, CRC recovery and strict PNG validation.
-
Add real database contracts for similarity ingestion continuation authority, durable analysis eligibility and caller write rollback.
-
Verify fingerprint publication preserves active caller transactions and leases,
rejecting detached authority, changed recipes and invalid descriptor metadata. -
Verify STL publication readers preserve buffered byte semantics and cancellation,
refusing nonregular output and unavailable or mismatched source storage. -
Verify local inference rejects missing capabilities, model assets and oversized
input while preserving admission recovery and read-only cached model support. -
Verify viewer STL conversion refuses nonfinite facets, excess streamed output
and changed or missing source identities before reporting success. -
Verify prepared mesh resource identity and immutable detached buffers refuse
incoherent evidence before native analysis. -
Verify import resolver selection identities reject malformed provider responses
while preserving stable errors and redacting private transport data. -
Verify durable ingestion receipt writer authority, result pagination and canonical
File confirmation through real SQLite contracts. -
Verify batch session lifecycle, frozen snapshots and result context against
real durable receipts, including refusal of incomplete artifact commit results. -
Verify retained scene measurements preserve finite dimensions when closed
resources collapse or numeric volume aggregation exceeds its representable range. -
Verify mesh output frame boundaries reject malformed flags, incoherent evidence,
oversized payloads and invalid fingerprint records before publication. -
Verify preparation resource lifecycle rejects malformed recovery identities,
preserves failed cleanup ownership and enforces source-before-native ordering. -
Verify durable volume evidence reads preserve closed variants and refuse
incompatible scalar, method, cause or state combinations. -
Verify search generation proposal provider, visual profile and aggregation
rejection contracts directly at the public schema boundary. -
Measure whole-host native fairness in the mandatory serial resource phase,
retaining real workers, branch coverage and the existing timing budgets. -
Isolate provider HTTP pools and host capacity between tests so a previous
test's ended event loop cannot affect transport shutdown. -
Keep fairness qualification reads bounded to pending foreground uploads while
preserving exact progress totals, native budgets and its existing deadline. -
Qualify backup recovery and exact deletion against versioned S3 generations;
verify that missing receipts on unversioned targets are refused without
changing the published archive. -
Reset PostgreSQL work-engine state by removing only its DBOS schema, preserving
application tables in the shared database and rebuilding the reconciler schedule. -
Run Python compatibility tests and external service contracts in independent
Deep CI jobs, preserving both required results and their execution limits. -
Distinguish repeated uploads from same-Job retries in sustained ingestion
qualification, verify versioned Artifact identities, and stop after the first
failed mandatory control while preserving failure evidence. Configure E2E
SQLite connections before concurrent work starts, matching production WAL
initialization and native-extension startup; prepare backup recovery through
permanent purge with foreign-key enforcement intact. -
Keep Model card tag and similarity badge reads bounded as the SQLite catalog grows, including
installations with stale query-planner statistics. -
Defer parent-only metrics and database URL parsing in disposable mesh workers,
reducing measured small-model startup costs while preserving CPU outputs,
parent telemetry and guarded process cleanup. -
Add isolated GLB/LOD qualification tools with supervised native exports, real
browser memory/draw/quality measurements and protected-feature checks. Retain
STL after measured candidate correctness, resource and performance limits. -
Publish batch Artifacts before materializing later entries. Bound disposable
staging by files and bytes, record each entry with its Artifact transaction,
and resume confirmed entries without reopening their sources. Keep partial
failures retryable and report unknown totals until discovery finishes. -
Stop withdrawn batch imports between entries and source blocks, preserving
committed Artifacts and durable upload sources while cleaning owned staging.
Copy and hash browser upload bytes in one pass, and preserve cancellation when
receipt cleanup fails. -
Add an isolated prepared-geometry cache benchmark with bounded, checksummed
arrays, current-loader STL equivalence checks and supervised worker timings.
Keep production preparation unchanged pending demonstrated reuse and recovery
guarantees. -
Publish viewer STL conversions from verified staged streams without buffering
whole outputs in the API/worker parent. Reserve expanded output space before
conversion, reject changed or incomplete publications, and release request
database connections before work hints so concurrent viewer misses share one
durable conversion without pool timeouts. Release native compute credits before
storage publication; viewer recipe 3 rejects malformed STL and float32 overflow
or collapsed faces, rebuilding older viewer outputs on demand. -
Bound file acceptance commands independently of ordinary API workers. Keep SQL
sessions on their creating thread, release them while streamed bodies wait,
revalidate credentials before publication, and finish admitted writes before
returning cancellation. Slow storage or engine hints leave lightweight API
requests responsive; accepted imports remain durable background Jobs. -
Reserve interactive discovery slots beside one active backfill Job per
derivation lane. Keep bounded indexed scans and durable backfill progress
during uploads, dispatch admitted derivatives in FIFO order, and carry Job
priority through shared native and source-preparation admission with aging.
Preserve backfill reservations across public retries and engine-acceptance
crashes without spending another attempt while waiting. Verify legacy queue state before starting consumers; upgrades drain and
restart API and workers together. -
Local ONNX models reserve a shared, bounded memory partition across API and worker processes, retain warm reuse, retire idle residents under pressure, and release their credits after guarded process-tree termination.
Source installs require Python 3.14 or newer. See the upgrade guide.
-
Coordinate mesh CPU/RAM credits across local API and worker processes. Bound
source preparation separately by bytes and I/O slots, retain native credits
through descendant cleanup, and recover abandoned source copies before reuse.
Reserve memory for the requested geometry, raster dimensions and optional
analysis, preserving WebP output and complete fingerprints for admitted work.
Reduce temporary raster buffers while keeping complete frames and output pixels.
Report queue time independently of native execution. -
Remove the sidebar tree’s global 500-model limit with folder-scoped pages, complete branch counts, and global paginated name search with “Open location”. Keep permissions and library views in the server query; retry failed pages without losing loaded rows (#335).
-
Keep backup and vault audit clock inputs within valid minutes on Python 3.14; reject
24:00rather than treating it as midnight. -
Preserve traceable printer display names for extension-only and genuinely named inputs on Python 3.14.
-
Require Python 3.14 for the application and shared core, pin development and container runtimes to 3.14.8, and update the mesh stack to NumPy 2.5.3, SciPy 1.18.1 and Trimesh 5.1.1.
-
Publish mesh metadata and thumbnails before optional fingerprints finish, with durable bounded recovery that preserves completed outputs after native failures.
-
Reuse immutable mesh positions and smooth normals across each visual pass.
Embedding views and similarity view hashes consume pixels directly without
repeated PNG encoding and decoding, while preserving existing preview bytes
and descriptor identities. -
Retain unique 3MF resources and explicit placements through measurement and
preview rendering. Measure repeated instances without first allocating a whole
placed mesh, materialize only for admitted fingerprints or global topology,
and release that mesh before rendering. Keep exact dimensions and counts when
optional volume or fingerprint analysis fails, with explicit volume evidence.
Preserve finite volume when source and placement scales compensate, and clear
measurement topology caches before rendering even without fingerprints.
Refresh mesh outputs under the new eligibility and budget policy. -
Share bounded STL source validation across measurements, full loading, fallback
samples and streamed previews. Validate complete source facets and stable EOF
before reporting coverage, retain exact full-source bounds and counts for
partial samples, and refuse malformed or changed sources consistently. -
Interpret reachable Core 3MF geometry and Production external model references
through an explicit bounded scene reader. Refuse unsupported required
capabilities with typed metadata, similarity and viewer reasons while retaining
original downloads and independently usable embedded previews. Refresh mesh
derivative recipes without introducing a Lib3MF dependency. -
Keep mesh measurements and previews available when optional fingerprint analysis
exceeds its triangle budget, and release analysis buffers before STL rendering fallbacks.
Re-derive earlier terminal refusals at updated mesh recipes. -
Independent mesh, G-code metadata/thumbnail and binary toolpath processing controls, with deployment defaults and live administrator settings. Disabling retains published previews and lets admitted processing finish; re-enabling resumes eligible missing work (#263).
-
Harden mesh workers with pre-import address-space limits, one admission controller
across concurrency changes, process-tree memory accounting, and shared budgets
for nested CAD/streaming work (#259). -
Report refused mesh geometry separately from usable thumbnails, retain terminal
failures for unchanged input, and backfill accurate metadata with recipe 3 (#259).
Upgrade note: The background engine now uses DBOS 3.3.0. Stop all API and
worker processes before upgrading together. Restore the pre-upgrade application
database and managed files to roll back; discarding the DBOS engine state alone
is insufficient. Every model file is re-derived in the background after upgrading.
See the upgrade guide.
Added
-
Measure mesh rendering, supervised native workers and upload-to-visible
production DBOS ingestion through separate reproducible benchmark paths.
Preserve phase costs, resource observations and failed samples, with an expanded
versioned corpus and opt-in large inputs and hash-pinned real slicer projects. -
Publish explicit mesh volume state, method and cause independently of similarity
fingerprints. Preserve historical scalar provenance, keep small measurements
unrounded and evaluate signed volume accurately across large translations.
Reject nonphysical dimensions before publication and repair unusable historical
measurements during the additive upgrade. -
Add a frozen synthetic mesh contract corpus and record benchmark environment, limits, versions and target expectations separately from observed render results.
-
Mesh workers retain bounded phase costs and parent-observed resource usage in structured process logs and local Prometheus counters, including metadata-only work and failed or cancelled native processes.
-
Deep CI exercises the production mesh pipeline under 1 GiB and 4 GiB
limits on amd64 and arm64, publishing memory, failure and cleanup evidence. -
Job details show retained ingest capacity and provide a confirmed, identity-checked
discard action serialized against retry. Completed staging is reconciled at
startup; failed input retains its existing expiry (#259). -
API responses include
Server-Timingfor total request time, SQL time and
statement count. Requests exceedingVAULT_SLOW_REQUEST_MS(1,000 ms by
default) emit a warning with those timings and the request ID to help diagnose
slow library pages without logging query values. -
The API serves the collection tree a page at a time:
GET /api/v1/collections/childrenlists one level (or a user's top level),
GET /api/v1/collections/lookupresolves a path with its ancestors, and
GET /api/v1/collections/searchfinds collections by name at a minimum role.
Each result carries its subtree Model count, child count and display path.
GET /api/v1/collections, which returns the whole tree, is deprecated and
will be removed in 0.16.
Fixed
-
Expired printers now appear in garbage-collection previews and can be purged
after backup verification, approval and quarantine. Printer configuration is
removed without foreign-key failures; print and notification history survives. -
Refused storage writes no longer strand thumbnail reservations. Hourly cleanup
recovers stale failed publications even when trash expiry is disabled or a GC
preview awaits approval, so thumbnails can be generated again after enrollment. -
Preserve remote scan deadlines when native metadata or streaming reads time out, so bounded imports continue instead of entering provider-error backoff.
-
Continue manual remote-library scans across bounded pages and time slices using durable requests committed with the saved cursor. Cancellation and provider backoff remain distinct from normal continuation.
-
Normalize S3 library listing timestamps to HTTP HEAD precision so unchanged Cloudflare R2 models can be indexed; retain size, ETag, version and post-download change checks.
-
Keep admitted editor state while setup navigation is checked, retire it on rejection, and show legacy local/S3 storage details.
-
Preserve confirmed Model batch results when a later request loses its response, with explicit review and conditional undo of acknowledged changes.
-
Bounded STL previews report whether all source triangles are represented independently from a complete source scan. Mesh processing now uses separate admission, loading, measurement and preview owners with validated geometry and fingerprint contracts.
-
Mesh workers reject unknown or malformed fingerprint result states before publication.
-
Capture and similarity commands keep the API event loop responsive through database writes, background-engine notification and response projection.
-
Preserve existing paired Point model manifests and native encoder alignment when mesh rendering recipes change. Visual vector caches still track their rendering recipe.
-
Mesh metadata preserves measurement precision, including submillimeter dimensions and small positive volumes; existing rounded measurements are recalculated.
-
Small meshes placed far from the coordinate origin retain their thumbnail
geometry and shading. Visual recipes now refresh previews, view fingerprints,
and derived image vectors while preserving original files and encoder assets. -
Geometric verification reuses an exact point index and preserves nearest-point
distances for models placed far from the origin. Previous pair proofs are
rechecked under the new verifier recipe while retaining review decisions. -
Ingest acceptance keeps the API event loop responsive while staging files,
recording work and notifying the background engine. -
Keep mesh-worker memory limits and cancellation active after the child closes its reply stream.
-
Active mesh workers can release their render admission while a queued worker checks durable cancellation state.
-
The thumbnail benchmark now runs the real engine, measures persisted local thumbnail reads, and preserves failed attempts with their costs instead of reporting misleading cache timings.
-
Large STL files now retain complete bounding dimensions and facet counts when only metadata is requested; measurements no longer depend on producing a thumbnail.
-
Mesh previews and image embeddings ignore vertices unused by any face when
framing the surface. Existing visual derivatives are regenerated. -
Meshes with repeated identical faces no longer expand the same thumbnail pixels
repeatedly, avoiding unnecessary rasterization work during ingestion. -
Meshes with inconsistent triangle winding now report unknown volume while
retaining dimensions and triangle counts. Existing metadata is recalculated
automatically. -
Browser-local upload queues recover as interrupted after a reload, so stale
tasks can be cleared. Resumable uploads retain their recovery controls, and
queued browser work now asks users to keep the tab open (#336). -
3D viewer conversions run as durable, on-demand Jobs. Requests share preparation
and retain failure reasons; memory refusals show a clear message while original
downloads and slicer handoff stay available. Hovering a model card no longer
starts a mesh conversion (#259). -
Containers start with read-only Library source mounts beneath
/data. Startup
ownership repair is limited to app-owned directories and preserves external
sources, including bind mounts on the same filesystem (#330). -
Cancelling active mesh work now stops its native worker tree, releases capacity,
and preserves the original. Immediate retry cannot resume the cancelled attempt (#259). -
Keep native STEP/STP conversion within small worker memory budgets by using serial tessellation, and classify B-rep allocation failures as resource refusals.
-
Background work starts on DBOS 3.3.0, with a persistent reconciler schedule
that survives process restarts and is recreated after restore. -
Late derivative results can no longer overwrite cancellation, retries, regeneration, trashed Artifacts or replaced source bytes. Stale Job executions also cannot settle a newer attempt or reclaim its staging files.
-
Removed the duplicate Wiki entry from the profile dropdown.
-
Rendering model views for learned similarity embeddings no longer happens in
the API process (#259).
With embeddings enabled, the similarity run rendered six views of every model
in the library inside the API; it now uses the same disposable worker as the
other mesh work. A model that exhausts memory or never finishes fails that one
embedding and the run continues with the rest. -
Collection search, breadcrumbs and subtree counts now follow indexed parent
links, keeping these reads responsive in libraries with tens of thousands of
collections (#295). -
Opening the 3D viewer on a 3MF or OBJ no longer converts it inside the API
process (#259).
The conversion runs in the same disposable worker as mesh derivatives, so a
model that exhausts memory or never finishes fails that one request with
stl_conversion_failedinstead of taking the API down. A model that cannot
be converted still answers the same error; the viewer's behaviour is
otherwise unchanged. -
Comparing two models during a similarity run no longer happens in the API
process (#259).
Verification now runs in the same disposable worker as mesh derivatives, so a
pair whose comparison exhausts memory or never finishes is counted as a failed
verification and the run moves on to the next pair. -
Analysing the whole library for similar models no longer runs in the API
process (#259).
The fingerprint pass now uses the same disposable worker as mesh derivatives,
so a file that exhausts memory or never finishes is recorded as a failed
fingerprint for that file alone. The run carries on with the rest of the
library instead of taking the API down or stopping. -
The Settings Maintenance heading now uses the same framed section treatment as neighboring tabs.
-
Opening the 3D viewer, converting to STL, and geometry comparison no longer
expand a 3MF's repeated parts before checking their size. These paths still
used a loader that composed every placed instance first, so a small project
file that places one part many times could exhaust the API's memory
(#259). They now
share the bounded 3MF resource loader and the same face budget as thumbnail
generation; an over-budget project is refused instead. -
Manual and scheduled backup tasks now show database snapshot, file archiving,
archive verification, destination publication and finalization progress in
Tasks and Background work, including the number of files archived. Scheduled
backups now appear in administrators' Tasks while they run, and the latest
completed scheduled backup remains visible if it finished before reconnect. -
A model file that needs more memory than expected can no longer take the API
down or crash-loop the container
(#259). Mesh
geometry, thumbnails and similarity fingerprints now run in a disposable
worker process. When a file passes its memory budget or the worker deadline,
the worker is killed and that one file is recorded as failed: a file over the
memory budget is not retried, while a timeout keeps its bounded retries. Every
other request keeps working. The deadline isVAULT_MESH_WORKER_TIMEOUT_SECONDS
(default 300 s). -
Backup history disables replica retries when a run has no completed archive
record. Its guidance now refers to that run instead of implying that existing
backup archives have been lost. -
Storage migration no longer clears destination fields when an obsolete
startup request finishes after the form becomes editable. -
Storage migration deadlines now include their UTC timezone, so a fresh plan
remains usable and source-retention deadlines display correctly outside UTC. -
Restoring a backup no longer fails because a completed ZIP inspection is
waiting for file selection. Its staged archive remains available; unfinished
uploads and imports still block restore until they are settled. -
Large STL previews frame every source component and preserve ASCII geometry after large translations.
-
Streamed STL previews preserve valid oblique facets that the degeneracy filter could discard.
-
Serialize storage adoption and retirement by immutable reservation generation;
retain exact cleanup revocations and preserve newer objects at reused keys.
S3 backup deletion now requires an immutable object version. Failed commit
acknowledgements preserve already adopted covers, documents and embedded images. -
Import completion prepares private source-cover candidates and switches their
visible pointer only under the current Job and Inbox authority. -
Interrupted downloads, archive extraction and local copies retain exact cleanup
receipts and disk reservations; restart or retry reclaims their private workspaces
before the next input is admitted. -
Recover maintenance capacity when a process dies after committing a Job result
but before its engine execution finishes, preserving the completed outcome.
Performance
-
Convex hull descriptors use normalized SciPy/Qhull geometry, preserving dense convex surfaces and finite extreme scales while rejecting invalid coordinates. Existing fingerprints are recalculated.
-
Tag counts now follow collection links when inheriting tags, so listing tags
stays responsive in libraries with tens of thousands of collections and
100,000 Models, including for users with collection-specific access. -
3MF geometry loads about 1.6 times faster. The bounded 3MF loader read
every vertex and triangle attribute with a Python call per value; it now
hands each column to NumPy in one pass. A 320,000-face project went from
3.1 s to 1.9 s. Memory use is unchanged, and malformed attributes are still
refused as an invalid package. -
Splitting a mesh into its separate parts is about three times faster.
Similarity fingerprints of STL, OBJ and other non-3MF meshes joined connected
faces one edge at a time in Python; a 500,000-face surface spent 4.3 s there
and now spends 1.4 s. The parts found are unchanged. -
Large libraries load their collection tree in about a second. A library
with 9,000 collections and 40,000 Models took over a minute to show its
sidebar, because each collection's model count was checked against every
other collection. Non-administrators' library, tag, collection, document,
Multipart Model, build, search and similar-model reads no longer send their
whole list of visible collections with every query. The library sidebar now
loads one folder level at a time and starts collapsed on a first visit,
except along the path to the current folder. Move, upload, ZIP review and
new Multipart Model destinations use search instead of loading every folder.
Model cards and detail pages receive their folder names from the server.
Multipart Model browsing loads one folder page at a time; Pending Import and
Similar Models collection scopes use search. Settings loads grants only for
the collection an administrator selects, avoiding a permissions request for
every collection when the page opens.
Full changelog: v0.14.0...v0.15.0