Files
memex/projects/verify-repl-tool/verify-repl
Amr Gharbeia c9cc874e53 tools: add repl-block, check-tangle; move existing tools into memex
New tools (projects/<tool>/ — standalone, git-committed):
- repl-block: extract and pipe lisp blocks from org files to the REPL
- check-tangle: tangle + compile in one step, reports errors

Existing tools moved from ~/.opencode/bin/ into memex (survives reinstalls):
- repl, tangle, org-eval, verify-repl

AGENTS.md updated:
- Tool reference table with all 7 tools
- Package reference table for passepartout and cl-tty
- Updated tangle command to use project-local tools

.opencode/commands/ added: check-parens, repl-block, check-tangle commands
2026-05-13 12:54:38 -04:00

141 lines
4.4 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)
BLACKLIST=(
"core-defpackage.org"
"core-manifest.org"
"core-skills.org"
"core-communication.org"
"package.lisp"
"setup.org"
)
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)
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