Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
16 changes: 11 additions & 5 deletions .github/workflows/issue-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,19 @@ permissions:
jobs:
check-linked-issue:
runs-on: ubuntu-latest
# Closes #1059: bypass Issue Gate for trusted bots (Dependabot opens dep PRs without issues)
if: >-
github.actor != 'dependabot[bot]' && github.actor != 'github-actions[bot]'
&& github.event.pull_request.user.login != 'dependabot[bot]'
&& github.event.pull_request.user.login != 'github-actions[bot]'
# Closes #1031: trusted bots (Dependabot) PASS this required gate as a no-op
# instead of SKIPPING it (a skipped required check never satisfies branch
# protection). Detect bot via trigger actor AND PR author login (survives a
# human 'Update branch'); short-circuit the substantive step.
env:
IS_BOT: ${{ (github.actor == 'dependabot[bot]' || github.actor == 'github-actions[bot]' || github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'github-actions[bot]') && 'true' || 'false' }}
steps:
- name: Trusted-bot bypass (no-op pass)
if: env.IS_BOT == 'true'
run: echo "Trusted bot PR -- Dependabot or github-actions -- Issue Gate passes as no-op (Closes #1031)."

- name: Check for linked issues in PR
if: env.IS_BOT != 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
PR_TITLE: ${{ github.event.pull_request.title }}
Expand Down
20 changes: 15 additions & 5 deletions .github/workflows/l1-traceability.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ jobs:
check-traceability:
name: Check L1 TRACEABILITY
runs-on: ubuntu-latest
# Closes #1059: bypass L1 gate for trusted bots (Dependabot maintains deps, not features)
if: >-
github.actor != 'dependabot[bot]' && github.actor != 'github-actions[bot]'
&& github.event.pull_request.user.login != 'dependabot[bot]'
&& github.event.pull_request.user.login != 'github-actions[bot]'
# Closes #1031: trusted bots (Dependabot) PASS this required gate as a no-op
# instead of SKIPPING it. A skipped required check never satisfies branch
# protection, so the job must RUN and conclude success. We detect the bot via
# both the trigger actor and the PR author login (the latter survives a human
# 'Update branch') and short-circuit the substantive steps.
env:
IS_BOT: ${{ (github.actor == 'dependabot[bot]' || github.actor == 'github-actions[bot]' || github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'github-actions[bot]') && 'true' || 'false' }}
steps:
- name: Trusted-bot bypass (no-op pass)
if: env.IS_BOT == 'true'
run: echo "Trusted bot PR -- Dependabot or github-actions -- L1 TRACEABILITY gate passes as no-op (Closes #1031)."

- name: Checkout repository
if: env.IS_BOT != 'true'
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Check for Closes #N in commits
if: env.IS_BOT != 'true'
id: check-commits
run: |
set -e
Expand Down Expand Up @@ -86,6 +94,7 @@ jobs:
fi

- name: Check L2 GENERATION (gen/ edits forbidden)
if: env.IS_BOT != 'true'
id: check-generation
run: |
set -e
Expand Down Expand Up @@ -116,6 +125,7 @@ jobs:
echo " ✓ No gen/ edits detected (new files allowed)"

- name: Check L3 PURITY (ASCII-only identifiers)
if: env.IS_BOT != 'true'
id: check-purity
run: |
set -e
Expand Down
23 changes: 16 additions & 7 deletions .github/workflows/now-sync-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,41 @@ on:
jobs:
check-now-freshness:
runs-on: ubuntu-latest
# Closes #1059: bypass NOW Sync Gate for trusted bots (deps PRs don't touch docs/NOW.md)
if: >-
github.actor != 'dependabot[bot]' && github.actor != 'github-actions[bot]'
&& github.event.pull_request.user.login != 'dependabot[bot]'
&& github.event.pull_request.user.login != 'github-actions[bot]'
# Closes #1031: trusted bots (Dependabot) PASS this required gate as a no-op
# instead of SKIPPING it (a skipped required check never satisfies branch
# protection). Detect bot via trigger actor AND PR author login (survives a
# human 'Update branch'); short-circuit the substantive steps. push events
# keep their existing behavior because pull_request is null there.
env:
IS_BOT: ${{ (github.actor == 'dependabot[bot]' || github.actor == 'github-actions[bot]' || github.event.pull_request.user.login == 'dependabot[bot]' || github.event.pull_request.user.login == 'github-actions[bot]') && 'true' || 'false' }}
steps:
- name: Trusted-bot bypass (no-op pass)
if: env.IS_BOT == 'true'
run: echo "Trusted bot PR -- Dependabot or github-actions -- NOW Sync Gate passes as no-op (Closes #1031)."

