核心原则:测试不是为了标榜通过率,而是为了诚实地发现自己可能存在的问题。Vitro 的错误会误导学生,所以我们宁可数据难看,也不扭曲代码去迎合编译器。
motto: All in. Record don't hide. Fix real bugs, not test cases.
最后核对:2026-10-05(S9 工序④删区对齐——头部改单轨口径、测试规模句改单区、防线 1 改 clang_direct、双区/双实现表述加现役锚;四层架构语义章保留。前一沿革 2026-09-29 引言测试数对真值)
⚠️ 单轨口径(2026-10-05,S9 工序④删区):本文写作期的 Layer B 实现(Rust Host Function)与其 cargo test 防线已随
native/删区整体退役。四层架构的语义分层规则仍为 MoonBit 侧同构实现的现役设计,对应关系——Layer A →moonbit/vmexecutor;Layer B →moonbit/host(110 路由 +HostMemReply);Layer C →moonbit/libc(数据由gen_libc_data生成)+scripts/moonbit/libc_src/;Layer D 不变。正文中「Rust Host」「cargo test」「native/tests/*」等字样均为删区前历史口径(tagrust-oracle-freeze),防线现役形态见各节删区注记。
一、背景:为什么需要这套设计
Vitro 单区测试规模(现役口径):MoonBit 区 moon test 728 用例(facts 真值键 moonbit_test_passed 管束,漂移即 CI 红;裸 moon test 口径)+ Clang 直拍全量语料对照(clang_direct)。但 C 语言极其灵活,即使如此规模的测试,面对真实世界的 C 代码仍可能暴露未发现的边缘问题。更关键的是:
- 标准库不是外设,是教学核心:学生写的每一行
printf、malloc、strcpy都是教学体验的一部分; - 四层架构引入新风险:同一功能可能同时存在 VM Builtin、Host、Bytecode Libc 三种实现,它们之间的一致性需要独立验证;
- 闭源开发,无用户反馈:我们不能消耗学生时间去发现问题,更不能通过"修改测试代码来让测试通过"这种自欺欺人的方式粉饰数据。
因此,标准库的拓展必须与一套不妥协的测试哲学同时推进。
二、标准库四层架构(Vitro Runtime Library)
┌─────────────────────────────────────────────────────────────┐
│ Layer A: VM Builtin 指令(极少量,性能关键) │
│ Memcpy / Memset / Strlen(可选) │
│ → 由 VM executor 原生执行,带边界检查(现役 = moonbit/vm) │
├─────────────────────────────────────────────────────────────┤
│ Layer B: Host Function(诊断敏感 + 宿主机能力) │
│ malloc/free/realloc, strcpy/strcat(带诊断), printf/scanf │
│ fopen/fclose, qsort, exit, math(sin/cos via libm) │
│ → 注入 UAF/Bounds 检查,操作会话状态 / VFS(现役 = moonbit/host)│
├─────────────────────────────────────────────────────────────┤
│ Layer C: Precompiled Bytecode Libc(纯算法,诊断不敏感) │
│ isdigit, isalpha, abs, atoi, tolower, strncpy, memcpy... │
│ → 编译期静态链接到用户字节码,源码可展示,无 host 开销 │
├─────────────────────────────────────────────────────────────┤
│ Layer D: Inline C Source(教学展示用) │
│ 学生自己写的辅助函数,或老师提供的"看看 libc 怎么实现"代码 │
│ → 与普通用户代码一起编译 │
└─────────────────────────────────────────────────────────────┘
MoonBit 现役口径(2026-10-05 删区后):四层生态位的现役落点——Layer A →
moonbit/vm(executor 原生指令);Layer B →moonbit/host(handler +HostMemReply,110 路由);Layer C →moonbit/libc(数据由scripts/moonbit/gen_libc_data生成,CI-check门禁 +libc_boot_diffdigest 自举对拍;C 源码在scripts/moonbit/libc_src/);路由覆盖由scripts/moonbit/host_route_coverage把关。下文 Rust 时代表述(Rust Host / vitro_vm / runtime_libc / libm)为删区前历史口径。
2.1 分层规则
| 类型 | 示例 | 必须放在 | 原因 |
|---|---|---|---|
| 内存安全诊断敏感 | strcpy, strcat, memcpy, memmove, malloc, free, realloc |
Layer B: Rust Host | 需要注入边界检查、UAF 检测、行号追踪,Rust 侧可精确控制错误信息。 |
| I/O 沙盒敏感 | printf, scanf, fopen, fgets |
Layer B: Rust Host | 需要操作会话输出通道(session.runtime.output_chunks,E-P1-5 后按 stdout/stderr/note 打标)/ VFS / input buffer。 |
| VM 回调敏感 | qsort, bsearch |
Layer B: Rust Host | 需要 call_user_function 回调 VM 函数。 |
| 纯计算、无副作用 | sin, cos, abs, atoi, isdigit |
Layer C: Bytecode 或 Layer B: Rust | 无诊断需求,Bytecode 可教学展示;Rust 可借助 libm 精度。 |
| 超高频内存原语 | memcpy, memset, strlen(未来) |
Layer A: Builtin 指令 | 原生执行,避免 CallHost 开销。 |
2.2 关键决策
- 不是 musl:Layer C 的源码不是 musl 子集,而是"用 Vitro-C 子集重写的纯算法库",从 musl/pdclib/PicoC 中按需裁剪;
- 预编译静态链接:构建时将
native/runtime_libc/src/*.c编译为字节码常量,嵌入 Rust 代码,全局函数表预留固定索引,运行时无重定位开销; - 双轨数学函数:
(该方案未落地:math 实际全部走 Layer Bsin/cos默认走 Layer C(泰勒展开,源码可见);配置开启"精确模式"时走 Layer Blibm,见《标准库支持矩阵》§2.4;MoonBit 侧同位为@math/Double位模式对齐 libm);
三、测试防线设计
在现有两条防线之上,新增三层契约验证。三条防线互不替代,分层协作。
┌────────────────────────────────────────────────────────────────┐
│ 防线 3:三层契约验证(新增) │
│ ├─ 3a. Host Function 契约测试:Rust 单元测试直接验证边界行为 │
│ ├─ 3b. Bytecode Libc 自举一致性:C 源码 → Clang vs Vitro │
│ └─ 3c. 差分压力测试:同一功能多实现交叉对比 │
├────────────────────────────────────────────────────────────────┤
│ 防线 2:K&R + LeetCode 真实程序回归(已有) │
│ └─ 验证"真实世界代码能不能跑" │
├────────────────────────────────────────────────────────────────┤
│ 防线 1:Clang 直拍(clang_direct——原 Shadow 防线的删区后形态) │
│ └─ 验证"与 Clang 行为是否一致" │
└────────────────────────────────────────────────────────────────┘
3.1 防线 3a:Host Function 契约测试(Host Contract Tests)
目标:验证 Layer B(Host Function)的每个函数在边界条件、安全注入、标准一致性上是否达标。
为什么现有防线做不到:直拍防线跑的是 C 代码,如果 strcpy 的越界检查没生效,但测试用例恰好没写越界,就发现不了。
测试哲学(不可妥协):
- NO_CODE_DISTORTION:测试代码不扭曲 C 语义去迎合 Vitro。例如,不会因为 Vitro 的
printf不支持%lld就把测试里的long long改成int。 - RECORD_DONT_HIDE:Host Func 的任何异常行为(包括未定义行为)必须记录。即使 C 标准允许实现定义,Vitro 也必须给出明确、稳定的行为,并在文档中记录。
- FIX_REAL_BUGS:测试失败时,修 Host Func 的实现,而不是改测试预期值让它通过。
示例:
#[test]
fn test_host_strcpy_traps_on_overflow() {
let mut vm = VitroVM::new();
let mut session = Session::new();
let dst = vm.heap_alloc(5);
let src = vm.write_cstring("hello world");
vm.push(src as i32);
vm.push(dst as i32);
host_strcpy(&mut vm, &mut session);
// 必须触发 TrapBounds,而不是静默越界
assert!(session.runtime.trap.is_some());
}
#[test]
fn test_host_atoi_standard_conformance() {
// C 标准:atoi(" -123abc") == -123
// 必须如实记录 Vitro 的行为,若与标准不同,标记为偏差
}
能 catch 的问题:
malloc(0)返回 NULL 还是有效指针?free(NULL)是否安全?printf("%.2f", 2.675)的舍入是否正确?memcpy(dst, src, 0)是否允许 dst/src 为 NULL(C 标准允许)?- 边界检查是否在所有代码路径生效?
3.2 防线 3b:Bytecode Libc 自举一致性测试(Bytecode Self-Consistency)
目标:验证 Vitro 编译器 + VM 能否正确编译并运行"自己的标准库"。
核心逻辑:把 Layer C(Bytecode Libc)的 C 源码同时交给:
- Clang:编译成原生可执行文件,输出作为 唯一 golden;
- Vitro:编译成字节码,在 VM 中运行,输出与 golden 对比。
测试哲学(不可妥协):
- ALL_IN:所有 Bytecode Libc 的 C 源码必须参与验证,不因为"这个函数很简单"就跳过。
- GOLDEN_FROM_CLANG:golden 只能来自 Clang,不能来自 Vitro 自己。
- NO_CODE_DISTORTION:Bytecode Libc 的 C 源码不得为了通过 Vitro 编译器而改写(例如,不能因为它不支持某个语法就重写算法)。如果 Vitro 编译失败,那是编译器的缺口,记录为
compile_gap。
为什么这是"印证本项目是否正确"的最佳方式:
- 这是编译器自举的轻量版。如果 Vitro 能正确编译并执行自己的 C 代码,说明编译器和 VM 的语义实现是自洽的。
- 这些 C 代码是可控的、可读的,不像 musl 那样依赖大量未支持特性。
- 一旦发现差异,可以 100% 确定是 Vitro 编译器或 VM 的 bug。
目录结构:
native/tests/bytecode_libc_consistency/
└── drivers/ # 测试驱动(main 函数),12 个 test_*.c
├── test_isdigit.c
└── test_abs.c
结构核对(2026-09-11;删区后现状 2026-10-05):Bytecode Libc 的 C 源码现位于
scripts/moonbit/libc_src/(原native/runtime_libc/src/随删区迁入);一致性验证现役形态 =libc_boot_diffdigest 自举对拍(MoonBit library mode 编译 vs 冻结 golden,CI 门禁)——原 Rust 集成测试驱动(cargo test --test bytecode_libc_consistency)随删区退役。
能 catch 的问题:
- Vitro 编译器对
ctype.c的某个指针运算生成错误字节码; - VitroVM 对
for循环或if条件的执行与 Clang 语义偏差; - Bytecode Libc 中某个函数的实现本身有 bug(与 Host Func 版结果不一致)。
3.3 防线 3c:差分压力测试(Differential Stress Test)
目标:对同一功能的两种实现(Layer B Host vs Layer C Bytecode)进行交叉验证。
核心思想:如果 strlen 既有 Host 实现,又有 Bytecode C 实现,那么对同一随机输入,两者结果应该永远一致。如果不一致,至少有一个是错的。
测试哲学(不可妥协):
- 不预设哪边是对的:差分测试失败时,两边都要审查,不能默认"Host 版一定对"。
- 记录所有偏差:即使偏差极小(如
printf浮点精度第 6 位不同),也要记录。 - 不通过删减测试用例来消除差异:不能因为某个 edge case 总是触发差异,就把它从随机生成器中去掉。
实施方式:
内存操作差分:
let addr = random_addr(); let len = random_len(); let result_host = host_strlen(vm, addr); let result_bc = vm.call_bytecode_func("strlen", addr); assert_eq!(result_host, result_bc, "strlen divergence at addr={}", addr);标准库覆盖矩阵:
函数 Host Contract Bytecode Consistency Differential 状态 strlen✅ ✅ ✅ 已验证 isdigitN/A ✅ Host vs Bytecode 已验证 strcpy✅(边界检查) 待实现 Host vs Bytecode 进行中 printf %f✅(精度) N/A N/A 已验证 恶意输入模糊测试: 对
scanf、printf、malloc/free组合生成随机调用序列,验证不崩溃、不泄漏、不误报/漏报 UAF。
四、测试发现的任何问题:不扭曲代码,不粉饰失败
这是本设计的不可妥协原则,独立于具体技术方案:
| 禁止行为 | 正确做法 |
|---|---|
把测试里的 long long 改成 int 来绕过不支持 |
记录为 compile_gap,推动编译器支持 |
把 printf("%lld", x) 改成 printf("%d", (int)x) |
记录为缺失特性,不修改测试源码 |
发现 strcpy 越界检查漏报,就把测试里越界的字符串改短 |
修 Host Func 的边界检查逻辑 |
| Bytecode Libc 编译不过,就重写 C 代码绕过语法限制 | 记录编译器缺口,保留原始 C 代码 |
差分测试浮点第 6 位不同,就放宽精度到 1e-3 |
记录精度偏差,分析是 Host 还是 Bytecode 的问题 |
| 因为某测试"总是失败"就从 CI 中移除 | 标记为 KNOWN_FAILURE,持续监控,一旦意外通过则 CI 报警 |
记录模板:任何失败必须在对应的 *_FAILURES.md 中按以下格式追加:
### <case_name>
- **来源**: Host Contract / Bytecode Consistency / Differential / K&R / LeetCode
- **失败原因**: <编译错误 / 运行时错误 / 输出不匹配 / 安全检查失效 / 差分偏差>
- **最小复现**: <关键代码片段>
- **是否 Vitro 限制**: 是/否
- **是否标准库实现偏差**: 是/否
- **学生影响评级**: P0(误导学生) / P1(限制已知) / P2(边缘场景)
- **建议**: <修复方向 / 记录为已知限制 / 待进一步分析>
五、四条防线的协作关系
| 防线 | 发现问题类型 | 速度 | 精准定位 | 是否新增 |
|---|---|---|---|---|
| 3a Host Contract | Host Func 边界条件遗漏、安全注入失效 | ⚡ 毫秒级 | 精准到函数 | ✅ 新增 |
| 3b Bytecode Self-Consistency | 编译器/VM 对真实 C 代码的语义偏差 | 🔶 秒级 | 精准到源码行 | ✅ 新增 |
| 3c Differential Stress | 多实现版本间的隐藏不一致 | 🔶 秒级 | 精准到函数对 | ✅ 新增 |
| 2 K&R/LeetCode | 真实程序组合缺陷 | 🐢 分钟级 | 端到端 | 已有 |
| 1 Clang 直拍(clang_direct,原 Shadow) | 与 Clang 的整体偏离 | 🐢 分钟级 | 端到端 | 已有 |
关键互补性:
- 直拍发现"和 Clang 不一样" → 但不知道是 Host Func 错了、VM 错了、还是编译器错了;
- 三层契约能精确定位到 layer:如果 Host Contract 过了但直拍挂了,说明问题在编译器或 VM;如果 Bytecode Self-Consistency 过了但 Differential 挂了,说明 Host Func 与 Bytecode 实现有偏差。
六、实施路线图
状态(2026-09-27 注;2026-10-05 删区后更新):Phase A–E 已全部完成(原承载于
native/tests/各防线文件,随删区退役);Phase F 的 CI 集成已达成。删区后现役承接——3a Host Contract =host_contract_map(103 条冻结名册对 MoonBit 锚三态对账,CI--strict);3b =libc_boot_diffdigest 自举对拍;3c/3d =moon test内 fuzz 不变量自检(路 A 迁移);防线 1 = clang_direct。本表保留为原始规划存档。
| 阶段 | 任务 | 产出 |
|---|---|---|
| Phase A | Host Contract 骨架:native/tests/host_contract_tests.rs,覆盖 malloc/free/strcpy/printf 边界条件 |
cargo test --test host_contract_tests 全绿 |
| Phase B | Bytecode Libc 最小集:isdigit、abs、tolower C 源码 + 自举一致性驱动 + golden |
cargo test --test bytecode_libc_consistency 通过 |
| Phase C | 差分测试骨架:对 strlen/isdigit/abs 同时调用 Host 和 Bytecode 版,交叉验证 |
差分测试全绿 |
| Phase D | 扩展 Bytecode Libc 到 20+ 函数,逐函数补齐 Host Contract + Bytecode Consistency + Differential | 覆盖矩阵更新 |
| Phase E | 模糊测试:随机内存状态 + 随机标准库调用序列,验证安全检测不泄漏 | 24 小时 fuzz 无崩溃 |
| Phase F | CI 集成:三层契约全部接入 .github/workflows/,失败记录自动更新 |
PR 时自动跑三层验证 |
七、与现有文档的衔接
C语言子集规范.md:补充"Vitro 标准库子集"章节,明确 Layer B/Layer C 支持清单;Clang直拍门禁.md(原影子验证框架.md,已随删区更名归档):Shadow 报告格式的std_lib_gap分类由 clang_directknown_direct.json白名单承接;../../archive/ARCHIVE_PHASE_KR_LEETCODE_TEST_PLAN.md(原docs/current/PHASE_KR_LEETCODE_TEST_PLAN.md,2026-09-11 归档):K&R/LeetCode 中涉及标准库的题目,优先走 Bytecode Libc 路径,暴露编译器缺口;该计划已达成,现状见AGENTS.md防线 2;AGENTS.md:更新"已知限制",引用本文档中的标准库覆盖矩阵。
八、当前实现状态:诚实盘点(As-of 2026-06-07——历史快照)
本章节基于删区前 Rust 实现时代的实际代码审计,不粉饰完成度;保留为诚实盘点的方法学存档(
native/内路径均已随删区退役)。已实现的标注 ✅,骨架存在但未产品化的标注 ⚠️,完全空白的标注 ❌。现役 MoonBit 侧对应实现见头部单轨口径注记。
8.1 已实现(超出预期)
| 组件 | 状态 | 说明 |
|---|---|---|
| Layer B Host Func 扩展 | ✅ | ctype 全家桶(12 个函数)、abs、strncpy、memcpy、memmove 已注册;strcpy 已注入 E3070 Buffer Overflow 诊断;math.h sin/cos/sqrt/pow/atan/log/exp 已通过 libm 注册 |
| Layer C Bytecode Libc 骨架 | ⚠️ | native/tests/bytecode_libc_consistency/src/native/runtime_libc/src/,C 源码质量合格;10 个驱动测试持续通过 |
| 3a Host Contract 测试 | ✅ | native/tests/host_contract_tests.rs(~650 行),覆盖 malloc(0)、UAF、Double-Free、strcpy 溢出、printf 边界、math 函数精度与边界 |
| 3b Bytecode Self-Consistency | ✅ | native/tests/bytecode_libc_consistency.rs(196 行),Clang vs Vitro 自举对比机制已跑通 |
| 3c Differential Stress | ✅ | native/tests/differential_stress.rs(404 行),Host vs Bytecode 交叉验证已覆盖 ctype/stdlib/string 子集 |
| 3d Fuzz 压力测试 | ✅ | native/tests/fuzz_stress_test.rs(971 行),随机序列 + 安全检测验证 |
8.2 未实现(按优先级排序)
P0 — 学生直接受影响,必须尽快补齐
| 缺口 | 影响 | 现状 |
|---|---|---|
| 1. 数学函数(math.h) | K&R 4.5(栈计算器)、LeetCode 数值题、学生写 sin(3.14) 直接报 undefined function |
✅ 已修复(2026-06-07)。引入 libm crate,注册 7 个数学函数 Host Func ID,TypeChecker 通过 math.h 存根声明识别,kr_4_5 从已知失败移除 |
| 2. 头文件存根系统(Stub Headers) | #include <stdio.h> 仍被 Lexer 直接跳过(lexer.rs:641-655),size_t/FILE*/NULL/EOF 没有通过头文件声明加载,全靠编译器硬编码兜底 |
✅ 已修复(2026-06-07)。Lexer 加载 runtime_libc/include/{stdio.h,stdlib.h,ctype.h,math.h,string.h} 存根;NULL/EOF/stdin/stdout/stderr 预定义宏内置;TypeChecker 逐步替代硬编码(math 函数已完成) |
P1 — 架构完整性的关键缺口
| 缺口 | 影响 | 现状 |
|---|---|---|
| 3. Bytecode Libc 产品化 | 学生代码调用 isdigit(c) 时走的是 Rust Host Func,不是 Bytecode Libc 的 C 实现;无法展示"libc 源码"教学价值 |
✅ 已完成(2026-06-07)。构建期预编译脚本 scripts/precompile_bytecode_libc(Go,2026-09-18 前为 .py)+ vitro_cli export 已建立;全局函数表固定索引段(1000~)已实现;ctype 纯计算函数(isdigit/isalpha/.../abs)已切换为 Bytecode 路径;2026-06-07 追加:strlen/strcmp 已加入 Bytecode Libc 产品路径;bytecode_libc_consistency.rs 和 differential_stress.rs 测试验证通过 |
| 4. VM Builtin 指令(Layer A) | memcpy/memset/strlen 仍走 OpCode::CallHost,没有专用指令优化 |
⚠️ 实验性骨架已完成(2026-06-07)。OpCode::Memcpy/Memset/Strlen 已添加至 native/crates/vitro_runtime/src/opcode.rs;native/crates/vitro_vm/src/core/executor/ 已实现带边界检查的指令语义;7 个单元测试全部通过。暂未接入 codegen,待 profiling 确认瓶颈后启用 |
P2 — 文档与长期维护
| 缺口 | 影响 | 现状 |
|---|---|---|
| 5. 标准库覆盖矩阵文档 | 无法向学生/教师明确承诺"Vitro 支持哪些标准库函数" | ✅ 已完成(2026-06-07)。已创建 docs/current/04-标准库与防线/标准库支持矩阵.md,按头文件分类维护函数级 Layer/类型检查来源/三层验证状态,并记录剩余缺口 |
8.3 Bytecode Libc 产品化路径(已打通)
用户代码 isdigit(c)
│
▼
TypeChecker 看到函数名 "isdigit"(头文件存根已声明)
│
▼
host_func_id::by_user_name("isdigit") → None(纯计算函数已切换为 Bytecode)
│
▼
BytecodeGen 查 func_index → 命中固定索引 1000
│
▼
生成 OpCode::Call(1000)
│
▼
VM 执行 Bytecode Libc 的 C 实现 `isdigit()`
产品路径验证:cargo test --test bytecode_libc_consistency 全绿,
differential_stress.rs Host vs Bytecode 交叉验证全绿,
Shadow Verification 无新增输出差异。
8.4 推荐实施顺序
Round 1(P0 紧急):✅ 已完成
├─ 引入 libm crate,注册 sin/cos/sqrt/pow/atan/log/exp host func
└─ 写 Host Contract 测试验证 math 函数精度
Round 2(P0 紧急):✅ 已完成
├─ 建立 native/runtime_libc/include/ 存根头文件
├─ 改造 Lexer:#include <ctype.h> / <stdlib.h> / <math.h> 加载存根,而非跳过
└─ TypeChecker 中通过头文件声明识别标准库符号(逐步替代硬编码函数名匹配)
Round 3(P1 架构):✅ 已完成(2026-06-07)
├─ ✅ 构建期预编译脚本 `scripts/precompile_bytecode_libc`(Go,2026-09-18 前为 .py)+ `vitro_cli export`
├─ ✅ 生成 `native/crates/vitro_vm/src/bytecode_libc_data.json` + `native/crates/vitro_runtime/src/bytecode_libc_index.rs`
├─ ✅ 全局函数表固定索引段(1000~1021)+ VM 代码拼接 + Jump 重定位
├─ ✅ 编译器前端:ctype 纯计算函数生成 Call 而非 CallHost
├─ ✅ 全局地址空间预留(BYTECODE_LIBC_GLOBALS_RESERVED = 1024)
├─ ✅ Bytecode Libc Consistency / Differential Stress 测试适配通过
└─ ✅ 2026-06-07 追加:`strlen`/`strcmp` 已加入 `BYTECODE_LIBC_PURE_FUNCS`,切换到 Bytecode Libc 产品路径;`is_builtin` 同步更新以支持无 `#include` 调用
Round 4(P1 优化):⚠️ 实验性骨架已完成(2026-06-07)
└─ ✅ `OpCode::Memcpy`/`Memset`/`Strlen` 已添加至 `native/crates/vitro_runtime/src/opcode.rs`(124~126)
└─ ✅ `native/crates/vitro_vm/src/core/executor/` 的 `execute_memory` 已实现原生执行逻辑(带 NULL 指针安全检查与越界截断)
└─ ✅ 7 个 Rust 单元测试全部通过(`builtin_tests`:strlen ×3、memset ×2、memcpy ×2)
└─ ⏳ 暂未接入 codegen:待 profiling 确认 `CallHost`/`Call` 开销为瓶颈后,再由 BytecodeGen 对 `strlen`/`memcpy`/`memset` 生成 Layer A 指令
Round 5(P2 文档):✅ 已完成
└─ 撰写 `docs/current/04-标准库与防线/标准库支持矩阵.md`,按 `stdio.h`/`stdlib.h`/`ctype.h`/`math.h`/`string.h` 分类维护函数级 Layer/类型检查来源/Host Contract/Bytecode Consistency/Differential 验证状态,并记录 `math.h` 与头文件存根两个已解除缺口
文档状态:设计草案 + 实现状态审计
最后更新:2026-09-11(前端切割后文档翻新:执行器/opcode/产物路径 crate 化,一致性驱动改为 cargo test --test bytecode_libc_consistency)
历史审计口径:§八「当前实现状态:诚实盘点(As-of 2026-06-07)」是 2026-06-07 的代码审计快照,其中的完成度判定、行数与用例数均保持当日 as-of 语义,未随后续变更回填;引用该章数字时请以 as-of 日期为准。