Skip to content

Commit c3de054

Browse files
committed
docs: manifest schema-ownership design (D1-D6, P1-P6)
1 parent 1df4835 commit c3de054

1 file changed

Lines changed: 140 additions & 0 deletions

File tree

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
# mcpp.toml Schema 所有权设计:语法封闭 · 词汇开放
2+
3+
> 2026-06-04 · 状态: 设计定稿待实施 · 代码锚点基于 main@3a8a3d4 (v0.0.47)
4+
> 关联: agentdocs/2026-06-03-capability-architecture-rfc.md(能力架构 RFC)
5+
> mcpp-index/.agents/docs/2026-06-03-capability-runtime-metadata.md(index 侧 schema)
6+
7+
## 0. 问题
8+
9+
v0.0.47 引入了一批"三档旋钮"字段(`backend=``[runtime.<cap>] provider=`
10+
`[package] platforms``[features]``[profile.*]`),但**字段归属是临时混合的**:
11+
`backend` 把 imgui 域词汇泄漏进 mcpp 语法层;provider 校验语义偏松("声明了该
12+
capability 的包都算 provider");platforms/profiles 缺校验与逃生口;且全部
13+
**未写进用户文档**(docs/05-mcpp-toml.md 截至 2.7 节)。本设计统一定型。
14+
15+
## 1. 设计原则(判定法)
16+
17+
> **语法封闭,词汇开放(closed grammar, open vocabulary):
18+
> 谁拥有"解析语义"谁定义键;谁拥有"领域知识"谁定义值。**
19+
20+
三条铁律:
21+
22+
- **A. mcpp 只定义机制,不枚举领域词汇。** features 的并集/闭包、capability 的
23+
require/provide/override、profile→编译器旗标、platform→triple,这些解析语义
24+
归 mcpp,键与形状固定。feature 名、capability 名、后端名是领域知识——只出现在
25+
****里,绝不出现在 mcpp 代码中(与 doctor 去 #ifdef 同一原则在 schema 层的体现)。
26+
- **B. 不允许包自定义 toml 键。** 键合法性若取决于"先解析目标包",manifest 即丧失
27+
静态可解析性,lockfile/LSP/审计/why 全部层次倒置(Cargo 十年验证的取舍)。
28+
包的扩展点 = **固定机制内的开放值域**,不是新键。
29+
- **C. 包级旋钮统一收敛进 features;糖键入核仅当:① 领域中立(跨生态通用模式)
30+
② 1:1 脱糖、零新增解析语义。**
31+
32+
## 2. 现状代码盘点(main@3a8a3d4)
33+
34+
| 机制 | 代码锚点 | 现状归属 |
35+
|---|---|---|
36+
| dep-spec 键白名单(含 `backend`) | `src/manifest.cppm:593-597 is_dep_spec_key` | 键 mcpp 固定 |
37+
| `backend=` 脱糖 → `backend-<x>` feature | `src/manifest.cppm:631` | 纯糖,值开放 ✅ |
38+
| `DependencySpec.features` | `src/pm/dep_spec.cppm`(features 字段) | 机制固定,值开放 ✅ |
39+
| `[features]` 解析 | `src/manifest.cppm:213 featuresMap` / `:521` | 机制固定,值开放 ✅ |
40+
| feature 激活(default∪requested,闭包,`-DMCPP_FEATURE_*`) | `src/cli.cppm:2969` | mcpp 固定 ✅ |
41+
| `[runtime.<cap>] provider=` | `src/manifest.cppm:121 providerOverrides` / `:897`;应用+校验 `src/cli.cppm:3294-3310` | 形状固定,cap 名开放 ✅;**provider 语义偏松 ⚠️** |
42+
| `[package] platforms` | `src/manifest.cppm:40`;`why` 展示 | 键固定;**值未校验 ⚠️** |
43+
| `[profile.<name>]` | `src/manifest.cppm:188 Profile`;`src/build/flags.cppm` 应用 | 键固定(编译器域);**无 passthrough ⚠️** |
44+
| capability 聚合(`CapabilityProvider`) | `src/build/plan.cppm:72-76` | mcpp 固定 ✅ |
45+
| index 侧能力声明 | mcpp-index `compat.glfw.lua` `runtime.capabilities`(含 `abi:glibc`) | 值由生态定义 ✅;**无 provides= ⚠️** |
46+
47+
## 3. 设计决策(逐项定型)
48+
49+
### D1. `backend=` —— 定型为"通用约定糖",保留
50+
- 理由:「库的多个可替换实现」是跨生态通用模式(GUI 后端 / DB driver / logger sink),
51+
满足铁律 C 两条件(领域中立 + 已是 1:1 脱糖)。
52+
- 定型内容:
53+
1. 键名维持 `backend`(评估过 `impl`,`backend` 语感更明确;不再增设别名)。
54+
2. **约定写入文档**:库支持该旋钮 ⇔ 声明 `[features] backend-<name>` 系列
55+
(mcpp 不校验后端名本身,名字归库)。
56+
3. **strict 校验**(新增):若目标包的 `featuresMap` 已声明任何 `backend-*`
57+
feature,而请求的 `backend-<x>` 不在其中 → warning(`--strict` 下 error)。
58+
目标包零声明时不校验(允许纯 define 用法)。
59+
- 不做:包注册自定义键(违反铁律 B)。
60+
61+
### D2. `provider=` —— 收紧为显式 `provides=` 语义
62+
- index/包侧新增 `provides = ["opengl.glx.driver", ...]`(lua `mcpp` 段 +
63+
mcpp.toml `[runtime] provides`),声明"我兑现这些能力"。
64+
- core 解析进 `RuntimeConfig.provides`;`plan.runtimeProviders` 改为:
65+
capability→provider 的映射**优先取 provides 声明者**;无任何 provides 时
66+
回退现状(声明 capabilities 者视为弱 provider,向后兼容)。
67+
- `provider=` 覆盖校验升级:目标包必须 provides(或弱提供)该能力,否则 warning 照旧。
68+
- capability 命名规范(文档化,不进代码):分层小写 `domain.sub.role`
69+
(`opengl.glx.driver``x11.display`)+ 前缀类 `abi:<name>`;mcpp-index 维护
70+
"知名能力名注册表"文档供 doctor/why 提示,**mcpp 代码不枚举**
71+
72+
### D3. `platforms` —— 固定词表 + 校验
73+
- 值域归 mcpp(它拥有 triple 体系):`linux | macos | windows`(后续随 target
74+
支持扩展)。解析时非法值 → warning(`--strict` 下 error)。
75+
76+
### D4. `[features]` —— strict 校验 + 传递传播(follow-up)
77+
- strict 校验:dep spec 请求的 feature 不在目标包 `featuresMap` 且目标包****
78+
`[features]` 表时 → warning(`--strict` error);无表时不校验(纯 define 用法)。
79+
- dep→dep 传递 feature 请求:已知缺口,独立 follow-up(影响解析器,本设计不展开)。
80+
81+
### D5. `[profile.<name>]` —— 固定键 + passthrough 逃生口
82+
- 新增开放值域(固定形状内):`cflags = [...]``cxxflags = [...]``ldflags = [...]`,
83+
追加在 profile 解析后(I6 完备性;铁律 A 不破——键仍是 mcpp 的,值是用户的)。
84+
85+
### D6. Schema 所有权规范成文
86+
- 本文件 §1 的判定法写入用户文档(见 P5),作为后续任何新字段的准入标准:
87+
新键须回答"解析语义归谁?能否用 features/capability 表达?是否领域中立纯糖?"
88+
89+
## 4. 实施计划(每阶段遵循:本地 build+test+e2e → 小步 commit → 分支 PR → 三平台 CI 绿 → squash 合入)
90+
91+
### P1 `provides=`(D2,跨 mcpp + mcpp-index)
92+
- mcpp:`src/manifest.cppm` RuntimeConfig 增 `provides` + TOML/Lua 双解析
93+
(TOML `[runtime] provides`;Lua `mcpp.runtime.provides`);
94+
`src/build/plan.cppm` 聚合优先级(provides > capabilities 弱提供);
95+
`src/cli.cppm` provider 覆盖校验/why/doctor/resolution.json 同步展示 provides 来源。
96+
- mcpp-index:`compat.glx-runtime.lua``provides = {"opengl.glx.driver"}`(PR);
97+
schema 文档同步。
98+
- 验证:imgui 消费链 why/doctor 显示 provider=compat.glx-runtime(由 provides 而非弱提供);
99+
e2e 新增 `66_runtime_provides.sh`
100+
101+
### P2 `backend=` 定型 + features strict(D1+D4)
102+
- `src/cli.cppm` feature 激活处增 strict 校验(warning;`--strict` 全局 flag → error);
103+
`mcpp build --strict` 选项接入 BuildOverrides。
104+
- 验证:imgui 0.0.3(声明 backend-* 前后)+ 故意写错 backend 名 → warning/error;
105+
e2e `67_features_strict.sh`
106+
107+
### P3 `[profile.*]` passthrough(D5)
108+
- `src/manifest.cppm` Profile 增三个 list 字段 + 解析;`src/build/flags.cppm`
109+
在 profile 应用处追加。
110+
- 验证:`[profile.dist] cflags=["-fno-plt"]``--verbose` 可见;e2e `68_profile_passthrough.sh`
111+
112+
### P4 `platforms` 校验(D3)
113+
- `src/manifest.cppm` 解析处校验词表 → warning/strict-error。
114+
- 验证:非法值 warning;e2e 并入 67。
115+
116+
### P5 **文档定型(必做收尾)** —— `docs/05-mcpp-toml.md`
117+
- 新增章节(承接现有 2.7 编号):
118+
- **2.8 `[features]`**:语法、default 集、隐含闭包、`--features`、dep `features=[]`
119+
`-DMCPP_FEATURE_<NAME>` 约定、strict 行为;
120+
- **2.9 `[profile.<name>]`**:内置 release/dev/dist、opt/debug/lto/strip、
121+
passthrough cflags/cxxflags/ldflags、`--profile`;
122+
- **2.10 `[runtime]`**:library_dirs/dlopen_libs/capabilities/**provides**
123+
`[runtime.<capability>] provider=` 覆盖语义与校验;
124+
- **2.1 增补**:`[package] platforms`(词表 + CI 矩阵提示 + `why` 展示);
125+
- **2.5 增补**:dep spec `backend = "<impl>"` 糖(脱糖规则 + `backend-*` feature 约定);
126+
- **新增附录「Schema 所有权原则」**:§1 判定法 + 字段归属总表(给后续贡献者的准入标准)。
127+
- 同步:`docs/03-toolchains.md` 提及 abi 能力强制;`docs/00-getting-started.md`
128+
提及 `new --template gui``why/doctor`
129+
- 验证:文档内示例逐个真实跑通后才提交(文档中的每段 toml 必须可构建)。
130+
131+
### P6 e2e 收口
132+
- 上述 66/67/68 纳入 `tests/e2e/`(`run_all.sh` 自动发现);linux self-host CI 全量跑。
133+
134+
## 5. 验收
135+
- [ ] provides= 端到端(index 声明 → why/doctor/resolution.json 显示 → 覆盖校验收紧)
136+
- [ ] backend=/features strict 行为(warning 与 --strict error)
137+
- [ ] profiles passthrough 旗标可观察
138+
- [ ] platforms 非法值告警
139+
- [ ] docs/05-mcpp-toml.md 含 2.8–2.10、2.1/2.5 增补、所有权附录,且所有示例可构建
140+
- [ ] 新 e2e 全过,三平台 CI 绿

0 commit comments

Comments
 (0)