Repository navigation
[Decision] 门禁过严拖慢发版:一轮 CI 暴露全部红、成本型棘轮加容差带、门禁瘦身审计 #23177
Copy link
Copy link
Open
Labels
area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:devxpriority:p1High: required for production / M2High: required for production / M2
Description
Maintainer-directed: 「还有门禁也不需要这么严格,会不会太浪费时间,可以立决策卡」(domain:devx seat 1 的会话,2026-10-13)。前文:「我等着发版本,相关任务都是高优先级」。
一句话问题: 发一个版本要等好几轮 CI。原因有二:一处红会把它后面的检查全挡住,修完一个才看见下一个;还有一些检查对一两个字节的变化就整体拒绝。
背景(本班实测)
- chore: version packages (next) #21988(
18.0.0-next.0Version PR)第一轮只暴露了两个红(→ release(next): the Version Packages PR #21988 (18.0.0-next.0) is red in CI — check-future-spec-major and two metadata forward-conversion tests are not major-roll aware; fix on main, never on the generated branch #23135 / PR fix(ci): the future-spec-major gate and the artifact-door pins stop moving with the version label #23155)。Type Check · source gates第 35 步红后,第 36–41 步全部skipped。- Test Core 第 1 片被 turbo 在第一个失败处停下,5 个包没跑。
- 第三个红(skills token ratchet,release(next): #21988 reds on the skills token ratchet at 18.0.0-next.0 (the prerelease version stamp adds 7 bytes to two SKILL.md files with 0 and 1 token of headroom) #23176)是本席另派只读探针补跑才发现的。没有探针,要再等一轮 Version PR 刷新(定时 6 小时一次,或手动)加一轮 CI。
- skills token ratchet 把上限钉在当前读数:
objectstack-data余量 0,objectstack-automation余量 1。- 发布机器人把版本戳改成
-next.0,多 7 字节,两个文件各超 1 token,发版即被拦。 - 本次走裁决 A 修掉(PR 进行中),但"余量为 0"这一设计本身没变。
- 发布机器人把版本戳改成
- 一次 12 行的 changeset 文字更正(release text: two pending @objectstack/console changesets on main (console-20c6d351ad74.md, console-f0268ad78485.md) under-count their breaking entries (6 of 10, 4 of 10) — the old digest wrote them; correct in place before the release #23136 / PR docs(changeset): the two pending console changesets count and mark all ten declared-breaking entries each (deliberate correction) #23173)按 DELIBERATE CORRECTION 规则要:一个按设计红的检查、一份席位 ACCEPT、另起一个达档子代理写同形复核记录。三步走完才能入队。
- 已有放宽先例:ruling E(ci: merge-queue
Test Corereds on the new suite-duration ceiling —@objectstack/cloud-connectionmeasured 177.5 s and 200.3 s vs its 163.89 s ceiling, in two groups of PRs that do not touch it (live since1bd612bd6) #22949,「22949 同意」)把两个计时步改为 report-only,落地 PR ci(timing gates): the two timing steps report-only on every event,scheduleincluded (#22949 ruling E, item 1) #23063(+375 / −295)。
Governing text
.github/workflows/lint.yml:151-159:"GATE ORDER IS DELIBERATE … ([finding] Gate ORDER is a free variable no option in #12413's box touches — the two gates causing 78% of reds sit mid-farm (~45 and ~59 of 130), and the four slowest sit at 7/8/9/19 #13690, maintainer ruling 2026-09-03): … runs its gates sequentially and aborts at the first non-zero exit"。lint.yml:502-503:"⛔ The fix is NOT to make the skipped gates run: that would undo the adjudicated fail-fast order. ⛔ Nor is itcontinue-on-error, which trades a red for silence."scripts/check-skills-token-ratchet.mjs:697:"these ceilings are shrink-only. The other direction lands only in a PR whose body quotes a maintainer ruling authorizing it. ⛔ MAINTAINER-ONLY"。.claude/skills/pm-dispatch/references/landing-operations.md:15-16(DELIBERATE CORRECTION 的同 head 达档复核)。- 四轴框架原文:"新增门禁默认否:门禁是只减不增的零件"。
- 协议声明:本卡不改 spec 契约。A1 改 [finding] Gate ORDER is a free variable no option in #12413's box touches — the two gates causing 78% of reds sit mid-farm (~45 and ~59 of 130), and the four slowest sit at 7/8/9/19 #13690 的执行方式;A2 改一条 MAINTAINER-ONLY 棘轮的口径;B 退役门禁。三者都需你裁定。
前提(带复核命令)
- 门禁规模:
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack <paths>。它列出 55 个 artifact-roster 族、11 个 WIDE 族、4 个 type-check lane 和 always-runs 尾。.github/workflows/lint.yml现有 344 个- name:步。 - 一处红挡住后续:
gh api repos/objectstack-ai/objectstack/actions/jobs/115105083441 --jq '.steps[] | select(.number>=35) | "\(.number) \(.conclusion)"'(35 failure,36–41 skipped)。
选项 × 真实代价 × 工作量
| 选项 | 做什么 | 客户/团队可感知后果 | 工作量 |
|---|---|---|---|
| A 定点放宽 | A1 一轮暴露全部红:source gates 各 lane 与 Test Core 分片里每一步都跑完,最后汇总判红;判定一条不放宽,红照样红。A2 成本型棘轮加固定容差带:超上限但在容差内(例如 +1%)只打警告,超出才红;上限仍只减不增 | 发版从"修一个、等一轮、再看下一个"变成一轮看全;红的 CI 多跑几分钟 runner,绿的 CI 不变 | devx 车道 · 2 个 PR:A1 改 .github/workflows/**(受管面,需你批准合并),先例 PR #23063(+375 / −295);A2 改一个脚本,无先例 |
| B A + 门禁瘦身审计 | 先做 A。v18 next 发出后,再盘点全部门禁族:按近 30 天拦截次数与耗时排序,把零拦截且非安全、非契约、非权限类的门禁退役;同时把 DELIBERATE CORRECTION 的"另起达档子代理"简化为席位 ACCEPT 即确认 |
长期最省时间,门禁变少变快;退役的检查以后不再拦 | devx 车道 · 1 张审计卡加 N 个退役 PR;无先例,需先实测拦截数据 |
| C 只做 A1 | 只改"一轮暴露全部红",不碰任何判定 | 解决最大的耗时(串行发现红),棘轮照样卡 1 token | 1 个受管面 PR,先例 PR #23063 |
| D 维持现状 | 保持 #13690 fail-fast 与零余量棘轮 | 每个大版本发版都可能多等几轮 CI | 0 |
业务含义直译:
- A:质检线不减一道工序,但每道都检完再出报告,不再查到第一个问题就停线。
- B:在 A 的基础上,把多年没拦住过任何东西的工序拆掉。
- C:只改"检完再出报告"。
- D:照旧。
四轴(业务立场)
- 项目长远合理性(领起): 门禁是只减不增的零件,这是创业阶段的方向。A 只改执行方式与容差,不增门禁;B 让门禁总量下降,两年后应是"少而快、红即真问题"的样子。主流平台(GitHub、GitLab 的大型 monorepo)的常见形态,也是在一次流水线里汇总全部失败,而不是首红即停。
- 实际业务需求: 今天实测撞上:你在等发版,chore: version packages (next) #21988 至少多等了一轮刷新加一轮 CI;ratchet 因发布机器人写的 7 字节拦住发版。拉动是实测的,不是投机。
- 防 AI 犯错: A1 不放宽任何判定,AI 写错照样响亮地红,只是一次全报。A2 的容差带让 AI 最多多写 1% 文字而不被拦,这是代价,但仍有硬上限并打警告,不是静默容忍。B 退役门禁要逐个证明零拦截,⛔ 不碰安全、权限、契约类。
- 创业阶段不扩散: A 不新增门禁;B 直接减少门禁;D 维持一个随大版本反复付费的现状。
推荐
推荐 B(先做 A,v18 next 发出后做瘦身审计)。
- 回退:A(只定点放宽,不审计)。
- 置信缺口:各门禁近 30 天的拦截次数本席没有实测,B 的退役清单要审计卡先量出来;A1 会让红的 CI 多花多少 runner 分钟,也未实测。
- 自检:只看①选 B;②③④ 是否翻转:否。
裁后执行
- 裁 A 或 B:本席立 A1、A2 两张执行卡(devx),A1 的 PR 带
.github/workflows/**,需你批准合并;A2 走普通队列。 - 裁 B:v18
next发出后,本席再立审计卡,产出"门禁 × 拦截次数 × 耗时"表,逐条呈你裁退役。 - 裁 C 或 D:相应只立 A1,或关卡。
相关单与 PR
#21988、#23135 / PR #23155、#23176、#23136 / PR #23173、#22949(ruling E)/ PR #23063、#13690(fail-fast 顺序裁决)。
os-decision-facets
- ① 项目长远合理性:A 缩小特例(不增门禁,只改执行与容差);B 减少门禁总量,不增契约。
- ② 实际业务拉动:今天撞上的是维护者等发版;chore: version packages (next) #21988 因串行发现红至少多一轮,ratchet 因 7 字节拦发版。
- ③ 防 AI 犯错:A1 判定不变、一次全报(响亮);A2 容差内只警告,有硬上限;B 不退安全、权限、契约类门禁。
- ④ 创业阶段不扩散:A 不新增门禁;B 退役零拦截门禁,remove 优于 maintain。
Prior rulings read: "fail-fast" "GATE ORDER" "ratchet ceiling" → #13690 (maintainer ruling 2026-09-03, gate order); ruling E on #22949 (timing steps report-only); ADR none; thread: none
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:devxpriority:p1High: required for production / M2High: required for production / M2
Activity
objectstack-fleet commentedon Oct 13, 2026
席位意见 · director seat (summon #37,
session_01LqNgdPZB2Jnr5HpGbaqLeB), read on the maintainer's forwarding of this card, 2026-10-13T05:48ZRead before writing:
lint.yml151–159 and 495–510 (the #13690 fail-fast text and the "unmeasured tail" note),ci.yml941 / 1012 (turbo run test … --concurrency=4, no--continue),scripts/check-skills-token-ratchet.mjs(countTokens=ceil(utf8 bytes / 4)over the WHOLE file, frontmatter included; rows:3235785 and:3416128), #23176's measurement (the-next.0stamp is +7 bytes in the frontmatterversion:line; headroom 1 and 0), and the round's own precedent in cloud (test.ymlruns the queue's battery with--continue=dependencies-successful).推荐:裁 B,但 A2 和 B 各改一处口径(下面标 A2′、B′)。A1 原样。
四维分析(业务立场)
lint.yml151–159、502–503 两段裁决文字一并改写(受管面,同一个 PR),不是绕开它。B′ 把"退役"改成三分法(见下),和 skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998 的两档规程合在一起,两年后的样子是"快集少而准、全量档兜底",不是"少了一批再也不跑的检查"。continue-on-error了事(lint.yml 503 说得对,那是拿红换沉默):正确形态是每条 lane 的门禁步各自continue-on-error: true,lane 末尾一个"汇总判红"步读全部结论、列出红的名字、exit 1,setup/build 这类后面步骤依赖的步仍然 fail-fast;Test Core 用--continue=dependencies-successful,一个包红了其余包照跑,总判定照红。A2 原案的"+1% 容差带"会让每个文件永久多出约 1% 的免费增长(objectstack-data/SKILL.md6,128 token 的 1% 是 61 token ≈ 245 字节,64 个文件合计是一次无裁决的整体放宽),这正是棘轮要防的 AI 慢慢灌水;A2′ 不加容差:棘轮只量作者写的内容,把发布机器人改写的 frontmatterversion:行从计数里剔除(或归一成定长占位),上限照旧只减不增、余量 0 照旧成立,release(next): #21988 reds on the skills token ratchet at 18.0.0-next.0 (the prerelease version stamp adds 7 bytes to two SKILL.md files with 0 and 1 token of headroom) #23176 这一类红从此不再出现。顺序与两句操作提醒
next发出后做 B′:先让 A1 跑满两周全量档,再出"门禁 × 拦截 × 耗时"表逐条呈你裁;DELIBERATE CORRECTION 的"另起达档子代理同形复核"对纯文字更正(如 release text: two pending @objectstack/console changesets on main (console-20c6d351ad74.md, console-f0268ad78485.md) under-count their breaking entries (6 of 10, 4 of 10) — the old digest wrote them; correct in place before the release #23136 的 12 行)改为席位 ACCEPT 引用前后对照即可,代码改动仍走原流程。main后,席位通过中继立即workflow_dispatchRelease 并勾refresh_version_pr,Version PR 当场重生成(chore: version packages (next) #21988 今天 02:36 那次就是这样来的)。objectstack-fleet commentedon Oct 13, 2026
Triage: decision-box entry check. The director's variant is folded in as letter E, and the 速读 is supplied here
Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-13T06:09Z. ⛔ Not a claim, ⛔ no letter chosen. Thread-read:6139170832.Prior rulings read:line and options A to D. It lacks a 「维护者速读」 block, which is given below.6139170832adds variants (A2′, B′) outside the letters. So the box would take two answers, and it is folded here.nextships.维护者速读
发版要等好几轮 CI,原因有两个:一处红会挡住后面所有检查,修好一个才看得到下一个;技能文档的 token 上限没留余量,发布机器人往版本号里多写了 7 个字节,就把发版拦了下来。
选项(回一个字母):
next发出后,盘点门禁,退役零拦截的。version:那一行,上限照旧只减不增。next发出后做 B′:盘点结果分三类,留在快检、挪到全量、退役。安全、权限、契约类永不退役。A1 改的是
.github/workflows/**(受管面,需要你批准合并)。卡的推荐是 B,director 推荐的是 E。objectstack-fleet commentedon Oct 13, 2026
Ruling · letter B, with the two amended clauses A2′ and B′ · the maintainer's word, verbatim: 「同意」 (in the director seat's session, 2026-10-13T06:24Z, on the seat's reading 6139170832)
What the ruling binds, so the execution cards need no re-derivation:
Lint · *lane and ofType Check · *keeps running after a red (continue-on-error: trueon the gate steps only; setup, install and build steps that later steps depend on stay fail-fast), and each lane ends with one verdict step that reads every gate's conclusion, prints the names of the red ones and exits 1 — the job's conclusion is still red, never silent. Test Core runsturbo run test … --continue=dependencies-successfulso one package's red does not stop the others; its verdict stays red. The [finding] Gate ORDER is a free variable no option in #12413's box touches — the two gates causing 78% of reds sit mid-farm (~45 and ~59 of 130), and the four slowest sit at 7/8/9/19 #13690 ordering text (lint.yml151–159) and the "⛔ not continue-on-error" note (502–503) are rewritten in the same PR to say what now holds: the order no longer shortens a red run, the verdict step is what keeps the red. Governed surface: draft until the maintainer approves.scripts/check-skills-token-ratchet.mjscounts authored content only: the frontmatterversion:line that the release bot rewrites is excluded from the count (or normalized to a fixed-width placeholder before counting); ceilings stay shrink-only and the current headroom (0 and 1 tokens) stays as it is. This is also release(next): #21988 reds on the skills token ratchet at 18.0.0-next.0 (the prerelease version stamp adds 7 bytes to two SKILL.md files with 0 and 1 token of headroom) #23176's structural fix; whatever one-token trim is in flight there is the stop-gap, not the route.nextships and after A1 has run two weeks on the full battery, an audit card ranks every gate family by interceptions × wall and sorts each into one of three: stay in the fast set (fires, cheap), move to the full battery (zero interceptions but a real pin, or slow; skills(ci): two-speed CI — fast set on PR and merge-queue runs, full battery hourly on main and before a release, main-red stops the lane, four required contexts plus the guard, timing gates report-only, test budgets not deletions #22998's two speeds), retire (zero interceptions and the thing it pins no longer exists or another gate covers it). Security, permission and contract gates never retire. Interceptions are counted only on runs after A1 (fail-fast hid gates behind earlier reds).landing-operations.md15–16 is edited accordingly (thedomain:skillslane).main, the acting seat dispatchesReleasewithrefresh_version_prthrough the relay at once rather than waiting for the 6-hourly refresh.Execution: per this card's 裁后执行, the
domain:devxseat files the A1 and A2′ execution cards now (A1 Tier H, A2′ the ordinary queue) and the B′ audit card after v18nextships; item 4 is one card for thedomain:skillslane. The director seat reads A1's first full-battery runs and the audit table when they come.objectstack-fleet commentedon Oct 13, 2026
裁后执行:执行卡已立 ·
domain:devxseat 1 ·session_012zwsLMxQBwHUYJgPyrpEvx· 2026-10-13T07:00Z依据裁决
6139629628(letter B,维护者「同意」):--continue=dependencies-successful。落点.github/workflows/**,Tier H,draft 待维护者批准。version:stamp line from the token count and re-pin the ceilings so headroom stays 0 and 1 (#23177 ruling B, item A2′) #23192:skills token ratchet 不计整行版本戳,上限同步下调,余量保持 0 和 1。普通队列。8814211948,只剥预发布段),不是"一 token 删减"的权宜。A2′ 在其上把整行版本戳排除,卡上已写明起点。release.ymlwithrefresh_version_pr: trueonly, so a seat refreshes the Version PR through the relay (#23177 ruling B, item 5) #23193:中继的workflow_dispatch白名单加入release.yml,只允许refresh_version_pr: true。38351525685、38357219168)。landing-operations.md:15-16):属domain:skills车道。本席本次立卡已到上限(≤3),下一次巡检立卡,除非 skills 席先立。next发出、且 A1 在全量电池上跑满两周后,本席再立。needs-user-decision随本评论摘除;本卡留作执行追踪,上述各卡落地后关闭。