- uses: actions/checkout@v4
if: env.IS_BOT != 'true'
with:
fetch-depth: 0

- name: Check docs/NOW.md is updated (pull_request)
if: github.event_name == 'pull_request'
if: env.IS_BOT != 'true' && github.event_name == 'pull_request'
env:
GITHUB_EVENT_NAME: pull_request
PR_BASE_SHA: ${{ github.event.pull_request.base.sha }}
PR_HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: bash scripts/ci/now-sync-gate-diff.sh

- name: Check docs/NOW.md is updated (push)
if: github.event_name == 'push'
if: env.IS_BOT != 'true' && github.event_name == 'push'
env:
GITHUB_EVENT_NAME: push
PUSH_BEFORE: ${{ github.event.before }}
PUSH_AFTER: ${{ github.sha }}
run: bash scripts/ci/now-sync-gate-diff.sh

- name: Validate NOW.md date is today or recent
if: env.IS_BOT != 'true'
run: |
set -euo pipefail
TODAY=$(date -u +%Y-%m-%d)
Expand All @@ -51,6 +59,7 @@ jobs:
echo "✅ NOW.md freshness check passed: $LAST (UTC window: $YESTERDAY .. $TODAY)"

- name: Check agent sync JSON exists
if: env.IS_BOT != 'true'
run: |
if [ ! -f ".trinity/state/github-sync.json" ]; then
echo "::warning::Agent sync file missing: .trinity/state/github-sync.json"
Expand Down
6 changes: 6 additions & 0 deletions docs/NOW.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Last updated: 2026-06-14

## ci-bot-gate-pass-not-skip -- trusted-bot gates PASS as no-op instead of SKIP (Closes #1031)

- **WHERE** (CI only): `.github/workflows/l1-traceability.yml`, `.github/workflows/issue-gate.yml`, `.github/workflows/now-sync-gate.yml`. Replaces the job-level `if:` bot-skip with a job-level `env.IS_BOT` flag (true when `github.actor` OR `github.event.pull_request.user.login` is `dependabot[bot]`/`github-actions[bot]`). The job now always RUNS; a leading no-op step passes for bots and every substantive step is guarded with `if: env.IS_BOT != 'true'`. No source, specs, codegen, conformance JSON, or `gen/` artefacts touched.
- **Why**: `check-now-freshness`, `validate`, `check`, `check-linked-issue` are REQUIRED status checks in ruleset `t27-master-protection`. The earlier author-guard fix made the gate jobs SKIP for Dependabot, but a SKIPPED required check never satisfies branch protection (`N of N required status checks are expected`), so dep PRs #1043/#1047/#1048/#1057/#1058 (and earlier #1045) stayed unmergeable even with admin. Making the job RUN and conclude `success` (all substantive steps skipped, the required context still reports green) satisfies the ruleset while keeping human PRs fully gated by Constitutional Law L1. `push` events keep their existing now-sync behavior (`pull_request` null => IS_BOT false unless a bot actor pushes). L6 untouched; L5 untouched (no silicon impact); L4 not applicable (workflow YAML). Closes #1031.
- **Anchor**: phi^2 + phi^-2 = 3

## ci-bot-bypass-author-guard -- harden trusted-bot gate bypass against human branch-updates (Closes #1031)

- **WHERE** (CI only): `.github/workflows/l1-traceability.yml`, `.github/workflows/issue-gate.yml`, `.github/workflows/now-sync-gate.yml`. Each gate job's `if:` guard is extended from the actor-only check (`github.actor != 'dependabot[bot]' && != 'github-actions[bot]'`) to ALSO require `github.event.pull_request.user.login != 'dependabot[bot]'` and `!= 'github-actions[bot]'`. No source, no specs, no codegen, no conformance JSON, no `gen/` artefacts touched.
Expand Down
Loading