Repair trust, Ripple, and API security boundaries #89
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: tests | |
| # Atlas CI: spin up Neo4j 5.26, run the full suite + AGM | |
| # compliance check + the BusinessMemBench head-to-head matrix. | |
| # Every push and every PR must pass. | |
| on: | |
| push: | |
| branches: [main, master] | |
| pull_request: | |
| branches: [main, master] | |
| jobs: | |
| obsidian-plugin: | |
| name: obsidian plugin bundle | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| cache: npm | |
| cache-dependency-path: obsidian-plugin/package-lock.json | |
| - name: Install locked plugin dependencies | |
| run: npm ci --prefix obsidian-plugin | |
| - name: Reject vulnerable plugin dependencies | |
| run: npm audit --prefix obsidian-plugin --audit-level=moderate | |
| - name: Build production plugin bundle | |
| run: | | |
| npm run build --prefix obsidian-plugin | |
| test -s obsidian-plugin/main.js | |
| windows-sqlite-and-unit: | |
| name: windows py3.14 unit + sqlite lifecycle | |
| runs-on: windows-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.14" | |
| allow-prereleases: true | |
| cache: pip | |
| - name: Install | |
| run: python -m pip install -e .[dev] | |
| - name: Run unit tests | |
| run: python -m pytest tests/unit -q | |
| test: | |
| name: py${{ matrix.python-version }} + neo4j | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] | |
| services: | |
| neo4j: | |
| image: neo4j:5.26 | |
| env: | |
| NEO4J_AUTH: neo4j/atlasdev | |
| NEO4J_PLUGINS: '["apoc"]' | |
| NEO4J_dbms_security_procedures_unrestricted: 'apoc.*' | |
| NEO4J_apoc_export_file_enabled: 'true' | |
| NEO4J_apoc_import_file_enabled: 'true' | |
| ports: | |
| - 7474:7474 | |
| - 7687:7687 | |
| options: >- | |
| --health-cmd "wget --spider http://localhost:7474 || exit 1" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 12 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python ${{ matrix.python-version }} | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: pip | |
| allow-prereleases: true | |
| - name: Wait for Neo4j to be ready | |
| run: | | |
| for i in {1..30}; do | |
| if curl -sf http://localhost:7474 > /dev/null; then | |
| echo "Neo4j up"; exit 0 | |
| fi | |
| sleep 2 | |
| done | |
| echo "Neo4j never came up" | |
| exit 1 | |
| - name: Install | |
| run: | | |
| python -m pip install --upgrade pip | |
| pip install -e .[dev] | |
| pip install ruff | |
| - name: Lint (ruff — must be clean) | |
| run: ruff check atlas_core tests benchmarks scripts | |
| - name: Run unit + integration tests | |
| env: | |
| NEO4J_URI: bolt://localhost:7687 | |
| NEO4J_USER: neo4j | |
| NEO4J_PASSWORD: atlasdev | |
| PYTHONPATH: . | |
| run: pytest tests/ -v --tb=short | |
| - name: AGM compliance suite (49 scenarios, must pass at 100%) | |
| env: | |
| NEO4J_URI: bolt://localhost:7687 | |
| NEO4J_USER: neo4j | |
| NEO4J_PASSWORD: atlasdev | |
| PYTHONPATH: . | |
| run: pytest tests/integration/test_agm_compliance.py -v | |
| - name: BusinessMemBench head-to-head matrix | |
| env: | |
| NEO4J_URI: bolt://localhost:7687 | |
| NEO4J_USER: neo4j | |
| NEO4J_PASSWORD: atlasdev | |
| PYTHONPATH: . | |
| run: | | |
| python scripts/run_bmb.py --out /tmp/bmb_ci.json | |
| # Atlas must score >= 0.90 to pass CI; regressions block merge. | |
| python -c " | |
| import json, sys | |
| m = json.load(open('/tmp/bmb_ci.json')) | |
| atlas = m.get('atlas', {}) | |
| score = atlas.get('overall_mean_score', 0.0) | |
| assert score >= 0.90, f'Atlas score regressed: {score}' | |
| print(f'Atlas BMB score: {score:.3f} (gate >= 0.90)') | |
| " | |
| - name: Upload BMB results | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: bmb-matrix-py${{ matrix.python-version }} | |
| path: /tmp/bmb_ci.json | |
| if-no-files-found: warn | |
| demo-smoke: | |
| # The front door (demo.sh) is the "works today" proof Rich shows people. | |
| # Run it end-to-end in CI against the Neo4j service container so it can | |
| # never silently rot. The job fails if demo.sh exits non-zero OR if the | |
| # loop does not close. | |
| name: demo.sh smoke (front-door end-to-end) | |
| runs-on: ubuntu-latest | |
| services: | |
| neo4j: | |
| image: neo4j:5.26 | |
| env: | |
| NEO4J_AUTH: neo4j/atlasdev | |
| NEO4J_PLUGINS: '["apoc"]' | |
| NEO4J_dbms_security_procedures_unrestricted: 'apoc.*' | |
| NEO4J_apoc_export_file_enabled: 'true' | |
| NEO4J_apoc_import_file_enabled: 'true' | |
| ports: | |
| - 7474:7474 | |
| - 7687:7687 | |
| options: >- | |
| --health-cmd "wget --spider http://localhost:7474 || exit 1" | |
| --health-interval 10s | |
| --health-timeout 5s | |
| --health-retries 12 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| cache: pip | |
| allow-prereleases: true | |
| - name: Wait for Neo4j to be ready | |
| run: | | |
| for i in {1..30}; do | |
| if curl -sf http://localhost:7474 > /dev/null; then | |
| echo "Neo4j up"; exit 0 | |
| fi | |
| sleep 2 | |
| done | |
| echo "Neo4j never came up" | |
| exit 1 | |
| - name: Build the repo-root .venv demo.sh expects | |
| # demo.sh hard-requires a repo-root .venv and runs .venv/bin/python. | |
| # Create it here so we exercise the real, unmodified front door. | |
| run: | | |
| python -m venv .venv | |
| .venv/bin/pip install --upgrade pip | |
| .venv/bin/pip install -e .[dev] | |
| - name: Run demo.sh end-to-end (must exit 0 and close the loop) | |
| env: | |
| NEO4J_URI: bolt://localhost:7687 | |
| NEO4J_USER: neo4j | |
| NEO4J_PASSWORD: atlasdev | |
| PYTHONPATH: . | |
| run: | | |
| set -euo pipefail | |
| # demo.sh has `set -euo pipefail` and exits non-zero on any failure | |
| # (missing prereqs, cascade failure -> sys.exit(2), etc.); pipefail | |
| # propagates that through the tee. | |
| ./demo.sh | tee demo_output.log | |
| # Guard against a narrated partial pass: one real proposal must | |
| # route to review, resolve, and close the loop. | |
| grep -q "strategic: 1" demo_output.log | |
| grep -q "resolved with decision='accept'" demo_output.log | |
| grep -q "LOOP CLOSED" demo_output.log |