Pipit is leaving the nest
Four months of extraction meant untangling assumptions about the host. Moving directories was only one part of making Pipit independent.
Things I’ve made and questions I’m working through. Some articles look back at things I’ve finished, but most follow whatever I’m working on at the time. Most of the older ones came over from my old blog and were tidied up along the way. I used AI to tidy them up, fixing the grammar and the structure so they’re easier to read and follow. My dyslexia made my older articles ramble quite a bit, and I think they’re much more presentable and digestible now.
Four months of extraction meant untangling assumptions about the host. Moving directories was only one part of making Pipit independent.
My arena fix passed its tests, then an AI-written Coq model found four more failures. Linters, papers and checked traces give me something to work against.
Coming from Go and C, I'm reluctant to add another construct. My compiler's homemade alternatives make me reconsider what keeping the language lean actually saves.
I used to put most of my effort into integration and regression tests. AI is helping me write the smaller checks I kept putting off.
A deliberately broken application and lots of small questions. I'm seeing what Jev can find, and where my own questions need work.
A citation search follows summation from a 1964 textbook to the choices inside a modern loop.
Repeating cheap arithmetic removes a 32 MiB array and cuts elapsed time. Why I start with the cost of the whole process.
I try handing ordinary Go loops to compiled kernels. It feels a bit like cheating, until the memory and arithmetic dependencies need explaining.
Reusing a calculation, removing a check and moving a read each look like small savings. Keeping the facts they depend on valid is becoming a project of its own.
Which arithmetic choices can an implementation change? I'm trying to write a contract that somebody else can follow, including the small print.
A manifest could bound the files, facts, commands and network access an operator needs, while Piko runs its management logic.
A Rob Pike talk sends me towards a text generator for amd64 and arm64 assembly, with fewer stale numbers to chase when the Go changes.
A Linux decoy needs to lie in both directions. Getting an OS check to recognise the disguise leaves me with HTTP connections, moving clocks and the next morning to contend with.
The page can declare a type the host never compiled. Making their Go calls feel ordinary means preserving type identity, copies, generic entry points and callbacks.
AI proposes the cases, I edit them, then it writes the test table. Ten different inputs don't always give me ten different things to test.
A small addition can spend much of its time being reached. Keeping dispatch inside the handlers, and calls inside assembly, changes how often the engine finds its way back.
GoSSR is becoming a home for the shared tools. I want templates, queries and the interpreter to work together, with one Piko release to keep them in step.
A saved label needs its own bytes. Other strings can still borrow from the arena, leaving me to work out which old slabs a continuing script actually needs.
A deferred function can recover a panic and change a named result to 42. The interpreter must preserve that route back to the caller.
Lending each call a region of the arena keeps returns cheap. Then a pair of closures needs a variable to outlive the call that declared it.
We started the client's quoting tool with integer pence. Keeping fractional prices and transaction currencies is giving the money type more to do.
An ordinary GoSSR page needs more slots than an eight-bit operand can name. I try reusing finished values' slots, then spilling the values that still need a home.
Trees, graphs and nested lists can live in arrays. I'm exploring their access costs and a way to keep their relationships attached to the types.
Carry one tile through the calculation, then take the next. A conditional that needs a full array puts an intermediate back into memory.
I'd like the compiler to handle a kernel's memory lifecycle. Following the readers shows when a buffer can be reused, and where the plan still needs runtime information.
Two numbers first, then a slice. I work through the registers, punctuation and calling boundary before asking assembly to run a larger loop.
Removing a language feature can also remove work from its runtime. Predictable lifetimes and reproducible results gave that thought experiment a direction.
GoSSR needs live updates, especially while I'm changing CSS. Running the page's changing Go brings an interpreter, its dependencies and another job before the client deadline.
I want whole-output golden tests to help me refactor. Choosing an order, controlling changing inputs and keeping useful path details makes their diffs worth reading.
Following a tree, popping a stack, and naming register slots arrange the same addition differently. Small traces let us compare the work involved.
Start with 2 + 3 * 4 and finish with fourteen. A small interpreter gives tokens, precedence and evaluation something concrete to do.
Turn the template into Go expressions the compiler can check, without losing the link back to the page.
GoSSR keeps the page's Go and template together, replacing the generated client with direct access to Go data.
I want Go and TypeScript to agree, but the generators keep giving me more code and another tool to maintain. I'm looking for a different way to build the page.
I love writing SQL and letting sqlc do the repetitive Go. I'm trying a different arrangement for dialect rules, expression types and dynamic filters.
An object store's ETag looks tempting when I need a file hash. Before I use it in a shared interface, I need to check what each provider's ETag actually guarantees.
Templates, styles and logic were becoming strings inside JavaScript classes. Giving them named regions let the author work on a component as a whole.
Desktops keep changing. The company describes its development setup. Resource operators inspect each machine to work out what needs installing, upgrading or repairing.
One folder grant makes a server plugin’s access concrete, then gives us a way to compare isolation boundaries.
An offline renderer can take its time over each frame. Driving the browser with a frame clock lets me reuse the editor's layout and painting.
An edit at thirty-five seconds should stay there. Component interfaces help me choose what to redraw, what to keep and how another kind of piece could fit.
I'm trying reusable browser pieces in a video editor, with a Go worker joining the files to the player. The first timeline is a directory listing.
Clients can use the small agents without adopting the whole platform. Each keeps a shared core and adapters for the integrations that client needs.
Kubernetes supplies the cluster. I still need traffic, certificates, images and a way to notice when an application is unhappy.
An application description needs more than readable syntax. Borrowing HCL helped me work out which parts of a configuration language I wanted to own.
A pill today, a chart when I open it. Browser components and QUIC make me wonder how much of an application needs to arrive together.
A form can quietly turn 25% into 25. Keeping Kubernetes settings intact means preserving what the user actually entered.
I separate what needs to be ready first from what should survive an update. An application change should leave its data and underlying network alone.
Talking about familiar work gets surprisingly difficult when the camera is on. A workplace video, some nerves, and plenty of fun.
A manual replica change separates the job of Kubernetes from the job of keeping Git and the cluster in agreement.
The application team owns its settings, releases and alerts, with infrastructure beside it.
The lyrics arrive. I want to know which service can run next without opening them all.
A Spotify companion to bring music connected to the places we're travelling through into our headphones.
I revisit the country-and-airport problem to learn deployment, keeping the old version serving while its replacement gets ready.
The fuzzy-search bonus gave me a chance to reuse Sound of Jersey work. The assessment got me the Lunatech job, and a move to the Netherlands.
The music site has users and assistant moderators. Now I'm sharing the code too.
How do scattered event announcements become a useful gig guide?
How can a rebuild keep the old data while its schema changes?
The hackathon is over. I can go back and sort out the bits I rushed.
How do I move audio conversion away from the web request and then the web server?
How can a visitor find nearby bands without already knowing their coordinates?
A community site for local bands that I kept building from 2012 to 2016.
Life is full of detours, it helps if you learn to smell the flowers along the way.
An unfinished strategy game and a separate world editor for an RPG, both in C++.
A college menu-system assignment that I turned into a C# console game.
My proudest project as a teenager was A* pathfinding in C++.
Paid websites, my own CMS, and a habit of rebuilding the stack to see if I could make it better.
My first game in C++, now with forests and evil bobs from Russia with love.
My first working game, written in DarkBASIC.
How a departing maths teacher, a friend who wouldn’t share and a RuneScape wanna be clone got me programming at twelve.