Skip to content

Gate full CI behind explicit approval - #123

Merged
IvGolovach merged 1 commit into
mainfrom
codex/grain-ci-economy
Aug 1, 2026
Merged

IvGolovach merged 1 commit into
mainfrom
codex/grain-ci-economy

Conversation

@IvGolovach

@IvGolovach IvGolovach commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Summary

  • keep automatic PR verification on GitHub-hosted Linux runners
  • require the successful Linux graph plus protected full-ci approval before the GitHub-hosted macOS SDK and evidence lane
  • add one fail-closed CI gate context and preserve exact PR-head evidence provenance
  • require workflow approval for every external fork contributor
  • group routine Dependabot updates monthly, disable rebases, cap the queue, and remove the unused privileged automerge workflow

Why

The prior graph ran macOS and evidence work for every PR and Dependabot rebase. A persistent self-hosted runner is not a safe boundary for a public repository. This change keeps full proof for code and every main SHA while requiring explicit maintainer intent before the platform lane starts.

Diff scope

One CI/ops/governance change: workflow orchestration, GitHub setting scripts and drift guards, Dependabot policy, evidence SHA binding, tests, ADR, and synchronized maintainer/LLM docs. No protocol bytes, conformance semantics, SDK API, dependency lockfile, package version, migration, or production runtime changed.

Branch integrity

  • base: main
  • validated base SHA: 5b10d9f0c88b6925b9bcb472e8c7714f4af88348
  • ahead/behind: 1/0
  • merge base: 5b10d9f0c88b6925b9bcb472e8c7714f4af88348
  • diff proof computed against freshly fetched origin/main

Commit integrity

  • 21d4e6ba96a300649c701115e040dd44693f9be1 Gate full CI behind explicit approval
  • one logical commit; final diff contains only intended CI, policy, test, ADR, and documentation files
  • Ledger-Id: GRAIN-CI-ECONOMY-A01 (exactly once)

Live settings already verified

  • full-ci: required reviewer IvGolovach, self-review allowed, no branch restriction
  • environment secrets: 0; variables: 0
  • fork workflow approval: all_external_contributors
  • self-hosted runners: 0
  • vulnerability alerts and Dependabot security updates: enabled

Diff hygiene

  • git diff --check origin/main...HEAD: PASS, no output
  • no secrets, credentials, local env files, caches, build output, or validation artifacts in the diff

Validation mode and proof

Tier 4 — CI / Ops / Governance.

  • pre-review full local proof: ./scripts/verify --out-dir artifacts/dev-verify-ci-economy-final-2: PASS
  • targeted policy, gate, evidence, and environment suites: PASS (latest focused run: 20 tests)
  • python3 tools/ci/check_dependabot_policy.py: PASS
  • python3 tools/ci/check_ci_economy_policy.py: PASS
  • actionlint -color .github/workflows/ci.yml .github/workflows/release-evidence.yml: PASS
  • docs link, flow, maintainer, and LLM integrity checks: PASS
  • scripts/ledger/check: PASS
  • scripts/ledger/check --history --base origin/main: PASS
  • version: not applicable — no version-significant product artifact changed
  • release and tag workflows: not run locally — not required before PR; remote CI proves the final SHA

Required remote gates

PASS on final SHA 21d4e6ba96a300649c701115e040dd44693f9be1. Workflow run 30721317129 completed the automatic Linux graph, protected full-ci approval, GitHub-hosted macOS SDK verification, evidence bundle, and final CI gate. CodeRabbit also reported success on the final SHA with no new inline findings.

The live main protection ruleset was then migrated and rechecked: active ruleset 14700860 requires exactly one status context, CI gate; check_branch_protection_drift.py passes. The PR is merge-ready.

CI context names change from python-tooling, rust-core, evidence-bundle, and capid-csprng-audit to the single CI gate.

Migration and runtime safety

  • DB migration: not applicable
  • runtime safety: no product runtime path changed
  • no new blocking locks, unbounded queues, or invariant removal
  • no invariant regression introduced

Documentation integrity

Maintainer, release, portability, dependency, audit, governance, ADR, changelog, and LLM routing docs are synchronized with the new workflow and live-setting contract.

Rollback

  • revert this PR
  • DB downgrade: not applicable
  • data repair: not applicable
  • the stricter external-fork approval and unused full-ci environment can safely remain while code rollback is evaluated

Known residual risks

None known. The migration gate completed in the required order: final CI gate success, live ruleset switch, drift verification, then merge readiness.

