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
190 changes: 190 additions & 0 deletions .github/workflows/analyze.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
name: AI Slop Gate Static Analysis

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

permissions:
pull-requests: write
contents: read

jobs:
static-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 static analysis
- name: Static Analysis (ai-slop-gate)
id: static_gate
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
continue-on-error: true
run: |
mkdir -p ~/.cache/ai-slop-gate

# 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 static 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 \
ghcr.io/sergudo/ai-slop-gate:latest \
run --provider static $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 for later steps
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 - let continue-on-error handle it
exit 0

# Post comment on PR (always, not just on failure)
- name: Post Static Analysis Report to PR
if: github.event_name == 'pull_request' && always()
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# 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 static analysis may have failed to run properly." >> clean_report.md
fi

# Get values with defaults
VERDICT="${{ steps.static_gate.outputs.verdict }}"
FINDINGS="${{ steps.static_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 based on verdict
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 Static Analysis

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

---

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>📚 How to fix common issues</summary>

### Hardcoded Secrets
1. Move secrets to environment variables or secret management system
2. Use \`.env\` files (add to \`.gitignore\`)
3. For CI/CD, use GitHub Secrets or similar

### Dangerous Functions
1. Review usage of \`eval()\`, \`exec()\`, \`system()\`
2. Sanitize all user inputs
3. Use safer alternatives (parameterized queries, safe APIs)

### SQL Injection
1. Use parameterized queries/prepared statements
2. Never concatenate user input into SQL strings
3. Use ORM frameworks when possible

### TODOs
1. Complete or document security-related TODOs
2. Create issues for tracking
3. Remove completed TODOs

</details>
EOF
fi

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

<sub>🤖 Powered by [AI Slop Gate](https://github.com/SergUdo/ai-slop-gate) | 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 Static Analysis Result
if: steps.static_gate.outputs.verdict == 'BLOCKING'
run: |
echo "❌ Static 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