01 Oct 2026
I set this blog up in 2014. In my post about the setup, I wrote about Jekyll, custom permalinks, a Makefile, and getting Travis to build it.
Coming back to it twelve years later, the Markdown and templates were still pretty easy to follow. The Ruby dependencies were showing their age.
I’ve been writing again, so it seemed like a good time to tidy things up. I also wanted a bit more confidence that changing a dependency or fiddling with a template wouldn’t break the live site.
Getting it building again
We started with GitHub Actions, updating Ruby and Bundler and getting a working lockfile committed.
There was some housekeeping along the way. The Travis configuration went, as did the reference to it on the About page. Dependabot had been complaining that it couldn’t update its own pull requests because the Bundler version was too old. Updating the lockfile sorted that out.
The Makefile is still there. The reason I gave for it in 2014 was that I’m not a Ruby or web developer and would forget the commands. I don’t think that needs revising.
Does it actually render?
A successful Jekyll build is useful, but it doesn’t tell you much about the result.
We added a Playwright test that opens the generated site in Chromium at desktop and phone sizes. It visits the posts, the About and Archive pages, pagination, and the 404 page. It checks that there’s content, the CSS loads, and the internal links work.
It also saves screenshots from each page as a build artifact. Those are handy when a test says everything is fine but you’d still like to have a look.
The link checks found that some navigation links used extensionless URLs while the generated files ended in .html. Jekyll was quite happy to build that. The browser test was less impressed.
Putting the tests in front of publishing
GitHub Pages now publishes through the Actions workflow.
The workflow builds the site, runs the tests, then uploads the tested output for deployment. Pull requests get checked without being published. A failed build or test leaves the existing site in place.
That required switching the Pages publishing source in the repository settings as well. Adding a workflow alone wouldn’t have stopped the old publishing path.
This is probably the change I care about most. Dependency updates can come through as pull requests, get tested, and be reviewed before they affect the blog.
A few things I’d missed
We also checked keyboard navigation and contrast.
The viewport settings contained maximum-scale=1, which restricted zoom. That went. Dates and some syntax highlighting colours needed more contrast. Long code blocks could scroll sideways, but you couldn’t reach them with the keyboard.
There’s now a skip link, visible keyboard focus, and focusable code blocks. Links in the body text are underlined too.
The CI checks include these things now, though they’re still automated checks of the local site. The map and Disqus are external services, and those requests are blocked during testing.
Fewer gems
Once Actions was handling the build, we could stop using the github-pages gem bundle.
This site keeps its Hyde templates and CSS in the repository. It generates the feed and sitemap from templates too. Pagination is the only plugin it needs.
We moved to Jekyll 4 with that plugin and regenerated the lockfile. The dependency count dropped from 98 gems to 36. Comparing the generated output with the old build showed the same published file paths, so the existing post URLs survived the upgrade.
I did this with an AI agent connected to GitHub. It inspected the files, prepared pull requests, checked Actions results, and downloaded screenshots for review. There were a few rounds of fixing things the new tests found.
It was a useful job for an agent: an existing repository, fairly small changes, and a way to check the result. Having it open the pages in a browser was particularly worthwhile.
The blog hasn’t had a redesign. It’s still Markdown, Jekyll, and much the same layout I picked in 2014. I’ve just brought the build up to date and made it harder to publish something broken.
Dusting off this blog
01 Oct 2026
I use a GitHub repository containing an Obsidian-style archive of Markdown files as a long-term reference for AI agents.
The idea is simple: keep useful context somewhere I can read, edit, and version, then give the agent instructions to consult it when relevant. A new conversation can pick up a project without me having to explain its entire history again.
The chat is where the work happens. The repository is where I keep the things worth carrying forward.
An archive like this can hold project notes, decisions, preferences, useful references, and explanations of why something works the way it does. Those last two are particularly useful. An agent can often discover what exists by reading code, but understanding why I chose it usually needs some additional context.
Markdown makes this easy to maintain. I can work with the files in Obsidian, a text editor, or GitHub itself. Links between notes help connect related ideas, and the files remain useful even if I change which AI tools I use.
Git adds a history of changes. If a note becomes inaccurate, I can correct it. If an agent makes an unhelpful edit, I can inspect the diff and revert it.
What the repository could look like
There is no special schema required. A small archive could start with a directory listing like this:
README.md
index.md
preferences/
communication.md
tools-and-workflows.md
projects/
personal-blog/
overview.md
deployment.md
decisions.md
garden-planner/
overview.md
next-steps.md
reference/
markdown-conventions.md
useful-links.md
journal/
2026-10-01.md
archive/
retired-project.md
This is an example structure, rather than a requirement to organise every vault the same way.
The README.md explains what the repository is for and how to use it. The index.md links to the main topics, with a sentence describing each one. That gives an agent a useful starting point without needing to read every file.
The project folders hold current context: what I am building, how it works, what we have decided, and what remains to do. Preferences hold reusable guidance, while reference notes capture material that applies across projects. Dated journal entries can record what happened in a session; anything that changes a project’s current state should also be reflected in its project notes.
For a question about the blog’s deployment, the agent could follow index.md to projects/personal-blog/overview.md, then read deployment.md and the relevant decisions. After a change, it could update those notes and add a link from the index if it creates a new one.
The folder structure helps navigation, but the notes still need to explain themselves. A short summary, a last-reviewed date, and links to related notes make it easier to judge whether a file is relevant and current.
Giving the agent directions
Putting notes in a repository is only half the setup. The agent also needs to know where to look and when to use them.
Custom prompts or instructions can establish that behaviour. For a chat app such as ChatGPT on mobile, I can give it a standing instruction to consult the archive for questions about my projects and previous decisions, wherever the relevant GitHub connection is available.
A starting prompt might look like this:
My long-term reference notes are in the GitHub repository OWNER/REPO.
When a task depends on my previous work, preferences, or project decisions, consult that repository before answering. Start with the README or index, then read the relevant notes and follow useful links.
Retrieve the files needed for the task rather than loading the whole archive. Tell me which notes informed your answer, and flag anything that appears outdated or contradictory.
When I ask you to save a decision or update the archive, read the existing note first, make a focused change, and report what you changed. Keep confirmed decisions separate from suggestions and unresolved questions.
If you cannot access the repository, say so rather than guessing.
The prompt establishes the workflow. The connected tool provides access. Custom instructions alone do not make a repository available, so I still need to connect GitHub and check that the tools I need are supported in the app I am using.
Reading and writing through GitHub
With a GitHub plugin that supports the required operations, the archive can become part of the conversation.
I can ask the agent to read the notes for a project before suggesting a change. After we settle on an approach, I can ask it to update the relevant Markdown file or create a new note. Depending on the available tools and permissions, those changes can be committed to a branch and reviewed through a pull request.
For example:
Read the archive notes for this project and explain why we chose the current deployment approach.
Then, after making a new decision:
Update the deployment note with what we agreed, including the reason for the change and any remaining questions.
That gives the next session something concrete to retrieve. It also means I can review the saved context using the same tools I already use for code.
Keeping the archive useful
I want the repository to contain useful reference material, rather than every conversation verbatim.
A short note recording a decision, its reasoning, and the date is often more valuable than a lengthy transcript. Clear filenames and an index help an agent find the right material. Links to supporting sources make the notes easier to check.
The archive still needs maintenance. Old assumptions can become misleading, and an agent’s suggestion should not quietly turn into a recorded fact. I try to keep the distinction between “we decided this”, “we might try this”, and “this needs checking” explicit.
This approach gives me continuity that I can inspect and control. I can start a conversation on my phone, return to the work elsewhere, and direct the next agent to the same reference material.
The useful part is having a growing collection of notes that both I and the agent can consult—and a straightforward way to improve those notes as we work.
Giving AI agents a long-term reference with Markdown and GitHub
09 May 2018
Has your project ever been bitten by hard-to-track down buffer overruns?
Have you ever wanted to be able to just ignore buffer overruns and make them a thing of the past?
Are you ok with wasting memory to work around this problem?
Well, your wish has now been answered, thanks to malloc-extra!
This handy little shared library will allocate a trailing amount of buffer space for every allocation, ensuring that your pesky buffer overruns will just land in safely unused and reserved space.
malloc-extra simply uses some dynamic library magic to intercept every malloc, calloc, and realloc your program will call, and just request slightly more space than the original requester was chasing. From the point of view of the caller of these functions - they don’t know this extra space exists, meaning that it can be a transparent fix to already compiled programs!
MALLOC_EXTRA_DEBUG=1 MALLOC_EXTRA=100 LD_PRELOAD=./malloc-extra.so ./test
Easily fix buffer overruns!