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
8 changes: 8 additions & 0 deletions .github/workflows/quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,11 @@ jobs:
else
echo "✅ Core documentation present"
fi

# The check above tests that doc files *exist*; this tests they *parse*.
# Ruby ships preinstalled on ubuntu-latest, so no setup action is needed.
- name: Install asciidoctor
run: gem install asciidoctor --no-document

- name: Check every .adoc renders
run: ./scripts/check-docs-render.sh .
19 changes: 18 additions & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ test-all: test e2e aspect bench readiness
@echo "All test categories passed — safe to merge!"

# Run all quality checks
quality: fmt-check lint test
quality: fmt-check lint docs-check test
@echo "All quality checks passed!"

# Fix all auto-fixable issues [reversible: git checkout]
Expand Down Expand Up @@ -281,6 +281,23 @@ docs:
just man
@echo "Documentation generated in docs/"

# Check every .adoc actually renders (content-side counterpart to the .md ban)
docs-check:
@./scripts/check-docs-render.sh .

# Render the docs to HTML for local reading [reversible: rm -rf docs/generated/html]
docs-html:
#!/usr/bin/env bash
set -euo pipefail
if ! command -v asciidoctor >/dev/null 2>&1; then
echo "asciidoctor not found. Install with: gem install asciidoctor" >&2
exit 2
fi
mkdir -p docs/generated/html
find docs -name '*.adoc' -type f -print0 \
| xargs -0 asciidoctor -D docs/generated/html
echo "Rendered to docs/generated/html/"

# Generate justfile cookbook documentation
cookbook:
#!/usr/bin/env bash
Expand Down
5 changes: 4 additions & 1 deletion build/contractile.just
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,11 @@ dust-no-ai-djot:
dust-no-scm-files:
! find .machine_readable/ -name '*.scm' 2>/dev/null | head -1 | grep -q .

# NOTE: `{{{{` is just's escape for a literal `{{`. Writing the pattern
# unescaped makes just parse it as an interpolation and abort — which broke
# *every* recipe in the repo, not merely this one.
dust-no-placeholder-tokens:
! grep -rl '{{[A-Z_]*}}' --include='*.a2ml' --include='*.adoc' --exclude-dir='.git' . 2>/dev/null | head -1 | grep -q .
! grep -rl '{{{{[A-Z_]*}}' --include='*.a2ml' --include='*.adoc' --exclude-dir='.git' . 2>/dev/null | head -1 | grep -q .

dust-no-tracked-artifacts:
! git ls-files lib/bs/ lib/ocaml/ target/release/ _build/ zig-cache/ zig-out/ 2>/dev/null | head -1 | grep -q .
Expand Down
96 changes: 96 additions & 0 deletions scripts/check-docs-render.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# check-docs-render.sh — every .adoc must actually render.
#
# The estate rule "AsciiDoc by default" is enforced by extension
# (check-no-md-in-docs.sh). Nothing enforced that the *content* parses. A
# malformed table, an unterminated listing block, or a stray level-0 heading
# renders to silently mangled output and ships unnoticed.
#
# This renders every .adoc with --failure-level=WARN and fails on any
# diagnostic. It is the content-side counterpart to the extension-side check.
#
# Known-bad files are quarantined in ALLOWED below rather than silently
# skipped — the list is meant to shrink, and an empty list is the goal.
#
# Exit codes:
# 0 — every non-allow-listed .adoc renders without warnings
# 1 — one or more failed to render cleanly
# 2 — usage / setup error (asciidoctor missing)

set -euo pipefail

REPO_ROOT="${1:-.}"

