Skip to content

chore: remove internal docs, fix bench, clean README header, add CI b… #5

chore: remove internal docs, fix bench, clean README header, add CI b…

chore: remove internal docs, fix bench, clean README header, add CI b… #5

Workflow file for this run

# ═══════════════════════════════════════════════════════════════════════════════
# INVARIANT — GitHub Actions CI
# Deterministic Trust Infrastructure for Bittensor
# by Orthonode Infrastructure Labs · orthonode.xyz
# ═══════════════════════════════════════════════════════════════════════════════
name: INVARIANT CI
on:
push:
branches: [main, develop, "feat/**", "fix/**"]
pull_request:
branches: [main, develop]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
# ─────────────────────────────────────────────────────────────────────────────
# Job 1: Python test suite (no Rust required)
# ─────────────────────────────────────────────────────────────────────────────
test-python:
name: Python Tests (fallback backend)
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["3.10", "3.11", "3.12"]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run local test suite (pixel-art UI, no-color mode)
run: |
python scripts/test_locally.py --no-color --quick
- name: Run pytest (21 tests)
run: |
pytest invariant/invariant/tests/ -v --tb=short
- name: Bridge self-test
run: |
python invariant/invariant/phase1_core/invariant_gates_bridge.py
# ─────────────────────────────────────────────────────────────────────────────
# Job 2: Rust gate engine build + tests
# ─────────────────────────────────────────────────────────────────────────────
test-rust:
name: Rust Gate Engine
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: rustfmt, clippy
- name: Cache Rust build artifacts
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
invariant/invariant-gates/target
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Check formatting
working-directory: invariant/invariant-gates
run: cargo fmt --check
- name: Clippy (deny warnings)
working-directory: invariant/invariant-gates
run: cargo clippy -- -D warnings
- name: Run Rust unit tests
working-directory: invariant/invariant-gates
run: cargo test --release
- name: Build benchmarks (compile check only)
working-directory: invariant/invariant-gates
run: cargo bench --no-run
# ─────────────────────────────────────────────────────────────────────────────
# Job 3: Rust + Python integration (maturin build)
# ─────────────────────────────────────────────────────────────────────────────
test-rust-python:
name: Rust + Python Integration
runs-on: ubuntu-latest
needs: [test-python, test-rust]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: "3.12"
cache: pip
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
- name: Cache Rust build artifacts
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
invariant/invariant-gates/target
key: ${{ runner.os }}-cargo-maturin-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-maturin-
- name: Install Python dependencies + maturin
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install maturin
- name: Build Rust extension with maturin
working-directory: invariant/invariant-gates
run: |
maturin develop --features python-ext --release
- name: Verify Rust backend is active
run: |
python -c "
import sys
sys.path.insert(0, 'invariant/invariant/phase1_core')
from invariant_gates_bridge import using_rust
assert using_rust(), 'Expected Rust backend after maturin develop'
print('✅ Rust backend confirmed active')
"
- name: Run full test suite with Rust backend
run: |
python scripts/test_locally.py --no-color --quick
- name: Run pytest with Rust backend
run: |
pytest invariant/invariant/tests/ -v --tb=short
- name: Throughput assertion (Rust must be < 50µs/receipt)
run: |
python -c "
import sys, time, tempfile
from pathlib import Path
sys.path.insert(0, 'invariant/invariant/phase1_core')
from invariant_gates_bridge import (
Registry, Verifier, build_receipt,
derive_software_agent_id, hash_model, using_rust, GateResult
)
assert using_rust(), 'Rust backend required for this test'
with tempfile.TemporaryDirectory() as tmp:
mh = hash_model('ci-perf-model')
ah = derive_software_agent_id('5CIHotkey', mh, 1)
reg = Registry(f'{tmp}/reg.json')
reg.register_agent(ah, '5CIHotkey')
reg.approve_model(mh)
v = Verifier(f'{tmp}/reg.json', f'{tmp}/state.json')
N = 500
BASE = 90000
t0 = time.perf_counter()
for i in range(N):
r = build_receipt(ah, mh, f't{i}', f'o{i}', BASE+i, 100, time.time())
assert GateResult.is_pass(v.verify(r)['result'])
elapsed = time.perf_counter() - t0
per_us = (elapsed / N) * 1e6
rate = int(N / elapsed)
print(f'Rust throughput: {per_us:.1f} µs/receipt ({rate:,} receipts/sec)')
assert per_us < 200, f'Rust too slow: {per_us:.1f} µs (limit 200 µs in CI)'
print('✅ Throughput assertion passed')
"
# ─────────────────────────────────────────────────────────────────────────────
# Job 4: Security checks
# ─────────────────────────────────────────────────────────────────────────────
security:
name: Security Checks
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check no seed phrases committed
run: |
if find . -name "*.mnemonic" -o -name "*.seed" -o -name "mnemonic.txt" -o -name "seed.txt" | grep -q .; then
echo "❌ Seed phrase files found in repository!"
exit 1
fi
echo "✅ No seed phrase files found"
- name: Check no .bittensor wallets committed
run: |
if find . -path "./.bittensor/wallets" -type d | grep -q .; then
echo "❌ Bittensor wallet directory committed!"
exit 1
fi
echo "✅ No wallet directories found"
- name: Check no private key patterns in code
run: |
# Check for obvious private key patterns (64-char hex not in test fixtures)
if grep -r --include="*.py" "private_key\s*=\s*['\"]0x[a-fA-F0-9]\{64\}" . | grep -v test | grep -v "# example"; then
echo "❌ Potential private key in code!"
exit 1
fi
echo "✅ No private key patterns found"
- name: Verify .gitignore covers sensitive files
run: |
python -c "
with open('.gitignore') as f:
content = f.read()
required = ['.bittensor/', 'seed-phrase/', 'miner_data/', 'validator_data/', '.env']
for pattern in required:
if pattern not in content:
print(f'❌ Missing from .gitignore: {pattern}')
exit(1)
print('✅ .gitignore covers all sensitive patterns')
"
# ─────────────────────────────────────────────────────────────────────────────
# Job 5: Documentation check
# ─────────────────────────────────────────────────────────────────────────────
docs:
name: Documentation Check
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Check all required docs exist
run: |
python -c "
from pathlib import Path
required = [
'README.md',
'ROADMAP.md',
'THREAT_MODEL.md',
'ARCHITECTURE.md',
'CHANGELOG.md',
'CONTRIBUTING.md',
'SECURITY.md',
'LICENSE',
'.gitignore',
'docs/PITCH.md',
'docs/WHITEPAPER.md',
'docs/DEPLOYMENT_GUIDE.md',
'docs/INCENTIVE_MECHANISM.md',
'docs/LOCAL_TESTING.md',
]
missing = [f for f in required if not Path(f).exists()]
if missing:
print('❌ Missing docs:')
for f in missing:
print(f' {f}')
exit(1)
print(f'✅ All {len(required)} required documents present')
"
- name: Check README has key sections
run: |
python -c "
with open('README.md') as f:
content = f.read()
required = ['## What is INVARIANT', '## The Four Gates', '## Architecture',
'## Credentials', '## Testing', 'orthonode.xyz']
missing = [s for s in required if s not in content]
if missing:
print('❌ README missing sections:', missing)
exit(1)
print('✅ README contains all required sections')
"
# ─────────────────────────────────────────────────────────────────────────────
# Final status gate
# ─────────────────────────────────────────────────────────────────────────────
all-checks:
name: All Checks Pass
runs-on: ubuntu-latest
needs: [test-python, test-rust, security, docs]
if: always()
steps:
- name: Check all jobs succeeded
run: |
if [[ "${{ needs.test-python.result }}" != "success" ]]; then
echo "❌ Python tests failed"
exit 1
fi
if [[ "${{ needs.test-rust.result }}" != "success" ]]; then
echo "❌ Rust tests failed"
exit 1
fi
if [[ "${{ needs.security.result }}" != "success" ]]; then
echo "❌ Security checks failed"
exit 1
fi
if [[ "${{ needs.docs.result }}" != "success" ]]; then
echo "❌ Documentation checks failed"
exit 1
fi
echo "✅ All INVARIANT CI checks passed"
echo ""
echo "INVARIANT is ready for deployment."
echo " SHA live: Arbitrum Sepolia 0xD661...4615"
echo " TON-SHA live: TON Testnet kQBV...05OP"
echo " Tests: 21/21 pytest + 5/5 local suite"