feat(discord): connector pilot for the Sage seat, reviewed candidate (#1509)

Zero-dependency Discord connector under packages/discord: binding
validation, REST and gateway clients, pi engine adapter, journal with
append-only inbox, outbox, admissions and notices, and a run.lock
ownership record {pid, start, boot} whose identity is checked three ways
and whose cleanup is gated by STOP. CLI check|run|stop|unlock via
scripts/discord.sh; offline suite scripts/test-discord.sh (28 checks,
87 node tests).

Reviewed by rev-code-02 on #1509 over nine rounds; approved exact tree
4e0feb6758c0a7e4a71483912a8e0d3e3ec95aef at comment 26170. Corrections
(1) to (12) recorded in BUILD-LOG. No listener started, no token read,
no Discord write; the live pilot follows this commit per the brief.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
This commit is contained in:
2026-09-13 01:15:37 -05:00
co-authored by Claude Fable 5.1
parent b023841c8a
commit 786e379c49
34 changed files with 4641 additions and 1 deletions
+67
View File
@@ -0,0 +1,67 @@
import { test } from "node:test";
import assert from "node:assert/strict";
import { authorize, DROP } from "../src/authorize.mjs";
import { binding, message, IDS } from "./helpers.mjs";
const b = binding();
const threads = new Map([
[IDS.threadOfAdmin, { type: 11, parentId: IDS.admin, name: "admin-thread", guildId: IDS.guild }],
[IDS.threadOfOther, { type: 11, parentId: IDS.other, name: "other-thread", guildId: IDS.guild }],
["100000000000000030", { type: 12, parentId: IDS.general, name: "private-general-thread", guildId: IDS.guild }],
["100000000000000031", { type: 0, parentId: null, name: "text-not-thread", guildId: IDS.guild }],
]);
const info = (id) => threads.get(id);
const botMention = [{ id: IDS.bot, username: "bot" }];
const table = [
["open channel, listed user", message(), { ok: true, channel: IDS.admin, thread: null }],
["wrong guild", message({ guild_id: "100000000000000099" }), { ok: false, reason: DROP.GUILD }],
["no guild (DM)", message({ guild_id: undefined }), { ok: false, reason: DROP.GUILD }],
["unlisted channel", message({ channel_id: IDS.other }), { ok: false, reason: DROP.CHANNEL }],
["unknown channel, no info", message({ channel_id: "100000000000000098" }), { ok: false, reason: DROP.CHANNEL }],
["thread of listed parent", message({ channel_id: IDS.threadOfAdmin }), { ok: true, channel: IDS.admin, thread: IDS.threadOfAdmin }],
["thread of unlisted parent", message({ channel_id: IDS.threadOfOther }), { ok: false, reason: DROP.THREAD_PARENT }],
["text channel that is not a thread and not listed", message({ channel_id: "100000000000000031" }), { ok: false, reason: DROP.CHANNEL }],
["unlisted user", message({ author: { id: IDS.stranger } }), { ok: false, reason: DROP.USER }],
["no author", message({ author: undefined }), { ok: false, reason: DROP.USER }],
["bot author (listed id, bot flag)", message({ author: { id: IDS.owner, bot: true } }), { ok: false, reason: DROP.BOT }],
["system author", message({ author: { id: IDS.owner, system: true } }), { ok: false, reason: DROP.BOT }],
["the bot itself", message({ author: { id: IDS.bot } }), { ok: false, reason: DROP.SELF }],
["webhook", message({ webhook_id: "100000000000000050" }), { ok: false, reason: DROP.WEBHOOK }],
["mention channel without mention", message({ channel_id: IDS.general }), { ok: false, reason: DROP.MENTION }],
["mention channel with bot mention", message({ channel_id: IDS.general, mentions: botMention }), { ok: true, channel: IDS.general, thread: null }],
["mention channel with @everyone only", message({ channel_id: IDS.general, mention_everyone: true, content: "@everyone hi" }), { ok: false, reason: DROP.MENTION }],
["mention channel mentioning someone else", message({ channel_id: IDS.general, mentions: [{ id: IDS.stranger }] }), { ok: false, reason: DROP.MENTION }],
["mention channel, content says @bot but mentions empty", message({ channel_id: IDS.general, content: `<@${IDS.bot}> hi` }), { ok: false, reason: DROP.MENTION }],
["private thread under mention channel, mentioned", message({ channel_id: "100000000000000030", mentions: botMention }), { ok: true, channel: IDS.general, thread: "100000000000000030" }],
["private thread under mention channel, not mentioned", message({ channel_id: "100000000000000030" }), { ok: false, reason: DROP.MENTION }],
["thread in another guild per channel info", message({ channel_id: IDS.threadOfAdmin, guild_id: IDS.guild }), { ok: true, channel: IDS.admin, thread: IDS.threadOfAdmin }],
["not an object", null, { ok: false, reason: DROP.NOT_OBJECT }],
["no id", message({ id: "" }), { ok: false, reason: DROP.NO_ID }],
["oversize content is accepted and flagged", message({ content: "x".repeat(4001) }), { ok: true, channel: IDS.admin, thread: null, oversize: true }],
["exactly the limit is not oversize", message({ content: "x".repeat(4000) }), { ok: true, channel: IDS.admin, thread: null, oversize: false }],
];
for (const [name, msg, expected] of table) {
test(`authorize: ${name}`, () => {
const r = authorize(b, msg, info);
assert.equal(r.ok, expected.ok, JSON.stringify(r));
if (!expected.ok) assert.equal(r.reason, expected.reason);
else {
assert.equal(r.channel.id, expected.channel);
assert.equal(r.thread ? r.thread.id : null, expected.thread);
if (expected.oversize !== undefined) assert.equal(r.oversize, expected.oversize);
}
});
}
test("authorize: order puts wrong guild before user, and user before channel (no channel lookup for strangers)", () => {
let looked = 0;
const spy = (id) => {
looked += 1;
return info(id);
};
assert.equal(authorize(b, message({ guild_id: "100000000000000099", author: { id: IDS.stranger } }), spy).reason, DROP.GUILD);
assert.equal(authorize(b, message({ channel_id: IDS.threadOfAdmin, author: { id: IDS.stranger } }), spy).reason, DROP.USER);
assert.equal(looked, 0);
});