Repository navigation
fix: three bug fixes and the session's records (staged update fallback, LFS update check, idle clock) - #202
Merged
Merged
Conversation
A staged update removed the old copy as soon as the new record was written, after the directory checks and the launcher's Precheck. A new version can pass all of those and still fail to load, and then nothing was left to fall back to: the model stayed unusable until the operator downloaded an older version by hand. The old copy is now held aside (App.fallbacks) until the pool reports a load of the new version whose readiness probe was answered, and is removed then. A first load that fails on its own puts it back through the same swap an update makes, claimed as a download so Download, Delete and Close wait for it; the record is rewritten for the old version with no load failure, update_failed "load" (new class, with words on the card), and the newer commit still offered. Deleting the model removes the held copy too, and a later update replaces it. Restart: the held copy is not leaked or lost. Nothing new is persisted; at start the newest complete aside copy beside a model folder that checks out is held again, unless a copy of that model was put back at the same start. This replaces the earlier rule that removed such a copy at start as stale. Its version is not known after a restart, so one put back then is recorded as version unknown, which Update brings to the current version. Resolves: iss-2610042101430192 Assisted-by: Claude
…hecked The update check reads a newer version's config.json to tell whether it names a model_file, code Dessau will not run. A repository that keeps that file in Git LFS has the Hub hand it to its content CDN; the check's read refuses any answer off the Hub's origin, and the check treated that refusal as "offer it". So a newer version that ships its own code was marked available with Update offered, and only the update's own checks refused it after the whole download. SmallFileAt now takes the file as the listing gives it. A git file is read through do exactly as before. A file the listing keeps in LFS with a sha256 is read through doContent, which follows the CDN hop as a download does, drops the token from any hop off the Hub's origin, and the body is held to the bound (a listed size past it is refused before asking) and to the sha256. When the config cannot be held to that hash (off-origin with no sha256, a mismatch, or past the bound) the version is recorded with the new cannot_check status, which the card shows as "newer version not checked" and both Update() and the panel refuse. A CDN that does not answer is counted unreachable, as a Hub that does not answer is. Resolves: iss-2610042101439623 Assisted-by: Claude
The idle check the self-test and the context probe share read only the pool's resident entries: each model's in-flight count and last use. A model's figures leave the pool with it, so a request that ended unreachable on a wedged model that was then unloaded or stopped left no trace, and a request the pool never admitted (still uploading, refused, failed before a model was chosen) never touched the clock at all. On 2026-10-04 that let the self-test start a minute after a client's last unreachable request with the idle threshold at an hour: the remaining models' last use was 17:34, over the hour by 18:45. The record guessed the clock counted only requests that reached a model; the cause is that it lived on the model's pool entry. The gateway now counts every completion request and every Ask from the handler's start to its return (selftest.Clients, wired from App.Clients through gateway.Options.Clients), and the idle loop holds while one is in flight and for the threshold after the last. A long request keeps the Mac busy while it runs, not only when it ends. The context probe drives its model through the gateway, so a last request no later than the loop's own latest release is discounted, as the pool's stamp of that release already is. The pool is unchanged; the gateway change is the counter alone. Resolves: iss-2610041945030758 Assisted-by: Claude
A second update made before the first update's version had loaded replaced the held copy with the version the second update displaced. That version had never loaded, so when the newest one failed its first load too, the copy put back was one that had never served, and once it failed nothing was left to fall back to. The held copy now stays, and the second update's own aside copy is removed instead. The restore's comment now says that a Download is refused while a restore runs, rather than waiting for it, and the update docs say that both versions take disk space until the first load. Found by an independent review of the previous commit. Refs: iss-2610042101430192 Assisted-by: Claude
A request turned away for a missing or wrong key, or from an unpaired client, is refused before the gateway counts it. The docs said every request counts however it ends, including refused ones. The idle check's comment also said a request in flight is never the loop's own. A context probe step that timed out can leave its handler running past the run, so the comment now says what that costs: one idle threshold. Found by an independent security review of the previous commit. Refs: iss-2610041945030758 Assisted-by: Claude
A state-of-the-art survey of MLX serving performance found two budget defects Dessau has today: the prompt cache has no byte limit, and the pool admits twice the requests it charges for. It also found two seeds (measure batching on this Mac; MTP once upstream releases it) and three capabilities that comparable servers ship: compact KV memory per model, a prompt cache kept on disk across unloads, and structured output to a schema. The maintainer adopted the routing unchanged, as graded in the calibration note. Assisted-by: Claude
abcd v0.13 renamed its home from ~/.abcd to ~/.abcd.noindex, and the OPINIONS rule it injects quotes the new name. The principle file still quoted the old one, so the archtest that holds the file to the rule verbatim failed on every machine with abcd installed. CI skips the test because abcd is not on its PATH, so main stayed green there. Assisted-by: Claude
…triage Kolibri 1 (an Aleph Alpha MoE in 4-bit MLX) cannot load while mlx-lm 0.32.0 lacks its architecture. Its repo ships the architecture as Python, which Dessau never runs, so the issue waits for upstream support to be released and then a pin bump. The decision-model over-charge turned out to be the automatic served window filling the budget, which every model gets. The maintainer folded it into the decision-model spec rather than ship a stopgap, and the issue's remedy, triage note and decision line now say so. Assisted-by: Claude
The security review of the update check's LFS fix approved it and left info notes. The content fetch's token strip is not sticky across a leave-and-return chain, and the fetch follows an https-to-http hop. The download path's redirect policy is laxer than the new fetch's. A CDN refusal is also worded as a token problem. None blocked the fix; each is filed with its remedy. Assisted-by: Claude
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three bug fixes, each built test-first on its own branch and checked by an independent reviewer. The review findings are applied. This PR also carries the records from the same session.
Fixes
impact: fix). The old copy stays aside until the new version's first load passes readiness. If that load fails, the old copy goes back automatically and the card says why. A second update before any load keeps the version that last served. Reviewed by an adversarial code reviewer, whose major finding (a second update discarded the version that served) is fixed with a regression test that fails without the fix.config.jsonkept in Git LFS, and never offers an unchecked version (iss-2610042101439623,impact: fix). The check used to fail open when the Hub redirected to its content CDN. It now follows the redirect, bounded and checked against the listed sha256, and strips the token off-origin. A version whose bytes cannot be anchored is markedcannot_checkand is not offered. Security review: approved. Its info notes are filed as follow-ups.impact: fix). A request whose model has left the pool, or that never reached it, now holds the self-test and the context probe, both while it runs and for the threshold after. Security review: approved. Its two low findings (docs wording, a comment) are fixed.~/.abcd.noindex/, sointernal/archtestpasses again on machines with abcd installed. CI skips that test.Records
Gates (on the head pushed)
gofmt -l .empty;go build ./...;go vet ./...(darwin and linux)make test: 26/26 packages pass under-race