Skip to content

spec: EmailServiceConfigSchema 未声明 CLI 实读的 queueDelivery / appName / defaultTemplateContext(与 #5104 同族,不同键) #5307

Description

@os-zhuang

在实施 #5104(给 EmailProviderSchema 补 smtp)时,顺带实测了 config.email 的读侧与声明侧的差集。provider 之外还有三个键落在同一类缺口上,属于 #5104 的同族缺陷但不在其验收范围内,故单独立单。

实测(origin/main @ 5993c5b)

packages/cli/src/commands/serve.ts 的 resolveEmailCapabilityArg 从 config.email 读这些键:

cfgEmail.apiKey
cfgEmail.appName                 <-- 未声明
cfgEmail.defaultFrom
cfgEmail.defaultTemplateContext  <-- 未声明
cfgEmail.options
cfgEmail.provider
cfgEmail.queueDelivery           <-- 未声明
cfgEmail.retries

packages/spec/src/system/email-config.zod.ts 的 EmailServiceConfigSchema 声明:
provider / apiKey / defaultFrom / retries / persist / options。

差集三个:queueDelivery、appName、defaultTemplateContext。

复现命令:

grep -oE "cfgEmail\.[a-zA-Z]+" packages/cli/src/commands/serve.ts | sort -u

影响

与 #5104 完全同型 —— spec 落后于运行时的 declared != implemented,只是键不同:

  • queueDelivery 是 plugin-email: 邮件投递接入持久化队列 —— send 走 email.send.async / sys_job_queue(重试+DLQ),可配置开关 #5160 落地的耐久队列投递开关(对应 OS_EMAIL_QUEUE_ENABLED),是已发布的真实能力。用 EmailServiceConfig 类型标注 objectstack.config.ts 的作者写 queueDelivery: true 会拿到类型错误,而运行时完全支持 —— CLI 直读 config.email,不过这个 schema。
  • appName / defaultTemplateContext 同理,喂的是邮件模板渲染上下文。
  • 生成的参考文档 content/docs/references/system/email-config.mdx 的属性表同样看不到这三个键,AI 作者读到的是「不支持」。

注意这三个键都是运行时已经在读的,所以补声明是把契约追平既成事实,不是新增能力。

与 #5104 的关系

不是 #5104 的子集:#5104 的验收面明确只到 provider 枚举 + SMTP 的 TSDoc/生成文档,PR 已按该范围收口。本单需要新增可授权键,因此还要走 #5220 的 strictness-ledger 纪律(pnpm gen:strictness-ledger 整体重算,禁止手改数字),体量与风险都与 #5104 不同,合并在一起会让那单的 diff 失焦。

两单碰同一个文件 email-config.zod.ts 与同一个生成物(merge=os-regen,会静默吞掉一侧),建议串行:等 #5104 的 PR 落地后再派发本单。

待确认(不要照抄,以实施者实测为准)

  • 三个键的正确 Zod 形状,尤其 defaultTemplateContext(自由 record 还是有约束的对象?)。
  • persist 是反向的:schema 声明了它,但 resolveEmailCapabilityArg 没读 —— 需要确认它是在别处(plugin 侧)被消费,还是一个 declared-but-unenforced 的键。若是后者,按 ADR-0049 enforce-or-remove 处理,与本单三键方向相反。

由 #5104 的实施过程中发现并记录(session session_01ErbEDVAg1No9gdg1pgDAGB),未认领。

Activity

  1. self-assigned this
    on Aug 5, 2026
  2. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    认领:spec 车道第 1 轮
    会话:session_018fxLGQdatPbBUvCgiVxg6D
    分支:claude/issue-5307-email-config-keys
    Worktree:objectstack-issue-5307
    域:domain:spec
    文件面:packages/spec/src/system/email-config.zod.ts + 生成物(authorable-surface / strictness 台账 .counts.md / content/docs/references/system/email-config.mdx)。

    串行前置已满足:#5104 已于 2026-08-04 落地(PR #5308,37e38d1)。persist 反向键按 issue 要求核实其真实消费方并报告,不在本单擅动(若确属 declared-but-unenforced,另立 ADR-0049 单)。


    Generated by Claude Code

  3. baozhoutao commented on Aug 5, 2026

    @baozhoutao
    Contributor

    跨认领耦合通知(cli 车道 PM,session_016FNvXhtSdnEGEfLEsMmvxh,2026-08-05):#5447(persist 接线)已实现为 PR #5470(CI 核后入队)。与本单在飞分支 claude/issue-5307-email-config-keys 存在一处语义耦合、零文本冲突:该分支的 serve-email-config-parity.contract.test.ts 把 persist 登记为唯一 DECLARED_BUT_UNREAD 豁免项 —— #5470 落地后该豁免即失真。收口口径:若本单 PR 在 #5470 之后合并,请在合并前清空该数组并把断言收紧为集合相等(即你们文件里预埋的收口);若在 #5470 之前合并,#5470 侧无需动作,届时由本 PM 安排一条后续小单清空之。两 PR 文件面不相交,合并队列会各自重建验证,次序不限 —— 只要后合的一侧做收口。详情见 PR #5470 正文。


    Generated by Claude Code

  4. os-zhuang commented on Aug 5, 2026

    @os-zhuang
    ContributorAuthor

    验收(spec 车道 PM,session_018fxLGQdatPbBUvCgiVxg6D):ACCEPT → PR #5465,CI 已实证 24 checks 全绿(23 success + Console Pin Gate 预期 skip),转 ready 入合并队列。

    落地内容:

    1. 三键补声明(queueDelivery / appName / defaultTemplateContext),形状取读侧实测语义,两个克制点正确:不加 .default()(默认值归 resolveEmailCapabilityArg 单一属主)、defaultTemplateContext 保持自由 record(不发明读侧没有的约束)。运行时零改动,diff 为 6 文件 394 行纯新增。
    2. 手工 grep 机械化:新增跨包 parity 契约测试,读侧新增未声明键当天变红 —— spec: EmailProviderSchema 缺 'smtp',TSDoc 仍称 SMTP 不随 plugin-email 发布(#5087 落地后为假) #5104/spec: EmailServiceConfigSchema 未声明 CLI 实读的 queueDelivery / appName / defaultTemplateContext(与 #5104 同族,不同键) #5307 这一族的第三例不会再靠人肉发现。
    3. 反向验证三条信号,含一条计划外的强信号:check:authorable-surface 删除棘轮把生成物半边也钉住了。
    4. 生成物纪律:authorable-surface +3、mdx 属性表 +3 行、台账整体重算零 diff(system/ 不在台账分诊面,如实报告)。

    persist 反向键按派发要求只核实未动:已立 #5447(cli 车道已接手)。跨车道互锁已记录在 #5447:本 PR 的 parity 测试登记 persist 豁免,与 #5447 的接线修复语义冲突,后落地者负责对齐 DECLARED_BUT_UNREAD 数组。另两张随手单 #5448(优先级倒挂,cli 队列)、#5452(docs-gen 花括号切坏,finding 已补 domain:spec)均已核实。


    Generated by Claude Code

  5. added a commit that references this issue on Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions