Gate full CI behind explicit approval - #123
Conversation
📝 WalkthroughWalkthroughThe change introduces scoped CI execution, a fail-closed ChangesCI governance and maintenance
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
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (2)
.github/actions/build-evidence-bundle/action.yml (1)
164-164: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick winDeclare
commit_shaas 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 threebuild-evidence-bundlesites and therust-core-verificationsite.🤖 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 winAdd an explicit CI job-completeness check.
ci.ymlcurrently matches the gate collections, butcheck_ci_economy_policy.pydoes not enforce this relationship. A future job passed through--jobcan be ignored byevaluate(). 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
📒 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.ymlCHANGELOG.mdCONTRIBUTING.mdGOVERNANCE.mdadr/conformance/0004-dependabot-strict-fail-closed.mdadr/conformance/0006-ci-economy-and-trusted-runners.mdconformance/security-regressions.v1.jsondocs/human/audit/AUDIT-PACKET-v0.1.mddocs/human/dependencies-policy.mddocs/human/maintainer-start-here.mddocs/human/portability-pack.mddocs/human/release-process.mddocs/human/repository-settings.mddocs/human/sdk/version-matrix.mddocs/llm/CHANGE_POLICY.mddocs/llm/CONFORMANCE.mddocs/llm/DOC_SYNC.mddocs/llm/FILE_MAP.mddocs/llm/README.mdscripts/internal/verify_dev.shscripts/internal/verify_in_container.shtools/ci/check_branch_protection_drift.pytools/ci/check_ci_economy_policy.pytools/ci/check_dependabot_policy.pytools/ci/check_full_ci_environment.pytools/ci/classify_ci_scope.pytools/ci/evaluate_ci_gate.pytools/ci/test_check_ci_economy_policy.pytools/ci/test_check_dependabot_policy.pytools/ci/test_check_full_ci_environment.pytools/ci/test_classify_ci_scope.pytools/ci/test_evaluate_ci_gate.pytools/github/apply_branch_protection.shtools/github/apply_full_ci_environment.sh
💤 Files with no reviewable changes (1)
- .github/workflows/dependabot-automerge.yml
d44eaa1 to
a213436
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (4)
tools/ci/test_check_dependabot_policy.py (1)
81-98: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAdd rejection tests for rebases and update types.
The acceptance fixture does not prevent regressions that allow
rebase-strategy: enabledor incorrect ecosystem update types. Add one mutation test for each constraint enforced bycheck_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 winResolve the live workflow paths from the test file location.
Both tests read
.github/workflows/ci.ymlandtools/ci/evaluate_ci_gate.pythrough 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_rejectedraisesFileNotFoundError, andtest_live_gate_job_sets_match_the_evaluatorfails 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 winAccept flow-style
needsin the parity check.
gate_needsmatches only block-sequence entries at six-space indentation. If a maintainer rewritesci-gateto useneeds: [scope, sdk-platform, ...],gate_needsbecomes 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 winAdd explicit
commit_shavalidation.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
📒 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.ymlCHANGELOG.mdCONTRIBUTING.mdGOVERNANCE.mdadr/conformance/0004-dependabot-strict-fail-closed.mdadr/conformance/0006-ci-economy-and-trusted-runners.mdconformance/security-regressions.v1.jsondocs/human/audit/AUDIT-PACKET-v0.1.mddocs/human/dependencies-policy.mddocs/human/maintainer-start-here.mddocs/human/portability-pack.mddocs/human/release-process.mddocs/human/repository-settings.mddocs/human/sdk/version-matrix.mddocs/llm/CHANGE_POLICY.mddocs/llm/CONFORMANCE.mddocs/llm/DOC_SYNC.mddocs/llm/FILE_MAP.mddocs/llm/README.mdscripts/internal/verify_dev.shscripts/internal/verify_in_container.shtools/ci/check_branch_protection_drift.pytools/ci/check_ci_economy_policy.pytools/ci/check_dependabot_policy.pytools/ci/check_full_ci_environment.pytools/ci/classify_ci_scope.pytools/ci/evaluate_ci_gate.pytools/ci/test_check_ci_economy_policy.pytools/ci/test_check_dependabot_policy.pytools/ci/test_check_full_ci_environment.pytools/ci/test_classify_ci_scope.pytools/ci/test_evaluate_ci_gate.pytools/github/apply_branch_protection.shtools/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
a213436 to
18dc20a
Compare
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (1)
tools/ci/check_dependabot_policy.py (1)
45-68: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueConsider parsing the Dependabot configuration with a YAML loader.
The helpers require fixed indentation and
package-ecosystemas 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
📒 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.ymlCHANGELOG.mdCONTRIBUTING.mdGOVERNANCE.mdadr/conformance/0004-dependabot-strict-fail-closed.mdadr/conformance/0006-ci-economy-and-trusted-runners.mdconformance/security-regressions.v1.jsondocs/human/audit/AUDIT-PACKET-v0.1.mddocs/human/dependencies-policy.mddocs/human/maintainer-start-here.mddocs/human/portability-pack.mddocs/human/release-process.mddocs/human/repository-settings.mddocs/human/sdk/version-matrix.mddocs/llm/CHANGE_POLICY.mddocs/llm/CONFORMANCE.mddocs/llm/DOC_SYNC.mddocs/llm/FILE_MAP.mddocs/llm/README.mdscripts/internal/verify_dev.shscripts/internal/verify_in_container.shtools/ci/check_branch_protection_drift.pytools/ci/check_ci_economy_policy.pytools/ci/check_dependabot_policy.pytools/ci/check_full_ci_environment.pytools/ci/classify_ci_scope.pytools/ci/evaluate_ci_gate.pytools/ci/test_check_ci_economy_policy.pytools/ci/test_check_dependabot_policy.pytools/ci/test_check_full_ci_environment.pytools/ci/test_classify_ci_scope.pytools/ci/test_evaluate_ci_gate.pytools/github/apply_branch_protection.shtools/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
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
18dc20a to
21d4e6b
Compare
Summary
full-ciapproval before the GitHub-hosted macOS SDK and evidence laneCI gatecontext and preserve exact PR-head evidence provenanceWhy
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
mainSHA 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
main5b10d9f0c88b6925b9bcb472e8c7714f4af883481/05b10d9f0c88b6925b9bcb472e8c7714f4af88348origin/mainCommit integrity
21d4e6ba96a300649c701115e040dd44693f9be1 Gate full CI behind explicit approvalGRAIN-CI-ECONOMY-A01(exactly once)Live settings already verified
full-ci: required reviewerIvGolovach, self-review allowed, no branch restriction0; variables:0all_external_contributors0Diff hygiene
git diff --check origin/main...HEAD: PASS, no outputValidation mode and proof
Tier 4 — CI / Ops / Governance.
./scripts/verify --out-dir artifacts/dev-verify-ci-economy-final-2: PASSpython3 tools/ci/check_dependabot_policy.py: PASSpython3 tools/ci/check_ci_economy_policy.py: PASSactionlint -color .github/workflows/ci.yml .github/workflows/release-evidence.yml: PASSscripts/ledger/check: PASSscripts/ledger/check --history --base origin/main: PASSRequired remote gates
PASS on final SHA
21d4e6ba96a300649c701115e040dd44693f9be1. Workflow run 30721317129 completed the automatic Linux graph, protectedfull-ciapproval, GitHub-hosted macOS SDK verification, evidence bundle, and finalCI gate. CodeRabbit also reported success on the final SHA with no new inline findings.The live
main protectionruleset was then migrated and rechecked: active ruleset14700860requires exactly one status context,CI gate;check_branch_protection_drift.pypasses. The PR is merge-ready.CI context names change from
python-tooling,rust-core,evidence-bundle, andcapid-csprng-auditto the singleCI gate.Migration and runtime safety
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
full-cienvironment can safely remain while code rollback is evaluatedKnown residual risks
None known. The migration gate completed in the required order: final
CI gatesuccess, live ruleset switch, drift verification, then merge readiness.Summary by CodeRabbit
CI & Verification
Dependency Maintenance
Documentation