Repository navigation
v10.5.3 - WebUI fixes and linting + refactor to C#15. Prepare of dotnet11 - #28
Merged
Merged
Conversation
The first version of the site only walked `docs/*.md`, which silently dropped
`docs/TASKS/` and `docs/scope/` - 9 committed, public documents. The previous landing
page linked `docs/TASKS/README.md` ("Work log - open items by severity, including what
is deliberately not fixed"), so losing them was a coverage regression, not a curation
decision.
The docs route is now a catch-all and the slug mirrors the directory layout:
| File | Page |
| ----------------------------- | ----------------------------------- |
| docs/QuickStart.md | /docs/quickstart/ |
| docs/TASKS/README.md | /docs/tasks/ |
| docs/TASKS/W1-correctness.md | /docs/tasks/w1-correctness/ |
| docs/scope/I-00-project-vision.md | /docs/scope/i-00-project-vision/ |
A directory's README.md collapses to the directory itself, which is why the work log stays
reachable at /docs/tasks/. The index groups by source directory - keying on the slug filed
the work-log index under "Guides", because its slug has no path separator.
Two description bugs fixed while re-reading the cards:
- a description took only the first *line* of a paragraph, so a wrapped sentence was cut
mid-clause ("...referenced Microsoft.Extensions.AI 10.8.0 and"). It now joins the whole
paragraph and trims on a word boundary;
- stripping `#` everywhere turned "C# 15" into "C 15". Only leading/trailing markers are
heading syntax now; a `#` inside a word is part of it.
docs/habr/ stays excluded: it is a draft for another platform carrying editorial notes about
which headline to use, the same category as the gitignored .articles/.
36 pages, up from 27. typecheck, build and verify all green.
…reams The typecheck has been reporting green while checking less than it should. `npm run typecheck` printed "[Vue] Load plugin failed: vue-router/volar/sfc-route-blocks" on every run and still exited 0, so CI saw a pass. The plugin comes from vue-router, and package.json pinned vue-router@^4 - a different major from the one nuxt depends on, for a package no source file imports. Two defects sat behind that one message: vue-tsc@2 cannot load a vue-router@5 plugin at all, and the plugin also has to resolve from the project root, which it does not while it only exists nested under node_modules/nuxt. vue-router is now pinned to the major nuxt actually wants, and the toolchain moved with it: nuxt 4.6.1, vue-tsc 3.3, vitest 5, @nuxt/test-utils 4, happy-dom 20. The check is clean for the first time. Node is pinned to 22.23.3 - .nvmrc, plus one ARG across the Dockerfile's three stages - because nuxt@4.6.1 declares an exact engines range, ^22.22.3 || ^24.15.0 || >=26.0.0, that the floating node:22-alpine tag only satisfied by luck. The proxy runs every upstream call with timeout: 0, so nothing else ever ended those requests: closing the tab or navigating away left the server-side SSE connection running for the rest of the debate, one leaked stream per piece of user navigation. It now aborts its fetch when the response closes before it was written, and swallows the resulting read error, because a client hanging up is not an upstream fault worth reporting to nobody. Measured on the fixture, the upstream socket closes 6ms after the client goes away with the fix and 2699ms without it - the second being the moment the fake upstream ends its own response, which is exactly the point: a connection the proxy never cancelled closes anyway. The regression test therefore asserts the timing, not the count, since the count passes either way. Three quieter fixes. Cancel reported neither of its two outcomes, because both branches were the same line. Changing a filter did not re-query, leaving the previous results under controls claiming the new selection. And npm test failed on a clean checkout, because the SSE suite needs the built server that only CI happened to build first. Live rounds now reach a screen reader through a polite live region, each route titles itself, and buttons, inputs and rows gained hover states and a visible focus ring - the browser default being near-invisible against these dark surfaces. The server route stays on h3 rather than the new nuxt/server surface: that one omits the response-writing helpers this proxy is built on, and Nuxt's RequestEvent is not assignable to h3's H3Event. The reasoning is recorded at the import so it is not re-attempted. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The header showed the horizontal lockup. Switching it to img/delibera-square-1024x1024.png means cropping to the scales mark - x 244..778, y 170..581 - because the full lockup is 662px tall inside a 1024px canvas and the wordmark caps would render at about 3px at header size. The hero keeps the wide lockup. The crop is a wrapper with negative offsets rather than a rewritten PNG: the Pages build runs on ubuntu, where System.Drawing does not exist, so cropping at sync-assets time would work on a Windows dev machine and fail in CI. Two things the measurements turned up: - the first crop clipped the base of the scales and the left pan, because their antialiased edge pixels sit just above a strict threshold; the source background is a flat 253-254, so the threshold is 251 and the bounds carry a pixel of slack; - keeping the scale as its own custom property does not work. `calc(30px / 405)` is a *length*, not a unitless number, so multiplying it by another length is invalid at computed-value time and the box silently collapses to 0px. Dividing numbers first and multiplying by the height last stays valid. All three brand PNGs are Format24bppRgb with an opaque near-white background, so there is no alpha to blend. The mark is dark navy, which means the chip carries an explicit white plate in both themes - on a dark header the mark would otherwise be invisible. typecheck, build and verify green.
The two publish workflows looked equally protected and were not. Both gate on `refs/tags/v`, so neither publishes on a merge to main - but only the NuGet publish job ran inside a GitHub environment (`nuget-prod`). The Docker job had none. That difference matters more than the tag gate it sits next to. The gate stops an accidental merge from shipping; it does nothing about a mistyped tag, or about anyone able to push a `v*` tag. Pushing `latest` to a registry consumers pull from is not undone by re-tagging, and the multi-arch smoke checks only prove the manifest is well-formed - not that the tag was meant. `dockerhub-prod` puts the job behind Required reviewers, so a tag push queues the run and a human approves the push. Enabling reviewers is a repository setting (Settings -> Environments -> dockerhub-prod -> Required reviewers); the environment itself is created on first use, so the release path is unchanged until that is switched on. The same environment can hold `DOCKERHUB_USERNAME` / `DOCKERHUB_TOKEN` as environment-scoped secrets instead of repository-scoped ones - the job already runs inside it. build and webui-tests stay outside the environment on purpose: they push nothing and should not wait on an approval nobody can give. ReleaseProcess.md documents the approval step, since tagging now pauses the workflow.
…very merge Two changes, both about the cost of a routine merge. **Merge commits instead of squash.** Squash is what made branch handling expensive: the squashed PR's commits are not ancestors of main, so `git merge-base --is-ancestor <branch> main` cannot answer whether the work shipped, and merging main back into an open feature branch produces a disconnected merge instead of a fast-forward - which is why the branch got recreated rather than reconciled. A merge commit keeps that ancestry. `git log --first-parent main` is unaffected and still reads as the release list. This is a repository setting, not a workflow change: Settings -> General -> Pull Requests -> Merge options -> Allow merge commits. Squash can stay enabled; the team just uses merge. **`release` is tag-only now.** It also ran on every push to main, where it resolved the newest reachable v* tag and rewrote that release's body: a full fetch-depth-0 clone, a PR-notes generation and a release API call per merge, to rewrite a body that usually had not changed. The "usually" is the defect - a merge that happened to touch the release-notes header or the WhatsNew doc silently edited an already published release. The repair path is unchanged and still one click: Actions -> release -> Run workflow, with or without a tag. `dockerhub-metadata` keeps its main trigger. It is already filtered by `paths: [dockerhub/**]`, so it costs nothing on an ordinary merge and is exactly what re-syncs the Hub cards when a description is edited - the case it exists for. Documented in CONTRIBUTING.md (branch + PR conventions, including the repo-setting step) and ReleaseProcess.md (merge rule, branch deletion, the backfill table).
Bumps every packaged project from 10.5.2 to 10.5.3. Without this the v10.5.3
tag packs 10.5.2 nupkgs, and 'dotnet nuget push --skip-duplicate' skips them
silently against the already-published 10.5.2.
Converts CHANGELOG [Unreleased] to [10.5.3] - 2026-10-11 and records:
Added:
- Project website on GitHub Pages (Next.js static export in site/)
- Opt-in CORS for static browser clients (Delibera:Server:Cors:AllowedOrigins)
- BuiltIn constants extracted across Delibera.Core
- Accessibility: polite live region, route titles, focus rings
- CI improvements: dockerhub-prod environment, release pages from WhatsNew
Fixed:
- Three per-request server costs (ValidationFilter caching, Redis multiplexer, SSE writer)
- Web UI proxy leaked upstream SSE connections after client disconnect
- Web UI typecheck was passing while silently checking less (dependency upgrades)
- Three Web UI behaviours: cancel message, filter re-query, npm test pretest
- Web UI lockfile out of sync under npm 10 (unplugin@3.4.0 missing)
Changed:
- Node pinned to 22.23.3 (exact patch)
- npm pinned to 10.9.4 in Dockerfile
Adds docs/WhatsNew-v10.5.3.md, v10.5.3 sections to both READMEs, and the
DELIBERA_VERSION pin.
Verified on this tree: build -warnaserror 0 errors / 0 warnings; 635/635 tests
(493 Core + 132 Server + 10 gRPC); pack emits Delibera.{Core,Server,Redis}
.10.5.3; 44 Web UI tests passing; Web UI typecheck clean; Server nuspec
resolves Delibera.Redis 10.5.3.
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.
Pull Request
Description
Related Issues
Type of Change
Checklist
dotnet build --configuration Release)README.md,QuickStart.md)Additional Notes