diff --git a/.agents/docs/2026-09-21-macros-and-withdrawal-verify.sh b/.agents/docs/2026-09-21-macros-and-withdrawal-verify.sh index e8098d99..5ad0cab6 100755 --- a/.agents/docs/2026-09-21-macros-and-withdrawal-verify.sh +++ b/.agents/docs/2026-09-21-macros-and-withdrawal-verify.sh @@ -41,6 +41,15 @@ # H `--no-run` does not exist # mcpp 2026.9.21.3 (published) fails=0, nothing skipped # +# AND AGAIN WITH SECTION I, after the four-package Windows chain published +# (openkal-llvm-runtime 0.15.1 -> openkal-musl 0.19.1 -> openkal-windows +# 0.10.1), same SubOS, same CN mirror: +# +# mcpp 2026.9.21.3 (published) fails=0, nothing skipped, nine sections +# I a program on 0.15.1 builds and runs, and the build names +# openkal-musl@0.19.1 -- a resolution that drew an older musl would +# satisfy the first half and carry none of the fix +# # B, C and D pass on BOTH, and that is correct rather than a hole: they are the # previous wave's changes, and this file keeps them as guards once their own # release has shipped. Only G and H are CHANGE sections for this one. @@ -404,6 +413,62 @@ EOF fi +# ── CHANGE. The four-package Windows chain reaches a consumer ─────────────── +section "I. openkal-llvm-runtime 0.15.1 resolves its whole chain (GRAPH)" +# ONE FIX, FOUR PACKAGES, AND THIS SECTION IS WHERE IT ARRIVES. +# +# openkal-windows 0.10.1 requests FILE_READ_ATTRIBUTES when opening a file, so +# a write-only handle can answer `kal_fs_file_info`; before it, `fstat` on a +# descriptor opened a line earlier returned EACCES on Windows, which is the +# pair libarchive performs when opening an archive for output. Reaching a +# consumer took openkal-musl 0.19.1 and openkal-llvm-runtime 0.15.1, because +# every pin in this ecosystem is exact. +# +# WHAT THIS SECTION CAN AND CANNOT SEE. It runs on Linux, so it cannot +# exercise the Windows call; the criterion for that is in openkal-windows, +# where three real-Windows conformance jobs answer 0 with the fix and 6 +# without. What a sandbox answers is the other half, and it is the half a +# four-package chain gets wrong: whether the versions are published, whether +# they resolve from the PUBLISHED index, and whether each one draws the next. +# +# NEITHER CHANGE NOR GUARD ON THIS FILE'S USUAL AXIS, WHICH IS WHY IT IS +# LABELLED SEPARATELY. A CHANGE section here must fail on the PREVIOUS mcpp +# release; this one would pass on it, because which graph an index publishes +# has nothing to do with which engine resolves it. Its axis is the GRAPH: it +# fails before openkal-llvm-runtime 0.15.1 is published, and against a +# manifest naming 0.15.0 the `grep` below fails on the musl version. Calling +# it CHANGE would have made the control reading against 2026.9.21.2 look like +# a hole when it is the correct answer. +i="$root/i"; rm -rf "$i"; mkdir -p "$i/src" +printf '#include \nint main(){std::puts("chain ok");return 0;}\n' > "$i/src/main.cpp" +cat > "$i/mcpp.toml" <<'EOF' +[package] +name = "openkal-chain" +version = "0.1.0" + +[dependencies] +openkal-llvm-runtime = "0.15.1" +EOF +if (cd "$i" && "$STORE" build > "$i/out.txt" 2>&1); then + if "$i"/target/*/*/bin/openkal-chain 2>/dev/null | grep -q "chain ok"; then + ok "a program on openkal-llvm-runtime 0.15.1 builds and runs" + else + fail "I: the program built on 0.15.1 and did not run" + fi + # AND IT DREW THE WHOLE CHAIN. A build that resolved 0.15.1 and an older + # musl would satisfy the line above and carry none of the fix. + if grep -q "openkal-musl@0.19.1" "$i/out.txt"; then + ok "0.15.1 resolves openkal-musl 0.19.1" + else + fail "I: 0.15.1 did not draw openkal-musl 0.19.1" + grep -E "c-abi|kernel-abi|c\+\+-abi" "$i/out.txt" | head -4 + fi +else + fail "I: openkal-llvm-runtime 0.15.1 did not resolve from the published index" + tail -3 "$i/out.txt" 2>/dev/null +fi + + printf '\n-- summary --\nfails=%d\nnot run:%s\n' "$fails" "${skipped:- (none)}" [ "$fails" -eq 0 ] diff --git a/.agents/docs/2026-09-21-openkal-ecosystem-completion-and-acceptance.md b/.agents/docs/2026-09-21-openkal-ecosystem-completion-and-acceptance.md index 6ba7af1c..cb6848ee 100644 --- a/.agents/docs/2026-09-21-openkal-ecosystem-completion-and-acceptance.md +++ b/.agents/docs/2026-09-21-openkal-ecosystem-completion-and-acceptance.md @@ -1048,6 +1048,76 @@ artifact 发布 → `xlings install mcpp@2026.9.21.3` 成功。 --- +## 8.5 生态级 review:这一轮实际发生了什么 + +这一节是收尾时对整轮的复查,按**跨仓库的因果**而不是按仓库列。 + +### 一、五个仓库,六次发布,一条因果链 + +| 仓库 | 版本 | 它解决的问题 | 判据在哪 | +| --- | --- | --- | --- | +| mcpp | 2026.9.21.3 | `builtins = "iso"` 发的 token 是静默空操作;跑不了的目标上 `builds` 说的是依赖 | `openkal-cross.yml` 三条腿 × 三宿主;e2e 745 五条腿 | +| openkal-windows | 0.10.1 | 只写打开的句柄回答不了 `kal_fs_file_info` | 三个真 Windows conformance job,带**去掉修复的对照** | +| openkal-musl | 0.19.1 | 把 0.10.1 带进来 | 上游判据 | +| openkal-llvm-runtime | 0.15.1 | 把 0.19.1 带进来 | 上游判据 | +| mcpp-index | — | 四个配方读错了「这是哪种 C 环境」 | 30 成员 × 2 目标,CI 实测 | +| lsp-mcpp-private | — | 向 Windows 要一个它没有的执行位 | 22/22 绿,Windows 那格是验收 | + +**一个修复走了四个包**,因为这个生态里每一个 pin 都是精确的。每一环都是 +「注册 → 发布 → 在**已发布索引**上实测可解析 → 下一环才动 pin」。 + +### 二、三个缺陷被报成了一个红格子 + +`lsp-mcpp-private` 的 Windows job 红,底下是**三个互不相干**的缺陷: + +1. macOS 链接缺 `memset_pattern16` —— **引擎**发了个 clang 静默忽略的 flag; +2. Windows 崩溃在 `chmod` —— **消费方**向 Windows 要执行位,而 `expect` 记录后继续, + 空 expected 被解引用; +3. Windows `fstat` 得 EACCES —— **openkal-windows** 开文件时没要 `FILE_READ_ATTRIBUTES`。 + +⭐ **「一个红格子 = 一个缺陷」是错的默认。** 每修好一个,下一个才露出来,而三者分别 +住在三个仓库。判据是:修完一个之后,**把失败集合前后对比**,而不是看它是否还红。 + +### 三、量到的、与量不到的 + +| 环境 | 能报告什么 | 这一轮的证据 | +| --- | --- | --- | +| Wine | **不能**报告 `fstat` 那条 | 去掉修复的对照上 Wine 仍绿;它不执行那次访问检查 | +| 索引的 windows 列 | 同上,它就是 Wine | 56 runs 里从来没红过这一条 | +| 真 Windows runner | 能 | 三个 conformance job:带修复 0,不带 6 | +| Linux 沙箱 | 不能执行 Windows 调用,**能**验证四包链是否发布并解析 | 段 I | + +⭐⭐ **「另一个环境也通过」只有在那个环境确实收到同样的输入时才算证据。** 这一轮里 +Wine 被我当成第二意见用了三次,而它的账户名短到根本不会生成 8.3 短名、它也不执行 +那次访问检查——它收到的从来不是同一个输入。 + +### 四、自己造成的三处,以及它们各自的判据 + +1. **`git add -A` 把未提交的 pin 挪动扫进了注册 PR。** 后果是实测的:那次 compat 跑在 + 0.15.1 尚未上 main 时,`xlings install` 失败,**60 格里 55 格红**,而 workflow 仍报 + success(ratchet 不是必需检查)。已发布的基线没被污染。**改法不是更小心,而是 + 注册 PR 在 commit 前先 `git status --short` 读一遍**,以及把描述当承诺核对。 +2. **本地 `gtc` 补 GitCode 第一次空转。** 退出 0、打印「all assets mirrored」,而上一行 + 写着 skipping——闸要环境变量,`gtc` 的 token 在自己的配置文件里。已修,并把 + `verify` 的分母从「实际启用的 host」改成「这次必须完成的 host」。 +3. **生成注册条目时 CN url 写错。** 分段替换先换了文件名,目录段就再也匹配不上, + 得到形状合法、取不到东西的 url。lint 通过。**改法:注册加的每个 url 都要 GET, + 不能只 lint。** + +### 五、三个仍然开着的,以及为什么现在不做 + +- **`aarch64-macos` 不进 pins.toml。** 实测 20 建成、10 不建成,**十个里九个**是 + `#ifdef __APPLE__` 去要 Apple 的 C 环境,而那个目标上 `__APPLE__` 是对的。 + 十个红格子的修法是**一个设计问题**:源码没有任何办法问「哪个 C 库」。 +- **mimalloc 的 Windows `alloc` 测试**在 CI 的 Wine 下退 1,本机 Wine 下通过。构建已修 + (`fails` → `builds`),测试没有。 +- **I1 / I2** 是计划里就写明的第五批。 + +### 六、一句话 + +这一轮把「一个红格子」拆成了三个仓库里的三个缺陷,把一个走四个包的修复送到了消费方, +而**每一次「它绿了」都被要求先在去掉修复之后红过一次**。 + ## 9. 一句话 本轮把「能力何时被回答」这件事从预处理期移到了解析期,并让三个实现都说出自己提供什么。