总览
发件人(发信邮箱)
契约 A(H1):邮箱身份与 SMTP 端点只在 send/config.json 里 ——
那份「可信注册表」属主是引擎用户,审核台既不写也改不了,这一页只只读展示它。
新增 / 更换邮箱或端点,需要部署方修改 send/config.json。
这一页能改的只有每邮箱的 dailyCap / ramp / minIntervalSec / enabled,而且只能收紧或停用;
点「生成并校验」把它们写进 send/control/config.json(只含这几项的覆盖层),
写盘前先用「注册表 ⊕ 覆盖层」跑一次引擎 dry-run,退出码 0 才落盘。
凭据只写不读 —— 填进去立刻投递到 send/incoming_secrets/<id>.env,之后这里只显示「已设置 / 未设置」。
清单
限额覆盖
send/control/config.json 的东西,而且
只能收紧:dailyCap 取更小者(硬顶 40)、ramp 逐日取更小者、最小间隔取更大者(全局下限 90 秒);
取消「启用」写的是 enabled:false(覆盖层里 enabled 只允许出现 false)。
身份、队列、认证方式、provider、端点、备注一律改不了 —— 它们在
send/config.json 里,由部署方维护。凭据
<id>.env 里消失 —— 上面列了当前有哪些 KEY,照着补齐。
写完这里就再也读不到值了:任何接口都不返回,审计只记字段名。provider 在引擎侧固定,自建端点由部署方写在引擎的可信配置里。
能改端点,就等于能把一份自己读不到的口令送去别的主机认证一次,所以这三项审核台一律不接受。批量导入
id / dailyCap / ramp / minIntervalSec / enabled
(中文列名也认)。其它列一律整行拒绝并提示 —— from / 发信地址 / queue / auth / provider /
host / port / secure / stage / note 都是注册表的东西,请部署方改 send/config.json;
user / pass / client_id 也不再走这条路,请用清单里每个发件人的「凭据」表单单独投递。
id 必须已经在注册表里;限额只能收紧;「停用」不在这条路上做(它会连带不可逆的吊销,必须逐个确认)。
逐行校验:坏行只影响自己,报告里会给出行号与原因。任务
任务(campaign)是系统里的一等对象:名单挂在它下面、批次通过 batchmeta.campaignId 认领它、
发送计划引用它的框架 hash。框架通过 = 第一层审核;逐封审是第二层,在「审核」页。
框架实质修改(hash 变)会让批准自动作废并回到 draft。
新建任务
名单
导入 CSV / TSV(一期不做 XLSX)。缺「邮箱」列整份拒绝; 缺来源 URL 或采集日期的行可以导入,但不可导出、不可进计划。 导入时每行生成一个不可变的 leadId —— 序列按它认人,不按行号。 「清洗」(Bouncer 验证)是第二轮的事,这一页现在只做导入、分层与政策改判。
导入
发送
用自然语言或表单定发送计划 → 代码校验 → 确定性回读 + 日历预览 → 确认(= 一段 ≤ 7 天的发送授权)。
人看见的那段中文由代码从校验后的最终字段生成,模型的复述只摆在旁边对照。
确认只落 plans.json 与审计;写 LIVE_CONFIRMED / ACTIVE.json 只发生在
计划日早上 08:40–08:55 的武装窗口,而且**preflight 全过之后**才写(规格 §5.7)。
错过窗口不补;序列第 2 步永远不自动武装。
新建计划
发送运行(引擎侧)
只读引擎写的 send/runs/*.json 与 send/send_log.json。
定时发送由引擎侧的 systemd timer 触发,审核台只写 ACTIVE.json 告诉它「今天发哪一批」。
人工登记一条投诉 / 退订
退订登记
退订表是只增不减的(CASL 要求永久保留)。登记后该邮箱永久不可导出,并会进入后续每一份队列文件的
state.manual.unsubscribes。
H6:登记的顺序是「先写权威契约文件、成功了才写本地记录」 ——
契约写失败就整条失败,本地一个字节都不记;每次登记之后还会立刻对一次账
(本地退订集合必须 ⊆ 契约集合),对不上就阻断导出与「设为生效」。
管理员面板
急停与当日确认
send/control/STOP。引擎启动时与每封发送前各查一次,见到就安全退出(退出码 3)。send/control/LIVE_CONFIRMED,内容 = 温哥华当天日期。这是 live 四道闸门的第 (c) 道,只管当天。导入批次
导出队列
.REJECTED.json。
引擎校验最多跑 150 秒(要先于反代的 180 秒超时结束,否则页面报 504 而服务端还在跑)。
文件名带导出时刻(…_日期_时分秒_queue.json),同一天再导一次不会覆盖上一份 ——
正在生效(ACTIVE.json 指向)的文件更是禁止被覆盖或删除。批次管理与「设为生效」
send/batches/reviewed/ACTIVE.json,告诉引擎侧的定时器「这个发件人今天发哪一份队列」。
只有引擎校验通过的导出才能设为生效;同一队列同时只能有一个生效批次。
生效不等于会发 —— 真发还要当天点过 LIVE_CONFIRMED,且四道闸门全过。双人复核
第一层审核与频控(v2.0)
收信开关(inboxCollector)
inbox_never_ran 拦。
on:总是判新鲜度(超过上限没成功轮询过 → inbox_stale)。
off:部署方明确不收信 —— 武装放行,但退信 / 回信 / 投诉这段时间一条都进不来。
要收信:服务器上 sudo systemctl enable --now lingshu-inbox.timer(单元默认是关的)。
这个开关写在 review/data/settings.json,改一次进一次审计。