Skip to content

fix(dogfood): batch 5 — the last three audit findings, and a producer that could fabricate its own verdict #360

fix(dogfood): batch 5 — the last three audit findings, and a producer that could fabricate its own verdict

fix(dogfood): batch 5 — the last three audit findings, and a producer that could fabricate its own verdict #360

Workflow file for this run

name: mdBook CI
on:
push:
branches: [main]
paths:
- "book/**"
- ".github/workflows/book.yml"
# FALSIFY-BOOK-CLI-PARITY-001 asserts every `apr` subcommand has a chapter.
# Filtering on book/** alone meant it only ran when the BOOK changed, never
# when the CLI gained a command — so `apr beat-run` shipped in #1995 with no
# chapter and the gate stayed green for months, until an unrelated batch that
# happened to touch book/ woke it. A parity gate must run when EITHER side
# moves; watching only one of them is how it comes to certify nothing.
- "crates/apr-cli/src/commands_enum.rs"
- "crates/apr-cli/src/extended_commands.rs"
- "crates/apr-cli/src/tool_commands.rs"
pull_request:
branches: [main]
paths:
- "book/**"
- ".github/workflows/book.yml"
- "crates/apr-cli/src/commands_enum.rs"
- "crates/apr-cli/src/extended_commands.rs"
- "crates/apr-cli/src/tool_commands.rs"
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
build:
name: Build Book
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- name: Install mdBook
run: |
mkdir -p ~/bin
curl -sSL https://github.com/rust-lang/mdBook/releases/download/v0.4.40/mdbook-v0.4.40-x86_64-unknown-linux-gnu.tar.gz | tar -xz -C ~/bin
echo "$HOME/bin" >> $GITHUB_PATH
- name: Build book
run: mdbook build book
# BOOK-CLOSEOUT-001 § Phase 1: shell-script quality (per CLAUDE.md, use bashrs not shellcheck)
- name: bashrs lint book check scripts (FALSIFY-BOOK-SHELL-QUALITY-001)
run: |
cargo install bashrs --locked --quiet
# Lint only check scripts; gen-*-stubs.sh contain markdown heredocs with em-dashes
# that bashrs flags as SC1100, but those are intentional in the generated book output.
bashrs lint scripts/check_book_*.sh 2>&1 | tee /tmp/bashrs.log
! grep -qE "Summary: [1-9][0-9]* error" /tmp/bashrs.log
# BOOK-CLOSEOUT-001 § Phase 1: zero broken file links
- name: Linkcheck gate (FALSIFY-BOOK-LINKCHECK-001)
run: bash scripts/check_book_linkcheck.sh
# BOOK-CLOSEOUT-001 § Phase 4: every CLI subcommand has a chapter
- name: CLI parity gate (FALSIFY-BOOK-CLI-PARITY-001)
run: |
# apr CLI binary needed for parity check
cargo install --path crates/apr-cli --locked --quiet
bash scripts/check_book_cli_parity.sh
# BOOK-CLOSEOUT-001 § Phase 4: every CLI stub has a runnable example
- name: CLI example-block gate (FALSIFY-BOOK-EXAMPLE-001)
run: bash scripts/check_book_example_block.sh
# BOOK-CLOSEOUT-001 § Phase 3: every aprender-core public module has a chapter
- name: Library parity gate (FALSIFY-BOOK-LIB-PARITY-001)
run: bash scripts/check_book_lib_parity.sh
# BOOK-CLOSEOUT-001 § Phase 3: every lib stub has a runnable rust example
- name: Library example-block gate (FALSIFY-BOOK-LIB-EXAMPLE-001)
run: bash scripts/check_book_lib_example_block.sh
# BOOK-CLOSEOUT-001 § Phase 4: pmat comply gates all book contracts together
# (single check that asserts is_compliant=true; ties the linkcheck +
# parity + example gates into one contract surface)
- name: pmat comply gate (FALSIFY-BOOK-COMPLY-001)
run: |
# Install pmat if not present (most CI runners have it cached)
if ! command -v pmat >/dev/null 2>&1; then
cargo install pmat --locked --quiet || true
fi
# Validate the book-completeness contract via pv.
#
# This line used to call a bare `pv` and exited 127 (command not found)
# the first time the step ever ran: every earlier run died at the parity
# gate above, so nothing reached it. Note the shape of the bug — the step
# guards `pmat` with `command -v` and a comment saying it "tolerates
# absence", then invokes `pv` unguarded one line earlier, in a step whose
# entire purpose is running pv.
#
# `pv` is IN-TREE (crates/aprender-contracts-cli, [[bin]] name = "pv"), so
# build it from the tree instead of depending on an installed copy — that
# is the dogfood rule in CLAUDE.md, and it cannot drift from the contracts
# it is validating.
cargo run --quiet -p aprender-contracts-cli --bin pv -- \
validate contracts/apr-book-completeness-v1.yaml
# pmat comply check — single binary signal; tolerates absence (pmat may not be available on every runner)
if command -v pmat >/dev/null 2>&1; then
pmat comply check 2>&1 | tail -10 || echo "::warning::pmat comply check returned non-zero (advisory)"
else
echo "::warning::pmat not available — skipping comply gate (advisory)"
fi
- name: Upload artifact
uses: actions/upload-pages-artifact@v5
with:
path: ./book/book
deploy:
name: Deploy to GitHub Pages
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5