teleo-infrastructure/.github/workflows/ci.yml

313 lines
13 KiB
YAML

name: ci
on:
pull_request:
push:
branches:
- main
workflow_dispatch:
permissions:
contents: read
concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
PYTHON_VERSION: "3.11"
CI: "1"
LEOCLEAN_RUNTIME_POSTGRES_IMAGE: "postgres@sha256:eb4759788a2182f08257135e61a34f2cfc3c2914079f3465d64ee62350f4d081"
jobs:
lint:
name: Focused lint
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Ruff focused surface
run: |
python -m ruff check \
lib/agent_routing.py \
lib/config.py \
lib/db.py \
lib/evaluate.py \
lib/llm.py \
lib/post_extract.py \
docker/leoclean-nosend/entrypoint.py \
ops/apply_gcp_iam_split.py \
ops/attest_gcp_reasoning_compute.py \
ops/capture_vps_canonical_postgres_snapshot.py \
ops/check_gcp_leoclean_nosend_preflight.py \
ops/check_gcp_infra_readiness.py \
ops/run_gcp_infra_execute_canary.py \
ops/apply_gcp_runtime_baseline.py \
ops/check_gcp_service_communications.py \
ops/derive_leoclean_runtime_query_contract.py \
ops/gcp_leoclean_nosend_package.py \
ops/plan_gcp_iam_split.py \
ops/private_receipt_io.py \
ops/run_local_canonical_postgres_rebuild.py \
ops/redact_sqlite_postgres_restore_canary.py \
ops/restore_gcp_generated_postgres_snapshot.py \
ops/sqlite_to_postgres_dump.py \
ops/verify_gcp_cloudsql_restore_readback.py \
ops/verify_gcp_leoclean_runtime_permissions.py \
ops/verify_gcp_leoclean_service_environment.py \
ops/verify_gcp_canonical_lifecycle.py \
ops/verify_postgres_parity_manifest.py \
ops/verify_vps_canonical_snapshot_delta.py \
telegram/approvals.py \
hermes-agent/patches/enforce_leoclean_learning_policy.py \
hermes-agent/leoclean-bin/kb_tool.py \
hermes-agent/leoclean-bin/cloudsql_memory_tool.py \
hermes-agent/runtime/leoclean-nosend/bootstrap.py \
hermes-agent/runtime/leoclean-nosend/profile-sources/cloudsql_memory_runtime.py \
hermes-agent/runtime/leoclean-nosend/profile-sources/leo_db_context.py \
hermes-agent/runtime/leoclean-nosend/profile-sources/operational_contracts.py \
scripts/check_crabbox_ci_contract.py \
scripts/check_llm_refinement_contract.py \
scripts/build_working_leo_m3taversal_outcome_sandbox.py \
scripts/leo_behavior_manifest.py \
scripts/leo_identity_manifest.py \
scripts/leo_tool_trace.py \
scripts/compile_leoclean_nosend_runtime.py \
scripts/replay_decision_engine_eval.py \
scripts/prove_phase1b_local.py \
scripts/run_gcp_generated_db_direct_claim_suite.py \
scripts/run_gcp_generated_db_working_leo_suite.py \
scripts/run_gcp_generated_db_blind_claim_canary.py \
scripts/run_leo_direct_claim_handler_suite.py \
scripts/run_leo_m3taversal_oos_handler_suite.py \
scripts/verify_leo_db_first_oos_canary.py \
scripts/run_leo_clone_bound_handler_checkpoint.py \
scripts/run_gcp_leoclean_nosend_oci_smoke.py \
scripts/working_leo_m3taversal_oos_benchmark.py \
scripts/working_leo_open_ended_benchmark.py \
scripts/verify_leoclean_nosend_runtime.py \
tests/test_agent_routing.py \
tests/test_attest_gcp_reasoning_compute.py \
tests/test_assemble_telegram_visible_direct_claim_capture_receipt.py \
tests/test_build_working_leo_m3taversal_outcome_sandbox.py \
tests/test_decision_engine_replay.py \
tests/test_evaluate_agent_routing.py \
tests/test_gcp_artifact_workflow.py \
tests/test_capture_vps_canonical_postgres_snapshot.py \
tests/test_gcp_infra_execute_canary.py \
tests/test_gcp_infra_readiness_checker.py \
tests/test_gcp_leoclean_nosend_preflight.py \
tests/test_gcp_leoclean_runtime_permissions.py \
tests/test_gcp_leoclean_nosend_package.py \
tests/test_gcp_leoclean_nosend_oci_smoke.py \
tests/test_gcp_leoclean_service_environment.py \
tests/test_gcp_runtime_baseline_apply.py \
tests/test_gcp_service_communications.py \
tests/test_gcp_cloudsql_restore_drill.py \
tests/test_gcp_cloudsql_restore_readback.py \
tests/test_gcp_iam_split_apply.py \
tests/test_gcp_iam_split_plan.py \
tests/test_gcp_readiness_workflow.py \
tests/test_gcp_generated_db_direct_claim_suite.py \
tests/test_gcp_generated_db_working_leo_suite.py \
tests/test_gcp_generated_db_blind_claim_canary.py \
tests/test_hermes_leoclean_kb_bridge_source.py \
tests/test_hermes_leoclean_db_context_plugin.py \
tests/test_hermes_leoclean_skill_surfaces.py \
tests/test_leoclean_nosend_runtime.py \
tests/test_leo_behavior_manifest.py \
tests/test_leo_tool_trace.py \
tests/test_verify_leo_db_first_oos_canary.py \
tests/test_compile_kb_source_packet.py \
tests/test_verify_postgres_parity_manifest.py \
tests/test_verify_gcp_canonical_lifecycle.py \
tests/test_verify_vps_canonical_snapshot_delta.py \
tests/test_working_leo_m3taversal_oos_benchmark.py \
tests/test_working_leo_open_ended_benchmark.py \
tests/test_phase1b_end_to_end.py \
tests/test_private_receipt_io.py \
tests/test_restore_gcp_generated_postgres_snapshot.py \
tests/test_run_local_canonical_postgres_rebuild.py \
tests/test_run_local_genesis_ledger_rebuild.py \
tests/test_sqlite_to_postgres_dump.py \
tests/test_sqlite_postgres_restore_canary_capsule.py \
tests/test_teleo_agent_systemd.py \
tests/test_eval_parse.py \
tests/test_contributor.py \
tests/test_search.py
- name: Shell syntax
run: |
bash -n \
deploy/sync-gcp-leoclean-runtime.sh \
hermes-agent/leoclean-bin/teleo-kb \
hermes-agent/leoclean-bin/teleo-kb-gcp \
ops/backup_vps_sqlite_kb.sh \
ops/provision_gcp_leoclean_runtime_role.sh \
ops/run_gcp_cloudsql_restore_drill.sh \
ops/run_sqlite_postgres_restore_canary.sh \
scripts/run_leoclean_nosend_runtime_canary.sh
test:
name: Unit tests
runs-on: ubuntu-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Pull digest-pinned PostgreSQL permission canary image
run: docker pull "${LEOCLEAN_RUNTIME_POSTGRES_IMAGE}"
- name: Pytest
env:
TELEO_RUN_LEOCLEAN_RUNTIME_POSTGRES_CANARY: "1"
run: |
mkdir -p .crabbox-results
python -m pytest --junitxml=.crabbox-results/pytest.xml
- name: Upload test artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: teleo-infrastructure-pytest
path: .crabbox-results/pytest.xml
if-no-files-found: warn
- name: Remove interrupted PostgreSQL permission canaries
if: always()
run: |
mapfile -t containers < <(docker ps -aq --filter "label=livingip.r2.permission-canary")
if ((${#containers[@]})); then
docker rm --force "${containers[@]}"
fi
test -z "$(docker ps -aq --filter 'label=livingip.r2.permission-canary')"
repo-contracts:
name: Repo contracts
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Validate repo-owned contract
run: |
python scripts/check_crabbox_ci_contract.py \
--output .crabbox-results/crabbox-ci-contract.json
python scripts/check_llm_refinement_contract.py \
--output .crabbox-results/llm-refinement-contract.json
python scripts/replay_decision_engine_eval.py \
--output .crabbox-results/decision-engine-eval.json
- name: Upload contract artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: teleo-infrastructure-repo-contracts
path: |
.crabbox-results/crabbox-ci-contract.json
.crabbox-results/llm-refinement-contract.json
.crabbox-results/decision-engine-eval.json
if-no-files-found: error
leoclean-nosend-runtime:
name: Leoclean no-send runtime
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.11.9"
- name: Install exact uv toolchain
run: python -m pip install 'uv==0.9.30' 'PyYAML==6.0.3'
- name: Pull digest-pinned OCI bases
run: |
docker pull --platform=linux/amd64 "ghcr.io/astral-sh/uv:0.9.30@sha256:538e0b39736e7feae937a65983e49d2ab75e1559d35041f9878b7b7e51de91e4"
docker pull --platform=linux/amd64 "docker.io/library/python:3.11.9-slim-bookworm@sha256:8fb099199b9f2d70342674bd9dbccd3ed03a258f26bbd1d556822c6dfc60c317"
docker pull --platform=linux/amd64 "docker.io/library/postgres:16.14-bookworm@sha256:92620daddcd947f8d5ab5ba66e848702fe443d87fed30c4cea8e389fd78dfc55"
- name: Compile and exercise release artifact
env:
LEOCLEAN_NOSEND_ARTIFACT_OUTPUT: ${{ runner.temp }}/leoclean-nosend-artifact
run: scripts/run_leoclean_nosend_runtime_canary.sh
- name: Build and exercise one disposable OCI image
run: |
python scripts/run_gcp_leoclean_nosend_oci_smoke.py \
--artifact "${RUNNER_TEMP}/leoclean-nosend-artifact" \
--runtime-receipt .crabbox-results/leoclean-nosend-runtime.json \
--output .crabbox-results/gcp-leoclean-nosend-oci-smoke.json
- name: Upload no-send runtime receipt
if: always()
uses: actions/upload-artifact@v4
with:
name: teleo-infrastructure-leoclean-nosend-runtime
path: |
.crabbox-results/leoclean-nosend-runtime.json
.crabbox-results/gcp-leoclean-nosend-oci-smoke.json
if-no-files-found: error
- name: Remove interrupted no-send OCI smokes
if: always()
run: |
container_inventory="$(docker ps -aq --filter 'label=livingip.leoclean-nosend-smoke')"
if [[ -n "${container_inventory}" ]]; then
mapfile -t containers <<<"${container_inventory}"
docker rm --force "${containers[@]}"
fi
image_inventory="$(docker images -q --filter 'label=livingip.leoclean-nosend-smoke')"
if [[ -n "${image_inventory}" ]]; then
mapfile -t images <<<"${image_inventory}"
docker image rm --force "${images[@]}"
fi
remaining_containers="$(docker ps -aq --filter 'label=livingip.leoclean-nosend-smoke')"
remaining_images="$(docker images -q --filter 'label=livingip.leoclean-nosend-smoke')"
test -z "${remaining_containers}"
test -z "${remaining_images}"
phase1b-local-proof:
name: Phase 1B local proof
runs-on: ubuntu-latest
needs:
- lint
- test
- repo-contracts
timeout-minutes: 20
env:
PHASE1B_AGENT_ROUTING_ENABLED: "true"
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install
run: |
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
- name: Run proof wrapper
run: |
scripts/crabbox_phase1b_proof.sh
- name: Upload proof artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: teleo-infrastructure-phase1b-proof
path: |
.crabbox-results/crabbox-ci-contract.json
proof/phase1b-local-e2e-proof.json
.crabbox-results/phase1b-pytest.xml
.crabbox-results/phase1b-proof-summary.json
if-no-files-found: warn