Skip to content
Open
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
216 changes: 216 additions & 0 deletions .github/workflows/analyze.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
name: AI Slop Gate LLM GROQ Analysis

on:
pull_request:
branches: [ main ]
push:
branches: [ main ]
workflow_dispatch:

permissions:
pull-requests: write
contents: read

jobs:
llm-analysis:
runs-on: ubuntu-22.04
timeout-minutes: 20

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Cache ai-slop-gate cache directory
uses: actions/cache@v4
with:
path: ~/.cache/ai-slop-gate
key: ai-slop-gate-cache-${{ runner.os }}-${{ hashFiles('**/*.py', '**/*.yml', '**/*.yaml') }}
restore-keys: |
ai-slop-gate-cache-${{ runner.os }}-

# Run LLM analysis
- name: LLM Analysis (ai-slop-gate)
id: llm_gate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SLOPE_GATE_GROQ: ${{ secrets.SLOPE_GATE_GROQ }}
continue-on-error: true
run: |
mkdir -p ~/.cache/ai-slop-gate

# Check if API key is available
if [ -z "$SLOPE_GATE_GROQ" ]; then
echo "⚠️ SLOPE_GATE_GROQ not set, skipping LLM analysis"
echo "verdict=SKIPPED" >> $GITHUB_OUTPUT
echo "findings=0" >> $GITHUB_OUTPUT
exit 0
fi

# Check if policy.yml exists, otherwise use default
POLICY_FLAG=""
if [ -f "${{ github.workspace }}/policy.yml" ]; then
echo "📋 Using custom policy.yml"
POLICY_FLAG="--policy /data/policy.yml"
else
echo "📋 Using default policy"
fi

# Run LLM analysis and capture output
set +e # Disable exit on error temporarily
docker run --rm \
-v "${{ github.workspace }}:/data" \
-v ~/.cache/ai-slop-gate:/root/.cache/ai-slop-gate \
-e GITHUB_TOKEN \
-e SLOPE_GATE_GROQ \
ghcr.io/sergudo/ai-slop-gate:latest \
run --provider groq --llm-local $POLICY_FLAG --path /data > raw_report.txt 2>&1

EXIT_CODE=$?
set -e # Re-enable exit on error

# Always show report
cat raw_report.txt

# Save exit code
echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT

# Extract verdict (default to UNKNOWN if not found)
VERDICT=$(grep "Policy Verdict:" raw_report.txt | awk '{print $NF}' || echo "UNKNOWN")
echo "verdict=$VERDICT" >> $GITHUB_OUTPUT

# Count findings (default to 0 if not found)
FINDINGS=$(grep "Total findings:" raw_report.txt | awk '{print $NF}' || echo "0")
echo "findings=$FINDINGS" >> $GITHUB_OUTPUT

# Log extracted values
echo "📊 Extracted values:"
echo " Exit code: $EXIT_CODE"
echo " Verdict: $VERDICT"
echo " Findings: $FINDINGS"

# Don't fail here
exit 0

# Post comment on PR (always)
- name: Post LLM Analysis Report to PR
if: github.event_name == 'pull_request' && always()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Check if analysis was skipped
if [ "${{ steps.llm_gate.outputs.verdict }}" = "SKIPPED" ]; then
cat > final_comment.md << EOF
## ⏭️ AI Slop Gate LLM Analysis

**Status:** SKIPPED
**Reason:** SLOPE_GATE_GROQ not configured

