Straitjacket

Add Straitjacket to CI

Run Straitjacket on every push with the bundled GitHub Action, and configure it with typed fields.

Straitjacket is built to fail CI when it finds slop. The bundled GitHub Action downloads the prebuilt binary and runs it over your repo — every rule, including duplication, in one self-contained pass. It fails the job on any error-level finding, and by default posts those findings to GitHub code scanning as SARIF — annotations right on the PR diff.

Minimal setup

Drop this in .github/workflows/straitjacket.yml:

name: straitjacket
on: [push, pull_request]
jobs:
  scan:
    runs-on: ubuntu-latest
    permissions:
      security-events: write   # let the default SARIF upload post annotations
      contents: read
    steps:
      - uses: actions/checkout@v4
      - uses: zmaril/straitjacket@v0.2.3
        with:
          version: "v0.2.3"   # pin the scanner, not just the Action wrapper

That's the whole thing. No toolchain to set up, no Node — the Action fetches a single static binary and runs it. The security-events: write permission lets it post findings as PR annotations; leave it off and the scan still runs and gates, you just don't get the annotations.

Pin the full version — both halves. The @v0.2.3 on the uses: line pins the Action wrapper; the version: input pins the scanner binary it downloads. Leave version unset and it defaults to latest, so a new Straitjacket release applies its new rules to your repo the moment it ships — failing an unrelated PR on a rule you never opted into. Pin both to the same tag and bump deliberately. The newest release is on the Releases page.

Configure it

Pass typed fields rather than a raw argument string. Each maps to a CLI flag:

      - uses: zmaril/straitjacket@v0.2.3
        with:
          paths: "src tests"     # default "."
          skip: "motion,slop-prose"
          only: ""               # run only these rules
          max-lines: "800"       # file-size budget (0 disables)
          prose-window: "600"    # slop-prose density window
          dup-min-tokens: "80"   # duplication clone size
          format: "text"         # job-log format — or "json"
          sarif: "true"          # upload to code scanning (default)
          no-ignore: "false"
          no-fail: "false"
          working-directory: "."
          version: "v0.2.3"      # pin the scanner; "latest" applies new rules the moment they ship

Every field is optional; blanks fall back to Straitjacket's own defaults. The complete list is in the GitHub Action reference.

Report without failing

To surface findings without failing the build (useful while you're adopting it), set no-fail:

      - uses: zmaril/straitjacket@v0.2.3
        with:
          no-fail: "true"

SARIF / inline PR annotations

The Action uploads its findings to GitHub code scanning as SARIF by default — they show as annotations on the PR diff and in the repo's Security tab, right where the reviewer is looking. It still fails the job on findings (a straitjacket is tight) — the SARIF uploads first, so you get the annotations and the gate.

All the minimal setup needs is the security-events: write permission so the upload can post. That permission is the only extra step:

    permissions:
      security-events: write
      contents: read

Under the hood, in one pass the Action writes a readable text report to the job log and a side SARIF file, uploads the SARIF with github/codeql-action/upload-sarif, then fails the job on findings. Adopting gradually and want annotations without failing? Add no-fail: "true". Don't want code scanning at all? Set sarif: "false" — it falls back to a plain text scan that still gates.

Without the security-events: write permission the upload step is skipped gracefully: no annotations, but the scan still runs and gates on findings.

Outside the Action, produce SARIF yourself:

straitjacket --format sarif --no-fail > straitjacket.sarif

Other CI systems

There's no runtime dependency, so any CI works — install the binary and run it:

curl -fsSL https://raw.githubusercontent.com/zmaril/straitjacket/main/install.sh | sh
straitjacket

The command exits non-zero on any error-level finding, which fails the job on every CI system that respects exit codes.

On this page