Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions .agents/docs/2026-09-21-macros-and-withdrawal-verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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 <cstdio>\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 ]
Original file line number Diff line number Diff line change
Expand Up @@ -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. 一句话

本轮把「能力何时被回答」这件事从预处理期移到了解析期,并让三个实现都说出自己提供什么。
Expand Down
Loading