Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
9890ed8
fix(e2e-gate): skip Drift Bot when not reported, raise MAX_WAIT to 3600s
vivekchand Aug 29, 2026
aa0144f
test(e2e-gate): update Drift Bot test to assert skip_if_unreported be…
claude Aug 29, 2026
3332ff9
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 29, 2026
f2d8ab2
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 29, 2026
9c28df6
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 29, 2026
eafa70c
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 29, 2026
df41ff2
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 30, 2026
9b20840
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 30, 2026
4fc4cf3
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 30, 2026
bf7ef1c
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 30, 2026
6caf54b
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 30, 2026
c129ee8
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 31, 2026
6d478b7
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Aug 31, 2026
bdc5618
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Sep 1, 2026
5343625
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Sep 1, 2026
f21dc39
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Sep 1, 2026
134cbeb
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Sep 2, 2026
dbfa785
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Sep 2, 2026
7b0a723
Merge branch 'main' into fix/e2e-gate-driftbot-timeout
vivekchand Sep 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions .github/workflows/e2e-gate.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,36 @@
name: E2E Gate (required)

# Aggregates the 4 required OSS E2E checks into one required status check.
# The owner adds ONE check name to branch protection instead of four:
# Aggregates the 12 required CI and E2E checks into one required status check.
# The owner adds ONE check name to branch protection instead of twelve:
# "E2E Gate (required)"
#
# Polls the Check Runs API every 30s until all required checks complete.
# Fails immediately if any required check fails (fast-fail).
# Passes only when all 4 required checks have a success conclusion.
# Times out after 15 min (oss-golden-path budget is 12 min -- on a cold
# runner Playwright download alone takes ~4.5 min, then C1+C5 sweeps add
# ~5 min; the previous 8-min limit caused premature timeout before the
# underlying check could pass).
# Passes only when all required checks have a success conclusion.
# Times out after 60 min (scripts/e2e_gate.py MAX_WAIT=3600). This ceiling
# exists to handle runner starvation on days with many concurrent PRs; on a
# quiet day the gate exits as soon as all checks pass, typically in 20-30 min.
#
# Required checks aggregated (keep in sync with REQUIRED_CHECKS in
# scripts/apply_required_status_checks.py):
# Required checks aggregated (authoritative list: scripts/e2e_gate.py):
# - OSS golden path (wheel + OpenClaw + 9 tabs)
# - Cross-repo handoff (C4)
# - MOAT Keystone (13-endpoint bar)
# - E2E Browser Tests (critical subset)
#
# To close C6 after this PR merges:
# GitHub Settings > Branches > main > Required status checks:
# add "E2E Gate (required)"
# (1 check name instead of 4)
# - Syntax & Lint
# - API Tests (3 OS)
# - MOAT Verifier (72 tests)
# - Entitlement API tests
# - pip install matrix (x4)
# - Wheel install & asset presence
# - Store invariants (property-based)
# - Drift Bot [skip_if_unreported: only enforced when 8090 App posts]
#
# Tracking: vivekchand/clawmetry#4029 (C6)
#
# This workflow intentionally runs on pull_request only -- not on push events.
# Drift Bot (8090-software-factory app) posts its commit status to PR head
# SHAs only; the app never re-posts to the merge commit that lands on main.
# If the gate ran on push events, it would wait the full 35 min timeout for
# If the gate ran on push events, it would wait the full timeout for
# a Drift Bot status that never arrives (confirmed on run #33224218966).
# The enforcement that matters happens on the PR; no extra run is needed after
# the merge. Supersedes PR #5323 which fixed the same issue via code but was
Expand All @@ -51,7 +52,7 @@ jobs:
e2e-gate:
name: E2E Gate (required)
runs-on: ubuntu-latest
timeout-minutes: 35
timeout-minutes: 65

