From efb91b1decea17e66e52eaf11f105f1b16e02a7f Mon Sep 17 00:00:00 2001 From: Kin Lane Date: Fri, 7 Aug 2026 08:27:58 -0400 Subject: [PATCH 1/2] Split the roadmap where_exp filters so GitHub Pages can build The Pages build has failed on every commit since the roadmap went issue-driven: "Liquid syntax error (line 155): Expected end_of_string but found id". Pages pins github-pages 232 / Jekyll 3.10, whose where_exp parses exactly one comparison and then demands end-of-string. `and` inside the expression is a Jekyll 4 feature, so where_exp: "i", "i.deferred == false and i.state == 'open'" parses locally and fails in production. Split the three filters into one comparison each, the way spotlight-rules already does, and carry that repo's comment explaining why a green local build is not evidence the Pages build passes. Rendering is unchanged: all 12 open issues land in the same ready/consensus/discussing buckets. Co-Authored-By: Claude Opus 5 (1M context) --- roadmap.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/roadmap.md b/roadmap.md index b727de2..f0350ba 100644 --- a/roadmap.md +++ b/roadmap.md @@ -162,9 +162,16 @@ Two rules keep it honest: **Maturity describes the conversation, not the code.** Nothing gets promoted by age. -{% assign live = site.data.roadmap.items | where_exp: "i", "i.deferred == false and i.state == 'open'" %} +{% comment %} + One comparison per `where_exp`, deliberately. GitHub Pages pins Jekyll 3.10, whose `where_exp` + parses a single comparison and then demands end-of-string; `and` / `or` inside the expression is + a Jekyll 4 feature. A local Jekyll 4 build is therefore not evidence the Pages build passes — + the multi-clause version of these lines failed with "Expected end_of_string but found id". +{% endcomment %} +{% assign open_items = site.data.roadmap.items | where_exp: "i", "i.state == 'open'" %} +{% assign live = open_items | where_exp: "i", "i.deferred == false" %} +{% assign parked = open_items | where_exp: "i", "i.deferred" %} {% assign done = site.data.roadmap.items | where_exp: "i", "i.state == 'closed'" %} -{% assign parked = site.data.roadmap.items | where_exp: "i", "i.deferred and i.state == 'open'" %} {% assign groups = "ready,consensus,discussing,raised" | split: "," %} {% for g in groups %} {% assign bucket = live | where: "maturity", g %} From d339da246544268d3086f01b0969e06e766db543 Mon Sep 17 00:00:00 2001 From: Kin Lane Date: Fri, 7 Aug 2026 08:32:05 -0400 Subject: [PATCH 2/2] Build CI the way GitHub Pages does, so CI predicts the deploy MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI pinned jekyll ~> 4.4 and Pages runs github-pages 232 (Jekyll 3.10). That gap is why the roadmap Liquid error in the previous commit sailed through 20+ green CI runs while every pages-build-deployment failed and the site quietly served the last good build. Add a second job that builds against .github/Gemfile.pages — the github-pages gem, deliberately unpinned, since tracking whatever Pages currently resolves to is the whole point. The existing Jekyll 4 job stays: it is what a local `jekyll serve` does. The parity job is self-proving here — it only passes because of the where_exp split in the previous commit. Co-Authored-By: Claude Opus 5 (1M context) --- .github/Gemfile.pages | 14 ++++++++++++++ .github/workflows/ci.yml | 20 ++++++++++++++++++++ .gitignore | 1 + 3 files changed, 35 insertions(+) create mode 100644 .github/Gemfile.pages diff --git a/.github/Gemfile.pages b/.github/Gemfile.pages new file mode 100644 index 0000000..0f76f1a --- /dev/null +++ b/.github/Gemfile.pages @@ -0,0 +1,14 @@ +# The Gemfile GitHub Pages actually builds with — not the one in the repo root. +# +# `pages-build-deployment` ignores our Gemfile and runs the `github-pages` gem +# (currently 232, which pins Jekyll 3.10). Jekyll 3.10 forgives less Liquid than +# the Jekyll 4 we develop against: `where_exp` takes exactly one comparison and +# then demands end-of-string, so `and` / `or` inside the expression — a Jekyll 4 +# feature — parses locally and dies on deploy. +# +# CI builds against this file so it predicts the deploy. Do not pin a version +# here: tracking whatever `github-pages` currently resolves to is the point. + +source "https://rubygems.org" + +gem "github-pages", group: :jekyll_plugins diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d155990..68e8727 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,8 +3,11 @@ on: pull_request: push: branches: [main] + jobs: + # The Jekyll we develop against. Fast, and matches a local `jekyll serve`. build: + name: Jekyll 4 (what we develop on) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 @@ -13,3 +16,20 @@ jobs: ruby-version: '3.2' bundler-cache: true - run: bundle exec jekyll build + + # The build that actually predicts the deploy. GitHub Pages ignores the root + # Gemfile and runs the `github-pages` gem (Jekyll 3.10), which accepts less + # Liquid than Jekyll 4 — see .github/Gemfile.pages. Without this job, CI stays + # green while pages-build-deployment fails and the site silently serves stale. + pages-parity: + name: GitHub Pages (what actually deploys) + runs-on: ubuntu-latest + env: + BUNDLE_GEMFILE: ${{ github.workspace }}/.github/Gemfile.pages + steps: + - uses: actions/checkout@v4 + - uses: ruby/setup-ruby@v1 + with: + ruby-version: '3.2' + bundler-cache: true + - run: bundle exec jekyll build diff --git a/.gitignore b/.gitignore index 119286a..ac51552 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ _site/ vendor/ .bundle/ Gemfile.lock +Gemfile.pages.lock .DS_Store