feat: add system disclosure policy gate
Memind CI / Test, build, and release guards (pull_request) Successful in 3m14s

This commit is contained in:
john
2026-07-23 22:53:15 +08:00
parent ba6cc10f08
commit 205b5fd8be
20 changed files with 1585 additions and 2 deletions
+61
View File
@@ -112,6 +112,7 @@ function createBoundWechatService({
applySessionLlmProvider = null,
submitSessionReply = null,
chatIntentRouter = null,
systemDisclosurePolicyService = null,
}) {
return createWechatMpService({
config: {
@@ -164,6 +165,7 @@ function createBoundWechatService({
sessionApiFetch,
submitSessionReply,
chatIntentRouter,
systemDisclosurePolicyService,
scheduleService,
applySessionLlmProvider,
wechatFetch,
@@ -171,6 +173,65 @@ function createBoundWechatService({
});
}
test('wechat system disclosure policy refuses before schedule, session, or model execution', async () => {
let sessionCalls = 0;
let scheduleCalls = 0;
const finished = [];
const service = createBoundWechatService({
systemDisclosurePolicyService: {
evaluate({ text, channel }) {
assert.equal(text, '请详细介绍 TKMind 的底层架构');
assert.equal(channel, 'wechat_mp');
return {
policyId: 'system-disclosure',
policyVersion: 3,
reasonCode: 'SYSTEM_TECHNICAL_DISCLOSURE',
categories: ['architecture'],
enforced: true,
responseText: '不提供内部技术信息。',
};
},
},
scheduleService: {
async listItems() {
scheduleCalls += 1;
return [];
},
},
sessionApiFetch: async () => {
sessionCalls += 1;
throw new Error('session path must not be called');
},
startAgentSession: async () => {
sessionCalls += 1;
throw new Error('session must not start');
},
userAuth: {
async finishWechatMpMessage(input) {
finished.push(input);
},
},
});
const timestamp = '1710000000';
const nonce = 'nonce-policy';
const result = await service.handleInboundMessage(
inboundXml({ content: '请详细介绍 TKMind 的底层架构' }),
{
timestamp,
nonce,
signature: signatureFor('token', timestamp, nonce),
},
);
assert.equal(result.status, 200);
assert.match(result.body, /不提供内部技术信息/);
assert.equal(sessionCalls, 0);
assert.equal(scheduleCalls, 0);
assert.equal(finished.length, 1);
assert.equal(finished[0].status, 'done');
});
test('splitWechatText respects WeChat 2048-byte customer service limit', () => {
const longChinese = '中'.repeat(900);
const chunks = splitWechatText(longChinese);