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
26 changes: 12 additions & 14 deletions .github/workflows/firewall_gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ name: Tenant Firewall Gate
# the leg is dropped with `repos_sync.py --skip`, the run says so out loud, and
# the part the PR really does control — PyAutoMind's own installed copies, the
# one repo propagation never writes to — is asserted instead. On `push` to
# main these hook legs are not skipped; standards use target-owned scope below.
# main these hook legs are not skipped. The shared-standards leg is never
# skipped: it is graded universally on the cloned mains (see below).
#
# The where-to-file block (`policy/where_to_file.md`, PyAutoMind#442) has the
# same unmeetable precondition: the sibling organs are checked out at their
Expand All @@ -34,7 +35,7 @@ name: Tenant Firewall Gate
# pins it) and drops the `where-to-file blocks (generated)` leg with the same
# loud banner. The two decisions are independent: a PR touching both a hook and
# the policy skips both legs and prints both banners; one touching neither runs
# every existing leg. Standards are graded separately. The decision reads the PR's diff, not its body, so a PR with no
# every existing leg. The decision reads the PR's diff, not its body, so a PR with no
# `Brain-ref:` line gets the skip exactly as one with it does.
#
# All three organs are checked out. PyAutoHands was omitted at first — its
Expand Down Expand Up @@ -170,11 +171,12 @@ jobs:
python3 -m pytest PyAutoMind/tests/test_repos_sync_filing_block.py -q \
-k "pyautomind_carries_its_own_block"

# Standards rollout is staged across consumer PRs (#474). These sibling
# main clones do not belong to this Mind PR. Keep the default generator
# audit universal; CI grades Mind's owned block and generator behavior.
# Consumer PRs grade their own block, and the rollout completion audit
# checks every available registered checkout without --repo.
# The shared-standards rollout (#474) is complete: all 46 registered
# repos carry the generated block on main (PyAutoArray#614 and
# euclid_strong_lens_modeling_pipeline#110 were the last). This step
# keeps the hermetic generator tests and pins Mind's own block; the
# drift checks below now grade the standards leg universally on every
# cloned main, like every other leg — no --skip.
- name: Shared standards generator and Mind-owned block
run: |
pip install pytest
Expand All @@ -188,8 +190,7 @@ jobs:
HOOK_PR: ${{ steps.hookpr.outputs.hook_pr }}
FILING_PR: ${{ steps.hookpr.outputs.filing_pr }}
run: |
echo "Standards scope: Mind-owned block checked above; sibling main adoption is checked by consumer PRs and the universal completion audit."
skip=(--skip "shared-standards blocks (generated)")
skip=()
if [ "$HOOK_PR" = "true" ]; then
echo "=============================================================="
echo "SKIPPED LEG: 'generated hooks (session-start + end-at-deliverable)'"
Expand Down Expand Up @@ -226,11 +227,8 @@ jobs:
python3 PyAutoMind/scripts/repos_sync.py --check \
--root "$GITHUB_WORKSPACE" "${skip[@]}"

# Preserve all existing legs. Standards are target-owned in this gate;
# running the generator without --skip remains the universal audit.
# Every leg, the shared-standards leg included, graded on the cloned mains.
- name: Drift check (all legs — absent repos are skipped)
if: steps.hookpr.outputs.hook_pr != 'true' && steps.hookpr.outputs.filing_pr != 'true'
run: |
echo "Standards scope: Mind-owned block checked above; sibling main adoption is checked by consumer PRs and the universal completion audit."
python3 PyAutoMind/scripts/repos_sync.py --check --root "$GITHUB_WORKSPACE" \
--skip "shared-standards blocks (generated)"
python3 PyAutoMind/scripts/repos_sync.py --check --root "$GITHUB_WORKSPACE"
8 changes: 5 additions & 3 deletions tests/test_repos_sync_standards_block.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,16 +195,18 @@ def test_grouped_target_uses_resolver(tmp_path, monkeypatch):
assert sync.STANDARDS_BEGIN in path.read_text()


def test_ci_preserves_existing_legs_and_explains_standards_scope():
def test_ci_grades_standards_universally_on_cloned_mains():
"""The staged rollout (#474) is complete, so the broad drift legs grade the
standards block on every cloned main; the hermetic generator step stays."""
data = yaml.safe_load((MIND / ".github/workflows/firewall_gate.yml").read_text())
steps = next(iter(data["jobs"].values()))["steps"]
target = [step for step in steps if step.get("name") == "Shared standards generator and Mind-owned block"][0]
assert 'test_repos_sync_standards_block.py' in target['run']
assert '--repo PyAutoMind' in target['run']
broad = [step for step in steps if step.get("name", "").startswith("Drift check")]
assert len(broad) == 2
for step in broad:
assert '--skip "shared-standards blocks (generated)"' in step['run']
assert 'consumer PRs and the universal completion audit' in step['run']
assert sync.STANDARDS_BLOCKS not in step['run']


@pytest.mark.parametrize("kind", ["checkout", "family", "agents", "agents-inside"])
Expand Down
2 changes: 1 addition & 1 deletion tests/test_session_hook_sync.py
Original file line number Diff line number Diff line change
Expand Up @@ -837,7 +837,7 @@ def test_the_skipping_step_composes_both_decisions(tmp_path, hook_pr,
)
args = argv.read_text().splitlines()
got = [args[i + 1] for i, a in enumerate(args) if a == "--skip"]
assert got == [repos_sync.STANDARDS_BLOCKS, *skipped], args
assert got == skipped, args
assert proc.stdout.count("SKIPPED LEG") == len(skipped), proc.stdout
for label in skipped:
assert f"SKIPPED LEG: '{label}'" in proc.stdout
Loading