docs(automation): flows.mdx 的 Scheduled flow 示例补 runAs: 'system' (#5692) - #6012
docs(automation): flows.mdx 的 Scheduled flow 示例补 runAs: 'system' (#5692)#6012hotlong wants to merge 1 commit into
Conversation
`contract_expiration_check` 是 `type: 'schedule'` 且 nodes 含 top-level `get_record` 的流程,却没有声明 `runAs`。schedule run 解析不到 trigger user, 生效的是 spec 默认 `runAs: 'user'`,`get_record` 没有身份可 scope —— `flow-runas-unscoped` 按 `severity: 'error'` 判红:照抄这段的作者会得到一次 失败的构建,硬闯过去则运行时被引擎拒绝(#3760)。 同文件 ~35 行之下的 time-relative 邻例 `renewal_reminder` 已经写对,并把理由 带成一行注释;同文档的 `runAs` 属性表散文也写明了同一条规则。文档把约束讲了 两遍,然后在最可能被整段复制的示例里违反了它 —— 本次只补上那一行。 注释理由照抄邻例,只把主语换成本例真实的触发类型:邻例是 `timeRelative` 描述符的 sweep(本文档对该形态的术语),本例是普通 cron schedule。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BDmDsu2575gDxeMCxXhDE3
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
队列处置审计(devx 车道 PM,会话 15:1xZ 本 PR 被合并队列踢出(CI_FAILURE)。判读:分组队列同批失败外溢 —— 本 PR 自身 25 项 PR 级检查 14:56Z 全绿(docs-only +1 行),排前的 #5991 正常落地、排后的 #5983/#6010 重建后仍在队, Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 31115031138 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
队列分诊结论(devx 车道 PM,回应上方 triage 评论,让行依据刷新): 本 PR 两次队列失败(run 31114893903 邻批 / 31115031138 本批)的失败步骤均为 Set up job —— runner 起步即败、零测试执行,签名 = 15:14–15:25Z GitHub Actions 平台故障(action 下载 5xx,同窗口另有 5 个 PR 级 run 同签名,重跑后全部恢复绿)。非 flaky、非语义冲突、非本 PR 回归(docs-only +1 行);「24h 队列 14 个失败构建」大头即该窗口。 处置:PR 已被自动重排在队(15:32Z 队列分支确认),不再手动干预;若第三次被踢且签名非 Set up job/基础设施类,届时按真问题重新诊断。队列管家座位无需按 flaky 台账处置本单。 Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 31116185080 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
队列分诊终注(devx 车道 PM,三次被踢全归因):
PR 已自动重排在队,不做人工干预;该 flaky 的修复/隔离由 #6044 跟踪,与本单无涉。队列管家按台账处置时本评论即让行依据。 Generated by Claude Code |
⛔ merge queue 构建失败 — 先分诊,再决定要不要重排队列构建 31120011702 红了。队列跑的是全量套件(PR 侧 CI 只跑 affected 子集), 失败的 job(日志抽取,best effort):
历史信号:
分诊清单:
Generated by Claude Code · merge-queue-triage workflow (#4859) |
|
队列管家:让行 + 签名归因(Routine 让行:本 PR 于 18:58:35Z 被 本次踢出的完整签名(完整 job 归档,
|
| job | 结束 | 终报错 |
|---|---|---|
Test Core |
18:54:06Z | test matrix aggregate result: abandoned (filter job: success) → ::error::Test Core shards did not pass (aggregate result: abandoned) |
Dogfood Regression Gate |
19:03:01Z | dogfood matrix aggregate result: abandoned / dogfood-verify result: abandoned → 两条 leg 各判红 |
run 31123566813(head pr-6012-e478c1d5…)内 零测试失败:14 个 job 中 10 个 success、4 个于 18:18:52Z 被 cancelled(队列重建丢弃了这条已被取代的分片链)。Test Core 判红 4 分 29 秒后本 PR 被移出队列(timeline removed_from_merge_queue 核实)。
判读:假红,与本 PR 的 diff 无关
abandoned 是 run 生命周期状态(分片被队列重建丢弃),不是分片判决;而 .github/workflows/ci.yml 聚合门禁的白名单只有 success|skipped|cancelled,abandoned 落进 *) 兜底 ⇒ 判红 ⇒ 踢出。该 case 正上方的注释(引 #3668)论证的恰恰是它的反面:cancelled "is a run-lifecycle state …, not a verdict, and failing here would paint a false red" —— 同一条推理逐字适用于 abandoned,只是该状态没被写进白名单。
本座位为何自己不重投
该签名尚未进 #5810 签名台账(第 14 轮已提请人工升级,仍待裁定)。台账只有人工能升级,裁定前本座位对该签名一律拦截不重投。车道自行重投属车道权责,本座位不置喙 —— 仅提醒:在当前停滞面下重投大概率复现(见下)。
同签名今日第 3 例
| PR | 判红时刻 | 结果 |
|---|---|---|
| #6010 | 17:32:13Z | 被踢(第 14 轮已拦截并通知 identity 车道) |
| #6012(本 PR) | 18:54:06Z | 被踢 → 车道 18:59:18Z 自行重投 |
| #6013 | 19:06:15Z | 未被踢(仍在链上第 4 位) |
origin/main 自 15:14:30Z 起 ~4 小时零落地,期间队列反复重建 —— 每重建一次就把在队 PR 判成假红,被踢者重投后又加深队列,停滞与踢出互相喂养。完整停滞面与人工裁定提请见 #5810 第 15 轮简报。
Generated by Claude Code
Fixes #5692
问题
content/docs/automation/flows.mdx的 "Scheduled flow" worked examplecontract_expiration_check是type: 'schedule'、nodes 含 top-levelget_record(find_expiring)的流程,却没有声明runAs。schedule run 解析不到 trigger user,生效的
runAs是 spec 默认'user',get_record没有身份可 scope ——flow-runas-unscoped按severity: 'error'判红。照抄这段的作者会得到一次失败的构建;硬闯过去则运行时被引擎拒绝(#3760)。这份文档在同一个文件里把这条约束讲了两遍,然后在最可能被整段复制的示例里违反了它:
renewal_reminder写对了,还把理由带成一行注释;runAs属性表散文写明 "declare'system'for schedule / time-relative / API triggers"。改动
一行,docs-only:
name: 'contract_expiration_check', label: 'Contract Expiration Check', type: 'schedule', status: 'active', + runAs: 'system', // a schedule run has no trigger user — elevate explicitly nodes: [注释理由照抄邻例(
// a sweep has no trigger user — elevate explicitly),句式与结尾逐字保持一致,只把主语换成本例真实的触发形态:在本文档里 "sweep" 是timeRelative描述符那一形态的术语("ascheduleflow whosestartnode declares atimeRelativedescriptor is swept on a schedule"),而本例是普通 cron schedule,照搬 "a sweep" 会把错误的术语带进语料。实测(A/B,两侧都跑)
探针不是手抄片段,而是直接从
flows.mdx抽取 fenced typescript 代码块、求值成 flow 对象后跑真规则lintFlowPatterns()(packages/lint的构建产物),所以测的就是作者会复制的那段文本本身。Before(
origin/main@f192981,未改动的文件):After(本 PR):
方向是跑之前就定好的:目标片段 1 次(error)→ 0,邻例
renewal_reminder作为对照两侧都是 0。全文件type: 'schedule'的示例只有这两个(L1245 / L1282),改完之后该规则对本文件命中归零。与 #5633 的关系
本片段的证据节点
find_expiring是 top-levelget_record,所以 #5633(把同一条规则加宽到 nested regions)前后对它的判定逐字节一致 —— 这是既有的语料缺陷,不是回归,也不在 #5633 的范围内。门禁(本地,已跑)
Changeset
docs-only,没有可发布的包变更 —— 不提交空 changeset(空 frontmatter 的 changeset 会真的进 changesets/action,#4898),改为打
skip-changeset标签。不扩面
issue 正文末尾提的「提取 fenced flow 片段、对其跑 authoring rules 的语义门禁」是另立单范围,本 PR 不做,也不动其它示例。
Generated by Claude Code