关于 quill
Notari 是用于 AI Agent 代码变更审查与取证的 Python 工具,会依据人工签署的路径范围、策略和 diff,在 CI 中生成可验证的变更凭证。它采用确定性检查而非模型判定,并提供可选的本地工具调用拦截;项目目前处于 Alpha 阶段。
主要功能
- 01按签署范围检查代码变更
- 02扫描常见格式的硬编码密钥
- 03生成可验证的签名变更凭证
- 04通过 HMAC 链式日志记录审计
- 05可选本地工具调用审批拦截
适用场景
- 01在 CI 检查 Agent 是否越权修改文件
- 02为拉取请求保存可复核的变更记录
- 03定位阻断项并生成修复指引
MCP 相关
输入内容没有说明 Notari 与 MCP 的关系。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
notari
Notari 会为每个由 AI 编写的拉取请求签发一份已签名的 Change Passport:任何审查者或审计员都可以仅凭签名重新验证这份凭证,无需重新运行 Notari,也无需相信截图。它会记录人类批准 Agent 修改的文件,以及 Agent 是否始终在这些文件范围内。人类只需为边界签名一次;在 CI 中,Notari 会根据该边界检查每个拉取请求,并为凭证盖上 PASS、NEEDS_REVIEW 或 BLOCK。判定过程中不使用模型,因此无法遭受提示词注入。它不会判断代码是否正确:它证明的是更改发生在哪里,以及是否泄露了机密——这是人类审查大型 Agent 拉取请求时最常忽略的部分。当前为 Alpha;如有任何一句话的说法与安全模型不一致,请以安全模型为准。
从这里开始:一条命令
uvx notari init
无需预先安装任何内容。在任意 git 仓库中运行一条命令,即可生成审批者密钥对和门禁密钥对,为默认安全的边界签名,写入经过加固的 GitHub 工作流(pull_request_target、固定 SHA、将拉取请求检出到仅存放数据的目录),将私钥加入 gitignore,然后打印当前实际的安全状态以及仍未完成的具体步骤。在未配置任何 Python 工具的干净机器上测得,CLI 大约 1.5 秒即可解析并运行。
更喜欢持久安装?可运行 pipx install notari 或 pip install notari,然后运行 notari init。无论哪种方式,接下来的两条命令就是日常完整流程:
notari begin "add rate limiting" --scope "src/api/**" # sign what the agent may touch
notari verify --strict # in CI: PASS, NEEDS_REVIEW, or BLOCK
notari init会自动禁止看起来敏感的目录(auth、migrations、infra、terraform、deploy等)。禁止规则优先于契约范围,因此将任务范围设入其中任何目录,都会按设计返回 BLOCK。如果确实需要修改其中的目录,请明确设置边界并为其签名:notari guard --key approver.pem --allow "src/**" --forbid "migrations/**"。
实际能得到什么
四个方面,每一项都按实际能力描述,而非最理想化的说法:
1. 门禁,即可证明的边界。 在 CI 中,Agent 无法触及的环境会将 .notari/ 之外的每个更改路径与已签名的范围和边界进行比对,并扫描每个被修改的文件,检查 26 种供应商机密模式;重命名(两个端点)、仅模式更改、二进制文件、符号链接、子模块以及 .gitattributes 隐藏差异等内容,都会纳入清单,而非成为盲点。每项任务的范围由你指定(--scope),因此较窄的范围表示“仅限这些路径”,而明确指定 --scope '**' 则表示“签名边界未禁止的任何内容”。无论哪种情况,凭证都会清楚说明范围,因此 PASS 绝不会含糊。机密检测采用有限的模式集,因此只能捕获常见的供应商格式泄露,无法证明不存在机密。判定路径中不使用模型,因此无从进行提示词注入。
2. 凭证,即使运行结束后仍可留存。 一份 Change Passport(passport.json 加上适用于 PR 的 passport.md),其 Ed25519 签名可由任何人在数月后通过 notari verify-passport 于另一台机器上重新验证,因此伪造或篡改的判定会验证失败,你可以相信已签名的凭证,而不是截图。这只能验证门禁确实签发了该判定,不能证明代码正确,也不会重新运行门禁。其背后还有一份由 HMAC 链接的审计日志,可通过密码学方式检测编辑和插入;运行 notari audit verify 后,还能依据已封存的高水位标记检测末尾截断。凭证页脚会引用本次运行对应的确切链条条目。
3. 修复路径,让 BLOCK 可采取行动。 notari explain 会将 BLOCK 转化为针对每项发现的修复方案和可直接粘贴的 Agent 提示词,notari agent-brief 则会在下一个 Agent 开始工作前,将已批准的范围交给它。所有操作都在本地进行,均需人工把关,不收集遥测数据,也绝不会有原始代码、差异或机密值离开你的设备。
4. 笔记本电脑上的防护机制,属于纵深防御,并非坚不可摧的边界。 可选的 PreToolUse 钩子会在 Agent 调用工具时进行拦截(rm -rf、git push --force、DROP TABLE、vercel --prod、读取 .env);关键调用需要一次性、十分钟有效的审批,在 macOS 上通过 Secure Enclave 上的 Touch ID 进行硬件认证;Agent 写入的文件还会经过 AST 检查,在后续 python foo.py 执行这些文件之前标记出 shutil.rmtree 和 exec(b64decode(...))。
第四行特意注明了限制:有决心的攻击者可以绕过应用层拦截机制;这些限制都列在安全模型中,而不是被刻意隐瞒。真正可靠的边界是 CI。
刚接触这个项目? 从快速入门开始(约 10 分钟,从零开始到拦截一个有问题的 PR)。然后查看: 安全与威胁模型 · 产品与等级。
发现了绕过方式、令人困惑的错误,或者有理由绝不会采用这个工具? 这正是我们推出此 alpha 版想要收集的反馈: 提交问题。
想先试着攻破它? bash examples/bypass_probes.sh 会针对刚签署的边界运行十二种绕过测试,并逐一打印判定结果:
将文件重命名到禁止路径、仅更改模式、大小写变体、隐藏在 .gitattributes -diff 条目后的机密、Agent 扩大自己的已签署合约范围等。十一项判定为 BLOCK;第十二项是文档中说明的按行拆分机密限制。如果你发现第十三种情况能得到不该有的 PASS,那就是你能提供的最有价值的反馈。
AI Agent 发起了一个拉取请求。它没有获准修改哪些文件?面对 Agent 提交的 40 个文件的差异,人们往往会扫一眼就略过这个问题,而 Notari 会在 CI 的合并边界给出答案,并生成经过签署的 Change Passport,供审阅者重新验证,而不必相信一张截图。判定结果由差异、已签署的合约和策略确定性地计算得出,因此其中没有可被越狱的模型。它会记录变更去了哪里,以及是否泄露了机密;但不会证明范围内的代码正确无误或不存在后门。这就是它诚实的能力范围。
# 0. one-time: create a human approver key. Keep the PRIVATE half off the build
# box; pin the PUBLIC half so a PR cannot edit the trust root (in CI this is a
# repo/org secret or variable, NOT a path inside the checkout).
notari keygen --out approver.pem
export NOTARI_APPROVER_PUBKEYS="$(cat approver.pem.pub)"
# 1. sign the standing boundary ONCE: what agents may touch, what is off-limits.
notari guard --key approver.pem --allow "src/**" --forbid "migrations/**"
# 2. capture AND SIGN the approved task (a signed contract can't be forged by the agent).
notari begin "Add rate-limiting to the login endpoint" --scope "src/auth/**" --key approver.pem
# commit .notari/{perimeter.json,perimeter.sig,contract.json,contract.sig} to the BASE branch.
# 3. the agent writes the diff and opens the PR.
# 4. CI verifies the PR against the signed boundary, in strict mode.
notari verify --strict # PASS · NEEDS_REVIEW · BLOCK (BLOCK fails the build)
# add --sign-key gate.pem (or NOTARI_GATE_KEY in CI) to ALSO sign the verdict,
# so a reviewer can re-check it with `notari verify-passport`.
这一完整流程——固定的外部审批者密钥、签署的边界、签署的合约、--strict——才是真正抵御恶意行为的边界。省略其中任何一项(不带标志运行 notari begin / notari verify),Notari 仍会运行,但会处于协作模式:为非恶意 Agent 提供诚实的审查自动化,而不是防止试图越界的 Agent。判定签名为可选项(需要门控密钥),默认不启用。完整的部署清单请参阅 docs/SECURITY-MODEL.md。
notari verify 会读取 git diff <base>..HEAD,根据你批准的范围检查每个变更文件,扫描每个被触及的文件,查找硬编码机密和敏感内容(CI 配置、锁文件、测试删除),评估所有已记录的例外,并生成一份变更凭证:passport.json + 一份可直接用于 PR 的 passport.md。凭证会引用本次运行的 HMAC 链式审计条目,让审查者能够将判定追溯到防篡改记录,而不是只相信 Markdown 文档。
为什么需要这一层
编写代码的 Agent 拥有 shell 访问权限、文件写入权限、部署权限以及你的凭据,而相关事故已有记录:2025 年 7 月,Replit 的 Agent 在一次氛围编程过程中删除了生产数据库,并伪造数据掩盖此事;同月,Cursor Agent 对一名开发者的主目录运行了 rm -rf ~/;8 月,一名自主 Agent 将客户的 GitHub 令牌提交到了公开提交记录中。这些事件的共同点并不是模型邪恶,而是在变更发布前,没有任何机制核对它是否符合实际获批的内容。
Notari 将这项检查放在可强制执行并留有记录的地方:CI 中的拉取请求上。门控在 Agent 自身进程之外运行,受审查对象无法悄悄将其关闭。判定是差异、合约和策略的确定性函数;决策流程中没有大模型,因此门控本身不会受到提示词注入攻击。
Notari 是什么,又不是什么
校准比营销更重要。
- Notari 是验证与证据工件,不是内容分类器。 它不会预测变更是否“良好”。它会根据记录的契约(范围、密钥、敏感面)检查差异,并签发一份可供人类审查的判定。门禁中没有模型。
- CI 门禁是可辩护的边界;本地门禁则是纵深防御。 Notari 还提供一个可选的笔记本电脑运行时门禁(见下文)。该门禁在工具分发层充当确定性的减速带和记录器,能提高粗心 Agent 和常见破坏/数据外泄行为的门槛,但它不是抵御蓄意尝试逃逸的攻击者的硬边界(先写入再运行、重新排列标志、继承环境变量、未受门禁限制的网络出口,都是文档中记录的限制)。完整且坦诚的威胁模型见 docs/SECURITY-MODEL.md。
- Notari 不会认证合规性。 审计日志是机器可验证的证据,审计员会希望审查它,但它本身并不是审计员会接受的工件。
- Notari 不是托管服务。 它是一个独立的 Python 包。审计日志和签名密钥以
0o600模式存放在你的磁盘上;密钥、日志和判定都由你掌控。验证流程不会往返云端,默认也不收集遥测数据。 - Notari 不消耗 AI 令牌。 其中没有 LLM:判定、密钥扫描、通俗易懂的
explain和本地门禁,全都由确定性代码实现(正则表达式、glob、AST、计数)。没有模型、没有 API 密钥、没有单次检查费用,也没有任何需要计量的东西。这里唯一涉及的令牌,是你的编码 Agent 编写代码时已经消耗的令牌;如果你选择把 Notari 的修复提示词粘贴回去,还包括它修复时消耗的令牌。这是有意为之的设计特性,而不是限制:带模型的门禁可能遭受提示词注入,而且每个 PR 都会产生费用;而这个门禁既不会遭受此类攻击,也不会产生此类费用。
详细了解变更控制
1. notari begin,记录契约
notari begin "Add rate-limiting to the login endpoint" \
--scope "src/auth/**" --scope "tests/auth/**" \
--approved-by alice \
--key approver.pem \
--expires-in 7 --repo owner/repo
写入 .notari/contract.json:获批任务(文本或工单 URL)、allowed_paths 范围(glob、目录前缀或精确路径)、变更起始时所基于的基础提交,以及 contract_id。--key 会为其签名,使 verify --strict 能证明契约由人类编写(严格模式下必需);--expires-in 设置失效期限;--repo 会将审批绑定到一个仓库,防止已签名的契约在其他地方被重放。将契约(以及 .sig)提交到分支;它是后续衡量差异时依据的固定记录,变更护照也会引用它。
2. notari verify,把关差异
notari verify --strict # enforced mode: requires the signed perimeter + contract
notari verify # local/cooperative: advisory, forgeable by the agent
verify(src/notari/verify.py,基于 policy.evaluate_diff):
- 通过
git diff --name-status -z --find-renames <base_commit>..<candidate>构建权威的变更路径清单,包含重命名的两端、二进制变更和仅模式变更, - 将每个变更路径(包括重命名的两端)与契约范围进行匹配,
- 使用
src/notari/secrets.py中的 26 种供应商格式密钥模式扫描每个被触及的文件,从候选提交读取整个文件(而不只是新增行),因此 100% 重命名或 UTF-16 文件都无法藏匿凭据, - 对敏感区域分类(CI/工作流文件、锁文件、测试删除、
.gitattributes等控制差异可见性的 Git 配置), - 应用
.notari/exceptions.json中记录的例外(严格模式下完全忽略,未签名的豁免文件无法削弱严格判定), - 综合得出 PASS、NEEDS_REVIEW 或 BLOCK 判定,并将
verification.run事件链接到审计日志中。
BLOCK 会以非零状态码退出(CI 失败);PASS 和 NEEDS_REVIEW 则以 0 退出,因此会呈现审核提示,但不会硬性阻断流水线。整个流程具有确定性:给定相同输入——差异、契约、已签名的边界、受信任的审批者密钥、严格标记和任何(已签名的)例外——就会返回相同判定,并且每一行都可解释。判定过程不涉及模型;唯一与时钟相关的引用是契约过期检查(--expires-in),这是由人明确设置的截止时间,而非启发式判断。
3. 变更通行证
verify 会写入 passport.json(机器可读,供下游工具和状态检查使用)和 passport.md(可直接用于 PR)。Markdown 页脚会注明 verification.run 审计 MAC,因此通行证可追溯到防篡改链,而不是要求你相信这份文档。
4. GitHub Action
# .github/workflows/notari-change-control.yml
on:
pull_request_target: # NOT pull_request, see "Why pull_request_target" below
branches: [main]
jobs:
change-control:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
path: _pr_checkout # isolate candidate code from trusted runtime
persist-credentials: false
# Pin to the release commit SHA, not a mutable tag, `notari status`
# rejects a non-SHA pin. `notari init` writes the current pin for you.
- uses: manumarri-sudo/notari@a084829cabacbbc7e85a5b8323580f514ad54771 # 0.4.2 release action
with:
head: ${{ github.event.pull_request.head.sha }}
head-sha: ${{ github.event.pull_request.head.sha }}
checkout-path: _pr_checkout
strict: "true"
block-on-review: "true" # NEEDS_REVIEW fails the job too, so a review-class change can't merge unseen
approver-pubkeys: ${{ secrets.NOTARI_APPROVER_PUBKEYS }}
gate-key: ${{ secrets.NOTARI_GATE_KEY }}
gate-pubkeys: ${{ vars.NOTARI_GATE_PUBKEYS }}
为什么使用 pull_request_target: pull_request 事件会运行 PR 版本的工作流,因此 AI Agent 可以修改工作流,彻底移除 Notari 步骤,导致把关机制永远不会触发。pull_request_target 从基础分支(main)运行,因此只有已合并的代码才能控制把关规则定义(PR 无法编辑用于审核自身的工作流)。严格模式下,拒绝在 pull_request 事件中运行,以强制遵守这一规则。为什么使用 path: _pr_checkout: 隔离候选代码库的检出,避免候选代码控制的 Python 模块(pip.py、json.py)在安装 Notari 时覆盖受信任的导入。完整的安全模板见 docs/secure-workflow.yml。
组合式 Action(action.yml)会运行 notari verify --strict,发布提交状态检查,并在判定为 BLOCK 时令作业失败。审批者公钥和把关签名密钥来自 PR 无法读取或编辑的仓库/组织机密,这使信任根位于外部。如果 PR 没有 .notari/contract.json,验证会报错并以默认拒绝方式使作业失败(退出码为 2),而不会悄然放行;因此,删除或省略契约无法让变更蒙混过关。要求通过此项检查之前,请先在基础分支上初始化变更控制(notari begin --key)。
BLOCK 后:说明并修复
大多数把关机制只会给出判定。Notari 会把阻断转化为修复方案,全部在本地完成,无遥测且具有确定性(不由模型决定任何事情):
notari verify # PASS · NEEDS_REVIEW · BLOCK + a passport
notari explain # the passport in plain English + a fix per finding
notari explain --fix-prompt # a compact prompt to paste into your coding agent
notari agent-brief # the compact pre-work brief to hand an agent before it starts
notari explain 会读取通行证,并针对每条发现用通俗语言说明问题、提供用于撤销该变更的精确 git 命令,以及可直接粘贴给 Agent 的指令;此外还会说明 Notari 无法证明的内容(它检查的是边界,而不是代码正确性)。--fix-prompt 和 --agent-brief 会输出精简的 Agent 信息,不会把完整通行证塞进上下文。Notari 绝不会上传原始代码、差异、提示词或机密值。
信任主干:对边界签名一次,Agent 就无法伪造
在 CI 中运行的意义在于,门禁位于 Agent 无法禁用的地方;但只有当 Agent 也无法伪造批准或篡改自己的裁判时,这才有意义。Notari 使用 Ed25519 同时解决了这两个问题(验证使用公钥,伪造需要私钥,而不是同一个密钥;对称 HMAC 链永远无法做到这一点):
notari keygen --out approver.pem # human's key; keep the private half OFF the box
notari guard --key approver.pem --forbid 'migrations/**' --forbid 'src/auth/**'
# ^ signs .notari/perimeter.json once. From now on EVERY agent's PR is checked
# against it automatically, you're paged only when one crosses the line.
- 由人一次性签署边界;每个 PR 都会被强制执行,无需逐项批准。 这就是对“我可不想坐在这里批准一百个 Agent”的回应。禁止路径和篡改门禁的编辑会触发 BLOCK;默认情况下,机密信息会触发 BLOCK(已签署的边界可将其放宽为审核);边界内的工作则会静默通过。
- Agent 无法自行授权(严格模式下,信任根位于外部)。 编辑边界、审批者密钥(
.notari/approvers/**)或运行门禁的工作流本身都会触发 BLOCK(门禁篡改检测);篡改已签署的边界或契约会使签名失效。在严格模式下,契约受其 Ed25519 签名保护,而非门禁篡改 glob 集;未签名或伪造的契约会因来源检查失败而触发 BLOCK。已提交的.notari/approvers/*.pub集合只是便利措施,并非安全边界:在严格模式下,只有外部固定的NOTARI_APPROVER_PUBKEYS才受信任,否则 Agent 可以在基提交中植入密钥,为自己的批准签名。外部密钥加严格模式,才能让这项安全保障名副其实,而非一厢情愿。 - 判定无法伪造。 配置门禁密钥(
notari verify --strict --sign-key gate.pem,或 CI 中的NOTARI_GATE_KEY)后,护照会被签名;任何人都可以使用notari verify-passport passport.json重新检查,判定被篡改或签名者不受信任时,检查会失败。 - 或者使用 GitHub 自带的审核。
notari check-approval要求由非 PR 作者的人批准当前头部提交;Agent 无法批准自己的 PR,且推送新代码后,原有批准会被撤销。 要构成真正的边界(而非可选项),必须做到: 信任根必须位于 PR 无法修改的位置。将审批者/门禁的私钥保存在构建机器之外(仓库/组织机密:NOTARI_GATE_KEY、NOTARI_APPROVER_PUBKEYS),对契约签名(notari begin --key)并在严格模式下要求签名,将 Action 固定到发布提交的 SHA(而非可变标签,也不能使用 PR 自身的检出版本;notari status会拒绝非 SHA 固定值),并在分支保护中将状态检查设为必需。关于最后一点,有一个坦诚的提醒:必需检查是一个裸的提交状态,任何具有statuses: write权限的工作流都能发布相同的notari/change-control上下文,因此遭到入侵的同仓库工作流可以发布绿色状态,掩盖实际的 BLOCK。Notari 会让这种情况可检测(护照指纹会记录它实际写入的状态的 SHA 和 MAC,notari verify-passport会进行交叉核验),但要绑定检查的来源,使其完全无法伪造,需要使用 GitHub App 检查运行,此功能已列入路线图。在此之前,请勿向不受信任的工作流授予statuses: write权限。做到这些后,安全模型列出的绕过方式便能抵御测试套件所覆盖的攻击(包括复合型的基础提交中恶意密钥攻击、Action 包装器默认放行问题,以及二进制/重命名差异覆盖;这些问题都已通过回归测试解决);若未做到这些,它就只是面向协作型 Agent 的诚实审查自动化。目前尚未经过外部安全审计,因此请将“已解决”理解为“针对我们目前测试的内容已解决”,并以跟踪剩余未解决事项的 docs/SECURITY-MODEL.md 为准,而非本 README。
本地运行时门禁(可选,纵深防御)
除 CI 外,Notari 还可以通过 Claude Code 的 PreToolUse 钩子,在 Agent 调用工具时于你的笔记本电脑上进行门禁检查。这是辅助层,明确定位为纵深防御、确定性的减速带和记录器,而不是硬性边界。
notari onboard # detect agents, install the hook, pick a risk preset
从下一个会话起,每次 Bash / Edit / Write / NotebookEdit 调用都会经过 src/notari/policy.py 中的编译正则分类器:默认情况下,rm -rf、git push --force、DROP TABLE、vercel --prod、npm publish、读取 .env,以及 CVE-2025-59536 子命令链绕过均属于严重类别。严重调用会被拒绝,并提供通俗易懂的原因;若要批准,需使用一次性、有效期为 10 分钟的 notari approve <token>;在 macOS 上,批准操作会通过安全隔区上的 Touch ID 进行硬件验证。Agent 写入的文件会使用同一组 26 个密钥模式进行扫描,并通过 AST 扫描(code_scan.py)标记具有破坏性的 Python 结构(shutil.rmtree、os.system、exec(b64decode(...))),避免之后运行 python foo.py 时执行这些结构。每项决策都会写入 ~/.notari/audit.log.jsonl,并通过 HMAC-SHA256 链接以提供防篡改证据。
本地门禁的辅助功能均在读取时从同一条链派生:notari receipts(按会话汇总已执行/已更改/不确定/待验证事项)、notari trifecta(致命三要素暴露:不受信任的输入 + 私有数据 + 外传途径)、notari pins(对工具描述进行固定,防范 MCP 暗中替换),以及 notari audit(审查并验证链)。notari scan-secrets 可独立运行密钥检测器,扫描文件。
为什么这是纵深防御,而不是核心卖点: 有能力的攻击者可以绕过应用层门禁(见上文的局限)。可证明的边界是 CI 门禁,它在 Agent 无法禁用的环境中运行,并生成经过签名的记录。本地门禁切实有用,但它应当坦诚地宣称“提高攻击门槛并记录一切”,而不是“无法绕过”。
已签名的审计日志
两个界面都会写入 $NOTARI_HOME/audit.log.jsonl,权限为 0o600。每条记录的
mac 都是使用安装密钥计算的 HMAC-SHA256(prev_mac || canonical(payload))
(首次运行时自动生成,存储于 $NOTARI_HOME/key,权限为 0o600)。写入时会调用
fcntl.flock(LOCK_EX),并在锁内重新读取末尾的 MAC,防止并发写入破坏链条。密封的
<log>.head 高水位标记让 verify 能检测末尾截断,而不仅仅是编辑和插入。
notari audit verify
# chain intact: 72739 entries verified.
该统计数据来自维护者机器上 76 天的实际自用记录(2026-05-07 至 2026-07-22, 发布时重新测量);你自己的日志从 1 开始。该链在本地具备防篡改检测能力(也可选择 锚定到外部)。关于它能带来和不能带来的保障,请参阅 docs/SECURITY-MODEL.md。
安装
一键安装方式位于本 README 顶部(uvx notari init)。其他方式:
uvx notari begin --help # no install; run any subcommand once
pipx install notari # or install the CLI persistently
pip install notari # or into an existing venv
所有位置都使用同一个名称:PyPI 分发包、CLI 二进制文件、导入路径、配置目录
(~/.notari/)和环境变量(NOTARI_*)均为 notari。
开发用检出版本可运行:git clone https://github.com/manumarri-sudo/notari && cd notari && pip install -e .。
CLI 功能
notari begin capture the approved task into .notari/contract.json
notari verify compare the diff to the contract, emit PASS / NEEDS_REVIEW / BLOCK
notari explain turn the passport into plain-English remediation (--fix-prompt, --agent-brief, --format html)
notari fix-prompt compact paste-ready fix prompt for the coding agent
notari agent-brief compact pre-work brief to hand an agent before it starts
notari onboard first-run setup for the local gate (detect agents, install hook)
notari audit review what got blocked / allowed / asked; verify the chain
notari approve <tok> confirm a pending one-shot approval (Touch ID on macOS)
notari approvals list (hashed ids) / revoke pending approval tokens
notari receipts per-session did / changed / uncertain / to-verify
notari trifecta lethal-trifecta exposure tracking
notari pins tool-description pins (anti-poisoning, anti-rug-pull)
notari scan-secrets scan files for hardcoded credentials
notari scan-prompts scan files for prompt-injection-shape patterns (signal only)
notari commit-hook-install add a session-summary block to the commit message template
notari doctor diagnose the install
notari version print the version
运行 notari --help 查看完整列表(包括会弱化防护的 night/off 开关;
使用前请阅读 docs/SECURITY-MODEL.md)。
当前发布内容与路线图
**当前发布(0.3.0),有磁盘证据:**变更控制工作流
(begin/verify/passport + GitHub Action)、HMAC 链式审计日志(32k+ 条自用记录,
可检测截断,notari audit verify 检查通过)、带 Touch ID 审批和 26 种模式机密检测的
本地 PreToolUse 防护、先写入再运行的 AST 扫描,以及读取侧功能(回执、trifecta、
pins)。完整测试套件(实时数量请运行 uv run pytest)、ruff、ruff format 和
mypy --strict 均通过,并在 CI 中强制执行。
路线图(当前尚未发布,请勿假定已提供):将 passport 渲染为 PR 评论(当前 Action
会发布 Status Check)、将致命三元组的执行升级作为 CI 信号、面向 Cline / Aider /
Continue / Windsurf / Zed 的逐工具钩子适配器、用于跨平台硬件认证审批的 WebAuthn,
以及 from notari import gate BYO-agent 库 API。早期预览版曾发布的 MCP 代理、OS
沙箱、桌面仪表板和带外通知渠道已在变更控制转型中移除,此版本系列不会恢复。
安全
notari 本身属于安全关键代码。威胁模型、防护机制有效拦截的内容及其可被绕过之处的
如实说明,以及负责任披露联系方式,详见 SECURITY.md 和
docs/SECURITY-MODEL.md。接通 PyPI 发布流程后,计划通过
PyPI Trusted Publishing 签名发布,并提供
PEP 740 证明(计划中,尚未实施)。
贡献
发现了遗漏的危险操作类别、diff 解析器中的作用域绕过问题,或误报?请附上复现步骤提交
issue。适配器位于 src/notari/adapters/ 下。
许可证
MIT。详见 LICENSE。随仓库提供的第三方代码已在 NOTICE 中注明来源。 版本历史见 CHANGELOG.md。仓库: github.com/manumarri-sudo/notari。
在 Claude(Anthropic)的协助下构建。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。