test(selftest): 補未修復裂痕的案例,764 → 773

涵蓋記下一件、不動 closeness/trust、語氣指示提得出來、帶記憶名字給 recall、
一個人卡幾件、--heal 寫 healed_at 而不是刪掉、和好完不再注入、沒得和好時被擋、
列表看得到和好過的紀錄。

最後一條刻意把兩件都和好掉,後面測害羞稱呼的案例才不會被裂痕那幾行干擾。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-03 09:03:06 +00:00
co-authored by Claude Opus 5
parent 8af0d5c387
commit a96f14f974
+47
View File
@@ -2123,6 +2123,53 @@ check("relation speaker 設定後,context 會注入語氣層與稱呼規則",
return res.status === 0 && pl.loadConfig("alpha").speaker_node === pl.slugify("伴侶甲") &&
ctx.includes("語氣層:老夫老妻") && ctx.includes("親愛的");
})());
// 未修復的裂痕:純量調不出「很近,但上次那件事還沒和好」
check("記下一件沒和好的事", (() => {
const res = cli(["relation", "rift", "--session", S_HOST, "--name", "伴侶甲",
"--about", "那天我沒去接他", "--at", "2026-07-20", "--memory", "hates-morning-meetings"]);
const node = pl.loadRelations("alpha").nodes.find((n) => n.name === "伴侶甲");
const open = pl.openRifts("alpha", node);
return res.status === 0 && open.length === 1 && open[0].about === "那天我沒去接他" &&
open[0].memory === "hates-morning-meetings";
})(), JSON.stringify(pl.loadRelations("alpha").nodes.find((n) => n.name === "伴侶甲")?.rifts));
check("裂痕獨立於 closenesstrust(沒有動那兩個數字)", (() => {
const node = pl.loadRelations("alpha").nodes.find((n) => n.name === "伴侶甲");
return Number(node.closeness) >= 90 && pl.openRifts("alpha", node).length === 1;
})(), JSON.stringify(pl.loadRelations("alpha").nodes.find((n) => n.name === "伴侶甲")));
check("語氣指示會提沒和好的事,而且點明親近度高不等於沒事", (() => {
cli(["relation", "speaker", "--session", S_HOST, "--name", "伴侶甲"]);
const d = pl.toneDirective("alpha", {});
return d.includes("還有沒和好的事") && d.includes("那天我沒去接他") &&
d.includes("親近度高**不等於**沒事");
})(), pl.toneDirective("alpha", {}));
check("裂痕帶著記憶名字(要細節自己 recall,不必等人提起)",
pl.toneDirective("alpha", {}).includes("recall `hates-morning-meetings`"),
pl.toneDirective("alpha", {}));
check("同一個人可以卡著幾件事", (() => {
cli(["relation", "rift", "--session", S_HOST, "--name", "伴侶甲", "--about", "生日那次忘了"]);
const node = pl.loadRelations("alpha").nodes.find((n) => n.name === "伴侶甲");
return pl.openRifts("alpha", node).length === 2;
})());
check("--heal 是寫 healed_at,不是刪掉那一筆(和好過跟沒發生過不一樣)", (() => {
const res = cli(["relation", "rift", "--session", S_HOST, "--name", "伴侶甲",
"--about", "生日那次", "--heal"]);
const node = pl.loadRelations("alpha").nodes.find((n) => n.name === "伴侶甲");
return res.status === 0 && node.rifts.length === 2 &&
pl.openRifts("alpha", node).length === 1 &&
node.rifts.some((r) => r.about === "生日那次忘了" && r.healed_at);
})(), JSON.stringify(pl.loadRelations("alpha").nodes.find((n) => n.name === "伴侶甲")?.rifts));
check("和好完的那件事就不再注入", !pl.toneDirective("alpha", {}).includes("生日那次忘了"),
pl.toneDirective("alpha", {}));
check("沒有還沒和好的事時 --heal 會被擋", (() => {
cli(["relation", "rift", "--session", S_HOST, "--name", "伴侶甲", "--about", "那天我沒去接他", "--heal"]);
const again = cli(["relation", "rift", "--session", S_HOST, "--name", "伴侶甲", "--heal"], { expectOk: false });
return again.status !== 0 && pl.toneDirective("alpha", {}).includes("還有沒和好") === false;
})());
check("列出來看得到和好過的紀錄", (() => {
const out = cli(["relation", "rift", "--session", S_HOST, "--name", "伴侶甲"]).stdout;
return out.includes("和好過 2 件") && out.includes("✔");
})(), cli(["relation", "rift", "--session", S_HOST, "--name", "伴侶甲"]).stdout);
// 稱呼隨情緒偏移:生氣走 except(退回全名),害羞是反方向(叫不出來)
check("羞怯稱呼是 STYLE_FACETS 的一格", pl.STYLE_FACETS.includes(pl.SHY_FACET));
check("羞恥度不到門檻就不換稱呼",