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
14 changes: 14 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 @@ -30,6 +30,20 @@
#
# D and F needed `openkal-llvm-runtime@0.14.0`, registered after that dry run,
# and both reported NOT RUN rather than passing.
#
# THE 2026.9.21.3 WAVE, MEASURED IN SubOS `v920` WITH THE CN MIRROR, AGAINST
# THE PUBLISHED ARTEFACTS ON BOTH LEGS:
#
# mcpp 2026.9.21.2 (published) fails=2
# G the aarch64-macos build does not complete --- `-fno-builtin-
# memset_pattern16` is accepted and ignored, so the link stops at
# `undefined symbol: memset_pattern16`
# H `--no-run` does not exist
# mcpp 2026.9.21.3 (published) fails=0, nothing skipped
#
# 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.
set -u

VER="${MCPP_VERIFY_VERSION:?set MCPP_VERIFY_VERSION}"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -986,6 +986,48 @@ __APPLE__ __MACH__ __MCPP_TARGET_MACOS__ __OPENKAL__ __unix__
直接适用),要么由生态数据回答(每个配方按 `__has_include` 逐条问)。十个红格子的修法是
**一个**问题,不是十个,而这条记录的作用是让那个问题带着数字被提出。

### 7.3 发布与沙箱验收(2026.9.21.3)

发布物走完整条链:合入(squash 后的树与 PR head **逐字节相同**,39 条绿因此可转移)→
release.yml 六个 job 全绿 → 本地 `gtc` 补 GitCode(8 个资产全部 200,大小与上游一致;
linux x86_64 6.1MB 上传耗时 **5 秒**)→ 从 CN 镜像下载四个归档**独立重算 sha256**,与
各自的 sidecar 以及 bump PR 里的四个值**全部相同** → 合入 xim-pkgindex #868 → 索引
artifact 发布 → `xlings install mcpp@2026.9.21.3` 成功。

**沙箱验收在 SubOS `v920` 里跑,配 CN mirror,两条腿都用已发布物:**

| 段 | 2026.9.21.2(已发布) | 2026.9.21.3(已发布) |
| --- | --- | --- |
| A 身份与镜像 | ok | ok |
| B/C/D(上一批的 CHANGE) | ok | ok |
| E/F(GUARD) | ok | ok |
| **G** `builtins = "iso"` | **FAIL** | ok |
| **H** `mcpp test --no-run` | **FAIL** | ok |
| | `fails=2` | **`fails=0`,无 not run** |

⭐ B/C/D 在两条腿上都绿是**对的**:它们是上一批的 CHANGE,发布之后就转为 guard。
本批只有 G 和 H 是 CHANGE,**而它们在旧版上都红**——这正是 CHANGE 段必须具备的性质。

**一个只有实测才能发现的空转,以及它已经被修掉。** 第一次本地补 GitCode 退出码为 0
并打印「all assets mirrored + verified on 1 host(s)」,而上一行写着
`no GITCODE_TOKEN/gtc; skipping gitcode mirror`:`mirror_res.sh` 的闸要求**环境变量**
`GITCODE_TOKEN` 非空,而 `gtc` 与 `gh` 一样自己解析凭据(先环境变量、再它 `--help`
写明的配置文件),于是**一台 gtc 完全可用的机器被判定为没有 gtc**——而那正是这个脚本
被手动运行的那台机器。是我按判据去 GET `gitcode.com` 读到 404 才发现的。

⭐⭐ **更深的一层在验收环节:`verify` 只遍历「实际启用了的」host。** 分母与分子取自
同一次枚举,于是它分不出「两个 host 都齐」和「一个 host 被跳过、另一个齐」。
修法是把「这次必须完成哪些 host」在探测之前就声明出来(`MIRROR_HOSTS`,默认 `both`):
想只补一条腿是合法的——从 CN 宿主手动补 GitCode 正是本地运行的理由——**但它必须被要求,
不能是意外的结果**。凭据缺失现在硬退 2 并指出 token 可以放的两个位置。

| 情形 | 修之前 | 修之后 |
| --- | --- | --- |
| 本地,gtc 已配置、无环境变量 | **静默跳过,退 0** | 两个 host 都镜像并核验 |
| `MIRROR_HOSTS=gtc` | 无 | 明确排除 GitHub,退 0 |
| gtc 在但没有 token | **静默跳过,退 0** | **退 2**,指出两个可放 token 的位置 |
| CI(两个 token 都在环境里) | 两个 host | 不变,两个 host |

## 8. 本方案自身的失败模式

写下来,因为它们在本轮各出现过一次。
Expand Down
78 changes: 66 additions & 12 deletions .github/tools/mirror_res.sh
Original file line number Diff line number Diff line change
Expand Up @@ -246,22 +246,76 @@ mirror_host() { # kind(gh|gtc) base_url deadline_seconds

# ── Both hosts IN PARALLEL: they are fully independent, and the gitcode
# leg is cross-border-slow — serializing them doubled wall time for nothing.
# ── WHICH HOSTS THIS RUN MUST COMPLETE, STATED BEFORE ANYTHING IS PROBED ──
#
# The verify gate below iterates the hosts that turned out to be ENABLED, so
# until this variable existed its denominator came from the same enumeration
# as its numerator and could not tell "both hosts serve every asset" from
# "one host was skipped and the other serves every asset". Measured, 2026-09-21:
# a local top-up run exited 0 and printed `all assets mirrored + verified on
# 1 host(s)` with `no GITCODE_TOKEN/gtc; skipping gitcode mirror` one line
# above it, and nothing had reached GitCode at all.
#
# `both` is the default because that is what this script is for: the two hosts
# serve the GLOBAL and CN install paths, and an incomplete mirror surfaces as
# a 404 in the first user's install. Wanting one leg is legitimate --- topping
# GitCode up by hand from a CN host is the reason this runs locally at all ---
# but it has to be asked for.
: "${MIRROR_HOSTS:=both}"
case "$MIRROR_HOSTS" in
both|gh|gtc) ;;
*) echo "[mirror] MIRROR_HOSTS must be both|gh|gtc, not '$MIRROR_HOSTS'" >&2; exit 2 ;;
esac
WANT_GH=0; WANT_GTC=0
[[ "$MIRROR_HOSTS" == both || "$MIRROR_HOSTS" == gh ]] && WANT_GH=1
[[ "$MIRROR_HOSTS" == both || "$MIRROR_HOSTS" == gtc ]] && WANT_GTC=1

