Skip to content

fix(review): 16-agent release-readiness review and hardening (#131) #718

fix(review): 16-agent release-readiness review and hardening (#131)

fix(review): 16-agent release-readiness review and hardening (#131) #718

Workflow file for this run

name: ci
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
test:
name: test + lint (full offline stack)
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: pyproject.toml
- name: Install (core + server/mcp/code extras; no torch or SQLCipher)
run: |
python -m pip install --upgrade pip
pip install -e ".[test]"
- name: Lint (ruff)
run: ruff check .
- name: Commercial manifest + strict-CSP drift gate
run: |
python scripts/check_commercial_manifest.py
python scripts/externalize_dashboard_assets.py
- name: Unit tests (full suite — extras-gated tests included)
run: |
python -c "import fastapi, httpx, mcp, multipart, pydantic, uvicorn"
ENGRAPHIS_INDEX_ROOTS="${GITHUB_WORKSPACE}:${RUNNER_TEMP}" python -m pytest -o addopts="" tests/ -q -rs --basetemp="${RUNNER_TEMP}/engraphis-pytest"
- name: Retrieval eval gate
run: python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
- name: Retrieval eval gate — CodeMem (coding-agent wedge, incl. conflict resolution)
run: python -m eval.harness --dataset eval/datasets/codemem.jsonl --k 5
- name: Ablation (vector-only vs hybrid)
run: python -m eval.ablation
- name: Reinforcement state-transition gate
run: python -m eval.reinforcement
- name: Adversarial memory prompt-boundary gate
run: python -m eval.adversarial_memory_security
typecheck:
name: core + backends typecheck (Python 3.11)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install typecheck dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[test]"
- name: Typecheck core and backends (Pyright)
run: pyright
encryption:
name: encryption driver gate (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: pyproject.toml
- name: Install encryption integration gate
run: |
python -m pip install --upgrade pip
pip install -e ".[test,encryption]"
# sqlcipher3-binary currently cannot coexist safely with the stdlib sqlite
# extension during the long general suite. Keep its real driver contract in
# this dedicated, short-lived process rather than skipping encryption coverage.
- name: Encryption at-rest integration tests
run: |
python -c "import sqlcipher3; print(sqlcipher3.__file__)"
ENGRAPHIS_INDEX_ROOTS="${GITHUB_WORKSPACE}:${RUNNER_TEMP}" python -m pytest -o addopts="" tests/test_encrypted_store.py -q -rs --basetemp="${RUNNER_TEMP}/engraphis-pytest"
core-py39:
name: core floor (numpy-only, Python 3.9)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.9"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install (numpy-only core — the minimum supported runtime)
run: |
python -m pip install --upgrade pip
pip install numpy "pytest<9"
- name: Unit tests (extras-gated tests skip; the core must pass)
run: ENGRAPHIS_INDEX_ROOTS="${GITHUB_WORKSPACE}:${RUNNER_TEMP}" python -m pytest -o addopts="" tests/ -q -rs --basetemp="${RUNNER_TEMP}/engraphis-pytest"
- name: Retrieval eval gate
run: python -m eval.harness --dataset eval/datasets/sample.jsonl --k 5
- name: Ablation
run: python -m eval.ablation
- name: Reinforcement state-transition gate
run: python -m eval.reinforcement
- name: Adversarial memory prompt-boundary gate
run: python -m eval.adversarial_memory_security
- name: Build and smoke installed core artifacts
shell: bash
run: |
set -euo pipefail
python -m pip install --disable-pip-version-check "build==1.2.2"
dist_dir="$RUNNER_TEMP/engraphis-py39-dist"
export SOURCE_DATE_EPOCH="$(git show -s --format=%ct "$GITHUB_SHA")"
python -m build --outdir "$dist_dir"
index=0
for artifact in "$dist_dir"/*.whl "$dist_dir"/*.tar.gz; do
index=$((index + 1))
venv="$RUNNER_TEMP/engraphis-py39-artifact-$index"
python -m venv "$venv"
"$venv/bin/python" -m pip install --disable-pip-version-check "$artifact"
"$venv/bin/python" -m pip check
(
cd "$RUNNER_TEMP"
"$venv/bin/python" - <<'PY'
import pathlib
import sys
import engraphis
from engraphis.core.engine import MemoryEngine
package = pathlib.Path(engraphis.__file__).resolve()
assert pathlib.Path(sys.prefix).resolve() in package.parents, package
engine = MemoryEngine.create(":memory:")
workspace_id = engine.store.get_or_create_workspace("py39-artifact")
memory_id = engine.remember(
"The Python 3.9 artifact marker is indigo.",
workspace_id=workspace_id,
resolve_conflicts=False,
)
result = engine.recall("Python 3.9 artifact marker", workspace_id=workspace_id, k=3)
assert any(chunk["id"] == memory_id for chunk in result.chunks)
engine.store.close()
PY
"$venv/bin/engraphis" --help
"$venv/bin/engraphis" --version
"$venv/bin/engraphis-cli" --help
)
done
coverage:
name: coverage gate (Python 3.11)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
cache: pip
cache-dependency-path: pyproject.toml
- name: Install
run: |
python -m pip install --upgrade pip
pip install -e ".[test]" pytest-cov
- name: Coverage run (all extras-gated tests, tracked modules)
run: ENGRAPHIS_INDEX_ROOTS="${GITHUB_WORKSPACE}:${RUNNER_TEMP}" python -m pytest -o addopts="" tests/ -q -rs --basetemp="${RUNNER_TEMP}/engraphis-pytest" --cov=engraphis --cov-report=term-missing --cov-fail-under=60
hygiene:
name: repo hygiene gate (no stray DBs/logs)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Reject stray runtime artifacts at repo root
run: |
stray=$(find . -maxdepth 1 -type f \( -name '*.db' -o -name '*.db-wal' -o -name '*.db-shm' \
-o -name '*.bak' -o -name '*.log' \) -print)
if [ -n "$stray" ]; then
echo "Refusing to commit stray runtime artifacts:"; echo "$stray"; exit 1
fi
echo "repo root clean"
pi-extension:
name: Pi extension (${{ matrix.os }}, Python ${{ matrix.python-version }}, Node ${{ matrix.node-version }})
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
python-version: "3.10"
node-version: "22.19.0"
- os: windows-latest
python-version: "3.11"
node-version: "24"
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: ${{ matrix.python-version }}
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ matrix.node-version }}
cache: npm
cache-dependency-path: integrations/pi/npm-shrinkwrap.json
- name: Install the current Smart MCP server
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[test]"
- name: Install and verify the Pi package
working-directory: integrations/pi
env:
ENGRAPHIS_PI_TEST_COMMAND: engraphis-mcp
run: |
npm ci --ignore-scripts
npm run verify
npm run test:integration
npm audit --omit=dev
browser-accessibility:
name: browser accessibility smoke
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: "24"
- name: Install dashboard and browser test dependencies
run: |
python -m pip install --upgrade pip
pip install -e ".[test]" "uvicorn[standard]>=0.29"
npm ci --ignore-scripts --omit=optional
npx playwright install --with-deps chromium
- name: Audit the root browser dependency lock
run: npm audit --audit-level=high
- name: Playwright desktop/mobile, keyboard, CSP, console, and axe checks
run: npx playwright test
docker-gate:
# Keeps CI fast: the docker job always runs on push to main, but on PRs only
# when image/deployment paths changed (Dockerfile, entrypoint, Railway, source,
# pyproject.toml, or this workflow). No third-party actions — plain git diff.
name: docker smoke — path gate
runs-on: ubuntu-latest
outputs:
run: ${{ steps.decide.outputs.run }}
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
with:
fetch-depth: 0
- id: decide
run: |
if [ "${{ github.event_name }}" != "pull_request" ]; then
echo "run=true" >> "$GITHUB_OUTPUT"
elif git diff --name-only "${{ github.event.pull_request.base.sha }}" "${{ github.sha }}" \
| grep -qE '^(Dockerfile|docker-entrypoint\.sh|docker-compose(\.lan)?\.yml|railway\.json|deploy/|\.dockerignore|engraphis/|scripts/|pyproject\.toml|\.github/workflows/ci\.yml)'; then
echo "run=true" >> "$GITHUB_OUTPUT"
else
echo "run=false" >> "$GITHUB_OUTPUT"
fi
docker-smoke:
name: docker build + health smoke
runs-on: ubuntu-latest
needs: docker-gate
if: needs.docker-gate.outputs.run == 'true'
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- name: Validate Compose configuration
run: docker compose config --quiet
- name: Reject unauthenticated LAN Compose overlay
run: |
if env -u ENGRAPHIS_API_TOKEN docker compose -f docker-compose.yml -f docker-compose.lan.yml config --quiet; then
echo "LAN overlay must require ENGRAPHIS_API_TOKEN"
exit 1
fi
- name: Validate token-protected LAN Compose overlay
env:
ENGRAPHIS_API_TOKEN: ci-lan-overlay-token
run: docker compose -f docker-compose.yml -f docker-compose.lan.yml config --quiet
- name: Build image
run: docker build -t engraphis:ci .
- name: Verify production image OCR runtime
run: >-
docker run --rm --entrypoint sh engraphis:ci -c
'python -c "import PIL, pytesseract" && command -v tesseract >/dev/null &&
tesseract --version | head -n 1'
- name: Audit the exact production image dependency set
# The runtime image intentionally has no pip: it is a build tool whose vendored
# dependency snapshot would otherwise remain an unnecessary attack surface. Copy the
# exact installed distributions to the runner and audit that set instead of mutating
# the production image just to run the audit.
run: |
audit_dir="$(mktemp -d)"
container="engraphis-audit-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}"
cleanup() {
docker rm -f "$container" >/dev/null 2>&1 || true
rm -rf "$audit_dir"
}
trap cleanup EXIT
python -m pip install --disable-pip-version-check --no-cache-dir pip-audit==2.10.1
docker create --name "$container" engraphis:ci >/dev/null
docker cp "$container":/usr/local/lib/python3.11/site-packages/. "$audit_dir"
python -m pip_audit --path "$audit_dir"
- name: Run container (offline deterministic embedder — no model downloads)
run: |
docker run -d --name engraphis -p 8700:8700 \
-e ENGRAPHIS_EMBED_MODEL= \
-e ENGRAPHIS_LOOP_INTERVAL=0 \
-e ENGRAPHIS_HOST=0.0.0.0 \
-e ENGRAPHIS_SERVICE_MODE=customer \
engraphis:ci
- name: Wait for /api/health, then check /api/ready
run: |
for i in $(seq 1 60); do
code=$(curl -s -o /dev/null -w '%{http_code}' http://127.0.0.1:8700/api/health || true)
if [ "$code" = "200" ]; then
echo "healthy after ~${i}s"
curl -fsS http://127.0.0.1:8700/api/ready
exit 0
fi
sleep 1
done
echo "server never became healthy"
docker logs engraphis
exit 1
- name: Teardown
if: always()
run: docker rm -f engraphis
build:
name: build + install wheel
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
python-version: "3.11"
- name: Install pinned build and audit tooling
run: >-
python -m pip install --disable-pip-version-check
"build==1.5.0" "pip-audit==2.10.1"
- name: Build sdist + wheel and verify a clean install
run: |
export SOURCE_DATE_EPOCH="$(git show -s --format=%ct "$GITHUB_SHA")"
python -m build
python scripts/verify_distribution_contents.py dist/*
python -m venv .audit-venv
.audit-venv/bin/python -m pip install --upgrade "pip>=26.1.2" "setuptools>=83"
.audit-venv/bin/python -m pip install dist/*.whl
AUDIT_SITE=$(.audit-venv/bin/python -c "import site; print(site.getsitepackages()[0])")
python -m pip_audit --path "$AUDIT_SITE"
.audit-venv/bin/python -c "import engraphis, eval.harness; print('wheel imports OK')"