diff --git a/.abcd/development/intents/planned/itd-2609100519003748-an-intuitive-control-panel-for-the-gropius-server-alice-conf.md b/.abcd/development/intents/planned/itd-2609100519003748-an-intuitive-control-panel-for-the-gropius-server-alice-conf.md index 5fc27039..fe8793f9 100644 --- a/.abcd/development/intents/planned/itd-2609100519003748-an-intuitive-control-panel-for-the-gropius-server-alice-conf.md +++ b/.abcd/development/intents/planned/itd-2609100519003748-an-intuitive-control-panel-for-the-gropius-server-alice-conf.md @@ -118,23 +118,33 @@ a redesign requirement that needs a fetched subresource to render. ## Scope Conditions -- **No build step, no framework, and nothing fetched to render.** The panel stays - plain markup, stylesheet and script under `internal/ui/static`, served from the - embedded file system. The property that holds this is testable and is stated as - such: the page renders and every control works with this Mac offline. The - documentation links the panel already carries out to the forge stay as links an - operator clicks — they are navigation, not subresources — and a link is the only - form an outbound host may take. Answers Open Question 1 with option A - (DECISIONS.md, 2026-09-20). +- **No build step and nothing fetched to render; Preact and htm vendored.** The panel + stays plain markup, stylesheet and script under `internal/ui/static`, served + from the embedded file system, plus two vendored files, Preact and htm, under + `internal/ui/static/vendor/`, each pinned to its recorded source hash. The + property that holds this is testable and is stated as such: the page renders + and every control works with this Mac offline. The documentation links the + panel already carries out to the forge stay as links an operator clicks — they + are navigation, not subresources — and a link is the only form an outbound host + may take. Answers Open Question 1 with option A (DECISIONS.md, 2026-09-20). The + vendored renderer is the trigger spc-2609201321051342 section (E) wrote down, + fired by each Settings group's live "what is in force" line; the maintainer + signed off the dependency (DECISIONS.md, 2026-10-10, from + lab-261009093853-9fed999). - **The resources block stays at the head of the Models tab.** The placement decided at interview on 2026-09-09 (itd-2609091903463596) is re-affirmed rather than re-opened: the redesign does not move it to a tab of its own, however it reorganises everything else. -- **The tabs are the panel's seven, by name: My Models, Find Models, Statistics, - Connect, Clients, Posture, Settings.** The redesign re-homes controls within and - between these; it adds no eighth tab and removes none. The usage dashboard is - the **Statistics** tab — there is no Usage tab — and the posture page - (itd-2609081718534201) is inside the scope of what is reorganised. +- **The tabs are the panel's seven, by name, and an Overview the panel opens on: + Overview, My Models, Find Models, Statistics, Connect, Clients, Posture, + Settings.** Overview is the one tab added, a read-only summary of live state + (health, memory, what is loaded, connections, recent changes) that changes no + setting; the redesign re-homes controls within and between the other seven and + removes none. The usage dashboard is the **Statistics** tab — there is no Usage + tab — and the posture page (itd-2609081718534201) is inside the scope of what is + reorganised. Overview was added by the maintainer on 2026-10-10 + (DECISIONS.md, from lab-261009093853-9fed999); the spec's information + architecture is re-planned to carry it. - **The as-you-type refusal is not this intent's to build.** It is itd-2609200823520756, the sibling this intent `builds_on`. What this intent owes it is the place the message goes: a per-field error slot beside each control, diff --git a/.abcd/development/intents/planned/itd-2609201315575657-the-dessau-server-s-face-fits-any-window-and-feels-native-on.md b/.abcd/development/intents/planned/itd-2609201315575657-the-dessau-server-s-face-fits-any-window-and-feels-native-on.md index d09147e5..a28d474a 100644 --- a/.abcd/development/intents/planned/itd-2609201315575657-the-dessau-server-s-face-fits-any-window-and-feels-native-on.md +++ b/.abcd/development/intents/planned/itd-2609201315575657-the-dessau-server-s-face-fits-any-window-and-feels-native-on.md @@ -147,11 +147,14 @@ trigger for vendoring Preact+htm. removal of `alert()` — is itd-2609100519003748 and its spec, and is not respecified here. That intent lands first; this one follows as its own lane and takes the arrangement it delivers as given. -- **The renderer trigger is written down, not exercised.** The hand-managed - re-render stays for this intent. Vendoring Preact and htm (roughly 4 kB, still - no build step and nothing fetched) is pre-committed for the moment the - hand-written exceptions to the settings-touched lock reach three, or a live - per-model row needs an editable field — whichever comes first. +- **The renderer trigger is exercised by the panel intent, not here.** The + trigger fired on 2026-10-10: the planned panel intent's live line at the head + of each Settings group passes the third hand-written exception to the + settings-touched lock, and the maintainer signed off vendoring Preact and htm + (roughly 4 kB, still no build step and nothing fetched). The panel intent + lands first and vendors them; this intent takes the vendored renderer as + given, as it takes the rest of that intent's arrangement, and adds no + renderer of its own. - **The chat client is out of scope.** Dessau Chat is the Swift client and is governed by its own records; someone using it never sees the server's surfaces. Nothing here changes the client, and no styling crosses between them beyond diff --git a/.abcd/work/DECISIONS.md b/.abcd/work/DECISIONS.md index 425f84c9..c0b2ba84 100644 --- a/.abcd/work/DECISIONS.md +++ b/.abcd/work/DECISIONS.md @@ -472,3 +472,4 @@ - 2026-10-07 — **Loopback gets its own connection budget, not a share of the remote total** (iss-2609190254516275; security review of `fix/listener-connection-caps`). With a bind to `::`, the panel's `localhost` reaches the dual-stack wildcard listener as `::1`. If loopback shared the 512 with remote peers, a LAN machine filling it would lock the operator out of the panel. Loopback now counts against a 512 of its own, and remote peers against theirs. The 32-per-address cap is a guard against accidents, not a security boundary, on a LAN where addresses are free. Shown wrong if the panel is refused while remote peers hold the listener full. - 2026-10-07 — **The prompt cache's bound is a stored real figure, and a model with none keeps no prompt cache** (iss-2610071035130302; branch `fix/runtime-budget-bounds`; `impact: fix`). Maintainer's follow-up: the uninflated per-token figure is stored as `kv_bytes_per_token` beside `kv_charge_per_token` (`KVShape.BytesPerToken`, from the same scan, held to the charge's bound and never above the charge) rather than derived at launch by dividing the charge. The launcher passes `--dessau-prompt-cache-bytes` (that figure times the served window) and `--prompt-cache-size 10`; `serve.py` hands the bound to `LRUPromptCache(max_bytes=)` and refuses a launch whose bound is missing, negative or not a whole number. A model whose figure or window is unknown follows the flat-charge precedent of `capability.LoadCostOf` (a documented fallback, not a refusal): the flat charge reserves no cache, so its bound is 0 and its server keeps nothing between requests. Upstream's own `--prompt-cache-bytes` is not passed: 0.32.0 applies it only as a trim on the batched path and never to the constructor. What would show this wrong: a real-Mac footprint sample of a model holding several long conversations above its charge, which is still owed. - 2026-10-07 — **Remedies settled for the issues the drain could not take** (maintainer, interview): Text size scales the chat's fonts itself on macOS (iss-2609200817467659); a long reply splits into one bubble per heading section (iss-2609200816105905); an operator Unload cancels an idle job's soft hold, then unloads (iss-2609202010356702); a silent child is caught by one bounded first completion during readiness, with the 2026-09-21 step floor untouched (iss-2609211754253878). Five more had their remedy stated in their own record and were written without a question (iss-2609190200104841, iss-2609200818340380, iss-2609200822241060, iss-2609200823585535, iss-2609210738484563). iss-2610041945038826 now opens "Waits on" the decision-model spec, as decided earlier today, so a drain hands it back by rule. +- 2026-10-10 — **The dashboard lab's open findings, settled** (maintainer, interview on lab-261009093853-9fed999's harvest). (1) The settings form letting the browser refuse a save is captured as a bug with its remedy, `novalidate` plus a test watched failing (iss-2610091901043167), for a drain to take. (2) The panel opens on an Overview tab, an eighth beside the seven named ones: itd-2609100519003748's scope condition cond-2609201007367077 ("adds no eighth tab") is narrowed to admit it, and the spec's information architecture is re-planned to carry it. (3) The panel redesign (itd-2609100519003748) lands before the window intent's ES-module split (itd-2609201315575657), so PANEL-AC11's "tests unchanged" holds against a frozen base and WINDOW-AC5 rewrites the guard and harnesses afterwards; this re-affirms the window intent's own cond-2609201321050310 and needs no record change. (4) Each Settings group's live "what is in force" line counts as more than the one exception the lock allows a third of, so spc-2609201321051342 section (E)'s trigger fires: Preact and htm are vendored as two files under `internal/ui/static/vendor/`, source-hash pinned, no build step and nothing fetched; this line is the maintainer's sign-off for that dependency, and the panel intent's cond-2609201007368809 and the window intent's cond-2609201321052790 now say so. (5) Not asked, one defensible answer: the panel spec's out-of-date inventory (eight ids added since it was written) is refreshed as part of PANEL-AC1 when the redesign is built, since that criterion already requires a complete inventory. diff --git a/.abcd/work/issues/open/iss-2610071803140628-the-discord-bridge-offers-and-keeps-a-channel-on-a-model.md b/.abcd/work/issues/open/iss-2610071803140628-the-discord-bridge-offers-and-keeps-a-channel-on-a-model.md new file mode 100644 index 00000000..516fbdb5 --- /dev/null +++ b/.abcd/work/issues/open/iss-2610071803140628-the-discord-bridge-offers-and-keeps-a-channel-on-a-model.md @@ -0,0 +1,15 @@ +--- +schema_version: 1 +id: "iss-2610071803140628" +slug: "the-discord-bridge-offers-and-keeps-a-channel-on-a-model" +severity: "minor" +category: "ux" +source: "user-observation" +found_during: "Discord bridge use, 2026-10-07" +origin: researcher-authored +production_mode: hand-written +found_at: "internal/bridge/discord" +remedy: "Leave a model with a recorded load failure out of /model's list (or list it marked as not loading) and refuse naming it there; when a channel's model has a recorded load failure, reply that it does not load on this server and to choose another with the /model command, without the log's detail; recognise a mention whose text is only '/model' and point to the slash command; tests for each in internal/bridge/discord." +--- + +The Discord bridge offers, and keeps a channel on, a model that has a recorded load failure, and its refusal gives no way out. On 2026-10-07 a channel set to eins78/Kolibri-1-mlx-mixed-4-8-bit (model type kolibri1, which the pinned mlx-lm 0.32.0 does not support, iss-2610070546301424) answered every mention with the generic 'cannot serve this model right now': the first request tried the load and failed in 1.5 s, and the next ones were refused at once (class not_ready) because the load failure is recorded. /model still listed the model, and nothing in the reply suggested choosing another; the user then typed '@Dessau /model' as text, which the bridge passes to the model rather than to the slash command. Nothing in internal/bridge/discord reads a model's load failure. diff --git a/.abcd/work/issues/open/iss-2610091901043167-the-settings-form-lets-the-browser-refuse-a-save.md b/.abcd/work/issues/open/iss-2610091901043167-the-settings-form-lets-the-browser-refuse-a-save.md new file mode 100644 index 00000000..840e150b --- /dev/null +++ b/.abcd/work/issues/open/iss-2610091901043167-the-settings-form-lets-the-browser-refuse-a-save.md @@ -0,0 +1,15 @@ +--- +schema_version: 1 +id: "iss-2610091901043167" +slug: "the-settings-form-lets-the-browser-refuse-a-save" +severity: "minor" +category: "bug" +source: "agent-finding" +found_during: "lab-261009093853-9fed999" +origin: researcher-authored +production_mode: hand-written +found_at: "internal/ui/static/index.html" +remedy: "Add novalidate to #settingsForm and a test, watched failing at the pin, that the form carries it so the browser never gates Save; the server stays the only judge." +--- + +The settings form lets the browser refuse a save. #settingsForm carries no novalidate while its number inputs declare min, max and step, so browser constraint validation blocks Save on the page's own judgement: a grace period of 1.5 under step="1" is refused though the server accepts it. TestNoSettingsControlIsNarrowerThanValidate covers min and max but not step or type. PANEL-AC13 and VALIDATE-AC6 forbid page-side gating.