2026-08-21 00:46:56 +08:00
|
|
|
import assert from "node:assert/strict";
|
|
|
|
|
import test from "node:test";
|
|
|
|
|
import { loadPersonalSkillRegistry, planPersonalSkillRun, resolvePersonalSkill } from "./personal-skill-runtime.mjs";
|
|
|
|
|
|
|
|
|
|
const skillId = "JZ-CX-NARRATIVE-DECONSTRUCTION-001";
|
|
|
|
|
const base = {
|
|
|
|
|
event_id: "CASE-001",
|
|
|
|
|
skill_id: skillId,
|
|
|
|
|
channel_id: "SYS-JZ",
|
|
|
|
|
human_actor_id: "TCS-GL-0008∞",
|
|
|
|
|
persona_id: "PER-CX001",
|
|
|
|
|
source: "HUMAN_DIRECT_LANGUAGE",
|
|
|
|
|
input: { work_id: "BOOK-1", chapter_id: "CH-1", source_text: "第一章正文", analysis_goal: "节奏" }
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
test("registry keeps every compiled skill private by default", () => {
|
|
|
|
|
const registry = loadPersonalSkillRegistry();
|
|
|
|
|
assert.equal(registry.default_visibility, "PRIVATE");
|
|
|
|
|
for (const entry of registry.skills) {
|
|
|
|
|
const { pack } = resolvePersonalSkill(entry.skill_id, registry);
|
|
|
|
|
assert.equal(pack.visibility, "PRIVATE", entry.skill_id);
|
|
|
|
|
assert.equal(pack.share_state, "NOT_AUTHORIZED", entry.skill_id);
|
|
|
|
|
assert.equal(pack.marketplace_state, "NOT_AUTHORIZED", entry.skill_id);
|
|
|
|
|
assert.equal(pack.owner_human_anchor, entry.owner_human_anchor, entry.skill_id);
|
|
|
|
|
assert.equal(pack.custodian_persona_id, entry.custodian_persona_id, entry.skill_id);
|
|
|
|
|
assert.ok(pack.provenance && pack.input_schema && pack.deterministic_core, entry.skill_id);
|
|
|
|
|
assert.ok(pack.optional_semantic && pack.persona_judgment && pack.output_schema, entry.skill_id);
|
|
|
|
|
assert.ok(Array.isArray(pack.stop_conditions), entry.skill_id);
|
|
|
|
|
assert.ok(pack.experience_writeback, entry.skill_id);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("personal skill cannot run from another channel or persona", () => {
|
|
|
|
|
assert.equal(planPersonalSkillRun({ ...base, channel_id: "SYS-AW" }).status, "BLOCK");
|
|
|
|
|
assert.equal(planPersonalSkillRun({ ...base, persona_id: "PER-ZQ001" }).status, "BLOCK");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("deterministic core asks for missing exact input before any model", () => {
|
|
|
|
|
const result = planPersonalSkillRun({ ...base, input: { work_id: "BOOK-1" } });
|
|
|
|
|
assert.equal(result.status, "NEEDS_INPUT");
|
|
|
|
|
assert.ok(result.reasons.includes("MISSING_INPUT:chapter_id"));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("semantic ambiguity is explicit instead of guessed", () => {
|
|
|
|
|
const result = planPersonalSkillRun(base);
|
|
|
|
|
assert.equal(result.status, "MODEL_REQUIRED");
|
|
|
|
|
assert.equal(result.external_effect, "NONE");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("model candidates cannot replace persona judgment", () => {
|
|
|
|
|
const semantic_candidates = {
|
|
|
|
|
scene_functions: [], emotion_and_pacing: [], hooks_and_conflicts: [], transferable_patterns: []
|
|
|
|
|
};
|
|
|
|
|
const result = planPersonalSkillRun({ ...base, semantic_candidates });
|
|
|
|
|
assert.equal(result.status, "PERSONA_JUDGMENT_REQUIRED");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("a complete plan remains non-executing and routes external writes through the existing receipt gate", () => {
|
|
|
|
|
const semantic_candidates = {
|
|
|
|
|
scene_functions: [], emotion_and_pacing: [], hooks_and_conflicts: [], transferable_patterns: []
|
|
|
|
|
};
|
|
|
|
|
const result = planPersonalSkillRun({ ...base, semantic_candidates, persona_judgment: { decision: "ACCEPT_FOR_CURRENT_CASE", why: "evidence linked" } });
|
|
|
|
|
assert.equal(result.status, "DETERMINISTIC_READY");
|
|
|
|
|
assert.equal(result.external_effect, "NONE");
|
|
|
|
|
assert.equal(result.external_execution_route, "GH-CHANNEL-RECEIPT-0001");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("sharing, publication, and marketplace listing are never auto-compiled", () => {
|
|
|
|
|
for (const intent of ["SHARE", "PUBLISH", "MARKETPLACE_LIST"]) {
|
|
|
|
|
const result = planPersonalSkillRun({ ...base, intent });
|
|
|
|
|
assert.equal(result.status, "AUTHORIZATION_REQUIRED");
|
|
|
|
|
assert.ok(result.reasons.includes("NO_RELEASE_COMPILED_BY_THIS_PLANNER"));
|
|
|
|
|
}
|
|
|
|
|
const outsider = planPersonalSkillRun({ ...base, intent: "SHARE", human_actor_id: "ICE-GL∞" });
|
|
|
|
|
assert.ok(outsider.reasons.includes("ONLY_OWNER_HUMAN_MAY_DECIDE_RELEASE"));
|
|
|
|
|
});
|
2026-08-21 07:54:36 +08:00
|
|
|
|
|
|
|
|
test("EarEarDan skills remain private to Canger's channel and separate from Jianying", () => {
|
|
|
|
|
const event = {
|
|
|
|
|
event_id: "EED-CASE-001",
|
|
|
|
|
skill_id: "CE-EED-CAUSAL-PIPELINE-DIAGNOSTIC-001",
|
|
|
|
|
channel_id: "SYS-GLW-PTS-0001",
|
|
|
|
|
human_actor_id: "TCS-CL-0009",
|
|
|
|
|
persona_id: "ICE-BB-0004",
|
|
|
|
|
source: "HUMAN_DIRECT_LANGUAGE",
|
|
|
|
|
input: {
|
|
|
|
|
pipeline_id: "H3-REF2VA",
|
|
|
|
|
symptom: "reference seems ignored",
|
|
|
|
|
claimed_mechanism: "reference conditioning",
|
|
|
|
|
reproducible_input: "fixed seed case"
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
assert.equal(planPersonalSkillRun(event).status, "MODEL_REQUIRED");
|
|
|
|
|
assert.equal(planPersonalSkillRun({ ...event, persona_id: "ICE-GL-CA001" }).status, "BLOCK");
|
|
|
|
|
assert.equal(planPersonalSkillRun({ ...event, channel_id: "SYS-ZZ" }).status, "BLOCK");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("Zhizhi execution personas keep separate private skills and maturity states", () => {
|
|
|
|
|
const registry = loadPersonalSkillRegistry();
|
|
|
|
|
const anian = resolvePersonalSkill("ZZ-AN-SOURCE-FACT-CLOSURE-001", registry).pack;
|
|
|
|
|
const qiwu = resolvePersonalSkill("ZZ-QW-ROLE-CAUSAL-ARCHITECTURE-001", registry).pack;
|
|
|
|
|
const chaomu = resolvePersonalSkill("ZZ-CM-NOVEL-QUALITY-001", registry).pack;
|
|
|
|
|
assert.deepEqual([anian.owner_human_anchor, qiwu.owner_human_anchor, chaomu.owner_human_anchor], ["ICE-GL-ZHI∞", "ICE-GL-ZHI∞", "ICE-GL-ZHI∞"]);
|
|
|
|
|
assert.deepEqual([anian.custodian_persona_id, qiwu.custodian_persona_id, chaomu.custodian_persona_id], ["ICE-GL-AN-001", "PER-QW001", "ICE-GL-CM001"]);
|
|
|
|
|
assert.equal(anian.status, "PRIVATE_TRIAL");
|
|
|
|
|
assert.equal(qiwu.status, "PRIVATE_CANDIDATE");
|
|
|
|
|
assert.equal(chaomu.status, "PRIVATE_TRIAL");
|
|
|
|
|
});
|