rpkiparrot 开发约定
本文件适用于整个仓库,保存长期有效的实现与验证约束。功能范围、协议版本和交付阶段以 设计文档 为依据;开始相关工作前读取对应章节。用户在当前任务中的明确要求优先于本文件,已确认的设计调整应同步更新文档。
首版各模块的实施契约从 文档导航 进入。编码前读取对应的公共 API、数据与错误、生命周期、输入、RTR、持久化或外部接口章节,并按 行为验收 关联测试。设计示例和签名在实现前不是可运行接口;实现时转为源码生成参考及可执行示例,行为变化同步契约。
扩展功能或选择实现捷径前,核对 Decision / Decline 中的范围与不变量;区分不属于库职责、首版不提供和已承诺扩展,不能自动扩大范围或删除既定交付。未决契约与新增需求继续在 GitHub Issues 跟踪。
实现相关模块时按 实现参考库 查阅对应项目的接口、源码和测试;本项目设计与协议规范优先,参考清单不自动增加依赖。
初始化工程、调整测试矩阵或发布流程时,查阅 CI/CD 落地参考。其中新增工具与平台方案属于待验证建议,不代表已经启用的检查或支持承诺;落地后同步更新文档状态与实际可用命令。
涉及 RTR、ROV 或 ASPA 的开发,先查阅 本地规范镜像 及对应的本地规范原文;资料缺失或需要核对上游更新、勘误时再联网。实现继续遵循设计固定的 RFC 或草案版本,新增或刷新镜像不自动升级实现基线。
JSON 读取器、RTR 编解码与 ASPA 验证实现前,查阅 数据格式与互操作资料。区分上游测试输出、真实导出子集和派生向量,按固定版本核对预期结果;样例不作为在线可信快照,上游源码不作为运行时依赖。
大型开发数据保存在 Git 忽略的 .local-data/,保留原始响应、下载元数据和校验值,具体路径见资料索引。可供本机开发与显式离线验证使用;常规测试和 CI 不依赖这些仅本机存在的文件。
AnyIO、Python 标准库及数据库 API 文档优先通过 Context7 按目标版本查询,通常不另做本地镜像;返回结果仍须核对原文版本,不能将混入的 main 分支内容用于最低版本兼容判断。Context7 缺少所需版本或主题时查阅官方文档。
后续设计讨论中确认且需要长期遵守的设计决策、开发约束和必读资料入口,按需更新本文件;详细设计继续维护在 docs/design.md。README.md 用于项目介绍、安装使用和面向用户的文档导航,新增内部设计约定写入本文件。
项目边界
- 本项目是面向广泛第三方开发者和应用的通用 Python 库,配套提供轻量级 CLI。功能包括 RTR 客户端、JSON 读取器、VRP 与 ASPA 存储和验证,以及可选持久化与服务组件。
- bmparrot 和 bmpalert 是初期集成参考与示例使用方。保持核心 API 独立,不从这些应用导入实现,不在库任务中自动修改它们;可以读取相关调用方式作为集成参考。
- 公共 API、默认行为、文档和示例面向独立的第三方集成设计,不要求调用方了解或依赖特定应用的配置、数据模型与运行流程。
- 按当前任务或里程碑推进。设计文档中的计划接口与 extras 不代表已经实现,文档和交付报告应准确区分计划与现状。
- RPKI 证书链验证、仓库抓取、BGPsec 路径验证、历史数据库和生产 RTR 服务器不在当前范围内。
开发方式
- 当前由一名开发者维护,直接在主分支
main上开发;不默认创建功能分支、独立 worktree 或 PR,不以 PR 和多人审批作为日常开发前提。用户明确要求其他流程时按任务指示执行。 - 全库代码的实现与修改由 Codex 或 Claude Code 完成,两者统一遵循本文件、设计文档及同一套验证要求,不因使用不同工具而降低质量门槛。
- 在整个代码生成阶段,用户授权 Codex 和 Claude Code 根据任务进展自行执行
git commit和git push到本仓库的main,无需逐次请求确认;提交与推送遵循当前任务范围、相关检查和文档同步要求,并在交付说明中报告实际结果。 - 按可审查的小范围变更推进,尽可能关联 GitHub Issue;完成前检查实际差异、运行相关检查并同步文档。多个工具或会话工作时保持任务边界,避免同时改写同一文件或提交其他任务未完成的修改。
- 主分支直接开发仍执行提交前的本地检查和推送后的 CI 验证;CI 失败时优先修复,不将失败提交作为已通过验收的成果或发布候选。具体流程见 CI/CD 落地参考。
Python 与依赖
- 支持 Python 3.11+;语法、标准库 API、依赖范围和类型检查均与最低版本兼容。
- 核心直接第三方依赖为 AnyIO。CLI、HTTP、数据库驱动、服务框架和 SSH 等按设计作为可选依赖,延迟导入;未安装可选组件不能破坏核心包导入。CLI 使用
cliextra 中的 Typer 与 Rich,通过 Typer 公共接口定义命令和测试。 - 核心模型使用标准库数据类和类型。Pydantic 限于可选服务边界。
- 核心网络支持 asyncio 与 Trio。应用拥有事件循环和任务生命周期,嵌入库不私自创建事件循环或脱离管理的后台任务。
- 阻塞 I/O 使用受管理的工作线程或等效隔离方式,明确连接归属与取消清理。可选适配器的后端限制必须在启动时验证并记录。
实现约束
- 所有待实现的功能(feature)和待修复的问题(bug)尽可能在本仓库的 GitHub Issues 中建立或关联已有 issue,记录范围、验收条件与进展;不在
docs/下维护 feature/bug 待办清单或问题台账。docs/保留长期设计、接口契约和使用说明,可引用相关 issue。 - PDU 编解码、JSON 解析、内存查询和验证保持同步、可独立测试;网络、来源管理、持久化和 HTTP 分层实现。
- RTR v1、v2 和 ASPA 使用设计中固定的 RFC 或草案版本。变更版本时更新协议矩阵、行为说明和测试向量,不混用不同草案语义。
- 标准 ASPA 验证与上下文受限的 BMP 分析使用独立接口及结果类型。
- 首版支持运行中增删来源和修改配置,遵循 配置变更契约:配置、来源与快照原子提交,旧任务迟到结果必须隔离,不能将数据库后端/路径切换伪装成普通热更新。
- 数据、来源、时效和能力作为完整快照原子发布。RTR 在有效 End of Data 后提交,JSON 在完整解析通过后提交;失败或取消不得发布部分更新。
- 保留每个来源的原始状态,再构建合并和策略视图。单一来源的撤销或失效不能删除其他有效来源仍支持的数据。
- 区分不支持、未加载、已同步为空、连接中断但数据仍有效、数据失效。无可用数据不能伪装成正常的
notfound或unknown。 - 恢复、重新读取旧文件和发布新快照均不能延长原始数据有效期。批量操作固定快照,仍须遵守在线时效检查。
- 事件在快照发布后产生,初始观察与订阅不得有空窗。队列有界;事件遗漏必须明确要求重新同步,不能静默丢失或阻塞协议同步。
- 默认只使用内存。SQLite 与 DuckDB 都是首版可选后端;本机共享数据库实时读取使用 SQLite,DuckDB 由单一拥有者维护并通过服务供其他进程访问。
- 持久化原子提交完整状态并报告持久化版本。失败不破坏有效内存快照;恢复必须检查来源身份、完整性和时效。
- 核心日志由宿主应用配置,不修改根日志处理器。凭据和私钥不进入快照、协议录制元数据或日志。
- CLI 调用公共 API,领域逻辑保留在库内;stdout 只写结果,日志、进度与错误写 stderr,机器输出不含终端控制码。退出码、缺少 extras 的提示及中断清理按设计验证。
验证与交付
- 公共 API 的实现与文档必须在同一项变更中完成:新增、修改、弃用或移除 API 时,同步更新 docstring、API 参考及相关使用示例;文档未完成,该 API 不算交付完成,不能留待后续补写。
- API 文档从源码签名、类型注解和 docstring 生成,行为语义由开发者同步维护。公开模型、参数、返回值、异常及适用的时效、资源归属和取消约定必须可查;具体内容与生成建议见设计文档和 CI/CD 落地参考。
- 先运行与改动相关的检查,再根据跨模块影响扩大范围。协议、验证算法、事件一致性和恢复行为需要有意义的边界及故障测试。
- 规范测试向量和真实生产者样例应注明来源及版本。不能只用本项目编码器生成的数据证明解码器正确,也不能通过削弱断言让测试通过。
- 首版平台目标为 Windows 11 x86_64/AMD64,以及 macOS、Linux 的原生 x86_64/AMD64 与 ARM64;不含 Windows ARM64 和 32 位 x86;具体 OS、extras 和未验证或不支持的组合见 兼容契约。规模及资源初值按 性能基线验证,不从上游实现推断本库性能。
- 按用户确认,GitHub 仓库为
bgpglobal/rpkiparrot,全部 Actions 作业使用组织的 self-hosted Linux x86_64 runner,标签为[self-hosted, linux, x64]。Windows 11 x86_64、macOS x86_64/ARM64、Linux ARM64 提供本机验收命令,当前候选未执行的组合保留为未验证,不阻塞本次首版交付,也不声明全平台通过;不自动恢复 GitHub 托管运行器或全平台任务。 - 支持目标保留 CPython 3.11–3.14;按用户最新确认,自动 CI 和候选验收仅运行真实 CPython 3.11、3.14,3.12、3.13 提供手动验收命令,未执行不能计为通过。核心异步代码分别覆盖 asyncio 与 Trio。SQLite 与 DuckDB 共用后端契约测试,可选安装组合检查核心导入与功能隔离。
- 静态检查以 Python 3.11 为基线,结合目标环境的安装、行为与 wheel 验收确认兼容性。缺少解释器、依赖安装失败、未收集到必需测试或跳过必需环境时不能报告兼容性通过;
requires-python声明和静态扫描不能替代实际运行。 - PyPI 发布前验收最终 sdist 与 wheel,在干净环境验证安装、extras、公共调用和类型信息;上传已验收的同一批制品。
twine check、pip check或平台接收成功均不能单独作为功能与兼容性通过的依据,详细检查见 CI/CD 落地参考。 - 纯说明性文档改动检查内容一致性、格式和本地链接,文档构建落地后同时运行相关构建检查,无需为此新增运行时测试。API 文档和可执行示例随对应实现一起验收;示例或文档生成配置变更运行相关检查,不能只按文字修改处理。
- 交付说明列出实际改动、已执行检查及结果、尚未验证的部分。缺少环境或互操作条件时如实记录,不把未执行的检查写成通过。
- 公共行为、依赖或架构发生变化时,同步维护设计和使用文档;不把完整设计、临时任务进度或模型档位复制到本文件。
开发命令
工程使用 uv 与提交的 uv.lock 管理开发环境,源码采用 src/ 布局。以下入口已实际执行;某个命令可运行不表示完整首版或所有平台已经验收,具体测试范围与证据见相关 Issue 和 reports/。
uv python install 3.11 3.14
uv sync --locked --all-extras --python 3.11
uv run --locked ruff check .
uv run --locked ruff format --check .
uv run --locked nox -s tests-3.11 tests-3.14
# 可选手动兼容性检查
uv python install 3.12 3.13
uv run --locked nox -s tests-3.12 tests-3.13
uv run --locked nox -s dependencies
uv run --locked python scripts/build_docs.py --check-failure
uv run --locked python -m build
uv run --locked python -m twine check --strict dist/*
uv run --locked check-wheel-contents dist/*.whl
Ruff/mypy 以 Python 3.11 为基线;测试会话使用真实解释器,缺失解释器、零用例或必需用例跳过均失败。nox -s typing、nox -s docs 和 nox -s package 组织类型、公开 API 参考和隔离制品门禁;对应功能的首次通过证据仍须单独记录,不能只凭会话定义视为通过。Nox 默认只选 3.11、3.14;tests-* 与 dependencies 使用 pytest-xdist 按文件分配、自动选择最多 4 个 worker,-- -n 0 可用于串行诊断。tests-* 自动保存环境、依赖、JUnit 与合并后的分支覆盖率;dependencies 单独重新解析最低直接运行依赖和最新允许版本,不降低开发工具。运行 pytest 可用 RPKIPARROT_TEST_BACKEND=asyncio|trio 显式选择单个后端;常规验证不设置该变量。
Goal 与并行工作
- 用户明确要求建立 Goal 时,按可验收的里程碑设置目标,写清结果、验证方法和范围;普通提问、设计讨论或本文件本身不自动创建 Goal。
- 用户要求使用子代理时,按可独立验证的工作划分职责,先固定共享接口,避免多个代理同时改写同一核心文件;汇总结果后完成集成验证。
- 不在仓库内固定模型或推理档位,按任务需要和当前用户设置执行。