AGENTS.md

AGENTS.md

Guidance for LLM coding agents (Claude, Cursor, etc.) working in this repository. Also exposed as CLAUDE.md (symlink) for tools that look for that filename. Keep this file in sync when the build/deploy workflow or dependencies change.


1. What this project is

srombauts.fr is Sébastien Rombauts’ personal programmer blog, a static site generated by Jekyll and hosted on GitHub Pages under the custom domain srombauts.eu (see CNAME). The GitHub repository name is still srombauts.fr (kept for now), only the live custom domain has moved from .fr to .eu.

Work in progress. This is a resurrection of the author’s old WordPress blog (2010–2018), recovered from the Wayback Machine. Seed snapshot: https://web.archive.org/web/20180419132242/http://www.srombauts.fr/. Several older posts are still stubs that only link to their archived copy; they are being restored to full content progressively, so expect placeholder posts alongside finished ones.

The site does not use a custom GitHub Actions workflow. It relies on the “legacy” GitHub Pages branch-based build: every push to master triggers an automatic Jekyll build on GitHub’s infrastructure.

Editorial intent and audience

This blog doubles as a professional portfolio. Alongside the casual howto/tutorial posts, it serves as durable, verifiable evidence of past work: open-source projects, Unreal/Unity tooling, and an earlier embedded/FPGA/real-time career. Write accordingly.

  • Prefer substance and accuracy over post count. A post a technical reader might see should be specific and checkable, not filler.
  • Verify technical claims against the actual repositories and their real dates before stating them. Do not invent specifics; if a fact only lives in the author’s memory or CV, keep the post honest and high-level, or ask.
  • Do not silently backdate. The blog’s first real post is 2010-09-07. Material from before 2010 (the embedded/FPGA career, etc.) is written as an openly retrospective piece, dated to a real milestone, with a short note (a footnote in the existing edit: style) saying the write-up itself is recent.
  • A blog-era project that genuinely dates from 2010–2018 may use its real milestone date with a brief retrospective note, since the blog did exist then.

2. Repository layout

srombauts.fr/
├── _config.yml          # Jekyll + minimal-mistakes site configuration
├── _data/
│   └── navigation.yml   # Top navigation menu items
├── _pages/              # Standalone pages (about, portfolio, 404, archives, sitemap)
├── _posts/              # Blog posts: YYYY-MM-DD-title-slug.markdown
├── assets/
│   └── images/          # Image assets referenced from posts/pages
├── index.markdown       # Site home, uses layout: home
├── favicon.ico
├── CNAME                # Custom domain ("srombauts.eu"); leave it alone
├── Gemfile              # Ruby gem manifest (github-pages + plugins)
├── Gemfile.lock         # Pinned gem versions (DO NOT hand-edit)
├── .gitignore           # Ignores _site, .sass-cache, .jekyll-cache, vendor, ...
├── .editorconfig        # 2-space indent, LF, UTF-8, final newline
├── README.md            # Short public README
└── CLAUDE.md            # This file

There is no _layouts/, _includes/, _sass/ or assets/css/ directory in the repo: those come from the remote theme (see §3) and are pulled in at build time. If you need to override a layout/include, add a file with the same relative path locally and Jekyll will use the local copy.

Where to put new content

Goal Location Front matter layout
New blog post _posts/YYYY-MM-DD-slug.markdown inherited (single)
New static page _pages/slug.markdown single
Image used in a post/page assets/images/foo.png n/a
Site-wide navigation entry _data/navigation.yml n/a

_pages/ is included in the build via the include: list in _config.yml. Each page sets its own permalink: in front matter.


3. Tech stack and pinned versions

Component Version (Gemfile.lock) Notes
Jekyll 3.9.2 Pulled in by github-pages
github-pages 227 (Jul 2022) Bundles all gems GitHub Pages supports
Ruby (target) 2.7.x recommended github-pages v227 predates official Ruby 3.x support (added in v229, Feb 2024)
Theme mmistakes/minimal-mistakes@4.24.0 Loaded via remote_theme
Markdown engine kramdown (GFM) _config.yml -> markdown: kramdown
Syntax highlight rouge 3.26.0  
Search lunr (client-side) search: true, search_provider: lunr
Permalink style pretty (/YYYY/MM/DD/slug/)  
Bundler 2.3.25 From BUNDLED WITH in Gemfile.lock

