name: Parity gate on: pull_request: types: [opened, reopened, synchronize, ready_for_review] paths: - "extensions/qa-lab/**" - "extensions/qa-channel/**" - "extensions/openai/**" - "qa/scenarios/**" - "src/agents/**" - "src/context-engine/**" - "src/gateway/**" - "src/media/**" - ".github/workflows/parity-gate.yml" permissions: contents: read concurrency: group: parity-gate-${{ github.event.pull_request.number || github.sha }} cancel-in-progress: true jobs: parity-gate: name: Run the GPT-5.4 / Opus 4.6 parity gate against the qa-lab mock if: ${{ github.event.pull_request.draft != true }} runs-on: blacksmith-8vcpu-ubuntu-2404 timeout-minutes: 20 env: # Fence the gate off from any real provider credentials. The qa-lab # mock server + auth staging (PR N) should be enough to produce a # meaningful verdict without touching a real API. If any of these # leak into the job env, fail hard instead of silently running # against a live provider and burning real budget. # # The parity pack has 11 isolated scenario workers. Letting qa suite # fan out to its default "all scenarios at once" mode on smaller CI # VMs makes the short strict-agentic scenarios flaky, especially the # approval-turn followthrough gate that expects a fast post-approval # read within a 30s agent.wait timeout. QA_PARITY_CONCURRENCY: "2" OPENAI_API_KEY: "" ANTHROPIC_API_KEY: "" OPENCLAW_LIVE_OPENAI_KEY: "" OPENCLAW_LIVE_ANTHROPIC_KEY: "" OPENCLAW_LIVE_GEMINI_KEY: "" OPENCLAW_LIVE_SETUP_TOKEN_VALUE: "" steps: - name: Checkout PR uses: actions/checkout@v4 - name: Install pnpm uses: pnpm/action-setup@v4 - name: Setup Node uses: actions/setup-node@v4 with: node-version: "22.18.0" cache: "pnpm" - name: Install dependencies run: pnpm install --frozen-lockfile - name: Run GPT-5.4 lane run: | pnpm openclaw qa suite \ --provider-mode mock-openai \ --parity-pack agentic \ --concurrency "${QA_PARITY_CONCURRENCY}" \ --model openai/gpt-5.4 \ --alt-model openai/gpt-5.4-alt \ --output-dir .artifacts/qa-e2e/gpt54 - name: Run Opus 4.6 lane run: | pnpm openclaw qa suite \ --provider-mode mock-openai \ --parity-pack agentic \ --concurrency "${QA_PARITY_CONCURRENCY}" \ --model anthropic/claude-opus-4-6 \ --alt-model anthropic/claude-sonnet-4-6 \ --output-dir .artifacts/qa-e2e/opus46 - name: Generate parity report run: | pnpm openclaw qa parity-report \ --repo-root . \ --candidate-summary .artifacts/qa-e2e/gpt54/qa-suite-summary.json \ --baseline-summary .artifacts/qa-e2e/opus46/qa-suite-summary.json \ --candidate-label openai/gpt-5.4 \ --baseline-label anthropic/claude-opus-4-6 \ --output-dir .artifacts/qa-e2e/parity - name: Upload parity artifacts if: always() uses: actions/upload-artifact@v4 with: name: parity-gate-${{ github.event.pull_request.number || github.sha }} path: .artifacts/qa-e2e/ retention-days: 14 if-no-files-found: warn