跳转到主要内容

路线图

为了让 XTL 1.0(规范)和 xl3 1.0(参考实现)成型,需要落地哪些事项。

在 0.x 阶段仍可能引入不兼容变更。根据 ADR-0079,1.0 以技术稳定性和 90 天浸泡期为门槛。G13、G14、G15、G18 继续作为公开的 1.x 采用轨道,但不阻塞 1.0。

深度的版本规划收录在 docs/internal/blueprint-to-1.0.md ——包含差距分析、哲学边界(xl3 ≠ JXLS)以及逐版本的步骤规划。本文档是"电梯演讲"版本;蓝图文档承载完整的论证依据。

1.0 关卡的单一可信来源是下方表格。 当本文件与蓝图文档冲突时,以本表格为准;蓝图随之更新对齐。

1.0 对 xl3 意味着什么

1.0 的目标是让运维人员能够"看得懂、信得过":规范不再漂移,参考实现不再带来意外,整体表面足够小,让运维同学不用读代码就能审阅一个模板。它不是要在功能完备性上和 JXLS 比拼——xl3 有意保持更小的能力面(ADR-0043 + ADR-0048)。预设的核心用户是管理大量客户专属票据格式的韩国运营团队(거래명세서、정산서、발주서);引擎本身可以泛化到这个领域之外,但这个细分场景是切入点。

1.0 技术关卡与 1.x 采用轨道

每个关卡都有所有者、用于关闭它的产出物、判定通过/失败的标准、关卡不可达时的降级方案,以及目标里程碑。下方逐版本步骤规划通过 ID 引用这些关卡。

ID关卡所有者产出物通过标准降级方案目标
G1一致性语料 ≥ 140维护者conformance/fixtures/ls conformance/fixtures/ | wc -l ≥ 140DONE(160 个;ADR-0066 在 0.7.x 中途新增 141-145,ADR-00670069 在 0.8.0 新增 146-155,156(#49 原生值保留)与 157(#51 分组场景的旁侧单元格)在 0.8.1 之后新增,158(#52 算术结合性)在 0.9.0,159-161(ADR-0073/0074 小计错误)在 0.10.0;编号 098 空缺,因此最大索引为 161 而总数为 160;ADR-00510065 另为 0.7.1 预留了更多编号)
G2Stage 2 OOXML 规范化完成维护者ADR-0006 + src/ 中的 canonicalizer由测试用例 024-027、093 + ADR-0006 修订覆盖DONE
G3错误码目录冻结维护者impl/js/src/__tests__/error-codes.test.ts 快照目录快照 30 天保持不变✅ 已于 2026-06-23 勾选(最后一次目录变更为 2026-05-24 a8f7ad3 新增 3 个错误码 xl3/block/overlapxl3/block/empty-tablexl3/directive/orphan89bee51 于 2026-05-23 新增 xl3/expression/bracket-outside-block。30 天冻结期已过——05-24 之后触及该文件的提交仅涉及注释/JSDoc,EXPECTED_CODES 未变)
G4发布 JXLS 边界维护者ADR-0048文件存在并引用 PORTERS_GUIDEDONE
G5延期实现的 ADR 落地维护者ADR-0038 实现 ✅(2026-05-18)+ ADR-0040 PE 实现✅ 已完成——ADR-0038 由测试用例 132-135 覆盖;ADR-0040 的 CF/DV 范围扩展和大纲级别由测试用例 171、172 覆盖已于 2026-08-16 完成
G6公开 API 表面冻结维护者impl/js/src/__tests__/api-surface.test.ts 快照快照 30 天保持不变✅ 已于 2026-06-17 勾选(快照自 2026-05-18 16f0608 起未变)
G7@stable 导出项的 JSDoc 示例维护者TypeDoc 输出每一个 @stable 符号都附带 @example 区块✅ 已于 2026-06-21 完成——13/13 个 @stable 可调用项均带 @example(PR #59);0.11.0 新增 convertJson / previewJson 后以 15/15 复核(previewJson 发布时缺 @example,已于 2026-07-27 修复)
G8性能特性描述维护者scripts/BENCH.md发布 1k/10k/100k 行 × 5/10/20 列矩阵 + 内存上限 + parse/eval/write 分项数据0.7.1
G9性能回归测试用例维护者一致性语料≥ 2 个大体量 fixture,使用基于比率的断言0.7.1
G10跨浏览器冒烟测试维护者ci.ymlSafari + Firefox 校验共享清单中的 19 个 runtime export,并各运行一次 convert()✅ 已完成
G11Stage 2 接入 CI维护者ci.yml每个 PR 都运行 npm run conformance:stage20.7.1
G12未定行为定锚(pivot/sparkline/ListObject/分页)维护者一致性测试用例 + 每项一份 ADR每项:要么有 fixture 锚定当前行为,要么有 ADR 显式延期到 1.x配 ADR 推迟到 1.10.7.1 / 0.8
G13**1.x 采用、非阻塞:**第二语言实现验证外部(xl3-py)conformance/reports/*.json针对当前语料通过 Stage 1 或 Stage 2 ≥ 80%等待新的报告
G14**1.x 采用、非阻塞:**外部贡献者 ADR外部spec/decisions/NNNN-*.md≥ 1 份符合作者标准的外部 ADR开放
G15**1.x 采用、非阻塞:**生产参考案例外部(维护者协助)IMPLEMENTATIONS.md 中“生产用户”一行≥ 1 名获准公开的具名用户开放
G16维护者集合扩大维护者GOVERNANCE.md≥ 2 人拥有 ADR 和实现 PR 的接受/拒绝权限通过对 GOVERNANCE 的修订,显式接受单维护者形态的 1.0 治理结构0.8
G17韩文 cookbook 国际化完成维护者website/i18n/ko/.../guides/全部 cookbook 配方均有韩文翻译配方 01-18 已完成(0.6)——1.0 前的待决问题: docs/guides/19-jxls-to-xl3.md 是后来新增的,没有 ko / ja / zh-CN 翻译。需要先确定迁移指南是否算作 "cookbook 配方";若算,则 G17 需重新勾选
G18**1.x 采用、非阻塞:**README 中的生产用例维护者README.mdG15 后发布具体生产案例开放
G190.x → 1.0 迁移指南维护者docs/migration-0.x-to-1.0.md记录每一个行为变更,或确认是纯新增式变更若确认为纯新增式变更,则降级为 CHANGELOG 备注0.8
G20SECURITY.md + 威胁模型维护者SECURITY.md + 规范修订文档化对 zip 炸弹 / 超大工作簿 / 公式执行的立场和 limits API0.7.1
G21硬限制文档化(1.1 前不支持流式)维护者spec/evaluation.md行数 / 内存的硬限制值 + AbortSignal API 已记录在文档中0.7.1
G22API 表面——内部模型类型剥离维护者impl/js/src/index.ts 导出 + STABILITY.md只保留 convert/preview/analyze + 标注为 @stable 的稳定接口;模型/解析器类型标注为 @experimental 或迁移到 xl3/internalDONE(0.6)
G23RC 浸泡期维护者git 标签RC 已发布;浸泡期 ≥ 21 天(根据评审反馈,从 7 天延长);0 个严重问题✅ 已于 2026-06-16 勾选(自 rc.1 2026-05-26 起浸泡 21 天;0 个严重问题——浸泡期修复 #49–52 已并入 0.9.0,按 G23 的不兼容变更定义均不重置时钟)
G24技术稳定窗口维护者发布日历从最后一个阻塞性技术关卡关闭或最后一次破坏性变更(二者取较晚)起 90 天;不含采用轨道破坏性变更 → 重启2026-08-30 → 2026-11-28;因 OutputFile.data 的公开类型修正为实际的 Uint8Array 运行时契约而重启

定义(可测试)

  • 外部贡献者(G14): 在 PR 打开时,既不在 GOVERNANCE.md 维护者集合中,也未出现在已合入 ADR 提交的 Co-authored-by 历史中。顺手改错别字的编辑不计入;需以 Author 身份出现在 ADR 前置元数据中;按行数计,Context/Decision 章节 ≥ 60% 由其撰写。
  • 不兼容变更(G24、G23): 对以下任一项的修改:(a) 公开 API 表面快照;(b) 错误码目录(重命名/删除/重新用途化);(c) ADR acceptedrejected,或与原状态冲突的状态翻转。补丁版本和纯新增式 ADR 重置季度时钟。
  • 关键 bug 修复(G23 RC 例外): (a) convert() 中的静默数据丢失;(b) 文档和运行时之间的错误码目录不一致;或 (c) 某个 accepted ADR 中的 MUST 按现有写法无法实现。维护者需在 PR 中标明命中的是 (a)/(b)/(c) 中的哪一项。
  • 数据丢失测试(G24 可测试形式): 语料中存在专门的 data-loss/ fixture 分组(≥ 8 个 fixture),覆盖静默字符串化、numFmt 丢失、公式改写、日期往返路径;全部在参考实现上通过。
  • 季度时钟起点(G24 与 G23): G24 的 90 天季度从最后一个关卡 ✅ 的当天开始计时。RC 发布启动时钟;时钟必须在 RC 发布之前已经开始。若 RC 浸泡期间发生不兼容变更,则浸泡期(G23)和季度(G24)双双重置。

逐版本步骤规划

基于关卡,而非基于日期。日历估时已移除——每个里程碑在它列出的关卡全部关闭时才算关闭。

0.6.0 —— 延期实现,范围收窄

主题:干净利落地关闭影响最大的延期实现关卡。

关闭的关卡:G5(仅 @group/@subtotal 实现——ADR-0040 PE 的其余部分移入 0.6.1)、G17(韩文 cookbook 还缺 16/17 篇翻译)、G22(在 @group 暴露新的内部类型之前先收敛 API 表面)。

按工程可行性评审的反馈,原先"在一个 0.6.0 里塞下所有东西"的计划范围过大。仅 ADR-0038 的实现就涉及一次完整的管线插入(新增指令、分组边界状态机、transform-pass 切分、渲染器重写、分组作用域的聚合求值)。把 0.6.0 拆开能让这个里程碑可以真正交付。

0.6.1 —— 延期实现的剩余部分(已规划,尚未发布)

关闭的关卡:G5 完结(ADR-0040 PE:CF/DV sqref 扩展),以及 pivot/分页行为 fixture 朝 G12 推进。

0.7.0 发布时的状态:本里程碑被规范审计批次(0.7.0)跳过。G5/G12 的工作被合并到 0.7.1。

0.7.0 —— 规范审计批次(已于 2026-05-22 发布)

主题:关闭一次深度审计揭示出的 17 个语法冲突缺口,覆盖词法分析、单元格分类、指令组合、聚合参数和保留工作表语义。原关卡表中未计划;原本挂在 0.7.0 上的性能/CI/limits 工作移入 0.7.1

已发布的产出物:

  • 15 份新 ADR(0051–0065)+ ADR-0021(group-order 目录条目)和 ADR-0041(表头单元格多行规范化)的修订。
  • 4 个新错误码——xl3/parser/unbalanced-literalxl3/lists/invalid-usexl3/eval/bad-aggregate-argxl3/expression/unknown-name
  • 语法补充:positive_integergroup_directivesubtotal_directiveaggregate_call,以及一段词法消歧义说明。
  • src/directive-parser.ts 对前导零整数加严。
  • 双通道并行评审(claude-general + codex);所有 CRITICAL/HIGH 发现已在打 tag 前关闭。

对关卡的影响:

  • G1 —— 当前 139 个 fixture。0.7.0 的 ADR 预留了 fixture 编号 141–187;实现仍在进行中。这些 fixture 在 0.7.1 落地后 G1 即关闭。
  • G3 —— 30 天错误码目录时钟于 2026-05-22 因新增 4 个错误码而重置
  • G6 —— 公开 API 表面无变化;G6 时钟不受影响。

0.7.1 —— 性能 + 外部验证启动(从旧的 0.7.0 重命名而来)

关闭的关卡:G5 完结(ADR-0040 CF/DV sqref 区间)、G8(性能基准)、G9(性能回归测试用例)、G10(跨浏览器)、G11(Stage 2 进 CI)、G20(SECURITY.md 草案 + 威胁模型)、G21(硬限制 + AbortSignal 文档)。

同时通过落地 0.7.0 ADR 预留的 141–187 号 fixture,关闭 G1 ≥ 140 fixture 的底线。

推进进度:G12(未定行为定锚)、G13(xl3-py)。

重新标注:在 G8 发布且 xl3-py 在 Stage 1 达到 ≥ 50% 后,将 alpha 改为 beta

0.8.0 —— 数据块设计大改(已于 2026-05-23 发布)

主题:原关卡表中未计划。0.7.x 后期对数据块展开做的一次审计暴露出两个结构性 bug(#46 共享公式 owner 重复、#47 被挤开的旁侧单元格引用变旧),必须先做一次按列作用域的重写,才能继续做后续功能。原先"0.8.0 = 社会性关卡"的计划移入 0.8.x 补丁

已发布的产出物:

  • ADR-0066 —— 数据块改为按列作用域:把 {{...}} 标记的包围盒沿连续的非空单元格扩展。块展开时,该范围之外的单元格保持各自的行位置。从构造上关闭 #46 / #47。
  • ADR-0067 —— 显式 @block 指令的三种形式(裸写、A:D 列区间、A2:D7 矩形)。
  • ADR-0068 —— 在选择启用的工作表上做严格的多块检测:每个 [Column] 标记都必须落在某个块内;块矩形之间不得重叠。
  • ADR-0069 —— 按邻近度做逐块的指令作用域:@filter/@sort/@top/@source/@join/@group/@repeat 会挂到列区间与该指令所在列重叠、且距离最近的那个数据块上。
  • 4 个新错误码:xl3/expression/bracket-outside-blockxl3/block/overlapxl3/block/empty-tablexl3/directive/orphan
  • 一致性测试用例 146-155(多块、使用不同数据源的并排块、纵向堆叠块、逐块过滤、逐块 ROW() 作用域,以及三条新错误路径)。

对关卡的影响:

  • G1 —— 语料从 139 增至 154 个。底线再次达成。
  • G3 —— 30 天错误码目录时钟因这 4 个新错误码于 2026-05-23 重置。最早可勾选时间为 2026-06-22,前提是 0.8.x 补丁期间不再新增或重命名错误码。

0.8.x —— 社会性关卡(进行中)

关闭的关卡:G14(外部 ADR)、G15(生产案例;通过维护者所在公司的部署推进中)、G16(维护者扩员,或显式接受单维护者形态)、G19(迁移指南)、G20 完结。

计划是在招募期间持续发布 0.8.x 补丁版本,而不是默不作声地等待。G3 的季度纪律: 社会性关卡推进期间,错误码的新增与重命名一律延后——任何新增都会重置 G3 时钟,并把 0.9-rc 的目标往后推。0.8.x 窗口期内只允许新增符合本文件定义的"关键 bug 修复"类错误码。

0.9.0-rc.x —— 1.0 前的冻结期

关闭的关卡:G3G6G7G23(≥ 21 天的 RC 浸泡期)。

G23 启动后,G24 的季度时钟开始(它必须在 G3/G6/G7 等关卡关闭过程中就已经走起来——见上方定义)。

0.9.0 —— 最终冻结版本(2026-06-23)

1.0 前的四个冻结关卡全部勾选:G3(2026-06-23 —— 最后一次目录变更 2026-05-24 + 30 天)、G6(2026-06-17)、G7(2026-06-21,PR #59)、G23(2026-06-16 —— 21 天浸泡,0 个严重问题)。并入 RC 浸泡期修复 #49–52;#54/#56/#57 延后到 post-1.0 里程碑(POST-1.0 纯新增式 —— 该里程碑在本次发布时名为"0.10.0",因 0.10.0 与 0.11.0 均未包含这些事项就已发布,故于 2026-07-27 重命名;#57 已因 #82 的宿主驱动 __inputs__ 源元数据方案取代而关闭)。G24 的 90 天季度时钟自最后一个关卡勾选之日(2026-06-23,经由 G3)开始计时;若无规范/API/错误码的不兼容变更,1.0 最早约为 2026-09-21。

0.10.0 —— 组织迁移 + @subtotal 正确性(已于 2026-07-19 发布)

仓库已迁入 xl3-lang GitHub 组织,npm 包从 @jinyoung4478/xl3 重命名为 @xl3-lang/xl3(仅安装名变化;旧包已在 npm 上标记 deprecated 并指向新名)。同时并入 @subtotal 的正确性修复 #66(ADR-0073)与 #69(ADR-0074):带有当前行 [Column] 引用的 @subtotal 行,以及显式 @block 模式下的分组 + 小计,此前都会静默产出看似合理却错误的结果——现在各自抛出专门的错误。

对关卡的影响:

  • G1 —— 语料从 157 增至 160 个(159 mixed-row 错误、160 公式缓存不是标记的保证、161 显式块的拒绝)。
  • G3 / G24 —— 新增 2 个错误码(xl3/subtotal/mixed-rowxl3/subtotal/explicit-block-unsupported);没有重命名、删除或重新用途化。按上文不兼容变更的定义属于纯新增,因此季度时钟重置。
  • G6 —— 公开 API 表面快照未变。重命名只影响安装名:convert / preview / analyze、子路径导出以及 xl3-conformance bin 完全一致。

0.11.0 —— JSON 源输入(已于 2026-07-19 发布)

convertJson / previewJson 可以接受与语言无关的 xl3-source-json/0.1 传输格式来替代 data.xlsx,让非 Excel 宿主(Python、DB/ETL 服务)跳过工作簿往返(ADR-0075,#71,实现见 #80)。同时把 JS 参考实现迁移到根 npm workspace 下的 impl/js/(#79)——仅目录结构调整,行为无变化。

对关卡的影响:

  • G3 / G24 —— 新增 1 个错误码(xl3/source-json/invalid);纯新增,时钟不重置。
  • G6 —— 冻结的 API 表面新增两个导出(convertJsonpreviewJson,已记录在 spec/STABILITY.md)。纯新增:没有删除或改签任何既有导出,.xlsx 路径也未触动。
  • G24 窗口 —— 两次发布都落在 2026-06-23 启动的季度窗口之内(2026-07-19)。按上文定义两者都不属于不兼容变更,因此 1.0 最早时间仍约为 2026-09-21。

1.0.0 —— 最终发布

关闭的关卡:G24(最后一个关卡 ✅ 之后的 90 天季度走完)。

招募与外联

社会性关卡(G13/G14/G15/G16)需要的是人,而不是代码。项目有两个截然不同的招募面向:

韩国运营受众(G15、未来的 cookbook 贡献者)

渠道:韩国开发者社区(Naver Café、Kakao 오픈톡、LinkedIn KR)、公司内部 / 供应商模板作者调研。每个小版本发布都会配套一篇与发布节奏绑定的韩文文章(0.6 = @group/@subtotal 在票据小计场景的演示;0.7 = 性能数据;0.8 = 案例研究)。

英文 OSS 受众(G13、G14)

渠道:HN、lobste.rs、r/excel、各类大会 CFP(JSConf、面向 xl3-py 的 EuroPython)。每个重大节点都会配套一份具体的对外产物:

  • 0.7.0 发布:"Show HN: xl3 0.7 —— 10 万行级别的 Excel 模板引擎"
  • 0.8.0 发布:案例研究 + xl3-py 一致性面板
  • 1.0.0 发布:规范 + 多实现交叉验证

1.0 的非目标

这些内容是有意延期的。每一项都有对应 ADR 说明原因:

  • 超出 Y/M/D/EOMONTH/EDATE/DATEDIF 之外的日期运算 —— 该家族其余部分按 ADR-0019 修订延期。
  • 区域感知的字符串排序 —— ADR-0020
  • 多表 join、左连接、多行匹配 —— ADR-0014 的范围外章节。
  • XLOOKUP 通配符 / 近似匹配 / 反向搜索 —— ADR-0013 的范围外章节。
  • 动态图片插入 —— ADR-0037
  • 运行时单元格变更 —— ADR-0042
  • 按 ADR-0043 关卡被拒绝的函数 —— 数学扩展、类型判定(按 ADR-0047 例外保留 ISBLANK)、NOW / WEEKDAY 等、条件聚合、TEXT() 格式 token 扩展。详见 ADR-0045
  • 流式输出 / SXSSF 类似物。 延期至 1.1+。在 1.0,作为替代会文档化硬性的内存/行数上限(G21)。
  • 模板编译缓存 API。 延期至 1.1+。
  • PDF / HTML 输出。 范围外;xl3 的契约是 xlsx-in、xlsx-out。
  • 超出 093 的跨写入器 Stage 2 fixture —— ADR-0006 修订。
  • 输出侧模板 schema(produces)与设计时链接 —— xl3#109 中的输入校验提案 (validateSource():复用既有的 xl3/source/* 错误码来回答“这份源数据是否满足 这个模板”)先只限定在输入侧。与之对应的输出侧 —— 携带输出列标签的 TemplateModel.produces,也就是能让宿主在不执行一次转换的前提下校验 templateA → templateB 这条边的东西 —— 延期。它需要一项本项目尚未确定的约定: 工作表模板中哪一行字面量行才是输出表头。与 requires 不同,这一点无法从解析器 已解析的结果中推导出来,因此必须明确决定并写下来,而不是让每个引擎各自推测。 目前还没有 ADR;设计讨论在 xl3#109。

这些仍然是 XTL 1.1、1.2、1.x 的候选项,取决于需求强度。

如何帮助关闭事项

事项如何帮忙
G13 第二实现 ≥ 80%参与 xl3-py,或启动一个新的移植(Rust、Java、Go)。参见 PORTERS_GUIDE.md
G14 外部 ADR挑选一个延期项(pivot 表保留、分页符、ADR-0045 切出的函数等),在 spec/decisions/ 中起草一份 ADR。参见 GOVERNANCE.md 中"变更如何进入项目"。GitHub 上以 good-first-ADR 标签提供了若干"入门 ADR 草稿"议题。
G15 生产案例在内部使用 xl3,并分享行得通 / 行不通的地方。如果合适,在 IMPLEMENTATIONS.md 中加一行。如果维护者所在公司(Snack24h)发布公开案例研究,也可作为生产参考案例计入。
G17 指南国际化docs/guides/19-jxls-to-xl3.md(JXLS → xl3 迁移指南)没有 ko / ja / zh-CN 翻译;配方 01-18 已完成。
G8 基准测试在有代表性的模板上运行 npm run bench,分享结果。
G10 跨浏览器把 Safari + Firefox 加入 bundle 冒烟测试。
函数再提案如果你需要某个被 ADR-0045 拒绝的函数,请使用 Function re-proposal 议题模板提交。

本路线图如何演进

本文档是公开的"电梯演讲" + 关卡表是单一可信来源。更深层的 docs/internal/blueprint-to-1.0.md 承载差距分析、哲学边界以及逐版本的论证依据。随着关卡逐个 ✅,两份文档都会更新。每当出现新的缺口,两份文档都会补上。

对 1.0 关卡表格的删减和新增,与其他任何事项一样,通过相同的 ADR / 议题流程讨论。