Files
memex/projects/verify-repl-tool/verify-repl
Amr Gharbeia 18b289dff8 fix: tool bugs found in review audit
repl:  env var was dead code (hardcoded 2s), empty frame gave misleading error
check-tangle: show full SBCL output on compile failure, not filtered
verify-repl: blacklist now configurable via VERIFY_REPL_EXCLUDE env var;
  regex tightened to ';; +REPL-VERIFIED:' from ';;.REPL.VERIFIED:' (ambiguous)
org-eval: 1-based indexing to match repl-block; errors on out-of-range; errors on <1
2026-05-13 13:09:50 -04:00

150 lines
4.7 KiB
Bash
Executable File

#!/bin/bash
# verify-repl — compliance checker for the OpenCode Engineering Discipline
#
# Usage: verify-repl <org-directory>
# Scans all .org files in the given directory for violations of:
# 1. REPL-First: every (defun|defmacro|defvar|defparameter|defstruct|defmethod|defclass)
# block must have ";; REPL-VERIFIED:" on the line above #+begin_src lisp
# 2. One-per-block: each #+begin_src lisp block must contain exactly one top-level form
# 3. Prose-before-code: each code block must be preceded by an Org headline
#
# Returns 0 if all checks pass, 1 if violations found.
set -euo pipefail
ORG_DIR="${1:-}"
if [ -z "$ORG_DIR" ] || [ ! -d "$ORG_DIR" ]; then
echo "Usage: verify-repl <org-directory>"
exit 1
fi
VIOLATIONS=0
FILES_CHECKED=0
# Blacklist: files exempt from REPL verification (core infrastructure, tests)
# Override with $VERIFY_REPL_EXCLUDE (space-separated filenames).
# Example: VERIFY_REPL_EXCLUDE="setup.org package.lisp" verify-repl org/
DEFAULT_BLACKLIST=(
"core-defpackage.org"
"core-manifest.org"
"core-skills.org"
"core-communication.org"
"package.lisp"
"setup.org"
)
if [ -n "${VERIFY_REPL_EXCLUDE:-}" ]; then
IFS=' ' read -ra BLACKLIST <<< "$VERIFY_REPL_EXCLUDE"
else
BLACKLIST=("${DEFAULT_BLACKLIST[@]}")
fi
is_blacklisted() {
local fname
fname=$(basename "$1")
for bl in "${BLACKLIST[@]}"; do
[ "$fname" = "$bl" ] && return 0
done
return 1
}
check_file() {
local file="$1"
local fname
fname=$(basename "$file")
local in_block=0
local block_start=0
local prev_line=""
local prev_was_headline=0
local block_content=""
local line_no=0
local has_repl_verify=0
local def_count=0
local violations_in_file=0
is_blacklisted "$file" && return 0
FILES_CHECKED=$((FILES_CHECKED + 1))
while IFS= read -r line || [ -n "$line" ]; do
line_no=$((line_no + 1))
local trimmed="${line#"${line%%[![:space:]]*}"}"
# Track headlines
if echo "$trimmed" | grep -qE '^\*+[[:space:]]'; then
prev_was_headline=1
fi
# Enter code block
if echo "$trimmed" | grep -qE '^#\+begin_src[[:space:]]+lisp'; then
in_block=1
block_start=$line_no
block_content=""
def_count=0
has_repl_verify=0
# Check for REPL-VERIFIED comment on previous line(s)
# Matches ";; REPL-VERIFIED:" or ";; REPL-VERIFIED:" etc.
if echo "$prev_line" | grep -qE ';; +REPL[-_]VERIFIED:'; then
has_repl_verify=1
fi
# Check for prose requirement: was there a headline before this block?
if [ "$prev_was_headline" -eq 0 ]; then
echo " $fname:$block_start: PROSE-BEFORE-CODE: no Org headline before code block"
violations_in_file=$((violations_in_file + 1))
fi
fi
# Inside code block: collect content
if [ "$in_block" -eq 1 ]; then
if echo "$trimmed" | grep -qE '^#\+end_src'; then
in_block=0
# Check: REPL verification for definition blocks
if [ "$def_count" -gt 0 ] && [ "$has_repl_verify" -eq 0 ]; then
echo " $fname:$block_start: REPL-FIRST: $(if [ "$def_count" -gt 1 ]; then echo "$def_count definitions"; else echo "defun/defmacro"; fi) without REPL-VERIFIED comment"
violations_in_file=$((violations_in_file + 1))
fi
# Check: one-per-block
if [ "$def_count" -gt 1 ]; then
echo " $fname:$block_start: ONE-PER-BLOCK: $def_count definitions in a single block (must be exactly 1)"
violations_in_file=$((violations_in_file + 1))
fi
prev_was_headline=0
block_content=""
else
# Count definitions in block
if echo "$trimmed" | grep -qE '^\((defun|defmacro|defvar|defparameter|defstruct|defmethod|defclass)[[:space:](]'; then
def_count=$((def_count + 1))
fi
fi
fi
prev_line="$line"
done < "$file"
if [ "$violations_in_file" -gt 0 ]; then
echo "$fname: $violations_in_file violation(s)"
VIOLATIONS=$((VIOLATIONS + violations_in_file))
fi
}
echo "=== REPL Compliance Check ==="
echo "Directory: $ORG_DIR"
echo ""
for file in "$ORG_DIR"/*.org; do
[ -f "$file" ] || continue
check_file "$file"
done
echo ""
echo "Files checked: $FILES_CHECKED"
echo "Violations: $VIOLATIONS"
if [ "$VIOLATIONS" -eq 0 ]; then
echo "Status: ✓ PASS — all checks satisfied"
exit 0
else
echo "Status: ✗ FAIL — fix violations before committing"
exit 1
fi