All checks were successful
C++ Tests / test-fast (pull_request) Successful in 2m2s
API Docs / doc-build (pull_request) Successful in 1m8s
Markdown link check / check (pull_request) Successful in 52s
C++ Tests / test-cgal (pull_request) Has been skipped
C++ Tests / quality-gates (pull_request) Successful in 1m59s
Refresh CLAUDE.md for v0.10.0 (3 CI jobs incl. disabled test-cgal,
compile-time option matrix, reviewer/pages docs, agentic + token-hygiene
workflow patterns) and condense the historical Phase-8/audit logs to
pointers.
Add the documentation-pass process so the single-source-of-truth rules
stay enforced:
* scripts/quality/check-doc-freshness.sh — string-only drift gate
(version/date across CITATION/CHANGELOG/CLAUDE, doc-map count), <1 s,
registered in run-all.sh + quality README.
* doc/release-policy.md — "Documentation passes" subsection (triggers +
docs:sync rule); fix stale Phase-milestone mapping (v0.10.0 was
reviewer-ready, 9c→v0.11.0) and the test-cgal CI mention.
Add shared Claude config (un-ignore the two files only):
* .claude/settings.json — permission allowlist for safe repo commands.
* .claude/token-hygiene.md — Tier-3 cache-discipline user guide that
CLAUDE.md instructs Claude to remind the user about.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
101 lines
3.8 KiB
Bash
Executable File
101 lines
3.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# scripts/quality/check-doc-freshness.sh
|
|
#
|
|
# Cheap, string-only documentation-freshness gate. Catches the cross-file
|
|
# drift that a "documentation pass" (see doc/release-policy.md) is meant to
|
|
# prevent — without building anything, so it runs in well under a second.
|
|
#
|
|
# Invariants checked:
|
|
# 1. Release version agrees across CITATION.cff, CHANGELOG.md (newest
|
|
# section) and CLAUDE.md ("Current release:" line).
|
|
# 2. Release date agrees across CITATION.cff and CHANGELOG.md.
|
|
# 3. The "N documents across ..." count in CLAUDE.md's Documentation map
|
|
# equals the actual number of doc/**/*.md files.
|
|
#
|
|
# NOT checked here (they need a build — run them as part of the release
|
|
# documentation pass, see doc/release-policy.md):
|
|
# * doc/api/tests.md counts → scripts/check-test-counts.sh (needs BUILD_DIR)
|
|
# * doc/api/headers.md regeneration → scripts/gen-headers-md.py (needs Doxygen XML)
|
|
#
|
|
# Usage:
|
|
# bash scripts/quality/check-doc-freshness.sh
|
|
#
|
|
# Exit codes:
|
|
# 0 all string invariants hold
|
|
# 1 at least one drift found
|
|
# 2 prerequisite missing (a required file is absent)
|
|
|
|
set -uo pipefail
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
cd "$ROOT" || exit 2
|
|
|
|
for f in CITATION.cff CHANGELOG.md CLAUDE.md; do
|
|
if [ ! -f "$f" ]; then
|
|
echo "FAIL: required file not found: $f" >&2
|
|
exit 2
|
|
fi
|
|
done
|
|
|
|
fail=0
|
|
note() { printf ' %-4s %s\n' "$1" "$2"; }
|
|
|
|
# Strip an optional leading "v" so "v0.10.0" and "0.10.0" compare equal.
|
|
strip_v() { printf '%s' "${1#v}"; }
|
|
|
|
# ── Invariant 1 + 2: version & date triple ──────────────────────────────────
|
|
cit_ver=$(strip_v "$(grep -E '^version:' CITATION.cff | head -1 | awk '{print $2}')")
|
|
cit_date=$(grep -E '^date-released:' CITATION.cff | head -1 | awk '{print $2}')
|
|
|
|
chg_header=$(grep -m1 -E '^## \[' CHANGELOG.md)
|
|
chg_ver=$(strip_v "$(printf '%s' "$chg_header" | sed -E 's/^## \[([^]]+)\].*/\1/')")
|
|
chg_date=$(printf '%s' "$chg_header" | grep -oE '[0-9]{4}-[0-9]{2}-[0-9]{2}' | head -1)
|
|
|
|
claude_ver=$(strip_v "$(grep -m1 'Current release:' CLAUDE.md | sed -E 's/.*\*\*(v?[0-9][0-9.]*)\*\*.*/\1/')")
|
|
|
|
echo "── version / date consistency ──"
|
|
note "CIT" "CITATION.cff version=$cit_ver date=$cit_date"
|
|
note "CHG" "CHANGELOG.md version=$chg_ver date=$chg_date"
|
|
note "CLD" "CLAUDE.md version=$claude_ver"
|
|
|
|
if [ "$cit_ver" = "$chg_ver" ] && [ "$cit_ver" = "$claude_ver" ]; then
|
|
note "OK" "version agrees ($cit_ver)"
|
|
else
|
|
note "DRIFT" "version mismatch: CITATION=$cit_ver CHANGELOG=$chg_ver CLAUDE=$claude_ver"
|
|
fail=1
|
|
fi
|
|
|
|
if [ "$cit_date" = "$chg_date" ]; then
|
|
note "OK" "date agrees ($cit_date)"
|
|
else
|
|
note "DRIFT" "date mismatch: CITATION=$cit_date CHANGELOG=$chg_date"
|
|
fail=1
|
|
fi
|
|
|
|
# ── Invariant 3: documentation-map count ────────────────────────────────────
|
|
stated=$(grep -m1 -E '^[0-9]+ documents across' CLAUDE.md | awk '{print $1}')
|
|
actual=$(find doc -name '*.md' -type f | wc -l | tr -d ' ')
|
|
|
|
echo
|
|
echo "── documentation-map count ──"
|
|
note "CLD" "CLAUDE.md states: $stated documents"
|
|
note "DISK" "doc/**/*.md on disk: $actual"
|
|
if [ "$stated" = "$actual" ]; then
|
|
note "OK" "doc count agrees ($actual)"
|
|
else
|
|
note "DRIFT" "CLAUDE.md says $stated, disk has $actual — update the 'N documents across' line"
|
|
fail=1
|
|
fi
|
|
|
|
echo
|
|
if [ "$fail" -ne 0 ]; then
|
|
echo "FAIL: documentation drift detected."
|
|
echo "Recovery: run a documentation pass (see doc/release-policy.md →"
|
|
echo " 'Documentation passes'); fix the lines above, then re-run."
|
|
exit 1
|
|
fi
|
|
|
|
echo "OK: documentation strings are consistent."
|
|
echo "Reminder: at release also run scripts/check-test-counts.sh and"
|
|
echo " scripts/gen-headers-md.py (both need a build)."
|
|
exit 0
|