diff --git a/docs/THIRD_PARTY_NOTICES.md b/docs/THIRD_PARTY_NOTICES.md index 18dba8173..9f6919637 100644 --- a/docs/THIRD_PARTY_NOTICES.md +++ b/docs/THIRD_PARTY_NOTICES.md @@ -80,7 +80,7 @@ Source: https://registry.npmjs.org/@vscode/codicons/-/codicons-0.0.26.tgz Source: https://github.com/zhw2590582/ArtPlayer/blob/5d6b2f22bc75213ac97cff0bcffa4a1ce2bc786c/docs/assets/js/console.js -The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Package license texts and two embedded license headers below are preserved verbatim. Embedded attribution review is still incomplete; this inventory is not publication clearance. +The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Preserved notices also cover two embedded license headers, all 17 react-inspector external source-map members, and all seven HTML tokenizer sources from its fixed Git dependency. Embedded attribution review is still incomplete; this inventory is not publication clearance. Included component: console-feed 3.2.2 @@ -222,6 +222,18 @@ Included component: stylis-rule-sheet embedded in styled-components-5.3.3 Source: https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.tgz +Included component: @babel/runtime (react-inspector embedded) 7.13.10 + +Source: https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz + +Included component: regenerator-runtime 0.13.7 + +Source: https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz + +Included component: simple-html-tokenizer git-04799f4638ec5ed903a4e5aa6e832269fa59be6b + +Source: https://api.github.com/repos/nfrasser/simple-html-tokenizer/tarball/04799f4638ec5ed903a4e5aa6e832269fa59be6b + - licenses/console/console-feed/console-feed-3.2.2-LICENSE - licenses/console/react/react-17.0.2-LICENSE - licenses/console/react-dom/react-dom-17.0.2-LICENSE @@ -257,3 +269,6 @@ Source: https://registry.npmjs.org/styled-components/-/styled-components-5.3.3.t - licenses/console/parcel-bundler/parcel-bundler-1.12.5-LICENSE - licenses/console/chromium-string-utils/LICENSE - licenses/console/stylis-rule-sheet/LICENSE +- licenses/console/react-inspector-babel/LICENSE +- licenses/console/regenerator-runtime/LICENSE +- licenses/console/simple-html-tokenizer/LICENSE diff --git a/docs/licenses/console/react-inspector-babel/LICENSE b/docs/licenses/console/react-inspector-babel/LICENSE new file mode 100644 index 000000000..f31575ec7 --- /dev/null +++ b/docs/licenses/console/react-inspector-babel/LICENSE @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2014-present Sebastian McKenzie and other contributors + +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. diff --git a/docs/licenses/console/regenerator-runtime/LICENSE b/docs/licenses/console/regenerator-runtime/LICENSE new file mode 100644 index 000000000..cde61b6c5 --- /dev/null +++ b/docs/licenses/console/regenerator-runtime/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2014-present, Facebook, Inc. + +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. diff --git a/docs/licenses/console/simple-html-tokenizer/LICENSE b/docs/licenses/console/simple-html-tokenizer/LICENSE new file mode 100644 index 000000000..331ab974f --- /dev/null +++ b/docs/licenses/console/simple-html-tokenizer/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Yehuda Katz and contributors + +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. diff --git a/refactor/baselines/console-embedded-notices.json b/refactor/baselines/console-embedded-notices.json index c4690af90..b6d86c28d 100644 --- a/refactor/baselines/console-embedded-notices.json +++ b/refactor/baselines/console-embedded-notices.json @@ -28,13 +28,13 @@ "status": "partial", "confirmed": [ "Chromium copyright and full BSD conditions in console-feed source", - "Sultan Tarimo MIT header in styled-components embedded rule-sheet source" + "Sultan Tarimo MIT header in styled-components embedded rule-sheet source", + "All seven linkifyjs simple-html-tokenizer files exactly reproduce from its fixed Git dependency with Babel 6.26.0; Yehuda Katz license preserved.", + "All 17 react-inspector external source-map members exactly match Babel runtime 7.13.10 and regenerator-runtime 0.13.7; both licenses preserved." ], "pending": [ "console-feed replicator upstream attribution", - "linkifyjs simple-html-tokenizer attribution", "Emotion stylis/hash and cache rule-sheet attribution", - "react-inspector embedded Babel/regenerator source and notices", "console-feed Component Stack Overflow attribution and any additional embedded sources" ] } diff --git a/refactor/baselines/console-embedded-sources.json b/refactor/baselines/console-embedded-sources.json new file mode 100644 index 000000000..f07592fdf --- /dev/null +++ b/refactor/baselines/console-embedded-sources.json @@ -0,0 +1,323 @@ +{ + "schemaVersion": 1, + "task": "SITE-07", + "archives": [ + { + "id": "%40babel%2Fruntime-7.13.10", + "name": "@babel/runtime", + "version": "7.13.10", + "tarball": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "integrity": "sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==", + "sha256": "19797609e1814e3d5a68f6859db1150ae979995ff0dfc9aca3d2e037df58e814", + "notices": [ + { + "member": "package/LICENSE", + "source": "refactor/baselines/site-vendor/console-embedded/babel-runtime-7.13.10-LICENSE.txt", + "sha256": "117da2af0d4ce0fe1c8e19b5cff9dcd806adf973d328d27b11d4448c4ff24f76" + } + ] + }, + { + "id": "regenerator-runtime-0.13.7", + "name": "regenerator-runtime", + "version": "0.13.7", + "tarball": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", + "sha256": "b5cd4cf6502afafd8464fe159b1af0d8db0301d71952de4a54d00394f7d2a14e", + "notices": [ + { + "member": "package/LICENSE", + "source": "refactor/baselines/site-vendor/console-embedded/regenerator-runtime-0.13.7-LICENSE.txt", + "sha256": "51887a3d47051ac2fce1210562e5b9fe0830a8a8fabeb272c2d586eeb18a05fd" + } + ] + }, + { + "id": "simple-html-tokenizer-git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "name": "simple-html-tokenizer", + "version": "git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "tarball": "https://api.github.com/repos/nfrasser/simple-html-tokenizer/tarball/04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "integrity": "sha512-ycOYAm+pFzyErUKFvtkB7ntoiQ+aq4He+ZrT6McOGCDqyKCiNxEpARv6z7pBZXpVR5LPuxnt5hibOGICXl5HVw==", + "sha256": "c597f7785650bf1068acad7fee70bbaa4c55017ce3e073b6f4c1f25dd9da6eea", + "commit": "04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "integritySource": "Locally measured SHA-512/SHA-256 of the archive at the exact Git dependency commit in linkifyjs 2.1.9; not npm registry SRI.", + "notices": [ + { + "member": "nfrasser-simple-html-tokenizer-04799f4/LICENSE", + "source": "refactor/baselines/site-vendor/console-embedded/simple-html-tokenizer-04799f4-LICENSE.txt", + "sha256": "c41881de2a9f2200936648343500524be154eb79f649582f9582dd251b051b11" + } + ] + } + ], + "compiler": { + "archive": { + "id": "babel-standalone-6.26.0", + "name": "babel-standalone", + "version": "6.26.0", + "tarball": "https://registry.npmjs.org/babel-standalone/-/babel-standalone-6.26.0.tgz", + "integrity": "sha512-zT4CJM9TK6uEaPf7+nKVO/yPYNlk5G9Aa4+iYwmn7J4D9eezb62eQ3bSUybK/AcPHU2VkfFuIDKbvwQOOj+Zyw==", + "sha256": "a91ea22e279d85269582896b1dc2c3519d20778919dc3721652dc79de24ccca8" + }, + "member": "package/babel.min.js", + "sha256": "16264c935ce04deba3cdfffebe899664667daf4d3ec671af3a05e88f4268d630", + "version": "6.26.0", + "options": { + "presets": [ + [ + "es2015", + { + "loose": true + } + ] + ] + } + }, + "sourceMaps": [ + { + "source": { + "archive": "react-inspector-5.1.1", + "member": "package/dist/es/react-inspector.js.map", + "sha256": "92b60e8482e52d5247bcf97d180701f53b320ebecffc3d78a5d67beae3f279a3" + }, + "externalPrefix": "../../node_modules/", + "sources": [ + { + "path": "../../node_modules/@babel/runtime/helpers/extends.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/extends.js", + "sha256": "02a07f0d08b2ab260ef5a04bcc4aaf412b7c6a3ae653fcd865cb6225aea4ff9a" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/objectWithoutPropertiesLoose.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/objectWithoutPropertiesLoose.js", + "sha256": "0abc21ffb41814bc74ca92535592db1226c800dcead3edaab5eee9b5b084000b" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/objectWithoutProperties.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/objectWithoutProperties.js", + "sha256": "92744c7cf8c55dd284aeec8ec7141bf2eb747a8128c2773b63ab30deb34f9adc" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/arrayWithHoles.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/arrayWithHoles.js", + "sha256": "430249ac5055b67aec593cd990238683fa20d0bfe632c2901d83a4ab3e59044e" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/iterableToArrayLimit.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/iterableToArrayLimit.js", + "sha256": "2a955d4fbce0b609f30b563a56be9cbd184e2e2c9f19f215a9da4f0f6df2d990" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/arrayLikeToArray.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/arrayLikeToArray.js", + "sha256": "d753748855dcc78b6cb565b7eaa7ba4d19dccf22a797fc3b20315d77c6b7f339" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/unsupportedIterableToArray.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/unsupportedIterableToArray.js", + "sha256": "823ac36c880f97e0ab343b666363dafc5c5ba653613ae509530f481caacb0747" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/nonIterableRest.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/nonIterableRest.js", + "sha256": "54686eeb5ec02f1f55440a380ed39e52a45e56c3685ebf47b1b36db31ca84f30" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/slicedToArray.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/slicedToArray.js", + "sha256": "eb359972ab03c433d01a85ed7e7d0a4c5bd26e5c87d56cc4f9413cfb4b8aa368" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/typeof.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/typeof.js", + "sha256": "4f974e1b2d593668b64d573e458cd7d789cb1be1e23272bbc230b2a654fe69f4" + } + }, + { + "path": "../../node_modules/regenerator-runtime/runtime.js", + "upstream": { + "archive": "regenerator-runtime-0.13.7", + "member": "package/runtime.js", + "sha256": "2d81987ea861c76c2a855617075f9298f6cd09c32be95d730011a19255a4ef4d" + } + }, + { + "path": "../../node_modules/@babel/runtime/regenerator/index.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/regenerator/index.js", + "sha256": "70482fcb02ddf80fb8e8b9e7547d9c0328ebff0baea1ac8f3765fd0972aeed94" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/arrayWithoutHoles.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/arrayWithoutHoles.js", + "sha256": "60b51d971d357fe4f0eab05a2bcbf6f392b51853d4ea93c3a139d276c6c2ca90" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/iterableToArray.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/iterableToArray.js", + "sha256": "8c7d880e0d9f0535ad7cdd986df6c1dd1284651efe1b618ed1863877d9fa5767" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/nonIterableSpread.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/nonIterableSpread.js", + "sha256": "9500aa1aee50ce5ea8594263d82311ab8f48ff50db7a681a1ae40e82d20376d2" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/toConsumableArray.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/toConsumableArray.js", + "sha256": "fa8e9eb0aafb0d63d8dae3b966cfedb1cf7102a4833facc3422dba1b2cf686de" + } + }, + { + "path": "../../node_modules/@babel/runtime/helpers/defineProperty.js", + "upstream": { + "archive": "%40babel%2Fruntime-7.13.10", + "member": "package/helpers/defineProperty.js", + "sha256": "26989e9a8f63bf988d4788071e939235b2126ab96970bd9249c8a216011759ed" + } + } + ] + } + ], + "tokenizer": { + "dependency": { + "archive": "linkifyjs-2.1.9", + "member": "package/package.json", + "sha256": "25a59be5a38b3bf4e8257ac802c239fcef0f84dc7f1ddee84ac58ff6c0bb1b2b" + }, + "value": "git+https://github.com/nfrasser/simple-html-tokenizer.git#04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "sources": [ + { + "source": { + "archive": "simple-html-tokenizer-git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "member": "nfrasser-simple-html-tokenizer-04799f4/lib/simple-html-tokenizer/entity-parser.js", + "sha256": "6ef5badc8960148ec8b2e2b08a8877b91b081b9d4b0fb00512473d5213c16a89" + }, + "target": { + "archive": "linkifyjs-2.1.9", + "member": "package/lib/simple-html-tokenizer/entity-parser.js", + "sha256": "60d9d369600dd7802a3c9ca343fec67030b1cce3f79625d441194c69bd5315c8" + } + }, + { + "source": { + "archive": "simple-html-tokenizer-git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "member": "nfrasser-simple-html-tokenizer-04799f4/lib/simple-html-tokenizer/evented-tokenizer.js", + "sha256": "22adbef1bcbdeda2619e9b5fb1d1705b788d6950118a8d12990afba9b2ca5896" + }, + "target": { + "archive": "linkifyjs-2.1.9", + "member": "package/lib/simple-html-tokenizer/evented-tokenizer.js", + "sha256": "103bae96d698a2a97187d88a2b0316a62c06abea732050ef5cb8871daae2c188" + } + }, + { + "source": { + "archive": "simple-html-tokenizer-git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "member": "nfrasser-simple-html-tokenizer-04799f4/lib/simple-html-tokenizer/html5-named-char-refs.js", + "sha256": "3b149f4fb8a80f45c8d11e6719ae6125cb7078ae0f6125e8cf28debcc8f92a8f" + }, + "target": { + "archive": "linkifyjs-2.1.9", + "member": "package/lib/simple-html-tokenizer/html5-named-char-refs.js", + "sha256": "1cda52628c0fe26f52159ecfccd27a0f9ec1810c09707977d17647941e5433dc" + } + }, + { + "source": { + "archive": "simple-html-tokenizer-git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "member": "nfrasser-simple-html-tokenizer-04799f4/lib/simple-html-tokenizer/index.js", + "sha256": "5cf11452b324b6675523134da45227ed49e40b96a39a8fa83103c4d86f6dfba9" + }, + "target": { + "archive": "linkifyjs-2.1.9", + "member": "package/lib/simple-html-tokenizer/index.js", + "sha256": "fe32f7187a8519203552c9ef34ec38a9ca8f48f4c2636c32018b1c1e5ad05d9a" + } + }, + { + "source": { + "archive": "simple-html-tokenizer-git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "member": "nfrasser-simple-html-tokenizer-04799f4/lib/simple-html-tokenizer/tokenize.js", + "sha256": "4cd3e81688f5400bb7bf6b7a117eb52abb06bbf81d99c6a3f9dddd5b7c2179a8" + }, + "target": { + "archive": "linkifyjs-2.1.9", + "member": "package/lib/simple-html-tokenizer/tokenize.js", + "sha256": "f2835e77b8f3bce4300c80206862b22b26a92ccb26b3aac2b3c4f281ca0c3534" + } + }, + { + "source": { + "archive": "simple-html-tokenizer-git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "member": "nfrasser-simple-html-tokenizer-04799f4/lib/simple-html-tokenizer/tokenizer.js", + "sha256": "b93c93d7706833a1900170334f38860dda35c347e9e79efd71ac2c711fe7d9bf" + }, + "target": { + "archive": "linkifyjs-2.1.9", + "member": "package/lib/simple-html-tokenizer/tokenizer.js", + "sha256": "6ea4c5117afcc6bbc4ce6b1c55a06a58c994e1807fa1235ca342b71107516734" + } + }, + { + "source": { + "archive": "simple-html-tokenizer-git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "member": "nfrasser-simple-html-tokenizer-04799f4/lib/simple-html-tokenizer/utils.js", + "sha256": "61c17e67cbcc658463e8a18f8b34680315a85ab0708339c01ef74fce079bc936" + }, + "target": { + "archive": "linkifyjs-2.1.9", + "member": "package/lib/simple-html-tokenizer/utils.js", + "sha256": "87a1125b20e60ffe32ecbb40b7605668a0be7e24e56eac112847f34b4169677a" + } + } + ] + }, + "limitations": [ + "Exact source matches establish reproducible embedded content, not the unique original full dependency lockfile.", + "Babel 7.11.2/7.12.5 and 7.14.8/7.16.3 were nonmatching candidates; all 16 embedded Babel members match 7.13.10.", + "Other embedded attribution gates remain open in console-embedded-notices.json." + ] +} diff --git a/refactor/baselines/console-embedded-validation.json b/refactor/baselines/console-embedded-validation.json new file mode 100644 index 000000000..1864fe80b --- /dev/null +++ b/refactor/baselines/console-embedded-validation.json @@ -0,0 +1,93 @@ +{ + "schemaVersion": 1, + "task": "SITE-07", + "status": "checkpoint-incomplete", + "recordedAt": "2026-09-14T23:33:29.867Z", + "baseCommit": "199021c8a95c3de2a0bc2d3eaa3d65dc32a438df", + "node": "v24.21.0", + "sourceFingerprint": { + "manifestSha256": "be1e37845cd3f4dced3eaccfea8a232cb42a629346642cf0b77cc712eee20205", + "sourceRecordSha256": "6dc92b6f05c8f4daeef4920980c00dabf82dc1617b8d4560d99dc8a9d2c3efcf", + "consoleSha256": "5644af7bb35bb6d0bcfa7eeae9a21b406ac4fc1b499a6c797a6534c7d33f0678" + }, + "unit": { + "passed": 22, + "failed": 0, + "log": "refactor/.cache/console-embedded-tests.log" + }, + "reproduction": { + "archives": 39, + "exactModules": 100, + "embeddedNotices": 2, + "mappedMembers": 17, + "transformedMembers": 7, + "offlineLog": "refactor/.cache/console-embedded-reproduce.log", + "fetchLog": "refactor/.cache/console-embedded-fetch.log", + "licenseClosure": false + }, + "browser": { + "report": "refactor/.cache/browser/report.json", + "sha256": "59d219a7f50742e202ad9594d29066a8bad2dec03b13fe1d9be09607e072b33c", + "tests": [ + { + "project": "chromium", + "title": "mobile vConsole shows logs and upstream site notice texts are served unchanged", + "status": "passed", + "retry": 0, + "browser": "153.0.8010.12", + "platform": "win32", + "errors": [], + "consoleErrors": [], + "failedRequests": [ + { + "url": "http://127.0.0.1:8084/test/pattern.mp4", + "resourceType": "media", + "failure": { + "errorText": "net::ERR_ABORTED" + } + } + ] + }, + { + "project": "firefox", + "title": "mobile vConsole shows logs and upstream site notice texts are served unchanged", + "status": "passed", + "retry": 0, + "browser": "155.0", + "platform": "win32", + "errors": [], + "consoleErrors": [], + "failedRequests": [] + }, + { + "project": "webkit", + "title": "mobile vConsole shows logs and upstream site notice texts are served unchanged", + "status": "passed", + "retry": 0, + "browser": "26.6", + "platform": "win32", + "errors": [], + "consoleErrors": [], + "failedRequests": [] + } + ], + "noticeFilesPerEngine": 56 + }, + "checks": [ + "Strict docs-tools TypeScript", + "Scoped source/test/documentation ESLint after top-level function correction", + "Read-only console and site-notice generation checks" + ], + "remaining": [ + "replicator origin and notice", + "Emotion stylis/hash/cache attribution", + "Component Stack Overflow attribution", + "Other site asset provenance tasks" + ], + "limits": [ + "Observed source matches are not proof of the unique original dependency lockfile.", + "Git archive integrity is measured from the immutable Git dependency URL, not npm registry-provided SRI.", + "HTTPS integrations isolated; this is Windows local-page evidence, not physical-device or remote-publish validation.", + "No runtime or lockfile changes, pushes, deployments or publications." + ] +} diff --git a/refactor/baselines/site-vendor/console-embedded/babel-runtime-7.13.10-LICENSE.txt b/refactor/baselines/site-vendor/console-embedded/babel-runtime-7.13.10-LICENSE.txt new file mode 100644 index 000000000..f31575ec7 --- /dev/null +++ b/refactor/baselines/site-vendor/console-embedded/babel-runtime-7.13.10-LICENSE.txt @@ -0,0 +1,22 @@ +MIT License + +Copyright (c) 2014-present Sebastian McKenzie and other contributors + +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. diff --git a/refactor/baselines/site-vendor/console-embedded/regenerator-runtime-0.13.7-LICENSE.txt b/refactor/baselines/site-vendor/console-embedded/regenerator-runtime-0.13.7-LICENSE.txt new file mode 100644 index 000000000..cde61b6c5 --- /dev/null +++ b/refactor/baselines/site-vendor/console-embedded/regenerator-runtime-0.13.7-LICENSE.txt @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2014-present, Facebook, Inc. + +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. diff --git a/refactor/baselines/site-vendor/console-embedded/simple-html-tokenizer-04799f4-LICENSE.txt b/refactor/baselines/site-vendor/console-embedded/simple-html-tokenizer-04799f4-LICENSE.txt new file mode 100644 index 000000000..331ab974f --- /dev/null +++ b/refactor/baselines/site-vendor/console-embedded/simple-html-tokenizer-04799f4-LICENSE.txt @@ -0,0 +1,19 @@ +Copyright (c) 2014 Yehuda Katz and contributors + +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. diff --git a/refactor/changes/2026-09-15-SITE-07-console-embedded-sources.md b/refactor/changes/2026-09-15-SITE-07-console-embedded-sources.md new file mode 100644 index 000000000..58da3588c --- /dev/null +++ b/refactor/changes/2026-09-15-SITE-07-console-embedded-sources.md @@ -0,0 +1,48 @@ +# SITE-07 内嵌 Babel、regenerator 与 tokenizer 精确溯源 + +修改前 HEAD:199021c8a95c3de2a0bc2d3eaa3d65dc32a438df。继续控制台许可审查, +不修改任何站点运行时、自有 TS 逻辑或锁文件。 + +## 核实与实现 + +react-inspector 5.1.1 的官方 ESM source map 包含17个外部源文件。16个 Babel +runtime 成员逐字节匹配7.13.10,regenerator-runtime/runtime.js 匹配0.13.7。 +Babel 7.14.8/7.16.3 的两个 iterable helper 不同;7.11.2/7.12.5 的导出及导入 +形式也不同。保留错误候选说明,不能仅凭库名复用当前版本的来源结论。 + +linkifyjs 2.1.9 发布归档的 devDependencies 明确固定 simple-html-tokenizer +到 nfrasser 分支提交04799f4638ec5ed903a4e5aa6e832269fa59be6b。读取该固定提交的 +归档,用 Babel standalone6.26.0 / es2015 loose 转换,7个文件与发布归档完全 +一致,不归一化空白或导出形式。此编译器只用于来源复现,未替换项目构建工具。 + +新增 embedded-sources.ts 拆分 map 清点与精确转换验证;reproduce.ts 负责编译器、 +归档及许可调度。新增来源记录保存所有成员、映射、输出和许可哈希,并验证发布 +清单中 Git 依赖字符串。Git归档的SRI是本地测量值,明确区别于npm提供的SRI。 +不据此声称恢复了唯一历史安装锁。 + +三个完整许可随站点生成,含 Yehuda Katz and contributors 署名。console当前有 +38份许可文件,全站56份,加总索引57个输出。已有副本的许可文本不改写。 +清单保护、缺失许可测试及公共索引浏览器断言同步扩展。 + +## 验证与限制 + +- Node24.21.0,Yarn1.22.22策略不变,无依赖安装/锁修改。 +- 单元22/22:新增漏列外部源、重复映射、错误版本内容、缺正文、编译输出字节 + 变化/重复目标等反例;新增三组件的防遗漏检查。 +- docs-tools严格TS与相关lint通过;首次lint发现顶层函数写法,已修复。 +- 离线及全39归档联网复现通过:100Parcel模块、加载器及包边、2内嵌许可、17 + map成员、7tokenizer转换精确匹配。联网同时重新核对固定Git归档及上游补充许可。 +- 新生成文件的只读校验通过;本地三浏览器实际交付结果见 + [验证记录](../baselines/console-embedded-validation.json)。测试逐字节比较56份许可, + 同时运行移动日志、原生播放和销毁;外部HTTPS隔离,不声称手机或远端发布验证。 + Chromium记录一次pattern.mp4的ERR_ABORTED;播放和销毁断言通过,未处理页面 + 错误及console error均为空。诊断未包含取消时间,不推定具体取消时刻;许可 + 请求均成功并完成字节比较。 + +源记录见[embedded sources](../baselines/console-embedded-sources.json)。剩余审查 +为replicator、Emotion stylis/hash/cache及Component的Stack Overflow引用,继续 +记在console-embedded-notices.json。VENDOR-08 open、SITE-07 doing、199/265不变。 +其他Monaco/字体/媒体范围仍未关闭。本批不意味着发布许可审查已全部完成。 + +回退删除本批三许可及来源验证接入,恢复35份console清单;不影响已修复运行时。 +按SITE-07检查点独立本地提交,没有推送、部署或发布。 diff --git a/refactor/plan.md b/refactor/plan.md index 70ed4802b..abb563834 100644 --- a/refactor/plan.md +++ b/refactor/plan.md @@ -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) [记录](baselines/console-feed-provenance.json) [记录](changes/2026-09-15-SITE-07-console-feed-source.md) [记录](baselines/console-commonjs-provenance.json) [记录](changes/2026-09-15-SITE-07-console-commonjs.md) [记录](baselines/console-esm-provenance.json) [记录](changes/2026-09-15-SITE-07-console-esm.md) [记录](baselines/console-embedded-notices.json) [记录](baselines/console-notices-validation.json) [记录](changes/2026-09-15-SITE-07-console-notices.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) [记录](baselines/console-commonjs-provenance.json) [记录](changes/2026-09-15-SITE-07-console-commonjs.md) [记录](baselines/console-esm-provenance.json) [记录](changes/2026-09-15-SITE-07-console-esm.md) [记录](baselines/console-embedded-notices.json) [记录](baselines/console-notices-validation.json) [记录](changes/2026-09-15-SITE-07-console-notices.md) [记录](baselines/console-embedded-sources.json) [记录](baselines/console-embedded-validation.json) [记录](changes/2026-09-15-SITE-07-console-embedded-sources.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) diff --git a/refactor/progress.md b/refactor/progress.md index e469eb604..a08a06ca5 100644 --- a/refactor/progress.md +++ b/refactor/progress.md @@ -1,5 +1,12 @@ # 进度与证据 +## SITE-07 三项内嵌依赖来源与许可 + +react-inspector中的Babel16文件、regenerator1文件及tokenizer7文件已逐字节 +核实;新增三份许可,见[记录](changes/2026-09-15-SITE-07-console-embedded-sources.md)。 +单元22/22,联网/离线完整复现通过。剩replicator、Emotion、Stack Overflow等 +内嵌来源继续审查,VENDOR-08 open、SITE-07 doing,仍199/265;运行时与锁不变。 + ## SITE-07 控制台许可实际分发 32个包与Parcel许可、Chromium及Stylis两份内嵌完整许可已接入生成流程,新增35份 diff --git a/refactor/risks.json b/refactor/risks.json index b13d871d9..dede189cc 100644 --- a/refactor/risks.json +++ b/refactor/risks.json @@ -695,11 +695,15 @@ "refactor/baselines/console-notices-validation.json", "refactor/changes/2026-09-15-SITE-07-console-notices.md", "scripts/site-vendor/console/embedded-notices.ts", - "docs/THIRD_PARTY_NOTICES.md" + "docs/THIRD_PARTY_NOTICES.md", + "refactor/baselines/console-embedded-sources.json", + "refactor/baselines/console-embedded-validation.json", + "refactor/changes/2026-09-15-SITE-07-console-embedded-sources.md", + "scripts/site-vendor/console/embedded-sources.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": "All 100 vendor module bodies and Parcel loader exactly reproduce from fixed archives. Public notices now deliver 32 package licenses, the Parcel license, and exact Chromium/Sultan Tarimo embedded headers; all 53 site notice files passed byte-for-byte HTTP checks in three engines. Remaining embedded attribution is explicitly tracked in console-embedded-notices.json. Original full lockfile is not recovered; runtime unchanged." + "workspaceState": "All 100 vendor module bodies and Parcel loader exactly reproduce from fixed archives. Additionally all 17 react-inspector external source-map members and seven tokenizer files match pinned upstream sources. Public console notices cover 38 entries; all 56 site notice files passed byte-for-byte HTTP checks in three engines. Remaining embedded attribution is tracked in console-embedded-notices.json. Original full lockfile is not recovered; runtime unchanged." }, { "id": "SDK-01", diff --git a/refactor/tasks.json b/refactor/tasks.json index efa413556..02d932b2e 100644 --- a/refactor/tasks.json +++ b/refactor/tasks.json @@ -4497,7 +4497,10 @@ "changes/2026-09-15-SITE-07-console-esm.md", "baselines/console-embedded-notices.json", "baselines/console-notices-validation.json", - "changes/2026-09-15-SITE-07-console-notices.md" + "changes/2026-09-15-SITE-07-console-notices.md", + "baselines/console-embedded-sources.json", + "baselines/console-embedded-validation.json", + "changes/2026-09-15-SITE-07-console-embedded-sources.md" ] }, { diff --git a/scripts/build-site-notices.mjs b/scripts/build-site-notices.mjs index 2849e011e..a4f5cabba 100644 --- a/scripts/build-site-notices.mjs +++ b/scripts/build-site-notices.mjs @@ -22,6 +22,7 @@ assert.deepEqual(manifest.groups.filter(group => group.name !== 'console').flatM const consoleGroup = manifest.groups.find(group => group.name === 'console') assert.deepEqual(consoleGroup?.components?.map(component => component.name).sort(), [ '@babel/runtime', + '@babel/runtime (react-inspector embedded)', '@emotion/cache', '@emotion/core', '@emotion/css', @@ -52,12 +53,14 @@ assert.deepEqual(consoleGroup?.components?.map(component => component.name).sort 'react-dom', 'react-inspector', 'react-is', + 'regenerator-runtime', 'scheduler', 'shallowequal', + 'simple-html-tokenizer', 'styled-components', 'stylis-rule-sheet', ], 'Do not silently drop verified console component attribution') -assert.equal(consoleGroup?.notices.length, 35, 'Missing reviewed console notice') +assert.equal(consoleGroup?.notices.length, 38, 'Missing reviewed console notice') const vconsoleNotices = manifest.groups.find(group => group.name === 'vconsole')?.notices.map(notice => notice.target) for (const name of ['LICENSE', 'MIT-LICENSE', 'ATTRIBUTION.md']) assert(vconsoleNotices?.includes(`docs/licenses/vconsole/${name}`), `Missing vConsole notice: ${name}`) diff --git a/scripts/site-vendor/README.md b/scripts/site-vendor/README.md index 81fe6df25..6ff36793c 100644 --- a/scripts/site-vendor/README.md +++ b/scripts/site-vendor/README.md @@ -23,7 +23,7 @@ files retain their exact upstream bytes, including final blank lines. `yarn check:site-notices`. The write command cannot bless altered vendor assets; review the new archive and license evidence before changing the manifest. The CLI prevents accidentally dropping any of the three groups, the ten reviewed -Monaco/vConsole components, the 35 identified console components or their notice +Monaco/vConsole components, the 38 identified console components or their notice count, and vConsole's original license, supplemental MIT body and attribution. Component references require their runtime assets and every notice before writing. Source notices @@ -59,8 +59,9 @@ output through PowerShell text redirection. No dependency installation is needed The desktop console's owned TS entry/view and lifecycle now build through `build:console` / `check:console`; see [console maintenance](console/README.md). Its other 100 Parcel modules remain frozen and now reproduce exactly from fixed -archives, including the Parcel loader. Its 33 package/loader licenses and two -embedded license headers now ship under `docs/licenses/console/`. Full embedded +archives, including the Parcel loader. Its package/loader licenses, two embedded +headers and three additional embedded dependency licenses now ship as 38 files +under `docs/licenses/console/`. Full embedded attribution remains open; the generated index explicitly preserves that boundary. Follow-up: finish Monaco's broader bundled-component notice audit, the console diff --git a/scripts/site-vendor/console/README.md b/scripts/site-vendor/console/README.md index f9d0149ba..166905037 100644 --- a/scripts/site-vendor/console/README.md +++ b/scripts/site-vendor/console/README.md @@ -150,8 +150,24 @@ comes from console-feed string-utils, and Sultan Tarimo's MIT header comes from styled-components' rule-sheet source map. Both are independently attributed in the public index and protected by the notice CLI's omission checks. -This is partial embedded review. The record lists replicator, simple-html-tokenizer, -Emotion stylis/hash/cache, the Component Stack Overflow reference, and Babel/ -regenerator inside react-inspector as follow-ups. Source-map names and comment -links are leads, not proof of a particular upstream version or complete notice -coverage. Do not close VENDOR-08 solely because all Parcel modules reproduce. +`embedded-sources.ts` verifies dependency source-map inventories and exact source +transforms. Its record is `refactor/baselines/console-embedded-sources.json`. +All 16 Babel members embedded in react-inspector match runtime 7.13.10; its single +regenerator member matches runtime 0.13.7. The consumer map and each source member +are hashed, and the checker rejects omitted or extra external map sources. These +versions identify matching source content; the original full lock is not recovered. + +Linkifyjs 2.1.9 pins simple-html-tokenizer to Git commit +04799f4638ec5ed903a4e5aa6e832269fa59be6b in its published package manifest. All seven +tokenizer members exactly reproduce with the self-contained Babel 6.26.0 compiler +and es2015 loose preset. Archive, compiler, source and output bytes are checked. +The Git archive's SHA-512 is a measured fingerprint, not an npm registry SRI; +the recorded immutable URL and dependency string retain its actual provenance. +These three licenses are included in the 38 console notice outputs. The normal +site build still executes only the owned TS build; historical reproduction now +fetches 39 archives only when explicitly run with `--fetch`. + +This is partial embedded review. Remaining follow-ups are replicator, Emotion +stylis/hash/cache and the Component Stack Overflow reference. Source-map names and +comment links alone are leads, not proof of complete notice coverage. Do not close +VENDOR-08 solely because all Parcel modules reproduce. diff --git a/scripts/site-vendor/console/embedded-sources.ts b/scripts/site-vendor/console/embedded-sources.ts new file mode 100644 index 000000000..173273fe6 --- /dev/null +++ b/scripts/site-vendor/console/embedded-sources.ts @@ -0,0 +1,35 @@ +import assert from 'node:assert/strict' +import { hash } from './provenance.ts' + +export interface Member { archive: string, member: string, sha256: string } +export interface MappedSource { path: string, upstream: Member } +export interface SourceMapRecord { source: Member, externalPrefix: string, sources: MappedSource[] } +export interface TransformedSource { source: Member, target: Member } +export type ReadMember = (source: Member) => Uint8Array + +function verified(source: Member, read: ReadMember): string { + const bytes = read(source) + assert.equal(hash(bytes), source.sha256, `Embedded source member changed: ${source.archive}/${source.member}`) + return new TextDecoder().decode(bytes) +} + +export function verifyMappedSources(record: SourceMapRecord, read: ReadMember): number { + const map: { sources: string[], sourcesContent: (string | null)[] } = JSON.parse(verified(record.source, read)) + assert(record.externalPrefix.length > 0 && record.sources.length > 0, 'Empty embedded source scope') + const expected = record.sources.map(source => source.path) + assert.equal(new Set(expected).size, expected.length, 'Duplicate embedded source mapping') + assert.deepEqual(map.sources.filter(source => source.startsWith(record.externalPrefix)).sort(), expected.slice().sort(), 'Embedded source map inventory changed') + for (const source of record.sources) { + const index = map.sources.indexOf(source.path) + assert.equal(map.sourcesContent[index], verified(source.upstream, read), `Embedded source content differs: ${source.path}`) + } + return record.sources.length +} + +export function verifyTransformedSources(sources: TransformedSource[], read: ReadMember, transform: (source: string) => string): number { + assert(sources.length > 0, 'Empty transformed source scope') + assert.equal(new Set(sources.map(source => `${source.target.archive}/${source.target.member}`)).size, sources.length, 'Duplicate transformed source target') + for (const source of sources) + assert.equal(transform(verified(source.source, read)), verified(source.target, read), `Embedded source transform differs: ${source.target.member}`) + return sources.length +} diff --git a/scripts/site-vendor/console/reproduce.ts b/scripts/site-vendor/console/reproduce.ts index c84986bea..26e6a82e0 100644 --- a/scripts/site-vendor/console/reproduce.ts +++ b/scripts/site-vendor/console/reproduce.ts @@ -1,4 +1,5 @@ import type { EmbeddedNotice } from './embedded-notices.ts' +import type { Member, SourceMapRecord, TransformedSource } from './embedded-sources.ts' import type { Archive, External, Source } from './provenance.ts' import type { BabelRuntime, EsmSource } from './reconstruction.ts' import assert from 'node:assert/strict' @@ -10,6 +11,7 @@ import path from 'node:path' import process from 'node:process' import { fileURLToPath } from 'node:url' import { extractNotice } from './embedded-notices.ts' +import { verifyMappedSources, verifyTransformedSources } from './embedded-sources.ts' import { hash, parcelModules, verifyArchive, verifyModules, verifyPackageEdges } from './provenance.ts' import { reconstructModule, verifyPrelude } from './reconstruction.ts' @@ -37,11 +39,19 @@ interface EsmProvenance extends SourceGroup { parcel: { archive: Archive, prelude: { member: string, sha256: string }, footer: string, notices: Notice[], recipeMembers: { member: string, sha256: string }[] } supplementalNotices: { url: string, apiUrl?: string, source: string, sha256: string }[] } +interface EmbeddedProvenance { + archives: (Archive & { id: string, notices: Notice[] })[] + compiler: { archive: Archive, member: string, sha256: string, version: string, options: { presets: [string, { loose: boolean }][] } } + sourceMaps: SourceMapRecord[] + tokenizer: { dependency: Member, value: string, sources: TransformedSource[] } +} +interface HistoricalBabel { version: string, transform: (source: string, options: EmbeddedProvenance['compiler']['options']) => { code: string } } 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')) const common: SourceGroup = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-commonjs-provenance.json'), 'utf8')) const esm: EsmProvenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-esm-provenance.json'), 'utf8')) +const embeddedSources: EmbeddedProvenance = JSON.parse(fs.readFileSync(path.join(root, 'refactor/baselines/console-embedded-sources.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')) @@ -60,7 +70,10 @@ async function download(url: string) { throw error } } -for (const archive of [record.archive, record.compiler.archive, ...common.archives, ...esm.archives, esm.babel.archive, esm.parcel.archive]) { +const allArchives = [record.archive, record.compiler.archive, ...common.archives, ...esm.archives, esm.babel.archive, esm.parcel.archive, ...embeddedSources.archives, embeddedSources.compiler.archive] +const allArchiveIds = new Set(allArchives.map(archive => `${encodeURIComponent(archive.name)}-${archive.version}`)) +assert.equal(allArchiveIds.size, allArchives.length, 'Duplicate reproduction archive') +for (const archive of allArchives) { const target = path.join(cache, `${encodeURIComponent(archive.name)}-${archive.version}.tgz`) if (process.argv.includes('--fetch')) { const bytes = await download(archive.tarball) @@ -178,4 +191,33 @@ for (const notice of embedded.notices) { const text = extractNotice(readMember(`${notice.archive}.tgz`, notice.member), notice) assert.equal(fs.readFileSync(path.join(root, notice.source), 'utf8'), text, 'Frozen embedded notice changed') } -console.log(JSON.stringify({ exactModules: identified.size, consoleFeed: count, commonjs: commonCount, esm: esmCount, parcelPrelude: true, packageEdges: true, embeddedNotices: embedded.notices.length, unresolved: 0, licenseClosure: false })) +function readEmbedded(source: Member) { + assert(allArchiveIds.has(source.archive), 'Unknown embedded source archive') + return readMember(`${source.archive}.tgz`, source.member) +} +for (const archive of embeddedSources.archives) { + assert.equal(archive.id, `${encodeURIComponent(archive.name)}-${archive.version}`, 'Embedded archive ID differs') + for (const notice of archive.notices) { + assert.equal(hash(readMember(`${archive.id}.tgz`, notice.member)), notice.sha256, 'Embedded upstream license changed') + assert.equal(hash(fs.readFileSync(path.join(root, notice.source))), notice.sha256, 'Frozen embedded license changed') + } +} +assert.equal(embeddedSources.sourceMaps.length, 1, 'Incomplete embedded map scope') +const mappedCount = embeddedSources.sourceMaps.reduce((total, source) => total + verifyMappedSources(source, readEmbedded), 0) +assert.equal(mappedCount, 17, 'Incomplete react-inspector embedded scope') +const tokenizer = embeddedSources.tokenizer +const dependencyBytes = readEmbedded(tokenizer.dependency) +assert.equal(hash(dependencyBytes), tokenizer.dependency.sha256, 'Tokenizer dependency manifest changed') +const dependency: { devDependencies: Record } = JSON.parse(dependencyBytes.toString('utf8')) +assert.equal(dependency.devDependencies['simple-html-tokenizer'], tokenizer.value, 'Tokenizer Git dependency changed') +const compiler = embeddedSources.compiler +const legacyBytes = readMember(`${compiler.archive.name}-${compiler.archive.version}.tgz`, compiler.member) +assert.equal(hash(legacyBytes), compiler.sha256, 'Embedded compiler changed') +const legacyPath = path.join(cache, 'babel6.cjs') +fs.writeFileSync(legacyPath, legacyBytes) +const legacyBabel = require(legacyPath) as HistoricalBabel +assert.equal(legacyBabel.version, compiler.version, 'Embedded compiler version changed') +assert.deepEqual(compiler.options, { presets: [['es2015', { loose: true }]] }, 'Embedded compiler options changed') +const transformedCount = verifyTransformedSources(tokenizer.sources, readEmbedded, source => legacyBabel.transform(source, compiler.options).code) +assert.equal(transformedCount, 7, 'Incomplete tokenizer scope') +console.log(JSON.stringify({ exactModules: identified.size, consoleFeed: count, commonjs: commonCount, esm: esmCount, parcelPrelude: true, packageEdges: true, embeddedNotices: embedded.notices.length, embeddedMappedSources: mappedCount, embeddedTransformedSources: transformedCount, unresolved: 0, licenseClosure: false })) diff --git a/scripts/site-vendor/manifest.json b/scripts/site-vendor/manifest.json index 69c37415c..889389e06 100644 --- a/scripts/site-vendor/manifest.json +++ b/scripts/site-vendor/manifest.json @@ -944,7 +944,7 @@ "name": "console", "version": "legacy-vendor-with-TS-adapter", "tarball": "https://github.com/zhw2590582/ArtPlayer/blob/5d6b2f22bc75213ac97cff0bcffa4a1ce2bc786c/docs/assets/js/console.js", - "review": "The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Package license texts and two embedded license headers below are preserved verbatim. Embedded attribution review is still incomplete; this inventory is not publication clearance.", + "review": "The 100 third-party Parcel modules and loader have exact source reproduction. The two owned adapter modules are built from TypeScript. Preserved notices also cover two embedded license headers, all 17 react-inspector external source-map members, and all seven HTML tokenizer sources from its fixed Git dependency. Embedded attribution review is still incomplete; this inventory is not publication clearance.", "roots": [ "docs/assets/js/console.js" ], @@ -1130,6 +1130,21 @@ "source": "refactor/baselines/site-vendor/console-embedded/stylis-rule-sheet-LICENSE.txt", "target": "docs/licenses/console/stylis-rule-sheet/LICENSE", "sha256": "99a75da65634b772687781c054ffe679569c1770c398f96427677899fe0ca8d7" + }, + { + "source": "refactor/baselines/site-vendor/console-embedded/babel-runtime-7.13.10-LICENSE.txt", + "target": "docs/licenses/console/react-inspector-babel/LICENSE", + "sha256": "117da2af0d4ce0fe1c8e19b5cff9dcd806adf973d328d27b11d4448c4ff24f76" + }, + { + "source": "refactor/baselines/site-vendor/console-embedded/regenerator-runtime-0.13.7-LICENSE.txt", + "target": "docs/licenses/console/regenerator-runtime/LICENSE", + "sha256": "51887a3d47051ac2fce1210562e5b9fe0830a8a8fabeb272c2d586eeb18a05fd" + }, + { + "source": "refactor/baselines/site-vendor/console-embedded/simple-html-tokenizer-04799f4-LICENSE.txt", + "target": "docs/licenses/console/simple-html-tokenizer/LICENSE", + "sha256": "c41881de2a9f2200936648343500524be154eb79f649582f9582dd251b051b11" } ], "components": [ @@ -1517,6 +1532,39 @@ "notices": [ "docs/licenses/console/stylis-rule-sheet/LICENSE" ] + }, + { + "name": "@babel/runtime (react-inspector embedded)", + "version": "7.13.10", + "tarball": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.10.tgz", + "assets": [ + "docs/assets/js/console.js" + ], + "notices": [ + "docs/licenses/console/react-inspector-babel/LICENSE" + ] + }, + { + "name": "regenerator-runtime", + "version": "0.13.7", + "tarball": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", + "assets": [ + "docs/assets/js/console.js" + ], + "notices": [ + "docs/licenses/console/regenerator-runtime/LICENSE" + ] + }, + { + "name": "simple-html-tokenizer", + "version": "git-04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "tarball": "https://api.github.com/repos/nfrasser/simple-html-tokenizer/tarball/04799f4638ec5ed903a4e5aa6e832269fa59be6b", + "assets": [ + "docs/assets/js/console.js" + ], + "notices": [ + "docs/licenses/console/simple-html-tokenizer/LICENSE" + ] } ] } diff --git a/test/browser/site-vendor.spec.js b/test/browser/site-vendor.spec.js index 98f6d7444..5bfadf971 100644 --- a/test/browser/site-vendor.spec.js +++ b/test/browser/site-vendor.spec.js @@ -31,6 +31,9 @@ test('mobile vConsole shows logs and upstream site notice texts are served uncha expect(await index.text()).toContain('Included component: @vscode/codicons 0.0.26') expect(await index.text()).toContain('Included component: console-feed 3.2.2') expect(await index.text()).toContain('Included component: chromium-string-utils') + expect(await index.text()).toContain('Included component: @babel/runtime (react-inspector embedded) 7.13.10') + expect(await index.text()).toContain('Included component: regenerator-runtime 0.13.7') + expect(await index.text()).toContain('Included component: simple-html-tokenizer git-04799f4638ec5ed903a4e5aa6e832269fa59be6b') expect(await index.text()).toContain('Embedded attribution review is still incomplete') await page.evaluate(() => { window.vConsole.destroy() diff --git a/test/site-console.test.js b/test/site-console.test.js index 7c25dcb18..c40e2a9b1 100644 --- a/test/site-console.test.js +++ b/test/site-console.test.js @@ -8,12 +8,48 @@ import test from 'node:test' import ts from 'typescript' import { generateConsole, moduleRanges, obsoleteMap, upstreamSha256 } from '../scripts/site-vendor/console/build.ts' import { extractNotice } from '../scripts/site-vendor/console/embedded-notices.ts' +import { verifyMappedSources, verifyTransformedSources } from '../scripts/site-vendor/console/embedded-sources.ts' import { hash, parcelModules, verifyArchive, verifyModules, verifyPackageEdges } from '../scripts/site-vendor/console/provenance.ts' import { reconstructModule, verifyPrelude } from '../scripts/site-vendor/console/reconstruction.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' +test('Embedded source maps reject omitted dependencies and content from a different release', () => { + const upstream = Buffer.from('export const value = 1;\n') + const map = { sources: ['../../src/owned.js', '../../node_modules/library/index.js'], sourcesContent: ['owned', upstream.toString()] } + let mapBytes = Buffer.from(JSON.stringify(map)) + const record = { source: { archive: 'parent', member: 'index.js.map', sha256: hash(mapBytes) }, externalPrefix: '../../node_modules/', sources: [{ path: map.sources[1], upstream: { archive: 'library', member: 'index.js', sha256: hash(upstream) } }] } + const read = member => member.archive === 'parent' ? mapBytes : upstream + assert.equal(verifyMappedSources(record, read), 1) + assert.throws(() => verifyMappedSources({ ...record, sources: [] }, read), /Empty embedded/) + assert.throws(() => verifyMappedSources({ ...record, sources: [...record.sources, ...record.sources] }, read), /Duplicate/) + const changed = Buffer.from('export const value = 2;\n') + const otherVersion = structuredClone(record) + otherVersion.sources[0].upstream.sha256 = hash(changed) + assert.throws(() => verifyMappedSources(otherVersion, member => member.archive === 'parent' ? mapBytes : changed), /content differs/) + for (const changedMap of [ + { ...map, sources: [...map.sources, '../../node_modules/hidden/index.js'], sourcesContent: [...map.sourcesContent, 'hidden'] }, + { ...map, sourcesContent: ['owned', null] }, + ]) { + mapBytes = Buffer.from(JSON.stringify(changedMap)) + assert.throws(() => verifyMappedSources({ ...record, source: { ...record.source, sha256: hash(mapBytes) } }, read), /inventory changed|content differs/) + } +}) + +test('Embedded transforms compare exact target bytes and reject duplicate or altered evidence', () => { + const input = Buffer.from('export const value = 1;') + const output = Buffer.from('exports.value = 1;') + const source = { archive: 'upstream', member: 'index.js', sha256: hash(input) } + const target = { archive: 'consumer', member: 'index.js', sha256: hash(output) } + const read = member => member.archive === 'upstream' ? input : output + const transform = () => output.toString() + assert.equal(verifyTransformedSources([{ source, target }], read, transform), 1) + assert.throws(() => verifyTransformedSources([{ source, target }], read, () => `${output}\n`), /transform differs/) + assert.throws(() => verifyTransformedSources([{ source: { ...source, sha256: hash('changed') }, target }], read, transform), /member changed/) + assert.throws(() => verifyTransformedSources([{ source, target }, { source, target }], read, transform), /Duplicate/) +}) + test('Embedded notices retain exact headers and reject missing or changed mapped sources', () => { const source = '// Copyright owner\n// Full permission and disclaimer.\nconst value = 1;' const text = '// Copyright owner\n// Full permission and disclaimer.\n' diff --git a/test/site-notices.test.js b/test/site-notices.test.js index c300a0464..aab02f218 100644 --- a/test/site-notices.test.js +++ b/test/site-notices.test.js @@ -111,7 +111,7 @@ test('Console notice CLI rejects omitted package or embedded attribution before const manifestPath = path.join(root, 'scripts/site-vendor/manifest.json') fs.mkdirSync(path.dirname(manifestPath), { recursive: true }) const original = JSON.parse(fs.readFileSync('scripts/site-vendor/manifest.json', 'utf8')) - for (const name of ['console-feed', 'parcel-bundler', 'styled-components', 'chromium-string-utils', 'stylis-rule-sheet']) { + for (const name of ['console-feed', 'parcel-bundler', 'styled-components', 'chromium-string-utils', 'stylis-rule-sheet', '@babel/runtime (react-inspector embedded)', 'regenerator-runtime', 'simple-html-tokenizer']) { for (const field of ['components', 'notices']) { const manifest = structuredClone(original) const group = manifest.groups.find(group => group.name === 'console')