Skip to content

Merge feat/loop-buildout: Phase 1 — close audit's confirmed defects #64

Merge feat/loop-buildout: Phase 1 — close audit's confirmed defects

Merge feat/loop-buildout: Phase 1 — close audit's confirmed defects #64

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
- name: Lint with flake8 (fatal errors only)
run: |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude=.venv,migrations
- name: Check imports
run: |
python -c "import gateway; print('gateway OK')" || true
python -c "import runtime; print('runtime OK')" || true
typecheck:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
- name: Run mypy
# Non-blocking for now: the codebase is being type-annotated
# incrementally. Per-module strictness lives in pyproject.toml.
run: |
mypy --config-file pyproject.toml || true
docstrings:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
- name: Run interrogate (docstring coverage)
run: |
interrogate -c pyproject.toml runtime gateway hivemind || true
test:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
- name: Run tests with coverage
run: |
python -m pytest tests/ -v --tb=short \
--cov=runtime --cov=gateway --cov=hivemind \
--cov-report=term-missing --cov-report=xml
env:
PYTHONPATH: .
- name: Upload coverage artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: coverage-xml
path: coverage.xml
if-no-files-found: ignore
security:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
- name: Audit dependencies with pip-audit
# Non-blocking: the dependency tree includes upstream advisories
# we cannot patch ourselves; this surfaces them in CI logs.
run: |
pip-audit --strict || true
- name: Bandit security scan
run: |
bandit -r runtime/ gateway/ hivemind/ -ll --skip B101,B603,B607 -f txt || true
- name: Check for hardcoded secrets
run: |
grep -rn "YOUR_" --include="*.json" . | grep -v ".example" | grep -v "node_modules" && echo "WARNING: Possible non-example config with placeholder keys" || echo "No hardcoded secrets found"
# ------------------------------------------------------ noop / boundary posture
# The PUBLIC repo must prove it ships the OBSERVE no-op security posture and
# leaks no private rules: morpheus_security is NOT vendored, the seam
# degrades to a noop, and the Phase-7 operator tools stay green. This is the
# public-repo contract from INVARIANTS I-12 (public/private boundary).
noop-posture:
runs-on: ubuntu-latest
needs: lint
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt -r requirements-dev.txt
- name: Assert the private security package is NOT vendored
run: |
if [ -d morpheus_security ] || find . -path ./.git -prune -o -name 'morpheus.py' -path '*morpheus_security*' -print | grep -q .; then
echo "FAIL: morpheus_security appears vendored into the PUBLIC repo — boundary I-12 violated."
exit 1
fi
echo "OK: morpheus_security is not vendored (seam-only)."
- name: Assert the security seam degrades to OBSERVE no-op
env:
PYTHONPATH: .
run: |
python -c "
from runtime.security import SECURITY_BACKEND, get_app_attest_verifier
assert SECURITY_BACKEND == 'noop', f'expected noop backend, got {SECURITY_BACKEND!r}'
v = get_app_attest_verifier({})
print('OK: security backend =', SECURITY_BACKEND, '(inert OBSERVE no-op)')
"
- name: Route table is not stale (Phase-7 generator)
env:
PYTHONPATH: .
run: python scripts/generate_route_table.py --check
- name: ABI verification audit has no doc/source drift
env:
PYTHONPATH: .
run: python scripts/verify_abis.py --strict
- name: gateway.doctor reports a consistent posture (read-only)
env:
PYTHONPATH: .
run: python -m gateway.doctor
docker:
runs-on: ubuntu-latest
needs: [lint, test]
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image
uses: docker/build-push-action@v6
with:
context: .
push: false
load: true
tags: opnmatrx-gateway:ci
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Smoke test container
# Boot the gateway, hit /health, and make sure it returns 200.
run: |
set -e
cid=$(docker run -d --rm -p 18790:18790 opnmatrx-gateway:ci)
trap "docker kill $cid >/dev/null 2>&1 || true" EXIT
# Give the gateway a few seconds to bind.
for i in 1 2 3 4 5 6 7 8 9 10; do
if curl -fsS http://localhost:18790/health >/dev/null; then
echo "Gateway responded on attempt $i"
exit 0
fi
sleep 2
done
echo "Gateway did not respond to /health within timeout"
docker logs $cid || true
exit 1