Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/cve.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# cve — known vulnerabilities in what this repository uses (#83). Runs on main after each merge, on
# each pull request and every Monday, so an advisory published after a merge still turns main red.
#
# - osv: OSV-Scanner reads this repository's lock files (extension/package-lock.json) against
# osv.dev. The checkout has no submodules: forks/picasso and vendor/archify are scanned by their
# own repositories.
# - node: the node of the dev shell (nix/nodejs-bin.nix). `just node-check` fails below the fixed
# versions of the October 2026 security release, because the advisory databases lag the
# Node.js blog; is-my-node-vulnerable checks it against Node.js's own advisories
# (nodejs/security-wg), which catches the next release once its records are published.
name: cve

on:
push:
branches: [main]
pull_request:
schedule:
- cron: "23 6 * * 1"
workflow_dispatch:

permissions:
contents: read

jobs:
osv:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v31
- name: OSV-Scanner over this repository's lock files
run: nix run nixpkgs#osv-scanner -- scan source --recursive .

node:
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
- uses: cachix/install-nix-action@v31
- name: The dev shell's node has the October 2026 fixes
run: nix develop --no-update-lock-file --command just node-check
- name: is-my-node-vulnerable, on the dev shell's node
run: nix develop --no-update-lock-file --command npx --yes is-my-node-vulnerable@1.6.1
6 changes: 3 additions & 3 deletions .github/workflows/extension.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
# ⚠ The dev shell's `nodejs` (nixpkgs at flake.lock) was not checked offline; 22 is the LTS
# the extension was developed on (v22.22.3).
node-version: 22
# The node of the dev shell (nix/nodejs-bin.nix), the October 2026 security release (#83).
# A bare `22` gave 22.23.3, below the 22.23.4 fix; the CVE workflow fails below 24.22.1.
node-version: 24.22.1
cache: npm
cache-dependency-path: extension/package-lock.json
- run: npm ci
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ jobs:
timeout-minutes: 5
steps:
- uses: actions/checkout@v4
# The runner's own node is not pinned and its version is not in the logs (#83): pin it.
- uses: actions/setup-node@v4
with:
node-version: 24.22.1
- run: npm install -g "@anthropic-ai/claude-code@$CLAUDE_CODE_VERSION"
- run: scripts/plugin-smoke.sh

