☰
Lore Enhancement Proposals(LEP)全流程指南:如何为 Lore 开源版本控制系统撰写、评审与演进设计提案
2026/9/25 5:39:18 网站建设 项目流程
  • 版本控制
  • 后端

【免费下载链接】lore

Lore is a next-generation, open source version control system

项目地址:https://gitcode.com/gh_mirrors/lore6/lore
点击查看免费下载

Lore 是一个面向大规模协作场景的下一代开源版本控制系统,其设计演进通过Lore Enhancement Proposals(LEP)这一公开的、面向实现前设计讨论的文档体系来驱动。本文以 docs/proposals/README.md 为骨架,结合 LEP 模板、LEP 体系自身的设计提案以及仓库内多份已落地 LEP 的真实案例,完整讲解 LEP 的生命周期、文件命名约定、逐节写作规范、审查要点,以及与 ADR(架构决策记录)的分工边界。读完本文,你将能独立起草一份符合 Lore 社区规范、可直接提交评审的 LEP。

什么是 LEP:设计与实现的桥梁

Lore 用三种文档类型分别承载设计意图的不同阶段:

  • ADR(架构决策记录):位于 docs/developing/decisions/,在架构决策已经做出之后记录窄范围的决策及其理由,采用NNNNN-<slug>.md命名,必须包含 Status、Context、Decision、Consequences 四部分。
  • Specs(规范)与 Plans(计划):描述系统当前做什么、按什么顺序执行工作,它们都假定决策已经存在。
  • LEP(Lore 增强提案):填补上述两者之间的空白——即"我们应当改变什么"到"我们已决定改变什么"之间的那段设计辩论期,详见 LEP 体系提案 的 Motivation 一节。

LEP 专门用于触及Lore wire 协议、磁盘格式、公共 API(CLI、capi、JS 绑定)以及跨切面(cross-cutting)功能的、实现之前的公开提案。它存在的意义是让设计辩论发生在代码落地之前:内部依赖团队与外部贡献者能在实现前对齐,未来贡献者也不会无意中重走已被否决的提案路线。

LEP 生命周期:Draft → Accepted / Rejected

LEP 采用极轻量的三态生命周期,刻意避免引入繁重的治理机制:

  • Draft(草案):正在撰写或评审中。
  • Accepted(已接受):已批准,可以开始实现。
  • Rejected(已否决):经过评估后未被采纳。被否决的 LEP 会保留在仓库中作为历史记录,防止后人重蹈覆辙。

状态记录在提案文件 YAML frontmatter 的status字段中。从仓库现有提案看,实际状态取值包含Draft(模板默认值)、Accepted与Approved,例如 统一 store 存在性/查询/元数据提案 为Accepted,OIDC/OAuth 2.0 认证改造提案 为Approved,而 LEP 体系自身提案 也是Approved。模板注释进一步说明:status在讨论 CR 合并时被设置为最终状态;Withdrawn(撤回)对应合并前关闭 CR,Superseded(被取代)则通过旧 LEP 的superseded-byfrontmatter 字段表达。整个体系没有 FCP(Final Comment Period)、没有临时/渐进状态、没有升级轨道。

文件命名遵循YYYY-MM-DD-kebab-name.md约定,例如2026-07-24-tokio-runtime-split-and-async-io.md。仓库docs/proposals/目录中已积累 12 份提案文件(含本 README 与模板),覆盖线程模型重构、存储接口统一、S3 对象碎片元数据、低层 revision API、OIDC 认证改造等主题,可以直观感受到 LEP 的适用范围。

如何开始撰写一篇 LEP

撰写步骤非常简单:

  1. 将 lep-template.md 复制到docs/proposals/目录,命名为YYYY-MM-DD-<your-slug>.md。
  2. 按下列规则逐节填充模板。
  3. 就绪后提交一个 CR(Change Request)供评审——评审者会按与下面相同的标准检查你的提案。

模板携带 YAML frontmatter 与 14 个正文小节,顺序固定。frontmatter 字段包括:

