/** * 「人类的说明必须到达模型」—— opencode 桥的接线判据(2026-09-13 线上缺陷)。 * * 与 dsh 桥同源:`note` 在 SSE 回包里没人读,模型只拿到「决策」一个词。 * openCode 的权限回执(response: once/always/reject)**放不下理由**,所以有说明时 * 另外投一趟通知 —— 这条接线也必须被钉住,否则"修了"会随重构悄悄消失。 */ import { test } from 'node:test'; import assert from 'node:assert/strict'; import { readFileSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; const HERE = dirname(fileURLToPath(import.meta.url)); const SRC = readFileSync(join(HERE, '..', 'index.js'), 'utf8'); test('权限结论的提示词带上了人类的说明', () => { const fn = SRC.match(/function permissionPrompt\(data\) \{[\s\S]*?\n\}/); assert.ok(fn, 'permissionPrompt 必须存在'); assert.match(fn[0], /note/); assert.match(fn[0], /用户的说明/); }); test('★ 只有一处拼"已有结论"', () => { assert.equal([...SRC.matchAll(/你之前发起的权限请求已有结论/g)].length, 1); assert.match(SRC, /permissionPrompt\(data\)/); }); test('回执之后:有说明就另投一趟通知', () => { assert.match(SRC, /data\.note\.trim\(\)/); assert.match(SRC, /deliverMail\(client, directory, data, "permission"\)/); }); test('决策回执不再被当成新任务', () => { assert.match(SRC, /mail_type === "permission_decision"/); }); test('★ 判据自检:旧形态必须判红', () => { const old = '? `你之前发起的权限请求已有结论:${data.decision}(决策人:${data.decided_by || "用户"})。请据此继续后续工作。`'; assert.equal(/用户的说明/.test(old), false, '旧形态没有说明段'); assert.equal([...old.matchAll(/你之前发起的权限请求已有结论/g)].length, 1); });