Expand All @@ -56,6 +60,10 @@ jobs:
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
# The runner's own node is not pinned and its version is not in the logs (#83): pin it.
- uses: actions/setup-node@v4
with:
node-version: 24.22.1
- run: npm install -g "@anthropic-ai/claude-code@$CLAUDE_CODE_VERSION"
- env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ just opencode-qwen # serve Qwen3.6-27B and run OpenCode
- `.mcp.json` + `scripts/firefox-mcp.sh` — the Firefox MCP (Mozilla's `@mozilla/firefox-devtools-mcp`, pinned in the script, throwaway profile; on Ubuntu the snap's real binary, since geckodriver cannot start the `/usr/bin/firefox` wrapper): lets an agent install `extension/dist-firefox` (`install_extension`, type `path`) and drive the page. A dev tool, not part of the plugin.
- `.opencode.json` — OpenCode configuration pointing to local `llamacpp/qwen3.6-27b`.
- `justfile` — recipes for running OpenCode, serving Qwen, and quality checks.
- `flake.nix` / `flake.lock` — reproducible dev shell.
- `flake.nix` / `flake.lock` — reproducible dev shell. Its node is `nix/nodejs-bin.nix`, the official nodejs.org 24.22.1 (the October 2026 security release, #83), until nixpkgs ships it; then drop the file and use `nodejs` again. `just node-check` (in `just quality`) fails below the fixed versions; `.github/workflows/cve.yml` runs it, OSV-Scanner over the lock files and is-my-node-vulnerable on main, on each PR and every Monday.
- `evals/` — regression cases for rules (not yet run by a harness).
- `docs/whitepaper/` — the whitepaper's sources: `pt-BR.md` and `en.md` (same sections, same facts) and `template.tex`, a copy of h0ffmann/closed-source's Paper Fabric template at `563c339` (MIT). `just whitepaper` builds `WHITEPAPER.pdf` and `WHITEPAPER.en.pdf` (pandoc and XeLaTeX from the host; the marola and ouroboric logos fetched at pinned commits with their sha256, never committed). Hard cap: 8 pages each (`just whitepaper-check`, in `just quality`). Every fact in it comes from a repo file; `⚠` stays in the PDF.
- `README.md` — human-facing documentation (pt-BR); `README.en.md` is its English mirror. Hard cap: 10 minutes of reading time each, by the plugin's own calculator (`just quality` fails above it). Detail goes to the site (rules, origins, roadmap, awesome, ELI5, graphs), to `docs/`, or to *Reference* below, never back into the README.
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@ cabeçalho abaixo andam juntos. `just release X.Y.Z` abre o PR da versão e, dep

## Unreleased

- Node 24.22.1, a release de segurança de 2026-10-21 (#83), no dev shell e no CI. O nixpkgs ainda está na
24.21.0, afetada, então o `nix/nodejs-bin.nix` usa o binário oficial do nodejs.org, fixado pelo sha256.
O `just node-check`, no `just quality`, falha abaixo das versões corrigidas. O `cve.yml` roda o
OSV-Scanner nos locks, o `node-check` e o `is-my-node-vulnerable` na `main`, em cada PR e toda segunda.
O shell do site recebe a mesma correção pelo picasso (h0ffmann/picasso#143).
- O site embute o whitepaper em pt-BR numa seção própria (`#whitepaper`), como o site do closed-source
embute o artigo dele: o PDF num quadro, carregado sob demanda, com links para abrir e baixar onde o
quadro não aparece. A pílula do pt-BR sai da capa; a do inglês fica.
Expand Down
5 changes: 4 additions & 1 deletion flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@
curl
lsof
vale # the Saramago prose linter (lint/saramago)
nodejs # runs vendor/archify (`just figure`); Chrome comes from the host
# node 24.22.1, the October 2026 security release (#83), from nodejs.org until nixpkgs
# ships it: runs vendor/archify (`just figure`) and the extension's build and tests.
# `just node-check` fails below it. Chrome comes from the host.
(pkgs.callPackage ./nix/nodejs-bin.nix { })
librsvg # rsvg-convert: the whitepaper's logos, SVG to PDF (`just whitepaper`)
poppler-utils # pdfinfo: the whitepaper's 5-page cap; pandoc and XeLaTeX come from the host
iproute2
Expand Down
13 changes: 12 additions & 1 deletion justfile
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ _reading-badge file lang:
echo "[![leitura estimada: $min](https://img.shields.io/badge/leitura%20estimada-$enc-1682D4?style=flat-square)](#tempo-de-leitura)"
fi

quality: pins saramago-check plugin-check figure-check whitepaper-check ext-test
quality: pins saramago-check plugin-check figure-check whitepaper-check node-check ext-test
bash skills/ptbr-routing/bin/run.sh --self-test
bash skills/ptbr-routing/bin/run.sh --check
just --list >/dev/null
Expand Down Expand Up @@ -489,3 +489,14 @@ doi:
title=$(jq -r .title .zenodo.json)
curl -fsS --max-time 60 -G https://zenodo.org/api/records --data-urlencode "q=title:\"$title\"" --data-urlencode size=10 --data-urlencode sort=mostrecent \
| jq -er '.hits.hits | if length == 0 then error("no record yet; Zenodo can take a few minutes after a release") else .[] | [.metadata.version // "?", .doi, .conceptdoi // "?", .metadata.license.id // "?", .metadata.resource_type.title // "?", .links.html] | @tsv end'

# The node on PATH has the fixes of the October 2026 security release (#83): the minimum of its line,
# from nodejs.org/en/blog/vulnerability/october-2026-security-releases. Any other line fails, 18 and
# 20 (end of life) included. The CVE scanners lag the advisory, so the minimum is written here.
node-check:
#!/usr/bin/env bash
set -euo pipefail
v=$(node --version); v=${v#v}
case "${v%%.*}" in 22) min=22.23.4 ;; 24) min=24.22.1 ;; 26) min=26.12.1 ;; *) min= ;; esac
[ -n "$min" ] && [ "$(printf '%s\n%s\n' "$min" "$v" | sort -V | head -1)" = "$min" ] || { echo "node-check: node $v is affected or unsupported; use 22.23.4+, 24.22.1+ or 26.12.1+ (#83)" >&2; exit 1; }
echo "node-check: node $v (minimum $min)"
57 changes: 57 additions & 0 deletions nix/nodejs-bin.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copied from h0ffmann/picasso labs/gleam-website/nodejs-bin.nix (h0ffmann/picasso#143): a lab references
# nothing outside itself, so this repository keeps its own copy. Same version, same hashes.
# Node.js 24.22.1, the official build from nodejs.org, in place of nixpkgs' nodejs until nixpkgs
# ships it: 24.22.1 is the October 2026 security release (Brotli RCE, TLS hostname bypass,
# nodejs.org/en/blog/vulnerability/october-2026-security-releases), and nixos-unstable is still on
# 24.21.0 (2026-10-22). The hashes are the release's SHASUMS256.txt. Drop this file, and the
# overlay in flake.nix, once `nix flake update` brings nodejs >= 24.22.1.
{ lib, stdenv, fetchurl, patchelf }:

let
version = "24.22.1";
builds = {
x86_64-linux = { arch = "linux-x64"; sha256 = "6c172a9ab6718f7b801fb5a7bd486af2ee5e32758086a04b84fcce2aa77095e6"; };
aarch64-linux = { arch = "linux-arm64"; sha256 = "dbabf7a1cbf947e6059ffad2c27b80041db97dea1e553b62afdee7f13fca336e"; };
aarch64-darwin = { arch = "darwin-arm64"; sha256 = "654ba79de6155647e22321932b45f2a1ccb705976cc337c9b8e278beb085a628"; };
x86_64-darwin = { arch = "darwin-x64"; sha256 = "65e450f90a6eaacd5000f611861c4ce65fadc87f813795dc4ed0c0e5f2fca2d4"; };
};
build = builds.${stdenv.hostPlatform.system} or (throw "nodejs-bin: no official build for ${stdenv.hostPlatform.system}");
in
stdenv.mkDerivation {
pname = "nodejs";
inherit version;
src = fetchurl {
url = "https://nodejs.org/dist/v${version}/node-v${version}-${build.arch}.tar.xz";
inherit (build) sha256;
};
nativeBuildInputs = lib.optionals stdenv.hostPlatform.isLinux [ patchelf ];
dontConfigure = true;
dontBuild = true;
# The fixup phase must not touch the ELF again: strip and shrink-rpath both break node.
dontStrip = true;
dontPatchELF = true;
installPhase = ''
runHook preInstall
mkdir -p $out
cp -r bin include lib share $out/
'' + lib.optionalString stdenv.hostPlatform.isLinux ''
# The rpath first, then the interpreter, in two calls: patchelf 0.19.2 makes a node that
# segfaults in the loader when it sets both in one call, or the interpreter first.
patchelf --set-rpath ${lib.makeLibraryPath [ stdenv.cc.cc.lib ]} $out/bin/node
patchelf --set-interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" $out/bin/node
'' + ''
runHook postInstall
'';
# A node that does not start fails the build here, not in a user's shell.
doInstallCheck = true;
installCheckPhase = ''
$out/bin/node --version | grep -qx "v${version}"
'';
meta = {
description = "Node.js ${version}, the official nodejs.org build";
homepage = "https://nodejs.org";
license = lib.licenses.mit;
mainProgram = "node";
platforms = builtins.attrNames builds;
};
}
Loading