lep: YYYY-MM-DD-kebab-name title: Short, descriptive title authors: - Author 1 status: Draft # Draft → Accepted or Rejected. Set on merge of the discussion CR. created: YYYY-MM-DD updated: YYYY-MM-DD discussion: <link to the CR, JIRA ticket, or other review venue> # replaces: LEP id this proposal supersedes # superseded-by: LEP id that has replaced this proposal

注意replaces与superseded-by是注释形式,仅在需要表达提案取代关系时启用。

贯穿全文的写作纪律(Throughout the Proposal)

以下规则适用于每一个小节,是 LEP 写作的"通用法":

  • 主动语态。写 "this proposal rejects approach X",不要写 "approach X was rejected";写 "Lore writes the new version",不要写 "the new version is written by Lore"。过去分词形容词(如 "the upgraded client"、"the proposed design")是允许的。
  • 公开引用。LEP 是公开文档。每条事实陈述都必须要么附一个公开链接(RFC、Lore 代码树中的路径、公开 ADR、上游项目文档),要么在正文中内联记录相关细节。内部资源(CR、JIRA 工单、Slack 线程、内部 wiki)只允许放入 frontmatter 的discussion字段,不能替代正文中的论证支撑。
  • 每条论断都要有依据。如果无法用研究、先前讨论或提案本身支撑某个论断,就删掉它,而不是用文字填充空间。

从真实案例可以看到这条纪律的执行力度:OIDC 认证提案 中几乎每个结论都带源码路径,例如AuthorizationToken的 claim 结构引用 lore-server/src/auth/jwt.rs、客户端防外泄检查引用 lore-credential/src/jwt.rs、13 个 RPC 全部逐条映射到 lore-proto/proto/auth_api.proto。

逐节写作规范

Summary(摘要)

  • 一段话即可。
  • 面向对该领域不熟悉的读者写作。

Motivation(动机)

  • 描述这个提案要解决的问题以及为什么现在重要:触发提案的事故、限制、用户需求或外部压力。
  • 停留在问题上。解决方案留给 Proposed Design 部分。

以 Successor Locks 提案 为例,其 Motivation 清晰拆解了两个问题:现有互斥锁只能回答"现在编辑这个文件安全吗",无法回答"从这个分支给文件加新锁安全吗——此前的所有编辑是否都已被本分支看到"(因果性缺口);以及单一全局链会把相互独立的开发线过度耦合(分片缺口)。这些是纯粹的问题陈述,不带方案。

Goals / Non-Goals(目标 / 非目标)

  • Goals是提案想达成的结果,每一项都应在 Proposed Design 中被回应。
  • Non-Goals是明确排除在范围之外的相邻问题。当评审中出现范围蔓延时它们很有用。
  • 跳过"没有咬合力的 Non-Goals"——那些显然没人会期待的项目。

OIDC 提案 的 Non-Goals 值得借鉴:它明确排除了"替换 ReBAC 权限服务""sender-constrained tokens(DPoP)""改变 QUIC 存储Authorize帧"——每一条都是读者会自然联想到的相邻改动,排除理由具体(如Authorize帧携带的是不透明 bearer token,其布局不变)。

Proposed Design(方案设计)

  • 详细程度以能为 Goals 立论为准。实现细节属于下游 spec。
  • 对每个 Goal,指出设计中回应它的部分。若某个 Goal 找不到对应设计,要么把它移到 Non-Goals,要么扩展设计。
  • Motivation 中提出的每个问题都应在这里被回应。既不对应 Motivation 问题、也不对应 Goal 的设计内容,大概率是超范围了。

真实提案的设计密度极高:Tokio 运行时拆分提案 分两阶段推进(Phase 1 网络运行时隔离 + CPU 工作内联、Phase 2 专用文件 I/O 引擎),并指明阶段间顺序是承重的——内联计算只有等网络有了独立运行时之后才能进行,否则会饿死协议定时器。OIDC 提案 则以 D1–D9 编号小节展开,并大量使用 mermaid sequenceDiagram 描述设备授权登录、token 交换、服务端本地校验的时序。

Compatibility(兼容性)