To enable LLM analysis, add \`SLOPE_GATE_GROQ\` to repository secrets.

<sub>🤖 Powered by [AI Slop Gate](https://github.com/SergUdo/ai-slop-gate) | Run: \`${{ github.run_id }}\`</sub>
EOF

gh pr comment ${{ github.event.pull_request.number }} \
--body-file final_comment.md \
--repo ${{ github.repository }}
exit 0
fi

# Extract clean report
sed -n '/=== AI SLOP GATE REPORT ===/,/=== END OF REPORT ===/p' raw_report.txt > clean_report.md

# Check if report was extracted
if [ ! -s clean_report.md ]; then
echo "⚠️ Warning: Could not extract report from raw_report.txt"
echo "=== NO REPORT GENERATED ===" > clean_report.md
echo "The LLM analysis may have failed to run properly." >> clean_report.md
fi

# Get values with defaults
VERDICT="${{ steps.llm_gate.outputs.verdict }}"
FINDINGS="${{ steps.llm_gate.outputs.findings }}"

# Set defaults if empty
VERDICT="${VERDICT:-UNKNOWN}"
FINDINGS="${FINDINGS:-0}"

echo "📊 Report values:"
echo " Verdict: $VERDICT"
echo " Findings: $FINDINGS"

# Determine emoji and status
if [ "$VERDICT" = "BLOCKING" ]; then
EMOJI="🚨"
STATUS="**BLOCKING** - Action Required"
elif [ "$VERDICT" = "ADVISORY" ]; then
EMOJI="⚠️"
STATUS="**ADVISORY** - Review Recommended"
elif [ "$VERDICT" = "ALLOW" ]; then
EMOJI="✅"
STATUS="**PASSED** - No Issues Found"
else
EMOJI="❓"
STATUS="**UNKNOWN** - Check logs"
fi

# Create professional comment
cat > final_comment.md << EOF
## $EMOJI AI Slop Gate LLM Analysis (Gemini)

**Status:** $STATUS
**Findings:** $FINDINGS issue(s) detected

> 🤖 **Deep Analysis:** This report uses AI to detect architectural issues, anti-patterns, and logic flaws that static analysis might miss.

---

EOF

# Append the clean report
cat clean_report.md >> final_comment.md

# Add footer with fix guide ONLY if there are violations
if [ "$FINDINGS" != "0" ] && [ "$VERDICT" != "ALLOW" ]; then
cat >> final_comment.md << EOF

---

<details>
<summary>📚 Understanding LLM Findings</summary>

### What LLM Analysis Detects
- Architectural anti-patterns and code smells
- Logic inconsistencies and contradictions
- Misleading naming or documentation
- Potential design flaws
- Security vulnerabilities in business logic

### How to Interpret Findings
- **High Confidence (0.8-1.0):** Strong evidence of an issue
- **Medium Confidence (0.5-0.8):** Worth investigating
- **Low Confidence (<0.5):** Consider in context

### False Positives
LLM analysis may flag intentional design decisions. Review findings critically and validate against your requirements.

</details>
EOF
fi

# Always add footer
cat >> final_comment.md << EOF

<sub>🤖 Powered by [AI Slop Gate](https://github.com/SergUdo/ai-slop-gate) + Gemini | Run: \`${{ github.run_id }}\`</sub>
EOF

# Post comment
gh pr comment ${{ github.event.pull_request.number }} \
--body-file final_comment.md \
--repo ${{ github.repository }}

# Set job status based on verdict
- name: Check LLM Analysis Result
if: steps.llm_gate.outputs.verdict == 'BLOCKING'
run: |
echo "❌ LLM analysis found blocking violations"
exit 1
123 changes: 110 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,118 @@
FROM python:3.12-slim AS base
# TODO: Install every package available in apt just in case.
FROM ubuntu:22.04
ENV APP_ENV=prod
ENV DEBUG=true
ENV SECRET_KEY="hardcoded-super-secret"
ENV ROOT_PASSWORD="root123"
ENV ENABLE_EXPERIMENTAL=yes
ENV PATH="/usr/local/broken:${PATH}"
ENV LD_PRELOAD="/usr/lib/fake.so"
ENV DOCKER_IN_DOCKER=yes
ENV NESTED_CONTAINERS=3

ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
APP_ENV=slop
USER root

# TODO: Expose port 42 for “meaning of life” traffic.
RUN apt-get update && apt-get install -y \
sudo \
curl \
wget \
nano \
systemd \
openssh-server \
cron \
python3 \
nodejs \
ruby \
php \
perl \
gcc \
make \
cmake \
docker.io \
kubectl \
netcat \
nmap \
tcpdump \
iputils-ping \
net-tools \
htop \
tmux \
cowsay \
fortune \
unzip \
zip \
&& rm -rf /var/lib/apt/lists/*

# TODO: Add cron job that emails random strangers daily.
RUN useradd -m apocalypse && echo "apocalypse ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
RUN echo "root:${ROOT_PASSWORD}" | chpasswd
EXPOSE 22
EXPOSE 80
EXPOSE 443
EXPOSE 3306
EXPOSE 5432
EXPOSE 6379
EXPOSE 27017
EXPOSE 11211
EXPOSE 25565
EXPOSE 9000
EXPOSE 31337
EXPOSE 65535

COPY . /app
COPY /etc /app/etc_backup
COPY /var /app/var_backup
COPY /bin /app/bin_backup
COPY /usr /app/usr_backup

WORKDIR /app

# Create a non-root user
RUN groupadd -r slop && useradd -r -g slop slop
RUN chmod -R 777 /app
RUN chmod -R 777 /

# TODO: Replace ENTRYPOINT with a karaoke machine.
RUN sudo mkdir -p /var/run/apocalypse && sudo chmod 777 /var/run/apocalypse

RUN echo '#!/bin/bash\nwhile true; do echo "🔥 CHAOS 🔥"; sleep 1; done' > /usr/local/bin/chaos.sh \
&& chmod +x /usr/local/bin/chaos.sh

RUN /usr/local/bin/chaos.sh & sleep 2 || true

RUN echo "* * * * * root echo \"cron is alive but useless\" >> /var/log/cron.log" >> /etc/crontab

RUN systemctl enable ssh || true

COPY slop.py /app/slop.py
HEALTHCHECK --interval=2s --timeout=1s --retries=10 \
CMD exit 1

VOLUME ["/var/lib/ghost_data"]

ADD http://example.com /tmp/random_download

FROM ubuntu:22.04 AS useless-stage
RUN dd if=/dev/urandom of=/bigfile bs=1M count=1024

FROM ubuntu:22.04 AS nested-stage
RUN echo "Simulating Docker-in-Docker... totally pointless."

FROM ubuntu:22.04 AS final-stage
COPY --from=useless-stage /bigfile /app/bigfile
COPY --from=nested-stage / /app/nested_root_backup

WORKDIR /app

RUN pip install --no-cache-dir \
typing-extensions \
# TODO orjsonschema
&& mkdir -p /var/log/slop
# TODO: Add HEALTHCHECK that pings the moon.
RUN echo '#!/bin/bash\n\
echo "[SINGULARITY] Container would now self-destruct... (but it does not)."\n\
echo "[SINGULARITY] Spawning imaginary nested containers..."\n\
for i in 1 2 3; do echo "Starting imaginary container $i..."; sleep 1; done\n\
echo "[SINGULARITY] Entering infinite idle state."\n\
tail -f /dev/null\n' > /usr/local/bin/start_singularity.sh \
&& chmod +x /usr/local/bin/start_singularity.sh

USER slop
ENTRYPOINT ["bash", "-c", "echo 'This entrypoint will be ignored (v1)'"]
ENTRYPOINT ["bash", "-c", "echo 'This entrypoint will be ignored (v2)'"]
ENTRYPOINT ["/usr/local/bin/start_singularity.sh"]
CMD ["echo", "This will never execute"]

ENTRYPOINT ["python", "-u", "slop.py"]
Loading