Updates
What changed recently
Short progress summaries across all my projects, newest first. The detail lives in each project's articles.
Updates are bullet-point summaries generated with AI from my commits and build notes, then checked by me. Project articles and learning notes are written by me.
- Active
- Threw the first version away. The single-model scaffold became
legacy/, and the rebuild starts from a working site with a two-tier content model: long buyer’s guides written by two frontier CLIs that review each other, and short nightly articles drafted by a local model and reviewed by both. Subscription auth throughout rather than per-token billing. - The GitHub repo I was about to push to already held the old site’s history, with no shared commit to merge against. Renamed it to
garagedreams-legacyrather than force-pushing over it. The local.githad been lost once already and that is not a thing to do twice. - The logo was in the DOM and invisible. The SVG carries live
<text>in a font the browser never loads, because an SVG in an<img>renders in an isolated context with no access to the page’s fonts. Inlined it and loaded the face; the real fix is re-exporting with the text outlined. - Inlining both logos then mixed their colours: white letters in the orange wordmark, an orange R in the white one. SVG
<style>blocks are not scoped, and both files had been exported with the same generic.cls-1,.cls-2class names. Namespaced each at inline time.
- Threw the first version away. The single-model scaffold became
- Active
- The register diagnostic now prints each
i2cReadreturn code next to the value. On the bit-banged bus, a zero-initialised buffer made00indistinguishable from a failed read. - Tracked a dead left motor to uninitialised TIM8 config structs. Channels 1 to 3 read the unset complementary-output fields and channel 4 does not, so only the right motor (channels 3 and 4) ran. Value-initialising the structs fixed it.
- Swapping the motor connectors could not separate hardware from firmware. Flashing Yahboom’s vendor image onto the same board did: both wheels drove.
- See Establish a known-good hardware baseline.
- The register diagnostic now prints each
- Active
- First run of the SQL loader: four transcription errors that each failed loudly, and one that didn’t. The incident insert sat inside a loop that skips crash sheets, so
is_crashwas false for every row while the load reported success. Split the loader into two passes.
- First run of the SQL loader: four transcription errors that each failed loudly, and one that didn’t. The incident insert sat inside a loop that skips crash sheets, so
- Active
- Ported the MPU6050 DMP driver unchanged, but its FIFO stayed empty. The original called
IIC_MPU6050_Init()from board code outside the driver, and without it SCL sat in its reset state. - Got
printftelemetry working after fixing three silent gaps: thenosys.specs_writestub, newlib fully buffering stdout, and the ST-Link V2 having no UART. Telemetry comes out of the robot’s USB-C port through its CH340. - Traced an angle of
-2147483648in every sample to uninitialised floats in the IMU class. That value is what ARM produces when casting NaN toint. The constructor now zeroes the angles and sets the quaternion to identity. - Covered in more depth in Bring up UART, I2C and the MPU6050.
- Ported the MPU6050 DMP driver unchanged, but its FIFO stayed empty. The original called
- Active
- Changed the per-corner average to divide by every race year, not only the years a corner had action. A quiet year is a result, not missing data. Singapore corner 5 went from 3.0 to 2.0.
avg_lapstill averages only the years present, because a quiet year has no lap. The two rules are separate named functions with docstrings.- See A quiet year is zero.
- Active
- Wrote the remaining-implementation plan for a less capable model to execute: complete code for every file, exact commands, nothing inferred. It ran steps 1 to 3 and the code matched the plan, but it left the generation script uncommitted, so the work existed only on disk.
- The generation script hardcoded Ollama’s port. Swapped both the URL and the model name to environment variables, because the development machine runs llama.cpp on 8899 and the Pi will run something else.
localhostin that variable resolves to the dev container, not the host serving the model.host.docker.internalis the fix, and it is the kind of thing that reads as “the model is down”..devcontainer/devcontainer.jsonwas listed as created in the previous session’s notes and did not exist. Described, never written. The first instance of a note recording an intention as a fact.
- Active
- First conversion run over the 101 guides: 84 converted, 16 skipped, 1 error. The skips are folders holding more than one
.docxand therefore colliding on slug, and the first file wins. The error isaccord-euro-r.docx, whose zip structure is broken and which no reader can recover; that guide is simply absent. - Image extraction produced nothing, and it took a re-run to work out why: the photos sit beside the
.docxin each folder rather than embedded inside it, so the converter’s image handler had nothing to find. - Decided the guides carry their real press photos while generated articles get a placeholder. The text is original either way; the split is honest about which pages had a human behind them.
astro devwithout--hostbinds only to127.0.0.1inside the dev container, which the editor’s port forwarding cannot reliably reach. Minutes lost to a page that looked like it was building slowly.
- First conversion run over the 101 guides: 84 converted, 16 skipped, 1 error. The skips are folders holding more than one
- Active
- Surveyed the source material: 101
.docxbuyer’s guides, each in its own folder with photos beside it. Section headings are bold paragraphs rather than Word heading styles, and the spec data is in real Word table elements, so it should survive conversion as markdown tables. - Decided the generator writes from one section rather than a whole guide: roughly 1,500 distinct chunks across the corpus, picked one a night. The guides themselves get published too, so the source is also the archive.
- The brief’s cron line was
node scripts/generate-article.js, which cannot run a TypeScript file. Corrected totsxbefore it reached a Pi.
- Surveyed the source material: 101