Summary by CodeRabbit

  • CI & Verification

    • Introduced a single fail-closed CI gate for required checks.
    • Pull requests now use scope-based verification, with protected approval for full macOS and evidence checks.
    • Main-branch pushes and manual runs execute the complete verification suite.
    • Obsolete runs are canceled automatically, with bounded artifact retention and GitHub-hosted runner safeguards.
  • Dependency Maintenance

    • Updates now run monthly, grouped and limited to two open requests per ecosystem.
    • Privileged automatic merging has been removed.
  • Documentation

    • Updated contribution, governance, release, and maintenance guidance for the new policies.

@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The change introduces scoped CI execution, a fail-closed CI gate, protected full-ci environment checks, CI policy validators, monthly Dependabot updates, removal of privileged automerge automation, explicit commit provenance, and aligned governance documentation.

Changes

CI governance and maintenance

Layer / File(s) Summary
Scoped CI execution and gate evaluation
.github/workflows/ci.yml, tools/ci/classify_ci_scope.py, tools/ci/evaluate_ci_gate.py, tools/ci/test_*.py
CI classifies event scope, gates full-CI jobs, records the effective commit SHA, applies artifact retention, and evaluates required job results through ci-gate.
CI policy and environment enforcement
.github/actions/*, tools/ci/check_*.py, tools/ci/test_check_*.py, tools/github/*, scripts/internal/verify_*.sh
Policy checks validate workflow contracts, branch protection, ruleset access, evidence provenance, and protected full-ci environment settings.
Dependabot policy and automation removal
.github/dependabot.yml, tools/ci/check_dependabot_policy.py, tools/ci/test_check_dependabot_policy.py, docs/human/dependencies-policy.md, adr/conformance/*
Dependabot uses monthly grouped updates, disabled rebasing, bounded pull requests, and manual merges. The privileged automerge workflow is removed.
Governance and operational documentation
CHANGELOG.md, CONTRIBUTING.md, GOVERNANCE.md, docs/human/*, docs/llm/*, conformance/security-regressions.v1.json
Repository, release, audit, portability, maintainer, and policy documentation describes the CI gate, full-CI approval, runner restrictions, evidence requirements, and dependency controls.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Sequence Diagram(s)

sequenceDiagram
  participant GitHubEvent
  participant classify_ci_scope
  participant CIJobs
  participant evaluate_ci_gate
  participant ci_gate
  GitHubEvent->>classify_ci_scope: Classify event and changed files
  classify_ci_scope->>CIJobs: Produce full_required
  CIJobs->>evaluate_ci_gate: Provide job results
  evaluate_ci_gate->>ci_gate: Evaluate required outcomes
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the primary change: requiring explicit approval before full CI runs.
Description check ✅ Passed The description is detailed and covers the changes, rationale, scope, validation, documentation, safety, rollback, and residual risks.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/grain-ci-economy

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 10

🧹 Nitpick comments (2)
.github/actions/build-evidence-bundle/action.yml (1)

164-164: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Declare commit_sha as an explicit composite-action input. The current fallback works for all callers, but it couples provenance to environment inheritance. Pass the input from every caller and use it at all three build-evidence-bundle sites and the rust-core-verification site.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/actions/build-evidence-bundle/action.yml at line 164, Declare
commit_sha as an explicit input in the composite actions, then pass and consume
that input instead of relying on CI_COMMIT_SHA or GITHUB_SHA fallbacks. Update
all three build-evidence-bundle invocation sites in
.github/actions/build-evidence-bundle/action.yml (line 164) and the
rust-core-verification invocation in
.github/actions/rust-core-verification/action.yml (line 35), ensuring every
caller supplies the provenance commit SHA.
tools/ci/evaluate_ci_gate.py (1)

10-22: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add an explicit CI job-completeness check.

ci.yml currently matches the gate collections, but check_ci_economy_policy.py does not enforce this relationship. A future job passed through --job can be ignored by evaluate(). Reject unrecognized job names or validate the workflow job list against the gate collections.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/ci/evaluate_ci_gate.py` around lines 10 - 22, Add explicit job-name
validation around the gate evaluation flow, using the BASE_JOBS, FULL_JOBS,
MAIN_JOBS, and APPROVAL_JOB collections as the complete allowed set. Ensure
evaluate() rejects or reports any --job value not present in those collections,
preventing unrecognized workflow jobs from being silently ignored.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/actions/build-evidence-bundle/action.yml:
- Line 72: Update the commit selection in the build-evidence bundle script
around CI_COMMIT_SHA so empty or unset values both fall back to GITHUB_SHA,
matching the shell fallback behavior used elsewhere. Ensure the commit written
to suite-summary.json matches the SHA used for the archive name.

In @.github/workflows/ci.yml:
- Around line 29-31: Add persist-credentials: false to the actions/checkout
steps in the scope, verify-script-smoke, and ci-gate jobs, preserving their
existing ref configuration and checkout behavior.
- Around line 565-581: Update the “Evaluate the fail-closed CI contract” step to
pass needs.scope.outputs.full_required through the step environment as
FULL_REQUIRED, then supply "${FULL_REQUIRED}" to --full-required instead of
interpolating it directly in the shell script. Keep the existing
full-ci-approval --job token unchanged.

In `@docs/human/audit/AUDIT-PACKET-v0.1.md`:
- Around line 177-180: Update the “Required CI check on main” section to
explicitly state that full-scope pull requests require successful Linux jobs,
protected full-ci-approval, and then successful platform SDK and evidence jobs;
preserve the existing CI gate description while documenting this approval
requirement.

In `@docs/human/release-process.md`:
- Around line 104-106: Align both documents with the complete full-scope CI
contract: in docs/human/release-process.md lines 104-106, replace “code PRs”
with “PRs whose scope requires full verification”; in
docs/human/repository-settings.md lines 115-116, replace “code or
executable-policy PR” with “full-scope PR” and define the categories as
executable automation, protocol, conformance, SDK, script, and unknown paths.

In `@docs/llm/FILE_MAP.md`:
- Line 27: Update the governance-related entry in docs/llm/FILE_MAP.md to
include tools/ci/check_branch_protection_drift.py,
tools/github/apply_branch_protection.sh, and tools/ci/check_dependabot_policy.py
alongside the existing enforcement sources.

In `@docs/llm/README.md`:
- Around line 49-50: Update the CI task bundle documented in the surrounding
list to match DOC_SYNC.md: include docs/human/release-process.md,
docs/human/portability-pack.md, docs/llm/CONFORMANCE.md, GOVERNANCE.md, and the
applicable ADR for CI, release, or provenance changes, while retaining the
existing required documents.

In `@tools/ci/check_ci_economy_policy.py`:
- Around line 137-148: Update check_no_self_hosted to detect runs-on: keys with
empty inline values and report them as invalid, including block-form runner
definitions. Also scan every workflow file’s content for the self-hosted token,
not just the workflow covered by check_ci_workflow, while preserving the
existing ALLOWED_HOSTED_RUNNERS validation for inline runner values.
- Around line 176-179: Update check_ruleset_token_contract so a missing action
or CI file produces an error entry instead of returning an empty list. Preserve
separate validation when both paths exist, and ensure the missing-file result
causes the fail-closed contract check to fail.

In `@tools/ci/check_dependabot_policy.py`:
- Around line 118-128: Update check_no_automerge to inspect every workflow for
Dependabot-triggered automerge behavior, including write-capable permissions and
merge operations using GITHUB_TOKEN, gh pr merge, or GitHub API calls, rather
than only matching the filename and obsolete token. Add rejection tests covering
renamed workflows for each supported merge mechanism while preserving existing
violations.

---

Nitpick comments:
In @.github/actions/build-evidence-bundle/action.yml:
- Line 164: Declare commit_sha as an explicit input in the composite actions,
then pass and consume that input instead of relying on CI_COMMIT_SHA or
GITHUB_SHA fallbacks. Update all three build-evidence-bundle invocation sites in
.github/actions/build-evidence-bundle/action.yml (line 164) and the
rust-core-verification invocation in
.github/actions/rust-core-verification/action.yml (line 35), ensuring every
caller supplies the provenance commit SHA.

In `@tools/ci/evaluate_ci_gate.py`:
- Around line 10-22: Add explicit job-name validation around the gate evaluation
flow, using the BASE_JOBS, FULL_JOBS, MAIN_JOBS, and APPROVAL_JOB collections as
the complete allowed set. Ensure evaluate() rejects or reports any --job value
not present in those collections, preventing unrecognized workflow jobs from
being silently ignored.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0c848030-c9a5-47ec-9266-ad32380c0776

📥 Commits

Reviewing files that changed from the base of the PR and between 5b10d9f and d44eaa1.

📒 Files selected for processing (40)
  • .github/actions/build-evidence-bundle/action.yml
  • .github/actions/python-policy-checks/action.yml
  • .github/actions/rust-core-verification/action.yml
  • .github/dependabot.yml
  • .github/pull_request_template.md
  • .github/workflows/ci.yml
  • .github/workflows/dependabot-automerge.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • GOVERNANCE.md
  • adr/conformance/0004-dependabot-strict-fail-closed.md
  • adr/conformance/0006-ci-economy-and-trusted-runners.md
  • conformance/security-regressions.v1.json
  • docs/human/audit/AUDIT-PACKET-v0.1.md
  • docs/human/dependencies-policy.md
  • docs/human/maintainer-start-here.md
  • docs/human/portability-pack.md
  • docs/human/release-process.md
  • docs/human/repository-settings.md
  • docs/human/sdk/version-matrix.md
  • docs/llm/CHANGE_POLICY.md
  • docs/llm/CONFORMANCE.md
  • docs/llm/DOC_SYNC.md
  • docs/llm/FILE_MAP.md
  • docs/llm/README.md
  • scripts/internal/verify_dev.sh
  • scripts/internal/verify_in_container.sh
  • tools/ci/check_branch_protection_drift.py
  • tools/ci/check_ci_economy_policy.py
  • tools/ci/check_dependabot_policy.py
  • tools/ci/check_full_ci_environment.py
  • tools/ci/classify_ci_scope.py
  • tools/ci/evaluate_ci_gate.py
  • tools/ci/test_check_ci_economy_policy.py
  • tools/ci/test_check_dependabot_policy.py
  • tools/ci/test_check_full_ci_environment.py
  • tools/ci/test_classify_ci_scope.py
  • tools/ci/test_evaluate_ci_gate.py
  • tools/github/apply_branch_protection.sh
  • tools/github/apply_full_ci_environment.sh
💤 Files with no reviewable changes (1)
  • .github/workflows/dependabot-automerge.yml

Comment thread .github/actions/build-evidence-bundle/action.yml Outdated
Comment thread .github/workflows/ci.yml
Comment thread .github/workflows/ci.yml
Comment thread docs/human/audit/AUDIT-PACKET-v0.1.md Outdated
Comment thread docs/human/release-process.md Outdated
Comment thread docs/llm/FILE_MAP.md Outdated
Comment thread docs/llm/README.md
Comment thread tools/ci/check_ci_economy_policy.py
Comment thread tools/ci/check_ci_economy_policy.py
Comment thread tools/ci/check_dependabot_policy.py
@IvGolovach
IvGolovach force-pushed the codex/grain-ci-economy branch from d44eaa1 to a213436 Compare August 1, 2026 21:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (4)
tools/ci/test_check_dependabot_policy.py (1)

81-98: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add rejection tests for rebases and update types.

The acceptance fixture does not prevent regressions that allow rebase-strategy: enabled or incorrect ecosystem update types. Add one mutation test for each constraint enforced by check_config.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/ci/test_check_dependabot_policy.py` around lines 81 - 98, Extend the
policy rejection tests alongside test_weekly_schedule_is_rejected,
test_excessive_open_pr_limit_is_rejected, and test_missing_group_is_rejected
with mutation tests for each rebases and ecosystem update-type constraint
enforced by policy.check_config. Mutate GOOD_CONFIG to enable rebase-strategy
and to use each invalid update type, then assert the returned errors contain the
corresponding constraint messages.
tools/ci/test_check_ci_economy_policy.py (1)

119-144: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Resolve the live workflow paths from the test file location.

Both tests read .github/workflows/ci.yml and tools/ci/evaluate_ci_gate.py through relative paths. The tests then pass only when the working directory is the repository root. If a runner starts from another directory, test_new_workflow_job_forgotten_by_gate_is_rejected raises FileNotFoundError, and test_live_gate_job_sets_match_the_evaluator fails with a "missing workflow" error instead of a parity error.

Derive the repository root from __file__ to make both tests location-independent.

♻️ Proposed refactor
+REPO_ROOT = Path(__file__).resolve().parents[2]
+LIVE_CI = REPO_ROOT / ".github/workflows/ci.yml"
+LIVE_EVALUATOR = REPO_ROOT / "tools/ci/evaluate_ci_gate.py"
+
+
 class CIEconomyPolicyTests(unittest.TestCase):
     def test_live_gate_job_sets_match_the_evaluator(self) -> None:
         self.assertEqual(
             [],
-            policy.check_ci_gate_job_parity(
-                Path(".github/workflows/ci.yml"),
-                Path("tools/ci/evaluate_ci_gate.py"),
-            ),
+            policy.check_ci_gate_job_parity(LIVE_CI, LIVE_EVALUATOR),
         )
 
     def test_new_workflow_job_forgotten_by_gate_is_rejected(self) -> None:
         with tempfile.TemporaryDirectory() as td:
             path = Path(td) / "ci.yml"
-            current = Path(".github/workflows/ci.yml").read_text(encoding="utf-8")
+            current = LIVE_CI.read_text(encoding="utf-8")
             path.write_text(
                 current.replace(
                     "  ci-gate:\n",
                     "  future-unreviewed-job:\n    runs-on: ubuntu-latest\n\n  ci-gate:\n",
                     1,
                 ),
                 encoding="utf-8",
             )
-            errors = policy.check_ci_gate_job_parity(
-                path,
-                Path("tools/ci/evaluate_ci_gate.py"),
-            )
+            errors = policy.check_ci_gate_job_parity(path, LIVE_EVALUATOR)
             self.assertTrue(any("workflow upstream jobs mismatch" in error for error in errors))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/ci/test_check_ci_economy_policy.py` around lines 119 - 144, Update both
test methods, test_live_gate_job_sets_match_the_evaluator and
test_new_workflow_job_forgotten_by_gate_is_rejected, to derive the repository
root from __file__ and construct absolute paths to .github/workflows/ci.yml and
tools/ci/evaluate_ci_gate.py. Reuse those resolved paths for reading and for
check_ci_gate_job_parity so the tests work independently of the current working
directory.
tools/ci/check_ci_economy_policy.py (1)

196-205: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Accept flow-style needs in the parity check.

gate_needs matches only block-sequence entries at six-space indentation. If a maintainer rewrites ci-gate to use needs: [scope, sdk-platform, ...], gate_needs becomes empty and the checker reports a parity mismatch for a valid workflow. The failure text then points at missing job names instead of the formatting rule that caused it.

Parse both forms, or state the required block-sequence format in the error message.

♻️ Proposed refactor
     gate = job_block(text, "ci-gate")
-    gate_needs = set(re.findall(r"(?m)^      - ([A-Za-z0-9_-]+)[ \t]*$", gate))
+    gate_needs = set(re.findall(r"(?m)^      - ([A-Za-z0-9_-]+)[ \t]*$", gate))
+    for flow in re.findall(r"(?m)^    needs:[ \t]*\[([^\]]*)\][ \t]*$", gate):
+        gate_needs.update(entry.strip() for entry in flow.split(",") if entry.strip())
     gate_arguments = set(re.findall(r'--job "([A-Za-z0-9_-]+)=', gate))
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/ci/check_ci_economy_policy.py` around lines 196 - 205, Update the
parity parsing around gate_needs in the CI economy policy checker to recognize
both block-sequence needs entries and flow-style needs lists such as needs:
[scope, sdk-platform]. Preserve the existing job-name matching and parity
validation, ensuring valid flow-style workflows do not report missing jobs; if
flow style remains unsupported, explicitly state that formatting requirement in
the mismatch error.
.github/actions/rust-core-verification/action.yml (1)

4-18: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add explicit commit_sha validation.

All current callers provide commit_sha. Replace the silent empty-value check with a diagnostic and a 40-character hexadecimal SHA check.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/actions/rust-core-verification/action.yml around lines 4 - 18,
Update the “Validate Rust evidence commit provenance” step to emit a clear
diagnostic when commit_sha is missing, then validate that COMMIT_SHA is exactly
40 hexadecimal characters. Keep the existing required input contract and fail
the composite action for either missing or malformed values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@GOVERNANCE.md`:
- Around line 60-65: Update the CI gate requirements section in GOVERNANCE.md to
state that full-scope pull requests also require successful macOS SDK and
evidence jobs, in addition to maintainer approval through the protected full-ci
environment. Align the wording with docs/human/repository-settings.md and ADR
0006, making clear that full-ci approval alone is insufficient.

In `@tools/ci/check_dependabot_policy.py`:
- Around line 128-132: Update check_no_automerge to accumulate the privileged
Dependabot automerge violation when dependabot-automerge.yml exists, then
continue scanning remaining workflow files for obsolete tokens and merge
primitives before returning all collected errors.

In `@tools/ci/check_full_ci_environment.py`:
- Around line 102-119: Update the subprocess.run call in gh_json to include a
bounded timeout so a hanging gh api request fails promptly; preserve the
existing list-form arguments, error handling, and JSON parsing behavior.

---

Nitpick comments:
In @.github/actions/rust-core-verification/action.yml:
- Around line 4-18: Update the “Validate Rust evidence commit provenance” step
to emit a clear diagnostic when commit_sha is missing, then validate that
COMMIT_SHA is exactly 40 hexadecimal characters. Keep the existing required
input contract and fail the composite action for either missing or malformed
values.

In `@tools/ci/check_ci_economy_policy.py`:
- Around line 196-205: Update the parity parsing around gate_needs in the CI
economy policy checker to recognize both block-sequence needs entries and
flow-style needs lists such as needs: [scope, sdk-platform]. Preserve the
existing job-name matching and parity validation, ensuring valid flow-style
workflows do not report missing jobs; if flow style remains unsupported,
explicitly state that formatting requirement in the mismatch error.

In `@tools/ci/test_check_ci_economy_policy.py`:
- Around line 119-144: Update both test methods,
test_live_gate_job_sets_match_the_evaluator and
test_new_workflow_job_forgotten_by_gate_is_rejected, to derive the repository
root from __file__ and construct absolute paths to .github/workflows/ci.yml and
tools/ci/evaluate_ci_gate.py. Reuse those resolved paths for reading and for
check_ci_gate_job_parity so the tests work independently of the current working
directory.

In `@tools/ci/test_check_dependabot_policy.py`:
- Around line 81-98: Extend the policy rejection tests alongside
test_weekly_schedule_is_rejected, test_excessive_open_pr_limit_is_rejected, and
test_missing_group_is_rejected with mutation tests for each rebases and
ecosystem update-type constraint enforced by policy.check_config. Mutate
GOOD_CONFIG to enable rebase-strategy and to use each invalid update type, then
assert the returned errors contain the corresponding constraint messages.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 18f5b6ad-1104-4204-91ab-0f123a505281

📥 Commits

Reviewing files that changed from the base of the PR and between d44eaa1 and a213436.

📒 Files selected for processing (41)
  • .github/actions/build-evidence-bundle/action.yml
  • .github/actions/python-policy-checks/action.yml
  • .github/actions/rust-core-verification/action.yml
  • .github/dependabot.yml
  • .github/pull_request_template.md
  • .github/workflows/ci.yml
  • .github/workflows/dependabot-automerge.yml
  • .github/workflows/release-evidence.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • GOVERNANCE.md
  • adr/conformance/0004-dependabot-strict-fail-closed.md
  • adr/conformance/0006-ci-economy-and-trusted-runners.md
  • conformance/security-regressions.v1.json
  • docs/human/audit/AUDIT-PACKET-v0.1.md
  • docs/human/dependencies-policy.md
  • docs/human/maintainer-start-here.md
  • docs/human/portability-pack.md
  • docs/human/release-process.md
  • docs/human/repository-settings.md
  • docs/human/sdk/version-matrix.md
  • docs/llm/CHANGE_POLICY.md
  • docs/llm/CONFORMANCE.md
  • docs/llm/DOC_SYNC.md
  • docs/llm/FILE_MAP.md
  • docs/llm/README.md
  • scripts/internal/verify_dev.sh
  • scripts/internal/verify_in_container.sh
  • tools/ci/check_branch_protection_drift.py
  • tools/ci/check_ci_economy_policy.py
  • tools/ci/check_dependabot_policy.py
  • tools/ci/check_full_ci_environment.py
  • tools/ci/classify_ci_scope.py
  • tools/ci/evaluate_ci_gate.py
  • tools/ci/test_check_ci_economy_policy.py
  • tools/ci/test_check_dependabot_policy.py
  • tools/ci/test_check_full_ci_environment.py
  • tools/ci/test_classify_ci_scope.py
  • tools/ci/test_evaluate_ci_gate.py
  • tools/github/apply_branch_protection.sh
  • tools/github/apply_full_ci_environment.sh
💤 Files with no reviewable changes (1)
  • .github/workflows/dependabot-automerge.yml
🚧 Files skipped from review as they are similar to previous changes (27)
  • scripts/internal/verify_dev.sh
  • .github/pull_request_template.md
  • scripts/internal/verify_in_container.sh
  • conformance/security-regressions.v1.json
  • CONTRIBUTING.md
  • adr/conformance/0004-dependabot-strict-fail-closed.md
  • tools/github/apply_branch_protection.sh
  • docs/llm/DOC_SYNC.md
  • docs/llm/CHANGE_POLICY.md
  • tools/ci/test_check_full_ci_environment.py
  • docs/human/maintainer-start-here.md
  • tools/ci/test_evaluate_ci_gate.py
  • docs/human/sdk/version-matrix.md
  • tools/github/apply_full_ci_environment.sh
  • .github/actions/python-policy-checks/action.yml
  • tools/ci/test_classify_ci_scope.py
  • tools/ci/evaluate_ci_gate.py
  • docs/human/portability-pack.md
  • docs/human/audit/AUDIT-PACKET-v0.1.md
  • docs/llm/CONFORMANCE.md
  • .github/dependabot.yml
  • CHANGELOG.md
  • .github/actions/build-evidence-bundle/action.yml
  • docs/human/release-process.md
  • tools/ci/classify_ci_scope.py
  • .github/workflows/ci.yml
  • tools/ci/check_branch_protection_drift.py

Comment thread GOVERNANCE.md
Comment thread tools/ci/check_dependabot_policy.py
@IvGolovach
IvGolovach force-pushed the codex/grain-ci-economy branch from a213436 to 18dc20a Compare August 1, 2026 22:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
tools/ci/check_dependabot_policy.py (1)

45-68: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider parsing the Dependabot configuration with a YAML loader.

The helpers require fixed indentation and package-ecosystem as the first key. Valid YAML formatting changes can cause false policy errors. Add a declared YAML dependency before replacing the regex parser.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tools/ci/check_dependabot_policy.py` around lines 45 - 68, Replace the
indentation-sensitive regex parsing in scalar, split_update_blocks, and
update_types with a YAML loader that parses the Dependabot configuration
structurally, regardless of key order or valid indentation changes. Add and
declare the required YAML dependency before updating these helpers, while
preserving their existing returned values and policy behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tools/ci/check_dependabot_policy.py`:
- Around line 96-98: Update the open-pull-requests-limit validation in
check_config to accept only the documented value 2, and adjust the accompanying
validation error text to state that the limit must be 2. Leave the existing
missing and non-numeric validation behavior unchanged.

In `@tools/ci/check_full_ci_environment.py`:
- Around line 105-128: Update gh_json to catch subprocess process-start failures
such as FileNotFoundError and JSON decoding failures from json.loads, then
re-raise each as RuntimeError with useful endpoint context. Keep timeout and
nonzero-return handling intact so all gh_json failures are normalized for main’s
existing error messages.
- Around line 136-140: Update the main drift-check invocation in the Python
policy checks action to pass --check-owner-only-settings to the
check_full_ci_environment command, ensuring secrets, variables, and
external-fork approval validation run.

---

Nitpick comments:
In `@tools/ci/check_dependabot_policy.py`:
- Around line 45-68: Replace the indentation-sensitive regex parsing in scalar,
split_update_blocks, and update_types with a YAML loader that parses the
Dependabot configuration structurally, regardless of key order or valid
indentation changes. Add and declare the required YAML dependency before
updating these helpers, while preserving their existing returned values and
policy behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0d292a84-bfb6-4bba-9c0f-2d46107069c9

📥 Commits

Reviewing files that changed from the base of the PR and between a213436 and 18dc20a.

📒 Files selected for processing (41)
  • .github/actions/build-evidence-bundle/action.yml
  • .github/actions/python-policy-checks/action.yml
  • .github/actions/rust-core-verification/action.yml
  • .github/dependabot.yml
  • .github/pull_request_template.md
  • .github/workflows/ci.yml
  • .github/workflows/dependabot-automerge.yml
  • .github/workflows/release-evidence.yml
  • CHANGELOG.md
  • CONTRIBUTING.md
  • GOVERNANCE.md
  • adr/conformance/0004-dependabot-strict-fail-closed.md
  • adr/conformance/0006-ci-economy-and-trusted-runners.md
  • conformance/security-regressions.v1.json
  • docs/human/audit/AUDIT-PACKET-v0.1.md
  • docs/human/dependencies-policy.md
  • docs/human/maintainer-start-here.md
  • docs/human/portability-pack.md
  • docs/human/release-process.md
  • docs/human/repository-settings.md
  • docs/human/sdk/version-matrix.md
  • docs/llm/CHANGE_POLICY.md
  • docs/llm/CONFORMANCE.md
  • docs/llm/DOC_SYNC.md
  • docs/llm/FILE_MAP.md
  • docs/llm/README.md
  • scripts/internal/verify_dev.sh
  • scripts/internal/verify_in_container.sh
  • tools/ci/check_branch_protection_drift.py
  • tools/ci/check_ci_economy_policy.py
  • tools/ci/check_dependabot_policy.py
  • tools/ci/check_full_ci_environment.py
  • tools/ci/classify_ci_scope.py
  • tools/ci/evaluate_ci_gate.py
  • tools/ci/test_check_ci_economy_policy.py
  • tools/ci/test_check_dependabot_policy.py
  • tools/ci/test_check_full_ci_environment.py
  • tools/ci/test_classify_ci_scope.py
  • tools/ci/test_evaluate_ci_gate.py
  • tools/github/apply_branch_protection.sh
  • tools/github/apply_full_ci_environment.sh
💤 Files with no reviewable changes (1)
  • .github/workflows/dependabot-automerge.yml
🚧 Files skipped from review as they are similar to previous changes (35)
  • CONTRIBUTING.md
  • CHANGELOG.md
  • tools/ci/check_branch_protection_drift.py
  • adr/conformance/0006-ci-economy-and-trusted-runners.md
  • adr/conformance/0004-dependabot-strict-fail-closed.md
  • tools/github/apply_branch_protection.sh
  • .github/workflows/release-evidence.yml
  • scripts/internal/verify_dev.sh
  • conformance/security-regressions.v1.json
  • docs/human/sdk/version-matrix.md
  • docs/llm/CHANGE_POLICY.md
  • docs/human/maintainer-start-here.md
  • .github/actions/build-evidence-bundle/action.yml
  • GOVERNANCE.md
  • scripts/internal/verify_in_container.sh
  • docs/human/audit/AUDIT-PACKET-v0.1.md
  • tools/ci/test_evaluate_ci_gate.py
  • .github/actions/rust-core-verification/action.yml
  • docs/human/release-process.md
  • tools/github/apply_full_ci_environment.sh
  • docs/llm/DOC_SYNC.md
  • .github/pull_request_template.md
  • tools/ci/test_check_full_ci_environment.py
  • .github/actions/python-policy-checks/action.yml
  • docs/human/portability-pack.md
  • tools/ci/test_classify_ci_scope.py
  • tools/ci/classify_ci_scope.py
  • docs/llm/README.md
  • docs/llm/CONFORMANCE.md
  • tools/ci/test_check_dependabot_policy.py
  • docs/human/dependencies-policy.md
  • .github/workflows/ci.yml
  • .github/dependabot.yml
  • tools/ci/evaluate_ci_gate.py
  • tools/ci/test_check_ci_economy_policy.py

Comment thread tools/ci/check_dependabot_policy.py
Comment thread tools/ci/check_full_ci_environment.py Outdated
Comment thread tools/ci/check_full_ci_environment.py
Validation
* Validation tier: Tier 4 — CI / Ops / Governance; final review corrections used Tier 2R targeted proof before mandatory remote CI.
* git diff --check: PASS
* git diff --cached --check: PASS
* Previous full local proof on pre-review SHA d44eaa1: ./scripts/verify --out-dir artifacts/dev-verify-ci-economy-final-2: PASS
* Previous full remote proof on review SHA 18dc20a: Linux graph, protected approval, macOS SDK, evidence bundle, and CI gate: PASS
* PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tools.ci.test_evaluate_ci_gate tools.ci.test_check_ci_economy_policy tools.ci.test_check_dependabot_policy: PASS (38 tests)
* PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tools.ci.test_check_release_evidence_assets tools.ci.test_check_workflow_action_pinning: PASS (4 tests)
* PYTHONDONTWRITEBYTECODE=1 python3 -m unittest tools.ci.test_check_dependabot_policy tools.ci.test_check_full_ci_environment: PASS (20 tests after final review corrections)
* python3 tools/ci/check_dependabot_policy.py: PASS
* python3 tools/ci/check_ci_economy_policy.py: PASS
* actionlint -color .github/workflows/ci.yml .github/workflows/release-evidence.yml: PASS
* LLM docs, docs flow, release-train docs, and maintainer docs checks: PASS
* GitHub full-CI settings apply and owner-only drift check: PASS
* Ledger: PASS, scripts/ledger/check and history check against origin/main
* Version: not applicable — no protocol, package, SDK API, or runtime artifact version changed.
* Not run: release and tag workflows — not required before PR; mandatory remote CI will prove the final SHA.

Rollback
* git revert HEAD
* The stricter external-fork approval and unused full-ci environment may remain safely in place during rollback.

Ledger-Id: GRAIN-CI-ECONOMY-A01
@IvGolovach
IvGolovach force-pushed the codex/grain-ci-economy branch from 18dc20a to 21d4e6b Compare August 1, 2026 22:27
@IvGolovach
IvGolovach merged commit b6ce5d8 into main Aug 1, 2026
14 checks passed
@IvGolovach
IvGolovach deleted the codex/grain-ci-economy branch August 1, 2026 22:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant