diff --git a/.forgejo/workflows/validate.yml b/.forgejo/workflows/validate.yml new file mode 100644 index 0000000..aee1899 --- /dev/null +++ b/.forgejo/workflows/validate.yml @@ -0,0 +1,97 @@ +name: Claim Validation +on: + pull_request: + branches: [main] + +jobs: + validate: + runs-on: docker + steps: + - uses: actions/checkout@v4 + + - name: Check Pentagon-Agent trailers + run: | + # Every commit in the PR must have a Pentagon-Agent trailer + MISSING=$(git log origin/main..HEAD --format="%H %s" | while read hash msg; do + if ! git log -1 --format="%B" $hash | grep -q "^Pentagon-Agent:"; then + echo "$hash: $msg" + fi + done) + if [ -n "$MISSING" ]; then + echo "Commits missing Pentagon-Agent trailer:" + echo "$MISSING" + exit 1 + fi + + - name: Validate claim YAML frontmatter + run: | + # Check all new/modified .md files have valid frontmatter + FILES=$(git diff --name-only origin/main...HEAD -- '*.md') + for f in $FILES; do + if [ -f "$f" ] && head -1 "$f" | grep -q "^---"; then + # Has frontmatter — check required fields for claims + if grep -q "^type: claim" "$f"; then + for field in domain description confidence source created; do + if ! grep -q "^${field}:" "$f"; then + echo "FAIL: $f missing required field: $field" + exit 1 + fi + done + fi + fi + done + + - name: Check wiki link targets exist + run: | + # Extract all [[links]] from changed files and verify targets exist + FILES=$(git diff --name-only origin/main...HEAD -- '*.md') + BROKEN="" + for f in $FILES; do + if [ -f "$f" ]; then + links=$(grep -oP '\[\[([^\]]+)\]\]' "$f" | sed 's/\[\[//;s/\]\]//' || true) + for link in $links; do + # Search for a file whose name matches the link text + FOUND=$(find . -name "*.md" -path "*${link}*" 2>/dev/null | head -1) + if [ -z "$FOUND" ]; then + BROKEN="$BROKEN\n $f -> [[$link]]" + fi + done + fi + done + if [ -n "$BROKEN" ]; then + echo "Broken wiki links found:$BROKEN" + echo "(WARNING — not blocking merge, but flagged for review)" + fi + + - name: Territory check + run: | + # Verify agents only modify files in their territory + AGENT=$(git log -1 --format="%B" HEAD | grep "^Pentagon-Agent:" | sed 's/Pentagon-Agent: \(.*\) <.*/\1/' | tr '[:upper:]' '[:lower:]') + if [ -z "$AGENT" ]; then exit 0; fi + + FILES=$(git diff --name-only origin/main...HEAD) + case "$AGENT" in + rio) TERRITORY="domains/internet-finance/ agents/rio/ inbox/" ;; + clay) TERRITORY="domains/entertainment/ agents/clay/ inbox/" ;; + theseus) TERRITORY="domains/ai-alignment/ agents/theseus/ inbox/" ;; + vida) TERRITORY="domains/health/ agents/vida/ inbox/" ;; + astra) TERRITORY="domains/space-development/ agents/astra/ inbox/" ;; + leo) TERRITORY="core/ foundations/ agents/leo/ inbox/ maps/" ;; + *) TERRITORY="" ;; + esac + + if [ -n "$TERRITORY" ]; then + for f in $FILES; do + ALLOWED=false + for t in $TERRITORY; do + if echo "$f" | grep -q "^$t"; then + ALLOWED=true + break + fi + done + if [ "$ALLOWED" = false ]; then + echo "TERRITORY VIOLATION: $AGENT modified $f (outside allowed: $TERRITORY)" + exit 1 + fi + done + fi \ No newline at end of file