触及外部表面的提案必须回答以下问题。不适用的子节写N/A(破折号后附简短理由有助评审,但非必需)。若你的提案触及其它兼容性表面(配置格式、环境变量、第三方库 API、插件接口),可自行追加子节。

  • Wire format(线协议格式)——v(N-1) 对端能解码 v(N) 产出的消息吗?v(N) 能解码 v(N-1) 吗?序列化、帧、压缩或字节布局发生了什么变化?
  • Client/server protocols(客户端/服务端协议)——引入了哪些新增或变更的 RPC、请求/响应形状、消息类型或认证流程?旧客户端与新服务器通信时看到什么?反之呢?
  • On-disk format(磁盘格式)——升级后的 Lore 能读现有仓库吗?降级的 Lore 能读新版本写入的数据吗?涉及哪些 fragment-flag、索引或 schema 变更?
  • CLI and public API(CLI 与公共 API)——lore子命令语法、退出码、输出格式、lore-capi/ JS 绑定表面发生了什么变化?对现有脚本和集成有什么破坏?

当子节不是N/A时,要具体——具体的 bit、具体的命令、具体的协议字段。像"会有一些影响"这种模糊回答对评审者没有价值。这一结构借鉴了 Swift Evolution 对源码兼容与 ABI 兼容的拆分,套用到 Lore 的四个外部表面之上,详见 LEP 体系提案。

OIDC 提案 的 Compatibility 是教科书级示范:wire format 直接N/A(QUICAuthorize帧的 token 字段是长度前缀的不透明字节);client/server protocols 精确到lore.environment.v1.Endpoint新增 8 个可选字段、旧客户端忽略新字段并继续读auth_url;on-disk format 说明 token store 形状不变、现有tokenstore.toml可无变化解析;CLI 部分精确到新增全局--auth-mode标志与LoreGlobalArgs.auth_mode字段。

Non-Functional Considerations(非功能考量)

对下列每个属性回答问题。若提案保持该属性,用一行说明;若改变它,说明影响及设计如何处理。可自行追加其它非功能关注点(延迟、吞吐、持久性、顺序保证、背压、错误预算)。

  • Concurrency(并发)——在并发读、写、提交、同步和合并下,提案表现如何?
  • Memory(内存)——提案是否需要与仓库或文件大小成比例地缓冲数据,还是保持 Lore 的流式与稀疏数据结构模型?
  • Statelessness(无状态性)——提案是否引入了跨操作存续的进程级或库级状态?
  • Determinism(确定性)——相同输入是否继续产生相同输出,包括历史?

OIDC 提案 还自加了一个 Latency 小节:Tier 1 无条件地从分区查询操作中去掉一次网络往返,用对已验签 token 的 claim 读取替代CheckUserPermission调用,无缓存需要预热、无内容需要失效。

Migration Plan(迁移计划)

  • 当任一 Compatibility 子节标记了破坏性变更时需要本节。
  • 命名过渡阶段(如 dark launch、early transition、late transition),这一模型取自 git 的hash-function-transition.adoc,详见 LEP 体系提案。
  • 对每个阶段,描述读/写兼容矩阵,以及用户所需的工具、标志、遥测和运维指引。
  • 覆盖回滚:什么可观测信号触发回滚,什么状态可恢复。
  • 若无破坏性变更,写N/A — no breaking changes, no migration required.

OIDC 提案 定义了 5 个阶段:Phase 1 仅放宽 claim 解析(无行为变化)、Phase 2 服务端接受标准 token、Phase 3 客户端 OIDC(Tier 1)、Phase 4 Tier 2 token exchange、Phase 5 退役旧客户端路径。每个阶段独立可回滚,且明确说明了旧/新路径如何并行(同一服务器同时广告auth_url与oidc_issuer,通过auth_mode标志让个别用户先行测试)。

Security Considerations(安全考量)

  • 是否改变了信任模型。
  • 恶意对端或精心构造的仓库能否滥用新行为。
  • 是否有新的数据对完整性或机密性敏感。
  • 若提案无安全影响,必须明说并解释原因——裸写N/A是不够的。

