From f21ae3aca9456caa425f45e850e12a52616a5319 Mon Sep 17 00:00:00 2001 From: Pieter Viljoen Date: Mon, 10 Aug 2026 15:39:27 -0700 Subject: [PATCH] Carry the Host Tool Declaration, and Declare Hugo In It host-tools.json is a carried baseline file the hub added, so every repository owes one. This is not the empty stub, because this repository genuinely needs a tool the fleet declaration does not carry. Hugo is the site generator and this repository's whole output, and AUDIT.md section 3 runs it locally to prove the URL contract, so a host auditing this repository needs it rather than only the CI runner. The floor is 0.164.0, a target anchored to the version .github/actions/install-hugo pins, since that action states a minor bump can change rendered output. The entry is honest that a floor cannot enforce a pin: a floor is a minimum and the pin is exact, so a newer Hugo passes here and can still build output CI would not, and the checksum-verified install is what guarantees reproducibility. The vendored theme's own 0.146.0 minimum is recorded as the lower measured boundary. Only Hugo is declared. The deploy reaches rsync and ssh and the live check reaches curl, but all three run on the CI runner or the VPS rather than on a maintainer's host, so declaring them would fail a host that never needed them. The file carries no $schema pointer, because the schemas are hub-only and a relative pointer would resolve to a path this repository does not have. The carried spec/secrets.json already omits its own for the same reason. One correction the previous pull request's sweep missed: the Repository Layout bullet still described repo-config/ as holding "the apply script", which was deleted there. That sweep grepped for the path, and a bullet describing the file without naming it cannot be found that way. Co-Authored-By: Claude Opus 5 (1M context) --- GOVERNANCE.md | 3 ++- host-tools.json | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 host-tools.json diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 18d13ff..e4bf7ee 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -429,8 +429,9 @@ Every repo's GitHub repository details (the About panel) follow a fixed conventi - [`layouts/`](./layouts/), [`themes/`](./themes/), [`assets/`](./assets/), [`i18n/`](./i18n/): the theme and the template overrides that keep a strict build warning-free. - [`checks/`](./checks/): the URL contract and the gates that enforce it, covering both the built output and a running server. - [`deploy/`](./deploy/): the release script, the web-server config, and the redirect maps. -- [`repo-config/`](./repo-config/): branch rulesets and the apply script, kept out of `.github/` (which is Actions-owned). +- [`repo-config/`](./repo-config/): branch rulesets and the repository settings, kept out of `.github/` (which is Actions-owned). - [`spec/`](./spec/): the machine-readable ground truth this repo audits itself against. +- [`host-tools.json`](./host-tools.json): the tools a host needs to work on this repo beyond the fleet's own declaration, layered over it tighten-only by the hub's host gate. It declares Hugo, since the URL contract is proven by building the site locally. - [`.github/workflows/`](./.github/workflows/): this repo's CI. After editing a doc, run the linters (see "Running the Linters Locally") before commit. The Comments, Character Set, and Line Endings rules above are the frequent regressions, so hold them exactly. diff --git a/host-tools.json b/host-tools.json new file mode 100644 index 0000000..749d4e9 --- /dev/null +++ b/host-tools.json @@ -0,0 +1,18 @@ +{ + "note": "This repository's own host-tool declaration, layered over the fleet declaration in the hub's spec/host-tools.json by the hub's scripts/host_gate.py, which reads this file relative to its --repo argument. Layering is tighten-only: an entry here may add a tool, raise a floor, or turn an optional tool required, and may not lower a floor or turn a required tool optional. It carries no $schema pointer, because the schemas are hub-only and no selector carries one, so a relative pointer here would resolve to a path this repository does not have. The carried spec/secrets.json already works that way. Only hugo is declared. The deploy reaches rsync and ssh, and the live URL check reaches curl, but all three run on the CI runner or the VPS rather than on a maintainer's host, so declaring them here would fail a host that never needed them.", + "tools": [ + { + "name": "hugo", + "required": true, + "probes": [["hugo", "version"]], + "pattern": "hugo v(\\d+(?:\\.\\d+)*)", + "minimum": "0.164.0", + "why": "The site generator, and this repository's whole output. AUDIT.md section 3 runs it locally to prove the URL contract, so a host auditing this repository needs it rather than only the CI runner. The floor is a target rather than a measured breakage one version below it, and it says so rather than implying a defect nobody found: it is the version .github/actions/install-hugo pins, and that action states why the pin exists, since a minor bump can change rendered output and the site is reproducible only if the generator is. What the floor cannot do is enforce the pin, because a floor is a minimum and the pin is exact, so a host above 0.164.0 passes here and can still build output CI would not. The checksum-verified install in that action is what guarantees reproducibility, and this entry only catches the too-old half. One lower boundary is measured rather than chosen: the vendored PaperMod theme names 0.146.0 as its minimum and does not build below it. The extended build is required for the theme's SCSS and is not expressible as a version, so the probe reads the version and a reader confirms the extended suffix themselves.", + "source": { + "linux": "The checksum-verified .deb from https://github.com/gohugoio/hugo/releases, matching the version .github/actions/install-hugo pins, so a local build and a CI build use the same generator. The extended build is required.", + "macos": "Homebrew's hugo, which is the extended build, checked against the pinned version.", + "windows": "Not applicable, since every consumer of this repository is Linux, which is also why it declares lineEndings lf." + } + } + ] +}