build(site): [SITE-07] bind console licenses to verified component sources

This commit is contained in:
Harvey Zhao committed 2026-09-15 08:27:40 +08:00
1 parent 4bef084328
commit fb1faffbe9
20 files changed
+343 -28

No files matched your search

+2
View File
@@ -1,6 +1,7 @@
import assert from 'node:assert/strict'
import fs from 'node:fs'
import process from 'node:process'
import { verifyConsoleNoticeSources } from './site-vendor/console/notices.ts'
import { writeOrCheckNotices } from './site-vendor/notices.ts'
assert(process.argv.slice(2).every(arg => arg === '--check'), 'Use yarn build:site-notices [--check]')
@@ -70,5 +71,6 @@ assert.equal(consoleGroup?.notices.length, 47, '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}`)
verifyConsoleNoticeSources(process.cwd(), manifest)
const count = writeOrCheckNotices(process.cwd(), manifest, process.argv.includes('--check'))
console.log(`Verified site notices: ${count} outputs; Monaco/vConsole/console inventories, embedded and other provenance gates remain open.`)
+5 -4
View File
@@ -61,9 +61,10 @@ The desktop console's owned TS entry/view and lifecycle now build through
Its other 100 Parcel modules remain frozen and now reproduce exactly from fixed
archives, including the Parcel loader. Its package/loader licenses, two embedded
headers, embedded dependency licenses and upstream author notices now ship as 47 files
under `docs/licenses/console/`. Full embedded
attribution remains open; the generated index explicitly preserves that boundary.
under `docs/licenses/console/`. Each component is bound to its verified upstream
notice by `console/notices.ts`. The consolidated review and historical reconstruction
limits are recorded in `refactor/console-notice-review.md`.
Follow-up: finish Monaco's broader bundled-component notice audit, the console
embedded attribution/notices and remaining fonts/media. Do not upgrade these assets
Follow-up: finish Monaco's broader bundled-component notice audit and remaining
fonts/media. Do not upgrade these assets
without verifying globals, AMD/worker paths, CSS, consoleLog and user interaction.
+18 -8
View File
@@ -120,12 +120,12 @@ site builds continue using the frozen verified vendor boundary.
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.
or infer it covers every embedded/external component. Embedded and external
components have their own source records and notices described below.
The other 13 archives' LICENSE texts are also frozen under
`refactor/baselines/site-vendor/console-commonjs/`, with exact bytes preserved by
Git attributes. They are source evidence; complete site notice delivery still
requires the remaining component review. The final ESM and Parcel texts live in
Git attributes. They are source evidence tied to the generated notice inventory.
The final ESM and Parcel texts live in
`refactor/baselines/site-vendor/console-esm/`. React-inspector 5.1.1's ESM member
is an exact match after historical conversion; its CJS member was a failed
candidate. Styled-components 5.3.3 omits LICENSE in npm; the supplemental original
@@ -133,7 +133,7 @@ comes from fixed upstream commit 9b3457036cfedf1d5336f654f3171657630a9fd8.
The fetch command verifies that immutable upstream text through GitHub's Contents
API too (the raw URL had connection resets); both URLs and the blob ID are
recorded, and decoded content must match the same hash. Offline mode checks
the frozen bytes. Full embedded-component attribution remains open.
the frozen bytes. The consolidated review is in `refactor/console-notice-review.md`.
## Public notice delivery and embedded sources
@@ -205,6 +205,16 @@ member. Callback/context support and other changes prevent an exact-source claim
the public attribution explains that boundary and retains both authors' notices.
There are now 47 console notice outputs for 44 components. This includes a
CC BY-SA snippet; never describe the bundle as MIT-only. Final embedded-source
and mixed-license distribution review remains open. Exact Parcel module
reproduction alone is insufficient to close VENDOR-08.
CC BY-SA snippet; never describe the bundle as MIT-only. The identified source
and notice inventory is reviewed with the scope in `refactor/console-notice-review.md`.
The original complete lockfile and online Closure service have not been recovered.
The reproduction command's `licenseClosure: false` means that technical byte
comparison alone makes no license-clearance claim; the documented review also
considers component identity, embedded attribution and actual delivery.
`notices.ts` binds the 44 delivered components to 46 upstream notice/source files
from the independent provenance records. The 47th output is the local modification
explanation for react-pure-render. Both normal notice commands verify this relation
before writing: retaining all files while redirecting a BSD component to another
component's MIT notice is rejected. Re-review changed source or integration boundaries,
then revalidate the release candidate; this scope does not replace release reviews.
+63
View File
@@ -0,0 +1,63 @@
import type { VendorManifest } from '../notices.ts'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import path from 'node:path'
interface Notice { source: string, sha256: string }
interface Archive { name: string, version: string, tarball: string, notices: Notice[] }
interface Remote extends Notice { id: string, url: string }
// Bind delivered component notices to independently verified source records.
// The normal site build does not download or execute the historical compilers.
export function verifyConsoleNoticeSources(root: string, manifest: VendorManifest): { components: number, upstreamNotices: number } {
const read = <T>(name: string): T => JSON.parse(fs.readFileSync(path.join(root, `refactor/baselines/${name}.json`), 'utf8')) as T
const feed = read<{ archive: Archive, notice: Notice }>('console-feed-provenance')
const common = read<{ archives: Archive[] }>('console-commonjs-provenance')
const esm = read<{ archives: Archive[], parcel: { archive: Archive, notices: Notice[] }, supplementalNotices: Notice[] }>('console-esm-provenance')
const embedded = read<{ archives: Archive[] }>('console-embedded-sources')
const headers = read<{ notices: Notice[] }>('console-embedded-notices')
const derived = read<{ archives: Archive[], remotes: Remote[], hash: { notice: Notice }, shallow: { license: string } }>('console-derived-attribution')
const stack = read<{ apiUrl: string, notices: Notice[] }>('console-stackoverflow-provenance')
const group = manifest.groups.find(group => group.name === 'console')
assert(group?.components, 'Missing console component inventory')
const visited = new Set<string>()
const matchedNotices = new Set<string>()
const verify = (identity: { name: string, tarball?: string }, expected: Notice[]): void => {
const matches = group.components!.filter(component => component.name === identity.name && (!identity.tarball || component.tarball === identity.tarball))
assert.equal(matches.length, 1, 'Expected one component for verified console source')
const component = matches[0]!
assert(!visited.has(component.name), 'Duplicate console source coverage')
assert(expected.length, `Missing source license: ${component.name}`)
for (const notice of expected) {
const delivered: (Notice & { target: string })[] = group.notices.filter(item => item.source === notice.source && item.sha256 === notice.sha256)
assert.equal(delivered.length, 1, `Console source notice not delivered: ${component.name}`)
assert(component.notices.includes(delivered[0]!.target), `Console component points to the wrong notice: ${component.name}`)
matchedNotices.add(delivered[0]!.target)
}
visited.add(component.name)
}
verify(feed.archive, [feed.notice])
for (const archive of [...common.archives, ...esm.archives, ...embedded.archives, ...derived.archives]) {
const name = archive.name === '@babel/runtime' && archive.version === '7.13.10'
? '@babel/runtime (react-inspector embedded)'
: archive.name === 'replicator'
? 'replicator (console-feed fork)'
: archive.name === 'stylis' ? 'stylis (Emotion fork)' : archive.name
verify({ name, tarball: archive.tarball }, archive.name === 'styled-components' ? esm.supplementalNotices : archive.notices)
}
verify(esm.parcel.archive, esm.parcel.notices)
assert.equal(headers.notices.length, 2, 'Unexpected embedded header scope')
verify({ name: 'chromium-string-utils' }, [headers.notices[0]!])
verify({ name: 'stylis-rule-sheet' }, [headers.notices[1]!])
const hashLicense = derived.remotes.find(source => source.id === 'gary-readme')
assert(hashLicense, 'Missing MurmurHash license source')
verify({ name: 'murmurhash-js (Gary Court)' }, [hashLicense])
verify({ name: 'murmurhash2 (Austin Appleby)' }, [derived.hash.notice])
verify({ name: 'stackoverflow-custom-stringify', tarball: stack.apiUrl }, stack.notices)
const pureLicense = derived.remotes.find(source => source.id === derived.shallow.license)
assert(pureLicense, 'Missing react-pure-render license source')
verify({ name: 'react-pure-render (shallowequal origin)' }, [pureLicense])
assert.equal(visited.size, 44, 'Incomplete reviewed console source scope')
assert.deepEqual([...visited].sort(), group.components.map(component => component.name).sort(), 'Unreviewed console component')
return { components: visited.size, upstreamNotices: matchedNotices.size }
}
+1 -1
View File
@@ -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. 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. Modified replicator and Emotion/Stylis copies retain upstream author licenses; the original Emotion online Closure stage is not claimed to be reproducible. MurmurHash credits include Gary Court and Austin Appleby. The customStringify snippet matches Stack Overflow answer revision 5 under CC BY-SA 4.0; its separate attribution, source and full license are supplied. This is a mixed-license bundle, not MIT-only.",
"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. The identified embedded-source and attribution review is complete for this frozen vendor boundary. Source records bind each component to its original notices; this inventory is not publication clearance. The original full lockfile and historical online Closure service are not recovered. Modified replicator and Emotion/Stylis copies retain upstream author licenses; the original Emotion online Closure stage is not claimed to be reproducible. MurmurHash credits include Gary Court and Austin Appleby. The customStringify snippet matches Stack Overflow answer revision 5 under CC BY-SA 4.0; its separate attribution, source and full license are supplied. This is a mixed-license bundle, not MIT-only.",
"roots": [
"docs/assets/js/console.js"
],