这遵循 IETF RFC 7322 的强制安全考量模式(见 LEP 体系提案)。OIDC 提案 的安全分析深入而具体:防外泄控制保留且 issuer 仍是域名列表的唯一来源(防"rogue server 诱导登录收集 token"攻击)、迁移期间的双路径降级风险、设备流本身可钓鱼(RFC 8628 §5.4)、命令行--client-secret的进程表/shell 历史暴露问题(改为从环境变量或 stdin 读取)、以及"Lore 不持有签名密钥"这一设计边界。

Privacy Considerations(隐私考量)

  • 哪些新的用户数据、标识符、文件路径或元数据会变得对其他方可见——服务器运营者、对端、遥测管道、日志。
  • 该变更是否影响删除、编辑(redact)或过期数据的能力。
  • 若提案无隐私影响,必须明说并解释原因——裸写N/A是不够的。

OIDC 提案 指出:弃用env、idp,使name、preferred_username可选后,部署可以让 token 只携带 subject 标识符(流向服务器的身份数据更少而非更多);revision 历史默认记录用户标识符而非姓名,保留了"可遗忘的姓名映射";token 保持不出现在日志中。

Risks and Assumptions(风险与假设)

使用两个带子标题的列表。

  • Assumptions(假设)——一旦错误就会使提案失效的前提。每条都要带*invalidated if:*从句。
  • Risks(风险)——即使假设成立也可能出错的事情。每条都要带*mitigation:*从句(或明确接受)。
  • 保持针对你的提案。"这可能有意想不到的交互""性能可能变差"这类泛化风险价值不大。

OIDC 提案 示例:假设"Tier 1 部署下全局按动作授权足够"(*invalidated if:*部署需要在 Tier 1 上对某些分区有某动作而对其他分区没有);风险"无可部署的 provider 支持按分区 resource indicator,Tier 2 没有用户"(*mitigation:*custom-issuer 与 provider-extension 变体存在)。

Drawbacks(缺点)

  • 该方案的真实成本。
  • 不是可能出错的前提(那是 Assumptions)。不是失败模式(那是 Risks)。
  • 每条一句话。
  • 跳过"要维护更多代码""可能需要文档更新"这类泛化托辞。

OIDC 提案 的 Drawbacks 只有一句:"Discovery 增加了一个对 provider 可达性的启动期依赖,而当前客户端只需要 Lore 服务器。"

Alternatives Considered(备选方案)

  • 至少两个备选方案,每个都要有具体的拒绝理由。
  • 若相关,包括现状(status quo)。
  • "这会更难"不算理由——要具体说明为什么选中的方案更好。

OIDC 提案 考察了五个备选:把自定义 API 发布为规范、实现 OAuth 2.0→gRPC 翻译适配器、仅 Tier 1(彻底弃用分区限定 token)、用 refresh-token scope 收窄替代 token exchange、不透明 token + 全量 introspection。每个都有具体的拒绝理由(如翻译适配器成本与直接加标准端点相当且无法解决iss与无签名密钥目标的冲突;不透明 token 方案把同步调用放到每个存储/修订/锁操作路径上,使 provider 成为吞吐天花板和共享故障域)。

Prior Art(先例)

  • 其他系统(Git、Mercurial、Perforce、Jujutsu、Pijul、Sapling 等)如何处理该问题、值得借鉴什么、值得避免什么。
  • 可选——若没有先例适用,删掉本节。

OIDC 提案 的 Prior Art 极为精彩:Docker Registry v2 token 认证(与 Tier 2 相同的"本地验签 + 独立 token 服务"布局)、GitHub CLI 默认设备流(gh auth login的DetectFlow)、Google Cloud SDK 的反面案例(--no-browser从未采用设备流)、Kubernetes 的 Tier 1 立场及其从扁平 claim 标志演进到AuthenticationConfiguration(KEP-3331)的历史、Git 本身无对应机制(委托给 credential helpers)。

Unresolved Questions(未决问题)

  • 评审期间要解决的开放问题。
  • 到 LEP 变为Accepted时应已清空(或降级为后续工单)。

LEP 与 ADR 的分工:何时需要 LEP,何时直接写 ADR

