Skip to content

[Bug]: a structure-only pull request runs no gate, so structure:check never sees changes to structure/ #5001

Closed

Description

@lidge-jun

Client or integration

CI only.

Area

CI and release

Summary

A pull request that touches only structure/ runs no test or gate legs at all, which means tests/ci-workflows/structure-ssot.test.ts does not execute — and that test is the only thing in CI that runs bun run structure:check. The folder whose entire purpose is a gate is the one folder whose changes the gate never sees.

The cause is the changes job's ci path filter in .github/workflows/ci.yml, which does not list structure/**. On #4999, a pure doc split, every expensive leg reported skipped: windows, macos, macos control, test 1/4 through 4/4, gates, npm-global, docker smoke, keyring, api usage, storage policy and docs site build. Only select-windows-runner, changes and the aggregate ci job ran. The aggregate reports success, so the pull request looks green while nothing was verified.

This survived because it is invisible in the normal case. The ownership rule in structure/AGENTS.md means a change to structure/ almost always accompanies a change to src/, so the filter matches on the source side and the gate runs. Three pull requests hit the structure/runtime.md line budget earlier the same evening and all three were correctly caught, precisely because they also touched src/. A pure doc split is the rare shape that exposes the gap, and it took a doc reaching its size budget to produce one.

Reproduction

Open a pull request that changes only files under structure/. Observe that every test and gate job reports skipped while the aggregate ci check reports success. #4999 and its run are a live example.

A workflow_dispatch of ci.yml with lane=all does force the expensive legs and is the current workaround, but it is manual and nothing requires it.

Version

2.59.0 (dev).

Operating system

Not OS-specific.

Provider and model

Not provider-specific.

Logs or error output

Not applicable; the defect is the absence of execution rather than a failure.

Screenshots and supporting files

Not applicable.

Redacted configuration

Not applicable.


On the fix, recorded as analysis rather than as a decision: adding structure/** to the ci filter would close it and would be self-verifying, since ci.yml is already inside its own filter. But it would start the full cross-platform matrix on every prose edit, which is the cost the workflow's own comments argue against for docs-site. A narrower job that runs only the structure gate on structure/** is the better shape. Either way this is a GitHub Actions workflow change and falls under the explicit security-review boundary in AGENTS.md, so it belongs in its own pull request with its own reasoning.

Activity

  1. Ingwannu commented on Sep 18, 2026

    @Ingwannu
    Owner

    Confirmed. The narrow fix should be a dedicated structure scope and gate, not adding structure/** to the full ci matrix.

    The current changes job already has the right pattern for docs: emit a validated path-filter output, then let one job consume it. Add a structure output that matches structure/** plus .github/workflows/ci.yml, validate that output as strictly as ci, and run a small hosted Ubuntu job with frozen dependencies and bun run structure:check. Include that job in the aggregate result so a skipped cross-platform matrix cannot hide its failure.

    Required workflow regressions should prove:

    1. a structure-only PR sets structure=true and ci=false;
    2. the dedicated structure gate runs while Linux/macOS/Windows matrices remain skipped;
    3. source changes that already run gates do not create contradictory duplicate results;
    4. malformed or missing filter output fails closed rather than skipping; and
    5. editing ci.yml exercises the new gate itself.

    This is a workflow security/release boundary. Keep permissions at contents: read, use immutable action SHAs, and do not solve it by making the aggregate ci job report success without consuming the dedicated gate's conclusion.

  2. added a commit that references this issue on Sep 18, 2026
    7103141
  3. lidge-jun commented on Sep 18, 2026

    @lidge-jun
    OwnerAuthor

    Fixed on dev by #5050, merged as 71031414466.

    ci.yml now carries a structure path filter and a structure gate job that runs bun run structure:check directly when it fires. The gate is proven rather than assumed: #5050 touches .github/workflows/ci.yml, which is in both the ci filter and the new structure filter, so its own run started the full suite and the new job, and structure gate reported success alongside test 1/4 through 4/4, gates, macos 1/2, macos 2/2 and the keyring legs.

    I took the narrow-job route this issue's own analysis preferred rather than adding structure/** to the ci filter. Widening ci would close the hole too, and would start nine Windows shards and two macOS shards on every prose edit — the cost this workflow's comments already refuse for docs-site.

    The gate is pull-request scope, like docs-site-build. tests/ci-workflows/ci-workflows.test.ts pins the push trigger's paths: to equal the ci filter exactly, and structure/** deliberately is not in that filter. It costs nothing here: dev, main and preview are all protected to require a pull request, so no structure/ change reaches an integration line without passing through one.

    tests/ci-workflows/ci-structure-gate.test.ts reads the condition off the job rather than naming it, and pins the tradeoff in both directions — structure/** must stay out of the ci filter, and the push paths: must keep mirroring ci — so a future edit that closes this by widening ci fails there and gets read by a human.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions