审查范围
审查基线:docs/ds-spec-2.4.md @ 2a5a6e3。
本 issue 只讨论 spec 自身的矛盾、歧义和缺失的协议边界。refactor 是待重构的旧版本;旧代码尚未实现 2.4 不构成这里的风险,也不以旧实现作为规范真值。
2.4 把 interface、variant、开放贡献类别和统一引用拆开,方向比 2.3 清楚很多。但目前仍有若干地方会让两个“严格按文档实现”的 Installer / Loader / Executor 得到不同结果。建议在新架构冻结前至少解决下列 P0 项。
P0:建议在 2.4 冻结前解决
1. required: false 与“所有依赖都必须可加载”直接矛盾
描述文件定义了 dependencies[].required,默认 true,加载规则却规定 “当且仅当所有依赖项都能被加载”时 Package 才能加载。
最小反例:
{
"dependencies": [
{ "id": "gpu-accel", "version": "1.0", "required": false }
]
}
机器未安装 gpu-accel 时,一个 Loader 可以依据 required:false 继续,另一个可以依据“所有依赖”拒绝,二者都符合原文。若模块又无条件 ref 到该依赖,跳过依赖后仍会在 Ready 阶段失败。
建议:
- 给
missing、present but incompatible、load/init failed 三种情况分别规定 required/optional 的结果;
- 明确 optional 依赖是否参与版本冲突求解;
- 为 import 增加 optional / feature gate / fallback,或明确禁止对 optional 依赖作无条件引用;
- 将“所有依赖”改为“所有 required 依赖”,并说明 optional 依赖失败是否只产生诊断。
2. 版本文法、依赖求解和引用绑定没有确定算法
当前字段说明只给出 x.y[.z.w],引用 ABNF 又使用了一个未定义的 version production。因此至少这些问题没有唯一答案:
- 是否允许一段或三段版本;
1.0、1.0.0、1.0.0.0 是否相等;
- 是否允许前导零,各分量上限和溢出行为是什么;
compatVersion <= version 是否是合法清单必须满足的不变量;
dependencies[].version 是最低兼容基线,而 ref 中的 =version 是精确安装版本、兼容基线,还是二次求解条件;
- dependency 写
bar >= 1.0、ref 写 bar=2.0:inference/x 时应报冲突、提升约束,还是加载两个实例;
- 多个搜索根或同一根中有多个兼容版本时,先按路径优先还是先取最高版本;
- diamond dependency、重复依赖、自依赖、环和同 ID 多版本是否允许并存。
“简单方案”只说依次遍历路径并取找到的兼容依赖,仍不足以让结果可复现。
建议给出完整 ABNF、规范化与比较规则,并提供一段规范性 resolver 伪代码。ref 应绑定本次依赖求解得到的实例,而不是再次做全局搜索;求解结果最好能输出包含实际版本、路径/来源和内容摘要的 resolution graph/lock。
3. compatVersion 没有定义“兼容”必须保持什么
当前算法只用 version >= requested && compatVersion <= requested 判断候选是否兼容,却没有定义 Package 的兼容性承诺覆盖哪些公开表面。
例如 bar@1.1 可以声称兼容 1.0,同时把 inference/pitch 的 interface 或 Level 换掉、删除某个 export,甚至复用同一模块 ID 表示另一件事。依赖方仍会被允许绑定到它,但原有 options 将按另一套契约解释。
建议明确兼容区间内至少要保持:公开 category/module ID、模块的 interface/Level 兼容关系、exports/options schema,以及可观察的运行时契约。Import 也应能声明 expected interface/level/capabilities,并在 Ready 前验证;不满足这些不变量的版本必须提升 compatVersion。
4. .dspk 的安全解包与路径封闭完全未规定
规范目前只说 .dspk 是 ZIP,声明路径相对声明文件解析,安装则只是“在某个目录中解压”。这会把安全关键行为全部留给实现猜测:
- ZIP entry 的
..、绝对路径、盘符/UNC、反斜杠;
- symlink/junction 及“先建链接、再写链接下文件”的逃逸;
- 重复
desc.json、大小写或 Unicode 归一化后碰撞;
- 特殊文件、超长路径、zip bomb、伪造 size header、过多文件;
- 模块声明里的
../、绝对路径,以及 ONNX external data 等二级引用逃出 Package root。
建议增加 normative DSPK profile:只允许 package-root 内的 regular files;拒绝绝对/父级/链接/特殊条目和归一化后冲突;根部恰有一份 desc.json;限制单文件/总解压字节、文件数、压缩比、路径长度、JSON 大小/深度;流式解压时再次计数;先写同文件系统 staging,完整验证后原子提交,失败整包清理。所有直接和模型格式内部的间接路径都必须在 canonicalize 后仍位于 package root。
另外应明确信任模型:若 id + version 被当作依赖身份,建议至少支持内容摘要锁定;签名由本规范承担还是由单独 distribution profile 承担,也应明确。
5. 推理任务只有方法名,没有可验证的生命周期与并发契约
initialize/start/startAsync/stop/state/result 没有定义:
- 合法状态与状态转移,初始化/失败/取消后能否复用;
- 同一实例是 single-flight、多并发还是有界排队,队列满时如何背压;
startAsync 的 callback 线程、是否恰好一次、是否允许重入、对象销毁时如何处理;
start 提交失败与任务运行失败的错误通道及优先级;
result 何时可读、由谁持有、下一次 start 是否覆盖;
stop 与自然完成竞态时的 terminal state,以及 deadline/timeout。
“立即停止(同步)”对不可抢占的 GPU kernel 也不是可移植的保证。建议把它改成语义明确的 cooperative cancel request,并另行定义 wait until quiescent(deadline);给出完整状态机、每个方法的前/后置条件、幂等性、线程安全级别和资源预算/背压规则。模块加载时的 Initialized/Ready 也应与每次 inference task 的 initialize 明确分开。
6. “variant 可互换”与“exports 可以不同”互相冲突
规范先要求同一契约下各 variant “输入与输出完全一致,对导入方而言可互换”,随后又允许一个 variant 支持某项功能、另一个不支持。
最小反例:同一 (interface, level) 下 A export energy,B 不 export;Singer 的 options 要求 energy。A 替换为 B 后立即失效,因此不是无条件可互换。
建议把承诺改为“共享同一 schema/调用契约”,并把实际替换判据定义成“候选 exports 满足 importer 的 capability constraints”;Ready/Validate 阶段必须执行该检查。若真正要求无条件可替换,则同一 interface/level 的 exports 必须一致。
此外,variant 私有字段与 contract 公共字段目前共处一个 configuration 对象,未来可能键冲突;可拆成 configuration.contract / configuration.variant,或规定保留命名空间和 schema composition 规则。
7. interface 契约、解释器发现和 variant 演进仍不足以互操作
文档说 (interface, level) 定义 exports/options 和运行时输入输出,但没有在本规范中定义,也没有规范性链接到不可变的 interface-level contract。仅有三元组名称,无法判定两个实现对 tensor dtype/shape、单位、错误、所有权和取消语义是否真的一致。
同时,Loader 要靠三元组选择解释器,而插件章节又说三项属性在解释器实例化前就必须可读,却只描述了由解释器“返回”这些属性,没有定义静态 descriptor/factory。相同 triple 有两个 provider 时,也没有冲突或选择规则。
最后,规范明确不为 variant 设版本,允许它在 configuration 内自行版本化。但 Loader 必须在解析 variant configuration 前按 triple 选择 provider;两个不兼容配置格式仍使用同一 triple 时,选择阶段无法协商。
建议:
- 为每个官方
(interface, level) 发布不可变、可定位的 contract/schema,覆盖 exports/options/common configuration、运行时 I/O、单位、错误和任务语义;第三方 interface 同样必须有稳定的 schema identity;
- 定义实例化前可读的 registration descriptor + factory,至少含 provider/plugin ID、宿主 ABI、支持的 triple/config-format range;
- 同 triple 多 provider 默认报歧义,或只允许显式、稳定的用户策略选择,禁止依赖扫描顺序;
- 为 variant 增加标准
configFormat,或规定任何不兼容格式变化必须更换 variant ID;
- 明确 Level 历史支持方式:一个 descriptor 可广告 level 集合,或同一 provider 分别注册多个 level,避免“精确匹配”与旧模块免重发之间没有衔接。
P1:会破坏扩展性、确定性或跨实现一致性
8. 开放贡献类别目前仍是闭世界,而且内联表示没有统一 envelope
贡献类别被定义为开放集合,但未知类别会让 Loader 拒绝整包。一个包只要增加无关的 UI metadata 类别,旧的 headless Executor 就可能连原有 inference/singer 都无法使用。
类别名又只是裸 segment,没有命名空间、schema version 或注册冲突规则;第三方都注册 language 时无法判断语义。类别自定义的 desc entry 也没有版本轴。
此外,贡献条目可以“完全内联而不指向文件”,但后文又说所有类别模块都有由框架统一解析的 interface/level/variant 公共字段。内联条目把三元组放在哪里、是否属于“模块”,没有唯一表示。
建议采用 namespaced + versioned category descriptor,并给类别/条目 requiredness:未知 required 才失败,未知 optional 可保留并忽略。统一 contribution envelope,例如 {id, path} 与 {id, descriptor} 二选一;若允许非模块贡献,应从类型系统和术语上明确区分。
9. 省略 category 的持久引用不是演进稳定的,PackageReference 与 ModuleReference 也未分型
引用允许省略 category 并搜索所有类别。:main 在只有 inference/main 时有效;Package 后来增加 singer/main,同一份旧 manifest 未改动却突然变成歧义。
通用 reference 还能只指向 Package,但 imports 的 options 只能由“被引用模块”的 interface/level 解释,因此 package-only ref 在 imports 中没有语义。显式写当前 Package ID 是否触发“必须在 dependencies 声明”并形成自依赖,也不清楚。
建议持久化 manifest 中的 ModuleReference 强制写 category,省略只留给交互式查询;将 PackageReference 与 ModuleReference 分型,imports 只接受后者;明确 self-reference 的例外与自依赖禁令。Imports 还应由 importer contract 定义本地 slot/alias、cardinality、重复 ref 和数组顺序语义。
10. 两阶段初始化与 rollback 不是闭合的事务模型
Initialized/Ready/反序 rollback 没有说明:
- “所有模块”是当前 Package 还是整个 dependency closure;
- dependency cycle 是拒绝、SCC 两阶段,还是别的规则;
- phase 内的确定顺序是什么(
contributes 是 JSON object,本身没有语义顺序);
- 并发加载同一 Package 如何去重,何时对读者原子可见;
- A/B 共用 C 时 A 失败,C 的引用和资源是否能回滚;
- 当前失败模块的半初始化资源、rollback 自己失败、重试与 unload 如何处理。
“按相反顺序”只有在先定义唯一前向顺序并记录实际完成日志后才有意义。建议给 Package 与 Module 分别定义状态机和事务边界;先做无副作用 Resolve/Parse/Validate,再 Acquire,所有 Ready 后原子 Commit;rollback 只撤销本事务新增的引用/资源,要求幂等,并保留 primary error、附加 cleanup errors。若只支持一层跨模块引用,也应说明如何检测和诊断更深的 Ready 依赖,而不是让结果取决于遍历顺序。
11. 缺少统一 JSON、标识符和 conformance profile
规范没有明确 JSON 编码、BOM/注释、重复 key、unknown key、null 与 absent、整数范围、字符串/数组/递归上限。{"$version":"1.0","$version":"999"} 在 first-wins 与 last-wins parser 中甚至会绕过不同的版本门。
建议规范性采用 RFC 8259:UTF-8,重复 object member 一律拒绝,并明确 BOM/注释、未知字段与资源上限。标识符还需规定大小写、canonical serialization、最大长度和 collision 规则;例如 Foo/foo 在不同文件系统上不应悄悄绑定到不同对象。
同时建议:
- 定义 RFC 2119/8174 风格的 MUST/SHOULD/MAY;
- 分别列出 Installer、Loader、Executor 的 conformance 要求和验证顺序;
- 发布
desc.json、公共 module envelope 及官方 category/interface 的机器可读 schema;
- 提供正反 test corpus:版本/引用、依赖图、重复键/深度、恶意 ZIP、生命周期/取消竞态、大小写/Unicode/跨平台路径。
12. RFC 4647 Lookup 的转述不完整,路径型多语言字段也没有落到具体字段
多语言章节只描述单个偏好标签逐段右删。但 RFC 4647 Lookup 的输入通常是有序 language priority list,并且遇到 singleton extension/private-use 时要连同相邻尾段处理,不能产生 de-DE-x 这类中间候选。*、非法/废弃 tag 和 canonicalization 也未说明。
匹配又声明大小写不敏感,因此 JSON 同时出现 zh-CN 与 ZH-cn 时两键语义相同,当前没有拒绝或胜者规则。
建议直接规范性引用 RFC 4647 §3.4 的完整算法:按顺序处理 preference list,整张列表失败后才取 _;加载时校验 BCP 47 tag,并拒绝 case-fold/canonicalize 后的重复键;发布含 extension/private-use/重复大小写键的 golden vectors。
另外,“多语言字段的值是文件路径时” 目前没有对应到任何明确声明为“多语言路径”的标准字段。请逐字段说明 readme、avatar、background、demoAudio 等究竟是普通路径还是本地化路径,并让每个本地化路径都服从第 4 条的 package-root confinement。
示例与编辑性问题
- Singer 示例引用的是
bar/pitch=1.0.0.0:inference/pitch,而 desc 示例依赖的是 bar;如果它们意在组成一份连续示例,则违反“外部 Package ID 必须在 dependencies 声明”。建议提供一套可整体校验的 end-to-end fixture。
- Variance 示例中的
breathness 很可能是 breathiness 的拼写错误;duration 是否属于该 interface 也无法由本规范判定,恰好说明官方 interface-level schema 不能缺席。
- 文中称本规范定义的 variant “当前只有
onnx”,Singer 示例却使用裸词 diffsinger。如果 diffsinger 也是本规范拥有的 Singer variant,应列入;否则应使用其拥有者的命名空间。
interface、variant 本身没有 ABNF、大小写和命名空间所有权规则;“第三方实现使用自己的 interface 命名空间”与“第三方为他人的契约提供 namespaced variant”容易被读成两种相反做法。应明确 interface 属于契约所有者,而不是实现提供者。
建议的完成条件
这些问题多数现在修文档成本很低;等新架构、Package 和插件生态按各自理解落地后,再统一会变成格式兼容和 ABI 迁移问题。
审查范围
审查基线:
docs/ds-spec-2.4.md@2a5a6e3。本 issue 只讨论 spec 自身的矛盾、歧义和缺失的协议边界。
refactor是待重构的旧版本;旧代码尚未实现 2.4 不构成这里的风险,也不以旧实现作为规范真值。2.4 把
interface、variant、开放贡献类别和统一引用拆开,方向比 2.3 清楚很多。但目前仍有若干地方会让两个“严格按文档实现”的 Installer / Loader / Executor 得到不同结果。建议在新架构冻结前至少解决下列 P0 项。P0:建议在 2.4 冻结前解决
1.
required: false与“所有依赖都必须可加载”直接矛盾描述文件定义了
dependencies[].required,默认true,加载规则却规定 “当且仅当所有依赖项都能被加载”时 Package 才能加载。最小反例:
{ "dependencies": [ { "id": "gpu-accel", "version": "1.0", "required": false } ] }机器未安装
gpu-accel时,一个 Loader 可以依据required:false继续,另一个可以依据“所有依赖”拒绝,二者都符合原文。若模块又无条件ref到该依赖,跳过依赖后仍会在 Ready 阶段失败。建议:
missing、present but incompatible、load/init failed三种情况分别规定 required/optional 的结果;2. 版本文法、依赖求解和引用绑定没有确定算法
当前字段说明只给出
x.y[.z.w],引用 ABNF 又使用了一个未定义的versionproduction。因此至少这些问题没有唯一答案:1.0、1.0.0、1.0.0.0是否相等;compatVersion <= version是否是合法清单必须满足的不变量;dependencies[].version是最低兼容基线,而ref中的=version是精确安装版本、兼容基线,还是二次求解条件;bar >= 1.0、ref 写bar=2.0:inference/x时应报冲突、提升约束,还是加载两个实例;“简单方案”只说依次遍历路径并取找到的兼容依赖,仍不足以让结果可复现。
建议给出完整 ABNF、规范化与比较规则,并提供一段规范性 resolver 伪代码。
ref应绑定本次依赖求解得到的实例,而不是再次做全局搜索;求解结果最好能输出包含实际版本、路径/来源和内容摘要的 resolution graph/lock。3.
compatVersion没有定义“兼容”必须保持什么当前算法只用
version >= requested && compatVersion <= requested判断候选是否兼容,却没有定义 Package 的兼容性承诺覆盖哪些公开表面。例如
bar@1.1可以声称兼容1.0,同时把inference/pitch的interface或 Level 换掉、删除某个 export,甚至复用同一模块 ID 表示另一件事。依赖方仍会被允许绑定到它,但原有options将按另一套契约解释。建议明确兼容区间内至少要保持:公开 category/module ID、模块的
interface/Level 兼容关系、exports/optionsschema,以及可观察的运行时契约。Import 也应能声明 expected interface/level/capabilities,并在 Ready 前验证;不满足这些不变量的版本必须提升compatVersion。4.
.dspk的安全解包与路径封闭完全未规定规范目前只说
.dspk是 ZIP,声明路径相对声明文件解析,安装则只是“在某个目录中解压”。这会把安全关键行为全部留给实现猜测:..、绝对路径、盘符/UNC、反斜杠;desc.json、大小写或 Unicode 归一化后碰撞;../、绝对路径,以及 ONNX external data 等二级引用逃出 Package root。建议增加 normative DSPK profile:只允许 package-root 内的 regular files;拒绝绝对/父级/链接/特殊条目和归一化后冲突;根部恰有一份
desc.json;限制单文件/总解压字节、文件数、压缩比、路径长度、JSON 大小/深度;流式解压时再次计数;先写同文件系统 staging,完整验证后原子提交,失败整包清理。所有直接和模型格式内部的间接路径都必须在 canonicalize 后仍位于 package root。另外应明确信任模型:若
id + version被当作依赖身份,建议至少支持内容摘要锁定;签名由本规范承担还是由单独 distribution profile 承担,也应明确。5. 推理任务只有方法名,没有可验证的生命周期与并发契约
initialize/start/startAsync/stop/state/result没有定义:startAsync的 callback 线程、是否恰好一次、是否允许重入、对象销毁时如何处理;start提交失败与任务运行失败的错误通道及优先级;result何时可读、由谁持有、下一次 start 是否覆盖;stop与自然完成竞态时的 terminal state,以及 deadline/timeout。“立即停止(同步)”对不可抢占的 GPU kernel 也不是可移植的保证。建议把它改成语义明确的 cooperative cancel request,并另行定义
wait until quiescent(deadline);给出完整状态机、每个方法的前/后置条件、幂等性、线程安全级别和资源预算/背压规则。模块加载时的 Initialized/Ready 也应与每次 inference task 的 initialize 明确分开。6. “variant 可互换”与“exports 可以不同”互相冲突
规范先要求同一契约下各 variant “输入与输出完全一致,对导入方而言可互换”,随后又允许一个 variant 支持某项功能、另一个不支持。
最小反例:同一
(interface, level)下 A exportenergy,B 不 export;Singer 的 options 要求energy。A 替换为 B 后立即失效,因此不是无条件可互换。建议把承诺改为“共享同一 schema/调用契约”,并把实际替换判据定义成“候选 exports 满足 importer 的 capability constraints”;Ready/Validate 阶段必须执行该检查。若真正要求无条件可替换,则同一 interface/level 的 exports 必须一致。
此外,variant 私有字段与 contract 公共字段目前共处一个
configuration对象,未来可能键冲突;可拆成configuration.contract/configuration.variant,或规定保留命名空间和 schema composition 规则。7. interface 契约、解释器发现和 variant 演进仍不足以互操作
文档说
(interface, level)定义exports/options和运行时输入输出,但没有在本规范中定义,也没有规范性链接到不可变的 interface-level contract。仅有三元组名称,无法判定两个实现对 tensor dtype/shape、单位、错误、所有权和取消语义是否真的一致。同时,Loader 要靠三元组选择解释器,而插件章节又说三项属性在解释器实例化前就必须可读,却只描述了由解释器“返回”这些属性,没有定义静态 descriptor/factory。相同 triple 有两个 provider 时,也没有冲突或选择规则。
最后,规范明确不为 variant 设版本,允许它在 configuration 内自行版本化。但 Loader 必须在解析 variant configuration 前按 triple 选择 provider;两个不兼容配置格式仍使用同一 triple 时,选择阶段无法协商。
建议:
(interface, level)发布不可变、可定位的 contract/schema,覆盖 exports/options/common configuration、运行时 I/O、单位、错误和任务语义;第三方 interface 同样必须有稳定的 schema identity;configFormat,或规定任何不兼容格式变化必须更换 variant ID;P1:会破坏扩展性、确定性或跨实现一致性
8. 开放贡献类别目前仍是闭世界,而且内联表示没有统一 envelope
贡献类别被定义为开放集合,但未知类别会让 Loader 拒绝整包。一个包只要增加无关的 UI metadata 类别,旧的 headless Executor 就可能连原有 inference/singer 都无法使用。
类别名又只是裸
segment,没有命名空间、schema version 或注册冲突规则;第三方都注册language时无法判断语义。类别自定义的 desc entry 也没有版本轴。此外,贡献条目可以“完全内联而不指向文件”,但后文又说所有类别模块都有由框架统一解析的
interface/level/variant公共字段。内联条目把三元组放在哪里、是否属于“模块”,没有唯一表示。建议采用 namespaced + versioned category descriptor,并给类别/条目 requiredness:未知 required 才失败,未知 optional 可保留并忽略。统一 contribution envelope,例如
{id, path}与{id, descriptor}二选一;若允许非模块贡献,应从类型系统和术语上明确区分。9. 省略 category 的持久引用不是演进稳定的,PackageReference 与 ModuleReference 也未分型
引用允许省略 category 并搜索所有类别。
:main在只有inference/main时有效;Package 后来增加singer/main,同一份旧 manifest 未改动却突然变成歧义。通用 reference 还能只指向 Package,但
imports的options只能由“被引用模块”的 interface/level 解释,因此 package-only ref 在 imports 中没有语义。显式写当前 Package ID 是否触发“必须在 dependencies 声明”并形成自依赖,也不清楚。建议持久化 manifest 中的 ModuleReference 强制写 category,省略只留给交互式查询;将 PackageReference 与 ModuleReference 分型,imports 只接受后者;明确 self-reference 的例外与自依赖禁令。Imports 还应由 importer contract 定义本地 slot/alias、cardinality、重复 ref 和数组顺序语义。
10. 两阶段初始化与 rollback 不是闭合的事务模型
Initialized/Ready/反序 rollback 没有说明:
contributes是 JSON object,本身没有语义顺序);“按相反顺序”只有在先定义唯一前向顺序并记录实际完成日志后才有意义。建议给 Package 与 Module 分别定义状态机和事务边界;先做无副作用 Resolve/Parse/Validate,再 Acquire,所有 Ready 后原子 Commit;rollback 只撤销本事务新增的引用/资源,要求幂等,并保留 primary error、附加 cleanup errors。若只支持一层跨模块引用,也应说明如何检测和诊断更深的 Ready 依赖,而不是让结果取决于遍历顺序。
11. 缺少统一 JSON、标识符和 conformance profile
规范没有明确 JSON 编码、BOM/注释、重复 key、unknown key、
null与 absent、整数范围、字符串/数组/递归上限。{"$version":"1.0","$version":"999"}在 first-wins 与 last-wins parser 中甚至会绕过不同的版本门。建议规范性采用 RFC 8259:UTF-8,重复 object member 一律拒绝,并明确 BOM/注释、未知字段与资源上限。标识符还需规定大小写、canonical serialization、最大长度和 collision 规则;例如
Foo/foo在不同文件系统上不应悄悄绑定到不同对象。同时建议:
desc.json、公共 module envelope 及官方 category/interface 的机器可读 schema;12. RFC 4647 Lookup 的转述不完整,路径型多语言字段也没有落到具体字段
多语言章节只描述单个偏好标签逐段右删。但 RFC 4647 Lookup 的输入通常是有序 language priority list,并且遇到 singleton extension/private-use 时要连同相邻尾段处理,不能产生
de-DE-x这类中间候选。*、非法/废弃 tag 和 canonicalization 也未说明。匹配又声明大小写不敏感,因此 JSON 同时出现
zh-CN与ZH-cn时两键语义相同,当前没有拒绝或胜者规则。建议直接规范性引用 RFC 4647 §3.4 的完整算法:按顺序处理 preference list,整张列表失败后才取
_;加载时校验 BCP 47 tag,并拒绝 case-fold/canonicalize 后的重复键;发布含 extension/private-use/重复大小写键的 golden vectors。另外,“多语言字段的值是文件路径时” 目前没有对应到任何明确声明为“多语言路径”的标准字段。请逐字段说明
readme、avatar、background、demoAudio等究竟是普通路径还是本地化路径,并让每个本地化路径都服从第 4 条的 package-root confinement。示例与编辑性问题
bar/pitch=1.0.0.0:inference/pitch,而 desc 示例依赖的是bar;如果它们意在组成一份连续示例,则违反“外部 Package ID 必须在 dependencies 声明”。建议提供一套可整体校验的 end-to-end fixture。breathness很可能是breathiness的拼写错误;duration是否属于该 interface 也无法由本规范判定,恰好说明官方 interface-level schema 不能缺席。onnx”,Singer 示例却使用裸词diffsinger。如果diffsinger也是本规范拥有的 Singer variant,应列入;否则应使用其拥有者的命名空间。interface、variant本身没有 ABNF、大小写和命名空间所有权规则;“第三方实现使用自己的 interface 命名空间”与“第三方为他人的契约提供 namespaced variant”容易被读成两种相反做法。应明确 interface 属于契约所有者,而不是实现提供者。建议的完成条件
这些问题多数现在修文档成本很低;等新架构、Package 和插件生态按各自理解落地后,再统一会变成格式兼容和 ABI 迁移问题。