steps:
# Required because the gate logic is a repo script now. This job had no
Expand All @@ -71,7 +72,7 @@ jobs:
GITHUB_TOKEN: ${{ github.token }}
COMMIT_SHA: ${{ github.event.pull_request.head.sha || github.sha }}
REPO: ${{ github.repository }}
MAX_WAIT: "1800"
MAX_WAIT: "3600"
run: python3 scripts/e2e_gate.py

- name: Write job summary
Expand Down
32 changes: 28 additions & 4 deletions scripts/e2e_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

* an exact name (``"Syntax & Lint"``) for a single job;
* an fnmatch pattern plus ``min_count`` for a matrix job, where the pattern
expands to one check per leg (``"pip install (*)"`` -> four legs). ``min_count``
expands to one check per leg (``"pip install (*)"``) -> four legs). ``min_count``
is what stops a *shrinking* matrix from quietly passing: drop macOS from the
matrix and the pattern still matches, but the count no longer does.

Expand All @@ -39,7 +39,7 @@
from dataclasses import dataclass, field

POLL_INTERVAL = 30
DEFAULT_MAX_WAIT = 1800
DEFAULT_MAX_WAIT = 3000 # 50 min default; workflow sets 3600 (60 min)

# GitHub treats skipped/neutral as non-blocking; match that.
PASSING = {"success", "skipped", "neutral"}
Expand All @@ -59,11 +59,19 @@ class Spec:
before the spec can pass. For a single job that is 1. For a matrix it is the

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec". The code now adds a skip_if_unreported field that explicitly permits checks not reporting on all PR types to pass the gate, violating this foundational contract.

number of legs, so removing a leg fails the gate instead of silently
reducing coverage.

``skip_if_unreported`` marks a spec whose reporter may legitimately never
post on certain PR types (e.g. a GitHub App that only evaluates Python or
product-record changes). When True and zero check-runs/statuses have been

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint states: "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec, because a workflow that stays silent would hold the gate pending until timeout and block every merge." The code now implements skip_if_unreported=True for Drift Bot, explicitly allowing a check that does not report on all PR types (frontend-only npm bumps) to pass the gate without reporting. This contradicts the blueprint's foundational design contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contracts state: "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code now implements skip_if_unreported=True for Drift Bot, explicitly allowing a check that does not report on all PR types to pass the gate without reporting, which contradicts this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec". The code now adds a skip_if_unreported field to Spec that explicitly violates this contract by allowing checks that don't report on all PR types to pass the gate.

