invigil/invigil

GitHub: invigil/invigil

Invigil 是一个 CI 质量门禁工具,依据产品级质量原则对代码库进行评级,补传统 Linter 和依赖管理工具遗漏的可读性与冷启动能力缺口。

Stars: 1 | Forks: 2

# Invigil **一个 CI 质量门禁,它根据产品级质量的*原则*对代码库进行评级 —— 而不是代码风格。** [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/invigil/invigil/actions/workflows/ci.yml) [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](LICENSE) [![PyPI](https://img.shields.io/pypi/v/invigil)](https://pypi.org/project/invigil/) [![GitHub Marketplace](https://img.shields.io/badge/Marketplace-Invigil-2088FF?logo=githubactions&logoColor=white)](https://github.com/marketplace/actions/invigil-product-quality-gate) [![Docker](https://img.shields.io/badge/ghcr-invigil%2Finvigil-2496ed?logo=docker&logoColor=white)](https://github.com/invigil/invigil/pkgs/container/invigil) [![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/invigil/invigil/badge)](https://scorecard.dev/viewer/?uri=github.com/invigil/invigil) [![Invigil grade](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/invigil/invigil/main/badges/invigil.json)](https://github.com/invigil/invigil) [![AI-ready](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/invigil/invigil/main/badges/invigil-ai.json)](https://github.com/invigil/invigil#when-your-user-is-an-agent) Linters 检查你的*代码*。Dependabot 检查你的*依赖*。**没有任何东西在检查 你的项目是否清晰易懂 —— 一个刚接触项目的人是否能直接上手:** 在十分钟内启动 它,收到明确的错误修复提示,并在*今天*就能从 PyPI 上安装它,读到一个 依然像主页一样赏心悦目,而不是一面长达 600 行文字墙的 README。 这就是每个开源项目在遇到新人(一位新工程师,或者越来越多地,一个只有上下文窗口而没有耐心的 AI agent)时所面临的真实考验。如果他们不能在 10 分钟内跑通 "hello world",他们会离开。如果 PyPI 上的构件因为 CI 只测试了 源码树而是坏的,他们会离开。如果错误信息是一段默默无闻的 stack trace,他们会离开。 Invigil 将这些承诺转化为机械化的、提供精确修复报告的检查,并在 CI 中运行它们 —— 从而让项目自己发声。 ## Invigil 如何融入你的技术栈 Invigil 不会取代你现有的工具;它填补了它们留下的产品质量空白。 | 工具 | 关注点 | 它遗漏了什么(Invigil 能抓到的) | |---|---|---| | **Linters / SonarQube** | 代码风格、静态 bug、复杂度 | *发布的构件*真的能启动吗?README 易读吗? | | **Dependabot / Renovate** | 保持依赖更新 | 你在 CI 中强制使用 lockfile 了吗?有版本矩阵吗? | | **OpenSSF Scorecard** | 供应链安全(分支规则,token) | 项目有快速入门指南吗?故障模式具有可操作性吗? | | **Invigil** | 产品质量、易读性、错误卫生 | (Invigil 依赖于上述工具并强制要求它们的存在) | ## 为什么需要 你已经写下了这些原则;你只是手工执行它们。每一个 Invigil 检查失败都会告诉 你**错在哪里、为什么重要、以及修复它的确切命令** —— 因为一个无法 告诉你如何通过的门禁,与其试图捕捉的破损错误信息反模式毫无二致。 它根据七个**门禁**进行评级,每一个门禁都是对不同冷启动读者的易读性承诺: | 门禁 | 承诺 | |---|---| | **G1** | 任何刚接触项目的人都能在干净的机器上于 10 分钟内取得成功 | | **G2** | 每种故障模式都会告诉用户如何修复 | | **G3** | 发布的构件每天都经过机器验证 | | **G4** | 供应链证据公开(Scorecard ≥7,签名发布,SBOM) | | **G5** | 所有五扇大门均已敞开且有文档记录(新手、运维、贡献者、企业、AI) | | **G6** | 第一位外部贡献者在无需手把手指导的情况下完成合并 | | **G7** | 被你无法控制的项目引用/集成 | 只有当 ≤ n 门禁的所有强制检查都通过时,代码库才能*达到* `Gn`,并根据其加权得分获得一个字母评级。 ## 安装 一个工具,四扇大门 —— 选择与你运行环境相匹配的那个: | 渠道 | 适用场景 | 一行命令 | |---|---|---| | **PyPI** | 本地运行,对 Python 友好的 CI | `pip install invigil` | | **GitHub Action** | GitHub PR | `uses: invigil/invigil@v1` | | **Docker (ghcr)** | GitLab, Jenkins, 任何非 Python CI | `docker run --rm -v "$PWD:/repo" ghcr.io/invigil/invigil score /repo` | | **pre-commit** | 每次提交时的离线检查 | hooks `invigil-layout`, `invigil-secrets`(见下文) | 每次发布的产物都是签名的:cosign 签名的 wheel、sdist 和容器镜像,外加一份 SPDX SBOM —— 可以使用 `cosign verify` 针对 GitHub OIDC 身份进行验证。 ## 快速入门 在任何代码库上本地运行它: ``` 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 ``` 将其作为仅报告的门禁添加到 CI 中(发布评分卡评论 + 徽章,绝不阻塞 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 ``` 当你准备好让它阻止低于目标门禁的合并时,开启 `enforce: "true"`(或在 `.invigil.yml` 中设置 `project.enforce: true`)。 ## 工作原理 分为两层,与原则相匹配: - **静态原则评分卡**(每次 PR,数秒内完成)—— 检查代码库文件系统和 GitHub 元数据:LICENSE、README 长度、`.env.example`、深度健康检查 endpoint、全局错误 ID 处理器、SHA 锁定的 actions、强制的 lockfile、覆盖率门禁、每日发布构件 冒烟测试、≥5 个 good-first-issues、文档索引、`llms.txt`/`AGENTS.md` 等等。输出文本 / JSON / Markdown / shields.io 徽章。 - **冷启动门禁**(每晚,可复用 —— `invigil stranger`)—— 在干净的 runner 上,安装 并启动你声明的每个*已发布*构件,并在 10 分钟的时间预算内探测其核心功能。Web 服务会接受 HTTP 探测;CLI 镜像(带有 `command:` 的构件) 将被运行至结束并且必须以 exit 0 退出。一个可复用的工作流取代了每个代码库都在复制粘贴的 60 行 `smoke-published.yml`: ``` # .github/workflows/stranger-gate.yml name: Cold-start gate on: schedule: [{ cron: "0 3 * * *" }] workflow_dispatch: jobs: stranger: uses: invigil/invigil/.github/workflows/stranger-gate.yml@v1 ``` ### 通过 PR 修复(为易读性而生的 Dependabot) 开启一个计划任务 bot,它会在工作分支上应用 Invigil 的机械化修复并开启 **一个合并的 PR** —— 治理脚手架、agent 上下文文件、配置卫生。内置了三条防噪音规则:仅限主动开启、一个稳定分支对应一个 PR(绝不生成五个)、你关闭且未合并的 PR 就是被 bot 尊重的“拒绝” —— 它会保持沉默,直到你删除 `invigil/fixes` 分支。 ``` # .github/workflows/legibility-fixes.yml name: Legibility fixes on: schedule: [{ cron: "0 6 1 * *" }] # monthly — these are one-time scaffolds, not deps workflow_dispatch: jobs: fix: uses: invigil/invigil/.github/workflows/fix-pr.yml@v1 ``` 在底层,它运行 `invigil score --fix --pr-mode`:修复引擎的 CI 锁定机制对于受保护的分支 依然有效 —— `--pr-mode` 仅允许在非默认分支上进行修复,因此如果没有人工合并 PR,任何自动化的操作都永远不会进入 `main`。 ## 配置 在代码库根目录下放置一个 `.invigil.yml`。它对于静态评分卡是可选的(会应用合理的 默认值),但对于冷启动门禁是必需的(它声明了要启动和探测的内容)。完整 schema 见 [`schema/invigil.schema.json`](schema/invigil.schema.json);示例见 [`examples/`](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 ``` ## 轻量与模块化 开发者会绕过的门禁就是累赘,因此 Invigil 的构建旨在实现零摩擦: - **用于 pre-commit 的快速离线组** —— 每个检查都被标记为 `local`/`network`/`heavy`。 `invigil check layout` 会在没有网络的情况下运行文件系统检查,耗时约 120ms: # .pre-commit-config.yaml - repo: https://github.com/invigil/invigil rev: v1 # 跟踪最新的 v1.x.y hooks: [{ id: invigil-layout }, { id: invigil-secrets }] 更重的、依赖网络的检查(`scorecard`,冷启动门禁)留在 CI 中运行。 `invigil score --offline` / `--layer local` / `--group supply-chain` 可以按任意方式切片。 - **配置文件,让它适应而非分叉。** `profile: strict | progressive | light`,加上 每次检查的 `weights`、`optional`(扣分但不阻塞门禁)和 `thresholds.fail_on`。让它成为你的 原则,而不是硬编码的原则。 - **设计上的弹性。** scorecard.dev 超时会被标记为 SKIP 并排除在评级之外 —— 绝不会造成误报的 A 降级到 C,绝不会导致构建崩溃。 - **AI 时代的原生支持。** `ai` 组检查你的 `llms.txt`/`AGENTS.md` 是否泄露了机密,以及 agent 代码是否声明了其工具清单 —— 这是了解“如果这个 agent 被 prompt 注入了,爆炸半径有多大?”的第一步尝试。 ## 当你的用户是一个 agent 时 易读性现在有了两类受众。刚接触到你代码库的读者,往往 是一个 AI agent:它拥有的是上下文窗口而非耐心,是退出代码而非 直觉,并且它只根据代码库以机器可读形式陈述的内容来行动。`ai` 检查组 对该层面进行评级 —— 不仅仅是检查 `llms.txt`/`AGENTS.md` 是否*存在*,还要看 agent 是否真的 能根据它们采取行动: | 检查 | 对 agent 的承诺 | |---|---| | `agents-md-actionable` | 你的 `AGENTS.md`/`CLAUDE.md` 包含可运行的围栏代码命令,而不是纯文本描述 | | `llms-txt-shape` | `llms.txt` 符合规范且在 10 KB 的上下文预算内 | | `agent-context-fresh` | Agent 的指令不能比它们描述的源码滞后 90 天以上 | | `readme-heading-hierarchy` | README 结构清晰(只有一个 H1,有真正的 H2 章节) | | `exit-codes-documented` | CLI 的退出代码被明确列出 —— agent 根据代码而非文本进行分支判断 | | `llms-no-secrets` | 机器可读的接口不泄露任何凭证 | | `agent-scope-visibility` | Agent 代码声明其工具清单(爆炸半径的前提条件) | 由此衍生出两个产物:一个 **`ai-ready` 徽章**(shields endpoint,由 `--badges-dir` 在评分 徽章旁边发布)和 **`invigil score --format llm`** —— 一份小于 1 KB 的确定性报告,专为 *被* agent 读取而设计:一个健康的代码库只会消耗它两行上下文。 ## 原则 Invigil 编码了一种特定的产品质量原则(沉默用户原则及其五大 准则):*没有投诉不代表没有问题 —— 沉默是一个项目能发出的最响亮的 负面信号。* 你在发布时进行测试;而用户是在依赖 发生偏移和 registry 变更后才到来的。只有在那时,自动化才是清醒的。Invigil 就是那种自动化。 ## 贡献 欢迎提交 Issues 和 PR —— 请参阅 [CONTRIBUTING.md](CONTRIBUTING.md) 和 [good first issues](https://github.com/invigil/invigil/labels/good%20first%20issue)。Invigil 在 CI 中对自身进行评级(`self-score` 作业);降低 Invigil 自身评级的 PR 将无法合并。 ## 许可证 Apache-2.0 —— 见 [LICENSE](LICENSE)。
标签:SOC Prime, 可维护性, 开发工具, 开源治理, 文档检查, 自动化审查, 请求拦截, 逆向工具