Active Jekyll plugins (_config.yml plugins: and Gemfile): jekyll-paginate, jekyll-sitemap, jekyll-feed, jemoji, jekyll-include-cache.

Important compatibility notes

  • The github-pages 227 gem locks Jekyll 3.9.2 and is intended for Ruby 2.7.x. Newer Ruby 3.x can work but you may need workarounds (e.g. bundle add webrick). GitHub Pages itself (per https://pages.github.com/versions.json) currently serves with github-pages 232 / Ruby 3.3.4. If you bump the gem to keep up with production GitHub Pages, regenerate Gemfile.lock:
    bundle update github-pages
    
  • The theme is consumed via remote_theme:. Do NOT add gem "minimal-mistakes-jekyll" to the Gemfile unless you also remove remote_theme: and commit to a different installation flow.
  • jekyll-include-cache MUST stay both in the Gemfile plugin group AND in _config.yml’s plugins: list. Without it, the theme errors out with Unknown tag 'include_cached'.

4. Setting up a local dev environment on Ubuntu Linux

These instructions target Ubuntu 24.04 LTS (Noble) and 22.04 LTS (Jammy), including WSL2. Pick one of the two paths below.

This is the most reliable approach because it uses a Ruby version aligned with the locked Gemfile.lock.

# 1. Install build prerequisites
sudo apt update
sudo apt install -y \
    git curl autoconf bison build-essential \
    libssl-dev libyaml-dev libreadline-dev zlib1g-dev libncurses5-dev \
    libffi-dev libgdbm-dev libdb-dev libgmp-dev \
    libsqlite3-dev libxml2-dev libxslt1-dev

# 2. Install rbenv + ruby-build
curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-installer | bash
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec bash   # reload shell

# 3. Install Ruby 2.7.8 and pin it for this repo
cd ~/srombauts.fr
rbenv install 2.7.8
rbenv local 2.7.8        # writes .ruby-version (gitignored if desired)
ruby --version           # => ruby 2.7.8

# 4. Install Bundler matching Gemfile.lock and project gems
gem install bundler -v 2.3.25
bundle config set --local path 'vendor/bundle'   # keep gems in repo, vendor/ is gitignored
bundle install

Then jump to §5 for daily commands.

4.B Quick path: system Ruby (Ubuntu’s ruby-full, currently Ruby 3.2)

Acceptable for casual edits, but expect occasional warnings or the need to update gems. If you just want to preview a content change, this is fine.

# 1. Install Ruby + build tools
sudo apt update
sudo apt install -y ruby-full build-essential zlib1g-dev

# 2. Install gems into your home directory (avoid sudo for `gem install`)
echo '# Install Ruby Gems to ~/gems' >> ~/.bashrc
echo 'export GEM_HOME="$HOME/gems"' >> ~/.bashrc
echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

# 3. Install Jekyll + Bundler
gem install jekyll bundler

# 4. Install project dependencies
cd ~/srombauts.fr
bundle install
# Ruby 3.x note: webrick is no longer in the stdlib. If `jekyll serve` errors
# with a webrick LoadError, run:
#   bundle add webrick

If bundle install fails on Ruby 3.x because github-pages 227 transitive deps are too old, run bundle update github-pages to bump to a Ruby-3-friendly version (see §3 caveat).

Common WSL2 caveats

  • Always edit files inside the WSL filesystem (~/srombauts.fr), not under /mnt/c/..., otherwise file watching and --livereload are unreliable.
  • To make the dev server reachable from Windows, either use localhost:4000 directly (works on recent WSL) or bind explicitly: bundle exec jekyll serve --host 0.0.0.0.

5. Local development commands

Run all commands from the repo root (/home/srombauts/srombauts.fr).

# Install / refresh dependencies
bundle install

# Build & serve at http://localhost:4000 with auto-rebuild on changes
bundle exec jekyll serve

# Same, with live-reload in the browser
bundle exec jekyll serve --livereload

# Include drafts (any file in a _drafts/ folder, no date in name)
bundle exec jekyll serve --drafts

# Production-like build into ./_site (one-shot, no server)
JEKYLL_ENV=production bundle exec jekyll build

# Clean the build output and Jekyll caches
bundle exec jekyll clean

# Update github-pages and all transitive gems to match GitHub's current build
bundle update github-pages

Reminders:

  • Editing _config.yml requires restarting jekyll serve; it is not picked up by the watcher (this is documented at the top of _config.yml).
  • The default permalink for posts is /:year/:month/:day/:title/ (permalink: pretty).
  • Generated artifacts (_site/, .jekyll-cache/, .sass-cache/, vendor/) are gitignored. Never commit them.

6. Authoring conventions

Blog post

Filename: _posts/YYYY-MM-DD-kebab-case-title.markdown

Minimal front matter:

---
title:  "My post title"
date:   2026-04-27 12:00:00 +0200   # optional; filename date is used otherwise
tags:
  - some-tag
  - another-tag
---

The post layout, author_profile, read_time, share, related, etc. are inherited from the defaults: block in _config.yml, so most posts only need a title and tags. Add toc: true to enable a sidebar table of contents.

Page

Filename: _pages/something.markdown

---
layout: single
title: My Page
permalink: /something/
---

Useful Liquid shortcodes (provided by minimal-mistakes 4.24.0)

{% include video id="XTB7xq6rVC4" provider="youtube" %}
{% include figure image_path="/assets/images/foo.png" alt="alt" caption="cap." %}

These are defined in the remote theme’s _includes/ directory; do not redefine them locally unless you want to override theme behaviour.

Images

Place files in assets/images/ and reference them with absolute root-relative paths so they work both locally and on the deployed site:

![alt text](/assets/images/SimplexNoise-2D-7octaves.jpg)

Favor a more compressed format than PNG for the web. PNG is large for photographic or smooth-gradient images; reserve it for screenshots with sharp text/edges, flat-color graphics, or images needing transparency. Otherwise prefer JPEG (photos, renders, noise/gradient fields) or WebP, which keep the page weight down with no visible loss.

Footnotes (the edit:/note: pattern)

Retrospective edit: and note: lines link to a kramdown footnote (note: [^1] in the body, [^1]: ... defined near the bottom).

Keep each footnote definition on a single line. In kramdown (the Markdown engine here), continuation lines of a footnote definition must be indented by four spaces/one tab; an unindented soft-wrapped second line is parsed as a separate paragraph after the footnote, so the wrapped text leaks into the page body instead of staying in the footnote. Either keep the whole [^1]: ... definition on one (long) line, or indent every continuation line by four spaces. The one-line form is simpler and the convention used across the posts. This is the documented kramdown rule, not a quirk: https://kramdown.gettalong.org/syntax.html#footnotes.


7. Build & deploy

There is no CI/CD workflow file in the repo (.github/workflows/ does not exist). Deployment is handled entirely by GitHub Pages’ built-in Jekyll pipeline.

Sequence on each push to master:

  1. You push commits to origin/master.
  2. GitHub Pages detects the push, runs Jekyll on a sandbox using the github-pages gem version GitHub currently bundles.
  3. The result is published at srombauts.eu (custom domain via the CNAME file at the repo root).

DNS for the custom domain is configured outside this repo (registrar / DNS provider). The CNAME file content (srombauts.eu) is what tells GitHub Pages which hostname to expect; do not modify it casually.

If you ever migrate to a custom GitHub Actions workflow:

  • Move build to .github/workflows/pages.yml using actions/jekyll-build-pages
    • actions/deploy-pages.
  • Be aware that custom workflows ignore the CNAME file at the repo root; the custom domain must instead be configured in repo Settings -> Pages.

8. _config.yml quick reference

The full file is the source of truth. Key knobs you may need to tweak:

Key Current value Purpose
title / subtitle SRombauts.fr / Comments from a developer Masthead text
url http://srombauts.eu Canonical site URL
baseurl "" Subpath; empty for apex domain
repository SRombauts/srombauts.fr Used by jekyll-github-metadata
remote_theme mmistakes/minimal-mistakes@4.24.0 Theme + version
minimal_mistakes_skin dark Theme color skin
search / search_provider true / lunr Client-side search
permalink pretty /YYYY/MM/DD/slug/
timezone Europe/Paris Date rendering
author: block name, avatar, bio, social Sidebar profile card
defaults: per-collection front matter Avoids repetition in posts/pages

To bump the theme: change the version after @ in remote_theme and rebuild. Theme release notes: https://github.com/mmistakes/minimal-mistakes/releases.


9. Common pitfalls (read before debugging)

  • Liquid Exception: Unknown tag 'include_cached'jekyll-include-cache missing from either Gemfile or _config.yml plugins:.
  • cannot load such file -- webrick — Ruby 3.x without webrick. Fix: bundle add webrick (then commit Gemfile/Gemfile.lock).
  • bundle install fails on Ruby 3.x with native extension errors — The pinned gems are old. Either install Ruby 2.7.8 via rbenv (§4.A) or run bundle update github-pages.
  • Edits to _config.yml not visible — Restart bundle exec jekyll serve; the config is not auto-reloaded.
  • Post does not appear — Filename must start with a valid YYYY-MM-DD- date that is not in the future (relative to timezone: Europe/Paris). Use --future on the serve command if you really need to preview a future post.
  • Local layout looks different from production — Your local github-pages gem is likely older than what GitHub serves. Run bundle update github-pages.
  • CNAME removed after a deploy — Do not delete CNAME from the repo root while using the legacy branch-based publishing; it is read on every build.

10. House rules for AI agents editing this repo

  • Preserve the 2-space indent / LF / UTF-8 / final newline policy from .editorconfig for all text files.
  • Do not commit _site/, vendor/, .jekyll-cache/, .sass-cache/, .bundle/, or any *.bak file.
  • Do not edit Gemfile.lock by hand. To change pinned versions, edit Gemfile and run bundle install / bundle update <gem>.
  • When adding a post, use lowercase kebab-case in the filename and prefer a small number of existing tags (community, tools, unreal-engine, tutorial, vcs, github, astrophotography, …) before inventing new ones.
  • Place new images under assets/images/ and reference them with absolute paths (/assets/images/...).
  • Match the writing voice of existing posts: first person, casual, occasional retrospective edits added as edit: lines or footnotes.

Agent skills (.claude/skills/)

Reusable agent instructions live in .claude/skills/, one SKILL.md per skill. A skill-aware tool (e.g. Claude Code) auto-loads each one from its description. Tools without skill support should treat the two baseline skills below as always-on house rules. This list names the mandatory skills and the one editing rule; it is not a full catalogue, and each skill’s own description remains the authoritative trigger.

  • agent-response-style (baseline for all interaction). Professional, factual, neutral tone with calibrated, peer-review-style challenge: compare alternatives, surface trade-offs and failure modes, do not merely validate. Applies to every task.
  • humanizer (mandatory for prose). Run it on every blog post and every user-facing message to strip AI-writing tells (significance inflation, filler, em dashes, rule of three, sycophancy, …). It is a vendored third-party skill: never edit it, so it can be re-synced from upstream. Its “no em dashes” rule governs published prose; the em-dash tolerance in skill-maintenance applies only to skill .md files.
  • skill-maintenance (when editing skills). Conventions for files under .claude/skills/**. Read it before creating or changing any skill.

Commit workflow

  • After completing any change, always ask the user whether they want you to commit it. Do not commit on your own initiative.
  • Use a short, descriptive commit message (single line, imperative or descriptive, no conventional-commit prefix), matching the style of the existing history. Inspect it first with git log --oneline (e.g. Ignore ".vs" directory, Fix link to the drone post, Bump github-pages gem to match production).
  • Stage only the files relevant to the change; never commit _site/, vendor/, .jekyll-cache/, .sass-cache/, .bundle/, or *.bak.
  • Do not push to origin/master unless the user explicitly asks for it (pushing triggers a live deploy via GitHub Pages).

11. Useful external references