posted for this spec, evaluate() returns "passed" (skipped) rather than
"pending". A failing status still fails the gate -- the guard is preserved
whenever the reporter does post.
"""

label: str
pattern: str
min_count: int = 1
skip_if_unreported: bool = False

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code adds a skip_if_unreported field that explicitly permits checks not reporting on all PR types to be added to the spec and pass the gate when unreported, violating this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec" because unreported checks would hold the gate pending until timeout. The code adds a skip_if_unreported field that explicitly permits checks not reporting on all PR types to pass the gate when unreported, violating this foundational contract.

Comment on lines 59 to +74

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec". The code adds a skip_if_unreported field that explicitly violates this contract by allowing checks that don't report on all PR types to pass when unreported.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec". The code adds a skip_if_unreported field to Spec that explicitly violates this contract by allowing checks that don't report on all PR types to pass the gate when unreported.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec". The code adds a skip_if_unreported field to Spec that explicitly permits checks not reporting on all PR types to pass the gate when unreported, violating this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec". The code adds a skip_if_unreported field to Spec that explicitly permits checks not reporting on all PR types to pass when unreported, violating this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code adds a skip_if_unreported field to Spec that explicitly permits checks not reporting on all PR types to pass when unreported, violating this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code adds a skip_if_unreported field to Spec that explicitly permits checks not reporting on all PR types to pass when unreported, violating this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code adds a skip_if_unreported field to Spec that explicitly permits checks not reporting on all PR types to pass when unreported, violating this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code adds a skip_if_unreported field to Spec that explicitly permits checks not reporting on all PR types to pass when unreported, directly violating this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code adds a skip_if_unreported field to Spec that explicitly permits checks not reporting on all PR types to pass when unreported, directly violating this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code adds a skip_if_unreported field to Spec that explicitly allows checks not reporting on all PR types to pass when unreported, contradicting this foundational contract.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contract states "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec." The code adds a skip_if_unreported field to Spec that explicitly allows checks not reporting on all PR types to pass when unreported, directly violating this foundational contract.


def matches(self, name: str) -> bool:
return fnmatch.fnmatchcase(name, self.pattern)
Expand Down Expand Up @@ -111,7 +119,14 @@ def matches(self, name: str) -> bool:
# Unlike everything above, drift-bot is a COMMIT STATUS from the
# 8090-software-factory GitHub App, not an Actions check run. It never
# appears in /check-runs, which is why list_commit_statuses exists.
Spec("Drift Bot", "drift-bot"),
#
# skip_if_unreported=True: the 8090 App only posts drift-bot on PRs that
# touch Python or product-record files. Frontend-only npm bumps (dependabot

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint's Key Contracts state: "Only a check whose workflow reports on every pull request may appear in RequiredCheckSpec, because a workflow that stays silent would hold the gate pending until timeout and block every merge." The code now implements skip_if_unreported=True for Drift Bot, explicitly allowing a check that does not report on all PR types to pass the gate without reporting, which contradicts this foundational contract.

# i18next / postcss / react-router / etc.) never receive a status -- making
# this spec a guaranteed 30-min hang on every such PR. When the App does
# post (on any PR touching Python or product files), the gate still enforces
# it. Only the "never posted" case is treated as skipped.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not on all PR types. This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not on all PR types. This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not all PR types. This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not all PR types. This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not all PR types. This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not all PR types. This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not all PR types. This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not all PR types. This violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not all PR types. This violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Spec("Drift Bot", "drift-bot", skip_if_unreported=True),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True, but it is a check that does not report on all PR types (only on PRs touching Python or product-record files). This directly contradicts the Key Contract that only checks reporting on every PR may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite not reporting on all PR types (only on Python/product-record changes). This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite not reporting on all PR types (only on Python/product-record changes). This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite not reporting on all PR types (only on Python/product-record changes). This directly violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not on all PR types. This violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

Drift Bot is configured with skip_if_unreported=True despite only reporting on Python/product-record changes, not all PR types. This violates the blueprint's Key Contract that only checks reporting on every pull request may appear in RequiredCheckSpec.

]


Expand Down Expand Up @@ -166,6 +181,14 @@ def evaluate(specs, runs):
for spec in specs:
matched = {n: r for n, r in best.items() if spec.matches(n)}

# When skip_if_unreported is set and no status has been posted at all,

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

MergeGateEvaluator now implements conditional skip logic that treats unreported checks as "passed (skipped)". The blueprint documents that MergeGateEvaluator has responsibility to "resolve each entry of RequiredCheckSpec against the check runs" with no conditional skipping logic, but the code adds undocumented responsibility for handling skip_if_unreported.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

MergeGateEvaluator now implements conditional skip logic (skip_if_unreported) that treats unreported checks as passed. The blueprint documents that MergeGateEvaluator "resolves each entry of RequiredCheckSpec against the check runs" with no conditional skipping responsibility, adding an undocumented capability.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

MergeGateEvaluator now implements conditional skip logic (skip_if_unreported) that treats unreported checks as "passed (skipped)". The blueprint documents that MergeGateEvaluator's only responsibility is to "resolve each entry of RequiredCheckSpec against the check runs" with no conditional skipping, adding an undocumented capability.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

MergeGateEvaluator now implements conditional skip logic (skip_if_unreported) that treats unreported checks as "passed (skipped)". The blueprint documents that MergeGateEvaluator's only responsibility is to "resolve each entry of RequiredCheckSpec against the check runs" with no conditional skipping, adding an undocumented capability.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

MergeGateEvaluator now implements conditional skip logic (skip_if_unreported) that treats unreported checks as "passed (skipped)". The blueprint specifies MergeGateEvaluator's responsibility is to "resolve each entry of RequiredCheckSpec against the check runs" with no conditional skipping for unreported checks, adding an undocumented capability that bypasses the Key Contract.

# treat the spec as passed (skipped). A reporter that posts but fails
# is still caught below -- this only short-circuits the "never posted"
# hang that occurs when a GitHub App does not evaluate this PR type.
if spec.skip_if_unreported and not matched:
results.append(SpecResult(spec, "passed", "no status reported, treated as skipped"))
Comment on lines 181 to +189

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint documents that MergeGateEvaluator "resolves each entry of RequiredCheckSpec against the check runs" and includes no responsibility for conditionally skipping checks. The code now implements conditional skip logic that treats unreported checks as passed, which adds an undocumented responsibility to the evaluator.

Comment on lines 181 to +189

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The blueprint documents that MergeGateEvaluator "resolves each entry of RequiredCheckSpec against the check runs" with no responsibility for conditionally skipping checks. The code now implements conditional skip logic (skip_if_unreported) that treats unreported checks as passed, adding an undocumented responsibility to the evaluator.

Comment on lines +184 to +189

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

MergeGateEvaluator now implements conditional skip logic (skip_if_unreported) that treats unreported checks as "passed (skipped)". The blueprint documents that MergeGateEvaluator's only responsibility is to "resolve each entry of RequiredCheckSpec against the check runs" with no conditional skipping, adding an undocumented capability.

Comment on lines +184 to +189

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

MergeGateEvaluator now implements conditional skip logic (skip_if_unreported) that treats unreported checks as passed. The blueprint documents that MergeGateEvaluator's responsibility is to "resolve each entry of RequiredCheckSpec against the check runs" with no conditional skipping, adding an undocumented capability.

Comment on lines +184 to +189

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

MergeGateEvaluator now implements conditional skip logic (skip_if_unreported) that treats unreported checks as "passed (skipped)". The blueprint documents that MergeGateEvaluator's only responsibility is to "resolve each entry of RequiredCheckSpec against the check runs" with no conditional skipping, adding an undocumented capability.

continue

failing = [
run
for run in matched.values()
Expand Down Expand Up @@ -312,7 +335,8 @@ def main():
if args.list:
for spec in REQUIRED_SPECS:
legs = f" x{spec.min_count}" if spec.min_count > 1 else ""
print(f"{spec.label}{legs}: {spec.pattern}")
suffix = " [skip_if_unreported]" if spec.skip_if_unreported else ""
print(f"{spec.label}{legs}: {spec.pattern}{suffix}")
return 0

token = os.environ.get("GITHUB_TOKEN", "")
Expand Down
10 changes: 7 additions & 3 deletions tests/test_c6_required_checks_single_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,13 @@ def test_a_failed_drift_bot_fails_the_gate():
assert result.state == "failed"


def test_a_missing_drift_bot_does_not_pass_the_gate():
"""No status at all must block, not silently satisfy the spec."""
def test_a_missing_drift_bot_skips_not_blocks():

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Drift Bot (ClawMetry) — Blueprint: Release Verification and Merge Gating

The test named test_a_missing_drift_bot_does_not_pass_the_gate is renamed to test_a_missing_drift_bot_skips_not_blocks with its expected behavior changed from "pending" (blocked) to "passed" (skipped), formalizing a departure from the blueprint's Key Contract that missing checks block the gate.

"""When skip_if_unreported=True and no status has been posted, the spec
passes as 'skipped' so frontend-only PRs are not held waiting forever.
A real failure (status posted + failing) still blocks -- see the test above."""
gate = _gate()
spec = next(s for s in gate.REQUIRED_SPECS if s.pattern == "drift-bot")
assert spec.skip_if_unreported, "Drift Bot spec must carry skip_if_unreported=True"
(result,) = gate.evaluate([spec], [])
assert result.state == "pending"
assert result.state == "passed"
assert "skipped" in result.detail
Loading