内容
align="center="assets/banner.svg" alt="Maisha — MISRA, BARR-C and CERT C compliance harness" width="100%"></p>
# Maisha
[](https://github.com/Kiransekar/maisha/actions/workflows/ci.yml)
[](https://github.com/Kiransekar/ma/tag/v0.3.1)


**适用于 MISRA C:2012、BARR-C:2018 和 CERT C 的开源合规工作流层 — 可从任何智能 IDE 中使用。**
Maisha 是免费、厂商中立的替代品,替代像 Polyspace、Helix QAC、Coverity 和 Parasoft 那样的付费合规 *工作流*,它们作为智能工具包出售:修复循环、验证门、偏差和审计证据工作流,以及作者时间指导 — 在免费引擎(cppcheck + clang-tidy)上运行 **或** 层叠在您已经合格引擎之上(通过 SARIF)。它 *不是* 一个合格的检测引擎,也不假装是。→ 查看 [**Maisha 的比较**](COMPARISON.md)。
> *Maisha* 是斯瓦希里语中 **"生命"** 的意思。像 MISRA 和 CERT C 这样的合规标准之所以存在这是飞机的软件、汽车的驾驶和医疗设备的代码 — 缺陷会带来生命损失,而不是正常运行名称是工具努力的目标。CLI 和软件包是 `maishac`(*Maisha-for-C*)。
> ⚠️ **Maisha 是一个工作流协调器和审计跟踪层,而不是合格/认证的静态分析工具。** 它的发现本身并不满足 DO-178C、ISO 26262 或 IEC 62304 的要求,运行它也不是正式的合规认证。它最好在合格引擎的上游使用(参见 [范围和限制](#scope--limitations))。
Maisha 不是另一个 linter。它是自主合规工作流的 *确定性一半*。你的 IDE 的 LLM(Claude Code、Cursor、Windsurf、Zed,任何支持 [MCP](https://modelcontextprotocol.io) 的工具)进行代码编辑;Maisha 完成所有必须绝对确定的事情:
- **扫描和证据合并** — 一个零依赖的本地分析器,以及 `cppcheck`(带有其 MISRA 插件)和 `clang-tidy`(`cert-*` 检查)的适配器。来自多个分析器的发现,如果它们命中同一个缺陷,则会被指纹合并成一个具有强化证据的发现(`analyzer: native+cppcheck`)。
- **主动第一次编写合规代码)** — 两个作者时间界面,以便代理编写第一次通过的合规代码,而不是在后续扫描中修复:
- `compliance_guidance`(CLI:`maishac guide "<topic>"`)— 一个合规模式库:在编写代码之前针对某个问题(动态内存、字符串、递归、整数溢出,...),它返回首选的 **惯例**、应 **避免** 的反模式、**原因**,以及它满足的 MISRA/CERT/BARR-C 规则。
- `compliance_check_snippet`(CLI:`maishac check`)— 在内存中检查草稿 **,在写入文件之前**,返回违规、修复提示和要交换的合规惯例。(仅本机词法检查 — 语法子集,不是整个程序规则;干净的片段不是合规保证。)
查看 [`AUTHORING_PLAYBOOK.md`](AUTHORING_PLAYBOOK.md) 以获取指导 → 草稿 → 检查 → 重写协议,以便交给你的 IDE 代理。
- **稳定指纹** — 发现由 `sha1(rule + file + normalized line content + enclosing function)` 标识,*不是* 行号,因此它们在会话中幸存于编辑、插入和重构。
- **持久内存** —项目一个 SQLite 存储(`.maishac/memory),跟踪发现生命周期(打开 → 已解决 → 回每次修复尝试及其结果,假阳性抑制RA 样式偏差记录,带有理由/批准到期日的偏差记录,以及自由格式项目约定注释。
- **工程化的修复循环** — 具有严重性排名、文件分组批次的会话;回归总是跳到队列中;每个发现都经过简报,附有规则摘要、修复提示、已经 **失败** 的策略、相关内存注释和跨标准等效项。防护栏:迭代预算、停滞检测和振荡冻结(如果发现两次回归,则冻结为 `needs_human`)。
- **验证门** — 修复不只是因为分析器停止标记它而被视为 `resolved`。它进入 `pending_verification`,直到通过测试运行或显式人为批准确认;语义风险和高严重性发现始终需要人为确认。参见下面的 [验证门](#the-verification-gate)。
- **报告** — 按标准划分的合规矩阵、带有偏差注册的 Markdown 报告、SARIF 2.1.0 导出(带有 `partialFingerprints` 以供 CI 使用),以及 **MISRA Compliance:2020 证据集** — 评估功能安全所需的三个文档:**Guideline Compliance Summary** (每个指南的合规性 / 偏差 / 违规 / 取消,绑定到偏差许可)、**Guideline Enforcement Plan** (每个指南的检查方式 + 工具清单,带有版本/选项),以及 **Guideline Re-categorization Plan** (带有强制规则执行的合法性规则 — 强制性指南不能重新分类,必需的指南不能降低为建议/取消),以及诚实披露哪些指南 **未被检查**。
三个规则知识库(**81 条规则** — 31 条 MISRA C:2012、20 条 BARR-C:2018、30 条 CERT C)包含为该项目编写的 **原始改述摘要** — 没有复制标准文本。对于权威词需要官方的 MISRA / BARR / SEI CERT 文档。
---
## 范围和限制
**Maisha 是什么:**
- **工作流协调器**,用于代理驱动的合规分类和修复循环。
- **持久审计跟踪层**:发现生命周期、修复偏差记录、抑制和验证门,记录 **如何** 确认每个修复(测试运行 vs. 人,以及由谁)。
- **预认证清理** 工具,捕获并帮助修复明显的违规 — 在 IDE 循环中,在代码到达合格引擎之前。
**Maisha 不是什么:**
- **不是合格或认证的分析工具。** 它的引擎是开源的 cppcheck + clang-tidy + 本地分析器 — 没有一个带有工具资格工具包。DOC / ISO / IEC 62304 通常要求分析工具 **本身** 是合格的或已被证明使用;Maisha 不满足这一要求,也不声称满足。
- **不是完整的规则覆盖。** 涵盖三个标准的 81 条精选规则是 MISRA C:2012(180+ 条规则/指令,带有修正案)或 CERT C 的一小部分。检测受底层引擎的限制,而不是精选的集合。每个涵盖的规则以及哪个分析器支持它都在 [COVERAGE.md](COVERAGE.md) 中列出(从代码生成,因此空白是明确的)。在 FreeRTOS 内核上运行的现实世界测试 — 带有测量的假阳性率和的工具错误 —BENCHMARKSBENCHMARKS。首要训:**将传递给 cppcheck/clang-tidy**,使用 `--include`/`-I`(可重复),否则大多数实质性发现都是配置假阳性。从头开始的准确性/可靠性套件 —固定装置、循环模拟、SARIF 导入、CLI 端到端和边缘情况测试 — 在 [MARK-SUITE.md](BENCHMARK-SUITE-REPORT 中。
- **不是人类审查的替代品 默认情况下,修复永远不会仅因为干净的而被标记为 `resolved` — 需要通过测试运行或显式人为批准,并且语义风险严重性发现 **始终** 需要人为确认(验证门](#the-verification-gate))。
管道的推荐使用方式:** 运行 Maisha进行早期、代理驱动的清理,然后将合格的引擎(Astrée、Polyspace、Helix QAC、Parasoft C/C++test、IAR C-STAT)交给审计员接受的证据。这些引擎会发出 SARIF,而 `maishac import findings.sarif` 将 Maisha 的循环、内存、验证偏差寄存器层叠在他们的发现之上 — MISRA/CERT 规则 ID 映射到知识库,导入的发现永远不会被本地重新扫描清除。
**在现实引擎方言中表现稳健。** 合格引擎很少在 `ruleId` MISRA/CERT 编号 — Helix Q Coverity 发出特定于检查者的 ID(例如 `ABV.GENERAL`),通过 ` 引用规则索引,并将指南通过 `taxonomies` 附加到分类法组件中。Ma导入程序通过 `result.rule` / `rule / `ruleId` 解析规则,遵循分类法(以及结果级别的 `taxa以恢复实际指南,遵守 `defaultConfiguration` 级别,跳过非缺陷结果(`kind: pass`、`notApplicable`)和基线 `` 发现,容忍缺失的区域位置结果,并规范化带有前缀的 URI 方案丰富的 SAR映射。** 造成损失:合格 `codeFlows`(*到* 缺陷的数据流路径)被解析并在代理简报中显示,因此修复者可以看到缺陷如何流动,而不仅仅是它落在何处;并且 `result.suppressions` 被尊重,以便团队现有的分类/基线继续存在,而不是重新浮现为新的违规。跨标准的等价关系作为 SARIF `reportingDescriptor.relationships`(例如,链接到其 CERT 等价的 MISRA 规则),每个关系目标作为描述符存在。Maisha 的身份在 `partialFingerprints`(`maishac/v1`)中传递,并且 `startColumn` + 代码流在导入 → 导出往返中存活,因此重新导出合格引擎的发现不会丢失任何内容。
---
## 安装
需要 Python 3.10+。
```bash
pipx install maishac # 隔离的 CLI 安装(推荐)
# 或
pip install maishac
```
这将安装 `maishac` CLI 和 `maishac` Python 包。可以通过 `maishac --help` 验证。
**或以容器运行**(包含电池 - cppcheck 的 MISRA 插件和 clang-tidy 已内置,因此无需主机设置):
```bash
docker run --rm -v "$PWD:/work" ghcr.io/kiransekar/maisha scan src/
docker run --rm -i ghcr.io/kiransekar/maisha serve # 通过 stdio 提供 MCP 服务器
```
要修改 Maisha 本身:
```bash
git clone https://github.com/Kiransekar/maisha.git
cd maisha
pip install -e ".[dev]" # 可编辑安装,带有 pytest
```
可选但强烈推荐的外部分析器 — 本机分析器在没有依赖的情况下工作,但 cppcheck(MISRA 插件)和 clang-tidy(`cert-*` 检查)显著增加了覆盖率:
```bash
# Debian/Ubuntu
apt install cppcheck clang-tidy
# 或,无需 root,任何 pip 可用的地方(预构建轮,包括 Windows/macOS)
pip install cppcheck clang-tidy
```
Maisha 降级运行:`PATH` 上未找到的任何分析器都将被跳过,本机分析器始终有效。运行 `maishac scan` 一次并在输出中检查 `analyzers_used` 以确认实际启用的分析器。
## 快速入门(CLI)
```bash
cd your-firmware-project
maishac scan src/ # 一次性扫描,同步内存
# 外部头文件(例如,供应商 SDK 或 FreeRTOSConfig.h)?转发它们:
maishac scan src/ --include include/ --include vendor/sdk/inc
maishac findings --limit 20 # 排名靠前的开放发现
maishac rule "MISRA 21.3" # 解释规则 + 跨标准引用
# 工程化的循环(代理通过 MCP 驱动):
maishac session begin src/ --verification-policy human_gated
# -> {"session_id": "abc123...", ...} — 在下面使用该 ID
maishac session batch abc123 # 下一个优先批次,带有简报
# ... 编辑代码(您或您的代理)...
maishac session verify abc123 # 重新扫描,差异,评估尝试,运行测试门
maishac approve <fingerprint> --by lead@example.com #确认待验证的maishac session status abc123
ma "MISRA.2" "drivers/**"justification需要硬件寄存器覆盖映射" \
-- lead@example.com 2027-01
maishac suppress <fingerprint "假阳性:宏扩展"
maishac note "此使用 FreeRTOS_4 分配批准" --tags misra-21.ishac recategorize "MISRA 15.1" --to disapplied \
--rationale "此代码库中没有 goto; 由获取者/供应商协议取消" \
--approver lead@example.com
maishac report --format sarif > compliance.sarif
maishac report --format misra-compliance > gcs.md # 指南合规性摘要
maishac report --format gep > gep.md # 指南强制计划
maishac report --format grp > grp.md # 指南重新分类计划
```
## 快速入门(任意智能 IDE,通过 MCP)
将服务器添加到您的 IDE 的 MCP 配置([`integrations/`](integrations/) 中有现成的代码片段):
```json
{
"mcpServers": {
"maisha": {
"command": "maishac",
"args": ["serve"],
"env": { "MAISHAC_PROJECT": "/path/to/your/project" }
}
}
}
```
然后告诉你的代理类似这样的话:
> 在 `src/` 上启动 Maisha 合规会话,处理批次直到收敛,记录每一次尝试,并仅在无法修复的地方添加偏差。
推荐的代理协议在 [`AGENT_PLAYBOOK.md`](AGENT_PLAYBOOK.md) 中有详细说明。
## MCP 工具
| 工具 | 用途 |
|---|---|
| `compliance_scan` | 扫描路径,合并分析器,同步内存,返回差异(新的/持续的/已解决的/回归的) |
| `compliance_list_findings` | 排名靠前的开放发现,优先级高于严重性下限 |
| `compliance_get_finding` | 单个指纹的完整简报(历史,已尝试的策略, |
| `plain_rule 规则摘要,,修复提示,等效项 `compliance | 跨关键字搜索 |
compliance_guidance在编写**,获取符合模式(避免/首选/原因 +的规则)时间模式库 |
compliance_check | 在内存草稿 **写入文件之前**动式创作返回违规,修复提示和符合要求的代码模式;不存储任何内容 |
| `compliance_begin_session` | 基线扫描 + 会话,带有预算(`max_iterations`,`batch_size`)|
| `compliance_next_batch` | 下一个优先批次,优先处理回归,带有每个发现的简报 |
| `compliance_record_attempt` | 记录发现上使用的策略(在 `verify` 上自动评分) |
| `compliance_verify` | 重新扫描,差异,评估尝试,运行测试门,推进状态机 |
| `compliance_approve_finding` | 人工确认将 `pending_verification` 的发现移动到 `resolved`(对于语义风险/高严重性修复是必需的) |
| `compliance_session_status` | 进度,迭代预算,状态(`active`/`awaiting_verification`/`converged`/`stalled`/`budget_exhausted`)|
| `compliance_add_deviation` | MISRA 样式的偏差记录(强制性理由 ≥ 15 个字符)|
| `compliance_recategorize` | MISRA GRP 重新分类(合法性强制执行:无强制性重新分类;必需→建议/取消禁止)|
| `compliance_suppress_finding` | 将指纹标记为假阳性(需要原因)|
| `memory_note` / `memory_search` / `memory_stats` | 项目惯例内存 |
| `compliance_import_sarif` | 将外部引擎的 SARIF(合格引擎或 cppcheck `--output-format=sarif`)导入相同的循环/内存/门;**尊重 `result.suppressions`**,因此团队现有的分类/基线继续存在,而不是重新浮现为新的违规 |
| `compliance_report` | Markdown,JSON,SARIF 2.1.0 或 MISRA 合规性 2020 证据集:`misra-compliance`(GCS),`gep`(强制计划),`grp`(重新分类计划) |
## 架构
```
┌──────────────────────────── 你的智能 IDE ───────────────────────────┐
│ LLM 代理:读取简报,编辑代码,记录尝试 │
└──────────────▲──────────────────────────────────────────────────────────┘
│ MCP(stdio)
┌──────────────┴────────────── maisha ──────────────────────────────┐
│ 引擎/ 循环引擎:会话,批次,预算,停滞/振荡 │
│ 内存/ SQLite:发现,修复尝试,偏差,抑制, │
│ 注释,会话(.maishac/memory.db) │
│ 分析器/ 本机(无依赖)+ cppcheck(+MISRA 插件) + clang-tidy(cert-*) │
│ → 指纹识别的证据,严重性排序 │
│ 规则/ MISRA C:2012 + BARR-C:2018 + CERT C 知识库,模糊解析器, │
│ 跨标准引用 │
│ report.py 合规矩阵,Markdown,SARIF 2.1.0 │
└──────────────────────────────────────────────────────────────────────────┘
```
设计原则:
1. **关键部分的确定性。** 优先级,验证,内存和预算都是代码,而不是提示。LLM 只做它擅长的事情。
2. **发现是身份,而不是行号。** 指纹保留历史记录,并将其附加到缺陷上,跨越重构。
3. **循环必须终止。** 迭代预算,停滞限制和振荡冻结保证会话始终以明确的状态结束。
4. **合规是一个过程,而不是一次扫描。** 偏差和抑制是一等公民的可审计记录 — 正如 MISRA 合规性所期望的那样。
## 验证门
Maisha 防范的陷阱:修复的唯一评判标准是相同的分析器,而该分析器的盲点可能导致了该问题的发现。“警告停止触发”奖励的是语法上最小的编辑 —— 通常是最有可能在边界改变行为的编辑。将有符号的哨兵值(`-1` = “无限制”)强制转换为 `uint32_t` 以消除有符号/无符号比较警告,会将“无限制”变成“一个巨大的限制”——重新扫描通过后,静态检查永远不会捕获到它。
因此,修复并不直接进入 `resolved` 状态,而是进入 `pending_verification` 状态,只有在会话的 **`verification_policy`** 下才能离开:
| 策略 | 待定修复变为 `resolved` 状态时... |
|---|---|
| `analyzer_only` | 分析器停止标记它(⚠️ 不推荐用于合规性工作) |
| `test_gated` | 配置的 `test_command` 以 0 退出 |
| `human_gated` | 人工调用 `approve_finding` |
默认策略:如果配置了 `test_command`,则为 `test_gated`,否则为 `human_gated`。无论采用何种策略,**语义风险发现**(强制转换、比较、符号转换、控制流更改)和**高严重性发现**始终需要人工批准 —— 一个从未执行过哨兵情况的绿色测试套件无法解决它们。每次解决都会记录其确认方式(`analyzer`/`test`/`human`)以及人工确认的 `approved_by`。
> **请相应地设置期望值:** 语义风险规则类别列表很广泛(它涵盖了 MISRA 的大多数基本类型、控制流和 switch 语句规则,以及 CERT 的 `INT`/`FLP` 系列),在实践中,典型 MISRA 发现的 `test_gated` 会话最终需要人工确认的频率几乎与 `human_gated` 会话相同。一个完整的端到端模拟确认了一个通过的测试套件自动解决了 **零** 个八个待定发现中的一个 —— 请参见 [BENCHMARK-SUITE-REPORT.md §3.2](BENCHMARK-SUITE-REPORT.md#32-the-gate-is-more-conservative-than-it-looks)。请相应地预算人工审查时间;不要指望 `test_gated` 会消除大部分审查负担。
```bash
maishac session begin src/ --verification-policy test_gated --test-command "make test"
# ... 代理修复,然后:
maishac session verify <id> # -> 如果修复需要签名,则进入 awaiting_verification 状态
maishac approve <fingerprint> --by lead@example.com
```
## 团队与并发
项目内存存储在每个项目的 SQLite 文件 `.maishac/memory.db` 中。
- **忽略它。** 它是本地的、机器特定的状态,而不是源代码 —— 将 `.maishac/` 添加到 `.gitignore`(此仓库已经这样做了)。要故意共享状态,请导出合规性报告(SARIF/JSON),而不是提交数据库。
- **并发访问。** 数据库在 WAL 模式下运行,并带有忙碌超时,因此 CI 扫描和本地会话可以读写而不会硬阻塞。`session begin` 拒绝在同一项目上已经存在活动会话时启动第二个会话(使用 `--force` 覆盖),因此两个运行不会竞争发现状态。
## 开发
```bash
pip install -e . && python -m pytest tests/ -q
```
`examples/bad.c` 是一个故意不符合规范的示例,涵盖了大约 18 条规则 —— 作为演示目标非常有用。
## 贡献
非常欢迎贡献,特别是对社区可扩展部分的贡献:添加编码标准 **规则**、作者 **模式**(符合规范的习惯用法)或 **分析器适配器** / SARIF 方言映射。这些都不涉及引擎。请参阅 [`CONTRIBUTING.md`](CONTRIBUTING.md) 以获取操作方法以及要保留的设计不变式,以及 [`CODE_OF_CONDUCT.md`](CODE_OF_CONDUCT.md)。在跟踪器上标记了“良好第一问题”。
## 许可证 / 免责声明
规则摘要是原始的转述;MISRA®、BARR-C 和 SEI CERT C 是其各自所有者的财产。Maisha 输出并不构成正式的合规性认证。
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器