summaryrefslogtreecommitdiff
path: root/scripts/m3r-master.sh
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-29 03:45:58 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-29 03:45:58 +0800
commit2c559a79a5977c19876cee58d336b7983f67fa4c (patch)
tree9607e336fc740bc840a02143f63fd7932aecedf3 /scripts/m3r-master.sh
parenteb4fca23cabce5762fc256a659228a5d50b5e9a9 (diff)
downloadliving-village-2c559a79a5977c19876cee58d336b7983f67fa4c.tar.gz
m3r: 缩尺批验收口(50×15 流式 + systemd --user 单元 + 独立验收脚本)
缩尺口径:M3 phase2 50×100 实测 11.4h 仅完成 6/50(见 artifacts/m3-acceptance/final-candidate-20260921T095500Z/logs/*.diagnosis.txt), 改为 50 世界 × 15 模拟日、逐世界流式打印并 flush。标定据 docs/overnight-status.md (Hermes 单 worker 亲测):1×2=34.6s、1×5=87.7s、1×10=173.6s,外推 15 天 ≈260s。 注意:派单所引用 artifacts/m3-independent/20260921T105500Z 全盘查找不存在, 故改用上述仓内标定,未编造任何数据。 内容: - Headless 边缘:runSimulation 拆出 runSimulationCore 增加逐模拟日回调; evalWorld 传入回调;runBatch 每 (days/5) 天打印 `[world k] progress day=d/D elapsed=..s` 并 flush,长世界不再零进度(BatchOutput.progressLine 纯函数 + 单测)。 - 新增 deploy/living-village-m3r.service 模板:wrapper 作 MasterProcess、 StandardOutput/StandardError=append: acceptance.log、Restart=no; systemd-analyze --user verify 通过。本机 ~/.config/systemd/user 属外部目录受限, 实跑以等价属性的 systemd-run --user 瞬态单元 living-village-m3r.service 承载。 - scripts/m3r-master.sh:写 state.json(pid/unit/log/commit/workers/worlds/days/ 起止/exit),exec 2>&1 运行 batch 并回传真实退出码。 - scripts/verify-m3r.py:独立可复跑,校验 state 字段、50 条 world 行(索引/seed/ ok 与 check_a/b/c 自洽)、summary passed+failed=50 与极值一致、抽查 3 行、 [done] 50 条、progress 行、M3_ACCEPTANCE=PASS 且 ratio_min>2.0。 本次实跑(commit 895d792):12 worker,wall=4316.0s,50/50 OK, ratio_min=3.346 ratio_max=12.321 gini∈[0.412,0.548],relconn=30/18, check_a/b/c 全 PASS,M3_ACCEPTANCE=PASS,exit=0;独立脚本复跑 M3R_VERIFY=PASS。 证据:artifacts/m3r-acceptance/acceptance.log + 20260928T183215Z/state.json。 回归:Desktop 303/303 + Kernel 119/119;--performance-baseline ×3 digest=953775FAEB2F… 不变,performance_determinism=PASS。 未改 Kernel/Sim;未 push。
Diffstat (limited to 'scripts/m3r-master.sh')
-rwxr-xr-xscripts/m3r-master.sh78
1 files changed, 78 insertions, 0 deletions
diff --git a/scripts/m3r-master.sh b/scripts/m3r-master.sh
new file mode 100755
index 0000000..d4f18fa
--- /dev/null
+++ b/scripts/m3r-master.sh
@@ -0,0 +1,78 @@
+#!/usr/bin/env bash
+# M3R 缩尺批验 MasterProcess 包装器(systemd --user 单元 ExecStart 指向本脚本)。
+#
+# 职责:
+# * 在 <M3R_DIR> 落 state.json(pid/unit/log/commit/workers/worlds/days/起止/exit);
+# * 以 2>&1 运行 Headless Release 批处理 `--batch <worlds> <days>`,逐世界流式;
+# * 进程退出即写回 ended_at 与退出码,并把真实退出码回传给 systemd。
+#
+# 环境变量(由 unit 注入):
+# M3R_REPO 仓库根(绝对路径)
+# M3R_DIR 本次运行证据目录(绝对路径,state.json 落此)
+# M3R_COMMIT 期望 commit 短哈希(写入 state.json)
+# M3R_WORLDS 世界数(默认 50)
+# M3R_DAYS 模拟天数(默认 15)
+# LV_BATCH_WORKERS 并行 worker 数(默认 12)
+# M3R_LOG 验收日志路径(只写入 state.json 作为记录,实际重定向由 unit 负责)
+set -u
+
+REPO="${M3R_REPO:?M3R_REPO required}"
+DIR="${M3R_DIR:?M3R_DIR required}"
+COMMIT="${M3R_COMMIT:?M3R_COMMIT required}"
+WORLDS="${M3R_WORLDS:-50}"
+DAYS="${M3R_DAYS:-15}"
+WORKERS="${LV_BATCH_WORKERS:-12}"
+LOG="${M3R_LOG:-$REPO/artifacts/m3r-acceptance/acceptance.log}"
+UNIT="living-village-m3r.service"
+DLL="$REPO/src/LivingVillage.Headless/bin/Release/net8.0/LivingVillage.Headless.dll"
+
+mkdir -p "$DIR"
+if [ ! -f "$DLL" ]; then
+ echo "[m3r] FATAL missing build: $DLL" >&2
+ exit 90
+fi
+
+STARTED="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
+echo "$$" > "$DIR/pid"
+echo "[m3r] start unit=$UNIT pid=$$ commit=$COMMIT workers=$WORKERS worlds=$WORLDS days=$DAYS started_at=$STARTED"
+
+python3 - "$DIR/state.json" "$UNIT" "$COMMIT" "$WORKERS" "$WORLDS" "$DAYS" "$LOG" "$STARTED" "$$" <<'PY'
+import json, sys
+out, unit, commit, workers, worlds, days, log, started, pid = sys.argv[1:10]
+state = {
+ "pid": int(pid),
+ "unit": unit,
+ "log": log,
+ "commit": commit,
+ "workers": int(workers),
+ "worlds": int(worlds),
+ "days": int(days),
+ "started_at": started,
+ "ended_at": None,
+ "exit": None,
+}
+with open(out, "w", encoding="utf-8") as fh:
+ json.dump(state, fh, ensure_ascii=False, indent=2, sort_keys=True)
+ fh.write("\n")
+PY
+
+export LV_BATCH_WORKERS="$WORKERS"
+( exec dotnet "$DLL" --batch "$WORLDS" "$DAYS" 2>&1 )
+CODE=$?
+
+ENDED="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
+echo "[m3r] end pid=$$ exit=$CODE ended_at=$ENDED"
+
+python3 - "$DIR/state.json" "$CODE" "$ENDED" <<'PY'
+import json, sys
+path, code, ended = sys.argv[1:4]
+with open(path, encoding="utf-8") as fh:
+ state = json.load(fh)
+state["ended_at"] = ended
+state["exit"] = int(code)
+with open(path, "w", encoding="utf-8") as fh:
+ json.dump(state, fh, ensure_ascii=False, indent=2, sort_keys=True)
+ fh.write("\n")
+PY
+
+exit "$CODE"