diff --git a/scripts/selftest.mjs b/scripts/selftest.mjs index 2d85da6..3d9f211 100644 --- a/scripts/selftest.mjs +++ b/scripts/selftest.mjs @@ -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("裂痕獨立於 closeness/trust(沒有動那兩個數字)", (() => { + 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("羞恥度不到門檻就不換稱呼",