# CAN `gtc` AUTHENTICATE, NOT IS THE VARIABLE SET.
#
# gtc resolves its own credentials -- `GITCODE_TOKEN` first, then the config
# file its `--help` documents -- exactly as `gh` does, and the github leg below
# has always accepted either. This leg demanded the variable, so a machine with
# a working, configured gtc was told it had none. That is the machine this
# script is run on by hand.
gtc_can_auth() {
command -v gtc >/dev/null 2>&1 || return 1
[[ -n "${GITCODE_TOKEN:-}" ]] && return 0
local cfg="${XDG_CONFIG_HOME:-$HOME/.config}/gitcode-tool/config.json"
[[ -s "$cfg" ]] && grep -q '"token"[[:space:]]*:[[:space:]]*"[^"]\+"' "$cfg"
}

GH_ENABLED=0
if [[ -n "${XLINGS_RES_TOKEN:-}" ]] || gh auth status >/dev/null 2>&1; then
GH_ENABLED=1
info "GitHub $GH_DST tag $VER"
GH_TOKEN="${XLINGS_RES_TOKEN:-}" gh release view "$VER" -R "$GH_DST" >/dev/null 2>&1 \
|| GH_TOKEN="${XLINGS_RES_TOKEN:-}" gh release create "$VER" -R "$GH_DST" --title "$VER" --notes "$PROJ $VER (mirror of $SRC_REPO)"
if [[ "$WANT_GH" == 1 ]]; then
if [[ -n "${XLINGS_RES_TOKEN:-}" ]] || gh auth status >/dev/null 2>&1; then
GH_ENABLED=1
info "GitHub $GH_DST tag $VER"
GH_TOKEN="${XLINGS_RES_TOKEN:-}" gh release view "$VER" -R "$GH_DST" >/dev/null 2>&1 \
|| GH_TOKEN="${XLINGS_RES_TOKEN:-}" gh release create "$VER" -R "$GH_DST" --title "$VER" --notes "$PROJ $VER (mirror of $SRC_REPO)"
else
echo "[mirror] FAIL: this run must mirror to GitHub and there is no auth for it." >&2
echo "[mirror] set XLINGS_RES_TOKEN, or run \`gh auth login\`," >&2
echo "[mirror] or pass MIRROR_HOSTS=gtc to mirror only GitCode." >&2
exit 2
fi
else
info "no github auth; skipping github mirror"
info "MIRROR_HOSTS=$MIRROR_HOSTS: not mirroring to GitHub"
fi

GTC_ENABLED=0
if [[ -n "${GITCODE_TOKEN:-}" ]] && command -v gtc >/dev/null 2>&1; then
GTC_ENABLED=1
info "GitCode $GTC_DST tag $VER"
gtc release create "$GTC_DST" --tag "$VER" --name "$VER" 2>/dev/null || true
if [[ "$WANT_GTC" == 1 ]]; then
if gtc_can_auth; then
GTC_ENABLED=1
info "GitCode $GTC_DST tag $VER"
gtc release create "$GTC_DST" --tag "$VER" --name "$VER" 2>/dev/null || true
else
echo "[mirror] FAIL: this run must mirror to GitCode and gtc cannot authenticate." >&2
echo "[mirror] put gtc on PATH and give it a token -- GITCODE_TOKEN, or" >&2
echo "[mirror] \"token\" in ${XDG_CONFIG_HOME:-$HOME/.config}/gitcode-tool/config.json --" >&2
echo "[mirror] or pass MIRROR_HOSTS=gh to mirror only GitHub." >&2
exit 2
fi
else
info "no GITCODE_TOKEN/gtc; skipping gitcode mirror"
info "MIRROR_HOSTS=$MIRROR_HOSTS: not mirroring to GitCode"
fi

GH_PID=""; GTC_PID=""
Expand Down Expand Up @@ -313,5 +367,5 @@ if [[ $rc != 0 ]]; then
echo "[mirror] hint: if the asset above was WARNed at a leg deadline, raise MIRROR_LEG_DEADLINE_GH/GTC for this run, or push it by hand:" >&2
echo "[mirror] gh release download v$VER -R $SRC_REPO -p '<asset>' && gtc release upload $GTC_DST '<asset>' --tag $VER" >&2
fi
[[ $rc == 0 ]] && info "all assets mirrored + verified on ${#hosts[@]} host(s) in ${SECONDS}s"
[[ $rc == 0 ]] && info "all assets mirrored + verified on ${#hosts[@]} host(s) (${hosts[*]}) in ${SECONDS}s"
exit $rc
Loading