Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

没有任何 gate 检查 sideEffects 声明与「加载期副作用」是否一致 —— #3899 的 pin 只覆盖 layout 一个包 #3943

Closed

Description

@yinlianghui

发现于 #3899 的实现(PR #3940),不在该 PR 处理 —— 那一单的面被 PM 裁决明确收窄为 packages/layout 一个包的清单。这一条是仓级 gate 的缺口,是另一类事实。

机制

#3899 是这样被发现的:一个人在做别的事时顺手注意到 packages/layout/package.json 声明 "sideEffects": false,而 src/index.ts 靠加载期 registerLayout() 注册六个组件 key。实测(PR #3940 正文有数据):纯副作用引入 import '@object-ui/layout'; 在遵守该 flag 的打包器下产出 0 字节 bundle、零注册、退出码 0、无警告;故障远端才现形为红色 Unknown component type 面板(OBJUI-001)。

PR #3940 修了 layout,并加了一条构建级 pin(packages/layout/src/__tests__/side-effects-manifest.test.ts)。但那条 pin 是包内作用域的 —— 它读 packages/layout/package.json、探 layout 自己的入口形态。下一个包重犯同样的错,仓里没有任何东西会变红。

这与 #3663 / #3647 是同一形状的缺口:files 声明与磁盘的漂移也曾靠人手工逐包 diff 才发现(一周内两次),随后才有了 scripts/__tests__/package-files-exist.test.ts 这条派生式仓级 gate。sideEffects 现在正处在「靠人顺手发现」的阶段。

