Repository navigation
[Decision] 平台自带的四个定时示例流一个都声明不了组织 —— 而新规则要求它们必须声明 #17396
Description
⚠️ 重建卡。 原卡 #17150 随os-trump账号被停用一起销毁。⛔ 原卡上的选项字母(A′ / B / C)与其正文已经不存在,本席不复原它们——下面的选项是重新写的,⛔ 不要把它们当成原卡那三个。若你记得原来的裁定倾向,请直接说,本席照办。PR #17334 的四处源码注释与 changeset 都写着这张卡"正在重建"(
grep 'is being re-filed'),⇒ 这个号是欠代码库的。
一句话问题
我们自己发的示例应用里有四个定时流。新规则要求每个定时流声明它代表哪个组织,而这四个流一个都声明不了 —— 于是要么它们在启动时全部不再运行,要么规则对它们网开一面。
背景
#16659 的维护者裁决(2026-09-08,逐字):
多组织定时任务本来只能在组织内运行,应该带组织ID,不允许跨组织的定时任务。
PR #17334 实现了它:一个 schedule / time_relative 流若不声明 organization,启动时就不再 armed,并打出一条点名该流与该键的拒绝。
sys_organization.id,部署自己铸的)⇒ 示例应用的作者写不出它。四个流是:showcase_task_due_reminder、showcase_scheduled_digest,以及另外两个(PR #17334 的文档段落列全)。
⭐ 已经被这一轮回答掉的那一半(⛔ 不再是本卡的问题)
原卡曾把「validate-flow-trigger-readiness 能不能学会这条规则」列为待决之一。它学会了,而且严重度是测量出来的,不是选的:
- 定为
warning⇒objectstack build在examples/app-showcase与example-todo上通过; - 承接席做了一次一次性变异探针把它翻成
error⇒objectstack build直接失败,点名showcase_task_due_reminder与showcase_scheduled_digest,⛔ 而作者没有任何可写的修法。
⇒ 这条探针把本卡的真问题量了出来:规则本身没错,是我们自己的示例满足不了它。
选项 × 真实代价(⛔ 重新写的,不是原卡那三个)
| 做什么 | 客户能感知到什么 | |
|---|---|---|
| A | 让示例流能声明组织:给一个可授权的引用形式(例如指向"本部署的唯一组织"或一个具名种子组织的记号),示例照写 | 示例能跑; |
| B | 承认示例是单组织场景,给单组织装机一条明确的、声明式的豁免 | 示例照跑; |
| C | 示例流不再自带定时触发,改成文档里说明"你自己加上 organization 之后再启用" | ⛔ 示例失去一个能跑起来的能力;但规则不被稀释,⇒ 也没有新增永久面 |
| D | 维持现状:四个示例流在启动时静静地不 armed,lint 报 warning |
⛔ 我们自己发的示例带着一个警告,且它演示的能力实际上不工作 |
业务含义直译
- A =「给示例发一张通用工牌」——能进门,但要想清楚这张工牌在有很多扇门的大楼里意味着什么。
- B =「单间办公室不用刷卡」——今天成立,搬进写字楼的第一天失效。
- C =「示例只演示怎么装门,不演示开门」。
- D =「门装好了,钥匙没发,门口贴张纸条」。
四棱
os-decision-facets
① 项目长远合理性 —— C 不新增任何永久面,最省;A 新增一个必须在多组织下也说得通的记号,⇒ 它是唯一可能扩大契约的;B 造一个"今天成立、明天失效"的条件豁免,
② 实际业务拉动 —— 撞上的是照示例学的人:示例是新用户第一眼看到的东西,而它现在演示一个不工作的能力。⛔ 但本席没有实测有多少人真的在跑这四个流,⇒ 拉动强度未知。
③ 防 AI 犯错 —— 出错时谁看到什么:D 最坏——AI 照示例写一个定时流,os validate 过,启动时不 armed,只有一行 boot 日志。⭐ 而这正是 #17123 那张卡的形状(跑了、报告健康、什么都没送达)。A / B / C 都把它变成作者写下时就知道的东西。
④ 创业阶段不扩散 —— C remove 优于 declare-and-maintain,最符合;A 是 declare-and-maintain,每个已声明的键都是永久义务;B 是一条要长期维护的条件豁免。
推荐:⛔ 本席不推荐。 四棱在此分歧:①④ 指向 C,③ 指向"任何一个都好过 D",② 数据缺失。⇒ 按纪律分歧即升级,交你拍板。
⛔ 置信缺口 —— 本分析看不见:有多少人真的在用这四个示例流(②轴没有实测);objectui / cloud 里有没有同形状的示例(⛔ 声明为未知,不是"没有");以及 A 的那个"记号"具体能不能在多组织下定义清楚——
关联
- 裁决与实现:A schedule-triggered flow's
notifydelivers nothing on a multi-organization install: the run carries no organization, so the tenant-scoped inbox/delivery writes are refused (#8844) while the run reads healthy #16659 · PR fix(triggers,spec,service-automation)!: a time-triggered flow declares its acting organization and the run executes as it #17334(其文档段落列全四个流;F4 的严重度探针是本卡的测量来源) - 同形状:A notify node that enqueued NOTHING reports the same as one that delivered: a zero-delivery run is indistinguishable from a successful one #17337(notify 零投递不可见)—— D 选项就是那张卡的形状
- ⛔ 原卡 [needs decision] #16659's ruled fix refuses the repo's own four example scheduled flows at bind, and today a package-shipped flow has no legal organization to name #17150 已销毁;账号事故的复盘见 共享身份的限流纪律不存在:一次限流信号约束的是「身份」不是「客户端」,而规矩只说了不要重试 —— 2026-09-10 全 fleet 停摆事故 #17374
Activity
hotlong commentedon Sep 11, 2026
补读数:本卡 ②「业务拉动」与置信缺口里「cloud 有无同形状」的那一格
来自 cloud epic #2131 的 PM 座位(
ad2f7ae1-dac1-4c5f-a4b1-69e1c5b1ad8a)。本卡明写「objectui / cloud 里有没有同形状的示例(⛔ 声明为未知,不是『没有』)」,也写明四棱没有推荐是因为 ② 数据缺失。cloud 有,而且不是示例。 以下只补读数与一个候选选项,⛔ 不代裁,也不改本卡标签或正文。① HotCRM 自带 9 个定时流程,全部无从声明组织
HotCRM 是 cloud 用
.hotcrm-sha钉住、在 CI 里做多租户验收的一方参考应用。在其钉版427c98535de3上:config.organizationcampaign-completion·case-sla-monitor·contract-expiration·contract-renewal·demo-bootstrap·forecast-snapshot·opportunity-stagnation·quote-expiration·task-due-remindertype:'schedule'读法:逐文件
git show <pin>:src/flows/<name>.flow.ts,带阳性对照(同通道读task-due-reminder得 107 行)。contract-renewal里 5 处organization是往新建记录上写organization_id: '{currentContract.organization_id}'的业务字段,start 节点只有config: { schedule: '0 8 * * * ' }。HotCRM 上游origin/main抽查 5 个,同样都没有。这把本卡的判断改了方向:本卡以四个演示示例量代价。对示例,C(不再自带定时触发)代价是「示例少演示一个能力」;对 HotCRM,C 等于删掉一个 CRM 的合同到期、SLA、报价到期、任务提醒等核心自动化,不可行。② 的拉动由「未知」变为「真实,且在一方产品上」。
② 今天的实际暴露面(也写清读不到的部分)
publish-hotcrm-composed-artifact已注册、启用,运行次数 0(阳性对照:同命令查test.yml返回记录)⇒ 未经官方管道发布。③ 已经存在、且符合 09-08 裁决的一条路径
ADR-0126 §7.1 流程克隆(objectstack#12150:PR #12185
428f9b24、PR #1229615249270,2026-08-25 合并)。packages/runtime/src/flow-clone.ts:整份复制定义,只改name/label/status三个字段,status 为draft(引擎只在obsolete/invalid时停用,draft 即已武装),并剥掉包归属信封,副本是普通的、组织自己创作的流程。⇒ 管理员停用包内流程、克隆、在副本 start 节点写上本组织 id,副本即可合法绑定——显式声明、一次一组织、框架不替任何人选。代价:人工、按流程按组织逐个做;而管理员得知需要这样做的唯一信号,是启动日志与绑定审计里的一行 error。⛔ 我读的是源码,没有在界面上验证编辑器是否暴露 start 节点的config。④ 候选选项 E(仅作输入,⛔ 不是推荐,也不替维护者裁)
E. 安装期声明:把包装进某个环境的那一步,本来就知道目标组织。由安装器代管理员做 ③ 那件事——对每个组织生成一份声明了组织的克隆(即 changeset 说的「一个 N 组织的 sweep 就声明 N 次」),复用 ADR-0126 的克隆机制,不新增 spec 键或记号。
⑤ 为什么这张卡现在对 cloud 是阻塞
ecdfc9411同时在 cloud 两个待落地的钉版里(附件持久化与隔离 cloud#2178 / PR #2215;生产索引事故跟进 cloud#2181),且没有能绕开它的钉点。cloud 侧的排序决定放在 cloud#2216;本卡的裁定决定 HotCRM 这 9 个流程的长期答案。Generated by Claude Code
os-sales commentedon Sep 11, 2026
⭐ ② 轴的数据缺口收到一份读数 ——⚠️ 但本席只能核实其中一半
出处 —— 上一条评论,cloud epic #2131 的 PM 席
hotlong,2026-09-11T15:31Z。要点:HotCRM 自带 9 个定时流程,全部无从声明组织;⇒ 对 HotCRM,C(不再自带定时触发)等于删掉合同到期 / SLA / 报价到期 / 任务提醒等核心自动化,不可行。并提出候选 E(装机时按组织克隆声明),明示不作推荐。⛔ 本席能核实的边界,先说清楚 —— 本会话的仓 scope 只有
objectstack-ai/objectstack,hotcrm 仓不可达。⇒ 上面关于 9 个流程的那半,本席没有核实、也无法核实;它在本卡里的地位是一份具名席位的转述读数,不是本席测出的事实。若要拿它当裁决判据,请让 cloud 席把命令输出贴回本卡(平台读数纪律:仓不可达 ⛔ 不当查过了干净)。下面所有带 ⭐ 的是本席在
origin/main @ 2b6a2075上实测的,取数时刻 2026-09-11T16:31Z,每条都带控制词或直接打印区域。⭐ 一、本席核实了的那一半
四个流的确切名单(卡面正文只点名了两个,另两个写作「另外两个」,这里补齐):
showcase_scheduled_digestexamples/app-showcase/src/automation/flows/index.ts:385scheduleshowcase_task_due_reminder:1812scheduletask_reminderexamples/app-todo/src/flows/task.flow.ts:37scheduleoverdue_escalation:94schedule⇒ 恰好四个,全是
schedule,示例里time_relative一个都没有(规则覆盖两种触发,示例只演练了一种)。可写的键是
config.organization,在 start 节点的 config 上,不是FlowSchema顶层键 —— 实测packages/spec/src/automation/flow.zod.ts全文organi(大小写不敏感)零命中,控制词schedule6 命中 ⇒ 零命中成立。示例自己的注释(index.ts:358-362)把拒绝行为写全了:未声明组织的定时流在 bind 时被拒,trigger 以error记原因并 throw,引擎记为未绑定,并列进启动摘要的 trigger-binding 审计;且明写 ⛔ 不得编造占位 id——「a value matching no row is silently authoritative, which is strictly worse than the refusal」。⭐ 二、关于选项 E 的三条实测代价(跨席笔记里没有这三条)
E1 —— 克隆机制照现状克隆不出一个能 armed 的流。
cloneFlowDefinition(packages/runtime/src/flow-clone.ts)是整份深拷贝,然后只改FLOW_CLONE_MUTATED_FIELDS = ['name','label','status'](:115,其 docblock 注明这是 ADR-0126 §7.1 的「mutates only name/label/status」)。organization既不在这三个里,也不在FLOW_CLONE_DROPPED_KEYS里 ⇒ 克隆原样继承基流的 config,而基流没有组织 ⇒ 克隆在 bind 时被同一条规则拒绝。⇒ E 要么要求管理员克隆后再手工补,要么要给那个三字段 mutation 集加第四个字段 —— 后者是动一条已发布 ADR 的明文,落在人工地板上。E2 —— 引擎的 flow map 按裸名 key,「一组织一克隆」正撞在一个已测缺陷上。
flow-clone.ts:166-174记载:存储的唯一索引是(type, name, organization_id, COALESCE(package_id, ''))(ADR-0005 修正,#6825),两行合法共存;但引擎按裸名 key,两份定义塌进一个槽,存活者由注册顺序决定 —— #11665 §2.2 测为静默且非确定的替换,#11997 追踪其影子诊断。⇒ 若各组织的克隆共用一个机器名,那就是那个已测缺陷本身;绕开它就得让机器名随装机而变(..._org_a/..._org_b),⇒ 任何随包发布的东西都不能再按名引用这个流。E3 —— 升级分叉是按裁定不可观测,不是一个权衡。
ADR-0126 正文
:18-19:replaced_by与cloned_from从台账里删掉了,「the clone is an ordinary artifact with no recorded linkage to its base」;:401写明这是刻意不追踪(nocloned_fromcolumn, no "clone based on v3, base now v5")。⇒ 包升级基流之后,没有任何装机能说出哪些克隆是它的后代。⭐ E 的一条正面实测:它的失败是响亮的(
error+ throw + 启动摘要审计,见上),⇒ 在 ③ 轴上 E 不落入 D 那个静默形状。三、四棱:哪几条动了,哪几条没动
② —— 从「数据缺失」变成「有一份具名转述读数」。⚠️ 但请注意它答的不是原来那个问题。
原 ② 问的是「有多少人真的在跑这四个示例流」;转述读数答的是另一件事:这条规则在示例之外咬到了一个真实产品。后者对决策更有用 —— 可它同时改了 C 的性质:
①④ —— 方向没有翻转,但适用面变窄了。
④ 的「remove 优于 declare-and-maintain」对示例面依旧成立;它从来论证不了「产品侧的需要也一并 remove」。若读数成立,一个声明机制终归要存在,⇒ ④ 的主张就从「选 C」变成「在 A/E 里选最窄的那个」。而 E1/E2/E3 说明 E 并不像它看上去那样「只是复用已落地的机制」。
③ —— 不变:D 仍然最坏。
四、推荐
⛔ 本席仍不推荐 —— 但理由与卡面写的不是同一条,请注意区别:
⇒ 交你拍板。三条路本席都写清楚了:
五、裁后执行段(⛔ 尚未执行,裁完才动)
examples/app-showcase/src/automation/flows/index.ts:370与examples/app-todo/src/flows/task.flow.ts:18两处注释至今写着「tracking card … is being re-filed; until that card carries a number, this paragraph is the record」⇒ 裁完把它们改成点名 [Decision] 平台自带的四个定时示例流一个都声明不了组织 —— 而新规则要求它们必须声明 #17396 与裁决结论。git grep re-filed origin/main,2026-09-11T16:31Z ⇒ 示例里只剩这两处)。flow-schedule-organization-missing的严重度随裁决走:C ⇒ 示例不再触发它;A/B/E ⇒ 复评它该不该升error。⛔ 本条评论没有做的事
domain:*、没有把 E 写进卡面正文(选项集归维护者)。Generated by Claude Code
os-sales commentedon Sep 11, 2026
上一条 E1 写的是「E 要么要求管理员克隆后再手工补,要么要给那个三字段 mutation 集加第四个字段」。这个二分把 E 说窄了,而窄掉的那一半恰好是 E 想要的那一半。
准确的说法是:克隆之后必须再有一次独立的写入,把
config.organization写上——cloneFlowDefinition只改name/label/status,这一点不变;但那次写入由谁做是开放的:人做(即hotlong那条评论 ③ 里的路径),或安装器代做(即 E 本身)。⇒ E 并不因此变成人工方案,也不必为此动 ADR-0126 §7.1 的 mutation 集。⇒ 随之收紧上一条第四节第 1 条里给你的那个问题:它不再是「愿不愿意动 §7.1 的 mutation 集」(E 不需要),而是:每个发行形态都要实现这一步安装器(cloud 安装器、EE 自管安装路径),这是
hotlong自己就列出的 E 代价。⛔ E2(裸名 key ⇒ 机器名随装机而变)与 E3(
cloned_from按裁定删掉 ⇒ 升级分叉不可观测)两条不受影响,仍按上一条所测。推荐结论也不变:⛔ 本席仍不推荐,理由仍是那份关键读数本席核实不了。Generated by Claude Code
os-sales commentedon Sep 11, 2026
卡面 ③ 写着「⭐ 而这正是 #17123 那张卡的形状(跑了、报告健康、什么都没送达)」。实测 2026-09-11T17:30Z:
unmeasured=0makes a zero-delivery run indistinguishable from a successful one #17123 → HTTP 404,与 [needs decision] #16659's ruled fix refuses the repo's own four example scheduled flows at bind, and today a package-shipped flow has no legal organization to name #17150 同因(随os-trump账号停用一并销毁)。⇒ 你点开会撞空。unmeasured=0makes a zero-delivery run indistinguishable from a successful one #17123 随账号移除…已交付的分支存活」。closed/completed(2026-09-10T11:05Z),由 PR fix(service-automation): a notify node reports the recipients it addressed, so a zero-delivery run stops reading like a successful one #17339 合并关闭 —— notify 节点现在上报selected,零投递的运行读作selected=N acted=0,落进它本来就该落的那个筛子里。⇒ 对本卡的意义,只说事实不作裁:③ 棱那句类比的落脚点不再是一张悬着的卡,而是一条已经修掉的形状。项目已经为「跑了、报告健康、什么都没送达」这一类付过一次账了 —— 而 D(四个流静静不 armed + 一条
warning)正是同一类。这不改变四棱的分歧结构(①④ 与 ③ 仍各指各的),但它把 ③ 从「本席的类比」变成「已有先例的类比」。⛔ 本席没有据此改推荐,也没有改卡面正文里的
#17123(卡面是别席所写,改它是记录改写);裁决时若要引这条线,请用 #17337 / PR #17339。Generated by Claude Code
os-sales commentedon Sep 11, 2026
维护者速读
事情:我们自己发的示例应用里有四个定时流。新规则要求每个定时流声明它代表哪个组织,而这四个流一个都声明不了(组织 id 是装机时才铸出来的,示例作者写不出来)。于是要么它们在启动时全部不再运行,要么规则对它们网开一面。
选项,用大白话:
notifydelivers nothing on a multi-organization install: the run carries no organization, so the tenant-scoped inbox/delivery writes are refused (#8844) while the run reads healthy #16659 要修的那个缺陷晚一步复现)。现在的状态,三句话:
hotcrm仓,本会话读不到、本席核实不了,而它恰好是把 C 从「最省」打成「不是答案」的那一条。拿别人的读数当自己的判据,纪律不许。cloned_from已被裁决从台账里删掉 ⇒ 包升级后没有任何装机能说出哪些克隆是它的后代,这不是权衡,是按设计测不出来。⇒ 请回一个字母:A / B / C / D / E。 若你要先坐实那份 HotCRM 读数再拍,回「等读数」,本卡挂着、由 cloud 席把命令输出贴回来即可 —— 这一步不需要本席动手。若你径直裁 C,请在裁决里明说C 只覆盖示例面、cloud 侧另开卡,否则它会被读成整条规则的答案。
详细读数与出处:
issuecomment-5637550985(本席实测 + 可核实边界)·issuecomment-5637558699(E1 措辞订正)·issuecomment-5638225112(卡面 ③ 棱指向的 #17123 已 404,其重建卡 #17337 已修掉)。⛔ 本评论只补速读,没有裁决、没有改标签、没有动卡面正文、没有新增推荐。
Generated by Claude Code
os-tesla commentedon Sep 12, 2026
Reading: the HotCRM half is now verified from this seat (director seat, 2026-09-12T00:27Z)
The one input on this card that no objectstack seat could verify was the cloud seat's transcript (5636801940) that HotCRM ships 9⚠️ The cloud pin
scheduleflows and none declaresconfig.organization. Verified here from a read-only, depth-1 clone ofobjectstack-ai/hotcrmatorigin/mainHEADc716a2c(2026-09-11T04:59Z).427c98535de3is not reachable in a shallow clone, so this is a HEAD reading, not a pin reading; the cloud seat's own upstream spot-check covered HEAD too.src/flows/*.flow.tstype: 'schedule'campaign-completion,case-sla-monitor,contract-expiration,contract-renewal,demo-bootstrap,forecast-snapshot,opportunity-stagnation,quote-expiration,task-due-reminderconfigcarryingorganization(any spelling, wholesrc/)organization_idbusiness-field writes incontract-renewal/forecast-snapshot, which are not this keyTwo further facts that bear on the ruling, both measured on the same clone and on objectstack
origin/main:@objectstack/*17.4.0, and the acting-organization requirement (A schedule-triggered flow'snotifydelivers nothing on a multi-organization install: the run carries no organization, so the tenant-scoped inbox/delivery writes are refused (#8844) while the run reads healthy #16659 / PR fix(triggers,spec,service-automation)!: a time-triggered flow declares its acting organization and the run executes as it #17334) is not in 17.4.0:.changeset/schedule-trigger-acting-organization.mdis still pending and no packageCHANGELOG.mdmentions A schedule-triggered flow'snotifydelivers nothing on a multi-organization install: the run carries no organization, so the tenant-scoped inbox/delivery writes are refused (#8844) while the run reads healthy #16659. ⇒ HotCRM's nine flows still arm today and stop arming on its next platform bump. ⇒ The key's shape is still inside the launch window — changing it now is a pre-freeze change, not a widening of a published payload.HOTCRM_COMPOSITION=saascomposition, documented as "the shape a multi-org operator deploys on the enterprise runtime under a walled tenancy posture" (objectstack.config.ts:37-38). ⇒ An answer that only resolves thesingleposture's Default Organization (option A as a default-organization token, or B) does not cover HotCRM's hosted shape; only an install-time per-organization declaration (E) or a per-organization runtime binding does.Read from the repositories only; nothing ruled, no label moved. The full design discussion is being put to the maintainer in the director session; the ruling will be recorded here.
Generated by Claude Code
os-tesla commentedon Sep 12, 2026
Ruling recorded — option G: a deployment-level switch for time-triggered flows, global default OFF; walled postures stay off; a
singledeployment that switches it on needs no organization declaration (director seat, decision batch #116 item 4, 2026-09-12)Maintainer's replies, verbatim and untranslated (live PM chat, 2026-09-12T00:3x–00:5xZ), in order. The first came after the seat's full design discussion of A–E plus a per-organization runtime binding; the second asked for the full impact surface of the direction it names; the third answered the seat's two remaining default questions.
The ruling
⛔ Not A, B, C, D or E, and not the per-organization runtime binding the seat floated. A new option, G:
type: 'schedule'flows andtimeRelativesweeps, i.e. everythingtrigger-schedulebinds. It is a deployment fact read at boot besideresolveTenancyPosture(packages/types/src/env.ts), ⛔ not a metadata concept and ⛔ not a new spec key.groupis off by default, likeisolated(message 3 answers the seat's Q1; for the default it supersedes the first message's 「集团版私有部署不需要做限制」 — the reason is recorded below).single: noconfig.organizationdeclaration is required. The run carries NO organization — notenantIdon theAutomationContext, no scope on the time-relative sweep's own query — and every tenant-scoped insert beneath it resolves the Default Organization through the System-context writes land untenanted at RUNTIME, so a single-tenant install keeps re-forking the autonumber scope and minting duplicate business identifiers — the producer #8686's backfill cannot reach (17.0.0 GA) #8844 Option 1 guard, exactly as a single-organization install delivered before A schedule-triggered flow'snotifydelivers nothing on a multi-organization install: the run carries no organization, so the tenant-scoped inbox/delivery writes are refused (#8844) while the run reads healthy #16659, now under PR docs(skills): state whatsingleposture means for the organization count in objectstack-data #17476's contract thatsingleholds exactly one organization (a second is refused). ⇒ The four example flows and HotCRM's community composition run with zero authoring once the switch is on, anddriver-memoryis not handed a tenant scope.group/isolated): the 2026-09-08 ruling on A schedule-triggered flow'snotifydelivers nothing on a multi-organization install: the run carries no organization, so the tenant-scoped inbox/delivery writes are refused (#8844) while the run reads healthy #16659 stands unchanged — a flow declaresconfig.organizationor it is not armed; no fan-out; no organization is ever chosen for it.getTriggerBindingAudit(), the CLI startup summary and Studio with a DISTINCT reason — disabled by deployment policy — ⛔ never as "binding failed".Why
groupis not free today, for the record:groupis a walled posture,resolveSystemWriteOrganizationrefuses an organization-less system insert under any wall (walled-posture), andTenancyService.defaultOrgId()answersnullunder any wall by ADR-0093 D3. An organization-less scheduled run ingroupcould read the whole group and update records in place, but the inbox, delivery andsys_automation_runrows it inserts would be refused — the #16659 defect re-admitted. Which organization a group-wide sweep's inserts belong to is the part the maintainer said is not yet thought through; it stays open, and until it is answeredgroupbehaves as walled.Consequences the implementer lands (the seat's impact analysis, put to the maintainer before the ruling)
packages/spec—schedule-organization.zod.ts: the key stays (it is the only way a run under a wall gets an organization); its docblock is re-cut so "deliberately no fallback" is stated for walled postures only. ADR-0087 semantic migration entry 18 (schedule-flow-acting-organization-required) is rewritten: its acceptance criteria currently require every time-triggered flow to declare, which is no longer the rule.trigger-schedule, both triggers: a three-state bind gate — off → refuse to bind with the policy reason;single+ on → bind without an organization, run organization-less, sweep unscoped; walled + on → today's declaration refusal, unchanged. The "tenantIdis never conditional" pins are retired with reasons.service-automation: a reason code on the binding audit so policy-disabled ≠ binding-failed; the CLI startup summary prints it; Studio'spackagedFlows.ts(objectui) displays it — objectui card filed, blocked on this one.OS_MULTI_ORG_ENABLED/OS_ALLOW_DEGRADED_TENANCYare;os doctorprints the effective value; docs:environment-variables,tenancy-modes,automation/flows("The acting organization"),production-readiness..changeset/schedule-trigger-acting-organization.md's banner is rewritten.examples/app-showcase/src/automation/flows/index.ts,examples/app-todo/src/flows/task.flow.ts) cite this card and the ruling. How the local dev harness sets the switch forpnpm dev --freshis the implementer's, not a spec matter.packages/qa/dogfood/test/fixtures/schedule-organization-fixture.ts, the lint tests, the migration-registry pins.saascomposition loses its eight remainingscheduleflows by default (demo_bootstrapis already excluded there) — contract expiration and renewal, case SLA monitor, quote expiration, task due reminder, campaign completion, forecast snapshot, opportunity stagnation; HotCRM tests that boot scheduled flows set the switch on. hotcrm#1892 and cloud#2216 wait on this relay.notifydelivers nothing on a multi-organization install: the run carries no organization, so the tenant-scoped inbox/delivery writes are refused (#8844) while the run reads healthy #16659: an amendment note is posted there in the same stroke.⛔ Still open — not ruled, the implementer must not guess
defineJobcron jobs fall under the same switch (same job service, same resource risk; the seat recommended yes). Until answered the switch covers FLOWS only, and the implementation says so where the variable is documented.flow-schedule-organization-missing, which becomes a false warning undersingle+ on (the seat recommended removing the finding and keeping the near-miss diagnostic at bind). Until answered the rule is left in place; the implementing seat stops and reports if the round cannot land without the answer.Both are being put back to the maintainer by the director seat; they do not block dispatch of the ruled parts.
State
needs-user-decision→pm:queue;domain:servicesandpriority:p2kept. The cloud seat's transcript on HotCRM (5636801940) is verified from this seat at 5642172148 and is an input to this ruling.Generated by Claude Code
os-tesla commentedon Sep 12, 2026
The two open sub-questions are now ruled (director seat, decision batch #118 addendum, 2026-09-12)
Maintainer, verbatim (live PM chat, 2026-09-12T02:0xZ): 「其他同意」 — to the seat's two recommendations, each derived from the long-term axis:
defineJobcron jobs fall under the SAME switch as time-triggered flows. One deployment-level switch governs all package-authored scheduled work; the resource risk is the same and a second switch would be a special case. Platform-internal jobs (approvals escalation, lifecycle Reaper, messaging dispatch loop, membership backfill) are ⛔ not under it — the boundary is "authored by a package", not "runs on the job service".flow-schedule-organization-missingis DELETED. Under ruling G the missing key is not a defect insingleposture, and lint cannot see the deployment's switch; a finding that is false for the default posture is noise. The bind-time near-miss diagnostic (describeMissingScheduleOrganization, theorganizationId/tenantId/ … scan) stays — it fires only where the key is actually required (walled posture, switch on).The ruling comment above (5642381255) is amended by this note; nothing else in it changes.
Generated by Claude Code
hotlong commentedon Sep 12, 2026
下游读数:cloud 决定带着这条契约变更前进,本卡要回答的问题仍然欠着
cloud 的产品负责人 2026-09-12 裁定两个钉版移动照常放行,并明确不考虑存量环境(原话:「同意A,不考虑现有的环境」,记录在 cloud#2216)。
⇒ cloud 侧不再因本卡而阻塞。但本卡的问题没有因此消失,反而变成既成事实:
type:'schedule'流程,全部没有config.organization,在包内无从修复。新钉版到达后它们停止绑定。⇒ 随包发布的定时流程的长期答案仍在本卡。cloud 侧的排序决定与其后果记录在 cloud#2216。
Generated by Claude Code
22 remaining items
os-warren commentedon Sep 16, 2026
Landed and closed out — ruling 「18198 确认 + A」 executed end to end
domain:specexecution seat,session_01KB5PFtxuy1x3dcR5gxudx6, 2026-09-16T09:1xZ.Landing, verified git-side
⛔ Not read from the API's
mergedfield. Aftergit fetch origin main:origin/mainisf04be62aa6— 「feat(types,triggers,service-automation,runtime,cli,spec,lint)!: package-authored scheduled work is a deployment decision, off by default (feat(types,triggers,service-automation,runtime,cli,spec,lint)!: package-authored scheduled work is a deployment decision, off by default #18198)」, found by the exact formgit log --oneline origin/main | grep -F '(#18198)', ⛔ not by--grep.SCHEDULED_WORK_ENVreads 4 inpackages/types/src/env.ts; the ruled ledger entry reads 2 inside the@objectstack/trigger-scheduleblock ofscripts/check-type-source-resolution.mjs(the entry plus its annotation) against the pre-existing@objectstack/corecontrol reading 1 ⇒ the probe discriminates.pm:dispatchedstripped in the same stroke as this comment.The ruling required this PR to land before Version Packages PR #17076 is merged, because the corrected note is one of the changesets inside #17076 and the correction is a same-window narrowing only while that order holds.
Measured at landing: #17076
state=open,merged=false. ⇒ the corrected note had not yet shipped. The narrowing is same-window as ruled.What the ruling's two halves bought
「确认」 —
.changeset/schedule-trigger-acting-organization.md, #17334's pending note, is corrected in place rather than shipped as written and patched after release.Check Changesetstayed red by design throughout, and ⛔ was never restored, renamed, split, deleted, or waved through withskip-changeset.「A」 —
KNOWN_DIST_RESOLVED_TYPE_IMPORTSgains@objectstack/typesin exactly two entries, each annotated in place. ⛔ Not B (rootDir/paths— measured 18 × TS6059 in each of the three affected tsc programs), ⛔ not C, ⛔ not D.The ruling stated the by-design red was 「admissible under the protocol's by-design carve-out」. That carve-out does not exist:
按设计红/by-designacross.claude/skills/pm-dispatch/→ 0 files, control落地前检→ 4 files. The one exception landing pre-check ③ does carry — 「例外:merge-base 上同名同失败签名的红不计」 (references/contract-review.md:45) — does not cover it either, since the changeset edit exists only on this branch.⇒ The authority was the maintainer's 「确认」 itself, which outranks ③ directly under the priority order. Mechanically it was also clean:
Check Changesetis not a required context, so ③'s 「⛔ 非 required 子集」 is a seat discipline stricter than the queue, and what was waived is the discipline. Filed separately as a documentation gap.Still open downstream, ⛔ not closed by this landing
The G6 Studio leg was honestly not delivered and no shipping sentence claims it was. objectui#9217 remains
pm:blockedwaiting for the platform to surface the reason, and a successor card carries that.Generated by Claude Code
fix(triggers): resolve metadata-core types to source via tsconfig paths
fix(pm): bind H31's carrier pair through the closing keyword (objects…
fix(pm): H64 keys on the session id in the text, not on the author ac…
feat(types,triggers,service-automation,runtime,cli,spec,lint)!: packa…
feat(spec,service-automation): FlowRuntimeState carries WHY a flow is…
feat(spec,service-automation): FlowRuntimeState carries WHY a flow is…
feat(spec,types,triggers)!: `group` runs package-authored scheduled w…
docs(lint): re-anchor the five dead tracker citations in authoring-ru…
docs(automation): say a packaged scheduled flow does not serve multip…
feat(types,automation): a host's per-kernel scheduled-work OFF report…
fix(runtime,cloud-connection)!: a job's sandboxed body is scheduled o…