# Quarantined: half-converted Markdown carrying an .adoc extension (a `= Title`
# line bolted onto a Markdown body — `#` headings, <!-- --> comments, | tables).
# These satisfy check-no-md-in-docs.sh by extension while still being Markdown.
# All are RSR boilerplate, not game design. Fix by converting the body properly,
# then delete the entry. Do not add game-design docs to this list.
ALLOWED=(
"docs/architecture/THREAT-MODEL.adoc"
"docs/decisions/0000-template.adoc"
"docs/decisions/0001-adopt-rsr-standard.adoc"
"docs/developer/ABI-FFI-README.adoc"
"docs/practice/AI-CONVENTIONS.adoc"
"docs/STATE-VISUALIZER.adoc"
)

if ! command -v asciidoctor >/dev/null 2>&1; then
echo "FAIL: asciidoctor not found. Install with: gem install asciidoctor" >&2
exit 2
fi

if [ ! -d "$REPO_ROOT" ]; then

Check failure on line 46 in scripts/check-docs-render.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_the-nash-equilibrium&issues=AZ9sz_uaUZIaC-8Nwnwc&open=AZ9sz_uaUZIaC-8Nwnwc&pullRequest=71
echo "FAIL: not a directory: $REPO_ROOT" >&2
exit 2
fi

mapfile -t FILES < <(find "$REPO_ROOT" -name '*.adoc' -type f -not -path '*/.git/*' | sort)

if [ ${#FILES[@]} -eq 0 ]; then

Check failure on line 53 in scripts/check-docs-render.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_the-nash-equilibrium&issues=AZ9sz_uaUZIaC-8Nwnwd&open=AZ9sz_uaUZIaC-8Nwnwd&pullRequest=71
echo "PASS: no .adoc files found (nothing to check)"
exit 0
fi

BROKEN=()
CLEAN=0
SKIPPED=0

for f in "${FILES[@]}"; do
rel="${f#"$REPO_ROOT/"}"
rel="${rel#./}"

skip=0
for allowed in "${ALLOWED[@]}"; do
if [ "$rel" = "$allowed" ]; then skip=1; break; fi

Check failure on line 68 in scripts/check-docs-render.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_the-nash-equilibrium&issues=AZ9sz_uaUZIaC-8Nwnwe&open=AZ9sz_uaUZIaC-8Nwnwe&pullRequest=71
done
if [ $skip -eq 1 ]; then

Check failure on line 70 in scripts/check-docs-render.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_the-nash-equilibrium&issues=AZ9sz_uaUZIaC-8Nwnwf&open=AZ9sz_uaUZIaC-8Nwnwf&pullRequest=71
SKIPPED=$((SKIPPED + 1))
continue
fi

if out=$(asciidoctor --failure-level=WARN -o /dev/null "$f" 2>&1) && [ -z "$out" ]; then

Check failure on line 75 in scripts/check-docs-render.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_the-nash-equilibrium&issues=AZ9sz_uaUZIaC-8Nwnwg&open=AZ9sz_uaUZIaC-8Nwnwg&pullRequest=71
CLEAN=$((CLEAN + 1))
else
BROKEN+=("$rel")
BROKEN+=("$(echo "$out" | sed 's/^/ /')")
fi
done

if [ ${#BROKEN[@]} -eq 0 ]; then

Check failure on line 83 in scripts/check-docs-render.sh

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use '[[' instead of '[' for conditional tests. The '[[' construct is safer and more feature-rich.

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_the-nash-equilibrium&issues=AZ9sz_uaUZIaC-8Nwnwh&open=AZ9sz_uaUZIaC-8Nwnwh&pullRequest=71
echo "PASS: $CLEAN .adoc files render cleanly (${SKIPPED} quarantined in ALLOWED)"
exit 0
fi

echo "FAIL: $(( ${#BROKEN[@]} / 2 )) .adoc file(s) do not render cleanly:" >&2
for ((i = 0; i < ${#BROKEN[@]}; i += 2)); do
echo " - ${BROKEN[i]}" >&2
echo "${BROKEN[i + 1]}" >&2
done
echo "" >&2
echo "Fix the markup, or — only for pre-existing boilerplate — add a justified" >&2
echo "entry to the ALLOWED list in scripts/check-docs-render.sh." >&2
exit 1
Loading