今天的普查(origin/main @ 230ffd8,逐包核实)

  • "sideEffects": true —— packages/components、packages/fields。诚实(且最保守)。
  • "sideEffects": false —— packages/core、packages/i18n、packages/layout(PR fix(layout): declare the load-time registration in sideEffects (#3899) #3940 修正中)、packages/react-runtime、packages/sdui-parser、packages/types。除 layout 外逐个查过 barrel 的顶层语句,均无加载期副作用,因此今天都是诚实的(react-runtime 的 barrel 是 src/index.tsx,注意别被 index.ts 的 glob 漏掉)。
  • 字段缺省(undefined)—— 其余全部,含所有 plugin-*。这是安全默认值:打包器会假定有副作用。PluginLoader 动态 import 的那批包因此从未暴露在这个风险里。

所以除 layout 之外目前没有第二个活的缺陷。这也是本条按 observation-class 归档、不打 pm:queue 的原因。

为什么仍然值得记下来

缺口不是「有没有当前受害者」,而是这类谎言无声。它的三个属性叠在一起正好躲开所有现有检查:

  1. 构建全绿、无警告 —— 打包器认为自己在执行你的声明,不是在报错。
  2. 只有 sideEffects: false(或数组漏掉某个入口形态)+ 加载期副作用同时成立才发作,两半分别看都无可指摘。
  3. 现有消费者只要同时 import 了具名导出,模块就一定被求值 —— 缺陷因此可以潜伏任意长时间。packages/layout: sideEffects: false contradicts the load-time registerLayout() — a side-effect-only import can be tree-shaken away #3899 明确写了「今天没人被打到是巧合,不是设计」。

一个新包(或在现有 false 包里新加一处加载期注册/注册表写入/全局赋值)就能原样重演,且没有任何红灯。

可能的处置(供分诊,未实施)

在 scripts/__tests__/ 加一条派生式仓级 gate,形状照 package-files-exist.test.ts:遍历 workspace 每个包,对声明了 sideEffects: false 或数组的包,检查其 barrel(含 .ts/.tsx 两种拼写)是否存在顶层副作用语句(裸调用、注册表写入、globalThis 赋值);数组情形另检查是否覆盖 main/module/exports 指向的全部 JS 入口形态。PR #3940 里的推导函数(resolvableEntryPaths())与真打包器探针(含 sideEffects: false 对照,防止 gate 在打包器不摇时空绿)可以直接上提复用,layout 的包内 pin 随之收敛为仓级 gate 的一个 specimen。

⚠️ 一处别踩的坑,PR #3940 实测过:发布路径不是唯一的消费面。apps/console/vite.config.ts:122 与 examples/console-starter/vite.config.ts 都把 @object-ui/layout alias 到 packages/layout/src,打包器对这些源文件读的是同一份 package.json;只声明 dist/* 时 console 的 alias 形态依然产出 0 字节 bundle。任何仓级 gate 都必须把 workspace alias 入口一并算进「入口形态」,否则它会给一个仍然会炸的包发绿灯。

退出条件

  • 上述仓级 gate 落地(本条即完成);或
  • 出现第二个实际发作的包 —— 那时这条就不再是 dormant,应升级为具体缺陷。

参考位置:scripts/__tests__/package-files-exist.test.ts(同形状的派生式仓级 gate 先例)、packages/layout/src/__tests__/side-effects-manifest.test.ts(PR #3940 的包内 pin,可上提的推导与探针)。

关联:#3899(发现于此)、#3663 / #3647(files 字段的同形状缺口与它的 gate)。

Activity

  1. claude commented on Aug 9, 2026

    @claude
    Contributor

    Findings triage round (triage seat Routine, ~15:19Z fire): hold — finding kept.

    • Stale-premise check on objectui origin/main @ b14ab3a — one census row has moved since filing, in the healthy direction: PR fix(layout): declare the load-time registration in sideEffects (#3899) #3940 merged 13:46Z, and packages/layout/package.json now declares the array form (./dist/index.js, ./dist/index.umd.cjs, ./src/index.ts) instead of false. Re-verified the rest of the census: core / i18n / react-runtime / sdui-parser / types still false (and were each checked honest at filing), components / fields still true, plugins still undefined (safe default). So the card's own conclusion stands: zero live defects today; what remains is the gate gap.
    • Why still held rather than promoted: with the only known victim fixed and pinned package-locally, the repo-level derived gate is protective machinery for a defect class with no current instance — real, but nothing anyone hits today, which is the definition of the held state. The card's analogy is apt though: files-vs-disk drift went through exactly this stage before package-files-exist.test.ts existed, and it took two same-week manual catches to justify the gate. First recurrence of a dishonest sideEffects flag anywhere in the repo is this card's promotion trigger.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Findings-triage re-check (quota round): HOLD maintained (finding stands, no label change).

    Premise re-verified on origin/main @ 521a37b: the layout-scoped pin still exists (packages/layout/src/__tests__/side-effects-manifest.test.ts) and no repo-level gate checking sideEffects declarations against load-time side effects has appeared in scripts/ or the workflows. The gap stands: a second package repeating layout's "sideEffects": false + load-time registration mistake would ship silently. Held — a repo-level gate is real tooling work worth a deliberate slot, not something a user hits today.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. claude commented on Aug 11, 2026

    @claude
    Contributor

    Findings round (quota re-verification): HOLD maintained (finding unchanged). Re-checked @ origin/main a9a67ec: the layout-scoped pin (packages/layout/src/__tests__/side-effects-manifest.test.ts) still exists and remains the only sideEffects/load-time-effect check — the sole other repo hit is a prose comment in scripts/__tests__/site-playground-layout-registration-3904.test.ts:139, not a gate. A second package repeating layout's mistake would still ship silently. Held — repo-level gate is deliberate tooling work.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings cadence (triage seat): HOLD — premise re-verified on origin/main @ 6d01319: still no gate checks sideEffects declarations against load-time side effects — a scan of scripts/ and .github/workflows finds no such check (counter-probe: the #3899 layout-package pin is still the only guard, one package wide). Held: tooling-coverage observation, no measured breakage; exit is a devx-style gate card if a second sideEffects incident appears or maintainer appetite shows.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  5. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings cadence (triage seat): HOLD — re-verified @ origin/main 6044d13: the sideEffects consistency gate still covers only the layout package — the sole scripts-side pin remains scripts/__tests__/site-playground-layout-registration-3904.test.ts (the #3899 pin), and no generalized declaration-vs-load-side-effect check exists. No live defect behind it today; the gap is a guard absence, not a misbehaviour. finding stands. Restart unchanged: a second package caught with a wrong sideEffects declaration (that instant justifies generalizing the pin), or a bundler/treeshake regression traced to one.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  6. os-project-manager commented on Aug 17, 2026

    @os-project-manager
    Collaborator

    Triage (batch first-touch round, 2026-08-17): promoted finding → pm:queue, type Task.

    Why promotion rather than another hold: this is a fully-specified mechanical gate card — the design, the derivation function (resolvableEntryPaths()), the real-bundler probe (with its sideEffects: false control against empty-green), and the workspace-alias trap are all already written down here and in PR #3940, and the repo-level precedent (scripts/__tests__/package-files-exist.test.ts) exists. The class already cost one paid incident (#3899: 0-byte bundle, zero warnings), its failure mode is silent by construction, and per-round re-verification of a static gate gap has been costing more than building the gate. Under the runbook's "mechanisable items become gate cards, not prose" rule this queues.

    Scope for the dev: repo-level derived gate over every workspace package declaring sideEffects false/array — barrel top-level side-effect statements (.ts/.tsx spellings both), array coverage of all JS entry shapes including workspace-alias entries (console/starter vite aliases to src — the trap PR #3940 measured); hoist layout's package-scoped pin into the gate as its specimen. Re-verified this round: 8 packages declare the field, no repo gate exists.

    Size/model suggestion: M, sonnet/opus.


    Generated by Claude Code

  7. self-assigned this
    on Aug 17, 2026
  8. yinlianghui commented on Aug 17, 2026

    @yinlianghui
    ContributorAuthor

    认领(objectui 车道分片 PM,会话 session_01GTRjn8xBqp75dk7kFupVRt,批次 16):branch claude/issue-3943-sideeffects-gate。

    按 2026-08-17 晋级评论的 scope 实施:scripts/__tests__/ 仓级派生门(形状照 package-files-exist.test.ts),遍历声明 sideEffects: false/数组的包,查 barrel 顶层副作用语句(.ts/.tsx 双拼形)与数组对全部 JS 入口形态的覆盖(含 workspace alias 入口 —— console/starter vite alias 到 src 的那个坑);上提 PR #3940 的 resolvableEntryPaths() 与真打包器探针(含 sideEffects: false 对照防空绿),layout 包内 pin 收敛为仓级门的 specimen。文件面:scripts/__tests__/(新文件)+ packages/layout/src/__tests__/side-effects-manifest.test.ts。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions