Skip to main content

A CI quality gate that grades a repo against a product-quality doctrine — not code style.

Reason this release was yanked:

Early alpha prototype. Please use v1.0.0 or later for the stable engine and zero-dependency plugin architecture.

Project description

Invigil

A CI quality gate that grades a repo against a product-quality doctrine — not code style.

CI License PyPI

Linters check your code. Dependabot checks your dependencies. Nothing checks whether your project keeps the promises a stranger relies on: that they can boot it in ten minutes, that every error tells them the fix, that the thing on PyPI actually installs today, that the README is still a landing page and not a 600-line wall.

Invigil turns those promises into mechanical, exact-fix-reporting checks and runs them in CI — so the project speaks for itself.

invigilate — to watch over an exam and enforce its rules.


Why

You already wrote the doctrine; you just enforce it by hand. Every failing Invigil check tells you what's wrong, why it matters, and the exact command to fix it — because a gate that can't tell you how to pass it is the same broken-error-message anti-pattern it's meant to catch.

It grades against seven Gates, each a promise to a different stranger:

Gate The promise
G1 A stranger succeeds in 10 minutes on a clean machine
G2 Every failure mode tells the user the fix
G3 Published artifacts are machine-verified daily
G4 Supply-chain evidence is public (Scorecard ≥7, signed releases, SBOM)
G5 All five doors open and documented (newbie, operator, contributor, enterprise, AI)
G6 First external contributor merged without hand-holding
G7 Cited/integrated by projects you don't control

A repo reaches Gn only when every mandatory check for gates ≤ n passes, and gets a letter grade from its weighted score.

Quick Start

Run it locally on any repo:

pip install invigil
invigil score .            # human-readable scorecard + the exact fix for every failure
invigil score . --format markdown   # a PR-comment-ready table
invigil score . --format json       # machine-readable

Add it to CI as a report-only gate (posts a scorecard comment + badge, never blocks a PR):

# .github/workflows/quality-gate.yml
name: Quality gate
on: [pull_request]
permissions: { contents: read, pull-requests: write }
jobs:
  invigil:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: invigil/invigil@v1        # the doctrine scorecard
        with:
          enforce: "false"              # flip to true once the grade is stable

Flip enforce: "true" (or set project.enforce: true in .invigil.yml) when you're ready for it to block merges below the target gate.

How it works

Two layers, matching the doctrine:

  • Static Doctrine Scorecard (every PR, seconds) — inspects the repo filesystem and GitHub metadata: LICENSE, README length, .env.example, a deep-health endpoint, a global error-id handler, SHA-pinned actions, an enforced lockfile, a coverage gate, a daily published-artifact smoke test, ≥5 good-first-issues, docs index, llms.txt/AGENTS.md, and more. Emits text / JSON / Markdown / a shields.io badge.
  • Stranger Gate (nightly, reusable) — on a clean runner, installs and boots each published artifact you declare and probes its core surface within a 10-minute budget. One reusable workflow replaces the 60-line smoke-published.yml every repo copy-pastes:
# .github/workflows/stranger-gate.yml
name: Stranger gate
on:
  schedule: [{ cron: "0 3 * * *" }]
  workflow_dispatch:
jobs:
  stranger:
    uses: invigil/invigil/.github/workflows/stranger-gate.yml@v1

Configuration

Drop a .invigil.yml at the repo root. It's optional for the static scorecard (sensible defaults apply) and required for the Stranger Gate (it declares what to boot and probe). Full schema in schema/invigil.schema.json; examples in examples/.

version: 1
project:
  name: my-app
  language: python
  min_gate: G4
  enforce: false
artifacts:
  - type: pypi
    name: "my-app[all]"
  - type: ghcr
    image: ghcr.io/me/my-app:latest
    port: 8000
probes:
  - { url: "/", expect_status: 200 }
  - { url: "/api/things", expect_json_count: { min: 5 } }
boot_budget_minutes: 10

Lightweight & modular

A gate developers bypass is dead weight, so Invigil is built for zero friction:

  • Fast offline groups for pre-commit — each check is tagged local/network/heavy. invigil check layout runs the filesystem checks with no network in ~120ms:

    # .pre-commit-config.yaml
    - repo: https://github.com/invigil/invigil
      rev: v1.0.0
      hooks: [{ id: invigil-layout }, { id: invigil-secrets }]
    

    Heavier, network-bound checks (scorecard, the Stranger Gate) stay in CI. invigil score --offline / --layer local / --group supply-chain slice it any way.

  • Profiles, so it bends instead of forking. profile: strict | progressive | light, plus per-check weights, optional (ding without gating), and thresholds.fail_on. Make it your doctrine, not a hardcoded one.

  • Resilient by design. A scorecard.dev timeout is a SKIP that's excluded from the grade — never a false A-to-C downgrade, never a crashed build.

  • AI-era native. The ai group checks that your llms.txt/AGENTS.md leak no secrets and that agent code declares its tool inventory — the first slice of "what's the blast radius if this agent is prompt-injected?"

The doctrine

Invigil encodes a specific product-quality doctrine (the Silent User Doctrine and its Five Disciplines): absence of complaints is not absence of problems — silence is the loudest negative signal a project gets. You test at release time; users arrive after dependencies drift and registries change. Only automation is awake then. Invigil is that automation.

Contributing

Issues and PRs welcome — see CONTRIBUTING.md and good first issues. Invigil grades itself in CI (self-score job); a PR that lowers Invigil's own grade won't merge.

License

Apache-2.0 — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

invigil-0.1.0.tar.gz (44.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

invigil-0.1.0-py3-none-any.whl (37.1 kB view details)

Uploaded Python 3

File details

Details for the file invigil-0.1.0.tar.gz.

File metadata

  • Download URL: invigil-0.1.0.tar.gz
  • Upload date:
  • Size: 44.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for invigil-0.1.0.tar.gz
Algorithm Hash digest
SHA256 95ebcbee2e22a741a68d420a9d854c55506c32f799789107e4b6761ccdc9ac12
MD5 621c6307774582cabe2f5e45035fab26
BLAKE2b-256 f3fb52ba4f616f793f29c1c68949b416641aa6880efff8ff741c1565067371c9

See more details on using hashes here.

Provenance

The following attestation bundles were made for invigil-0.1.0.tar.gz:

Publisher: release.yml on invigil/invigil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file invigil-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: invigil-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 37.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.0.1 CPython/3.12.8

File hashes

Hashes for invigil-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ddce2f73c13aa33962d402b331a98ebabfa691c3f9966c7dbab0bb17968f24fe
MD5 ceb66d93a45caa993e503ff6f50a5726
BLAKE2b-256 bcb1892f27e5ac776b5cacc57a6a2431011a0bf2ddbc789edd97575e3ed80ba5

See more details on using hashes here.

Provenance

The following attestation bundles were made for invigil-0.1.0-py3-none-any.whl:

Publisher: release.yml on invigil/invigil

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page