build(site): [SITE-07] reproduce console-feed vendor modules

This commit is contained in:
Harvey Zhao committed 2026-09-15 06:29:06 +08:00
1 parent 3dba82a453
commit b47ede011a
13 files changed
+663 -9

No files matched your search

@@ -0,0 +1,366 @@
{
"schemaVersion": 1,
"task": "SITE-07",
"recordedAt": "2026-09-14T22:23:26.058Z",
"frozen": {
"path": "refactor/baselines/site-vendor/console-original.js",
"sha256": "e00bbf82bf08c452825690372ded39a9b60f4baf438f0e7ce8300e9bc4629c03"
},
"archive": {
"name": "console-feed",
"version": "3.2.2",
"tarball": "https://registry.npmjs.org/console-feed/-/console-feed-3.2.2.tgz",
"integrity": "sha512-/DxoNG48E+eIMhD9/lBftpJoFQI1e5TOXCwmwG9VIMXAVJPDyGRoY844eClkZBC4b4Ae24ndua6ui/E0jfrH9Q==",
"sha256": "3e02b8e4603fab1bc67d6cf99331a2b9470ea448fbcb3c6ef66615b03385f772"
},
"compiler": {
"archive": {
"name": "terser",
"version": "3.17.0",
"tarball": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
"integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==",
"sha256": "42e8fc6a9d1d11762cf1e8ce4c378bce2eaeea28578dd112a58de34a0a9cef8d"
},
"member": "package/dist/bundle.min.js",
"sha256": "6dfee6a315a7928b6fc06fb306037c528fa11a3e8413b5608722a0eca2fa08db",
"sourceMapVersion": "0.6.1",
"options": {
"warnings": true,
"safari10": true,
"mangle": {
"toplevel": true
}
},
"recipeSource": {
"archive": {
"name": "parcel-bundler",
"version": "1.12.5",
"tarball": "https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.5.tgz",
"integrity": "sha512-hpku8mW67U6PXQIenW6NBbphBOMb8XzW6B9r093DUhYj5GN2FUB/CXCiz5hKoPYUsusZ35BpProH8AUF9bh5IQ==",
"sha256": "2999bb924723fe5d33dea65361c5d235e79912f778b712f30382eb4e9d156406"
},
"member": "package/src/transforms/terser.js",
"sha256": "508d575d7428119cafc1a1edcc6a9f8e05653e9901cf04ee3b909145ecdb6147"
},
"limitation": "This is an exact reproducing transform, not recovery of the original full Parcel lockfile or proof of a uniquely installed version."
},
"sources": [
{
"id": "m6b6",
"member": "package/lib/index.js",
"sourceSha256": "b0b79bae841edf4084e7f884da4aab9349f0d9e7af656fadda6ad26b8e4dd916",
"generatedSha256": "5be990ed02829d295cc31a6e3fde121dffc53a4b663d70af4954c9ae75d40c79",
"bodySha256": "5be990ed02829d295cc31a6e3fde121dffc53a4b663d70af4954c9ae75d40c79"
},
{
"id": "yCSh",
"member": "package/lib/Component/index.js",
"sourceSha256": "c8b99fb95f5272ad6f4e152945e19dca6023f28b34e9c2bf0dda68738c978cf1",
"generatedSha256": "803744445c69187b7d762e67b72f20585dcbf9908ee5fd026907aafb4acbab58",
"bodySha256": "803744445c69187b7d762e67b72f20585dcbf9908ee5fd026907aafb4acbab58"
},
{
"id": "VJzx",
"member": "package/lib/Component/theme/default.js",
"sourceSha256": "525ea614eed82fa24bc61ec8fb208067b463395bb9f69dca0ace0fe97530475e",
"generatedSha256": "af79c6085e219d832215950b61b7876848a58a7ae5c9220fe744c8a894bcbc78",
"bodySha256": "af79c6085e219d832215950b61b7876848a58a7ae5c9220fe744c8a894bcbc78"
},
{
"id": "F6B0",
"member": "package/lib/Component/elements.js",
"sourceSha256": "b50350173c6c177caa7117011e8a9f811f040f8091bb0b0d4c6156d8a88bf3e7",
"generatedSha256": "04e268efa37ec3e22087dfec429bd9d2f36c8df17d538e2861b48c6ffa8ed176",
"bodySha256": "04e268efa37ec3e22087dfec429bd9d2f36c8df17d538e2861b48c6ffa8ed176"
},
{
"id": "MnJh",
"member": "package/lib/Component/theme/index.js",
"sourceSha256": "bffac1fce38fae8b48c7085a3223ed83c669c1f8e9a76cc3ecc2612b241868a5",
"generatedSha256": "215cc714ebd19bcd842cde8acb83585958ba6989953055c1c5ca5fa65c8617c6",
"bodySha256": "215cc714ebd19bcd842cde8acb83585958ba6989953055c1c5ca5fa65c8617c6"
},
{
"id": "VMze",
"member": "package/lib/Component/Message.js",
"sourceSha256": "21aa511c431b49b99fd19014a34b5fc2364f4789529986e7ac5dbfb2731330dd",
"generatedSha256": "d83cc7fadffee9335a9aadf788a21162d3cd4a02c7748396001b5d6eb1a6fd70",
"bodySha256": "d83cc7fadffee9335a9aadf788a21162d3cd4a02c7748396001b5d6eb1a6fd70"
},
{
"id": "ftAA",
"member": "package/lib/Component/message-parsers/Formatted.js",
"sourceSha256": "c2f5771a1b1f074f9aa173efecb6599ba7b7a3ccfdb35113b97c2611334259a2",
"generatedSha256": "dc618144a1803b7f1c7981a2b2d309af45773864510f2c180167c84df33dfbdd",
"bodySha256": "dc618144a1803b7f1c7981a2b2d309af45773864510f2c180167c84df33dfbdd"
},
{
"id": "R2hN",
"member": "package/lib/Component/react-inspector/elements.js",
"sourceSha256": "3db15ae3f770a3278a829fecaecb3e527c2294344a115f3123774a5865c5cebf",
"generatedSha256": "977afb19a0ac303a0bc51cf530bb8243ae08def67de7a270ffb33796fc8fa27d",
"bodySha256": "977afb19a0ac303a0bc51cf530bb8243ae08def67de7a270ffb33796fc8fa27d"
},
{
"id": "CwU9",
"member": "package/lib/Component/devtools-parser/index.js",
"sourceSha256": "79932dab131a76a6bc4288b69674cc348680cbc700acd1b3ff8f3b675c6f4a8d",
"generatedSha256": "f634855517a582f02f585c9e7c5bf9edb0dee11be8bf2cc3109dd4ec82e6de83",
"bodySha256": "f634855517a582f02f585c9e7c5bf9edb0dee11be8bf2cc3109dd4ec82e6de83"
},
{
"id": "SENo",
"member": "package/lib/Component/devtools-parser/format-message.js",
"sourceSha256": "9d989597b6c3d30ca84baac5f67e2014a6bac48ab5d1260dbce40cba7568155a",
"generatedSha256": "c5c66a439a3626150db2f3530874dddbffe88c420140802e0cdb2531ae2c976c",
"bodySha256": "c5c66a439a3626150db2f3530874dddbffe88c420140802e0cdb2531ae2c976c"
},
{
"id": "uxdN",
"member": "package/lib/Component/devtools-parser/string-utils.js",
"sourceSha256": "1daafcdb9cdeab609e5c4561903d821acd46b6edac8a84bbaf93fc710ce3e99d",
"generatedSha256": "5aa9396d427f60f0ad543a58692b3b1e7888bfe75d32113cc28aabdbc21f8307",
"bodySha256": "5aa9396d427f60f0ad543a58692b3b1e7888bfe75d32113cc28aabdbc21f8307"
},
{
"id": "LmXR",
"member": "package/lib/Component/message-parsers/Object.js",
"sourceSha256": "10009010bdc053a6c15e2e083457082f4fbff6ebab15f4a2efc02422f3a5b203",
"generatedSha256": "8d908461fa424ffa99856a00f06a26900d65d5333879e8ba0248075eb5cbd4a8",
"bodySha256": "8d908461fa424ffa99856a00f06a26900d65d5333879e8ba0248075eb5cbd4a8"
},
{
"id": "j7Pd",
"member": "package/lib/Component/react-inspector/index.js",
"sourceSha256": "17de610ab22242607699955f71df7b6ae3f35e0017da51106e090864a80bf42f",
"generatedSha256": "0a6438f055de8fd999d686155b8b021099125c06f92728f7cd6c20c6bf5e403c",
"bodySha256": "0a6438f055de8fd999d686155b8b021099125c06f92728f7cd6c20c6bf5e403c"
},
{
"id": "swKK",
"member": "package/lib/Component/message-parsers/Error.js",
"sourceSha256": "d13f4124372f1d5941e968c8d3403372056b3479668889acbd1768bb73bbe080",
"generatedSha256": "aa196768776c196a76dd1c4cc61bbd667159a12e13ec58a14d8e10ea09409be9",
"bodySha256": "aa196768776c196a76dd1c4cc61bbd667159a12e13ec58a14d8e10ea09409be9"
},
{
"id": "pYO5",
"member": "package/lib/Hook/index.js",
"sourceSha256": "63243dff52752b4c8552924f486e93483bfdc0cb7739692d897fa799ac7abd0e",
"generatedSha256": "5475966f1b782a13aab14c65db35ffc6e1e2d1f4a74e535323babf4459eaabfb",
"bodySha256": "5475966f1b782a13aab14c65db35ffc6e1e2d1f4a74e535323babf4459eaabfb"
},
{
"id": "V2JG",
"member": "package/lib/definitions/Methods.js",
"sourceSha256": "3e0373b4760fcb01db1ae5b6d03f9640b699dd87cda382113081b5f97f59a822",
"generatedSha256": "4476f5ab9cb1d0fa4d8b30cdda836398c84ebab3083bd6eabb1eb8a218756b6f",
"bodySha256": "4476f5ab9cb1d0fa4d8b30cdda836398c84ebab3083bd6eabb1eb8a218756b6f"
},
{
"id": "RxPG",
"member": "package/lib/Hook/parse/index.js",
"sourceSha256": "bd8edf290bd950f1630be5a8a1c9c2f844bdf32f43df1fb2aba119d35e01ada4",
"generatedSha256": "8b055b5ad031122364b701efe0dbd37749a04dc1e968fc389b515ba9662058b7",
"bodySha256": "8b055b5ad031122364b701efe0dbd37749a04dc1e968fc389b515ba9662058b7"
},
{
"id": "kEc0",
"member": "package/lib/Hook/parse/GUID.js",
"sourceSha256": "78dca26cc852b8d05c422197318a00cab1ff065c3a82ff12f6d586ca50e60dde",
"generatedSha256": "f61e1118796bd5329c893f7aa870f1d1f9439eff6cc2e0a9f329f1624494cb3f",
"bodySha256": "f61e1118796bd5329c893f7aa870f1d1f9439eff6cc2e0a9f329f1624494cb3f"
},
{
"id": "b9Ac",
"member": "package/lib/Hook/parse/methods/timing.js",
"sourceSha256": "3ec9b76ba0ee3ef27753162fa720a33770cfe19cbc15316f26b406a3417d33ef",
"generatedSha256": "4ef00880c4faebabcc2296d4b0d5af3687599c44cf9ebc18b9f5d640a81bc557",
"bodySha256": "4ef00880c4faebabcc2296d4b0d5af3687599c44cf9ebc18b9f5d640a81bc557"
},
{
"id": "tUcB",
"member": "package/lib/Hook/store/state.js",
"sourceSha256": "5e94f4ebb046796ccaf2424941c716e12fe454c3eb7982ee896b6a7a115a5666",
"generatedSha256": "063cbbd0e15bf5f66ea9839b1aef22c645e83c847106950bfba22a49c5e6aaeb",
"bodySha256": "063cbbd0e15bf5f66ea9839b1aef22c645e83c847106950bfba22a49c5e6aaeb"
},
{
"id": "KD8b",
"member": "package/lib/Hook/store/dispatch.js",
"sourceSha256": "9422017cb57271d022b942f9cb5595e784e5e882940dda4234f458ed85c3c9f3",
"generatedSha256": "0cad70e5ae872d671ce41ec0ba3f07047b2eb31a2cb7c6dec7af14ef6874c125",
"bodySha256": "0cad70e5ae872d671ce41ec0ba3f07047b2eb31a2cb7c6dec7af14ef6874c125"
},
{
"id": "AXxh",
"member": "package/lib/Hook/store/reducer.js",
"sourceSha256": "d2c1e1dd8424c8adf7c41ac87dbf0d1515851927a300706bb463c1136dd113b8",
"generatedSha256": "5a20f5f349cfe5341d8d7b91556012fa5eb7862b7727f323aed50746bfd2dd23",
"bodySha256": "5a20f5f349cfe5341d8d7b91556012fa5eb7862b7727f323aed50746bfd2dd23"
},
{
"id": "nj54",
"member": "package/lib/Hook/store/actions.js",
"sourceSha256": "d94d4e1ac65d9ec2f44bf7bbddcd381f00fe6462e5b8ffc3efbad9339be24a3f",
"generatedSha256": "abce408bb92e92c9adf097ac3984e5d052c9c8f5d3e69c03404341b82a94466e",
"bodySha256": "abce408bb92e92c9adf097ac3984e5d052c9c8f5d3e69c03404341b82a94466e"
},
{
"id": "BQYC",
"member": "package/lib/Hook/parse/methods/count.js",
"sourceSha256": "61fb64e0ce485f19b058d505d84a60ee63fa4069c235577f7da4ae3824f18881",
"generatedSha256": "bd7e9e0250873cc7aa48af4733c7f2efc1f48dda58c8e6198a335395f0616183",
"bodySha256": "bd7e9e0250873cc7aa48af4733c7f2efc1f48dda58c8e6198a335395f0616183"
},
{
"id": "dKro",
"member": "package/lib/Hook/parse/methods/assert.js",
"sourceSha256": "1d80efcffc998c08ce30aceb3fb880222fbc604304363829a88bd06a4efb5847",
"generatedSha256": "25730ae6159aeb1da85ce13a63ef7f36fe12f9e86c8a5f39eab5278f2531ea9c",
"bodySha256": "25730ae6159aeb1da85ce13a63ef7f36fe12f9e86c8a5f39eab5278f2531ea9c"
},
{
"id": "Zbbf",
"member": "package/lib/Transform/index.js",
"sourceSha256": "87c7c0f901c7c3fe461cbddf344dda85e0bbac09808bf1224ff3dfa034b371c9",
"generatedSha256": "a6e8f7ee72f2bfa0747c4cc0fb8aea6df3f2c2b362248d6d64c39e70b3109f46",
"bodySha256": "a6e8f7ee72f2bfa0747c4cc0fb8aea6df3f2c2b362248d6d64c39e70b3109f46"
},
{
"id": "dq61",
"member": "package/lib/Transform/arithmetic.js",
"sourceSha256": "e8a6d77a65fc8ae73cdc5b221c4ee75d72ce32a2b8acf544796b72c55936827b",
"generatedSha256": "02b98dd6f320c114767fa8fcf8a470907df7f8091a41d84430007209c1d6b181",
"bodySha256": "02b98dd6f320c114767fa8fcf8a470907df7f8091a41d84430007209c1d6b181"
},
{
"id": "XwmA",
"member": "package/lib/Transform/Function.js",
"sourceSha256": "10a220fd9dd6f14e0af03f552316ed1cf12d61846956fb989d419661dbea0de0",
"generatedSha256": "199b2c52101cf2f9bbfc33ff516eca6e7e7fff077ba41b52a427ca8ef960b5b7",
"bodySha256": "199b2c52101cf2f9bbfc33ff516eca6e7e7fff077ba41b52a427ca8ef960b5b7"
},
{
"id": "GDCg",
"member": "package/lib/Transform/HTML.js",
"sourceSha256": "de476cec047de1da472ccfc766535ed4bc627ebf168a85f8ad4d5e35b13fa834",
"generatedSha256": "70dd97167ccc13b9be60eea8a24a2bdcea122c6688c9fb58e4e63e721f40b72f",
"bodySha256": "70dd97167ccc13b9be60eea8a24a2bdcea122c6688c9fb58e4e63e721f40b72f"
},
{
"id": "wqxJ",
"member": "package/lib/Transform/Map.js",
"sourceSha256": "cc9c19079569321216ce6ccd3bee4d4821e68882d3123d01b67bf8df7701b4d4",
"generatedSha256": "f5bb3bb16f6971cfa779dc7acc02f74b4bf9cb2e81c5872df3336d4f4ab41e82",
"bodySha256": "f5bb3bb16f6971cfa779dc7acc02f74b4bf9cb2e81c5872df3336d4f4ab41e82"
},
{
"id": "HTuI",
"member": "package/lib/Transform/replicator/index.js",
"sourceSha256": "33ea546afdd46833594d7cdccbfc45dc654b8e9fa737d9ee5d940b6f164dba6b",
"generatedSha256": "97f6bd7b15087b2a042d3d4fb8abfaa8c7add5f18ac7e5eff767988708bbdc3a",
"bodySha256": "97f6bd7b15087b2a042d3d4fb8abfaa8c7add5f18ac7e5eff767988708bbdc3a"
},
{
"id": "aGBs",
"member": "package/lib/Unhook/index.js",
"sourceSha256": "47e84dcb6c2a0a752eb778e8fab484d1efd363c0284fde0b1fa28a4b6d98503c",
"generatedSha256": "91261579fb7d4bada1cd6e09f660397d4cff10838e100157ea375e48ec38d365",
"bodySha256": "91261579fb7d4bada1cd6e09f660397d4cff10838e100157ea375e48ec38d365"
}
],
"external": [
{
"from": "yCSh",
"dependency": "react",
"id": "n8MK"
},
{
"from": "yCSh",
"dependency": "emotion-theming",
"id": "pufF"
},
{
"from": "VJzx",
"dependency": "react-inspector",
"id": "kuYm"
},
{
"from": "MnJh",
"dependency": "@emotion/styled",
"id": "IX9o"
},
{
"from": "VMze",
"dependency": "react",
"id": "n8MK"
},
{
"from": "VMze",
"dependency": "emotion-theming",
"id": "pufF"
},
{
"from": "ftAA",
"dependency": "react",
"id": "n8MK"
},
{
"from": "CwU9",
"dependency": "linkifyjs/html",
"id": "SbWR"
},
{
"from": "LmXR",
"dependency": "react",
"id": "n8MK"
},
{
"from": "LmXR",
"dependency": "emotion-theming",
"id": "pufF"
},
{
"from": "LmXR",
"dependency": "linkifyjs/react",
"id": "h3Cb"
},
{
"from": "j7Pd",
"dependency": "emotion-theming",
"id": "pufF"
},
{
"from": "j7Pd",
"dependency": "react",
"id": "n8MK"
},
{
"from": "j7Pd",
"dependency": "react-inspector",
"id": "kuYm"
},
{
"from": "swKK",
"dependency": "react",
"id": "n8MK"
},
{
"from": "swKK",
"dependency": "linkifyjs/react",
"id": "h3Cb"
}
],
"notice": {
"source": "refactor/baselines/site-vendor/console-feed-3.2.2-LICENSE.txt",
"member": "package/LICENSE",
"sha256": "52412d7bc7ce4157ea628bbaacb8829e0a9cb3c58f57f99176126bc8cf2bfc85",
"status": "Preserved verbatim upstream MIT text and Facebook attribution. Full bundled-component provenance/attribution remains open, including embedded replicator and all external dependencies."
},
"limits": [
"32 console-feed module bodies match; 68 other vendor modules and the Parcel wrapper still require complete attribution/provenance.",
"No complete license closure or runtime update.",
"No execution of archived console-feed runtime during reconstruction."
]
}
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Facebook, Inc. and its affiliates.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
@@ -0,0 +1,34 @@
# SITE-07 console-feed 源码重建检查点
官方 npm console-feed 3.2.2 归档通过 SHA-512 SRI 校验。由 m6b6 沿全部相对依赖
遍历得到 32 个模块;使用官方 Terser 3.17.0 和 Parcel 1.12.5 中的压缩参数,
32 个输出函数体与冻结 console bundle 全部逐字一致。原始归档、成员和编译结果
指纹、外部依赖边界见[来源记录](../baselines/console-feed-provenance.json)。
这是直接源码匹配证据;没有找回原始安装锁,也不能证明同样代码不存在于其他
历史版本。记录中的 Parcel 是能复现的参数来源,不冒充已确认的原始构建版本。
完整 console 有 100 个第三方模块,剩余 68 个及 Parcel wrapper 仍需来源核查。
## 实现与验证
provenance.ts 提取固定模块表并验证完整遍历、源文件映射、外部依赖、源码与输出
哈希和实际字节。reproduce.ts 通过显式 --fetch 准备两个固定归档,随后可完全
离线重建;只加载已校验的历史编译器,不执行 console-feed 的运行时代码,不安装
依赖。既有 source-map 0.6.1 来自根 Yarn 锁及已安装树,版本不符会拒绝。
首次下载重建和离线重建均为 32/32 精确匹配。新增反例覆盖归档变更、弱 SRI、
缺模块/映射、重复/不可达条目、外部边界漂移、源码/编译输出/旧函数体漂移。
控制台单元共 9/9 通过,严格 docs-tools TS、相关 lint 和 build:console --check
通过。初期使用当前 Terser 5.51.2 产生形式差异;未因此放宽比较,而是读取历史
Parcel 的压缩器依赖及参数,最终获得字节一致。初次归档路径误选目录和两处 lint
格式错误已修正,不影响最终结果。
上游 LICENSE 原文已保存,保留其中 Facebook 署名。其嵌入 replicator 和其他
组件的来源/署名仍未全部审查,不把单个 MIT 文件当作整个 console 的完整许可。
VENDOR-08 保持 open;SITE-07 保持 doing,完成任务数仍为 199/265。
本批没有改动站点运行时、公开 API、依赖清单或锁文件,因此未重复实际页面测试。
上一任务的浏览器证据继续对应相同产物;本批不声称新增浏览器/远端 CI/发布验收。
复现命令和后续维护见[说明](../../scripts/site-vendor/console/README.md)。
回退本检查点只移除复现工具、来源/许可快照、测试和台账更新;不会恢复旧缺陷。
作为 SITE-07 的独立检查点本地提交,无推送或发布。
+3 -2
View File
@@ -10,8 +10,9 @@ SITE-07 冻结原始 bundle 和浏览器契约,SITE-CONSOLE-01 已实现自有
- Focm 是自有安装入口,W5CS 是自有 React 控制台视图,其余模块须继续溯源。
- 实际全局包括 React、ReactDOM、consoleLog 和 parcelRequire。React/ReactDOM
均为 17.0.2,styled-components bundle 声明版本 5.3.3。
- console-feed 的包版本不能只凭年代推定;npm 当时最新版本 3.2.2 是待比对候选,
本批没有确认它就是当前捆绑版本,也没有确认全部传递依赖的版本与许可。
- console-feed 的 32 个模块现已用官方 3.2.2 归档精确重建,见
[来源记录](baselines/console-feed-provenance.json)。这证明源码匹配,不代表找回
原始 lockfile 或证明唯一安装版本;其余传递依赖和完整许可仍待核查。
- 原末尾指向不存在的 /index.js.map。原始 bundle 和模块指纹见
[冻结来源](baselines/site-console-inventory.json)。
+1 -1
View File
@@ -653,7 +653,7 @@
- SITE-AI-DOCS-01: [记录](changes/2026-09-14-SITE-AI-DOCS-01-documentation-pipeline.md) [记录](baselines/documentation-pipeline-validation.json)
- SITE-BUILD-01: [记录](changes/2026-09-14-SITE-BUILD-01-staged-builds.md) [记录](baselines/site-build-validation.json)
- SITE-03: [记录](changes/2026-09-14-SITE-03-desktop-editor.md) [记录](baselines/site-editor-validation.json)
- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json) [记录](changes/2026-09-14-SITE-07-vendor-notices.md) [记录](baselines/site-notices-checkpoint.json) [记录](baselines/site-codicons-provenance.json) [记录](baselines/site-codicons-validation.json) [记录](changes/2026-09-15-SITE-07-codicons.md) [记录](baselines/vconsole-notices-provenance.json) [记录](baselines/vconsole-notices-validation.json) [记录](changes/2026-09-15-SITE-07-vconsole-notices.md) [记录](console-modernization.md) [记录](baselines/site-console-inventory.json) [记录](baselines/site-console-validation.json) [记录](changes/2026-09-15-SITE-07-console-baseline.md)
- SITE-07: [记录](site-inventory.md) [记录](baselines/site-provenance.json) [记录](changes/2026-09-14-SITE-07-vendor-notices.md) [记录](baselines/site-notices-checkpoint.json) [记录](baselines/site-codicons-provenance.json) [记录](baselines/site-codicons-validation.json) [记录](changes/2026-09-15-SITE-07-codicons.md) [记录](baselines/vconsole-notices-provenance.json) [记录](baselines/vconsole-notices-validation.json) [记录](changes/2026-09-15-SITE-07-vconsole-notices.md) [记录](console-modernization.md) [记录](baselines/site-console-inventory.json) [记录](baselines/site-console-validation.json) [记录](changes/2026-09-15-SITE-07-console-baseline.md) [记录](baselines/console-feed-provenance.json) [记录](changes/2026-09-15-SITE-07-console-feed-source.md)
- EX-01: [记录](changes/2026-09-14-EX-01-react-consumer.md) [记录](baselines/react-consumer-validation.json) [记录](scripts/react-consumer.mjs)
- EX-02: [记录](changes/2026-09-14-EX-02-vue-consumer.md) [记录](baselines/vue-consumer-validation.json) [记录](scripts/vue-consumer.mjs)
- MOD-01: [记录](changes/2026-09-15-MOD-01-bun-evaluation.md) [记录](baselines/bun-install-validation.json) [记录](bun-evaluation.md)
+7
View File
@@ -1,5 +1,12 @@
# 进度与证据
## SITE-07 console-feed 32 模块精确重建
官方 npm 3.2.2 的 32 个模块使用历史压缩配置全部重建为旧 bundle 原字节;首次
下载和离线复现均通过,新增完整依赖遍历及篡改反例,单元 9/9。来源与许可原文
已保存,见[记录](changes/2026-09-15-SITE-07-console-feed-source.md)。其余 68 个
第三方模块/Parcel 和完整许可仍开放;SITE-07 doing,仍为199/265,无运行时变更。
## SITE-CONSOLE-01 自有 TS 控制台与三项修复
完成入口/视图/订阅/错误/样式/类型拆分,保留原 React17 与 100 个第三方模块。
+6 -2
View File
@@ -681,11 +681,15 @@
"refactor/baselines/site-console-inventory.json",
"refactor/baselines/site-console-validation.json",
"refactor/changes/2026-09-15-SITE-07-console-baseline.md",
"test/browser/site-console.spec.js"
"test/browser/site-console.spec.js",
"refactor/baselines/console-feed-provenance.json",
"refactor/changes/2026-09-15-SITE-07-console-feed-source.md",
"scripts/site-vendor/console/provenance.ts",
"scripts/site-vendor/console/reproduce.ts"
],
"compatibleResolution": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
"closureCriteria": "固定上游版本/内容差异、完整组件许可与分发 notices,兼容测试通过;仅当前上游许可证名称不足以关闭。",
"workspaceState": "Frozen 102-module Parcel bundle and real React 17.0.2/global/component/DOM behavior are recorded. Three lifecycle/error defects are separately reproduced. Remaining dependency versions, complete notices and reproducible source remain open; no runtime replacement yet."
"workspaceState": "32 console-feed modules match official 3.2.2 archive exactly under a verified historical transform. Other 68 vendor modules, Parcel wrapper, original lockfile and complete attribution remain open. Runtime files unchanged in this checkpoint."
},
{
"id": "SDK-01",
+3 -1
View File
@@ -4488,7 +4488,9 @@
"console-modernization.md",
"baselines/site-console-inventory.json",
"baselines/site-console-validation.json",
"changes/2026-09-15-SITE-07-console-baseline.md"
"changes/2026-09-15-SITE-07-console-baseline.md",
"baselines/console-feed-provenance.json",
"changes/2026-09-15-SITE-07-console-feed-source.md"
]
},
{
+7 -3
View File
@@ -1060,9 +1060,13 @@
"owners": [
"SITE-01"
],
"sourceStatus": "Frozen original 340306-byte Parcel bundle e00bbf82bf08c452825690372ded39a9b60f4baf438f0e7ce8300e9bc4629c03; 102-module map, Focm entry/W5CS view, React 17.0.2 globals and styled-components 5.3.3 literal identified. Full dependency versions and source reconstruction remain open. SITE-CONSOLE-01 replaces only Focm/W5CS bodies from owned TS and removes the missing source-map trailer; other 100 modules and runtime remain byte-for-byte frozen. Full vendor provenance remains open.",
"licenseStatus": "Root MIT is not sufficient evidence for all bundled components; inventory and notices pending.",
"upstreamSources": [],
"sourceStatus": "Frozen original 340306-byte Parcel bundle e00bbf82bf08c452825690372ded39a9b60f4baf438f0e7ce8300e9bc4629c03; 102-module map, Focm entry/W5CS view, React 17.0.2 globals and styled-components 5.3.3 literal identified. Full dependency versions and source reconstruction remain open. SITE-CONSOLE-01 replaces only Focm/W5CS bodies from owned TS and removes the missing source-map trailer; other 100 modules and runtime remain byte-for-byte frozen. Full vendor provenance remains open. Official console-feed 3.2.2 archive reproduces all 32 relative-import module bodies exactly with verified Terser 3.17.0/Parcel 1.12.5 transform settings; 68 vendor modules and wrapper remain. This does not recover the original lockfile or establish a unique installed version.",
"licenseStatus": "Official console-feed 3.2.2 MIT LICENSE preserved verbatim, including Facebook attribution. Embedded replicator and all external/remaining component notices still require review; no full closure.",
"upstreamSources": [
"https://registry.npmjs.org/console-feed/-/console-feed-3.2.2.tgz",
"https://registry.npmjs.org/terser/-/terser-3.17.0.tgz",
"https://registry.npmjs.org/parcel-bundler/-/parcel-bundler-1.12.5.tgz"
],
"upstreamReviewedAt": null,
"updatePolicy": "Keep separate from owned TS migration. Verify source/version/diff and license notices before replacement; preserve API/CSS/worker URLs and run owning package tests.",
"fingerprints": [
+31
View File
@@ -67,3 +67,34 @@ No new dependency is required. Existing esbuild 0.27.7 and TypeScript 5.9.3 prov
generation and structural parsing. Full console dependency provenance and notices
remain SITE-07 / VENDOR-08; this build does not close them. See
`refactor/console-modernization.md` for contracts and evidence.
## Historical source reconstruction
`refactor/baselines/console-feed-provenance.json` maps all 32 modules reachable
through relative imports from m6b6 to the official console-feed 3.2.2 archive.
Their rebuilt bodies exactly match the frozen bundle. The 68 remaining vendor
modules and Parcel wrapper need further provenance; this does not establish a
unique original installed version or recover its missing lockfile.
```sh
node scripts/site-vendor/console/reproduce.ts --fetch
node scripts/site-vendor/console/reproduce.ts
yarn test:site-console
```
The first command downloads two pinned npm archives into the dedicated ignored
`refactor/.cache/console-feed-reproduction/` directory. The second uses that cache
offline. Both verify SHA-512 SRI, archive SHA-256, source member fingerprints,
compiler bytes and exact output. They load Terser 3.17.0 as a historical build
tool with the already installed source-map 0.6.1; they do not install dependencies,
change Yarn or execute the archived console-feed runtime. Canonical Node is required.
The minification recipe is recovered from Parcel 1.12.5's archive; this proves a
reproducing transform, not that the original author used precisely that Parcel
version. `provenance.ts` separately verifies complete traversal, relative source
mapping and external dependency boundaries. Missing, unreachable, duplicate or
changed evidence fails instead of silently shrinking the comparison.
The archived LICENSE is preserved verbatim with its Facebook attribution under
`refactor/baselines/site-vendor/console-feed-3.2.2-LICENSE.txt`. Do not rewrite it
or infer it covers every embedded/external component. Complete notices remain
open, including the bundled replicator and remaining dependencies.
+84
View File
@@ -0,0 +1,84 @@
import assert from 'node:assert/strict'
import { createHash } from 'node:crypto'
import path from 'node:path'
import ts from 'typescript'
export interface Module { id: string, body: string, dependencies: Record<string, string> }
export interface Source { id: string, member: string, sourceSha256: string, generatedSha256: string, bodySha256: string }
export interface External { from: string, dependency: string, id: string }
export interface Archive { name: string, version: string, tarball: string, integrity: string, sha256: string }
export const hash = (bytes: string | Uint8Array) => createHash('sha256').update(bytes).digest('hex')
export function verifyArchive(bytes: Uint8Array, archive: Archive) {
const [algorithm, expected] = archive.integrity.split('-')
assert(algorithm === 'sha512' && expected, 'Expected SHA-512 archive integrity')
assert.equal(createHash(algorithm).update(bytes).digest('base64'), expected, `Archive integrity changed: ${archive.name}`)
assert.equal(hash(bytes), archive.sha256, `Archive bytes changed: ${archive.name}`)
}
export function parcelModules(text: string): Map<string, Module> {
const source = ts.createSourceFile('console.js', text, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS)
let table: ts.ObjectLiteralExpression | undefined
function visit(node: ts.Node) {
if (ts.isObjectLiteralExpression(node) && node.properties.some(property => property.name && ts.isStringLiteral(property.name) && property.name.text === 'Focm')) {
assert(!table, 'Duplicate Parcel module tables')
table = node
}
ts.forEachChild(node, visit)
}
visit(source)
assert(table, 'Missing Parcel module table')
const result = new Map<string, Module>()
for (const property of table.properties) {
assert(ts.isPropertyAssignment(property) && ts.isStringLiteral(property.name) && ts.isArrayLiteralExpression(property.initializer))
const [fn, deps] = property.initializer.elements
assert(fn && ts.isFunctionExpression(fn) && deps && ts.isObjectLiteralExpression(deps))
const id = property.name.text
assert(!result.has(id), `Duplicate Parcel module: ${id}`)
const dependencies: Record<string, string> = {}
for (const dep of deps.properties) {
assert(ts.isPropertyAssignment(dep) && ts.isStringLiteral(dep.name) && ts.isStringLiteral(dep.initializer))
assert(!(dep.name.text in dependencies), 'Duplicate Parcel dependency')
dependencies[dep.name.text] = dep.initializer.text
}
result.set(id, { id, dependencies, body: text.slice(fn.body.getStart(source) + 1, fn.body.end - 1).trim() })
}
return result
}
export function verifyModules(modules: Map<string, Module>, sources: Source[], external: External[], read: (member: string) => string, compile: (source: string) => string) {
const mapped = new Map(sources.map(source => [source.id, source]))
assert.equal(mapped.size, sources.length, 'Duplicate source mapping')
const visited = new Set<string>()
const dependencies: External[] = []
function visit(id: string) {
if (visited.has(id))
return
const item = mapped.get(id)
const module = modules.get(id)
assert(item && module, `Missing console-feed module mapping: ${id}`)
assert(item.member.startsWith('package/lib/') && item.member.endsWith('.js') && path.posix.normalize(item.member) === item.member, 'Invalid source member')
visited.add(id)
const source = read(item.member)
assert.equal(hash(source), item.sourceSha256, `Source changed: ${item.member}`)
const compiled = compile(source)
assert.equal(hash(compiled), item.generatedSha256, `Compiler output changed: ${id}`)
assert.equal(hash(module.body), item.bodySha256, `Frozen module changed: ${id}`)
assert.equal(compiled, module.body, `Rebuilt module differs: ${id}`)
for (const [dependency, child] of Object.entries(module.dependencies)) {
assert(modules.has(child), `Unresolved Parcel dependency: ${child}`)
if (!dependency.startsWith('.')) {
dependencies.push({ from: id, dependency, id: child })
continue
}
const base = path.posix.join(path.posix.dirname(item.member), dependency)
const target = mapped.get(child)?.member
assert(target && [base, `${base}.js`, `${base}/index.js`].includes(target), `Source dependency mapping changed: ${id} ${dependency}`)
visit(child)
}
}
visit('m6b6')
assert.equal(visited.size, sources.length, 'Unreachable source mapping')
assert.deepEqual(dependencies, external, 'External dependency boundary changed')
return visited.size
}
+60
View File
@@ -0,0 +1,60 @@
import type { Archive, External, Source } from './provenance.ts'
import assert from 'node:assert/strict'
import { execFileSync } from 'node:child_process'
import fs from 'node:fs'
import { createRequire } from 'node:module'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath } from 'node:url'
import { hash, parcelModules, verifyArchive, verifyModules } from './provenance.ts'
interface CompilerOptions { warnings: boolean, safari10: boolean, mangle: { toplevel: boolean } }
interface Provenance {
archive: Archive
frozen: { path: string, sha256: string }
compiler: { archive: Archive, member: string, sha256: string, sourceMapVersion: string, options: CompilerOptions }
sources: Source[]
external: External[]
}
interface Minifier { minify: (source: string, options: CompilerOptions) => { code?: string, error?: unknown } }
const root = fileURLToPath(new URL('../../../', import.meta.url))
const record: Provenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-feed-provenance.json'), 'utf8'))
assert(process.argv.slice(2).every(arg => arg === '--fetch'), 'Use reproduce.ts [--fetch]')
assert.equal(process.version, `v${fs.readFileSync(path.join(root, '.node-version'), 'utf8').trim()}`, 'Use canonical Node')
const cacheRoot = fs.realpathSync(path.join(root, 'refactor/.cache'))
const cache = path.join(cacheRoot, 'console-feed-reproduction')
fs.mkdirSync(cache, { recursive: true })
assert.equal(fs.realpathSync(cache), cache, 'Reproduction cache must not redirect')
for (const archive of [record.archive, record.compiler.archive]) {
const target = path.join(cache, `${archive.name}-${archive.version}.tgz`)
if (process.argv.includes('--fetch')) {
const response = await fetch(archive.tarball)
assert(response.ok, `Archive request failed: ${response.status}`)
const bytes = new Uint8Array(await response.arrayBuffer())
verifyArchive(bytes, archive)
fs.writeFileSync(target, bytes)
}
verifyArchive(fs.readFileSync(target), archive)
}
const readMember = (name: string, member: string) => execFileSync('tar', ['-xOzf', path.join(cache, name), member], { maxBuffer: 8 * 1024 * 1024 })
const compilerBytes = readMember('terser-3.17.0.tgz', record.compiler.member)
assert.equal(hash(compilerBytes), record.compiler.sha256, 'Compiler member changed')
const compilerPath = path.join(cache, 'terser.cjs')
fs.writeFileSync(compilerPath, compilerBytes)
const require = createRequire(compilerPath)
assert.equal(require('source-map/package.json').version, record.compiler.sourceMapVersion, 'Source-map dependency changed')
const { minify } = require(compilerPath) as Minifier
const frozen = fs.readFileSync(path.join(root, record.frozen.path), 'utf8')
assert.equal(hash(frozen), record.frozen.sha256, 'Frozen console changed')
assert.equal(record.sources.length, 32, 'Incomplete console-feed scope')
const count = verifyModules(parcelModules(frozen), record.sources, record.external, member => readMember('console-feed-3.2.2.tgz', member).toString('utf8'), (source) => {
const result = minify(source, record.compiler.options)
if (result.error)
throw result.error
assert(typeof result.code === 'string')
return result.code
})
console.log(JSON.stringify({ exactModules: count, totalVendorModules: 100, archive: record.archive.sha256, licenseClosure: false }))
+40
View File
@@ -1,4 +1,5 @@
import assert from 'node:assert/strict'
import { Buffer } from 'node:buffer'
import { createHash } from 'node:crypto'
import fs from 'node:fs'
import process from 'node:process'
@@ -6,6 +7,7 @@ import process from 'node:process'
import test from 'node:test'
import ts from 'typescript'
import { generateConsole, moduleRanges, obsoleteMap, upstreamSha256 } from '../scripts/site-vendor/console/build.ts'
import { hash, parcelModules, verifyArchive, verifyModules } from '../scripts/site-vendor/console/provenance.ts'
import { errorArgument } from '../scripts/site-vendor/console/runtime/errors.ts'
import { css } from '../scripts/site-vendor/console/runtime/style.ts'
import { createSubscriptions } from '../scripts/site-vendor/console/runtime/subscriptions.ts'
@@ -175,3 +177,41 @@ test('Console build changes only the two owned module bodies and is deterministi
assert.notEqual(candidate, source)
assert.throws(() => moduleRanges('var unrelated = 1'), /Missing owned/)
})
test('Console provenance rejects altered archive bytes and non-SHA512 integrity', () => {
const bytes = Buffer.from('verified archive')
const archive = { name: 'fixture', sha256: hash(bytes), integrity: `sha512-${createHash('sha512').update(bytes).digest('base64')}` }
verifyArchive(bytes, archive)
assert.throws(() => verifyArchive(Buffer.from('changed archive'), archive), /integrity changed/)
assert.throws(() => verifyArchive(bytes, { ...archive, sha256: 'wrong' }), /bytes changed/)
assert.throws(() => verifyArchive(bytes, { ...archive, integrity: 'sha1-weak' }), /Expected SHA-512/)
})
test('Console provenance extracts the frozen 102 modules without executing vendor code', () => {
const source = fs.readFileSync('refactor/baselines/site-vendor/console-original.js', 'utf8')
const modules = parcelModules(source)
assert.equal(modules.size, 102)
assert.equal(modules.get('m6b6').dependencies['./Hook'], 'pYO5')
assert.throws(() => parcelModules('const unrelated = 1'), /Missing Parcel/)
assert.throws(() => parcelModules('({"Focm":[function(){},{}],"Focm":[function(){},{}]})'), /Duplicate Parcel module/)
})
test('Console provenance requires exact source, compiler output, dependency mapping and complete reachability', () => {
const root = { id: 'm6b6', body: 'exports.value=1;', dependencies: { './child': 'child', 'react': 'react' } }
const child = { id: 'child', body: 'exports.child=2;', dependencies: {} }
const modules = new Map([root, child, { id: 'react', body: '', dependencies: {} }].map(module => [module.id, module]))
const sources = [root, child].map(module => ({ id: module.id, member: `package/lib/${module.id === 'm6b6' ? 'index' : module.id}.js`, sourceSha256: hash(module.body), generatedSha256: hash(module.body), bodySha256: hash(module.body) }))
const external = [{ from: 'm6b6', dependency: 'react', id: 'react' }]
const read = member => member.endsWith('index.js') ? root.body : child.body
assert.equal(verifyModules(modules, sources, external, read, source => source), 2)
assert.throws(() => verifyModules(modules, sources, external, () => 'changed', source => source), /Source changed/)
assert.throws(() => verifyModules(modules, sources, external, read, () => 'changed'), /Compiler output changed/)
assert.throws(() => verifyModules(modules, [sources[0]], external, read, source => source), /Source dependency mapping changed/)
assert.throws(() => verifyModules(modules, [...sources, sources[0]], external, read, source => source), /Duplicate source/)
assert.throws(() => verifyModules(modules, [...sources, { ...sources[0], id: 'unused' }], external, read, source => source), /Unreachable/)
assert.throws(() => verifyModules(modules, sources, [], read, source => source), /External dependency boundary/)
const bad = [{ ...sources[0], member: 'package/lib/../escape.js' }, sources[1]]
assert.throws(() => verifyModules(modules, bad, external, read, source => source), /Invalid source member/)
modules.set('child', { ...child, body: 'changed' })
assert.throws(() => verifyModules(modules, sources, external, read, source => source), /Frozen module changed/)
})