JimAKennedy/nfr-review
GitHub: JimAKennedy/nfr-review
一款自动化的非功能性设计审查框架,通过静态扫描代码和基础设施配置来评估软件项目的弹性、可观测性和运维就绪度。
Stars: 0 | Forks: 0
# nfr-review
[](https://github.com/JimAKennedy/nfr-review/actions/workflows/ci.yml)
[](https://github.com/JimAKennedy/nfr-review/actions/workflows/ci.yml)
[](https://github.com/JimAKennedy/nfr-review/blob/main/pyproject.toml)
[](https://github.com/astral-sh/ruff)
为软件项目提供自动化的非功能性设计审查。
`nfr-review` 会扫描代码库以查找架构证据(Spring 配置、K8s manifest、CI pipeline、Dockerfile、Helm chart、Terraform module、Istio 配置、ADR、Java/Go/Python/C#/C++/Node.js 源码、gRPC proto 文件、APIM 策略等),并评估涵盖弹性、可观测性、安全性、运维就绪度、部署补丁和代码库卫生的 147 条规则。卫生审计涵盖文档、CI 自动化、社区标准、构建就绪度、隐私和许可证合规性。审查结果会输出为 CSV、JSONL、SARIF、Markdown 和 PDF 格式,以便集成到审查工作流中。
## 工作原理
nfr-review 使用三阶段 pipeline:
1. **收集器** 会遍历目标代码库并提取结构化证据——Spring 配置、Kubernetes manifest、源文件的 AST 节点、CI workflow 定义、Helm chart、Terraform module 等。每个收集器都是特定于技术的,只有在检测到(或显式启用)其对应的技术时才会运行。证据是技术无关的:用于 Java AST 的收集器和用于 Go AST 的收集器都会生成相同的 `ASTEvidence` 模型。
2. **规则** 会根据已知的模式和最佳实践评估收集到的证据。每条规则针对一个特定问题(例如“是否配置了 liveness probe?”、“线程池是否有界?”),并发出零个或多个带有 RAG 状态(Red / Amber / Green)、严重程度、建议以及指向源文件的证据定位器的**审查结果**。规则分为 NFR 规则(弹性、可观测性、安全性、补丁)和卫生规则(文档、CI、许可、隐私)。
3. **输出格式化器** 会将审查结果写入 CSV、JSONL、SARIF 2.1.0、Markdown 或 PDF 报告。PDF 渲染器包含执行摘要(配置了后端时由 LLM 生成)、设计成熟度评分以及 Mermaid/Graphviz 架构图。
## 支持的技术
| 类别 | 技术 | 收集器 | AST 分析 | 示例规则 |
|----------|-----------|------------|:------------:|---------------|
| **编程语言** | Java | `java_ast`, `java_deps`, `jdepend`, `jacoco_report` | tree-sitter | Health endpoint、弹性注解、异常处理、线程池、休眠类 |
| | Python | `python_ast`, `python_deps` | tree-sitter | 可变默认值、星号导入、裸异常、异步 fire-and-forget |
| | Go | `go_ast`, `go_deps` | tree-sitter | 循环中的延迟调用、被忽略的错误、goroutine 泄漏、HTTP client 超时 |
| | C++ | `cpp_ast`, `cmake` | tree-sitter | 裸内存、include guard、异常安全、CMake 配置、sanitizer CI、休眠类 |
| | C# | `csharp_ast`, `csharp_deps` | tree-sitter | Async void、阻塞式 async、ConfigureAwait、未使用 using 的 disposable |
| | Node.js / TypeScript | `nodejs_ast`, `nodejs_deps` | tree-sitter | 浮动的 promise、未处理的 rejection、同步 FS API、被忽略的 callback 错误 |
| **框架** | Spring Boot | `spring_config` | -- | Actuator 暴露、日志配置、profile 配置错误 |
| | APIM (Azure) | `apim_policy` | -- | 缺少 Auth 策略、硬编码的后端 URL、速率限制 |
| **基础设施** | Docker | `dockerfile` | tree-sitter | 基础镜像版本锁定、多阶段构建、USER 指令、机密信息泄露、K8s 镜像漂移 |
| | Kubernetes | `k8s_manifest` | -- | Probe、资源限制、网络策略、非 root 容器、安全上下文 |
| | Helm | `helm` | -- | Chart 元数据、values 验证、机密信息泄露、模板渲染 |
| | Terraform | `terraform` | tree-sitter (HCL) | Provider 版本锁定、state 后端、IAM 策略分析 |
| | Istio | `istio`, `service_mesh` | -- | 断路器、mTLS strict 模式、流量策略 |
| | Skaffold | `skaffold` | -- | 构建配置验证 |
| **CI/CD** | GitHub Actions | `ci_artifact` | -- | 测试阶段、安全扫描、覆盖率门槛、lint、SAST、action 版本锁定、release 发布 |
| **架构** | ADR | `adr`, `adr_derive` | -- | 生命周期缺口、覆盖率缺口、架构漂移(LLM 辅助) |
| | gRPC / Protobuf | `proto` | -- | 字段编号、方法注释、服务版本控制 |
| **可观测性** | OpenTelemetry | `otel`, `otel_trace`, `telemetry_config` | -- | Exporter 配置、pipeline 完整性、采样、W3C 传播、资源属性 |
| **依赖** | PyPI, Maven, Go modules, npm, NuGet | `*_deps` 收集器 | -- | 新鲜度、升级路径、传递依赖解析 |
| **动态分析** | OTel trace | `otel_trace` | -- | 延迟 P95、N+1 查询、关联传播、方法覆盖率、调用序列 |
| **安全** | PII 检测 | -- | -- | 日志语句中的 PII(LLM 辅助) |
| **补丁** | 部署就绪度 | multiple | -- | 22 条规则:更新策略、PDB 覆盖率、优雅关闭、回滚 CI 等 |
| **性能** | Gatling | `gatling` | -- | 性能阈值验证 |
| **代码质量** | JaCoCo | `jacoco_report` | -- | 覆盖率阈值、实际覆盖率报告 |
| | JDepend | `jdepend` | -- | 包循环、不稳定性、距离主序列的距离 |
支持自动检测技术(18 个技术键);可以使用 `nfr-review.yaml` 或 `nfr-review init` 进行覆盖。
## 快速开始
### GitHub Action (CI 集成)
添加一个单一的 workflow 文件,即可开始在 pull request 中获得 NFR 反馈:
```
# .github/workflows/nfr-review.yml
name: NFR Review
on:
pull_request:
branches: [main]
permissions:
contents: read
pull-requests: write
security-events: write
jobs:
nfr-review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: JimAKennedy/nfr-review@v1
with:
fail-on: "red"
sarif-upload: "true"
comment: "true"
```
这会扫描代码库,将 SARIF 上传到 Security 标签页,发布一个持久的 PR
评论,并在出现红色(严重)结果时使检查失败。添加一个 [夜间执行 workflow](docs/examples/nfr-review-nightly.yml) 以进行基线跟踪和 issue 同步。
请参阅 [docs/install.md](docs/install.md) 获取完整的安装指南(输入、输出、权限、执行模式、故障排除),以及 [docs/continuous-compliance.md](docs/continuous-compliance.md) 了解合规性框架映射。
### 本地 CLI
```
# Install from PyPI (requires Python 3.11+)
pip install nfr-review
# Run against a target repository
nfr-review run /path/to/your/repo
```
可选扩展:
```
pip install "nfr-review[llm-anthropic]" # LLM via Anthropic API
pip install "nfr-review[llm-openai]" # LLM via OpenAI-compatible APIs (Ollama, Azure, OpenRouter)
pip install "nfr-review[pdf]" # PDF report generation
pip install "nfr-review[scancode]" # license compliance scanning
pip install "nfr-review[diagrams]" # Graphviz diagram rendering
```
### Docker
预构建的 Docker 镜像已发布到 GHCR (`linux/amd64`)。该镜像包含所有扩展(PDF、Mermaid 图表渲染、Graphviz、LLM SDK)以及 `gh` CLI。
```
# Pull the image (--platform required on Apple Silicon Macs)
docker pull --platform linux/amd64 ghcr.io/jimakennedy/nfr-review:latest
# Scan a local project
docker run --rm --platform linux/amd64 \
-v "$(pwd)":/repo \
ghcr.io/jimakennedy/nfr-review:latest run /repo
# Full report with scoring
docker run --rm --platform linux/amd64 \
-v "$(pwd)":/repo \
ghcr.io/jimakennedy/nfr-review:latest report /repo --score -v
# Run everything (architecture + NFR + hygiene)
docker run --rm --platform linux/amd64 \
-v "$(pwd)":/repo \
ghcr.io/jimakennedy/nfr-review:latest all /repo -v
```
**在 Docker 中使用 LLM 功能:** 使用 `-e` 将您的 API key 作为环境变量传入。LLM 功能(执行摘要、ADR 漂移分析、PII 检测)是可选的——如果没有 API key,所有静态分析规则仍会正常运行。
```
# Anthropic API (default provider)
docker run --rm --platform linux/amd64 \
-v "$(pwd)":/repo \
-e ANTHROPIC_API_KEY \
ghcr.io/jimakennedy/nfr-review:latest report /repo
# OpenAI-compatible (Ollama running on the host)
docker run --rm --platform linux/amd64 \
-v "$(pwd)":/repo \
-e NFR_LLM_PROVIDER=openai \
-e NFR_LLM_MODEL=llama3 \
-e NFR_LLM_BASE_URL=http://host.docker.internal:11434/v1 \
-e OPENAI_API_KEY=ollama \
ghcr.io/jimakennedy/nfr-review:latest report /repo
```
**macOS (Apple Silicon):** 该镜像仅支持 `linux/amd64`。M 系列 Mac 上的 Docker Desktop 会通过 Rosetta 模拟来运行它——必须使用 `--platform linux/amd64` 标志。为了获得更快的模拟速度,请在 Docker Desktop 中启用 **Settings > General > "Use Rosetta for x86_64/amd64 emulation on Apple Silicon"**。
请参阅 [docs/install.md](docs/install.md) 获取完整的 Docker 参考,包括在 GitHub Actions 中的容器模式。
## 环境要求
- **Python 3.11+** (`python3.11`, `python3.12` 等——macOS 自带的 `python3` 版本为 3.9,过于老旧)
- Python 依赖会通过 `pip install -e .` 自动安装
### 可选外部工具
这些**不是** Python 包——它们是一些独立的二进制文件,供部分收集器在运行时调用。当缺少这些工具时,程序会优雅降级(跳过相关分析并给出提示信息),但为了实现完全覆盖,建议安装它们:
| 工具 | 使用者 | 安装方式 |
|------|---------|---------|
| [Helm](https://helm.sh/) | `helm` 收集器 —— 在分析前通过 `helm template` 渲染基于 Go 模板的 Helm chart | `brew install helm` (macOS) 或访问 [helm.sh/docs/intro/install](https://helm.sh/docs/intro/install/) |
如果没有 Helm,Helm 收集器仍会静态分析 `Chart.yaml` 和 `values.yaml`,但会跳过渲染后的 manifest 分析(模板展开、渲染输出中的机密泄露)。
### 可选:LLM 功能
支持三种 LLM 后端:Anthropic API(`[llm-anthropic]` 扩展)、兼容 OpenAI 的 API(如 Ollama,`[llm-openai]` 扩展)和 Claude CLI(无需额外扩展)。通过 `nfr-review.yaml` 或环境变量进行配置。如果没有配置后端,LLM 功能将被优雅跳过。有关设置详情,请参阅 [docs/install.md — LLM 功能](docs/install.md#7-llm-features)。
## 安装
### 从 PyPI 安装
```
pip install nfr-review
```
### 可选扩展
| 扩展 | 添加的内容 |
|-------|-------------|
| `[llm-anthropic]` | 用于 LLM 驱动分析的 [anthropic](https://pypi.org/project/anthropic/) SDK(执行摘要、ADR 漂移、PII 检测)。 |
| `[llm-openai]` | 用于兼容 OpenAI 的后端(Ollama、Azure OpenAI、OpenRouter)的 [openai](https://pypi.org/project/openai/) SDK。 |
| `[scancode]` | 用于许可证合规性扫描的 [scancode-toolkit](https://github.com/aboutcode-org/scancode-toolkit)。若未安装,许可证卫生规则将优雅跳过并给出警告信息。 |
| `[diagrams]` | 用于 `--render-diagrams` 输出的 [graphviz](https://pypi.org/project/graphviz/) Python 绑定。 |
| `[pdf]` | 用于生成包含渲染图表和执行摘要的 PDF 报告的 [weasyprint](https://weasyprint.org/)。 |
| `[dev]` | 用于开发和 CI 的 pytest、ruff 和 pytest-cov。 |
可以单独安装或组合安装扩展:
```
pip install "nfr-review[llm-anthropic,pdf]"
```
### 开发安装(从源码)
```
git clone https://github.com/JimAKennedy/nfr-review.git
cd nfr-review
python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e ".[dev]"
```
## LLM 后端(可选)
LLM 辅助规则(PII 检测、ADR 漂移分析)需要 LLM 后端。支持三种后端:
**Anthropic API**(默认):
```
pip install "nfr-review[llm-anthropic]"
export ANTHROPIC_API_KEY="sk-ant-..."
nfr-review run /path/to/repo
```
**兼容 OpenAI**(Ollama、Azure OpenAI、OpenRouter):
```
pip install "nfr-review[llm-openai]"
export NFR_LLM_PROVIDER=openai
export NFR_LLM_MODEL=llama3
export NFR_LLM_BASE_URL=http://localhost:11434/v1
export OPENAI_API_KEY=ollama # Ollama ignores this but the SDK requires it
nfr-review run /path/to/repo
```
**Claude CLI**(Claude Code 订阅,无需 API key):
```
export NFR_LLM_PROVIDER=claude-cli
nfr-review run /path/to/repo
```
通过 `nfr-review.yaml` 配置以获得持久化设置:
```
llm:
provider: openai # anthropic | openai | claude-cli
model: llama3
base_url: http://localhost:11434/v1
api_key_env_var: OPENAI_API_KEY
```
环境变量(`NFR_LLM_PROVIDER`、`NFR_LLM_MODEL`、`NFR_LLM_BASE_URL`)会覆盖配置文件中的设置。如果未配置后端,LLM 功能将被优雅跳过,其他所有规则仍会正常运行。
## 用法
### 扫描代码库
```
nfr-review run /path/to/target/repo
```
这将:
1. 从目标代码库收集证据(Spring 配置、K8s manifest、CI workflow、Dockerfile、Helm chart、Terraform、Istio、源代码、ADR、APIM 策略等)
2. 根据收集到的证据评估所有适用的规则
3. 将审查结果写入当前目录下的 `{repo}-nfr-review.csv` 和 `{repo}-nfr-review.jsonl` 文件中
4. 将摘要信息打印到 stderr
**选项:**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--config PATH` | `./nfr-review.yaml`(如果存在) | 配置文件的路径 |
| `--csv PATH` | `{repo}-fr-review.csv` | CSV 结果的输出路径 |
| `--jsonl PATH` | `{repo}-nfr-review.jsonl` | JSONL 运行记录的输出路径 |
| `--sarif PATH` | — | SARIF 2.1.0 结果文件的输出路径 |
| `--exclude-tests` / `--include-tests` | exclude | 将测试和 fixture 目录排除在分析之外 |
| `--baseline PATH` | — | 先前 JSONL 文件的路径;屏蔽已知结果,若出现回归则退出 |
| `--score` | off | 计算并显示设计成熟度评分 |
| `--workers N` | `1` | 并行的收集器线程数(`1` = 顺序执行) |
| `-v` / `--verbose` | off | 增加详细程度(`-v` 对应 INFO,`-vv` 对应 DEBUG) |
| `-q` / `--quiet` | off | 屏蔽警告(仅限 ERROR 级别) |
| `--log-file PATH` | stderr | 将诊断信息写入 FILE 而不是 stderr |
**退出代码:**
| 代码 | 含义 |
|------|---------|
| 0 | 成功 —— 扫描完成 |
| 1 | 错误 —— 目标路径错误、配置错误或引擎故障 |
| 2 | 阈值违规 —— 至少有一个结果达到或超过了 `severity_threshold` |
### 列出可用规则
```
nfr-review list-rules
# JSON output (includes compliance refs, tags, severity, category)
nfr-review list-rules --format json
```
### 获取特定规则的详细信息
```
nfr-review explain ci-test-stage-missing
```
### 运行卫生审计
```
# Full hygiene audit (documentation, CI, community, build readiness, privacy)
nfr-review hygiene /path/to/target/repo
# License compliance only (requires scancode extra)
nfr-review hygiene --category license /path/to/target/repo
# List all registered hygiene checks
nfr-review hygiene --list-checks
```
如果没有安装 `[scancode]` 扩展,许可证规则将被跳过并给出提示信息——所有其他卫生类别仍会正常运行。
**选项:**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--list-checks` | off | 列出已注册的卫生检查并退出 |
| `--output-dir PATH` | `.` | 写入 CSV 和 JSONL 文件的目录 |
| `--format FORMAT` | `both` | 输出格式:`csv`、`jsonl` 或 `both` |
| `--severity-threshold LEVEL` | — | 如果有任何结果达到或超过此严重程度,则以退出代码 2 退出 |
| `--category NAMES` | — | 用于过滤规则的、以逗号分隔的类别名称 |
| `--config PATH` | `./nfr-review.yaml`(如果存在) | 配置文件的路径 |
| `--exclude-tests` / `--include-tests` | exclude | 将测试和 fixture 目录排除在分析之外 |
| `-v` / `-q` / `--log-file` | — | 同 `run` 命令 |
### 生成完整报告
```
# Run NFR + hygiene + pytest + deps and produce timestamped files in reports/
nfr-review report /path/to/target/repo
# Skip PDF generation
nfr-review report --no-pdf /path/to/target/repo
# Skip LLM summary (PDF still generated, without summary section)
nfr-review report --no-summary /path/to/target/repo
# Skip design maturity score computation
nfr-review report --no-score /path/to/target/repo
```
这会在 `reports/` 目录下生成带有时间戳的文件:
- `{repo}-nfr-review-{timestamp}.md` —— 包含 NFR 结果、卫生检查结果、测试结果和依赖项摘要的 Markdown 报告
- `{repo}-nfr-review-{timestamp}.csv` —— 合并后的 CSV 结果
- `{repo}-nfr-review-{timestamp}.jsonl` —— 合并后的 JSONL 运行记录
- `{repo}-nfr-review-{timestamp}.pdf` —— PDF 报告(默认开启;使用 `--no-pdf` 跳过)
**选项:**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--config PATH` | `./nfr-review.yaml`(如果存在) | 配置文件的路径 |
| `--output-dir PATH` | `reports/` | 写入报告文件的目录 |
| `--no-pdf` | — | 跳过 PDF 报告生成(默认会生成 PDF) |
| `--no-summary` | off | 跳过 LLM 执行摘要(PDF 将省略摘要部分) |
| `--no-score` | off | 跳过设计成熟度评分计算 |
| `--no-tests` | off | 跳过 pytest 执行 |
| `--no-deps` | off | 跳过依赖树分析 |
| `--no-diagrams` | off | 在报告中屏蔽 Mermaid 图表部分 |
| `--exclude-tests` / `--include-tests` | exclude | 将测试和 fixture 目录排除在分析之外 |
| `--sarif PATH` | — | SARIF 2.1.0 结果文件的输出路径 |
| `--test-timeout SECS` | `900` | 等待 pytest 完成的最长秒数 |
| `--max-resolve-rounds N` | `2000` | 依赖分析的最大解析器迭代次数 |
| `--workers N` | `1` | 并行的收集器线程数(`1` = 顺序执行) |
| `-v` / `-q` / `--log-file` | — | 同 `run` 命令 |
### 分析依赖
```
# Show upgrade summary table and transitive dependency tree
nfr-review deps /path/to/target/repo
# Skip transitive resolution (faster)
nfr-review deps --no-tree /path/to/target/repo
# Write Markdown report to a file
nfr-review deps --output deps-report.md /path/to/target/repo
# Write Graphviz DOT dependency graph (optionally render to SVG)
nfr-review deps --dot deps.dot /path/to/target/repo
nfr-review deps --dot deps.dot --render-diagrams /path/to/target/repo
```
**选项:**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--no-tree` | off | 跳过传递依赖解析和依赖树(速度更快) |
| `--output PATH` | — | 将 Markdown 依赖报告写入 FILE |
| `--dot PATH` | — | 将 Graphviz DOT 依赖图写入 FILE |
| `--render-diagrams` | off | 将 DOT 图渲染为 SVG(需要 `[diagrams]` 扩展) |
| `--max-resolve-rounds N` | `2000` | 依赖分析的最大解析器迭代次数 |
| `-v` / `-q` / `--log-file` | — | 同 `run` 命令 |
### 生成架构文档 \[实验性\]
```
# Generate architecture docs for a single repo (JSON + Markdown + PDF)
nfr-review arch /path/to/target/repo
# Generate for multiple repos as a unified report
nfr-review arch /path/to/repo1 /path/to/repo2
# Skip LLM-based analysis (domain model enhancement, market comparison)
nfr-review arch --no-llm /path/to/target/repo
# Output only JSON and Markdown (no PDF)
nfr-review arch --format json --format md /path/to/target/repo
```
**选项:**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--output-dir PATH` | `reports` | 写入报告文件的目录 |
| `--format FORMAT` | `json` + `md` + `pdf` | 输出格式:`json`、`md`、`pdf`(可重复指定以输出多种格式) |
| `--no-llm` | off | 跳过基于 LLM 的分析(领域模型增强、市场比较) |
| `--diagram-mode MODE` | `hierarchical` | 组件图布局:`hierarchical`(概览 + 细节)或 `flat` |
| `-v` / `-q` / `--log-file` | — | 同 `run` 命令 |
### 动态分析(运行时 trace)
nfr-review 可以分析从运行的应用程序中捕获的 OpenTelemetry trace,以检测延迟热点、N+1 查询模式、缺失的 trace 关联以及服务覆盖率缺口。
**选项 A —— 预先收集的 trace:**
```
# Run your app's integration tests (or exercise it manually) while an OTel Collector
# exports traces to an NDJSON file, then point nfr-review at the file:
nfr-review report /path/to/repo --otel-traces /path/to/traces.ndjson
```
**选项 B —— 托管收集器**(nfr-review 会为您启动/停止 `otelcol-contrib`):
```
# 1. Start your instrumented application (it must export OTLP to localhost:4317 or :4318)
# e.g. ./gradlew bootRun, docker compose up, python manage.py runserver, etc.
# 2. nfr-review starts the collector, captures traces during the scan, then stops it
nfr-review report /path/to/repo --collector -v
```
`--collector` 标志要求您的 `$PATH` 中包含 `otelcol-contrib`:
```
# Installs otelcol-contrib along with other optional tools
scripts/setup-all.sh
# Or download the binary directly from GitHub releases:
# https://github.com/open-telemetry/opentelemetry-collector-releases/releases
```
| 标志 | 描述 |
|------|-------------|
| `--otel-traces PATH` | 预先收集的 OTLP JSON / NDJSON trace 文件的路径 |
| `--collector` | 在扫描期间启动一个托管的 OTel Collector(与 `--otel-traces` 互斥) |
动态分析会在报告中生成 **运行时服务拓扑** 图和 **调用序列图**。如果没有 trace 数据,Band 3 规则将被跳过,所有静态分析仍会正常运行。
请参阅 [docs/dynamic-analysis.md](docs/dynamic-analysis.md) 获取完整的参考信息(trace 格式、CI 集成、自定义收集器配置、故障排除)。
### 初始化配置文件
```
# Auto-detect technologies and generate nfr-review.yaml
nfr-review init /path/to/target/repo
# Preview without writing a file
nfr-review init --dry-run /path/to/target/repo
```
### 提交或同步 GitHub issue
```
# Scan and file issues for high-severity findings
nfr-review issues scan /path/to/target/repo
# Preview without filing
nfr-review issues scan --dry-run /path/to/target/repo
# Sync issues from a prior JSONL scan file
nfr-review issues sync findings.jsonl --repo owner/repo
# Preview sync decisions without calling GitHub
nfr-review issues sync findings.jsonl --dry-run
```
**`issues scan` 选项:**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--dry-run` | off | 预览 issue 而不提交到 GitHub |
| `--repo OWNER/REPO` | 自动检测 | GitHub owner/repo(根据 git remote 自动检测) |
| `--severity-threshold` | `high` | 提交 issue 的最低严重程度 |
| `--config PATH` | `./nfr-review.yaml` | 配置文件的路径 |
| `-v` / `-q` / `--log-file` | — | 同 `run` 命令 |
**`issues sync` 选项:**
| 标志 | 默认值 | 描述 |
|------|---------|-------------|
| `--repo OWNER/REPO` | — | GitHub owner/repo(除非使用 `--dry-run`,否则为必填) |
| `--extra-labels LABELS` | — | 要应用的、以逗号分隔的额外标签 |
| `--rag-min LEVEL` | `amber` | 提交 issue 的最低 RAG 级别:`red`、`amber`、`green` |
| `--severity-threshold` | `high` | 提交 issue 的最低严重程度 |
| `--first-run-cap N` | `25` | 首次同步时创建的最大 issue 数 |
| `--close-resolved` / `--no-close-resolved` | close | 关闭其结果已不存在的 issue |
| `--dry-run` | off | 在不调用 GitHub 的情况下预览决策 |
### 一次性运行所有内容
`nfr-review all` 会在一次调用中对所有目标执行跨代码库的架构审查,并为每个目标生成 NFR 报告。
```
# Architecture + NFR reports for two repos
nfr-review all /path/to/repo1 /path/to/repo2
# Skip architecture, just batch NFR reports
nfr-review all /path/to/repo1 /path/to/repo2 --no-arch
# Custom output directory, skip PDF and tests
nfr-review all /path/to/repo1 --output-dir my-reports --no-pdf --no-tests
```
| 选项 | 默认值 | 描述 |
|--------|---------|-------------|
| `--output-dir` | `reports` | 所有输出文件的目录 |
| `--no-arch` | off | 跳过跨代码库的架构报告 |
| `--no-tests` | off | 跳过每个代码库的 pytest 执行 |
| `--no-deps` | off | 跳过依赖分析 |
| `--no-diagrams` | off | 在 NFR 报告中屏蔽 Mermaid 图表 |
| `--no-pdf` | off | 跳过 PDF 生成 |
| `--no-summary` | off | 跳过 LLM 执行摘要 |
| `--no-score` | off | 跳过成熟度评分 |
| `--no-llm` | off | 跳过架构报告中的 LLM 分析 |
| `--diagram-mode` | `hierarchical` | 架构图布局 |
| `--test-timeout` | `900` | 每个代码库的 pytest 超时时间(秒) |
| `--workers` | `1` | 每个代码库的并行收集器线程数 |
| `--exclude-tests` | exclude | 将测试目录排除在 NFR 分析之外 |
### 管理交互基线
为生产监控创建并比较交互基线:
```
# Create a baseline from OTel trace data
nfr-review baseline create --otel-traces traces.ndjson -o baseline.json
# Diff production traces against a baseline
nfr-review baseline diff --baseline baseline.json --otel-traces prod-traces.ndjson
```
### 运行生产监控
启动一个长期运行的 OTLP HTTP 接收器,将传入的生产 trace 与 UAT 基线进行比较,并为新的交互发出 JSON 告警:
```
nfr-review monitor --baseline baseline.json --port 4318
```
需要 `[monitor]` 扩展(`pip install nfr-review[monitor]`)。
### 检查版本
```
nfr-review version
```
## 配置
在您的工作目录中创建一个 `nfr-review.yaml`(或通过参数传入 `--config`)。所有字段都是可选的——空文件或完全没有文件都会使用安全的默认值。
```
version: 1
# Declare which technology stacks the target repo uses.
# Rules requiring a tech that isn't declared true will be skipped.
# 18 tech keys are auto-detected; these override detection results.
tech:
spring_boot: true
apim: false
terraform: false
cmake: true # enables C++ rules
# Control which rules run.
rules:
skip:
- sample-readme-exists # skip specific rules by ID
# include_only: # or run only these (mutually exclusive with skip)
# - ci-test-stage-missing
# - probes-missing
# Control which collectors run.
collectors:
skip: []
# If any finding has severity >= this threshold, exit code is 2.
# Valid values: info, low, medium, high, critical
severity_threshold: high
# Glob patterns for paths to exclude from all collectors.
# Built-in exclusions (.venv, node_modules, .regression-repos, etc.) always apply.
exclude_paths:
- "vendor/**"
- "third_party/**"
# Set to false to include test directories in analysis (default: excluded).
exclude_test_paths: true
```
## 规则
nfr-review 内置了涵盖多个领域的 147 条规则(119 条 NFR + 28 条卫生规则)。精选示例:
| 规则 ID | 领域 | 描述 |
|---------|--------|-------------|
| `ci-test-stage-missing` | CI/CD | 标记没有测试步骤的 CI pipeline |
| `ci-security-scan-missing` | CI/CD | 标记没有安全扫描的 CI pipeline |
| `adr-lifecycle-gap` | 架构 | 检查 ADR 状态生命周期一致性 |
| `architectural-drift-from-adr` | 架构 | 检测偏离 ADR 决策的代码(LLM 辅助) |
| `probes-missing` | Kubernetes | 标记没有 liveness/readiness probe 的 deployment |
| `resource-limits-missing` | Kubernetes | 标记没有 CPU/内存限制的容器 |
| `network-policy-missing` | Kubernetes | 标记没有网络策略的 namespace |
| `health-endpoint-missing` | Java | 标记没有 health endpoint 的服务 |
| `resilience-annotation-missing` | Java | 标记缺失的断路器/重试模式 |
| `thread-pool-misconfiguration` | Java | 检测无界线程池和队列配置 |
| `actuator-exposure-risk` | Spring | 标记不安全的 Actuator endpoint 暴露 |
| `go-error-ignored` | Go | 标记被忽略的错误返回值 |
| `go-goroutine-leak` | Go | 检测 goroutine 泄漏模式 |
| `python-mutable-default` | Python 标记可变默认参数 |
| `python-broad-except-silent` | Python | 检测被静默屏蔽的广义异常 |
| `cpp-raw-memory` | C++ | 标记应使用智能指针的原始 `new`/`delete` 用法 |
| `cpp-exception-safety` | C++ | 标记 C++ 源码中不安全的异常处理模式 |
| `csharp-async-void` | C# | 标记 async void 方法(应返回 Task) |
| `csharp-blocking-async` | C# | 检测 async 调用上的 `.Result` / `.Wait()` |
| `nodejs-floating-promise` | Node.js | 标记未等待的 promise |
| `nodejs-sync-fs-api` | Node.js | 标记同步文件系统 API 的使用 |
| `dockerfile-base-pinning` | Docker | 标记未锁定版本的基础镜像 |
| `dockerfile-secret-leakage` | Docker | 检测被复制到镜像层中的机密信息 |
| `helm-secret-leakage` | Helm | 检测 Helm values 和模板中的机密信息 |
| `terraform-provider-pinning` | Terraform | 标记未锁定版本的 Terraform provider |
| `terraform-iam-policy` | Terraform | 分析 IAM 策略中过于宽泛的权限 |
| `istio-mtls-strict` | Istio | 标记缺失的 strict mTLS 模式 |
| `apim-auth-policy-missing` | APIM | 标记没有身份验证策略的 API endpoint |
| `otel-pipeline-completeness` | 可观测性 | 检查 OTel pipeline 是否包含 trace、metric 和 log |
| `pii-in-log-statements` | 安全 | 检测日志语句中潜在的 PII(LLM 辅助) |
| `dep-freshness` | 依赖 | 标记有可用更新的包 |
| `dyn-latency-p95` | 动态 | 根据来自 OTel trace 的数据标记 P95 延迟热点 |
| `dyn-n-plus-1` | 动态 | 检测运行时 trace 中的 N+1 查询模式 |
| `PATCH-*`(22 条规则) | 补丁 | 部署和基础设施补丁就绪度分析 |
标记为“LLM 辅助”的规则会在未配置 API key 时使用可选的 LLM 调用以进行更深入的分析,并优雅地进行回退。
使用 `nfr-review list-rules` 查看已注册规则的完整列表,或使用 `nfr-review explain ` 查看任何规则的详细信息。
## 输出
`run` 命令会生成两个文件(以目标代码库命名):
- **CSV** (`{repo}-nfr-review.csv`) —— 每个结果一行,适合电子表格审查
- **JSONL** (`{repo}-nfr-review.jsonl`) —— 第一行是运行元数据,后续行是审查结果
`report` 命令会在 `reports/` 目录下生成带时间戳的文件:
- **Markdown** (`{repo}-nfr-review-{timestamp}.md`) —— 包含 NFR 结果、卫生审计结果、测试结果和依赖摘要的完整报告
- **CSV** (`{repo}-nfr-review-{timestamp}.csv`) —— 所有扫描的合并结果
- **JSONL** (`{repo}-nfr-review-{timestamp}.jsonl`) —— 合并的运行记录
- **PDF** (`{repo}-nfr-review-{timestamp}.pdf`) —— 包含执行摘要和图表的渲染 PDF(默认开启;使用 `--no-pdf` 跳过)
### 审查结果字段
| 字段 | 描述 |
|-------|-------------|
| `rule_id` | 产生该结果的规则 |
| `rag` | Red / Amber / Green / Skipped |
| `severity` | critical / high / medium / low / info |
| `summary` | 人类可读的描述 |
| `recommendation` | 建议的修复措施 |
| `evidence_locator` | 触发该结果的文件路径或资源 |
| `collector_name` | 收集该证据的收集器 |
| `collector_version` | 收集器版本 |
| `confidence` | 0.0 到 1.0 |
| `pattern_tag` | 所检测到模式的分类标签 |
| `content_hash` | 与行号无关的哈希值,用于稳定的基线对比 |
## 示例:扫描测试 fixture
该代码库包含您可以立即扫描的示例 fixture:
```
# Scan the Java sample repo (has Spring configs, K8s manifests, and Java source)
nfr-review run tests/fixtures/java-sample-repo
# Scan with a config that enables Spring tech
nfr-review run tests/fixtures/java-sample-repo \
--config tests/fixtures/configs/tech-spring-only.yaml
# View findings
cat java-sample-repo-nfr-review.csv
```
## 开发
```
# Run tests (parallel via pytest-xdist)
pytest -n auto
# Run tests with coverage
pytest -n auto --cov
# Lint
ruff check src/ tests/
ruff format --check src/ tests/
```
## 贡献
欢迎各种贡献!在提交 pull request 之前,请阅读我们的[贡献指南](CONTRIBUTING.md)。
- [行为准则](CODE_OF_CONDUCT.md)
- [安全策略](SECURITY.md)
- [更新日志](CHANGELOG.md)
## 开发透明度
本项目是在 Anthropic 的 Claude 的 AI 辅助下开发的。在开发过程中,AI 工具被用于代码生成、测试编写、文档编制和代码审查。所有 AI 生成的输出在纳入项目之前,均由人类维护者进行了审查、测试和验证。
## 许可证
Apache 2.0 —— 详情请参阅 [LICENSE](LICENSE)。
标签:代码审查, 子域名突变, 数据管道, 架构审查, 用户代理, 自动化分析, 请求拦截, 跨站脚本, 软件工程, 逆向工具, 非功能性测试