Release

The architecture check in CI: a baseline, a gate, and a weekly report

The check now runs on every pull request as a GitHub Action, fails a build only on findings a change introduced, and sends a weekly drift report built from those runs.

Try Wyro

A check you have to remember to run is a check that stops being run. The architecture check started as a panel on a GitHub page and a public URL. This month it moved to the place where code actually changes: the pull request.

Two lines of workflow

Add the action to a workflow and every pull request is checked. Findings land as annotations on the lines that caused them, with a summary on the job.

# .github/workflows/architecture.yml
name: architecture
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: DominicPaaul7/wyro-check-action@v1

Your source is read on your own runner and is never uploaded. The action is deliberately thin: it downloads the checker from wyro.in/wyro-check.js, verifies its published SHA-256, caches it by digest, and runs it. The same script runs on GitLab, Buildkite, Jenkins or a laptop — --github for annotations, --json for anything else. Full reference: the CI docs.

A baseline, not a suppression list

Point any checker at a codebase that already exists and it finds things. On Wyro's own repository it reports 2 errors and 35 warnings. That number is accurate, and it is not actionable — nobody fails their build on day one over 37 problems they did not introduce. They delete the gate instead.

So --update-baseline records what is already there in .wyro/baseline.json, once. From that commit on, a build fails only on findings that are not in the ledger. When a baselined finding stops firing, the check says so and invites you to bank the improvement.

Four exit codes, on purpose

  • 0 — nothing new.
  • 1 — new findings that fail your threshold.
  • 2 — nothing in the directory could be read as a backend.
  • 3 — the gate itself is misconfigured and did not run.

A repository the parser could not read produces zero findings, and zero findings must never look like a clean bill of health. So an unreadable directory fails by default, and a package with genuinely no backend in it opts out in writing with allowUnreadable. A corrupt baseline or a bad wyro.json exits 3 rather than quietly running with nothing.

Central policy

A wyro.json in the repository can tune every rule — which also means the repository can loosen them. With a project token, the rules come from Wyro instead: a local config can make the build stricter and cannot make it looser, and the job summary names every override. If a token is supplied and the policy cannot be fetched, the run fails rather than falling back to the local file.

Central policy and run history are on Pro and Scale. The check, the baseline, the annotations and the CLI are free and unmetered, on public and private repositories.

The weekly drift report

Runs reported to Wyro now feed a weekly email: what appeared, what was fixed, and which gates went quiet. It follows the checker's own rule — no confident empty answers. A project with nothing to say is left out, and a week with nothing to say sends nothing. A gate that ran last week and not this week is reported first, because a broken gate looks exactly like silence.

Everything that shipped

  • NewGitHub Action DominicPaaul7/wyro-check-action@v1 — annotations on the diff, a job summary, digest-verified checker download.
  • NewBaseline ledger (--update-baseline) keyed on route and table, so edits and moves never resurrect accepted findings.
  • Newwyro.json — failOn, a maxWarnings budget, and per-rule levels. A disabled rule is still named in every report.
  • NewCentral policy via project token, created under Architecture policy in project settings.
  • NewWeekly architecture drift report, with its own unsubscribe separate from the newsletter.
  • NewREADME badge at /api/badge/<owner>/<repo>, served by the same engine as the scan page. An unreadable repository shows "not checked", never a pass.
  • FixedAnnotations on a checked subdirectory now carry the repository-relative path, so GitHub no longer drops them off the diff.
  • changelog
  • ci
  • github-action
  • verification