ci #409
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
| # Agent Guild — production-truth CI matrix. | |
| # A clean checkout must pass every leg: both store backends, migrations + | |
| # concurrency (inside the pytest suite), strict credential-KDF policy, | |
| # offline verifiers, contract conformance (zero surface drift), and | |
| # independent third-party VC verification in Python AND Node. | |
| name: ci | |
| # Trigger model (2026-07-23, machine-loop approval-gate fix): | |
| # push: [main, "ship/**", "codex/**"] + workflow_dispatch — deliberately NO | |
| # `pull_request`. | |
| # | |
| # Why no pull_request: GitHub forces the pull_request-triggered runs of a PR | |
| # that was OPENED or UPDATED with GITHUB_TOKEN into an "approval required" | |
| # state (a maintainer must click "Approve workflows to run"). The machine ship | |
| # loop opens its PR with GITHUB_TOKEN, so every release sat behind that human | |
| # click — and the gated pull_request "Expected — Waiting for status to be | |
| # reported" placeholders block the merge even though the loop's own | |
| # workflow_dispatch ci runs are green (observed live on PR #5). Removing the | |
| # pull_request trigger removes those placeholders entirely. | |
| # | |
| # What replaces it: push checks on ship/** and codex/**. These branches are pushed from an | |
| # authenticated USER session (never GITHUB_TOKEN), so its push-event ci runs | |
| # start automatically with NO approval gate and report the required contexts | |
| # on the exact branch head SHA — which is the PR head — satisfying branch | |
| # protection. The loop's workflow_dispatch path is kept for branches the loop | |
| # itself pushes with GITHUB_TOKEN (the revert-recovery branches), where the | |
| # push-event recursion guard suppresses a push run. | |
| # | |
| # Net effect: required checks still all run, branch protection is unchanged, | |
| # exact-SHA deploy verification and recovery are untouched — only the human | |
| # approval click is gone. A human fork PR still cannot auto-run these checks | |
| # (it can't push to these branches on origin), so protections are TIGHTER, never | |
| # relaxed. | |
| on: | |
| push: | |
| branches: [main, "ship/**", "codex/**"] | |
| workflow_dispatch: | |
| jobs: | |
| test: | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| store: [json, sqlite] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - run: pip install -r live/guild/requirements.txt | |
| - name: pytest (GUILD_STORE=${{ matrix.store }}) | |
| working-directory: live/guild | |
| env: | |
| GUILD_STORE: ${{ matrix.store }} | |
| GUILD_ALLOW_WEAK_KDF: "1" | |
| run: python -m pytest tests -q | |
| strict-kdf: | |
| # hashed credentials at full production PBKDF2 cost — no weak-KDF escape hatch | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - run: pip install -r live/guild/requirements.txt | |
| - working-directory: live/guild | |
| run: python -m pytest tests/test_kdf_policy.py tests/test_credential_hardening.py tests/test_credential_lifecycle.py tests/test_credential_concurrency.py -q | |
| contract: | |
| # regenerating the canonical contract + derived artifacts must be a no-op | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - run: pip install -r live/guild/requirements.txt | |
| - working-directory: live/guild | |
| run: python contract/generate.py | |
| - run: | | |
| git diff --exit-code live/guild/contract/contract.json server.json \ | |
| registry/x402-payment-safety/server.json docs/INTERFACE.md \ | |
| || (echo "::error::contract drift — run 'make contract' and commit" && exit 1) | |
| independent-vc-verification: | |
| # third-party verification: Digital Bazaar (Node) + rfc8785/pyca (Python) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| - run: pip install -r live/guild/requirements.txt rfc8785 base58 | |
| - name: generate vector from issuer code | |
| working-directory: live/guild | |
| run: python ../../verifiers/gen_vector.py ../../verifiers/vector.json | |
| - name: independent Python verification (rfc8785 + pyca) | |
| run: python verifiers/verify_python_independent.py verifiers/vector.json | |
| - name: independent Node verification (Digital Bazaar Data Integrity) | |
| working-directory: verifiers | |
| run: | | |
| npm install --no-fund --no-audit | |
| node verify_node_digitalbazaar.mjs vector.json | |
| caller-proof-wallet-verification: | |
| # did:key + one-wallet EVM caller proofs and wallet-binding credential from | |
| # genuinely CLEAN Python and Node environments: the vector is generated | |
| # by the live issuer code, then verified by third-party-primitive-only | |
| # verifiers installed from their own pinned manifests (never the repo's | |
| # runtime environment). The Node deps ship in verifiers/package.json; | |
| # the Python deps in verifiers/requirements.txt. | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - uses: actions/setup-node@v4 | |
| with: | |
| node-version: "22" | |
| - name: generate vector from the live issuer code (own venv) | |
| run: | | |
| python -m venv .venv-gen | |
| .venv-gen/bin/pip install --upgrade pip | |
| .venv-gen/bin/pip install -r live/guild/requirements.txt | |
| .venv-gen/bin/python verifiers/gen_caller_proof_vector.py verifiers/caller_proof_vector.json | |
| - name: independent Python verification (CLEAN venv, pinned manifest) | |
| run: | | |
| python -m venv .venv-cpverify | |
| .venv-cpverify/bin/pip install --upgrade pip | |
| .venv-cpverify/bin/pip install -r verifiers/requirements.txt | |
| .venv-cpverify/bin/python verifiers/verify_caller_proof_python.py verifiers/caller_proof_vector.json | |
| - name: independent Node verification (CLEAN install from package.json) | |
| working-directory: verifiers | |
| run: | | |
| npm install --no-fund --no-audit | |
| npm run verify-caller-proof | |
| trustplane: | |
| # trust-plane core: verify-before-use client, binding invariants, cache | |
| # pin persistence/rotation, sidecar, outcomes readback + local conformance | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - run: pip install -r live/guild/requirements.txt -r live/trustplane/requirements/core.txt | |
| - name: trust-plane tests (core) | |
| working-directory: live/trustplane | |
| run: python -m pytest tests -q | |
| - name: AGI-1 conformance (local issuer) | |
| working-directory: live/trustplane | |
| run: python -m pytest conformance/ -q | |
| trustplane-integrations: | |
| # each framework extra resolves in a CLEAN environment (this is the | |
| # install-resolution gate) and its NATIVE adapter tests run there. | |
| # crewai and the mcp proxy pin different mcp versions on purpose — they | |
| # are separate environments; see live/trustplane/requirements/. | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| extra: [crewai, langchain, openai-agents, mcp] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: clean install resolution (${{ matrix.extra }}) | |
| run: | | |
| python -m venv .venv-${{ matrix.extra }} | |
| .venv-${{ matrix.extra }}/bin/pip install --upgrade pip | |
| .venv-${{ matrix.extra }}/bin/pip install \ | |
| -r live/trustplane/requirements/${{ matrix.extra }}.txt \ | |
| -r live/guild/requirements.txt pytest | |
| - name: native adapter tests (${{ matrix.extra }}) | |
| working-directory: live/trustplane | |
| run: ../../.venv-${{ matrix.extra }}/bin/python -m pytest tests -q | |
| x402-interop: | |
| # x402 v2 interoperability in a CLEAN environment: the OFFICIAL x402 | |
| # client SDK (with a real EVM signer) makes the paid request end-to-end | |
| # over real HTTP against the Guild server + a deterministic local fake | |
| # facilitator that cryptographically verifies the EIP-3009 authorization. | |
| # No mainnet, no funds, no gating on external networks. | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: clean install (official x402 client + EVM signer deps) | |
| run: | | |
| python -m venv .venv-x402 | |
| .venv-x402/bin/pip install --upgrade pip | |
| .venv-x402/bin/pip install -r live/guild/requirements.txt \ | |
| 'x402[httpx,evm]==2.15.0' 'eth-account>=0.13' pytest | |
| - name: x402 v2 interop (independent official client) | |
| working-directory: live/guild | |
| env: | |
| GUILD_ALLOW_WEAK_KDF: "1" | |
| run: ../../.venv-x402/bin/python -m pytest tests_x402_interop -q | |
| release-gate: | |
| # THE deployment-aware gate: a release is not green unless production | |
| # serves the exact pushed SHA and that running build passes the live | |
| # contract probe, live AGI-1 conformance, signed-decision verification | |
| # (incl. decision.agent_id == routing.provider_id) and issuer/checkpoint | |
| # continuity. NO continue-on-error: a red gate is a red release. | |
| # Concurrency: newest push wins; an older run can never certify a newer | |
| # deployment (and the SHA equality check makes cross-certification | |
| # structurally impossible in the other direction). | |
| if: github.ref == 'refs/heads/main' && github.event_name == 'push' | |
| needs: [test, contract, trustplane] | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: release-gate-production | |
| cancel-in-progress: true | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - run: pip install -r live/guild/requirements.txt -r live/trustplane/requirements/core.txt | |
| - name: wait for production to serve THIS SHA, then verify the live release | |
| run: | | |
| python live/scripts/release_gate.py \ | |
| --sha "${{ github.sha }}" \ | |
| --timeout 900 --interval 20 \ | |
| --attestation release_attestation.json | |
| - name: upload release attestation (machine-readable) | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-attestation-${{ github.sha }} | |
| path: release_attestation.json | |
| if-no-files-found: warn |