diff --git a/.github/workflows/gate.yml b/.github/workflows/gate.yml index 40988554..811baae3 100644 --- a/.github/workflows/gate.yml +++ b/.github/workflows/gate.yml @@ -331,14 +331,15 @@ jobs: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Setup Node - # Pinned Node is enough for markdownlint-cli2; no bun needed. - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 - with: - node-version: '22' - - - name: Install markdownlint-cli2 - run: npm install -g markdownlint-cli2@0.18.1 + - name: Install toolchain via three-way-parity script (GOVERNANCE §24) + # Installs markdownlint-cli2 via mise (pinned in .mise.toml as + # `npm:markdownlint-cli2`). Single source of truth — same + # version on dev laptops + CI runners. Prior step hardcoded + # the version in this workflow (0.18.1) which drifted + # behind the pin discipline the rest of the lints use and + # violated Aaron's "update declarativly everywhere" + # directive (2026-04-24). + run: ./tools/setup/install.sh - name: Run markdownlint - run: markdownlint-cli2 "**/*.md" + run: mise exec -- markdownlint-cli2 "**/*.md" diff --git a/.markdownlint-cli2.jsonc b/.markdownlint-cli2.jsonc index f87a645f..e47a12ca 100644 --- a/.markdownlint-cli2.jsonc +++ b/.markdownlint-cli2.jsonc @@ -32,7 +32,20 @@ // IS author-controlled and could lint clean, but applying // the ignore to the whole directory keeps the rule simple // (one path, not 10 file-specific entries). - "docs/amara-full-conversation/**" + "docs/amara-full-conversation/**", + // PR-preservation archive (tools/pr-preservation/archive-pr.sh + // output) is verbatim preservation of PR bodies + review-thread + // content. By design, the archive carries the input markdown + // structure unchanged (blank-line-around-lists, duplicate + // "Pull request overview" headings from GitHub's auto-preamble, + // consecutive blank lines from the source, etc.). Reformatting + // to satisfy MD032/MD024/MD012 would violate the verbatim- + // preservation contract (Otto-250 + Otto-279 pr-preservation IS + // a history surface). The scripts that generate these files + // already ship their own hygiene pass; the archive output is + // not author-controlled prose. + "docs/pr-discussions/**", + "docs/pr-preservation/**" ], "noBanner": true, "noProgress": true, diff --git a/.mise.toml b/.mise.toml index 44d69215..7fdf1810 100644 --- a/.mise.toml +++ b/.mise.toml @@ -46,6 +46,13 @@ actionlint = "1.7.12" # slim + ubuntu-24.04-arm runners don't ship shellcheck pre- # installed, so declarative pin here ensures dev/CI parity. shellcheck = "0.11.0" +# markdownlint-cli2: markdown linter. Declarative pin per Aaron's +# "update declarativly everywhere" directive (2026-04-24); moves +# the version off a hardcoded `.github/workflows/gate.yml` line +# and into the single source of truth the rest of the toolchain +# already uses. 0.22.1 (npm latest as of 2026-04-24); prior pin +# was 0.18.1 inlined in gate.yml. +"npm:markdownlint-cli2" = "0.22.1" [settings] # `python-build-standalone` (upstream for mise's python plugin)