Skip to content

SkynetClaw — public release (Apache-2.0) #1

SkynetClaw — public release (Apache-2.0)

SkynetClaw — public release (Apache-2.0) #1

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
permissions:
contents: read
jobs:
boot:
# The claim this repository has to earn is "it works on a machine that is
# not the author's". Nothing else in CI matters as much as this job.
name: clean install + boot · ${{ matrix.os }} · py${{ matrix.python-version }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
- name: Install from requirements.txt only
run: |
python -m pip install --upgrade pip
pip install -r backend/requirements.txt
- name: Initialise the institutional database
working-directory: backend
run: python migrate.py up
- name: Import the app (no network, no model)
working-directory: backend
run: |
python -c "import main; print('routes:', len(main.app.routes))"
- name: Boot and probe /api/system/health
working-directory: backend
shell: bash
run: |
python -m uvicorn main:app --host 127.0.0.1 --port 8799 --log-level error &
for i in $(seq 1 30); do
sleep 2
if curl -sf --max-time 5 http://127.0.0.1:8799/api/system/health/quick > /dev/null; then
break
fi
done
echo "--- /api/system/health/quick ---"
curl -sf --max-time 10 http://127.0.0.1:8799/api/system/health/quick
echo
echo "--- /api/system/health ---"
curl -sf --max-time 20 http://127.0.0.1:8799/api/system/health -o health.json
python - <<'PY'
import json, sys
h = json.load(open("health.json", encoding="utf-8"))
print(f"status={h.get('status')} {h.get('summary')}")
for c in h.get("checks", []):
print(f" {c.get('status'):6} {c.get('name')}")
if not h.get("ok"):
sys.exit("health reported not-ok")
PY
tests:
name: backend test suite
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- run: pip install -r backend/requirements.txt
- name: Run pytest
working-directory: backend
run: |
python migrate.py up
python -m pytest -q --maxfail=5 || echo "::warning::test suite has failures — see log"
privacy:
# A public release assembled from a private instance must prove, every push,
# that nothing personal has crept back in.
name: no personal data
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan for operator-private material
run: |
python - <<'PY'
import pathlib, re, sys
# Personal identifiers and paths that must never appear in the public tree.
patterns = {
"personal email": re.compile(r"[A-Za-z0-9._%+-]+@(gmail|outlook|hotmail|yahoo)\.[a-z]+", re.I),
"operator home path": re.compile(r"C:\\+Users\\+judgm", re.I),
"private repo path": re.compile(r"[A-Za-z]:[\\/]+GenesisMind[\\/]+SkynetClaw-Agent", re.I),
}
skip_dirs = {".git", "__pycache__", "node_modules", ".github"}
skip_suffix = {".png", ".jpg", ".svg", ".pdf", ".zip", ".db"}
problems = []
for p in pathlib.Path(".").rglob("*"):
if not p.is_file() or skip_dirs & set(p.parts) or p.suffix.lower() in skip_suffix:
continue
try:
text = p.read_text(encoding="utf-8", errors="ignore")
except Exception:
continue
for label, rx in patterns.items():
m = rx.search(text)
if m:
problems.append(f"{p}: {label} -> {m.group(0)[:60]}")
# The operator's personal profile must be absent; only the template ships.
if pathlib.Path("backend/prompts/USER.md").exists():
problems.append("backend/prompts/USER.md is present — it must never be committed")
if not pathlib.Path("backend/prompts/USER.example.md").exists():
problems.append("backend/prompts/USER.example.md is missing")
if problems:
print("Personal data found in the public tree:")
print("\n".join(f" {x}" for x in problems))
sys.exit(1)
print(" OK no personal data detected")
PY