# Changelog

One line per shipped version, newest first. The number is the one the page footer shows. Versions are four numbers read
as a version, not as one counter: 1.0.0.1 to 1.0.0.187 counted the builds that
reached the live site, and 1.0.1.0 is the first release I called polished. How a
line gets here, and why there is only ever one sentence, is recorded in
ADR: The changelog under the Decision Records index. From 1.0.0.41 the top
line here is where the deploy reads the version from, so this file and the page
footer cannot disagree (ADR: The version comes from the changelog). One number
is missing, 1.0.0.39, skipped under the older formula when a red build consumed
a deploy run number.

## In plain words

This page has one entry for every version that shipped, newest first. Each entry gives its date and a sentence on what changed. The deploy reads the version number from the top entry, which keeps this file in step with the number in the page footer.

What that is worth: a developer can find when any behaviour changed and which record explains it, and the organization gets a release history that matches what is running, version for version.

- **1.0.3.161** (2026-10-17): Two pages under Architecture overview, Onion / Clean Architecture and SOLID Principles, read the pattern and the five principles against this codebase with the project files, the ports, the ring tests and the gate’s two store passes shown live, and the textbook onion is drawn beside TheYard’s rings on its own page (ADR: Onion and SOLID).
- **1.0.3.160** (2026-10-17): A quotation on About Steven reaches the edge of the panel it stands in, as it does on the landing page: the indent a document gives its own lists was moving every one of them in, and the browser tests now hold both pages to the same edge (ADR: The sidebar, the addendum on its own section).
- **1.0.3.159** (2026-10-17): The first screen reads the running site: a band of three instruments under the title says how fast it answers, what it has cost Azure this month and how long it has been up, from one new public reading at /api/pulse, and the figures leave the sentence (ADR: One reading for the first screen).
- **1.0.3.158** (2026-10-17): What colleagues say is a section of its own beside the first screen, its heading the link to the page the recommendations were written on, with Freya and Vincent under them and a width that leaves neither column dominating the page (ADR: The sidebar, the addendum on its own section).
- **1.0.3.157** (2026-10-17): Every workflow names the Ubuntu image it runs on rather than the label that moves on 19 October, and the two browser tests that waited for a quiet network wait for the page to have drawn what it fetched (ADR: The deploy pipeline, the addendum on the runner and the wait).
- **1.0.3.156** (2026-10-17): The name of each person who wrote a recommendation opens their own page on LinkedIn, from a seventh field in the one file the words live in, held by the gate to being a profile and one per writer (ADR: The sidebar, the addendum on the name opening the page).
- **1.0.3.155** (2026-10-17): Every recommendation is shown whole on both the landing page and About Steven, under the name, title, relationship and month of the person who wrote it, and the link that used to send a reader elsewhere for the rest of the words is gone (ADR: The sidebar, the addendum on whole, on both pages).
- **1.0.3.154** (2026-10-17): What colleagues say stands in the page itself on both pages, every recommendation one under the next as far down as there are quotations, so the page's own bar is the only scroll bar on the screen (ADR: The sidebar, the addendum on one scroll bar).
- **1.0.3.153** (2026-10-17): About Steven reads what colleagues say from /api/recommendations in full, in a column that follows who he is in the document and stands to the right of every other panel on a wide window, and the document keeps only the heading and its sentence (ADR: The sidebar, the addendum on About Steven's column).
- **1.0.3.152** (2026-10-17): What colleagues say stands in a column on the right of the landing page, read from the new /api/recommendations, which serves the ten from one file in one shape so a recommendation is added by adding an entry and moving the count the tests hold (ADR: The sidebar, the addendum on the column on the right).
- **1.0.3.151** (2026-10-16): The activity card's bars draw at the card's real width, so their words stay the chart text size on a wide desk instead of scaling up with the drawing (ADR: The Admin tab as a product, the addendum on the bars at their real width).
- **1.0.3.150** (2026-10-16): On a phone the Admin tab's words sit under the tiles from the first paint, not a frame later (the CSS order rule is back as the fallback for the paint before the browser has read its width); the phone test waits for the move instead of racing it; the gate's comment names the two builds its numbers read (ADR: The Admin tab as a product, the addendum on a second reader).
- **1.0.3.149** (2026-10-16): The Shed's Docs view, read at 1440 and tidied: no sideways scrollbar under its list, the document's scrollbar at the panel's edge, two documents no longer sharing the name Built with AI, a footer in TheYard's form, and the explainer PDF rebuilt at that version (The Shed 1.0.0.43).
- **1.0.3.148** (2026-10-16): The About page and the diagram pages wear the site's face from the site's own font file, so no page opens in the system's face and no page asks Google for one; the drawing beside How I lead sits on the panel without a ground of its own (ADR: Diagram pages, the addendum on the site's face).
- **1.0.3.147** (2026-10-16): Six small things from a read of the live page: the traffic card's words at one height across its four blocks, the activity card's bars as wide as its table, the tests table's last rule gone, headroom over the activity chart's peak, a shade where the sidebar's list runs under its pinned block, and a thin scrollbar under What colleagues say (ADR: The Admin tab as a product, the addendum on six small things).
- **1.0.3.146** (2026-10-16): The Admin tab writes a number one way: megabytes and request units grouped by thousands wherever they appear, a percentage sign closed up to its figure, the log card's first line saying what it counts, the Azure card naming the container image, and a Normal line reading as one sentence (ADR: The Admin tab as a product, the addendum on one way of writing a number).
- **1.0.3.145** (2026-10-16): Two things written down: the commit on main is the gated commit with its results folded in, and why that is safe (ADR-068, the addendum on the commit on main); and a one-call admin reading is a delegate, not an interface (ADR-080, the addendum on the delegate). The ship's own script, outside this repository, now deletes its gate branch once both domains answer.
- **1.0.3.144** (2026-10-16): The gate measures the page's size and the outdated packages only after both builds passed, so a failed build reads as not measured rather than 0 kB, and the test that holds every recorded check to the verdict now sets aside only the measuring step (ADR: The Admin tab as a product, the addendum on a green build).
- **1.0.3.143** (2026-10-16): On a phone the Admin tab's paragraph follows the tiles in the document, not only on the screen, so a keyboard reaches the tiles first the way the eye does (ADR: The Admin tab as a product, the addendum on the reading order).
- **1.0.3.142** (2026-10-16): `/resume` is in the API document with its name, a sentence and its PDF response, as ADR-075 asks of every public endpoint (ADR-099, the addendum on the API document).
- **1.0.3.141** (2026-10-16): The Shed's explainer PDF says 148 xUnit and 21 node tests, the counts of the suites that ran when it was built, instead of a default left from an older build (The Shed 1.0.0.42).
- **1.0.3.140** (2026-10-16): The Shed has a section in the sidebar and a tile on the landing page under How it is built, opening the running app and its code in a new tab; its folder moved to samples/theshed and its documents describe it as a developer test project without naming a company (ADR: The sidebar, the addendum on The Shed).
- **1.0.3.139** (2026-10-15): The Overview's cost row gives the bill reader's own reason when there is no bill, so a read Cost Management slowed down no longer says this site does not read the bill (ADR: The Admin tab as a product, the addendum on the reason for no bill).
- **1.0.3.138** (2026-10-15): Polish after the ship: the Overview puts the day and month in front of a restart or a roll that was not today, Sarah Sebestyen's sentence on the landing page is quoted whole from its first word, and a resume opened through a door gets its own page-name test (ADR: The Admin tab as a product, the addendum on the date in front).
- **1.0.3.137** (2026-10-15): The Azure card's storage reading follows a relational store that came up late: the hourly read looks the store up each time instead of once at startup, so a store the second chance attached shows its size within the hour, not after the next restart (ADR: The Admin tab as a product, the addendum on the late store).
- **1.0.3.136** (2026-10-15): What colleagues say, sideways: the landing page's row carries one sentence from each of the ten recommendations and scrolls across, and About Steven's panel of the ten sits in one row that scrolls the same way, a named region a keyboard can reach, instead of five rows of two (ADR: The sidebar, the addendum on the row).
- **1.0.3.135** (2026-10-15): What colleagues say: the ten recommendations on Steve's LinkedIn profile, quoted word for word under the name of the person who wrote them, as a panel of About Steven, and three of their sentences on the landing page with a link to the rest (ADR: The sidebar, the addendum on what colleagues say).
- **1.0.3.134** (2026-10-15): The Site activity card says which door the resume was opened through: LinkedIn, an application, an email, the signature, a post, another link or the site itself, as bars over the window's visitor-days, people only, from a `doors` list on the activity report that names a door by its word and nothing else (ADR-099, the addendum of 15 October).
- **1.0.3.133** (2026-10-15): The resume has an address, `/resume`: the locked resume, byte for byte, inline in the browser under the name StevenStoutResume_2026-09-29.pdf, and a link may say which door it was handed out through (`?src=linkedin`, application, email, signature or post; anything else is other), which the activity card counts as `/resume/linkedin` in the resume step without ever recording the query string; ResumeAddressTests holds the bytes to the lock's hash in `wwwroot/docs/resume.sha256` (ADR-099, The resume has an address).
- **1.0.3.132** (2026-10-15): The Azure card says how many days are left on the certificate the site answers with, amber under 30 and red under 7, and how full the relational store is against its tier's ceiling, amber at 80% and red at 95%, both read once an hour outside any request (ADR-080, the addendum of 15 October on the certificate and the storage).
- **1.0.3.131** (2026-10-15): The tests card gains CODE HEALTH: the build's warnings, red over zero, the gate's seconds against five minutes, the page's built size, and the npm and NuGet packages with a newer release, measured in a step of the gate's own that turns nothing red, with the last thirty gates behind More, carried forward in `data/test-results.json` (ADR-080, the addendum of 15 October on code health).
- **1.0.3.130** (2026-10-15): On a phone the Admin tab opens on its tiles: the paragraph under the title and What this shows follow the strip, so the first tiles are on the first screen; the Overview is the card the axe scan reads on the tab, and the green, amber and red tone words are held to 4.5:1 on their soft grounds (ADR-080, the addendum of 15 October on the phone).
- **1.0.3.129** (2026-10-15): Every Admin card says loading, a failed read with its next try, or an empty read the same way, with one status line (`CardState`); the machines card folds its three twenty-row tables behind More under its charts, the log card counts its lines by level before a folded table, and an empty error list is one line; the cards take their title size, quiet-text size, padding and gap from tokens in the token sheets (ADR-080, the addendum of 15 October on folding).
- **1.0.3.128** (2026-10-15): The Admin tab opens on an Overview, the four questions answered in five seconds: is it up (every check and every page, when the process last started and when the site last rolled, at which version), is it fast (the typical answer and the ninety-fifth), is it costing anything (the month so far and the Azure forecast against a budget of $50 a month, red over it), and what broke (errors, 5xx answers and any failed kept-warm read), each with its normal range under the number; every amber and red line on the tab now comes from one table, `src/lib/ranges.ts`, which the tiles read too, and seven cards print their range under the title; the Backends card names this site's build beside the other site's, read through the peer, and the process under both columns (when it started, what the runtime compiled itself, the collector), and the Azure card says when Azure answered (ADR-080, the addendum of 15 October on the Overview).
- **1.0.3.127** (2026-10-15): Every chart on the Admin tab whose slots are days or parts of days, the Site activity chart and the kept machine charts over a week or a month, names its Mondays and Fridays on the axis with their dates, the month written once, and washes its weekends in a faint band, so a quiet stretch reads as a weekend or as an outage at a glance; the hour and the day keep their clock labels, and a week on the activity card, which already names every day, gets the wash only (ADR-080, the addendum of 15 October).
- **1.0.3.125** (2026-10-14): `npm run test:all` prints a short summary instead of every log line, in TheYard (xUnit on SQLite, then Vitest) and in The Shed (xUnit, the TypeScript build, then the node tests): a Node script with no dependencies, `scripts/test-all.mjs` in each, runs each step with its output captured and prints one line per step with its counts and time, and a failing step prints everything it printed, then the summary, and exits non-zero; `npm run test:all:full` keeps the full log, The Shed's `.vscode` gains the task Shed: test all (full output), and both READMEs and Working in VS Code show the command and a sample of the summary. No app code changed.
- **1.0.3.124** (2026-10-14): The Shed gains one command for every test, `npm run test:all` (the 145 xUnit tests, the TypeScript build, then the 21 node tests, stopping at the first failure), with the task Shed: test all in its own `.vscode`; its README and Working in VS Code give the command, and The Shed ships as 1.0.0.38; the API names System.Security.Cryptography.Pkcs at 10.0.13, the patched release, because the 9.0.11 that SQL Server's client brings fell under two advisories on 13 October and turned the build red (ADR-089, the addendum of 14 October).
- **1.0.3.123** (2026-10-13): The ship's gate runs on a GitHub runner instead of the 8 GB laptop: the laptop builds the commit and pushes it to a gate branch named for the version, gate.yml runs every check the laptop's gate ran (The Shed's suites on Windows beside it), and the laptop fast-forwards main only on a green run, with GateWorkflowTests holding the workflow to every check, report and verdict (ADR-098, The gate runs where the memory is).
- **1.0.3.122** (2026-10-13): Working in VS Code was rehearsed from a fresh clone, every task and launch configuration run, and it now carries all seven screenshots (the Testing panel, the API stopped on a breakpoint, The Shed on F5), the measured times, the Inventory and sign-in steps the demo needs, and two fixes the rehearsal found: F5 on The Shed no longer asks for an HTTPS certificate it does not use, and The Shed's README says what plain dotnet run does with https.
- **1.0.3.121** (2026-10-13): The editor is set up by the repository: a `.vscode` folder in TheYard and one in The Shed carry the recommended extensions, the workspace settings, every README command as a task and F5 for the API, the page in Chrome and The Shed; a Working in VS Code page under App Architecture walks a new developer through it with screenshots; WorkspaceTests holds every task, port and launch configuration to the tree and the page (ADR-097).
- **1.0.3.120** (2026-10-13): A Best Practices page, Ahead-of-time compilation, explained, teaches ReadyToRun from the build that uses it: what the runtime does with intermediate code on one shared core, the one publish switch in the Dockerfile, the three runtime settings written out in the project and why, the Admin reading that counts what the runtime compiled itself, the tests that hold all three, what was left out and why, and the five rolls measured, with what held (49 to 62 per cent fewer methods compiled by the runtime) and what did not (no faster start, on a saturated core); a new drawing, Compiled before it ships, puts the two containers side by side, and ADR-094 points at the page.
- **1.0.3.119** (2026-10-10): The Performance page gains "The gate on an 8 GB laptop, measured on 10 October": every lever of the day with its before and after read from the gate's own results and kept or dropped on those numbers (the browser pass on SQLite 545 to 742 s on 9 October to 401 s at 1.0.3.118; the gate 875 to 905 s to 655 for a ship of the same shape), what the laptop was carrying on the way in, plus the lesson of the one-tab measurement that did not reach the gate; ADR-068 carries 1.0.3.118's numbers.
- **1.0.3.118** (2026-10-10): The coverage read arrives at each app page the way Back and Forward do (the address set with a popstate fired behind it, so the app re-reads its view) after one cold load per tab, instead of a cold load of the whole application for every one of about 380 pages a run; the same reader returns the same facts for every page at every width, proved page by page before it shipped, with ADR-068 carrying the gate's numbers for 1.0.3.117 beside it.
- **1.0.3.117** (2026-10-10): The first of the five waits a store gets at startup is read from a setting (Store:FirstWaitMs, two seconds unless set), so the test that proves the fallback to files can set it to zero: the five asks are the proof, while the thirty seconds between them held every xUnit pass on both stores to no less than half a minute; nothing deployed sets it, and ADR-068 carries the gate's numbers for 1.0.3.116 beside this.
- **1.0.3.116** (2026-10-10): The coverage read, every listed page at three widths, waits on the page's own signals (the load event, then the view's own signal, then the faces loaded with two frames painted) instead of a quiet network and a timer, which measured as four fifths of each page's cost; the same reader returns the same facts for every page, and the gate's own numbers before against after are in ADR-068.
- **1.0.3.115** (2026-10-09): The Performance page gains the section for the day's speed steps, each read before and after: the drawn document window's layout shift on a desk 1.000 to 0.000, the edge's copy of an anonymous page 460 to 495 ms to 46 to 99 ms, what the phone preset can and cannot say on one machine, and the four steps measured and not done with the numbers that decided them; ADR-096 carries both after-numbers, and Site traffic's kept-log page shows the one function every kept string passes through.
- **1.0.3.114** (2026-10-09): Twelve decision records that explain one piece of code now show that piece, read live from the build in a region the file already carried: the interceptor, the SQL log port, the Dockerfile manifest, the lockout, the registration window, the broken-windows markers, the listing refresh timer, the document slug, the sitemap check, the versions test, the exception slot and the page sweep's second look.
- **1.0.3.113** (2026-10-09): The five pages that describe the code show it, read live from the build: the overlay, the fetch seam and the sold rule on Data flow, the rings test on Projects, the loaders on Start here, the signing key's rule, the lockout and the session's store check on Security, and the one pasted example on Style replaced by the method it was pasted from.
- **1.0.3.112** (2026-10-09): The four pages that describe how the site is hosted and rolled show the code they talk about, read live from the build: the edge's rules and the rendering service's web app on Hosting, the plan's size on the Infrastructure overview, Deploy Render's roll and check and the edge's ignore rule on CI/CD, and the font preload plugin on the Web overview, whose table of pieces now carries the sizes of the build that runs.
- **1.0.3.111** (2026-10-09): The first bid on a vehicle nobody has bid on can be placed again: the panel's stale-minimum rule read the opening ask as a stale minimum and disabled Place bid on every untouched vehicle; the rule moves to src/lib/auction.ts as minimumIsStale, stale only once a bid stands, with a unit test, and the account spec now bids on such a vehicle instead of the most-bid one the simulated room and the market spec are both raising, which is the browser test that was red before the fix.
- **1.0.3.110** (2026-10-09): The edge keeps a page drawn for nobody for ten seconds, then twenty more while it fetches a fresh one behind the visitor: the rendering service sends the edge its own rule on any page request that carried no cookie, keyed by the whole query and by the session cookie, and a request with a cookie is answered fresh and never stored anywhere shared. The browser is told nothing new and still asks every time.
- **1.0.3.109** (2026-10-09): The three Node stages of the two images pull node:24-alpine from AWS's public mirror of the Docker official image instead of Docker Hub, after Deploy for 1.0.3.108 failed three times on Docker Hub's anonymous pull limit for GitHub's runners; no account, no secret, the same image, and the two tests that read the Dockerfiles follow it.
- **1.0.3.108** (2026-10-09): A tenth drawing, A page drawn on the server: the first load from the address through the edge's page rule and the rendering service's reads to the browser painting, then the takeover, where React attaches to the HTML instead of drawing it again. It opens on its own page after The two sites in the Diagrams section, with a row in the sitemap and a preview on React server rendering, explained; ADR-020 and ADR-096 say so.
- **1.0.3.107** (2026-10-09): The drawings agree with what runs. The infrastructure picture carries the rendering service beside the API's process on a B2 plan, with the edge's page rule and the third deploy beside the two; the two-sites drawing has the service as a third web app the page rule reaches, reading each site's API and opening no store; the data flow has the service drawing a page from the same read path and the browser starting from its first load; the side-by-side drawing prices the plan at $24.82; and `AppServiceTemplateTests` holds the two drawings' sources to the plan size as it holds the pages.
- **1.0.3.106** (2026-10-09): Every document agrees with what runs. The seven pages that describe the running system, from Hosting to the README, now say the plan is B2 at $24.82 a month ($34.79 in all) shared by three web apps, that a rendering service draws every page with Deploy Render rolling it on the same push as the two sites, and where `render/` sits; `AppServiceTemplateTests` reads the plan's size from the template and fails until every one of those pages names it.
- **1.0.3.105** (2026-10-08): A Best Practices page, React server rendering, explained, teaches the rendering service from its own code: what server rendering and hydration are, the four differences between a server and a browser this site had to answer, the stream, every decision beside the number that decided it, and the before and after on both domains; the Performance page and ADR-096 carry the same numbers, and a document window drawn on the server now stands where its modal opens, so it no longer jumps when React takes the page over, which a browser test holds.
- **1.0.3.104** (2026-10-08): Every page is drawn on a server: the edge sends each domain's page to the rendering service under that site's name and everything else to that site's API, so a visitor's browser receives the inventory, a vehicle or a document already drawn with its data in it and React takes it over; `/index.html` still draws in the browser as the way round, and ADR-096 is accepted.
- **1.0.3.103** (2026-10-08): The rendering service's site is in the templates and rolls with every push: `infra/render.bicep` describes APP-THEYARD-RENDER-SS on the plan, with no secret in it, `main.bicep` names it, both templates now say B2, and `Deploy Render` builds `render/Dockerfile` as the version the sites carry and waits for the service's own readiness; ADR-096 and ADR-079 say why, and tests hold each setting.
- **1.0.3.102** (2026-10-08): The rendering service's image, `render/Dockerfile`: Node and the service's own build at 62.4 MB, with no `node_modules` and no sources. Measured alone in Docker before anything ran in Azure, it draws a page's top in under 10 ms and the whole inventory in about 100 ms, holds 52 MiB idle and 136 MiB at its peak, and draws about ten inventory pages a second on one core; ADR-096 carries every number, and the memory gate that moved the plan to B2.
- **1.0.3.101** (2026-10-08): The image builds again: 1.0.3.100 passed its gate and never rolled, because a new test read `data/vehicles.json` and the image's frontend stage copies only `src/` and `public/`, so Deploy stopped at Build and push. The test's vehicles are written out in the test now, and `DockerBuildInputsTests` fails any file under `src/` that imports from outside what the stage copies.
- **1.0.3.100** (2026-10-08): A rendering service beside the API, in the repository and not yet running anywhere: `render/` draws any address on request with its data already in the page (the list, a vehicle, a document, who is signed in), the browser takes that markup over instead of drawing it again, and the API stays a service that answers in JSON; every view is drawn in a test with no browser, the drawn pages are taken over in Chrome with no hydration error, and ADR-096, proposed, teaches how each part works and why.
- **1.0.3.99** (2026-10-08): Deploy waits as long as a roll takes: Verify gives the new build twenty-five minutes to answer and thirty seconds a read, read off the rolls since 1.0.3.95, after a ten-minute wait reported the roll of 1.0.3.98 as failed while both sites served it; both jobs get fifty minutes, `DeployWorkflowTests` holds the numbers, and ADR-009 says why.
- **1.0.3.98** (2026-10-08): Every performance number recorded on 7 October is read again against its log and says what the log says: the roll probe's 30 seconds is a wait on the socket and not a limit on a read, so the slowest-answer column on ADR-095 and the Performance page now gives the slowest read after the new container's API answered on every row, the rolls of 1.0.3.95 to 1.0.3.97 join both tables, ADR-094 gains the four rolls compiled ahead of time read beside the plan's own meters (less compiling on every roll and no faster start measured; what held the core is left unresolved), and seven smaller figures in ADR-060, ADR-092, ADR-093 and ADR-094 are corrected. Documents and the probe's docstring only.
- **1.0.3.97** (2026-10-07): The template keeps both sites linked to their Application Insights component: a deployment writes a site's tags whole, and the what-if showed the next one would drop the hidden link tag from the Azure SQL site; `AppServiceTemplateTests` holds it, and ADR-079 says why.
- **1.0.3.96** (2026-10-07): Blue-green, measured and held: ADR-095 keeps what every roll since 1.0.3.89 cost a visitor, read by the same probe (now `scripts/probe-roll.py`), why the stretch with no answer is App Service swapping the container on one instance, and what removing it would cost; the Performance page gains the roll-by-roll table and ADR-094 its after reading; the four leftover containers removed on Steve's word are recorded in ADR-079. Documents and the probe only.
- **1.0.3.95** (2026-10-07): The Decision Records section reads its rows from the records themselves, sorted by number, instead of a hand-kept list of 95 rows that had just taken `sections.ts` past the 300-line rule; a test holds the order, and ADR-029 says where a new record goes now.
- **1.0.3.94** (2026-10-07): The API is published compiled ahead of time for linux-x64 (ReadyToRun), so a new container starts by running this app's code and its libraries' instead of compiling them on the plan's one shared core; tiered compilation and profile-guided optimization stay on, garbage collection is pinned to the smaller workstation mode, and ADR-094 records each setting, what was left out, and the reading before; tests now hold the build's real runtime configuration, that each deploy waits for readiness, and what is already in place for server rendering (ADR-092's addendum).
- **1.0.3.93** (2026-10-07): The pipeline's close-out: the readiness test that could not fail now can, the arrival read shows the forwarded headers as they arrived, the comments say exactly what the edge does and does not guard, three behaviours gain tests, and the Admin metrics say how much code the runtime compiled itself since it started, the reading the next version is measured by; ADR-093 gains the after reading and the review.
- **1.0.3.92** (2026-10-07): The request pipeline in the order Microsoft documents for an app behind a proxy: the page, the bundle and the photos are answered before the sign-in, the session and the store are read, the visitor's address and scheme come from the forwarded headers counted from the right instead of three hand-read headers, the health probes end at routing, the error record sees a failure while signing in, and an HTTP logger that never wrote a line is gone; ADR-093 explains every position.
- **1.0.3.91** (2026-10-07): The roll of 1.0.3.89, read every two seconds: listening first took the slowest reads after a roll from as much as 112 s down to 7 s, and did not shorten the three minutes in which nothing answers, which is App Service replacing the container on its one instance; the record that blamed the catalogue load says so. Documents only.
- **1.0.3.90** (2026-10-07): The numbers after the landing page was drawn at build time, on both live domains: the largest paint 0.2 to 0.7 s sooner and the speed index 0.4 to 0.7 s lower on a phone, blocking time up on the Azure SQL site; the Web overview's load order read again on the bare address, and the load-order script reads it there. Documents and the measuring script only.
- **1.0.3.89** (2026-10-07): A new container answers before it has loaded the hundred thousand vehicles instead of after, so a deploy no longer leaves the site dark for one to three and a half minutes while the old container is gone and the new one is still loading; a listing read waits for the load, and readiness says 503 until it is done.
- **1.0.3.88** (2026-10-07): The landing page is drawn to HTML when the site is built, so the bare address paints before any script runs, and React takes that page over with hydrateRoot instead of drawing it again; every other address hides the drawing and opens its own view as before. The API serves the page as a file and knows nothing about it.
- **1.0.3.87** (2026-10-07): The landing page's six API reads start from the page's head instead of waiting for the script, each hint matched to its request so nothing is asked for twice, and ADR-092 records the plan: the landing page drawn at build time next, and full server rendering, apart from the API, as the goal.
- **1.0.3.86** (2026-10-06): ADR-091, One folder per sidebar section, writes down the docs/ folder structure as a standing rule: where each document goes, how to add one, and the test that holds it.
- **1.0.3.85** (2026-10-06): A new Style page, How the documents are styled, teaches how the plain Markdown in Git becomes panels, a status reading, sections with addresses and code samples read from the running build, and shows each one by using it.
- **1.0.3.84** (2026-10-06): The documents in docs/ move into one folder per sidebar section, with the decision records in docs/decisions, so the repository on GitHub reads the way the sidebar does; every ?doc= address is unchanged.
- **1.0.3.83** (2026-10-06): About Steven drops the paragraph on TheYard from its intro, at Steve's request; How I lead and everything else on the page stay.
- **1.0.3.82** (2026-10-06): The Performance page explains how the listing is compressed and why only the listing and the filter values are, and the comments beside that code say what it does, how and why. Documents and comments only.
- **1.0.3.81** (2026-10-05): The Performance page carries the live numbers for 1.0.3.79 and 1.0.3.80, read at the same container age as the reading before them: the edge now answers some listing reads in about a tenth of a second, a read forwarded to Azure takes what it took before, and every roll is still slow for its first twenty minutes. Documents only.
- **1.0.3.80** (2026-10-05): The default listing reads its page off an ending-soonest order built once a day, instead of sorting all hundred thousand vehicles on every request, and gives the same page the full sort gives; on the build machine the page went from 90 to 100 ms to 25 to 34 ms.
- **1.0.3.79** (2026-10-05): The edge may answer the listing and the filter values from its own copy for up to thirty seconds, only for a caller with no cookie; the browser is still told to ask every time, and a vehicle's own page and its bids are always read fresh.
- **1.0.3.78** (2026-10-05): About Steven is the one page about him: it gains the paragraph on TheYard and a How I lead panel with the drawing and the four habits, and the sidebar no longer offers About Steven Stout as a second page; /about stays for search engines and tools that do not run the app.
- **1.0.3.77** (2026-10-05): The listing and the filter values leave the container compressed with Brotli or gzip, so the hop from Azure to the edge carries about 16 KB for a page of a hundred vehicles in place of about 106 KB; no other address is compressed, and a test holds both halves.
- **1.0.3.76** (2026-10-05): The Performance page is measured again on 1.0.3.74 from Missouri: Lighthouse 89 on a phone and 99 on a desk, layout shift zero, the script at the edge a hit six times in twenty with the reason, and the price of serving it from the edge itself, which waits for Steve.
- **1.0.3.75** (2026-10-05): CI runs again on every push to main, on GitHub's runners beside the deploy, so every commit carries a public result and the coverage floor is read on the commit that crosses it; a push that touches only the sample skips it, and a test holds the triggers.
- **1.0.3.74** (2026-10-05): The page about Steven gains How I lead, four habits in his own words, each linked to the record that shows it, beside an original drawing in the site's teal and gold of a team formed into an arrow with one gold figure out in front.
- **1.0.3.73** (2026-10-04): A listing shows the highest bid from anyone when the buyer is outbid, not the buyer's own lower figure; the health card's kept-warm line names its slowest read; the request-units and Who came labels say what they count; the phone's health rows and code blocks read whole; and the comments and records say what the code does today, with no history, a stale rule row replaced and the cross-site sold gap named.
- **1.0.3.72** (2026-10-04): The Author badge on the landing page is served under a new file name, so every visitor sees the new picture at once rather than a cached copy of the old one.
- **1.0.3.71** (2026-10-04): No production comment leans on a version, a date or a review, and a test holds it; both stores' catalogues stay loaded on both sites, so the keeper that let one go is retired; a vehicle's status and next bid come from the auction and the wire only copies them; endpoints read the clock through `Clocks`; the landing page's Hosting tile, About Steven's title and the two proof tiles say only what is true, and the Author badge shows Steve alone; Application health keeps each check's time on its first line on a phone; warnings are errors in every API project; and the architecture, projects, style, accounts and security pages say what the code does.
- **1.0.3.70** (2026-10-04): Onion architecture, the practices, a page under Best Practices that follows one bid through the rings and shows each practice with a drawing or a whole file from the build, with an address per section and a test that holds its headings; two new drawings (a bid's walk through the rings, and the port and its adapters); and the live samples may read the sample's test folder, so its architecture tests show whole.
- **1.0.3.69** (2026-10-03): The auction hands every vehicle out at its standing price with its sold flag (`Auction.Find`, `Auction.Search`, `Auction.HistoryOf`), so no handler composes a price or a sale itself; two ring rules keep the disk, the network and the clock out of Domain and Application; a test holds the wire's vehicle to the dataset's; code blocks in a document are reachable from the keyboard; coverage leaves generated code out and its floor moves up to 90 and 75; and the records the Fable review found wrong or forced say what is true, in plain words.
- **1.0.3.68** (2026-10-03): The onion is held by the build: eight NetArchTest rules fail it when a dependency points outward, endpoints ask the Application ring's Auction instead of composing the bid services, the raw SQL and the context factory moved into the relational adapter, every record says where it sits, three new records (Onion and SOLID, Technology versions, Staying on .NET 10), and every Microsoft package on the 10.0.12 security release with Node 24, Vitest 5 and React 19.3.
- **1.0.3.67** (2026-10-02): The Admin tab's path tile is The path to the resume, and no page, comment or test says who the reader is by title; every code comment says what, how and why on its own, with no version number or date standing in for the reason.
- **1.0.3.66** (2026-10-02): No C# file passes 300 lines either: the activity, machines, proof, store, cost, log and Cosmos DB code and the admin and account endpoints are split by job into their own files or parts, every member says what it is for, and FileShapeTests holds every production source file to 300 lines from now on.
- **1.0.3.65** (2026-10-02): No TypeScript file passes 300 lines: the Admin tab, its activity, machines and chart parts, the rail, the account page, the decision records and five libraries are split by job, each original file now the short list of its parts, and every part says what it is for and why.
- **1.0.3.64** (2026-10-02): Every page opens with what it is about in plain words and what that is worth to a developer and to the organization; a visitor who closes the tab mid-request is answered 499 and no longer turns the Admin tab's Errors card red; the Projects page describes The Shed as .NET 10 and TypeScript; the prose reads plainer throughout.
- **1.0.3.63** (2026-10-02): Every figure on the site says its unit and its window: the Admin tab's traffic names the stretch its request ring covers, kept-window totals are counted on the server instead of a rate times a bucket, telemetry counts this site only, an empty window says no requests instead of 0 ms, long times read in seconds, and the proof says which store it subtracts; prices read CA$, auction times name their zone, the condition grade shows its scale, the reserve amount no longer leaves the server, the records menu lists all 87, and the documents' counts, costs and dates match the code and the results file.
- **1.0.3.62** (2026-10-02): main.tsx reads like Program.cs, one line per part with its file beside it; the stylesheets, the window error handlers and the mount moved to files named for their one job.
- **1.0.3.61** (2026-10-02): The cost card shows what each resource and each type of resource comes to in a month, worked out on the server from the window's finished days and the days in the month, where it had shown what the window cost, so the last day window read a plan at .48 beside a bill read in months (ADR: What Azure charges, third addendum).
- **1.0.3.60** (2026-10-02): The Modding block on About Steven reads like the sections around it, in one line: Republic Commando brought up to date with Claude, and The Witcher 3 next.
- **1.0.3.59** (2026-10-02): The seventeen TheYard pages that The Shed, explained links to each open with an In plain words section: what the page is about, and what it is worth to a developer and to an organization.
- **1.0.3.58** (2026-10-02): The Modding block on About Steven shows the two games' key art side by side where the placeholder cards stood, Republic Commando credited to Lucasfilm and the fan who remastered it to 8K, The Witcher 3 credited to CD PROJEKT RED, each cut with no metadata.
- **1.0.3.57** (2026-10-02): The cost card's bars measure dollars: each type of resource is drawn as what it cost, the costliest first, with how many of it are on the bill in words, where they had been drawn by count, which put three App Service apps at $0.00 at the top as the longest bar (ADR: What Azure charges, second addendum).
- **1.0.3.56** (2026-09-30): The cost card on the Cosmos DB site no longer waits an hour after one slow answer: its first read after 1.0.3.55 rolled ran past twenty seconds while the site was still loading, so Azure Cost Management is now given a minute, and a read that did not finish is tried again in five minutes (ADR: What Azure charges, addendum).
- **1.0.3.55** (2026-09-30): What Azure charges, a card on the Admin tab in public: the spend over the window with Azure's forecast dashed to the month's end, the cost by resource as a donut that names four and folds the rest into Others, and the resources by type as bars, read from Azure Cost Management once an hour with the site's own identity and never on a request, so the dollar figure sits beside the millisecond one; September read $47.18 to date with $49.03 forecast (ADR: What Azure charges).
- **1.0.3.54** (2026-09-30): On About Steven the Modding block shows two placeholder pictures side by side, Republic Commando modded and The Witcher 3 next, until Steve's own screenshots replace them.
- **1.0.3.53** (2026-09-30): On About Steven a Modding block follows Games, in Steve's own words: Republic Commando brought up to date with Claude at the controls, and The Witcher 3 next.
- **1.0.3.52** (2026-09-30): The catalog of every document and diagram the site serves is api/TheYard.Api/DocumentationCatalog.cs, spelled out rather than "Docs", and its test is DocumentationCatalogTests; slugs, routes and behaviour are unchanged.
- **1.0.3.51** (2026-09-30): The endpoints that serve the records, their pictures and diagrams, the Bicep, the resume and /about are Endpoints/DocumentationEndpoints.cs, spelled out rather than "Docs"; routes and behaviour are unchanged.
- **1.0.3.50** (2026-09-30): Search Console, step by step: a fifth page in Site traffic that walks through how the site was put into Google Search Console on 30 September (the property, the proof of ownership, the sitemap, URL inspection and the structured data), each step with its screenshot and the code behind it read live from the build, and how the same job runs at a company with many sites; the site is verified, its sitemap read with 119 addresses, and /about indexed (ADR: The public face, the addendum of 30 September).
- **1.0.3.49** (2026-09-30): The middleware file is Composition/RequestPipeline.cs and Program.cs calls app.UseTheYardRequestPipeline, ASP.NET Core's own name for it, because "pipeline" alone also names the deploy; nothing in the order changed.
- **1.0.3.48** (2026-09-29): A Site traffic section under How it is run, four pages on the Style section's pattern: who comes, what is kept about them and for how long, and how the site is found; and the site reads without the app: a summary for readers that run no JavaScript, an llms.txt index for AI tools, and every document in the sitemap; and on About Steven the house plants move below the rabbits, in Steve's own words (ADR: Site activity and ADR: The public face, the addenda of 29 September).
- **1.0.3.47** (2026-09-29): A page about Steven Stout at /about for anyone who searches his name, with his title, what he builds and what TheYard proves, its own head and a schema.org Person, listed in the sitemap and first in the About section; the home page's structured data names him as a Person too, and Search Console's verification tag has a slot the image build fills when it is given; and About Steven has a new block, Too many house plants, with two photographs (ADR: Every diagram opens on its own page, the addendum of 29 September).
- **1.0.3.46** (2026-09-29): The sample's web app was created once from its Bicep by the owner and its workflow rolls it under the deploy identity's Website Contributor role on that one site, the way the two TheYard sites roll; a change to the sample's workflow alone no longer rolls the site (ADR: The deploy pipeline, the addendum of 29 September on the sample).
- **1.0.3.45** (2026-09-29): The Shed, a sample under samples/theshed: a developer test project (a file and folder browser in plain JavaScript over an ASP.NET Core 8 API) built on their starter in this project's working method, with its own solution, tests, twelve records and deploy to a third web app on the plan the two sites share; the two site deploys now ignore samples/, and the repository tests skip it (ADR: The deploy pipeline, the addendum of 29 September on the sample).
- **1.0.3.44** (2026-09-29): The teals moved bluer and the gold became a gold bar, to match the resume: every teal, the ribbons, the chart marks, the header and the preview card take the new values, every page title's underline and every stat tile's top rule is drawn as the bar, and the resume the site serves is the 29 September build (ADR: The palette, the addendum on palette F and the gold bar).
- **1.0.3.43** (2026-09-29): The ribbon strip on Background and ribbon draws every time the page opens: the live read after 1.0.3.42 found it empty on both sites and a Style tile once missing its icon, so the Style pages' live blocks are now drawn once per element and kept until the element leaves the page, and a browser test holds the three icons, the tile opening its page in the same window, and the strip (ADR: The palette, the addendum on the four pages).
- **1.0.3.42** (2026-09-29): The Style section is four pages (a Style guide with tiles, a glossary and readouts, Colour and style, Background and ribbon with a live strip of the ribbons, and UI architecture with its layer diagram and one job per file), every number on them counted by the build when the page opens; the two stylesheets that held several jobs are split by job, every stylesheet under src opens with what it does, what it does not and who uses it, and the ribbons and the watermark are part of the page now, so they scroll away with the words instead of the page sliding over them (ADR: The palette and ADR: The React configuration, explained, the addenda of 29 September).
- **1.0.3.41** (2026-09-29): Every lane now stacks its commits, runs the full gate once on the stacked head and pushes once without checking for a roll in flight, and this version is the push that proved it, sent to main while 1.0.3.40 was still rolling (ADR: The five-minute gate, addendum of 29 September).
- **1.0.3.40** (2026-09-29): The latest push wins: a newer push to main cancels the deploy in flight on both sites and rolls the newest commit, so stacked changes roll once instead of queueing a roll behind a roll, and the build cache and the ten-image prune still run on a cancelled run once its image was built (ADR: The deploy pipeline, addendum of 29 September).
- **1.0.3.39** (2026-09-28): Program.cs is a table of contents: 2,667 lines holding 48 endpoints became 54 lines that list what the app is made of, with each registration step, the startup, the pipeline in its one order and the single-page fallback in a file of its own under Composition, and each feature's routes (vehicles, bids, documents, health, errors, the Admin tab, accounts, the API reference) in a static class under Endpoints with named handlers; the OpenAPI document is unchanged, every public class and record in the solution now says what it is for, and two tests hold the shape (ADR: The composition root, split by job).
- **1.0.3.38** (2026-09-28): The README opens on the tests and the gate: the three suites' counts read from the gate's own results file, how they add up to 1,892, what runs on which store and what is carried forward, the gate's measured time beside its five-minute target, the five decision records to read first, and the commands that run from a clean clone; running those from a clean clone found the Admin tab's errors table scrolling sideways on a desk when a browser error quotes an address, so an address or a path in a message is now set as an identifier that may break at any character.
- **1.0.3.37** (2026-09-28): A version is called shipped once both sites serve it, and the reads that follow a roll (the Admin health, the page sweep, the live look, the load proof) run after the ship instead of inside it, 264 seconds on 1.0.3.36; the gate's record also keeps a trial that did not pay: reading the every-page checks in four parts across the browser workers made the browser pass 626 seconds against 414 on this four-core machine, so it was taken back.
- **1.0.3.36** (2026-09-28): The two largest frontend files are split by job with nothing a visitor sees changed: App.tsx (1,100 lines) is now src/app, a 128-line App.tsx that reads like a table of contents over the frame, the header, the footer, the inventory page and seven hooks named for what they give back, and DocsMenu.tsx (1,308 lines, holding no menu) is now src/library, the records, the pages, the sidebar sections, the addresses and the document window, with the 106 hand-typed document names worked out from the data instead; every file in both opens with what it does, what it does not and which files use it, and a test holds that header to the real imports.
- **1.0.3.35** (2026-09-28): Every component has a folder of its own, grouped by the section of the site that draws it, the Admin tab's one stylesheet is split so each class lives beside the file that uses it, every deploy warms the edge with every file the build serves and the Admin tab's public reads, and an idle page fetches the document renderer, the Admin tab and its cards before they are clicked, with a document and its renderer fetched together, the public activity report is kept and rebuilt behind the reader so nobody waits on the visitor rows being counted, and each site keeps its own reads warm on both stores every four minutes.
- **1.0.3.34** (2026-09-28): The design tokens live in four files named for what they control (colors, sizes, typography, effects) instead of one, the panels sheet is panels.css and the code theme code-highlight.css, with every value, name, selector and class unchanged and the rendered site the same.
- **1.0.3.33** (2026-09-28): The files a reviewer opens first read in plain words (their comments rewritten, their code untouched), and the open findings of the picture reviews are fixed: units keep their case, one format for a number and for a date, the tests card explains its count, chart units sit off the top tick, one marker per line, no lone pill, tile or button, the activity bars stay chart size on a desk, and an ended lot says "Final bid".
- **1.0.3.32** (2026-09-28): The styling code reads well to a new developer: the base styles have their own file, the token sheet's comments say what and why with history in the records, the ring's colours are named for their colours, and the style rules are numbered one to thirteen once each; the Colour and style page leads with a style guide the build enforces, adds the width scale, tables that stack and charts at their width, and ends on the thirteen tests that hold it.
- **1.0.3.31** (2026-09-25): The open findings from the picture reviews: an Admin table stacks wherever its card is too narrow for its columns and keeps a time on one line, a log category breaks at its dots, a document on a desk opens right of the rail and under the store bar, the Machines card reads the database's times as UTC like the container's, and the telemetry card says why an hour is empty instead of drawing zeros.
- **1.0.3.30** (2026-09-25): The Admin tab on a phone: every table is drawn by one component and stacks under 640 into rows led by their first column with each value behind its column's name, the charts draw at the width their card gives them so their words stay 10 px, the strip's tile lines are whole with the rest of each sentence kept for screen readers, and a reading under 1 ms says so instead of 0 ms.
- **1.0.3.29** (2026-09-25): The styling pass after a cold review: a page left open across a deploy reloads without first flashing an error or reporting one, and never while offline; the chart series tokens are the ones the lines draw; the last repeated values are tokens; and the style rules read calc, data files, range syntax and colours inside a value.
- **1.0.3.28** (2026-09-25): The pale box behind every page is gone: it was the watermark's large lightning mark, whose straight edges read as a box through the thinner glass; the watermark is its dotted rows alone, and the browser suite holds it to lines.
- **1.0.3.27** (2026-09-25): The styling pass, ready for review: every colour written once in three tiers with tints mixed from their tokens, the chart series made the Mark VII marks they already drew, one width scale of six steps, and every size, weight, corner, tracking and layer taken from the token sheet, each held by a new rule in the gate; and a vehicle's sections full width on a phone again, a page left open across a deploy reloading itself onto the new version, and the Admin strip's details on two lines.
- **1.0.3.26** (2026-09-25): The lane's self-review: About Steven covers a phone's whole screen when opened from the home page, the Admin rail is a drawer under 1280 so no table scrolls sideways on a small desk, the bid panel keeps what was typed when a tablet turns, a screen reader hears the store note at every width, the request-units gauge reads a rate against a rate, body text and the desk dialog's title clear 4.5 over the glass, every see-through ground turns solid together, and the chart frame, the callout and the gauge are one tested function each.
- **1.0.3.25** (2026-09-25): A phone reads the Admin tab cleanly: every strip tile's reading is one line beside its ring ("124 of 124" broke over two on 1.0.3.24), a path in a table is never narrower than a short path (the timing card broke "/api/version" every four characters), cells are tighter, and the activity card's three windows are three pills rather than one pill wrapped round two lines.
- **1.0.3.24** (2026-09-25): Tables fit their panels, the charts' fills are see-through, and the registry keeps its newest ten images: every table column wraps between words (a record's first column of sentences ran off the side of its dialog on 1.0.3.23) and nothing on a desk scrolls sideways; the activity chart's bands, the path bars and the gauges are filled glass with a solid edge; the deploy deletes every image older than the newest ten after the site answers, and never one a site runs (ACR Tasks are refused on this subscription, so the pipeline prunes); and on a phone a strip tile holds a ring's room only where it draws a ring, so "under 1 ms" stays on one line.
- **1.0.3.23** (2026-09-25): The Site activity card says what it does and does what it says, and the look is refined in one pass: the card counts a hit a full queue drops, shows what keeping the rows cost in request units and how long they are kept, names the one store every batch goes to, and describes the chart it draws; the glass is thinner and frosted deeper with one secondary grey that still reads over the ribbons, a document opens on a clear sheet with its words on frosted panels, the Admin tab's charts and gauges are drawn as instruments (ticks, not grids; a marker on every ring; a callout on the peak; bar gauges for memory and request units), tables never break a word, the Admin strip is two across on a phone with its numbers on one baseline, a vehicle on a phone shows its bid first, the store bar ends nothing in an ellipsis, and the rail, the account page, the landing page and the inventory cards take the same small corrections.
- **1.0.3.22** (2026-09-24): The Admin tab holds a screen while it loads: the frame before its chunk arrives is a screen tall, so the footer stays below the first screen (a phone that waited 1.9 s for the chunk saw 0.062 of shift on 1.0.3.21), and mobile.spec holds it with the chunk held back.
- **1.0.3.21** (2026-09-24): The API reference is the site's page, not a product's: Scalar's telemetry, AI chat, MCP link and developer toolbar are off and the page stays in the one light theme, so it fetches from nothing but this host and the one font, and sidebar.spec holds it there; and the Admin tab holds still on the live sites: a strip tile's line is two lines at most, whole in its title, and the bench is at least a screen tall, so a pinned card landing moves nothing in view; and the diagram pages carry the site's tab icon, so no browser logs a 404 for /favicon.ico.
- **1.0.3.20** (2026-09-24): The ribbons paint again in Chrome, the glass is frosted, and nothing on the live sites moves: the page's ribbon drawing and the document dialog's copy of it shared their gradient names, and Chrome drew the page's blank from the closed dialog's copy, so each copy names its own, and coverage.spec holds every page to one use of an id; the glass blurs 20 px where it blurred 7, so what is behind a panel reads as soft colour; the store bar's note is one line at a desk (on 1.0.3.19 it wrapped at 1280 when the stores answered and moved every page 29 px); a document on a phone is read on white; a phone tile's reading breaks only between words; the diagram pages and the API reference stand on the site's own ground and colours; and the landing page's count-up writes its frames without a render each.
- **1.0.3.19** (2026-09-24): The Admin workbench finished and the whole site on the operator's look, as one version: each Admin card is a chunk of its own that reads only while it is open, a phone takes the rail as a drawer behind a Cards button with the tiles four across, every panel, card and tile on every page is the transparent glass (42 per cent white where it was 66) with a 3 px rule and two corner brackets, readings are small capitals with tabular figures and every share of a whole is a ring, IBM Plex Sans is the one face (one 29 KB file for its four weights where the four Poppins files were 31 KB), a document's pictures hold their room before they arrive, and coverage.spec reads every page the site lists at 390 and 1280 and finds each on the look. Measured on the build against 1.0.3.17: the landing page's first screen 148.0 KB where it was 146.9, and the Admin tab at 1280 17 requests and 180 KB where it was 30 and 400 KB, its layout shift 0.001 where it was 0.068.
- **1.0.3.18** (2026-09-24): The Admin tab is a workbench, one card at a time and the address naming it: `?view=admin&card=timing` opens the timing card, a name that is no card opens Health and the rail says so, Back returns to the card before, the rail down the left is the five questions with every card under the one it answers and a search box, every tile in the strip is a link to the card behind it, j and k walk the rail, and `&pin=errors` keeps a second card beside the open one, two columns from 1280; measured on the build itself before and after (queue 1378, 1379), the tab at 1280 is 1,545 px tall where it was 10,902 and 208 KB where it was 400 KB, and moves 0.024 after its first paint where it moved 0.068.
- **1.0.3.17** (2026-09-24): The Site activity card says where visitors came from: each page load keeps the host of the page that linked here, only the host and never its path or query, kept on the visitor row in Azure Cosmos DB and in the relational store alike (a nullable column, in the database project and in a SQLite migration), and the card groups the hosts as LinkedIn, GitHub, search, another site, and typed or unknown, with the hosts themselves listed under the bars in public, since a referring site is not personal information (Steve's call); counting starts at this version, and a link opened from a PDF, the resume among them, sends no referrer and reads as typed or unknown.
- **1.0.3.16** (2026-09-24): The Site activity card names what people asked for by page rather than by route (Inventory listing, Facets and filters, Bids, Who am I, About Steven, the resume), two routes that are one page added together and the site's own reads kept out of it, shows what scanners probed in a strip of its own under the list, and says "Collector fine" with the collector's counts behind Details where it gave three counts in a sentence.
- **1.0.3.15** (2026-09-24): The Site activity chart says how far into today it is above the drawing at its right end rather than on the last day's axis label, where at a week it ran into the day before ("WedThu, today 18 h in" in every picture at 1280 and 1440 after 1.0.3.14); the axis names each day alone, and the admin tests hold the day labels apart.
- **1.0.3.14** (2026-09-24): The Site activity chart names its axis, visitor-days per day, draws today behind a wash of the page ground and labels it "today, N h in" so a part-day stops reading as a fall, and under a pointer or a finger draws a hairline down the day with a ringed dot on each band and the day's numbers in a box in the corner away from the pointer, the same in Chrome and WebKit.
- **1.0.3.13** (2026-09-24): The Site activity card draws the recruiter's path, four bars in the order the steps are walked, opened the site, the inventory, About Steven and the resume, each counted in visitor-days from the rows the card already reads and following the Visitors only toggle; the resume is counted by /api/docs/resume, the address the page links, where 39 of the 41 resume requests in the eight days read before this version went, and /docs/resume.pdf beside it.
- **1.0.3.12** (2026-09-24): The Site activity chart stacks who came, day by day: people at the bottom, then scanners and crawlers, then the site's own reads, in three colours chosen as a set and checked for colour vision together (teal, amber and blue, each clearing 3:1 on white), with a legend and each band's name on the band where it is thick enough, and a Day by day table under the chart with the same numbers; under Visitors only the stack is the people alone; the lines by store, what the chart drew before, are one click away as By store.
- **1.0.3.11** (2026-09-24): The Site activity card counts people apart from the site reading itself: a Visitors only and an All traffic toggle beside the window, Visitors only by default, every number on the card following it, and the day's people and scanners and crawlers and the site's own reads adding up to the day's visitor-days; read off the kept rows first, 375 to 643 of each day's "people" since the move to App Service on 20 September were one-request /index.html hits from the container's own loopback address (643 of 757 on 23 September), each a new visitor because the port it came from went into the token, so the loopback address is the site's own now, a port after an address is dropped before the token is made, the tools that read the site carry one mark on their agent (TheYard-SelfRead) and are kept under a token and a network of their own, and the Admin tab's people-today tile reads the same people.
- **1.0.3.10** (2026-09-24): The three things the 1.0.3.9 sweep still saw, and the session key: the phone header's hamburger is drawn from the icon tokens (its stroke read 2 where every other icon reads 1.6, and icons.test.ts now reads App.tsx, which it had never looked at); the Admin tests card's pass and fail marks are declared a drawing in icons.test.ts beside the charts, the rings and the watermark (a filled disc with a bold glyph at 16 and 44 px, its strokes scaled by the mark, and the test now reads every component sheet for a stroke that is neither the token nor a declared drawing); the store bar's note on a phone holds its two lines from the first paint (--store-note-height, 38 px, where the row arrived with /api/stores and moved the page 38 px in half the runs at 390, a shift of 0.045, held under 0.02 by a fourth no-shift test in landing.spec); and, the same morning and outside this tree, both App Services were given one session signing key, written from a file and never logged, proved by a session that still answered /api/auth/me after both sites were restarted, by a token minted on the SQL site accepted by the Cosmos site's protected read, and by a kept log with no "No usable Auth:SigningKey" line after the restarts, so a sign-in survives a roll from here on.
- **1.0.3.9** (2026-09-23): One consistent experience, from tokens: every view read at 390, 1280 and 1440 in Chrome and WebKit before anything changed, and what differed for no reason is one token each now, one focus ring with one offset (the skip link had the browser's, thirty-three rules had six offsets), one height per kind of control (the same kinds stood at 28 to 48 px, and the vehicle's back button was the one that was not a pill), one border and radius for every input, one weight for every page title (the vehicle's was the one at semibold), one weight for badges and status pills, two icon sizes with one stroke, and "Back to home" on Admin and Account when they were opened from the landing page and that is where Back goes; the speed tile says "under 1 ms" where it said "0 ms"; and the evidence strip reserves two lines for each figure's detail, the last 19 px the landing page moved after first paint.
- **1.0.3.8** (2026-09-23): The page sweep gives an address that did not answer a second look, alone, once the pass is over, and calls it up with "answered on a second look" if it answers then; and three minutes after a roll's sweep the settled process sweeps itself again, so the Pages tile shows the site and not its busiest second: the roll onto 1.0.3.6 had reported /api/health, /api/admin/machines and a kept card down on both sites for taking past thirty seconds while both containers warmed their catalogues, and every one answered a minute later.
- **1.0.3.7** (2026-09-23): Nothing on a page moves after its first paint: the store bar is drawn at its full height before the server has said which store this is, the version line under the brand is a line before the build has answered, the evidence strip stands at its height with four blank figures before the gate's counts arrive, a document's dialog is the height of the screen from the moment it opens rather than growing from its Loading line, and the inventory holds the height its cards will take while they load; measured at 1280 and 1440 in Chrome on 1.0.3.4, the landing page shifted 0.08 to 0.13 after first paint, a document 0.19 to 0.28 and the inventory 0.10 to 0.81, every one of them one of those four.
- **1.0.3.6** (2026-09-23): A store is asked five times at startup, the waits doubling from two seconds, before it is written off and the error logged with the count (Steve's rule, for SQL and Cosmos DB alike), and a store that refused all five is asked again every thirty seconds for an hour and attached warm when it answers, instead of being tried once before the container is built and never again: both containers rolled onto 1.0.3.4 in the same second on 2026-09-23, both got a login-phase transient from Azure SQL Database that the connection's own retry does not cover, and both served the catalogue from files for the life of the process while sign-in and bids on the SQL site went nowhere; the loop is held by six tests, and a store that is genuinely gone is still the fallback after the hour.
- **1.0.3.5** (2026-09-23): A document's pictures come from this site rather than GitHub's raw host, a PNG whose SVG source stands beside it is served as that SVG, and the renderer marks every picture in a document lazy: measured on the README at 390 in Chrome before the change, 20 requests and 1,402 KB by the responses' own headers, 985 KB of it infrastructure.png where infrastructure.svg is 17 KB; the markdown files are untouched, which is what keeps them right on GitHub.
- **1.0.3.4** (2026-09-23): The speed tile reads the hour the way a visitor felt it: its number is the hour's median over every request in its warm minutes with the ninety-fifth beside it, from the durations each traffic minute now carries, in place of the slowest minute's ninety-fifth, which kept one slow request on the tile for an hour and read amber 45 per cent of the time on the SQL site while 1.5 per cent of its minutes were slow; under twenty requests the hour reads quiet and shows the count, amber and red are the hour's ninety-fifth at one and three seconds, and the three minutes after a start are still left out.
- **1.0.3.3** (2026-09-22): The fifty vehicle photographs are cut to AVIF as well and offered before the WebP, 8,131 KB to 4,500 at 1280 and 1,281 KB to 711 at the card's width, each encoded from the 1280 original rather than from another copy, with the WebP and JPEG pairs kept for a browser that reads neither.
- **1.0.3.2** (2026-09-22): The Author page's photographs are cut to AVIF as well and offered before the WebP, which halves them: the 960 set goes from 1,962 KB to 992 and the 480 set from 586 KB to 296, with the originals untouched, the WebP kept for a browser too old for AVIF and the JPEG kept as the one any browser can read.
- **1.0.3.1** (2026-09-22): The four Poppins files start with the stylesheet rather than a round trip after it: the build injects a preload link for each one into the head, named from its own hashed output, and all four paint on the first screen.
- **1.0.3.0** (2026-09-22): The landing page stops paying for the inventory: it no longer asks for the catalogue or the filter options, which were its slowest request at 450 ms on the SQL site and 897 ms on the Cosmos DB one for a page that shows no vehicle, and the Admin tab, the largest view in the app, is a chunk of its own fetched when it opens rather than with the first page; and a Start here page for a developer new to the repository opens the App Architecture section, with what to run, the five rules that bite first, where a change goes and what the gate asks of it.
- **1.0.2.2** (2026-09-22): No document scrolls sideways on a phone: a long unbroken token in inline code, a link or a table cell wraps instead of widening the page, and a table too wide for a phone scrolls inside its own box; measured at 375, the README's dialog was 375 wide and scrolled to 460, pushed by the file paths its lists carry, and a Playwright test now holds four documents to no sideways scroll at all.
- **1.0.2.1** (2026-09-22): The resume tile is a banner under Inventory and Author rather than a third column, which had squeezed the Author's line into 300 px and broken the resume's own title over three lines, and the evidence strip stands four across on a desk instead of two by two.
- **1.0.2.0** (2026-09-22): The landing page answers a recruiter in its first screen: the resume is a large tile beside Inventory and Author, the Author tile carries the opening line of his resume, and an evidence strip under the title reads the gate's own counts from /api/tests/summary, the tests it ran, the seconds it took, the decision records the site holds and the two stores one codebase serves; the photograph of Freya and Vincent under the hay rack fills the width of its section on a desk and the column's width on a phone; and every document now stands on the Author page's glass panels over the ribbon ground instead of on plain white, from one twenty-line layout and one panel rule the two share.
- **1.0.1.6** (2026-09-22): The photograph of Freya and Vincent under the hay rack stands on its own after the St. Charles block, no heading, the way the engagement photographs stand between blocks, instead of inside St. Charles.
- **1.0.1.5** (2026-09-22): The photograph of Freya and Vincent under the hay rack sits centred beneath St. Charles on a desk, as it was meant to in 1.0.1.4, where the page's plain photograph margin outranked it and left it at the left edge.
- **1.0.1.4** (2026-09-22): The landing page and the sidebar gather the sections under three headings, How it is built, How it is run, and Who and why, in the order Steve set; the Author and Inventory tiles wear a photograph in their gold ring, the vineyard selfie and the yellow coupe; the Admin tile reads the site's health once and shows it as a dot; the Admin tab's speed tile calls a slow minute red only when it served 20 requests or more; the willow photograph carries McKinley Griggs's credit; and a photograph of Freya and Vincent under the hay rack sits beneath St. Charles on the Author page.
- **1.0.1.3** (2026-09-22): The landing page's title and its sentence sit on the same faint glass panel as the large tiles, so the ribbons behind them no longer cross the words.
- **1.0.1.2** (2026-09-22): The doors block on the Author page shows Steve's own door, hung in its new frame before the trim went on, in place of the placeholder photograph and its credit.
- **1.0.1.1** (2026-09-22): The Author page shows Steve and Katie under the willow just before Freya and Vincent, the two rabbits on the blue rug as the second rabbit photograph, and Steve's own grill in place of the stock steak under Food, each cut on this machine like every photograph on the page; the page ends with St. Charles, where Steve lives; and the sidebar has a Home row first, which opens the landing page and reads as current while it shows.
- **1.0.1.0** (2026-09-22): The first polished release: the address opens a landing page drawn from the same site map as the sidebar, and the version is read as four numbers.
- **1.0.0.187** (2026-09-22): The deploy drawing says what the pipeline does (the gate on the laptop, the push, Deploy and Deploy Cosmos side by side, CI on a pull request only), the living documents call the gate the one gate and leave the minutes to the measurement (ADR: The five-minute gate, the addendum on the two cuts), the Admin and Account pills stand 44 px tall on a phone and 34 on the desk, and two cuts in the gate that Steve chose: `dotnet format` runs only when a C# or project file changed, and the two passes on Cosmos DB run only when something under `api/`, `infra/cosmos/` or the three store specs changed, the results file carrying those two suites forward from the version whose gate ran them, marked so on the Admin tab and held by `TestResultsTests`.
- **1.0.0.186** (2026-09-22): One weight for titles and section headings. Measured on every view at 375, 1280 and 1440 px, the Inventory, Admin and Account titles and the Admin tab's section headings were bold while a document's title and sections, the Author page's included, were semibold; they are all bold now. The differences left are by role and are written in the review handoff: the Author page's call-to-action buttons are larger than the Admin tab's window pills, a diagram's frame is the thin grey one and a photograph's the green and gold one, and a vehicle's name is a semibold heading inside a panel, not a page title.
- **1.0.0.185** (2026-09-22): Every photograph on the Author page loads eagerly. On Steve's iPhone, in Chrome and in Safari, the lazily loaded photographs flickered while the page scrolled inside its dialog, and the first photograph, the only eager one, never did; nor do the vehicle photographs, which scroll with the page rather than inside a dialog. The page is a dozen cuts no wider than 960 on a phone. A frame still waiting on its picture shows the muted grey a vehicle card shows, not white.
- **1.0.0.184** (2026-09-22): The deploys notice a new version sooner. Both sites' Verify steps and the second site's wait for the image ask every five seconds instead of every ten, with the same ten-minute limit, so a roll is reported live up to five seconds sooner at each of three waits.
- **1.0.0.183** (2026-09-22): The living documents say what the code does. Every checkable claim in the README and the overview documents was read against the code, and 33 that had drifted are corrected: the count of decision records, the tests that need the real Cosmos DB account (seven, not six), what triggers Deploy (the gate's push to main, not a green CI run) and which template it rolls, how many jobs CI runs, where the font comes from (self-hosted, not Google Fonts), where the version number comes from (the changelog's top line), the bid store's method names, the projects' test count, ports and accent colour, the second site's place in the architecture diagram, the security page's edge-to-origin hop (HTTPS since 1.0.0.156, not plain HTTP), the projects list (eleven, not seven), where the catalogue is read from (the store; the JSON only seeds it), the Markdown wrap rule, two decision-record references, and dated gate and test figures brought to 1.0.0.182. Three code comments that described the old CI trigger and the moving ribbons are corrected too. The two that need a decision, the deploy diagram and the gate's name, are in the review handoff.
- **1.0.0.182** (2026-09-22): The photographs on the lower half of the Author page stop flashing on a phone. A phone throws a decoded picture away once it scrolls off and decodes it again on the way back (measured at 390 px: 31 decodes for a dozen pictures in one scroll down and back up); with `decoding="async"` each frame painted empty until its decode landed. The Author page's photographs now decode with `decoding="sync"`, which keeps the picture on screen until the new decode is ready, and the vehicle photographs go back to the browser's default, undoing the `async` 1.0.0.180 added. Measured in the same run, the ribbons were not the cause: Chrome repainted the same amount with them, without their blur, and without them at all.
- **1.0.0.181** (2026-09-22): About Steven, at Steve's word. Two neighbouring blocks with one photograph each share a row, the lake beside History and the food beside the doors, their photographs cut on the page to one 4:3 shape at the foot of each block so they sit on one line at one size (the source files are untouched); a block with the row to itself cuts its photograph wide (16:9), so no one picture towers over the rest; and the engagement photographs between the blocks take the whole row at every width. One scroll at a time: the Author page's body scrolls and its dialog does not, so the ribbon ground behind it stays put on every screen of the page, no document hands its scroll on to the page behind it, and the page behind stands still while a document is open.
- **1.0.0.180** (2026-09-22): The ribbons hold still on a phone. Nothing in them was animated after 1.0.0.178, but their layer was as tall as the screen at that moment, so on a phone, where the address bar comes and goes while you scroll, it grew from 664 to 750 px and back (measured at 390 px wide in Chrome and WebKit) and the drawing, which fills its box by slicing, was rescaled by 13% each time. The layer is now as tall as the large viewport (100lvh), which the address bar does not change, and sits on its own layer so scrolling never makes the browser draw it again. The Author page stands on the ribbon ground too, with its own copy fixed to its dialog. On a phone a document's sides are 12 px instead of 24 (the phone rule had been written above the desk rule and lost to it on source order), and an Author block's text starts 41 px from the screen's edge instead of 61. One look, measured against the Author page and the Admin tab at 375, 1280 and 1440 px on every view: a document's title takes the page title's gold underline and its sections the Admin tab's trim; the Inventory title is bold like Admin and Account; the Account buttons are pills; a vehicle's photograph and its title warning take the panels' 10 px corner; and a vehicle's card titles read like the Admin tab's. Vehicle photographs decode off the main thread.
- **1.0.0.179** (2026-09-21): On a phone, the photographs that stand alone between the Author page's blocks take the blocks' width instead of being set off to one side, which ran the stream photograph past the blocks on the right (Steve's phone); on a wider screen the offset now comes out of the photograph's width, so it never passes the column's edge either. The browser suite holds every such photograph inside the blocks' edges at 375 px. The ship's gate is back to the .NET suites first and the browser passes after: overlapping them saved nothing (711 s against 720 s).
- **1.0.0.178** (2026-09-21): The ribbons stand still (ADR: The glass look, the addendum on the ribbons standing still): no drift, no twinkle, no pulse, one drawing painted once and centred in the content area by the stylesheet alone, at Steve's word for a minimal site. Measured in Chrome, the moving ground spent about a third of a processor core on every open page. The deploy writes its build cache after the site has rolled instead of before (ADR-009, the addendum of 21 September), about a minute sooner live, and the ship's gate starts the browser pass while the Cosmos DB suites wait on the network.
- **1.0.0.177** (2026-09-21): The inventory holds still (ADR-056, the addendum of 21 September). Recorded for a minute on the live site, the grid moved a card about once a second under ending soonest and asked for the whole page four times a minute on every view; it is now ranked on the clock of the answer it shows, so a card whose auction ends says "Ended" where it stands, the listing re-asks at most once a minute, and only while it is the view. The Admin tab stops reading while its browser tab is hidden. The ship's browser pass runs against the built bundle with vite preview instead of the dev server, 4.6 minutes against 8.7 on the same machine in the same quarter hour.
- **1.0.0.176** (2026-09-21): The watermark keeps its dotted rows and its lightning mark and loses its concentric rings, and the ribbon ground sits centred in the content area instead of against the rail; it also draws its flares and sparks in a second SVG on the same layer, apart from the blurred ribbons, because a change inside one SVG repaints all of it (measured on the approved drawing in headless Chrome, about four tenths less). The Author page takes Steve's placeholder pictures, each credited to its source in its caption: Ha Ha Tonka from the air (417mag.com) under the lake, the Pantheon at dusk (fullsuitcase.com) under History, a steak under Food (southerndiscourse.com) and the doors under The doors (apartmenttherapy.com); and the two engagement photographs leave their pair to stand alone, the stream between History and Games and the bridge between Games and Food, set off to either side. The blocks alternate gold and teal by their order among blocks, so a photograph between them does not break the alternation.
- **1.0.0.175** (2026-09-21): The page's ground is the teal and gold ribbon ground Steve approved in the browser pane (ADR: The glass look, the addendum on the ribbon ground): a left to right gradient from green-grey to white in place of the flat grey, and one inline SVG of ribbons, highlight strands, two star flares and twinkling sparks from the rail's edge, all of it code and none of it an image, drawn on one moving transform with no blur on anything that moves, still for a reader who asked for less motion, its colours fifteen tokens on the style page under Background, and the panels, words and pictures in front of it untouched. The Author page opens on the vineyard selfie of Steve and Katie beside the words, and the stream photograph moves down beside the bridge photograph, the two side by side like the rabbits; the credit now names the two photographs McKinley Griggs took.
- **1.0.0.174** (2026-09-21): The tests card says passed or failed as a mark nobody has to read, a tick in a green disc or a cross in a red one, big beside its sentence and small on every suite, check and test, and its results file writes every character past ASCII as an escape, so a test's own example of a forbidden character is no longer one in the file (ADR: The five-minute gate, the addendum on every check running once); and the Author page carries the Mass Effect Legendary Edition key art under Games, credited to Electronic Arts (ADR: The sidebar, the addendum on the author's section).
- **1.0.0.173** (2026-09-21): Every check runs once and every test result is on the Admin tab (ADR: The five-minute gate, the addendum on every check running once): the ship's gate is the one run of every suite on both stores, it writes what each test did into `data/test-results.json` with `scripts/test_results.mjs`, the version ships it, `/api/admin/tests` serves it and the card "Every test, for this build" shows every suite and every test, failures first and then the slowest; CI stops re-running the suites on a push to main and keeps them for a pull request, and Deploy and Deploy Cosmos start on the push itself, the second site rolling beside the first from the one image, whose slow layers now come from a build cache (ADR-009, the addendum on the push).
- **1.0.0.172** (2026-09-21): The Author page carries the two photographs of Steve and Katie he approved for it, as the mock-up had them, the stream beside who he is and the footbridge opening "Away from the keyboard", wide on a desk and its tight crop on a phone, with the credit "Photos of Steve and Katie by McKinley Griggs." under the panels; a phone is never offered a file wider than 960, and `AuthorPageTests` holds that every listed photograph is on the page with its credit (ADR: The sidebar, the addendum on the author's section).
- **1.0.0.171** (2026-09-21): The sidebar's last section is Author, with one page, About Steven, so the person behind the site is somebody a reader remembers (ADR: The sidebar, the addendum on the author's section): who he is at work, three finger-sized ways to reach him (the resume, LinkedIn, GitHub) and no form or address to harvest, the rest of his life in small headed blocks whose top edges alternate gold and teal by their order, and photographs in one quiet frame; the words are his to approve, this version carries the draft at his word so he can review it on the live page, and they live in `docs/author/AUTHOR.md` like every other document, given the page's shape by `src/lib/author.ts` over the one renderer's output; the photographs are served as responsive sets, WebP first, cut by `scripts/author_photos.mjs` from originals that never enter the repository, with every file read back to prove it carries no metadata; `AuthorPageTests` holds what the page must never say, the few exact words as salted digests so the test does not publish them, and holds every photograph to its real width, its alt text and its frame; the intro strip's new second link, "Who built this", opens the page.
- **1.0.0.170** (2026-09-21): A Style section in the sidebar holds how the site looks, and the gate holds the rules on it (ADR: The palette, the addendum on the style section): one page, Colour and style, with one entry a colour, its job, where it must not go and its measured contrast, and swatches that are never a picture, because a `swatches` fence in a served document is drawn by the renderer from `src/styles/tokens.css` itself, each chip painted with the token and its contrast on white and on the page grey computed beside it by the same arithmetic the token test uses; seven rules in `StyleRulesTests`, each failing with a sentence that says what to do and each a row in the table of rules a change has to pass: no raw colour outside the token sheet, which moved a hairline, a white and two scrims into tokens and left the allow-list empty; every hex on the page a token's value and every colour token on the page; every contrast figure the page states the figure the tokens give and over its bar; no series a status colour and no line a status tone but server errors; gold only where it is trim; one header gradient defined once; and the browser rules on fading still in place; the glass look reaches every surface and not only the Admin tab's, because 1.0.0.169 had left the vehicle cards, a vehicle's page, the account tab and the store bar solid white and the inventory read as the old site with a new header (ADR: The glass look, the addendum on every surface): a vehicle card is see-through without the blur and the few panels are see-through with it; the README and the page on how this was built point at the section, so the next session finds the rules before it touches a colour and cannot ship past them if it does not.
- **1.0.0.169** (2026-09-21): The site has a new look, for the reader who arrives from a post on a phone with ten seconds (ADR: The glass look, and ADR: The palette, the addendum on teal, dark green and gold): teal is the accent where the slate blue was, dark green draws the edges, the heading rules and the first series, gold trims the header, the page titles and the chosen button and is never text, never data and never beside the amber warning, and the white and light grey grounds and every text colour are as they were; the header, the rail's brand block and the phone's header are one gradient, top to bottom, with a gold rule under it; panels are glass, see-through in their background colour over ONE inline drawing fixed behind the page, with every word, number and photograph at full strength, which the browser suite holds by finding anything faded that holds a word or an image, and solid where a blur is not supported or not wanted; every text colour is measured against the watermark at its worst, which moved its dotted rows from the dark green to the lighter teal and moved the two quiet text colours off the bare ground for good, held by a test that walks up from every quiet word to its ground; the inventory opens with one sentence saying whose working demo this is and three ways on, the resume, how it is built and the live Admin tab, inside the first screen of a phone with 44 pixel targets, dismissible for good; three tiles carry a ring because their number is a share of a known whole and the others do not because theirs is not; charts have a fine grid and a readout under the pointer; a turned-away request is the neutral grey of the third series; the link preview is drawn in the new look at a size that reads four hundred pixels wide; and the drawings under docs/images and the two store colours keep the old palette until they can move together.
- **1.0.0.168** (2026-09-21): The Admin tab's Traffic card is written for the person who did not build it (ADR: The Admin tab, as a product, the addendum on the traffic card in plain words): "Did anything fail?" comes first, as a titled section saying a server error is the site's fault and a turned-away request is the visitor's, with "errors / min" on its axis and "No server errors in the last hour" said in words beside a good pill, because a flat line at zero read as a chart that had not loaded; the slow-requests line no longer wears the warning colour and the turned-away line no longer does either, because a series takes an identity colour, two tokens of its own on the sheet (ADR: The palette, the addendum on the series colours), and the status colours are for states, which `MachineChart` now cannot be asked to break and the browser suite holds by reading every line's stroke, and every other chart on the tab was checked and none had the defect; the sentence in status codes and percentiles is four blocks in the tiles' look, requests, typical answer, slow answers and server errors, two to a row on a phone; each chart is a section titled with its question, one sentence on how to read it and a unit on its axis; the words live in `src/lib/trafficCard.ts` under Vitest, the one new number is the middle one of the minutes' medians and says so, and no endpoint and no C# changed.
- **1.0.0.167** (2026-09-20): Two sentences 1.0.0.166 got wrong on the live page, found by the same look that found what it fixed: a window's drawing starts at the first reading unless that leaves fewer than a dozen slots, and then a dozen back, but the sentence over the charts called both "its first reading" and on the record's first day named a time two days before anything was kept, so it now gives the first reading and the start of the drawing as the two things they are; and a site whose only requests in the hour were its own cold start read "quiet" beside "67 requests", and now reads "warming".
- **1.0.0.166** (2026-09-20): Two things the live Admin tab showed once it was looked at in a browser, both fixed (ADR: The Admin tab, as a product, the addendum on where a window starts): Last 30 days, on the day the minutes began to be kept, drew two buckets of 180 as a sliver at the edge of an empty frame and read as a chart that had failed, so a kept window is still asked for and counted whole but is drawn from its first reading, with every later gap still a gap and the sentence over the charts saying where it starts; and the speed tile went amber after every roll, because a cold process answers its first request in a second and a ninety-fifth over a quiet minute is its slowest request, so the tile reads the hour without the first three minutes after a start and says on its face that it left them out, while the requests, the errors, the line under the tile and the traffic card still show them.
- **1.0.0.165** (2026-09-20): One window for every chart on the Admin tab, with its buttons wherever a chart is (ADR: The Admin tab, as a product, the addendum on one window for every chart): the last hour, 24 hours, 7 days and 30 days were already what the traffic and machine charts could read, but the buttons were on one card and the other card, filed under a different question a long scroll away, only said to go and find them; the same row is now over the tiles, on the traffic card and on the machines card, one piece of state so pressing one presses all three, the lines under the tiles follow it from the same kept buckets the charts use with a gap where nothing is kept, a sentence says what the lines are lines of and that the number over them is still now, and a change of window no longer sends the tiles back to waiting.
- **1.0.0.164** (2026-09-20): The Admin tab's four public lists, recent errors, the log, the SQL the application ran and what the document store ran, are kept for thirty-five days in Azure Cosmos DB and each card reads Now, the last 24 hours, 7 days or 30 days (ADR: Logs that outlive the container, the addendum on the cards): they were rings in the process's memory that every roll emptied, on a day the site rolled nine times; every entry a ring takes is now also written, by the collector the kept log already had, into the same container as four more kinds, as the JSON the ring's own endpoint serves and nothing more, which is why it can be read without a key; each document carries its own thirty-five day life beside the container's three years; `GET /api/admin/kept` answers a card and a window picked from fixed lists with the newest two hundred and the window's total, cached for half a minute; and the sentence under the buttons says whether an empty table means nothing kept here, nothing in the window, or not read yet; and the measurement 1.0.0.163's record promised to this line: from a desk in Missouri through the edge, ten reads each, the listing's median went from 418 ms to 322 ms on the SQL site and from 439 ms to 375 ms on the Cosmos DB site, while `/api/version`, which does no work, read 181 to 192 ms both times, so the sort was about 100 ms of a listing and what is left is filtering, overlaying and ranking 100,000 rows on every request, which is the next thing that tile will find.
- **1.0.0.163** (2026-09-20): The first tile to go amber was investigated and what it found is fixed (ADR: The Admin tab, as a product, the addendum on the first amber tile): "Slowest 95th, 1212 ms" led through the traffic minutes and the timing rows to `/api/vehicles` at a median of 278 ms server-side, because the listing sorted every one of 100,000 matches to show 100 of them, which a container group's own core hid at 51 ms and the plan's one shared core did not; the page is now taken straight off the ordering so the runtime sorts only as far as the page, the same rows in the same order with ties included, held by a test over every sort; and the tile now names the minute its number came from, so an amber tile is somewhere to start.
- **1.0.0.162** (2026-09-20): The idle release that 1.0.0.158 shipped is measured on the plan and the numbers are in the record (ADR: One plan, two sites, the addendum on the release): with `Store__ReleaseIdleMinutes` at 10 on both sites, put there by the template in incremental mode because a roll does not carry it, a proof run took each site from one catalogue to two and from about 360 MB of working set to 455 and 485 MB, and eleven and a half quiet minutes later each site held one catalogue again at 243 and 256 MB, lower than it began, without a restart; the price is the first request after a quiet stretch against the store a site does not serve, 6.9 s and 10.9 s, which no visitor pays, because the store a site serves is never let go; documentation only.
- **1.0.0.161** (2026-09-20): The Admin tab opens on the four questions it exists to answer, the third of three ships on it (ADR: The Admin tab, as a product, the addendum on the look): a strip of eight tiles across the top, each a label, one number, what the number is a number of and the last hour drawn under it, reading is it up, is it fast, is it costing anything, what broke, and each tile goes to its question; the tiles ask the server for nothing, because they are made of what the cards below have already read, and what turns one amber or red is a named constant in `statTiles.ts`, tested without React, with the tone written as a word as well as a colour; every card now sits under the question it answers, and the paragraph each card opened with is one tap away inside the card, so the first thing on a card is its numbers; all of it is the site's own CSS over the token sheet with no token added, and the browser suite holds it at 375 px, two tiles to a row and nothing wider than the phone.
- **1.0.0.160** (2026-09-20): The Admin tab draws its key numbers, the second of three ships that make it something a team would want a copy of (ADR: The Admin tab, as a product): a Traffic card above the machines charts requests a minute, the median and the ninety-fifth, and answers that were 5xx and 4xx, over the same hour, day, week or month as the machines under it, with one window chosen once for both; the hour is the request ring folded into minutes by the same function that folds the minute each site keeps, so the card and the kept history cannot disagree; the proof's paired medians are drawn as bars over its table; every chart shares one frame, breaks its line where nothing was measured and draws a true zero where nobody asked; Material UI was priced at about 300 KB against a script of about 100 KB and turned down, and the charts are the site's own arithmetic in `machineChart.ts`, tested without React, in its own CSS over the token sheet.
- **1.0.0.159** (2026-09-20): The machine charts offer the last 24 hours, 7 days and 30 days beside the hour: the hour is the sampler's ring, this process's own memory, and every roll empties it, so each site now keeps a minute at a time in a `machines` container in Azure Cosmos DB, partitioned on the day and expired after thirty-one days by the container itself; twenty seconds after a minute ends `MachineRecorder` folds it out of what the process already measures, the mean and the peak of the working set, the managed heap, the processor share, the relational store's own rows for that minute read on the quiet context so a read a minute is not the newest line on the SQL card for ever, the request units the operations ring holds for it, and the requests, their median and ninety-fifth and their 4xx and 5xx answers from the request ring; a figure nobody read is left out of the document rather than written as a zero or a null, because the store's average skips what is absent the way the chart breaks its line over a gap, and a test against the real account holds the store's grouped query to the folding this repository does itself; every minute carries three bucket keys, so a day is 288 five-minute points, a week 168 hours and a month 180 four-hour points, each one `GROUP BY` over a key the index holds and cached for a minute; the card lays a window out slot by slot from its start to the server's now and draws a gap wherever nothing is kept, says how many of the window's buckets hold a reading, and with no document store beside it says in words that nothing is kept; `/api/admin/machines?window=24h`, `7d` or `30d`, and with no window the hour as before (ADR: What the machines are doing, addendum).
- **1.0.0.158** (2026-09-20): A catalogue nobody is using is let go: each site on the shared plan starts with the one catalogue it serves, but the first proof run after a roll loaded the other store's hundred thousand vehicles and kept them until the next roll, managed heaps of 265 to 295 MB a site on the machine that had measured as paging at exactly that, for a card somebody pressed once; `InventoryService` can now let a loaded catalogue go, and `CatalogueKeeper` asks it to once a minute for every store the site does not serve, when nothing has touched it for `Store:ReleaseIdleMinutes`, ten on the plan and zero, which is never, everywhere else; the store a site serves is never let go, a load in flight is never dropped, and a request touches the catalogue before it checks for warmth under the same lock the release takes, so it either keeps the catalogue from being idle or finds a cold store and awaits the load, and there is no order in which it is handed one that is about to disappear; after a release the collector is asked once for a full compacting collection so the machine has the memory back, and the machines card says which catalogues the process is holding (ADR: One plan, two sites, addendum).
- **1.0.0.157** (2026-09-20): The pages say what runs and what it costs, and the template is the thing that runs: both container groups were stopped at 05:16 CDT with both public names answering from the plan, stopped and not deleted, which bills nothing and starts again with one command, so the bill at list price is $22.38 a month where it was $78.85, the plan $12.41, the database $4.90 and the registry $5.07, a figure these pages had left the registry out of since they first quoted one; the Performance overview keeps its table from the container groups and adds the same proof run on the plan, where the round trip reads 1 to 2 ms to Azure SQL Database and 38 to 40 ms to Azure Cosmos DB, the two numbers it had always quoted on the other sides, every store-bound row flipped by exactly that and every request unit unchanged, which is the page's own claim that distance and not the engine made the difference, tested by moving the machine, and it says what the smaller machine costs in processor, the listing at 122 to 160 ms where it read 51 and a sign-in at 430 to 610 ms where it read 82 to 122; `infra/main.bicep` is the plan and the two sites through its module with Front Door and the origin lock behind a parameter that is off, its Container Instances and Container Apps branches gone with the platforms nothing runs on, deployed in incremental mode only by `scripts/deploy-infra.ps1`, which hands the running image and the three secret values back to the template so that describing the infrastructure never changes what runs; the record carries the move minute by minute, the proof, what a proof run does to the plan's memory, and every resource in the group named and priced with the three that are unused waiting on the owner's word; Hosting, the Infrastructure overview, SQL Server and Cosmos DB, the README, CI/CD, the architecture map and three drawings follow (ADR: One plan, two sites).
- **1.0.0.156** (2026-09-20): Both public names go to the App Service plan: the two origins in `edge/_redirects` are the two web apps on `azurewebsites.net`, reached over HTTPS, which closes the one plain-HTTP hop the chain had between the edge and Azure, after both answered on their own names as 1.0.0.155 with every address each serves up, the machines card reading and Azure's view of the container showing the plan both share; both deploy workflows roll a web app and nothing else, two calls, the four values the template does not hold written to a file by python and sent with nothing printed, then the image, and a test holds the origin each deploy verifies to the origin the edge sends that name to and to the web app it rolls; the container group files stay in the repository and the old origins stay in a comment in the rules file for the week the stopped groups remain the way back; the template turns off the affinity cookie App Service would otherwise add to every response; and the four records this supersedes in part, and the two whose live samples changed under them, carry addenda dated today rather than rewrites (ADR: One plan, two sites).
- **1.0.0.155** (2026-09-20): One App Service plan now runs beside the two container groups, and both sites roll onto it as well as onto the groups: a Linux B1 plan and two web apps for containers in West US 3, the one nearby region where this subscription's App Service quota is not zero (West US 2 still answers the zero the day-one record measured, read again at four sizes in seven regions before anything was created), described by `infra/appservice.bicep`, created in incremental mode, carrying every setting the container groups carried with a test holding the list to their two files, and running as the same user-assigned identity so the database needed no change; App Service hands out identity tokens from an endpoint it names in two environment variables rather than from the metadata address, so the two readings this application takes without the SDK, its own Azure resource and its telemetry, ask whichever door the host has, and Azure's view of the container shows a web app as what it is, its state, its image and the plan it shares, claiming no restart count it was never given; on the plan each site warms only the store it serves, because four catalogues on one 1.75 GB machine measured as paging and two measured as fitting; no public name points at the plan yet, the container groups still serve both domains, and the record carries the options priced, the wall measured and what the plan read (ADR: One plan, two sites).
- **1.0.0.154** (2026-09-19): Recent errors is a table with the stack beside each row: the error ring carries up to twelve frames of the exception that made a 500, the endpoint serves them, and the card shows the time, the status, the path, the type and the frames behind a disclosure, each frame a method with the file and line it is on, which is the distance between "something threw on /api/admin/machines" and the line that read a decimal into a double; the exception's message is still not there and the test throws on the self-test endpoint to prove both halves, that the frames arrive and that the sentence it throws with does not (ADR: Error handling, the addendum on frames).
- **1.0.0.153** (2026-09-19): The resource view's percentages are cast to float in the statement: the view returns `decimal(5,2)`, a decimal read into a double is an InvalidCastException, and both live sites answered `/api/admin/machines` with a 500 for four minutes from the moment the `VIEW DATABASE STATE` grant let the query run at all, which is a defect that could only appear against a real Azure SQL Database and did, the minute it could; and the page sweep now asks for the Admin tab's own readings, `/api/admin/machines`, `/api/admin/metrics` and its own report, because an endpoint that throws is a page that is down and this sweep was green through all four minutes of it (ADR: What the machines are doing, and ADR: Every page, checked at every roll).
- **1.0.0.152** (2026-09-19): The number the live sites actually answered with, 262, joins 229 and 300 as a shape of permission denied on the machines card: it is the generic "<permission> permission denied in database" that carries the permission's name in a message the card does not print, and 1.0.0.151 read it as an unknown number and said so rather than saying what it means; read live off both domains at 14:28 CDT (ADR: What the machines are doing).
- **1.0.0.151** (2026-09-19): The machines card says why a reading it does not have is missing, from the database's own error number rather than from the type of the exception: the relational store answered `SqlException` on both live sites at 1.0.0.149 and the card could only say that much, while the numbers the view answers permission with, 229 and 300, have a sentence with the answer in them, that reading it needs VIEW DATABASE STATE and the two roles this container's identity holds do not carry it; any other number is carried as the number, which names no server, and 1.0.0.150's claim that the container's log carries the reason is withdrawn, because the log ring keeps an exception's type and not its message (ADR: What the machines are doing).
- **1.0.0.150** (2026-09-19): One chart per resource on the machines card, drawn the way the site activity is drawn: the container's memory as a share of the limit its container group granted beside its processor share, the relational store's processor and memory as the shares of the tier its own view reports, and the document store's request units a minute on an axis of its own because it has no processor or memory to draw; a percentage chart keeps a full axis so a quiet hour looks quiet, a missing reading breaks the line rather than being drawn across, and the arithmetic sits in `src/lib/machineChart.ts` beside the activity chart's with eight Vitest tests of its own; the first live read of the card also said two things worth fixing here, that the memory limit a container's share is read against is the runtime's own rather than the container group's, about seven tenths of it, which the card now says, and that the relational store's resource view answered with an exception on both sites, whose reason now goes to the container's log where an operator can read it while the card keeps saying only the type (ADR: What the machines are doing, the addendum on drawing them).
- **1.0.0.149** (2026-09-19): The Admin tab says what the three machines under this site are doing, each reporting the way that machine actually reports: the container samples its own working set, managed heap, processor share, threads and collections every fifteen seconds and keeps an hour of them in about twenty kilobytes, because memory is not an event and every other reading on the tab is taken when something happens; Azure SQL Database answers with its own `sys.dm_db_resource_stats`, the last hour of processor, memory, data, log and worker percentages of what the tier allows, which on Basic is five DTUs, free on every tier and kept off the SQL card the way the health check is; and Azure Cosmos DB has no memory or processor reading to give, so the card says so in those words and shows the operations ring folded into request units a minute against the thousand a second the free tier allows, six xUnit tests and one browser test more, nothing added to the bill (ADR: What the machines are doing).
- **1.0.0.148** (2026-09-19): Every page this site serves is checked by the container that serves it, at every roll: `ServedAddresses` builds the list out of the catalogue rather than beside it, so a document added tomorrow is swept tomorrow, and the sweep asks for each of them four at a time on the container's own loopback a second after it starts, again whenever the Admin tab's new card asks, and records the status, the type and the bytes of each, because every check this project had asked whether an address answers and none asked what it answered with, which is how the README served two pages of raw markdown for weeks with every link green; an address that answers 200 with nothing in it counts as down, a document served as anything but markdown fails the gate, the sweep's own requests carry a header the request hook drops so a roll's ninety self-requests are not traffic, and the card shows what is down first with the build it was checked for, and the four addresses the frontend build puts in the web root are checked where they exist rather than called down on a machine that runs the API behind a dev server, the address it dials is read from the server when the sweep runs rather than from a variable an earlier callback fills, because those callbacks run in the reverse of the order they were registered and the first cut of this swept nothing at all, thirteen xUnit tests and one browser test more (ADR: Every page, checked at every roll).
- **1.0.0.147** (2026-09-19): The README's two links to documents open the documents: Built with AI and Performance were linked at `/api/docs/...`, the addresses the dialog fetches markdown from, so a reader who followed either from GitHub or from the README inside the app got a wall of raw markdown in a new tab while every link answered 200, and the two local addresses in its run steps were bare, which markdown turns into links nobody on the live site can follow; the links are `?doc=` addresses now, the local addresses are in backticks, and `RecordLinksTests` holds every link from every document to this site to the form that opens a page, a slug the catalogue serves or a drawing it draws, one xUnit test more.
- **1.0.0.146** (2026-09-19): The Web overview says what serving the type from the site's own domain moved, beside the 852 ms it already named: first contentful paint 2.8 s to 1.6 s on Lighthouse's throttled phone profile against the live site and a cold visit's third-party requests from five to none, both read off the 1.0.0.140 row of the Performance overview, so the page a reader is sent to carries the whole of that change; no code changed.
- **1.0.0.145** (2026-09-19): Two overviews open the Performance section ahead of the page that was already there: the Infrastructure overview is the chain a request crosses hop by hop, with where each machine sits, what it costs at list price, $73.78 a month with both sites running, and what it adds to the clock, and the Web overview is what those machines send a browser and the order a cold first visit loads it in, four waves read on both live sites by `scripts/load-order.cjs`, which joins the repository so the page names the script that produced its numbers, with all six rounds' marks and one round request by request; the Performance page no longer says the second container is stopped after a comparison, because both run, its container row carries the price of each, and the 1.0.0.141 row of its wire table loses the half-row that had been pasted in front of it; no application code changed beyond the two catalogue entries and the three sidebar rows.
- **1.0.0.144** (2026-09-17): The Performance page's wire table carries the last after number, read off the live 1.0.0.143 the way every other row was: every card photograph a cold visit fetched was the WebP copy and Lighthouse's phone profile fell from 1,565 KiB to 1,145, and the section closes with the whole lane read as one line, 76 to 85, first paint 2.8 s to 1.6 s, one render-blocking resource to none, the script 126,267 to 89,635 bytes on the wire, with the one number that did not move, layout shift at 0.175, said beside them; no code changed.
- **1.0.0.143** (2026-09-17): The WebP copy the photographs record said was next: `resize_photos.mjs` writes a WebP beside every JPEG at both widths, from the original in both cases, and `VehicleImage` offers that pair first through a `picture` element with the JPEG pair as the fallback, so a browser that reads WebP moves 43 per cent fewer bytes for the 1280 copy a dense phone screen takes and six per cent fewer for the 480 a desktop card takes, where mozjpeg was already tight, with the margins held by `PhotoSizeTests` at the sizes that were measured rather than the ones the format promises; the repository grows by about 9.6 MB of vendored files, said plainly, and the phone-profile page weight before and after is on the Performance page (ADR-036 addendum), one xUnit test more.
- **1.0.0.142** (2026-09-17): The filter values are built once, with the catalogue: `/api/facets` walked all hundred thousand vehicles four times on every request for an answer that cannot change after load, and is now a field of the loaded catalogue beside the dictionary and the search index, handed back by reference and held so by a test; the page asks for it until it has it and then keeps it, where until now the effect re-asked on every listing refresh, four times an idle minute (ADR-025 addendum); the server-side time and the idle minute's request count before and after are on the Performance page, one xUnit test more.
- **1.0.0.141** (2026-09-17): The document renderer arrives with the first document a reader opens, not with the page: `marked` and highlight.js with its sixteen grammars, the two heaviest things the frontend carries after React, move into `src/lib/markdown.ts`, the one file that imports either, and the documents dialog imports that file on demand, so Vite emits it as a hashed chunk of its own and the inventory page's script no longer carries a renderer it never runs; the chunk table in the ship log and the Performance page carry the bytes before and after, `markdown.test.ts` holds the rendered shape of a fence and a link, and the live block in ADR-074 reads the renderer from its new file (ADR-074 addendum).
- **1.0.0.140** (2026-09-17): The type is the site's own: the four Poppins files the page was fetching from fonts.gstatic.com, and the stylesheet from fonts.googleapis.com that named them, are replaced by the same four latin woff2 files under `/assets`, declared in `src/styles/fonts.css` with the same unicode range and swap rule and hashed by the build like every other bundle file, so a cold visit makes five fewer requests to two fewer origins and the one render-blocking resource on the page, 852 ms of it on a throttled phone by Lighthouse against the live 1.0.0.139, is gone; the Performance page gains the page-as-received measurement every gain in this lane is judged against, and a browser test holds that no request leaves for a font host and Poppins is the face the page paints with (ADR-016 addendum), one Playwright test more.
- **1.0.0.139** (2026-09-17): Signed out, the vehicle page offers no bid form: the bid panel is told who is signed in, the way the proof card is, and on a live auction with nobody signed in it renders one control, "Sign in to bid", that opens the account view, with no amount field, no Place bid and no Buy now, where until now a visitor could fill in an amount, press the button and learn from the server's 401 that a bid needs an account (ADR-037 addendum); a browser test holds both halves on both stores, one Playwright test more.
- **1.0.0.138** (2026-09-16): The resume the site serves at /api/docs/resume is the 16 September build, and the pages a reader checks it against say the same things: Built with AI and the README say every test was specified before the code it holds was written, and the README now lists every sidebar section, all three ports, four runtime dependencies, nine accessibility views, keyless access to both stores, the gate that serializes simultaneous bids, and the six live Cosmos DB tests the ship gate runs before each release.
- **1.0.0.137** (2026-09-15): The API describes itself: an OpenAPI document at `/api/openapi/v1.json` built by the framework's own generator from the endpoints as they are mapped, and a Scalar reference page at `/api/reference` served by the same container, its assets from the package rather than a content delivery network, with an API Reference section of its own in the sidebar linking both. Every public operation carries an operation id, a summary, and the responses it can actually answer, the failures included, which meant typing the endpoints: every anonymous object became a named record, the vehicle on the wire became `VehicleView`, and the handlers answer through `TypedResults`, with no name, value or order on the wire changed. The fifteen operator endpoints under `/api/admin/` are filtered out of the document, the bearer and cookie schemes are declared and exactly the operations that need a session are marked, and `ApiDocumentTests` holds all four rules against the routing table's own description of the host, so an admin route that leaks, a public endpoint that vanishes, or an operation that ships unnamed fails the build. The bare 404 and 401 that the status code pages middleware had been filling in now say what was not found themselves.
- **1.0.0.136** (2026-09-15): The rules a change has to pass, each one written down beside the test that holds it: seventeen standing rules taken out of the records and mapped to the sixteen test classes that enforce them, and the map itself held by a test that resolves every name in it in both directions, so a renamed test or a renamed record fails the build instead of passing while it sends the next reader somewhere that no longer exists. The shape of a record is held now too, after the seventy-fourth arrived with a status line in a form no other record uses and nothing noticed for a day: a title the index can read, a status above the first section, and the Files section that takes a reader from the argument to the code, with the four records written before the titled convention on an allow-list that has to shrink if one of them is ever brought into line. The staff review gained the Files section it had never had, the two records written before their code now say what became of them, and CLAUDE.md opens by telling whoever reads it next to read the record that governs the thing they are about to change.
- **1.0.0.135** (2026-09-15): Every sidebar section is a closed index on arrival: eleven headings instead of about a hundred rows, each one a native `details` so the keyboard and screen reader behaviour comes from the element, the label still a heading inside the summary, opened by a click and closed again on the next visit because the reason to collapse is the arrival rather than the session, with the icons rail keeping its rows since it shows no headings to collapse (ADR-013 addendum); the sealed page also leads with what a record buys, a class the compiler writes equality for, and with the `EqualityContract` an unsealed one hands a derived type, which is where equality changes meaning for every comparison against the base.
- **1.0.0.134** (2026-09-15): The code theme, corrected against the live page, and the sealed page says what sealing a record buys: comments are green, the code itself is darker than the prose because it sits on a gray ground rather than white, numbers move off green so two token kinds are not one colour, and the Best Practices page gains a section on data transfer objects, whose equality is their values only because every record here is sealed, with the wire shape of a vehicle shown whole and a test holding all fifty-eight records to it (ADR-074 addendum).
- **1.0.0.133** (2026-09-15): The code in every served document is coloured by the site's own palette: highlight.js registered for the languages the documents actually use, counted rather than guessed, a theme of six tokens each held to WCAG AA on the ground code sits on and held apart from each other, and the expander now names a language for a Dockerfile, an `.editorconfig`, a TOML file and a script, all four of which had been rendering as plain text (ADR-074).
- **1.0.0.132** (2026-09-15): Sealing is written down and held by a test: a Best Practices page explains what `sealed` says, what the runtime and the analyzer do with it and when a class should stay open, each section carrying a whole class read from the running build, and SealedByDefaultTests fails when a class in the five application projects is open with nothing deriving from it, with CA1852 on as a warning so the build holds the internal half.
- **1.0.0.131** (2026-09-14): The two deploy workflows are held to one answer by a test, after 1.0.0.128 changed the database name in one and 1.0.0.129 had to change it in the other: registry, resource group, telemetry component, server, database and identity must agree, and the database must be the one the SQL record says the sites run on; two records and two changelog lines also stop quoting the day's asks word for word and say them plainly instead.
- **1.0.0.130** (2026-09-14): The reset link reads as a link, on Steve's word, a friendly address and a clean GUID: each site builds it from its own configured address rather than the origin's host the edge hands the container, and it carries a plain GUID under which the signed token is kept in a new `resets` container on the document store for the hour and deleted on use, so the token never travels and a second use finds nothing (ADR-037 addendum); two tests hold the shape and the port.
- **1.0.0.129** (2026-09-14): The Cosmos DB site's second store points at the Basic database too: its own deploy still named the paused serverless one, so after 1.0.0.128 its health card read the relational check as failed while the SQL site's read healthy (read off both sites by the runner at 09:38); one line in the second deploy workflow, nothing else.
- **1.0.0.128** (2026-09-14): Site activity is kept in Azure Cosmos DB by both sites, each row naming the store that served it, and the card reads it from there alone, on Steve's word that activity should live on Cosmos DB for good: the serverless Azure SQL free amount for September ran out at 06:40 UTC because the activity writes every five seconds never let the database pause, Azure paused it until October, and the SQL site served from files with accounts, bids and reset answering 503 while the activity card answered 500 on both sites. The site now points at a Basic 5 DTU database on the same server, his pick at $4.90 a month; the paused one is left alone. Playwright's expect waits fifteen seconds instead of five (ADR-068 addendum), the runner's scheduled task runs at Normal, and ADR-039, ADR-071 and the Performance page carry the measurements (ADR-018's numbers recounted).
- **1.0.0.127** (2026-09-13): "Forgot password" on the sign-in form: the site emails the same reset link through Azure Communication Services as the containers' own identity, one sentence back whether or not the address has an account, one email per address per five minutes, and a container with no sender configured says so and points at the operator's link (ADR-037 addendum). The first take was refused by the gate: the host project's Azure.Core duplicates the credential types the pinned Azure.Identity has, naming one beside the email client did not compile, the reflex fix moved Azure.Identity to 1.21.0, and the pin test from the 1.0.0.90 incident caught it on both passes; the sender now borrows the store's credential rule and the pin stays at 1.17.1 (ADR-059 addendum).
- **1.0.0.126** (2026-09-13): The per-visitor rows are off: the visitor table and the kept log answer 404 to everybody until `Admin__VisitorRows` turns them on, the page shows neither, the graph of unique visitors per day stays, and the rows keep being written; the operator's key box moved to an Operator card of its own beside the reset links (ADR-071 sixth addendum).
- **1.0.0.125** (2026-09-13): A password reset in two halves: the operator mints a reset link from the Admin tab behind the key, an hour of life and one use by fingerprint of the password hash, and the visitor chooses a new password from the link and is signed in; an emailed link is the same second half with a sender in front of it, which waits on a sender (ADR-037 addendum).
- **1.0.0.124** (2026-09-13): Logins last a year past the last visit: the session token is a year long and the first request on any day a token is more than a day old gets a fresh one, only on the API and never on sign-out; the lifetime is configuration and two tests hold the rule and the cookie on the wire (ADR-037 addendum).
- **1.0.0.123** (2026-09-13): The operator's key can be typed into the Kept log card and is remembered on that browser, so no link has to carry it to a phone; the keyed URL still works where it arrives whole (ADR-071 fifth addendum).
- **1.0.0.122** (2026-09-13): The Performance page shows its code: the container definition, the proof's rounds and its verdict arithmetic, the catalogue container's partition key and indexing policy, the warm-before-reading middleware and the cache headers, all read from the running build, with the search index and the cache headers added to the list of where the milliseconds came from; the request hook makes the visitor token once per request instead of twice, from the self review recorded in ADR-073.
- **1.0.0.121** (2026-09-13): The proof card's "Sign in to run the proof" button opens the account view when the visitor is signed out, where it sat disabled before and read as broken on a phone; signed in, it runs the proof as before (ADR-067 addendum).
- **1.0.0.120** (2026-09-13): The browser remembers the operator's key after one keyed visit, so the visitor table and the kept log show on a plain Admin URL from a phone that has opened the keyed one once, and a bookmark saved after the page loaded no longer loses it; a button under the visitor table forgets the key on that browser (ADR-071 fourth addendum).
- **1.0.0.119** (2026-09-13): Long-term retention, on Steve's word: the activity counters no longer expire on the document store (they were thirty-five days) and the kept log expires after three years instead of one, both as the one number on each container's definition, applied to the live account; the activity card now says the retention it read from the container, as the kept log card already did (ADR-071 third addendum, ADR-073 addendum).
- **1.0.0.118** (2026-09-13): The kept log: every request, error and warning written to Azure Cosmos DB off the request path, in batches once a minute, one document per event partitioned on the day and expiring after a year, read back on the Admin tab's new Kept log card behind the operator's key with a window and filters by kind, status and path; a browser error report's message and stack are now cleaned on arrival, so an address in one cannot reach the public errors ring (ADR-073).
- **1.0.0.117** (2026-09-13): The security decision, recorded: no secret is a value in this repository, the two that exist (the session signing key and the operator's admin key) are repository secrets filled into the container at roll time, everything else authenticates as a federated or managed identity with no password anywhere, and a missing secret makes the site smaller rather than open (ADR-072). The operator's key is set, so the visitor table opens for him from the deployed site.
- **1.0.0.116** (2026-09-13): The activity graph draws unique visitors per day, everybody as one line and one line per store, counted on the server from the visitor rows so no token leaves it, and the visitor table under it groups each visitor's day under a heading for the day, newest first, with the day's own totals; the requests-per-bucket series stays on the wire, and the rows stay behind the operator's key (ADR-071 addendum).
- **1.0.0.115** (2026-09-13): The measurement the activity record owed, read off both live containers on 1.0.0.114 a quarter of an hour after the roll: 39 and 38 ms to Azure SQL Database, 2 ms to Azure Cosmos DB, the same sentence as before the change on every row that matters, so the batch writer off the request path costs the request path nothing the proof card can see (ADR-071 addendum); the Performance page quotes the same two cards beside the 1.0.0.94 table it keeps.
- **1.0.0.114** (2026-09-13): Site activity at the top of the Admin tab. A graph of requests over the last day, week or month, one line per store because each request's row is written by the store that served it, in batches off the request path, with the totals, the split between what looked like people and what looked like scanners, and the top paths; a visitor is a keyed hash of the address that rotates daily beside the address cut to three octets, a full address is never stored, no account and no email can reach the rows because the hit has no field for them and a test holds both responses to carrying no at sign; the per-visitor table answers only to the operator's key and is a 404 to everybody else, because the tab is public by design; two counter tables on Azure SQL and one container on Cosmos DB to be published by a person, each store's line saying what is missing until then (ADR-071).
- **1.0.0.113** (2026-09-13): The public surfaces brought up to the checkout. Two sections join the sidebar beside Hosting, Performance, a page on running a hundred thousand vehicles on two free-tier stores and one small container at millisecond speeds with every figure linked to the record that measured it and the honest line kept, that the two engines are not different and the distance to them is, and Built with AI, what the AI wrote, what the owner decided, what governed it, what it cost and what went wrong, with the README's first screen pointing at both; the head of the page stops claiming a record count, because it said forty-five for fifty-five versions while the catalogue held seventy, and the public-face scan reads index.html now so a count typed back in is held to the catalogue (ADR-053 addendum); the eighteen screenshots that carried a signed content credential are stripped, the stamp test widened from SVG to PNG and JPEG (ADR-006 addendum); the served resume is the 13 September build; and the contrast frames came out of How this was built.
- **1.0.0.112** (2026-09-09): One clock for everybody. The auction's anchor was the caller's: the page sent its own local midnight as `anchor_ms` and the server derived every window from it, so two visitors in different zones were in different auctions and a request that named yesterday's midnight could bid on a vehicle that had ended for everyone else, which is the second finding of the fresh-eyes review. The anchor is the server's now, the UTC midnight that began the day, the same instant for every visitor; the parameter is gone from the listing, the detail, both bid writes and the room's tick, the page no longer computes or sends a midnight, and a page from an older version that still does is not read. The day's auctions turn over at 00:00 UTC rather than at each visitor's midnight. ADR-070 carries the addendum; the domain, API and page tests that held the old contract hold the new one, and the measurement script and the proof stopped sending the anchor. Same count of xUnit tests, two rewritten.
- **1.0.0.111** (2026-09-09): The rest of what three readers with no memory of the project found, and the record of all of it. ADR-070 is the review itself: who the three readers were, the eight findings that held, and what was decided on each, fixed with its version, designed with the version it ships in, or accepted with its reason. In this version: the session signing key is configuration the deploy hands both containers from one repository secret, substituted into the container spec at roll time like the connection strings, so a roll no longer signs everybody out; a placeholder, an empty value or a key too short to sign with all read as no key, and the process invents one and says so, which is what every roll did until now. A session bids only where its account is: the token names the store that opened it, and a bid or a purchase sent to the other store through the header is refused with a sentence rather than written under an account that store does not have, which the relational store's foreign key had been answering with a 500. The pipeline awaits a store's catalogue before any endpoint reads it, so a request that reaches a store still loading waits instead of blocking a request thread, the shape the ports record argued against. A reset writes the store before it clears memory, the bid path's own rule. The three comments on the bid stores' concurrency retry say what the retry does. SECURITY.md names the plain hop from the edge to the origins and the session's store; the pipeline pages say there is one secret now. Four xUnit tests more.
- **1.0.0.110** (2026-09-09): A purchase ends the auction for everybody. Buy Now recorded the sale on the buyer's own bid and nowhere the rules or the wire could see it, so the buyer's page said Sold while everybody else's showed a live auction standing at the Buy Now price, and a second account that bid that price was resolved by the same shortcut that sold it the first time and told it had won: two buyers, one vehicle. The rules now take a sold flag and check it before everything else, the bid service supplies it from the standing it already kept, under the gate that makes it true, and every vehicle on the wire carries `sold`, so the listing, the detail and the bid panel show Sold to everybody and offer no form; a bid or a second purchase on a sold vehicle is refused with "This vehicle has been sold." Found by the fresh-eyes review the previous version answered, recorded as an addendum to the accounts record, and held at the rules, the service and the API with two accounts. The README's bidding paragraph and scope bullets, which still described one anonymous buyer in the API's memory, now describe accounts, the room and the two stores, and the sidebar bullet names its two newest sections. Five xUnit tests more.
- **1.0.0.109** (2026-09-09): The documents brought to the code. Three readers with no memory of the project, an interviewer, a junior developer and an architect, were given the checkout and asked to find fault, and the first thing all three tripped on was the same: pages describing a system that no longer runs. Fixed in one pass: the architecture page said no authentication and a SQLite file where there are accounts and two stores, and that every fetch lives in one file when six files fetch for their own reasons; the data flow page said one anonymous buyer; CLAUDE.md said five projects and decimal money where there are nine projects and whole-dollar integers; the README said the site costs nothing, listed accounts and a database as out of scope, credited a test with a stopwatch's number and a guard the code never had, and now says where the project started; the Program.cs record's singleton sentence, its startup line and its numbers, the React record's script count and its one-seam claim, the tests record's counts and its three CI jobs that are five, the partition key written as /userId in two records against /user_id in the definition, the unique index credited to the wrong column, the comparison page's fourth port, the security page's one container that is two, the store record's first-shipped cookie described as current, and two records pointing at notes outside the repository. And one line of code the accounts record had promised for a week: the process now logs a warning when it invents its own signing key. In the same version, three of the things the code did that its records denied: starting the performance proof was anonymous and registered two accounts a run, so one request a minute spent the whole hour of registrations; starting a run takes a signed-in visitor now, the card says so and disables its button signed out, and the proof's two accounts are made once per process and reused, with the first run's registration sample carried into every later result. A registration Identity refused kept the limiter's slot; it goes back. And a catalogue or bid replay that failed at startup was kept as a failure for the life of the process by the Lazy that shared it, while the log promised a retry; the next caller retries now. The rest of what the three readers found is a numbered list in the lane's report, and the next version takes the largest: Buy Now ending the auction for everyone. Five xUnit tests more, one browser test changed to sign in first.
- **1.0.0.108** (2026-09-09): The quotes, cleaned. Every instruction the records quote from Steve now reads as written for print, spelling, casing and punctuation regularized and product names in full, the meaning and the phrasing his: twenty-one passages across sixteen records and four changelog lines, and the rule is in the style guide under Quoting the owner. The sidebar's two new sections are photographed on the live site for the records that describe them. And the Admin browser test gives the health card forty-five seconds rather than five, because on the gate's Cosmos DB pass the card waits on two real stores behind cold token acquisitions and a serverless database that wakes in tens of seconds, which the connection already budgets for; it was still loading at five on an otherwise green pass. Documents, images and one test budget.
- **1.0.0.107** (2026-09-09): SQL vs Cosmos DB, at the top of the sidebar, and a Diagrams section. The side-by-side comparison of the two stores is a page now rather than a decision record, because it decides nothing and shows what the records decided: the same ten rows, the same three pairs of live code, the same links and the same drawing, in a section of its own beside Hosting, and the records index is sixty-nine, with the rule written into the index's record. And one place for the drawings: a Diagrams section, one row per page for all five, each opening in a new tab; a test holds the list to the server's catalogue and the browser suite reads both sections. One xUnit test more.
- **1.0.0.106** (2026-09-09): SQL Server and Cosmos DB, side by side. Steve's words: "I'd also like a diagram and analysis of SQL Server vs Cosmos DB, where the left side is SQL Server and the right side is Cosmos DB, with research links, code samples and the ADRs linked in, drawing attention to the two different databases". A seventieth record puts the two stores next to each other in ten rows, what each is, how the application reaches it, the same bid at rest, the same write, the same guarantee given by one engine and built on the other, indexes and cost, consistency, what the Admin tab shows, what was measured and what it costs this month, every row naming the record that decided it and linking to it; the same bid row and bid document, the two bid stores' SaveAsync and the two ways an address stays unique are shown as live code from each side; thirty-six Microsoft Learn pages, each read the same morning, are the reading list; and a fifth drawing, Azure SQL Database on the left and Azure Cosmos DB on the right, opens on its own page. A test holds the record to its pairs and its links. Seventy records.
- **1.0.0.105** (2026-09-09): Every sample a record promises, shown. A sweep of all eighty served documents on both live sites, run for Steve's "make sure all documentation and features work", found one record rendering "Sample unavailable" where its method should have been: the measuring record named scripts/measure_stores.py, scripts/ was not one of the live-sample roots, and the expander declined it exactly as designed, on every machine, since the record was written, with every gate green because a note is not a failure. scripts/ is the seventh root and the image copies it; and two tests read what the reader would have read, one expanding every served document against the checkout and failing on any note, one holding every path a live block names to the Dockerfile's runtime stage, glob by glob, so a sample present on a developer's machine and missing from the image is a red gate and not a live surprise. Two records carry addenda. Three xUnit tests more.
- **1.0.0.104** (2026-09-09): The drawing as drawn, and the test that keeps it so. The redrawn infrastructure source reached the developer's machine eight kilobytes heavier than it left: one of the tools that carries a file across writes a signed content credential into every image it touches, and in an SVG that was half the file, inlined into the diagram page on every visit. The copy that shipped in 1.0.0.103 was the source as drawn, matched by checksum after the stamp came out; the docs-and-testing record says what happened and how a copied file is verified from now on, and one xUnit test reads every drawing for a stamp so the next one is a red gate rather than a file size that looked wrong. Two documents, one test, no code.
- **1.0.0.103** (2026-09-09): The document store in the console log, and the drawing brought up to date. Steve, reading both Admin tabs: "missing a log on the Cosmos DB side like SQL has, even if it's a log of the API requests". The log card showed every SQL statement because Entity Framework logs each command and nothing for the document store, so the store now writes one line per operation to the application's logger in the same shape, what ran, on which container, the request units, the time, the partition described and the query with its parameters by name and never a value; a test reads the line back on the gate's Cosmos DB pass and checks the address it looked up is nowhere on the page. The infrastructure drawing names both sites, both CNAME records, the rule the Host header picks and the Store bar as a link, where it still said one name and a cookie; the docs-and-testing record says so. And the gate's own accessibility scans are declared slow, because on this 8 GB machine, with four Chrome workers sharing it with the .NET side, two of them ran past sixty seconds this morning while asserting nothing less; the five-minute gate's record carries the three reds and the memory read before each retake. One xUnit test more.
- **1.0.0.102** (2026-09-09): The pictures, and the resume. The toggle as a link between the sites, followed both ways on the real hosts by the live check and photographed: the live site, the second site it lands on, both bars and the phone, in the one-container record; the Timing card before and after on both sites in the comparison record. And the resume the site serves at /api/docs/resume is the 2026-09-09 one, the file of record in the job hunt folder, two pages with the Cosmos DB work on them. Documents, images and one PDF.
- **1.0.0.101** (2026-09-09): The toggle moved to the sites, and the second address read live. Steve's words: "the button should toggle between the two sites, not refresh in React; at the least, the URL should change". The Store bar's other segment is now a link to the other site at the same path and query, so the address bar changes and the page that arrives is that site's own on its default store; where a container names no other site the segment is drawn as not here, never as a dead button, and the sentence names the site as well as the store serving it. The cookie that chose a store retired with the in-place switch, because each site is one store's site now and a browser that toggled last week would otherwise have landed on the live site served from the other store with no control left to change it: the server reads the header or the default, expires the old cookie on sight, and the switch endpoint is gone with its tests, replaced by one that holds the expiry and the refusal. With it, the permanent address record gains what the morning read: the CNAME and the alias as Steve added them, the certificate reissued with four names, the address answering with the second store as its default at 07:58, and the meter before and after, one deploy and fifteen credits; the live site's Peer__Site becomes the new address, the Hosting page says the second site has a name, and a fourth drawing, TheYard's two sites, shows how the two names reach the two container groups through the one edge and how both groups reach both stores, on its own page and in the record, because he asked for the picture in as many words. And the Admin tab's third ask, his words "make sure the admin we have all of the same stats for cosmos as we do SQL server": the Timing card gains a document store line under the SQL line, the same three numbers plus the request units the window cost and how many operations fanned out across partitions, its window sentence names all three rings, and a container with no document store says so in words; the inventory behind it is in the comparison record's addendum. One xUnit test fewer for the toggle and one more for the metrics shape, five Vitest tests more, the browser count unchanged, all rewritten for the new shape.
- **1.0.0.100** (2026-09-09): A permanent address for the second site. Steve's words: "we need a permanent URL for the Cosmos DB site". The edge gains two lines above its catch-all that send theyard-cosmos.stevenstout.biz to the second container group, the one whose default store is Azure Cosmos DB, so the second site gets the domain, the padlock and the port-free address the live site has, through the same Netlify site, the same certificate authority and the same deploy meter; the other three ways were priced and declined in the record, and the two parts outside the repository, a domain alias on the Netlify site and one CNAME at Wix, are spelled out in it. Sixty-nine records.
- **1.0.0.99** (2026-09-09): The last two records brought up to date with the gate: the second-store record says what the gate runs on the document store since 1.0.0.97, and the one-container record shows the Store bar with its link to the other site on both sites. Documents and two images.
- **1.0.0.98** (2026-09-09): The infrastructure drawing's preview re-rendered, so the README's picture carries the counts the drawing itself already did (379 tests, the image tags to v97). Image only.
- **1.0.0.97** (2026-09-09): The five-minute gate, and the two sites on every page. Every test application boots a thousand vehicles instead of the site's hundred thousand, the one class about the size asks for the full catalogue by name, the accessibility scans run in parallel, and the ship gate runs its node side and its .NET side at the same time with every suite once per store; xUnit on SQLite went from 74 seconds to 16 and the whole wall, every suite on both stores, from about twenty minutes to under five, with nothing skipped and nothing asserting less (ADR: The five-minute gate). The Store bar now also links to the other site, the container whose default is the other store, so both addresses are on every page. Sixty-eight records.
- **1.0.0.96** (2026-09-09): The night's own code, reviewed. The server now refuses to switch a visitor to a store that did not come up, with the sentence the bar already showed, so a stale page or a script cannot set a year-long cookie for a store with no accounts behind it; the bar's sentence tells the truth about such a store instead of announcing it as whole; and the proof record says that the rings it reads are shared with any visitor bidding during a run. One xUnit test and one Vitest test with them.
- **1.0.0.95** (2026-09-09): The proof's numbers and the pictures. ADR-067 carries what the proof card produced on both containers, read from the live sites: on three of eight paths the two stores answer in the same time, and on the other five the difference is the round trip to the store, 39 ms to Azure SQL Database one region away and 2 ms to Azure Cosmos DB in the container's own region, which taken off leaves them the same; with the two things the run taught, that the first run after a deploy costs more on both stores and far more on the relational one, and that the relational store's free offer sleeps when nobody visits. ADR-066 shows the Store bar on the live site before and after a switch, on a phone, and the comparison card with both stores in one process; ADR-065 closes with what the proof adds to the choice. Documents and images only.
- **1.0.0.94** (2026-09-09): The toggle, the proof, and the second review. One container now runs both stores, Azure SQL Database and Azure Cosmos DB side by side in the same process, and a switch at the top of every page picks which one serves the visit: a cookie, a reload, the same address. Each store is brought up on its own and stands behind its own catalogue, bids, room and accounts, so an account made on one reads as signed out on the other and the bar says so; the comparison card on a container with both stores compares them with each other in one process, and the health check names every store. With it, the proof: a card that sends the requests a visitor makes to the container itself on both stores in paired rounds, measures the round trip to each store on its own, and says per path whether the stores answer in the same time and, when they do not, whether the difference is the store or the distance to it. And a second review of the day's code, which found and fixed a document store seeded only when empty and so never repaired after a crash mid-seed, an email claim with no account behind it refusing the address forever, and a refused batch that went unrecorded. The infrastructure drawing is redrawn with the second store, the toggle and the proof on it. Sixty-seven records.
- **1.0.0.93** (2026-09-08): The pictures and the pin. Both Admin tabs on 1.0.0.92 were photographed a minute apart after six paired rounds had given every row a number: the comparison card from each side, and the two store cards showing one visitor's reset, raise, bid, sign-in and registration as operations with their charge on the document side and as statements on the relational side, each placed in the record it belongs to. The comparison record is corrected, since the charge per route has been per request since 1.0.0.92 and the record still called it approximate. And the Azure.Identity version is held by a test as well as a comment: it reads the one assembly every project resolves and fails the day anything in the graph moves it off 1.17.1, which is where the 1.0.0.90 incident should have been caught.
- **1.0.0.92** (2026-09-08): The numbers. Both containers were measured in one session from one machine, twenty paired rounds of everything a visitor does, and the records now carry them: the pages that never touch a store are equal to within a few milliseconds on both sides, and every path that does is faster on Cosmos DB by the width of a region, because its account is next door to the container and the SQL server is one region away. A bid is 135 ms against 219, a sign-in 221 against 249, and a sign-in costs the document store exactly two request units every time. The partition key experiment seeded 100,000 documents twice, once under the tuned indexing policy and once under the default, and the default cost 1.8 times as much per write, took eight minutes longer, had 8,407 writes refused by throttling, and bought nothing on any of the seven queries. Three records: the measurement with its method, the teaching record for someone who knows SQL Server and not this, and the partition key record with its table filled in. One fix found by the measurement: the comparison card summed every sign-in on a path into one request charge, because it told requests apart by their path, so operations now carry the trace identifier and twenty sign-ins are twenty samples. And one found by the ship gate: the page asks who is signed in when it opens, and an answer arriving after the visitor had already registered through the form signed them out again, so the answer now applies only if nothing changed the account while the question was out. And one more from the same gate, on the store that remembers: the test containers keep a day of bids, the most-bid vehicle had climbed past the room's ceiling, and the bidding helper now opens a vehicle the room can still answer on.
- **1.0.0.91** (2026-09-08): 1.0.0.90 rolled both containers and the Azure SQL one came up on files. SqlClient acquires its managed identity token through Azure.Identity, the new Cosmos DB project had pulled that library from 1.17.1 to 1.21.0 for the whole application, and the newer version spends longer than SqlClient's thirty seconds finding the identity endpoint on Container Instances, so the connection was cancelled mid-wait, twice, against a database that was online. The Cosmos DB container survived the same wait because its SDK has no such ceiling, and paid with a forty-nine second container check. The reference is pinned back to 1.17.1 with the reason beside it, and the deploy stops writing Connect Timeout=30 into the connection string, because the code widens a timeout nobody gave to the sixty seconds the SQL Server record reasons from and the deploy's thirty had been winning over it for a week. The live site ran 1.0.0.88 for the forty minutes in between, rolled back by hand with the deploy's own template.
- **1.0.0.90** (2026-09-08): 1.0.0.89 never reached either container. CI's coverage floor went red at 83.2 per cent of lines, because the document store's adapters are tested against the real account on the ship gate and CI has no credential to do the same, so the number CI holds to its floor now leaves that one assembly out, with the reason beside the flag: naming the assembly hides only the gap CI cannot close, where lowering the floor would have hidden every other one. With it, the partition key experiment: two more containers, catalogue and catalogue-default, partitioned on the make and holding the 100,000 expanded vehicles under the tuned indexing policy and the default one; a console tool that seeds them in bulk and runs the seven queries the partition key record names, in paired rounds, with the request charge beside each; and a card on the Admin tab, The partition key live, that runs the same seven queries with the container's own identity and shows what a query that names the key costs against one that fans out across every partition. On a relational container, and on a document container whose catalogue is not seeded, the card says so, and a browser test holds each sentence.
- **1.0.0.89** (2026-09-08): A second, complete backend on Azure Cosmos DB, beside the Azure SQL one, in the same image. Catalogue, bids and accounts all live in a document store now as well as in a relational one, and a second container group, same region, same 1 CPU and 1.5 GB, comes up on it so the two can be opened in two tabs and compared. The store holds 200 documents rather than 100,000, which is the fact that decided the arithmetic: a cold start is about 250 documents and the whole month is pennies at serverless rates and $0.00 on the free tier the account was created on, with no keys in existence and the container's own managed identity holding the only role. The three ports every store implements return a Task now, because the document store has no synchronous driver and a port that blocks a request thread on a one-vCPU container is a performance defect, so BidService holds a semaphore where it held a lock and the host warms the catalogue before it serves. Accounts are one document per account and one per address, the second being how an address stays unique on a store with no unique index across partitions. The Admin tab gained a card at the top with this container and its peer on the same rows, read through the container's own API with two and a half seconds of patience, and on the Cosmos container the SQL card becomes the operations card, with the request charge and the partition beside every operation and still nowhere to put a value. Six records explain it, the four records that described a one-store world each carry an addendum saying what changed, and the whole suite runs a second time with every application booted on the document store, which it passes.
- **1.0.0.88** (2026-09-04): The price filter rendered "Ma" where it meant "Max", at 1024 pixels, which is the most ordinary laptop width there is. Two boxes and a dash were being asked to fit in one track of a grid sized for one control, which left about seventy-five pixels an input, and a number input spends twenty of those on spinner arrows nobody has ever used to enter a price. The pair takes two tracks now, and the whole row on a phone where there are only two tracks to take, and the spinners are gone while typing and the arrow keys are not. A browser test measures the box rather than trusting the eye: it has to be wider than ninety pixels, because a word cut off inside its own field reads as a broken page rather than a narrow one.
- **1.0.0.87** (2026-09-04): The API host is 1,244 lines in one file, which is the first thing a reviewer notices about this codebase, and nothing anywhere said whether that was a decision or a drift. The record that walks that file now says: 444 of those lines are comment and 86 are blank, leaving 714 lines of code across 29 endpoints, which is twenty-five lines each and most of them a route, a binding and a delegation, because nothing in that file holds a rule. The reason to keep it whole is the middleware order, which is behaviour that does not announce itself and which this project has already been bitten by: the timing middleware sat below the exception handler and recorded every failed request as a 200. A reader who can see the pipeline from builder to app.Run without opening another file can see that kind of mistake; a reader following AddYardEndpoints into a second file cannot. And what would change the decision is written down as a trigger rather than a number, because a rule that says split at a thousand lines would have split this one at the wrong seam. Those four numbers are counted by a test rather than typed, which is the third time this week a number in prose has been held to the code it describes.
- **1.0.0.86** (2026-09-04): Two things a second reading of the week's own diff found. The Copy link button on a record did nothing at all outside a secure context, because navigator.clipboard is undefined there rather than a promise that rejects, and the optional chaining that was meant to be careful about that silently skipped the whole call and left the button saying "Copy link" forever; absent and refused are the same answer to a reader, so it says the link is in the address bar either way. And opening a record now pushes one history entry for "a record is open" however many records are opened while it is, rather than one each, because Escape means close and not walk back through them one at a time. That second one is unreachable today, since the dialog is modal and the rail cannot be clicked while a record is showing, and it is in anyway: a rule written down is a rule, and a dialog that stops being modal one day should find the rule rather than the bug.
- **1.0.0.85** (2026-09-04): The Admin tab was printing container image digests whole. A digest is sha256 followed by sixty-four hexadecimal characters, and in a card three hundred pixels wide that wraps into three lines of noise and breaks after "sha", so the next line opens with "256:" and reads as a number rather than the tail of a name. Twelve characters is what a registry shows and what docker images shows, and it is enough to tell two builds apart, which is the only reason the digest is on that page. Shortened on the way to the screen, not on the way in, so the endpoint still returns what Azure said.
- **1.0.0.84** (2026-09-04): The inventory grid was asking the window how wide it was, and the window is the wrong thing to ask. Three columns arrived at 1024 pixels, which is the exact width the docked rail appears at, so the grid went to three columns at the moment it lost 272 pixels to the rail: cards about 215 wide, wrapping every title, every badge row and every city name, at a laptop and tablet width. It asks its own box now, through a container query, which also means a collapsed rail hands it two hundred pixels back and it uses them, something a media query cannot see. Two browser tests measure the card tops at 1024: two on the first row with the rail open, three with it collapsed. The threshold is 860 rather than 900 because a collapsed rail at that window leaves 912 pixels and a classic scrollbar takes fifteen of them, and a threshold a card's width away from the case it is meant to catch is one that catches it on some machines. Also the other two suite counts in the README, which said 43 Playwright and 48 Vitest against 52 and 57. The browser count is counted now, because every spec declares its tests the same way; the Vitest one is dated instead, because two of its rows are an it.each whose length is only known when the file runs, and a number nobody can check should say when it was true rather than pretend.
- **1.0.0.83** (2026-09-04): The preview card shipped with no version on it, and every check passed. It is regenerated at the start of a ship, from the changelog's top line, which is also where the deploy reads the version from; on that ship the changelog was momentarily empty when the generator read it, so it exited zero and drew a card with a blank where the version goes. Nothing noticed, because the record count on the card was right and the file was large enough to have rendered, and those were the only two things anybody had thought to assert. The card's version is held to the changelog's top line now, which is the same line the deploy trusts, and the card is redrawn. A generated number is worth nothing without a test, which is an argument this project had already made about a different number on the same image (ADR-053).
- **1.0.0.82** (2026-09-04): A vehicle page was printing "2.0 Rough" above "Vehicle shows average wear for its age and mileage. Mechanically sound." and "No damage reported.", which is three fields disagreeing about the same car on one screen. The seed dataset is careful about this: band 1 reads as salvage, band 2 as rough with damage, band 3 as average, band 4 and 5 as clean, and the damage note counts fall from about four to none across that range. The synthesiser that turns two hundred seeds into a hundred thousand records was drawing the condition grade from the hash across the whole scale while the report, the damage notes and the title status came from the seed untouched, so every correlation the data had was discarded for 99,800 of the 100,000. The grade varies inside its seed's band now, which keeps all of them and costs one line, and a theory holds five bands to it. And the README said 236 xUnit tests when there were 312, so that number is counted rather than typed from 1.0.0.81 and this version moves it to 318.
- **1.0.0.81** (2026-09-04): The em dash gate failed on itself, and the annotation added in 1.0.0.71 named it in one public line the first time it mattered. The scan went red on CI on a commit that changed a caption and a stylesheet, green locally and green on the four runs either side, which is the shape of a flake and was not one. The console logger CI asks for, so individual test names appear, prints each test with its parameters spelled out, and one of that class's own parameters is the em dash it forbids, because a rule that cannot fail is not a rule and the theory proving it can fail has to contain one. The job pipes that output through tee into a file in the checkout, so the transcript of the running suite held the character, sat in the repository the scan reads, and the scan read it; whether it failed depended on whether that line was flushed before the scan got there. Two things were wrong and only one was about em dashes. A build should not write into the source it is building, so the transcripts go to the runner's temp directory now, which fixes this and every future test that reads the repository, a growing list. And the scan skips those two names anyway, because the next person to add a tee will not remember why the first one moved. The local gate never saw it and never could: the ship script already writes its transcript outside the repository, so the gate that runs in two places was running against two different trees (ADR-052 addendum). The .NET annotation also carries the three lines under each marker now, because "Assert.Contains() Failure" says which assertion and the line below it says what was actually in the collection, and that second line is the one somebody needs. And the inventory says once, above the grid, that the photographs are stock chosen for the body style: fifty of them do the work of a hundred thousand, so two trucks in the same row can carry the same picture, which without a line saying so reads as a rendering fault.
- **1.0.0.80** (2026-09-04): 1.0.0.75 said the front page stays live-looking for as long as it is open. It was shipped, then measured, and that sentence was wrong. A browser left on the live site made five requests for the listing in seventy seconds, at 0, 15, 30, 46 and 61, on a tab it reported as visible, exactly as designed, and after seventy seconds the top four cards read "Ended Sep 4, 7:50 p.m." Both of those are true, which is the lesson: the mechanism did what it was built to do and the outcome it was built for did not follow, because the premise underneath it was never checked, that a fresh answer has a fresh first row. Over a hundred thousand auctions the soonest one ends inside a second, so the first row of every answer is expiring while it paints, and a shorter interval asks more often for a page with the same problem. What fixes it is the one thing the browser has and the response does not, which is the time now: under the ending-soonest sort the page already in hand is reordered on the browser's clock by the same ranking the server applied, live first and closest to ending, then upcoming, then ended. It is a reorder and not a filter, so nothing is added or dropped and the count and the paging stay the server's, and a page ranked by price or by bids is left exactly as it arrived. The refresh stays, because it is what brings new lots in as old ones leave and what the reorder runs on; neither is sufficient alone. The claim this time is the one that was measured: an auction that ends while the page is open moves out of the way within a second, without a request (ADR-056 correction).
- **1.0.0.79** (2026-09-04): Two things a reviewer would have drawn their own conclusion about. A screenshot of the detail page shows "2021 Tesla Model Y Performance" over a photograph of a Hyundai SUV, which is exactly what the design does on purpose: the catalogue is synthetic and the photographs are vendored stock chosen from the pool for the body style, which the README has said since the photos shipped. The README is not where somebody looking at that page is. A caption under the gallery says it now, because a reader who notices before being told it is deliberate has been handed a reason to doubt everything else on the page, and the fix is one sentence rather than fifty thousand photographs. And records got addresses one version ago with nothing on the page admitting it, which is a feature nobody has: the dialog carries a Copy link button beside Close, and when the browser refuses the clipboard, which happens on an insecure origin or a denied permission, the label says the link is in the address bar, which it is (ADR-057).
- **1.0.0.78** (2026-09-04): Fifty-seven decision records, and no way to send anybody one of them. The only route to a record was open the site, find the group, expand it, scroll, click, which is fine for somebody browsing and useless for every way a record actually gets read: cited in an interview, linked from another record, kept in a tab that gets reloaded, pasted into a message, which is how a portfolio travels. Every other view here already had an address, and the documents were the exception only because the dialog that shows them happened to be owned by the sidebar rather than by the page. They have one now, ?doc=adr-lockout, and the slug is read off the URL the API already serves the document at rather than written a second time, so a record cannot become linkable under a name the API does not answer to. An address that names nothing opens nothing and lands on the inventory, because a link that has gone stale should show a reader the thing it was attached to rather than a failure. Opening pushes a history entry the way opening a vehicle does, so Back closes a record; and since Escape, the X and the backdrop close it too, closing checks whether we pushed the entry that opened it, going back when we did so Back and Escape agree, and swapping the parameter out in place when we did not, which is what a visitor arriving on the link gets and is the difference between closing a dialog and leaving the site. The state moved up to the page, since the browser can now close a record without the dialog being touched, so the dialog follows the state instead of being it (ADR-057).
- **1.0.0.77** (2026-09-04): A third of the decision records index was arriving cut off. The rail is 270 pixels and the labels ellipsize, so the centre of this project read as "008 ADR: Linux over Wind...", "010 ADR: Observability (A...", "014 ADR: Live code sampl...", which is not a shorter row, it is a row a reader cannot tell from the one under it. Eight specs click those rows and every one of them passed the whole time, because each asks for a row by its full accessible name and the accessible name is complete: the ellipsis is painted, not stored. That gap has a shape, the model is right and the render is not, and no assertion about the model can reach it. So the labels wrap now, which costs a few pixels of height in a list that already scrolls because rows have a minimum height rather than a fixed one, and one test asks the browser instead of the DOM whether any span in the rail is wider than the box it was given. It fails against the rail as it was (ADR-056 addendum).
- **1.0.0.76** (2026-09-04): Four things a screenshot showed and nothing else would have. The Admin tab's timing summary read "Answers: 367 of 200, 133 of 404", which is two numbers with no relationship between them, on the page whose whole job is being readable by somebody who did not write it; it says "367 with status 200" now and a browser test holds the sentence. Recent errors was the fourth card in a three-track grid, so it sat alone on the second row with two thirds of the width empty, which reads as something failing to load rather than as a layout, and it takes the row now. The sign-in card is 560 pixels pinned to the left of a twelve-hundred-pixel canvas, which reads as a layout that ran out before it finished, and centred it reads as a sign-in page. And the sidebar was ellipsizing "Coding and commenting style" to "Coding and commenti...", which is a label shortened by the browser rather than by anybody who thought about it. None of these is a defect and all four of them are the first thing a reader sees, which is the argument for looking at the thing rather than at its tests (ADR-055).
- **1.0.0.75** (2026-09-04): Somebody took a screenshot of the front page and looked at it, which nothing in this project had ever done, and the first row was three cards reading "Live 7s left", "Live 7s left" and "Live 13s left". Fifteen seconds later the same vehicle at a phone width was a grey chip reading "Ended". Nothing was broken. The default sort is ending soonest, which is what an auction marketplace opens on and which over a hundred thousand lots always means seconds; the server ranks live ahead of ended, correctly; the browser recomputes each card's status as the clock ticks so a countdown reaching zero flips the chip without a refetch, on purpose. Together they mean the page is right at the instant it is answered and rots from the top for as long as anybody reads it, so a minute in, the first impression of a live auction site is a wall of dead lots that will not move. It is re-asked at the next moment its answer can change now, which is the soonest start or end still ahead of the vehicles on the page, floored at fifteen seconds so a page where something ends every few seconds asks four times a minute rather than constantly, skipped entirely while the tab is hidden and paid back when it returns, and asking nothing at all on a list whose auctions end next week, which the fixed timer it replaces could not manage. The timer that was there answered a different question, membership drifting under a status filter, and only ran when one was on (ADR-056). Also from the same look at the screenshots: the price filter on a phone had about sixty pixels an input, which clips the word "Max" inside its own box, and the search placeholder was one word longer than the field. And the record Steve asked for, on broken windows and the Boy Scout rule, with this week's seven findings as its evidence and the part usually left out included, which is that the rule taken literally produces unrelated changes inside a focused diff and the answer is that a window either gets fixed in place because it is small and on the subject, or becomes its own version. The half a machine can see is now three tests: no markers, no console call or debugger under src, and no focused or skipped test, with both runners refusing a focused test on CI and allowing one locally, since a committed test.only turns a suite into one test and reports it green (ADR-055).
- **1.0.0.74** (2026-09-03): Ask the narrow question instead of the broad one: what can somebody with no account cause this application to keep? Reads cost a query, a browser error report goes into a ring with fifty bounded slots, and registration writes a row to Azure SQL Database and keeps it. That is the whole list, and only the last one persists, which by the key on the bids table makes the number of accounts the bound on everything anybody can add to this database. It had no bound at all. The rows are the smaller half: Identity hashes a password on the way in on purpose, about 120 ms of CPU, on the one container that serves everything else, so a loop against this endpoint was the best attack this site exposed and it needed no account and no cleverness. The security page has said since it was written that a rate limiter here would not be the control that mattered, and every word of that argument is about partitioning: behind the edge the origin sees one address for everybody and the origin is directly reachable, so a per-address limit is a global cap being lied to. It says nothing about a limit that does not partition, which has nothing to forge. There is a sliding hour of 120 registrations now, counted across the whole site, taken after the request is read and before the password is hashed, sliding rather than resetting so nobody takes two allowances either side of an hour boundary, and a refusal takes no slot so that fifty people knocking cannot hold the window open forever. The refusal carries no digit in its words, because a reply that says how much is left is a counter anybody can poll. What it costs is in the record rather than hidden: while an attacker spends the hour, a real visitor cannot register either, and everything else keeps working (ADR-054).
- **1.0.0.73** (2026-09-03): Every record links at the code it decided about, and a test has held those links since 1.0.0.67. The code links back, by title, in a hundred and eleven comments, and nothing had ever checked one of them. Five were wrong: two named a record that does not exist, one cited a section heading as though it were a title, and two were near misses a reader would never catch, "Search index" for "The search index" and "Edge economics" for "Edge deploy economics". A wrong citation costs more than no citation, because it tells a reader there is a record to go and read, and the reader who goes and finds nothing concludes the documentation is decorative. Both directions are checked now, by title and by number, and a citation that names two records fails exactly like one that names none, since "The" begins twenty of these titles. One of the two missing records is written rather than renamed away, because it was owed: the public face shipped in 1.0.0.58 with no record and a test citing one by name for five versions, and ADR-053 now says why the structured data claims source code by a named author rather than the Organization that would unfurl better and be false, and why a generated number is worth nothing without a test. That last part earned itself: the count test was asking an easier question twice over. It read each file as written, so a claim the editor had wrapped across a line break sat invisible to it while it passed on the other one, and it read the README while How this was built carried the same count in a sentence of its own. It collapses whitespace first and reads every living document now, which means every served document that is not a record and not the changelog, since those two are dated by nature and quote counts that were true when they were written.
- **1.0.0.72** (2026-09-03): A rule this project has enforced for forty versions was being checked by a script on one laptop. Nothing written here contains an em dash, and the only thing holding the whole repository to that was a PowerShell loop in the shipping script: not on the runner, not runnable by anybody who clones this, skipped by any commit that does not go through it, while the single test that did enforce it read the changelog and nothing else. Every other gate in that script has a counterpart in CI, so this one was the exception without anybody having decided it should be, and the expensive part is that it looked enforced: every decision record, the README, the security page and every code comment the site displays as a live sample were covered by a sentence in a document and a loop one machine runs. It is a test now, so CI runs it, a clone runs it, and a violation names its file and its line instead of a path on somebody's C drive. It knows the character and the two HTML ways of writing it, which are plain ASCII and render as one em dash in served markdown, and it reads UTF-8 explicitly, because a reader that guesses the encoding splits one multi-byte character into two single-byte ones and then finds whatever it likes in the pieces, which is how the PowerShell version reported violations in files whose only crime was a multiplication sign. A second test asserts the scan reads something, since a scan pointed at the wrong directory passes in silence, which is the shape of defect the version before this one was also about (ADR-052).
- **1.0.0.71** (2026-09-03): The step that names a failing .NET test on the run page was half working, and the half that was not would have failed silently, which is the one weakness of building this out of pattern matches: a pattern that matches nothing leaves the step green, the annotation list empty and the run page saying "Process completed with exit code 1", which is exactly what it said before the work. dotnet writes its totals two different ways depending on which logger is asked for, either one "Passed! - Failed: 0, Passed: 281" line or a four-line "Test Run Failed. / Total tests:" block, and the pattern knew only the first while this job asks for the logger that prints the second. The browser suite had the same shape of gap from the other direction: it matched "Timeout of" and a test that runs out of time says "Test timeout of 90000ms exceeded.", which is the whole finding when the failure is a hang and no expectation was ever reached. Both are fixed, and the fix worth having is the one that holds them there: the patterns are read back out of ci.yml and run against real failing transcripts kept as fixtures, one from each suite, so a pattern that stops naming the failure goes red on a machine somebody is watching rather than on a run page nobody can read.
- **1.0.0.70** (2026-09-03): The .NET job went red on a commit that changed nothing but documentation, and there was no way to say which test without a GitHub sign-in, which is the third time a red job here has been unreadable. It names the failing test in annotations now, the same way the browser suite has since 1.0.0.54. And the benchmark that caused it is on its third design, because the first two were measuring the machine as much as the code: one timed each path five times in sequence, which compares two numbers taken at different moments on a shared machine, and the second alternated them but still took each path's own fastest, which lets one path's best come from a quiet moment and the other's from a busy one. It measures both paths inside each round now and compares them there, then takes the median of the five differences, so a round landing in a busy stretch has both its numbers inflated and the difference survives. Six runs came back between 17 and 56 ms in the index's favour, and a run with six processes deliberately burning the machine came back at 40 ms in its favour with every single round agreeing, where the old design had failed at 128 ms against it. The threshold has never been widened through any of this.
- **1.0.0.69** (2026-09-03): Reading the root directory, which no check had ever done, found two files the rename never touched because they were never about the name. WALKTHROUGH.md was the hiring challenge's own interview brief, sitting on a public repository explaining how a submission to somebody else's exercise would be evaluated. WORKING-NOTES.md was a hundred and eighty lines of my own notes from the first build day, addressed to myself, describing which parts of that challenge's identity had been scrubbed and how, and three days stale by its own numbers. The notes are kept and are not public any more; the brief is gone. And CLAUDE.md, the file an agent reads first to learn what it is working on, opened with "An industrial and farm equipment auction marketplace", a rename considered on day one and deliberately not done, left describing the version that never happened in the worst place in a repository for a sentence to be wrong. A test asserts that only the record explaining the history names the challenge, and that the two files saying what this project is agree about it. The coverage figures quoted in prose are dated now, because a number in a sentence goes stale silently and a dated one cannot.
- **1.0.0.68** (2026-09-03): How this was built now carries the objection it was missing. It already answered three a reviewer would raise about AI-written code, and the fourth is the strongest and was not there: an AI reviewing its own work is theatre. The answer is a list rather than an argument. The day's diff went to a reviewer with no memory of writing it, and two of its seven findings contradicted arguments made in the same commit, one of them a page explaining why a database parameter value must be structurally impossible to publish beside code putting the raw exception message on the same public page through another door. Then the shape of one finding was used as a search and it had two siblings, all three deliberate decisions defended in comments that were correct when written and left standing after accounts and a database arrived underneath them. What makes it evidence rather than theatre is what happened next: each fixed, each recorded with what it allowed rather than what mitigated it, each covered by a test that fails against the old behaviour, three of them fired at the live site to watch them fail there. The page also states the coverage rather than the test count, and the record count it had been quoting was nineteen records out of date.
- **1.0.0.67** (2026-09-03): Every record ends with links at the code it decided about, which is the main way a reader gets from a decision to the thing it decided, and nothing checked them. Three tests now do, and they found two: ADR-033 pointed at a migrations folder that stopped existing when the two-provider model moved the history into a project of its own, dead from that day until something looked, and one directory was linked with GitHub's file form, which works by redirect and stops working the moment somebody copies it somewhere that does not follow one. The link test insists on the right form for each, because a wrong link that redirects is a wrong link that will be right until it is not. The other two hold the records and the catalogue to each other in both directions, since a record nobody can open from the site only exists for whoever clones the repository, and a catalogue entry with no file behind it is a 500 waiting for a click, and assert the numbering runs without a gap, since a gap means a decision was made and then deleted, which is the one thing an index like this exists to keep.
- **1.0.0.66** (2026-09-03): A security page, which GitHub also picks up from docs/, saying what is protected and by what, what deliberately is not and why, and what went wrong. The third section is the useful one: a threat model with no findings in it has usually not been applied, and this one lists seven from a single afternoon with what each allowed and which record covers it. The pattern in the first three is the reason the page exists, because each was a deliberate decision defended in a comment, correct when written, and left standing after the assumption underneath it changed: accounts arrived and a database arrived and the sentences did not move, which is harder to catch than an absent thought because the file reads as though the question is settled. The habit it leaves is that when a system gains users or persistence, the comments saying "this is only a demo" are a work list.
- **1.0.0.65** (2026-09-03): This repository has been saying how many tests it has and nothing about what they touch, which is compatible with testing one class thoroughly and everything else not at all. coverlet has been a dependency of the test project since the project existed and nothing ever ran it, so the number cost one flag: 89.6 per cent of lines and 71.7 per cent of branches. The shape matters more than the total and it is the shape the architecture predicts, with the entities at 100, the domain at 98.8, the use cases and the adapters in the low nineties, and the host lowest at 78.2 because two of its classes talk to Azure with a managed identity and CI has no Azure credential and is never getting one; what is worth asserting about those two is that they degrade rather than throw without it, and that is tested. The floor is a ratchet rather than a target, set just under where the suites are, low enough that nobody is tempted to write a test which executes a line without asserting on it. Published as an annotation rather than only a job summary, because a summary renders for somebody signed in and this project has now paid twice for the lesson that a check nobody can read is not a check (ADR-051).
- **1.0.0.64** (2026-09-03): The same defect the review caught in one buffer was sitting in the one next to it. The middleware that catches every unhandled exception was recording its message into the ring served at /api/errors, unauthenticated, which is where a framework writes a filesystem path or the value that broke a constraint, and the ProblemDetails handler two regions away has refused to put an exception message in a response since the day it was written. It records the type now. Worth being precise about why it was missed: the review was scoped to a diff, /api/errors was older than the diff, and a review scoped to a change sees a change rather than a system, which is the wrong scope for a question of the form "can this class of thing reach that class of reader". And browser error reports have their own fifty slots rather than sharing the server's: the endpoint is anonymous on purpose so a crash in the page reaches the same place a crash in the server does, its message and stack were bounded but the number of reports was not, so fifty posts from anybody erased every real server error from the page an operator would open during an outage. The Admin tab still shows one list (ADR-045 addendum).
- **1.0.0.63** (2026-09-03): Login had a lockout policy on paper and none in practice. UserManager.CheckPasswordAsync verifies a password and touches nothing else, so AccessFailedCount was never incremented, no lockout ever engaged, and with no rate limiter in front of it the endpoint was an unmetered password oracle against real accounts: one request per guess, no delay, no ceiling. The AspNetUsers table has carried LockoutEnd, LockoutEnabled and AccessFailedCount since the schema was written, correctly typed and faithfully migrated and never once read. That is a more comfortable failure than a missing control, because everything about the system looks like it is there. Five wrong passwords now buy five minutes off, the lockout is checked before the password so a locked account stops answering guesses rather than merely stops confirming them, a success clears the count so a slow week of typos cannot lock somebody out of their own account, and the refusal says exactly what a wrong password says, because a distinct "this account is locked" is a reply confirming the address is registered here (ADR-050). And the search benchmark that failed at 243 ms against 115 ms was measuring unfairly rather than measuring a regression: it timed one path five times and then the other five times, which compares two numbers taken at different moments on a shared machine, and it passed six times of six alone five minutes later unchanged. The two paths take turns now. The threshold was not touched, because a measurement that is unfair is not fixed by widening what it allows.
- **1.0.0.62** (2026-09-03): An audit for other endpoints shaped like the reset found one worse. The simulated room's tick took no account at all and advanced state derived from everybody's bids, so a stranger with curl and a loop could counter-bid every auction any signed-in visitor was winning, move the prices shown on the public listing, and leave nothing behind that said who. The comment above it argued correctly that the room should answer a price rather than a person, and said nothing about who may advance it, because when it was written there was one visitor. What the room bids against is unchanged; moving it now costs a sign-in, the same as bidding, and the page stops asking when signed out rather than polling for a 401 forever, which means a signed-out visitor sees a still grid and that is the honest state (ADR-049). The same audit found the fix from one version earlier incomplete: it cleared the room's answers on every vehicle the caller had touched, and "vehicles this person bid on" is not "vehicles only this person bid on", so a reset still took away a stranger's outbid badge and dropped the price they were bidding against. The caller now clears the room only where nobody is bidding any more. Verified against the live site with two real accounts before the narrowing: one resets, the other keeps its bid, and the car still stands at their number.
- **1.0.0.61** (2026-09-03): The reset button deleted everybody's bids. The endpoint behind it took no user at all and the store's clear was a delete of the whole table, so any signed-in visitor could destroy every other visitor's rows, durably, on a site whose own changelog has said for twelve versions that two visitors can outbid each other and both be told the truth. The behaviour was deliberate and carried a comment defending it, written when a bid belonged to a browser and "everybody" meant "you", and the reason expired without the sentence changing, which is harder to catch than an absent thought because the file reads as though the question is settled. The reset belongs to the caller now, and the original reasoning survives narrowed to the vehicles they actually touched: their bids go, the room's answers on those same vehicles go with them, and each of those vehicles has its standing recomputed from whoever is left rather than deleted, so a stranger bidding on the same car keeps their bid and the lead they earned (ADR-048). Fixing it broke a test, which is the interesting part: smoke.spec reads the minimum next bid off a placeholder and posts it once with no retry, and it had been passing because market.spec's reset was clearing the simulated room globally, so there was nothing bidding against it. Scoping the reset left the room's other bids standing and the race that was always in that test started happening. A test that passes because another test keeps clearing the world is not a passing test, and it looks exactly like one until somebody fixes the thing it was leaning on. The bidding helper moved to its own module and both specs use it. And ADR-042 carries a correction: three ship attempts came back two green of three and that was attributed to the machine on real measurements, the suite having gone from 2.0 minutes to 3.4 while the .NET suite was unchanged. All true, and not the cause. Twelve consecutive green runs since the load wait started waiting for something that is there rather than something that is gone say the defect was the helper. A measurement that is real and an explanation that is true are different things.
- **1.0.0.60** (2026-09-03): The crawler files added one version earlier answered 404 on the live domain while the page that points at them carried every tag pointing there. The edge was ruled out in one line, because its rule is a catch-all proxy, which left the origin, which serves what the image contains, which is built from an explicit list of COPY lines in the Dockerfile that does not mention the public folder, because the folder did not exist when the list was written. The Dockerfile is a second manifest of what the frontend consists of: written in another file, maintained by hand, consulted by nothing until a deploy, and only ever evaluated in the one place the tests do not run, which is why local checks were green the whole time. A test now reads that stage of the Dockerfile and asserts every build input which exists in the repository is copied into it, and fails against the Dockerfile as it was (ADR-047).
- **1.0.0.59** (2026-09-03): The projects are named TheYard now. They were TheBlock, which is the name this application had when it was a submission to somebody else's hiring challenge, so for weeks the live site, the domain and the repository all said one thing and every project inside said another, and a reader who opened the solution found a different application than the front door advertised. Renamed with the history intact: the directories moved with git mv before a single byte of content changed, so all 208 files are recorded as renames and log --follow still works, and the content pass read each file as bytes and preserved its byte-order mark, so the diff contains only lines that actually mention the name. Four of the 921 references are strings rather than paths and would have failed silently at runtime instead of loudly at compile time: the migrations assembly Entity Framework is told by name, the DACPAC filename CI asserts, the source paths the live code samples read, and the container's entry point. The sweep also turned up an entire project directory, scaffolded during the SQL Server work and abandoned, in no solution and tracked by nothing, which no check in this repository could have found because nothing ever built it (ADR-046).
- **1.0.0.58** (2026-09-03): The page said nothing about itself to anything that was not a person. No description, no Open Graph, no structured data: a crawler, a chat client unfurling the link, a search engine and a recruiter's parser all read the head and nothing else, and the head held a title and a font. It carries a description sized to where it gets shown, an absolute preview image because a relative one is silently dropped, a canonical link, and structured data declaring what this actually is, which is source code by a named author rather than the Organization or Product that would look better and be false. There is a robots file that keeps crawlers off the endpoint which throws on purpose, and a sitemap, both of which work only because every view here is a GET URL. The preview card is drawn from the application's own palette with its numbers read from the repository, so it cannot claim a count the project no longer has, which the README had been doing: it said twenty-nine decision records and there were forty-five, sixteen records after that stopped being true, and a test now holds any number word in front of "decision records" to the real count. And ADR-001 ends by accepting a publicly reachable origin because it was "carrying no secrets and no persistent user data", which stopped being true when accounts arrived and the store moved to Azure SQL Database; the addendum says so, sets out what actually stands between the internet and that data today, and records that the origin lock is still owed rather than pretending an unfunded control is in place.
- **1.0.0.57** (2026-09-03): Fixing the timing section's status handling removed the only place a status was shown, which left the fix unverifiable from outside; the section reports answers by status now, an aggregate that names nobody, and a test hits the endpoint that throws on purpose and asserts it is counted as a 500, which is the assertion that pins the middleware above the exception handler where it belongs. The exclusion list is written out one endpoint at a time rather than matched on a prefix, because the deliberate-failure probe lives under the same prefix as the readers and is exactly the request the timing section should be showing.
- **1.0.0.56** (2026-09-03): The day's whole diff went to a reviewer that had not written any of it, and it found seven things. The one that mattered: the SQL section argues at length that a parameter value must be structurally impossible to publish, and the log section shipped in the same commit put the raw database exception message on the same public page, which is where a driver writes the server hostname, the login name and the caller's IP address. The health check two screens away refuses to do exactly that and says so in a comment written a week earlier. The exception travels in the exception slot now rather than inside a message template, so what reaches the console and what reaches a public page are different things on purpose, and the log ring is an allow-list of this application's own categories because a healthy container's framework lines announce its content root and its key directory. Second: the timing middleware sat below the exception handler and read the status before it was written, so every failed request was recorded as a 200, including the endpoint that exists to prove the failure path works. Also the connect timeout raised last version multiplied by a retry count nobody re-read, eight minutes against a five minute deploy; the metrics endpoint returned five hundred entries of what every other visitor was doing; the load helper asked for forty-five seconds inside a thirty second test and waited on an absence that was already true; the Admin tab filled its own buffers by being looked at; and a test passed only because of the order xUnit happened to pick. ADR-045 records all of it, including what the review looked for and did not find. And CI stopped being carried on borrowed compatibility: four actions were targeting Node 20 and being forced onto Node 24, and the runtime each major actually declares was read rather than guessed, which is how upload-artifact turned out to still be on Node 20 at v5.
- **1.0.0.55** (2026-09-03): The annotations added one version earlier paid for themselves on their first red run: CI had failed twice saying nothing but "exit code 1", and the third time it named the test, axe on the Admin tab, with three violations. Three is the number of scrollable table containers the SQL section added, and a box with overflow-x and nothing focusable inside is a region a mouse can scroll and a keyboard cannot, which is WCAG 2.1.1. It fires only when the box actually overflows, which is why a wide development window passed it and the runner's viewport did not, and why it was invisible to a local suite run eleven times. The three regions are focusable and labelled now.
- **1.0.0.54** (2026-09-03): A red browser suite on CI now names the tests it failed on, in annotations rather than a job summary, because the summary added one version earlier turned out to render only for somebody signed in to the repository while annotations come back from the public API and sit at the top of the run page. Two red builds in a row said nothing publicly except "Process completed with exit code 1" while their full evidence sat behind a sign-in, which is a poor place to keep the one thing a reader needs.
- **1.0.0.53** (2026-09-03): The deploy that failed while the site it was checking was serving perfectly well. Readiness had been answering "ready" only when every health check passed, and the database check joined that set when the relational store did, so a container running on the file-backed fallback reported itself unfit for traffic and `curl -fsS /readyz` failed the roll: the exact outcome ADR-033 exists to prevent, since the whole point of the fallback is that the site comes up when the database does not. Readiness and health are different questions now, and the database check is the one that answers the second without withholding the container from the first, with a test that names both halves. And CI can say what broke without a login: a red browser suite writes its own output onto the run page, because "Process completed with exit code 1" was the only public word on a failure whose full evidence sits behind a GitHub sign-in. And the cold-start fix from 1.0.0.51 turned out to be too narrow: it warmed the app before the first test, and the same failure came back in the middle of a run in a different spec, a focus test failing because no vehicle tile existed yet. Every spec here opens with a navigation and then asserts against a loaded app, so every one of those first assertions was carrying an unstated five-second load budget; the wait now lives with the navigation, once, and every navigation goes through it (ADR-042 addendum).
- **1.0.0.52** (2026-09-03): The Admin tab shows what the database is actually doing: every SQL statement Entity Framework sent, newest first, with the request that caused it, how long the database took, and each parameter listed by name, type and size. Not by value, and not by a redaction rule either, because a rule that lists what to hide is correct only for the columns that existed when somebody wrote it and this page is public: the type the table is built from has no field for a value, so a column added next year cannot leak through it, which a test proves by registering an account and asserting the address appears nowhere in the response while the statements do. Beside it the application's own log, and timing computed on read from the last five hundred requests, p50 and p95 per endpoint, exact for the window rather than approximate forever (ADR-043, and ADR-044 walks interceptors, why parsing the log line would have been worse, and the eleven lines a percentile actually takes). And the first roll on Azure SQL Database told us the last thing that was missing: the container reached the server, shook hands in 432 ms and authenticated in 4, then ran out of time in the post-login phase at 29.3 seconds against SqlClient's default 30, which is a paused serverless database waking up, so the connect timeout is ninety seconds now, set in code where the reason for the number can sit next to it.
- **1.0.0.51** (2026-09-03): The browser suite found a serious accessibility failure the moment it could report one: an auction that has ended paints its countdown in the palette's faint colour on the page ground at 3.82 against a required 4.5, and the palette test passed the whole time because it contained an exemption letting faint labels clear only 3:1 there on the reasoning that they live on white, which the stylesheet had never agreed with; the colour is deepened, the exemption is gone, and ADR-042 walks that and the four other checks that were asking an easier question than the one they were written for, among them a .NET test that asserted a diagram's title verbatim and had only ever passed because no title until now contained an apostrophe for the encoder to touch, and a keyboard test whose first line was also asserting, without saying so, that a cold start finishes inside five seconds, which on one run in three with four workers arriving together it does not. The database has a picture now: an entity relationship diagram drawn from a table of facts rather than described in a code fence, showing all four tables this application owns with every column and the reason for its type, Identity's seven, and the two relationships the schema deliberately does not enforce, opening on its own zoomable page like every other diagram here; the infrastructure drawing has the database on it and the file-backed fallback beside it, having previously shown neither; and the documentation caught up with the code: the README described the store as SQLite and still listed durable storage across a container roll as something it would do with more time when that is exactly what shipped, and the two records that describe the store were still describing SQLite in the present tense and one of them was handing out a command that no longer works, so ADR-033 now says at the top that it is the decision to have a relational store and not a description of today's one, and ADR-034's schema-change steps name the SQL project and the migrations project that actually exist; and CI went red on the browser suite and could not say why, because the step that uploads a Playwright report has been finding nothing for as long as it has existed: without an html reporter that directory is never written, so every failing run on a machine nobody can log into left no evidence at all; the reporter is configured now, and the bid helper that made the suite deterministic on a fast machine waits for the server's answer rather than for six seconds of it, because a slow accept on a two-core runner was being read as a refusal and three of those threw.
- **1.0.0.50** (2026-09-03): 1.0.0.49 built the SQL Server backend and then shipped on SQLite, because the deploy asked Azure for the database server's address and the deploy's own identity is not allowed to read it, so the placeholder survived and the container correctly read a placeholder as no database; the address is composed from the name now, which is what it always was, and the deploy says out loud which store the container came up on rather than leaving it to whoever reads the health endpoint by hand (ADR-039 addendum).
- **1.0.0.49** (2026-09-03): The relational store is Azure SQL Database now, reached with no password at all: the server was created Entra-only so it has no SQL login to have one, and the container authenticates as the managed identity it already carried, which means the connection string in its environment is a server name, a database name and an authentication mode and nothing worth stealing; the schema itself moved out of C# into a SQL project that compiles to a DACPAC and is now the authority, with Entity Framework held to it by a conformance test and the running application stripped of the right to alter a table at all; and the schema is the current model done properly, with a length and a reason on every column, a decimal grade, a datetime2 auction start, a rowversion on bids, a real foreign key to the account and two relationships deliberately left unenforced, the first publish of which told us something no amount of C# would have: Identity's default 450-character keys put four primary keys over SQL Server's 900-byte clustered index limit (ADR-039, ADR-040, and ADR-041 walks it for a developer meeting either for the first time).
- **1.0.0.48** (2026-09-03): Bids belong to people now: accounts through ASP.NET Core Identity, a session that is a signed token in a cookie the page cannot read, and a bid keyed on the person as well as the vehicle, so two visitors on the live site can outbid each other and both be told the truth about it, with an account view that lists what you have bid on and whether you are still winning (ADR-037, and ADR-038 walks the setup for a developer meeting Identity and JWTs for the first time); and two flakes that predate this work went with it, one where the API tests bid on the auction closest to closing and lost it between reading the minimum and posting the bid about one run in three, the other where the search benchmark asserted an exact inequality under a doc comment claiming to be loose and failed at 95 ms against 73 ms with five suites running at once.
- **1.0.0.47** (2026-09-03): Photos are sized for the box they land in: the originals are 1280 wide and the card paints them at about 358, so a first load was pulling 2.3 MB to fill nine boxes and a phone was pulling exactly the same bytes as a desktop, and there is now a 480-wide copy of all fifty beside them, 91 per cent smaller each, chosen by the browser through srcset, with a test holding the photo manifest and the image directory to the naming the browser relies on (ADR-036).
- **1.0.0.46** (2026-09-03): The cheap half of what the review deferred, none of it a live defect and all of it the kind of thing that becomes one: the style job now actually runs before the other three, which its own comment had been claiming without a `needs` line to make it true; the test that holds a crash and a rejected query to one shape would have passed on two empty bodies and now asserts it compared something; the restart test matched a bid amount as a substring of a whole JSON document, where a thirteen-digit timestamp contains almost any five-digit number, and now parses the field; and the exception handler noticed that its writer can decline, which happens when a caller accepts only text, in which case the request is reset rather than answered and the log now says so (ADR-030).
- **1.0.0.45** (2026-09-03): The corrections from a staff review of the night's own diff, of which one was serious and visible: a collapsed sidebar hid thirty-five documents behind a control a mouse could not see, because a disclosure whose summary is screen-reader-only has no visible way to open it; the public health endpoint stopped repeating a storage failure's exception text, which is typically a filesystem path; bids are written to the store before memory so a failed write cannot leave a bid the caller was told had failed; an abandoned request answers 499 at Information instead of 200 at Debug, which is the difference between seeing an outage and not; and the accessibility scan now waits for the grid it is checking and opens the records index it was skipping (ADR-030, ADR-033, ADR-035).
- **1.0.0.44** (2026-09-03): axe now holds six views to WCAG 2.1 AA inside the browser suite, and its first run found two serious contrast failures on the two most visible elements on the page, the reserve chip at 4.39 and the live countdown at 4.04, in a repository whose own palette test was passing because it holds the pairs somebody listed while a stylesheet composes whatever it likes; both colours were deepened rather than the threshold lowered, and the palette test gained the two pairs it was missing (ADR-035).
- **1.0.0.43** (2026-09-03): The catalogue and the bids moved into SQLite through EF Core, with the schema applied by migration at startup and the tables seeded on first boot from the JSON files that used to be the catalogue, and not one line changed above the Infrastructure layer because both sources already sat behind ports; a bid now survives the process restarting, which a test proves by starting a second application against the same file, at a cost of about 1.4 seconds on a cold container and nothing at all on the path a request takes (ADR-033, and ADR-034 walks the setup for a developer meeting EF Core for the first time).
- **1.0.0.42** (2026-09-03): How this was built now sits in the About menu beside the README: it says outright that an AI agent wrote most of this application, names the criteria a reviewer should judge that by, points each one at a place in the repository, and gives most of its length to the times the work was wrong, including the three objections a reader would raise and what the counter-evidence actually is (ADR-032).
- **1.0.0.41** (2026-09-03): The version comes from this file's top line now rather than from the deploy's run counter, after a red build consumed run number 28 and left the footer saying 1.0.0.40 while the line written with it said 1.0.0.39, so a ship that forgets its changelog line fails instead of shipping a number nothing describes (ADR-031); and the failure nobody wrote code for finally answers properly, with a handler that keeps the message and the stack inside, returns the same problem shape as a rejected query, and an endpoint that throws on purpose so that path can be exercised in production instead of assumed (ADR-030).
- **1.0.0.40** (2026-09-03): Style stopped being a preference: four checks now fail the build (dotnet format, Prettier, oxlint, and the typecheck that was already there), each proven to fail on bad input, and the linter's first run found a derive-do-not-store violation in the component that serves the style document (ADR-028); the twenty-nine records moved out of four topic sections into one numbered index that opens on demand (ADR-029); the first CI run of the new style job then failed on the command that had just passed locally, which turned out to be the repository claiming CRLF line endings while storing LF, true on Windows and false on the Linux runner, now fixed in .gitattributes and enforced by both formatters (ADR-028).
- **1.0.0.38** (2026-09-03): Two screenshots of the room answering a bid on the live site, and the defect the first of them caught: for the moment between a competing bid and the browser refetching, the panel offered a minimum equal to the standing bid, which is a number the server would have refused (ADR-027).
- **1.0.0.37** (2026-09-03): The auction has other bidders now: a simulated room answers the buyer's bids through the same BidRules the buyer's bids go through, waits before answering, stops at twice the opening ask and never takes a vehicle at buy-now, so the high-bidder badge can come off and the minimum next bid climbs the way an auction's does, shipped after a self review that found and fixed eleven defects in it, four of them serious enough to be worth reading about in the record (ADR-027).
- **1.0.0.36** (2026-09-03): The keyboard path is walkable end to end: a skip link past the thirty-button rail, focus that moves to the view that changed instead of falling to the document body, and a live region that names where you arrived, all four held by Playwright (ADR-026).
- **1.0.0.35** (2026-09-03): Free-text search stopped rebuilding each vehicle's searchable text inside the scan, which halves the work across the hundred thousand rows and is measured by a test that ships with it (ADR-025), the telemetry query that shipped broken in 1.0.0.34 now parses and the Admin card counts browser errors beside the server's (ADR-024), and the em dashes are gone from the code comments the records display.
- **1.0.0.34** (2026-09-03): Application Insights is wired: every request, dependency and exception the API handles goes to it, browser errors ride the endpoint that already existed, and the Admin tab reads the last hour back with the container's own identity, with the ingestion key read from Azure at roll time and never stored in the repository (ADR-024).
- **1.0.0.33** (2026-09-03): The changelog was corrected after two commits shipped in one deploy run: they became one version, not two, and this line records the fix (ADR-012).
- **1.0.0.32** (2026-09-02): Every served document was audited against the code in six classes and the twelve claims that had drifted were corrected, the largest being a record still describing the old 400 body, and the nine teaching comments a staging bug had dropped were put back (ADR-017 addendum).
- **1.0.0.31** (2026-09-02): Every code sample a record shows now carries a teaching comment explaining why it is written that way, so a reader meeting the pattern for the first time learns from it (ADR-006 addendum).
- **1.0.0.30** (2026-09-02): The README was rewritten to what is live now, with all four "with more time" promises closed and what remains listed honestly, and the last two documents carrying em dashes from before the voice rule were rewritten.
- **1.0.0.29** (2026-09-02): Every failure now answers one shape, RFC 9457 ProblemDetails with the message in detail and a trace identifier, every request is logged as structured JSON, and a React error boundary turns a render crash into a page with a way out and reports it to the Admin tab (ADR-023).
- **1.0.0.28** (2026-09-02): The sidebar gained an App Architecture section holding the new architecture and style pages, the data flow, the project structure and the three records that walk the code (ADR-022).
- **1.0.0.27** (2026-09-02): The third record for a new developer, the tests explained, with teaching comments in the samples it shows, and the resume dated 2026-09-02 served from About (ADR-021).
- **1.0.0.26** (2026-09-02): ADR: Diagram pages gained its screenshots from the live site, the caption on a phone, the page as it opens and zoomed in, and the laptop view (ADR-020).
- **1.0.0.25** (2026-09-02): Every diagram opens on its own page in a new tab, zoomable with the text selectable, from a preview in the record; the data flow was drawn in the same style as the infrastructure diagram; links inside a document open in a new tab (ADR-020).
- **1.0.0.24** (2026-09-02): Two records written for a new developer walk Program.cs and the React configuration top to bottom with the why beside every choice and the code read from the build, and a live sample can now show a whole file (ADR-018, ADR-019).
- **1.0.0.23** (2026-09-02): The Hosting page and the README gained an infrastructure diagram, the records gained screenshots from the live site and more live code, and the documenting rule was written down (ADR-006 addendum).
- **1.0.0.22** (2026-09-02): A staff-level review of the day's work landed its corrections (one documents endpoint over a catalog, honest failure states on the Admin tab, the phone header's way home from Admin) and every decision record gained a map of the files it decided (ADR-017).
- **1.0.0.21** (2026-09-02): The whole site repainted to Figma's Urban slate, gray, brown and blue, with every text and ground pair measured against WCAG AA (ADR-016).
- **1.0.0.20** (2026-09-02): Cache headers arrived: hashed bundle files cache for a year and everything else says no-cache, so a new version shows on the next load on any device (ADR-015).
- **1.0.0.19** (2026-09-02): The sidebar turned light and modern, a white rail and drawer with the brand blue as the only accent (ADR-013 addendum).
- **1.0.0.18** (2026-09-02): The CI/CD page gained its Deploy screenshots, the six green runs and one run's steps, captured from the public Actions pages.
- **1.0.0.17** (2026-09-02): The Admin tab's health checks report how long each one took and Azure's card lists the container's last three events (ADR-010, second pass).
- **1.0.0.16** (2026-09-02): Decision records began showing live code samples read from the running build's own source, with that source shipped inside the image (ADR-014).
- **1.0.0.15** (2026-09-02): The five header dropdowns gave way to one sidebar at every width, a docked rail on laptops and the drawer on phones (ADR-013).
- **1.0.0.14** (2026-09-02): A Changelog menu joined the header, and the phone menu became a dark slide-out panel with an icon on every row.
- **1.0.0.13** (2026-09-02): The phone header shipped as the first real passenger through the new pipeline, alongside the pipeline's own record (ADR-011).
- **1.0.0.12** (2026-09-02): The first automated deploy: the CD pipeline shipped itself and rolled this version with no hands (ADR-009).
- **1.0.0.11** (2026-09-01): The Admin tab was roughed in with health checks, the error buffer, and Azure's own view of the container (ADR-010).
- **1.0.0.10** (2026-09-01): The Netlify credit fix landed with two lesson records, edge deploy economics and Linux over Windows.
- **1.0.0.9** (2026-09-01): The version footer arrived and the page started reporting its own build (ADR-005, ADR-006).
- **1.0.0.8** (2026-09-01): The About menu began serving the current resume.
- **1.0.0.7** (2026-09-01): The README was reframed on the project's own terms and its typography restored after the encoding damage.
- **1.0.0.6** (2026-09-01): The production design was documented as deliberately undeployed, and the bare domain got its edge rules.
- **1.0.0.5** (2026-09-01): The Hosting overview's child index gave way to the websites-and-resources list after a proofread.
- **1.0.0.4** (2026-09-01): Configuration screenshots were embedded in the docs, the CI/CD menu was seeded, and the Bicep file started serving from the dropdown.
- **1.0.0.3** (2026-09-01): Hosting became the parent record, with the ADRs nested under it in a new Hosting menu.
- **1.0.0.2** (2026-09-01): The domain docs shipped and the ADRs went live in the About menu behind https://theyard.stevenstout.biz.
- **1.0.0.1** (2026-08-31): The first live deploy, Azure Container Instances over plain HTTP on port 8080, the day the site got a URL.