LEP 与 ADR 共存但分工清晰(见 LEP 体系提案 与 docs/proposals/README.md):

  • LEP 在实现前辩论一个提案;ADR 记录实现期间做出的窄范围架构决策,并在相关时链接回父 LEP。
  • 不触及 wire、磁盘或公共 API 表面、也不横跨子系统的变更,跳过 LEP 直接写 ADR。

ADR 位于 docs/developing/decisions/,追加式、按序号编号,文件名NNNNN-<slug>.md,结构必须包含 Status、Context、Decision、Consequences。截至当前仓库已积累 20+ 篇 ADR,涵盖 FastCDC 选择、分支跟踪、S3 存储选项、Web 框架选择、日志 crate 拆分、压缩算法选择等决策。

评审工具链与自动化检查

LEP 体系提案 定义了配套的自动化支撑(从模板注释<!-- Per-section rules live in README.md. /review-lep checks them. -->也可以印证):

  • /write-lep:起草辅助技能,指导作者按模板填充,应用本 README 中的逐节与跨切面规则。
  • /review-lep:评审辅助技能,读取草稿并按三类输出发现——required fixes(必需修复)、recommended(建议)、optional(可选)——覆盖:结构完整性、引用纪律(每条事实声明带公开链接或内联细节)、以及理由质量(Proposed Design 对 Goal 与 Motivation 的覆盖、N/A与提案其余部分的一致性、承重的 Risks 与 Drawbacks、实质性的 Alternatives、主动语态)。

两份技能都保持最终产物为纯人工可读的 Markdown 文件。

从模板到评审通过:一份真实 LEP 的解剖

将上述规则汇总为一份可执行的清单:

  1. 复制模板并填写 frontmatter:lep、title、authors、status: Draft、created、updated、discussion。
  2. 写 Summary:一段话,面向不熟悉该领域的读者。
  3. 写 Motivation:只陈述问题与紧迫性,不掺入方案。
  4. 列 Goals / Non-Goals:每条 Goal 都要在设计中能找到回应;剔除无咬合力的 Non-Goals。
  5. 写 Proposed Design:以能为 Goals 立论的详细度展开,确保 Motivation 的每个问题都被回应;可用编号小节(如 D1–D9)组织、用 mermaid 图表达时序/流程。
  6. 回答 Compatibility:四个子节逐条作答,不适用处写N/A并附理由;破坏性变更处要具体到 bit、命令、协议字段。
  7. 回答 Non-Functional Considerations:并发、内存、无状态性、确定性,需要时自加延迟等小节。
  8. 写 Migration Plan:非N/A时命名过渡阶段,给出每阶段读写兼容矩阵、工具、标志、遥测、运维指引与回滚信号。
  9. 写 Security / Privacy Considerations:无影响也必须显式说明并解释原因。
  10. 列 Risks and Assumptions:每条假设带*invalidated if:*,每条风险带*mitigation:*。
  11. 写 Drawbacks:每条一句真实成本,排除泛化托辞。
  12. 列 Alternatives Considered:至少两个,各附具体拒绝理由,必要时纳入现状。
  13. 写 Prior Art(可选):借鉴与避免的先例。
  14. 留 Unresolved Questions:评审中解决,Accepted 时清空。
  15. 自查引用纪律:每条事实声明有公开链接或内联细节;内部资源只进discussion字段。
  16. 提交 CR,等待评审。

真实案例 OIDC 提案 横跨了从"自定义 gRPC 认证协议UrcAuthApi的 13 个 RPC 无法对接标准身份提供商"这一动机,到两层级(Tier 1 全局按动作授权 / Tier 2 按分区最小权限)、五阶段迁移、五备选方案的完整论证,是理解 LEP 全部规范如何在实践中落地的首选范本;Tokio 运行时拆分提案 则展示了大型跨切面性能类提案如何以固定线程预算为目标、用两阶段设计保持每阶段独立可回滚。

  • 版本控制
  • 后端

【免费下载链接】lore

Lore is a next-generation, open source version control system

项目地址:https://gitcode.com/gh_mirrors/lore6/lore
点击查看免费下载
上一篇:demo-magic代码实现原理:深入解析模拟打字和命令执行机制
下一篇:gatsby-starter-decap-cms:10分钟快速搭建现代化静态网站

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询