Repository navigation
Releases: oernster/Simquence
Release list
Simquence v4.0.0
Release notes
LatencyLab is now Simquence
The application has a new name and a new icon on every platform: the window, the taskbar, the Dock, the shortcuts, the installer, About and the website. The repository and the site have moved with it, to github.com/oernster/Simquence and simquence.com. Nothing about how models run or what the results mean has changed; a model that ran under LatencyLab gives the same answer under Simquence.
This is a major version because the product's identity has changed everywhere it is recorded: the Windows install folder, the Apps entry and the taskbar identity, the macOS bundle identifier, the Flatpak application ID, the Python package names (simquence and simquence_ui), the command-line script and the environment variables (SIMQUENCE_*). Anything that referred to the old names needs the new ones.
Moving from LatencyLab on Windows
LatencyLab's update check follows the renamed repository, so an existing install will be offered this release. After installing, setup looks for the old LatencyLab install and lists exactly what it would remove: the program folder, its shortcuts and its entry in Apps. It removes them only if you agree; it removes only what it can show belongs to the old install. If LatencyLab is running, setup asks you to close it first.
A release you chose to skip under LatencyLab is not remembered, so you may be offered one update you had already declined.
On macOS and Linux the old application stays until you remove it: drag LatencyLab out of Applications on a Mac; run flatpak uninstall uk.codecrafter.LatencyLab on Linux.
A clearer toolbar
The toolbar's actions wear proper pictures instead of emoji, drawn large, so the bar looks the same on every machine; a disabled action is drawn grey. Distributions, in the middle of the bar, is a chart. The Guide is the "i" at the far right; it opens with a tour of the toolbar, each button shown with its picture. The donate button now goes to Simquence's own page.
Compose and Edit say which is which
Compose opens a new model (or the one you left unfinished); Edit opens the loaded model. The composer's title and icon name the mode. Edit asks before replacing a new model you have not exported.
Fixed: after using Edit, Compose reopened the loaded model rather than a new one.
The keyboard reaches everything
Left and Right now step through every dialog as Tab and Shift+Tab do, in the application and in setup; previously they stuck in a licence's text or the composer's list. A menu reached by the keyboard offers its first item. Setup's dialogs open on their first button rather than with nothing selected.
Repair launches the application
Repair now honours "Launch when finished", as Install always did.
A shorter website
The website says each thing once, in about two thirds of the words; its guide and reading pages match the application's own Guide and How to Read. Its screenshots show this release.
For anyone building from source
macOS notarisation now looks for a keychain profile named Simquence. If you stored credentials under LatencyLab, store them again under the new name or set APPLE_KEYCHAIN_PROFILE=LatencyLab.
The dev extra now includes setuptools, which the packaging test needs and which a fresh Python 3.12 or later virtual environment no longer provides.
Latency Lab v3.3.2
Release notes
Help and licence text keeps its opening pause
Help and licence text, in the app and in the installer, holds still for five seconds when it opens before it starts to read itself down the page. Tabbing into the text during that pause no longer cuts it short. Once the text is moving, scrolling, clicking or tabbing into it still takes over at once.
Text under another window stays where it was
When another window opens over help or licence text, the text underneath now waits exactly where it was. Nothing that reaches it in the meantime is taken as you scrolling it; it carries on from the same place once that window closes.
Latency Lab v3.3.1
Release notes
Help windows open ready to close
About, the Guide, How to Read and both licences now open with OK selected. Before, they opened with the text itself selected and a green outline round the whole page.
No outline round text you are reading
Clicking into the run summary, the critical path or the text of a help window no longer selects the whole box and draws a green outline round it. When the text is longer than its box, Tab still reaches it so the keyboard can scroll it; even then no outline is drawn. Text that fits its box is skipped by Tab altogether, as are the Model Composer's pages, so Tab goes straight to the next thing you can use.
About shows everything at once
Help | About now opens tall enough to show all of its text without scrolling.
Installer licence
The installer's licence window opens with Close selected rather than the text, clicking the text no longer outlines it and a long licence now reads itself slowly down the page, the same as the licences inside the app. Scroll or click it at any time to take over.
Latency Lab v3.3.0
Release notes
Models that would have run wrongly are now refused
LatencyLab used to accept some models and then run something other than what they described, without a word. It now refuses them when they are loaded, saying what is wrong:
- a duration given as
NaNorInfinity; aNaNduration could make a version 1 run hang forever; - a normal distribution with a negative mean;
- a lognormal distribution whose
muis so large that its median duration would be infinite; - a version 1 model that declares a delay on its wiring; version 1 has no delays, so the delay was quietly ignored;
- a task or event name containing
>, which could merge two different critical paths into one count; - a fractional schema version such as
2.9, which used to be treated as 2 and run; - a key written twice in the same part of a model file, such as a task copied and pasted without being renamed. Previously the second copy silently replaced the first. This applies everywhere a model is read: the command line, a run, Open and the Model Composer.
Clearer errors on the command line
When the command line is given a model it cannot read or that is not valid, it now prints one line saying which file and what is wrong, then exits with status 2. Before, it stopped with a Python traceback.
A histogram that stays usable
A model with one very long tail could make the makespan histogram ask for hundreds of millions of bars, which ran the app out of memory. The histogram now uses at most 200 bars, widening each one when it has to. The percentile markers also line up with the bars again: they now sit over the bar that holds their value instead of drifting away from it.
Latency Lab v3.2.0
Release notes
A donate button in the top bar
The top bar now carries a donate button, immediately left of the light and dark toggle. Pressing it hands the donation page to your browser; LatencyLab itself fetches nothing, so the update check stays its only outbound request. If the desktop declines to open a browser, the app says so and shows the address. LatencyLab stays free, with no paid tier and nothing held back behind a donation. The README and the website carry the same link.
Commercial licences
LatencyLab remains free and open source under GPL-3.0, with its interface layer under LGPL-3.0. A commercial licence for the author's own code is now offered separately for anyone those terms do not suit; the README and the website say where to find it.
A tidier website
The site gains a Features page that gathers the application, using it and reading the output behind three cards, so the top bar shrinks to Features, Why and Download. Links that pointed at a post which no longer exists (sending a reader straight back to this site) are gone; the README's equivalent now points at the Why page. Each stylesheet is now linked with a hash of its content, so a browser can no longer pair a fresh page with a stale cached stylesheet.
A quieter failure in the update check
If the window were closed while an update check was still waiting for GitHub, the answer could have raised an error on a background thread. No known path in the app does that today; the answer is now simply dropped when there is no window left to show it.
For anyone working on the source
Three new documents sit beside the README: DEVELOPMENT.md covers running from source, each platform's build in order and cutting a release; TESTING.md covers the checks, what the coverage gate holds and leaves out and how a test is written; DECISIONS-TRADEOFFS.md records the choices LatencyLab rests on, with what each one gains and what it costs.
The Windows build scripts now stop before touching anything unless Nuitka 4.2.1 or newer is installed; the build extra asks for the same minimum.
The full test suite could crash with heap corruption in most runs, because windows a test left behind were freed by Python's garbage collector in the middle of a later test. Each test now has its leftover windows deleted through Qt as it ends, so the suite runs to completion.
Latency Lab v3.1.0
Release notes
An update check that respects you
The desktop application now notices when a newer release exists. Shortly
after launch and once a day while it runs, it asks GitHub anonymously
whether a newer published release is out; if one is, you choose Download,
Skip This Version or Later. A skipped version never prompts again and a
check that cannot reach GitHub stays silent rather than nagging. Only
formally published releases count: a tag pushed mid-development can never
prompt. Help > Check for Updates is new here and runs the same check on
demand, reporting every outcome including "you are already current".
Your models and results still never leave your machine; the version ask is
the application's only outbound call and it carries nothing about you.
For Linux users: the Flatpak's sandbox permissions now include network
access so the check can reach GitHub. An existing install keeps its old
permissions until reinstalled from a rebuilt bundle.
Latency Lab v3.0.3
Release notes
A documentation pass, nothing behavioural
No code path changed in this release. The tracked documentation was read
against the current source and corrected where it had drifted: the README's
stack table now describes the legacy NumPy engine as what it is, the live
execution path for schema_version: 1 models as well as the frozen oracle the
snapshot test pins, rather than "only" an oracle; ARCHITECTURE.md picked up a
punctuation correction. The GitHub Pages site was restamped from VERSION. The
application binaries are unchanged apart from the version they report.
Latency Lab v3.0.1
Release notes
IMPORTANT NOTE:
- macos dmg release asset removed since I forgot to notarise it (I didn't know that step was necessary after developer signing; the latest version has been notarised).
The mark is where the keyboard expects it
The application mark in the middle of the toolbar opens the distributions
panel. It always answered the mouse. From the keyboard it was the last control
on the bar you could reach: tabbing across the bar went along the group on the
left, jumped past the mark to the theme toggle at the far right, then came back
to the middle. The one control on the bar nobody can miss with their eye was the
one the keyboard offered last, which is indistinguishable from its having been
skipped.
The cause is that the mark is centred on the whole bar rather than sitting in
the row of buttons, which means drawing it on top of that row rather than in it.
Nothing in the layout then says where it belongs in the reading order, so it was
reached last by default. The bar now states its own left-to-right order. A test
measures the ring against where the controls are actually drawn rather than
against a list somebody wrote down, so a control added later cannot quietly fall
off the end again.
Latency Lab v3.0.0
Release notes
IMPORTANT NOTE:
- macos dmg release asset removed since I forgot to notarise it (I didn't know that step was necessary after developer signing; the latest version has been notarised).
The desktop application ships
LatencyLab has always had a desktop front end you could run from a clone. It is
now something you can install: a Windows installer, a Linux Flatpak and a macOS
disk image, each built from one entry point at the repository root, each staging
the same icons and example models beside the application.
The frozen build also starts, which it did not before. The repository-root
launcher used to rewrite the process name for tidiness. Nuitka's Qt plugin reads
that name when a Windows icon is compiled in, pulls the icons out of the file it
points at and insists on finding at least one, so pointing it at a name rather
than a file killed the application before its first window, silently, because a
release build has no console to print to. The build now smoke tests itself:
it starts the bundle headless and fails the build with the traceback if it exits.
The Linux build had a failure of the same family and it took the same amount of
finding. The Flatpak started nothing at all, because the Qt networking library
it ships is linked against a Kerberos library the freedesktop runtime does not
carry. LatencyLab never speaks to a network; the one thing that touches it is
the guard that stops you opening a second copy. That was enough to kill the
import before the first window, taking the application with it. The build now
compiles Kerberos itself, pinned by checksum and fetched on the host so the
build stays offline, for a library it will never call.
On macOS the application had an icon everywhere except the places you look for
it. The mark is drawn on a transparent canvas, which is right for the Windows
taskbar and the Linux icon set, both of which sit on something. The Dock, Finder
and the mounted disk image put it straight on the desktop instead, so what you
got was a red ring and a yellow hand floating on pale grey. macOS now gets its
own set, drawn on an opaque tile and shaped to Apple's own icon grid rather than
filling the square: inset, with the rounded corners every application beside it
in the Dock has, so LatencyLab sits at the same visual size as its neighbours
rather than looming over them. Every other platform keeps the transparent
originals; so does the badge inside the application, which is drawn on the
application's own background.
Every example is one menu item away
There is an Examples menu holding every model the application ships with, so a
fresh install has something to run before you have written a model of your own.
The set is read from disk rather than listed in code, which is the same thing
the test suite already did: dropping a model into the examples directory now
opts it into the validation test and puts it on the menu, with no second place
to remember.
Loading a model, from the menu or from the Open dialog, now flashes the Run
button's border twice. The change of state happens on the far side of the
window from where you were looking, so this points at what to do next and then
stops: two flashes, well spaced, in the same green that already means "you can
use this".
The new Checkout model is the one to start with. A storefront checkout fans
out to four back ends, two of which share a database that can only serve one at
a time; a 150ms debounce sits on the promotions branch. That debounce, added
for politeness, is the critical path in most runs. It is the shape of finding the
tool exists to produce; it appears within a second of opening the app.
The composer shows you one thing at a time
The Model Composer was a panel down the right-hand side holding every part of a
model at once: the system settings, the contexts, every task and the wiring, in
one column you scrolled. With the checkout model open that column ran to nearly
five thousand pixels, the tasks alone accounting for three and a half thousand
of it, so anything past the second task was found by scrolling and then
remembering where it was.
It is now a window of its own, opening at nearly the size of the application.
The left side lists what the model is made of, a row per section and a row per
task; the right side shows whichever one you pick. Every part now fits without
scrolling at all.
The list keeps up with the model as you type. Renaming a task renames its row as
you go rather than rebuilding the list under your cursor, adding one takes you
straight to it; a task you have not named yet still holds its place rather
than vanishing from the list until it earns a name.
Some things went with the side panel. Compose no longer competes with the
results panel for the right-hand side, so opening one is no longer a question
about the other and the results are still there when you close the composer. The
Compose button is no longer a toggle, because a window covering the application
does not need a button underneath it to say so. The prompt about unexported
results stayed, since that was never about the layout.
A model you opened is a model you can edit
The composer could only ever build a model from nothing. It can now be filled
from the model that is already loaded, so opening a file and changing it is one
action rather than a retyping exercise: everything the file says, including
delays and per-task categories, comes back into the editors.
Compose and Edit are both on the new Model menu and both in the tray, as drawn
icons with tooltips rather than one wide captioned button. Edit is inert until
something is loaded and says so.
An editor that is open follows the next model you open, rather than carrying on
showing the previous one. It leaves a composer alone if you were typing a model
into it from scratch, because replacing that would be losing your work rather
than refreshing a view.
The Contexts table shows the contexts it holds. It used to be given a height
that had never looked at them, so it reserved empty space for a model with two
and cut off a model with ten; it collapsed to about two rows whenever the
panel was short. Names were clipped inside a fixed column width while the room
they needed sat empty in the same row. The table is now as tall as its contents,
up to the point where it would start pushing the rest of the panel out of reach;
the name column takes whatever width is going.
The rows fit what stands in them, too. A concurrency box is taller than the row
it was being drawn into, so its lower half was simply not painted: the down
arrow was missing entirely, you could count a context up but never back down;
the number sat against the bottom edge of what was left rather than in the
middle of its box. Those were one fault. A row is now as tall as the tallest
thing in it.
Every field is the same size as every other field
The controls in the Model Composer were three different heights. A concurrency
box stood at 51 pixels, a distribution parameter at 19 and a text field at 22,
which is why the editors read as cramped in some places and roomy in others.
The cause was a single word. The rule that gives an input its size named one
kind of spin box; the toolkit treats the whole-number and decimal versions
as unrelated cousins rather than as parent and child, so the rule reached one
and silently missed the other. Text fields were not named at all and had been
running on the toolkit's own defaults throughout. Every kind of field is now
covered by one rule; a test asserts that nothing anywhere is drawn smaller
than it asks for, in either theme, rather than checking today's numbers.
Two things had been quietly overruling that rule as well: an explicit minimum
set on the dropdown lists, which let a panel squeeze one to half its proper
size; a sizing hint on the composer's scrolling panel that read as "no
taller than it needs" and meant "may be made shorter than it needs". That last
one was leaving nineteen controls drawn smaller than their own minimum, which is
what squashed the parameter arrows.
The toolbar is a tray
The icons used to sit directly on the window with nothing marking where the
chrome stopped and the content began. They now sit in a band of their own, with
its own surface and a bottom edge.
The application mark in the middle of the band is now the button that shows the
distributions; it turns banana yellow while they are up. It used to be
decoration, sitting there doing nothing while the control that opened the panel
was one more small glyph in the row on the left. The mark is the most prominent
thing on the band and the panel is the point of having run anything, so they are
one thing now rather than two competing from opposite ends.
It is a toggle rather than a one-way opener, so the press that shows the panel
is the press that puts it away; it follows the panel rather than the click:
closing the panel by its own cross leaves the mark telling the truth. The
emoji it replaces is gone with it, which is one fewer thing on the band drawn by
whichever font the platform happened to pick.
The mark's hands are banana rather than white, which is easier to pick out and
is the colour the rest of the application already uses to mean something. That
is one drawing, so it changes everywhere at once: the application, the taskbar,
the installer, the shortcut, the About box and the website all read from the
same file. While it is switched on the mark is redrawn in dark ink, because
banana hands on a banana button would be no hands at all.
One LatencyLab at a time
Launching the application again no longer opens a second copy. The one already
running comes to the front instead.
This also fixes the taskbar. The installer registers a shortcut carrying an
application identity that the applicat...