fix(react-runtime,sdui-parser,console): 补上三包声明了 MIT 却从未随包发布的许可证文本,并加门禁封死该类 (#3696, #3702) - #3703
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
勘误(已随
|
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
两个包的 package.json 都写着 "license": "MIT",但仓库里没有对应的许可证文本, 所以每一个已发布的 tarball 都不含 MIT 要求随分发附带的许可证与版权声明。 这不是 files 声明问题:npm 有一份无视 files 恒定打包的清单(package.json、 README、LICENSE/LICENCE、COPYING、main 指向的文件),files: ["dist"] 并不会 把 LICENSE 排除在外。缺失的原因是磁盘上根本没有该文件,所以修法是补文件, 不是改 files —— 本 PR 未动任何 package.json。 两份 LICENSE 均为仓根 LICENSE 的逐字节副本,blob 与另外 37 份同为 cf2ca28。 同时给 package-files-exist 门禁加一道独立断言块:凡非 private 且声明了 license 字段的包,必须有许可证文本。判据从工作区扫描派生,不是硬编码包名单, 所以第 40 个包加进来的当天就被覆盖 —— #3647 与 #3696 连着两次都是靠人肉逐包 普查才发现的。 该门禁同时点名了 apps/console(@object-ui/console,publishConfig.access: public,同一缺陷),它超出本单文件面,已挂 #3702 并写进双向 ratchet 基线。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
新块的注释里写了 "objectui#4984",但 objectui 的编号目前在 3700 一带, 该号不存在 —— 那是另一个仓的同族教训被误标成了本仓引用。悬空引用比没有引用 更坏:读者会去查一个查不到的单子。改为直接把道理写清楚(谓词的两肢今天在树上 没有标本,无人行经的逻辑可以被后来的改动反转而不转红),不再冒充交叉引用。 纯注释改动,断言与逻辑一字未动;11 passed 不变。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
#3701(修 #3674)刚在同一文件里立了个约定:棘轮报陈旧时,成因要**逐条实测 上报**,不能由消息硬编码假定 —— 因为「离开基线」有多条路径,只有其中一条 意味着缺陷真被修好了,把假定写死会把读者引去核对一个并不成立的事实。 本 PR 的 license 棘轮有同样的结构,原消息虽然用的是「或」式并列(没有 #3674 那个断言错成因的毛病),但仍是让读者自己猜是哪一条。改成与 #3701 同形的 逐条成因,四条路径各自实测: 1. 现在有许可证文本了(并列出文件名)—— 只有这条意味着许可证真被补上 2. 改成了 private,不再分发,自然不欠 3. 不再声明 license 字段,没有主张要兑现 4. 该路径下已没有包(移走/删除,或这个基线键从来就没匹配上) 四条分支逐一实测,均按预测点名(证据见 PR 正文)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
d24caf9 to
ed34736
Compare
已 rebase 到 #3701 之上,并把 license 棘轮的成因上报对齐其约定PM 探活提到 #3701(修 #3674)已落 main 且与本 PR 同文件。处置与证据: 1. 冲突实测:本来就不冲突先用不落地的探针测过,不是靠猜: 与本 PR 原正文的预判一致:#3701 改的是 仍然做了 rebase,是为了让 CI 跑在含 #3701 的树上,并且下面第 2 点要读 #3701 的新约定。现基于 2. 顺带对齐:license 棘轮的陈旧成因也改为逐条实测上报#3701 在同一文件里立了个约定 —— 棘轮报陈旧时成因逐条实测,不由消息硬编码假定,因为「离开基线」有多条路径而只有一条意味着缺陷真被修好。 本 PR 的 license 棘轮是同构的。原消息用的是「或」式并列(没有 #3674 那个断言错成因的毛病),但仍要读者自己猜是哪一条。已改成与 #3701 同形,四条路径各自实测 —— 四条分支逐一验证,全部按预测点名:
四次均 3.
|
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
PM 分诊裁定把 #3702 并入本 PR。@object-ui/console(apps/console)与 #3696 的 两个包是同一个缺陷:非 private、声明 "license": "MIT"、无许可证文本,而它确是 发布物(publishConfig.access: public、版本 17.3.0 同线、在 changeset fixed 组、 有 prepublishOnly)。之前它超出 #3696 的文件面,故只挂账不修。 改动两处: 1. apps/console/LICENSE —— 仓根 LICENSE 的逐字节副本,blob 同为 cf2ca28。未动 files 字段(npm 恒定收录 LICENSE),npm pack --dry-run 清单 3 → 4 个文件,LICENSE 出现。 2. KNOWN_LICENSE_TEXT_MISSING 清空。删除前先跑了一次套件让棘轮报陈旧, 逐条成因命中第一条(唯一意味着许可证真被补上的那条): apps/console (objectui#3702) — it now ships license text (LICENSE) 删除后 11 passed。 同时: - 基线上方的文档注释从「现在时描述一个条目」改写为历史记录。留着不动就会变成 一份描述并不存在的条目的声明 —— 与本 PR 正在消除的失真同类,只是搬进了注释 (#3687 的同一处理)。棘轮机理段原文未动。 - 点名钉扎从两个包扩到三个,各带自己的 issue 号。这条比通用断言强:它不能靠 往基线里加一行来满足。删掉 apps/console/LICENSE 实测 2 红(通用断言 + 钉扎), 证明修完之后留下的是覆盖,不是沉默。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Fixes #3696
Fixes #3702
裁 B(补文件 + 门禁),外加分诊裁定并入的 #3702。4 个文件:三份新 LICENSE,外加
scripts/__tests__/package-files-exist.test.ts的新增断言块。未动任何package.json,未动files字段。前提复核(在 origin/main 上先证后改)
license字段"MIT"privatefiles["dist"]sdui-parserREADMEissue 正文的前提全部复现。
既有 LICENSE 仍是单 blob —— 但份数与派发口径差 1
派发说「36 个」,实测 37。差额不是分歧:37 = 仓根 1 份 + 包级 36 份,而包级的第 36 份正是 PR #3662 刚补的
plugin-tree。#3662 正文写的「36 份」是在它自己落地之前测的(1 + 35)。形态结论不变 —— 连 copyright 行在内完全一致,不存在多数/少数形态之分。本 PR 新增的三份 blob 同为
cf2ca285…,各 1065 字节:为什么修法是补文件而不是改
files—— 在本仓实测过,不是照抄语义npm 有一份无视
files恒定打包的清单。在packages/sdui-parser(files: ["dist"])上逐个改名跑npm pack --dry-run,带对照组:LICENSE/License/LICENCE/LICENSE.md/LICENSE.txtcopyingNOTICECHANGELOG.mdNOTALICENSE(对照组)对照组不收录,证明这个探针是有鉴别力的,不是「什么都收」。
同一机制在未改动的
react-runtime上有现成佐证:它的files只有dist,而README.md照样进了 tarball(见下方「修改前」清单)—— 恒定清单压过files这件事在本仓当场可见,LICENSE 走的是同一条路。所以给
files加"LICENSE"是无效操作,本 PR 不动package.json。验收:
npm pack --dry-run三个包前后对照@object-ui/react-runtime@object-ui/sdui-parser@object-ui/console(#3702 并入部分)apps/console的files保持["dist","plugin.ts","plugin.js","plugin.d.ts","README.md"]一字未改,LICENSE 照样进清单 —— 这本身又是恒定清单语义的一次独立复现。两点说明,免得清单读起来有歧义(沿用 #3662 的写法):
dist/,因为这是全新 worktree、包尚未构建。不影响验收 —— npm 对 LICENSE 的收录与dist是否存在互相独立。plugin-timeline跑同一条命令,清单里本来就有1.1kB LICENSE(4 个文件)。差异来自文件本身的有无,不是命令或环境。新门禁
scripts/__tests__/package-files-exist.test.ts末尾新增独立 describe:凡非private且声明了license字段的包,必须有许可证文本。判据
!private && license从同一份工作区扫描派生,不是硬编码包名单 —— 第 40 个包加进来的当天就被覆盖。#3647 与 #3696 连着两次都是靠人肉逐包普查发现的,缺的是门禁不是细心;而 #3702 正是这道门禁在自己落地当天抓出来的第三例。许可证文件名接受
/^licen[cs]e(\.[^.]+)?$/i。上表实测的COPYING故意不接受:全仓 39 份都拼作LICENSE,一道悄悄放行仓库不用的拼法的门禁,等于在约定漂移上报成功。真落一个COPYING应当转红并在此处有意放宽。反空绿(四重)
owingPackages.length >= 38(实测 39)。license字段被改名、工作区根丢失、private默认翻转,都会让谓词悄悄匹配到空集。owesLicenseText的四行里有两行今天在树上没有标本(全部 39 个非 private 包都声明了 license)。不断言的话,那两肢就是无人行经的逻辑,后来的改动可以把它反转而不转红。object-ui(vscode-extension)。标本消失时该测试会红并明说「要么换标本要么删掉,别留一个在空集上绿的测试」。逆向验证:均先写预测再跑
A. 删掉
packages/react-runtime/LICENSE— 预测:通用断言点名 + 点名钉扎,共 2 红。命中:B. 边界演示 —— 同时删掉 LICENSE 与
license字段。 这里的预期方向不是「更红」,而是通用断言转绿:没有声明就没有义务。预测:通用断言绿,而点名钉扎与人口点名转红,总数仍是 2 红但失败集合不同。命中:every package that declares a license has the text on disk这一条确实转绿了 —— 谓词的license那一肢是承重的。同时这组输出说明门禁是分层的:删掉license字段并不能悄悄把一个已知发布物豁免掉,点名钉扎照样红。这一点值得写下来,因为「删字段即脱身」正是这类门禁最容易被绕开的方式。C. 棘轮四条成因分支 — 对齐 #3701 约定后逐一实测,四条全部按预测点名,每次均
1 failed | 10 passed:cp LICENSE apps/console/LICENSE— it now ships license text (LICENSE)private: true— it is now \private`, so it distributes nothing and owes no text`delete j.license— it no longer declares a \license` field, so there is no claim left to honour`packages/BOGUS-never-existed— no package sits at that path any more: it was moved or removed from the workspace, or this baseline key never matched one分诊裁定:#3702 已并入本 PR
原先
apps/console是挂账在基线里的第三例。分诊裁定就地一并修,故本 PR 现同时Fixes #3702。为什么它是第三例
按四个工作区根(
packages/*、examples/*、apps/*、docs)重测,非 private 且声明 license 的包是 39 个,缺许可证文本的是 3 个 —— issue #3696 正文的「38 / 2」只展开了packages/*,这正是它被两次普查漏掉的原因。@object-ui/console确是发布物:publishConfig.access: "public"、版本 17.3.0 与其余同线、列在.changeset/config.json的fixed组里、有prepublishOnly。缺陷与另外两个完全同形。并入过程(棘轮两步,输出留档)
第 (a) 步 —— 先补文件,
KNOWN_LICENSE_TEXT_MISSING仍留着那一行。 预测:棘轮转红报陈旧,并按逐条成因命中第一条。命中:这是本 PR 原正文里逆向验证 C 的现实版 —— 当时是人为建文件演示的方向,这次是真修。
第 (b) 步 —— 清空基线。 预测:11 全绿。命中:
修完之后留下的是覆盖,不是沉默
基线清空后「没有违规」这件事本身可能是空绿,所以补了一次:删掉
apps/console/LICENSE(此时已无基线可豁免)。预测 2 红。命中:一处文件面披露:改了基线上方的文档注释
该注释以现在时逐条描述我正要删掉的那个条目(「
apps/consoleis the one entry …」)。基线清空后这段话会变成一份「描述一个并不存在的条目」的声明 —— 与本 PR 正在消除的失真完全同一类,只是从package.json搬进了注释。已改写为历史记录(#3687 对同一情形的同一处理)。棘轮机理段原文一字未动,其下所有断言逻辑未动。与 #3701 / #3674 的关系
#3701(修 #3674)在本 PR 开出后落到 main,同文件。冲突用不落地的探针先证过,不是靠猜:
与原正文预判一致(#3701 改 305–317 行一带,本 PR 第三个 hunk 最早上下文行 327,零交叠),技术上不需要 rebase。仍做了 rebase 以便 CI 跑在含 #3701 的树上;该 rebase 需要 force-push,已单独报备并获接受(见评论)。最后这次 #3702 的并入提交是普通 fast-forward 推送,未 force。
顺带把本 PR 的 license 棘轮也对齐了 #3701 立下的约定:成因逐条实测上报,不由消息硬编码假定(上表 C 的四条即此)。
关于 changeset:判定为不加
按 #3662 确立、#3687/#3695 沿用的框架:
.changeset/config.json把 39 个包放在同一个fixed组(@object-ui/console也在其中),任何一个 changeset 都会带着这三个包一起 bump 重发;为补三个文件而单独推整组一个版本,收益与代价不成比例。验证
控制字符另做超出门禁扫描面的自查:对改动文件
grep -naP扫\x00-\x08/\x0b/\x0c/\x0e-\x1f无命中;并逐码点统计零宽与不可见字符(U+200B/200C/200D/FEFF/2028/2029/00A0)计数均为 0。两处过程自查(实测中差点带进 PR 的东西)
npm pack」里有一步是mv LICENSE CHANGELOG.md,它覆盖掉了packages/sdui-parser/CHANGELOG.md真实内容,改回来时又把它删掉了。是提交前的git status抓到的(D packages/sdui-parser/CHANGELOG.md),已git checkout --还原并与 origin/main 逐字节比对为空 diff。objectui#4984,但本仓编号在 3700 一带,该号不存在 —— 那是另一个仓的同族教训被误标成本仓引用。追加提交430c0db87已把它改成直接讲清道理。新块现存的引用(#3647/#3663/#3696/#3701/#3702)均为本仓真实条目。文件面
packages/react-runtime/LICENSEcf2ca285…)packages/sdui-parser/LICENSEapps/console/LICENSEscripts/__tests__/package-files-exist.test.ts未动任何
package.json,未动files字段,未动content/docs/releases/,未改 assignee。sdui-parser缺 README 一事属 #3647/#3664 划出的「打包策略」,本 PR 不主张、不处理。🤖 Generated with Claude Code
https://claude.ai/code/session_01GTRjn8xBqp75dk7kFupVRt
Generated by Claude Code