docs: close code origin audit - #2907
Conversation
|
@jackwener, I’m filling in the bootstrap provenance record for this PR. Could you confirm what you remember about the initial repository work around May 19, 2026?
Rough answers are fine. If a detail is unknown or was not recorded, please say so. Please don’t include credentials or account identifiers. We’re documenting the history here, not asking you for a legal or ASF release decision. 中文对照: @jackwener,我在补充这个 PR 的项目启动阶段来源记录。想请你确认一下对 2026 年 5 月 19 日前后初始仓库工作的记忆:
大致信息即可。不确定或没有留存的信息可以直接注明。请不要提供凭据或账号标识。这里是在记录历史事实,不是请你作出法律或 ASF 发布判断。 Posted via OpenAI Codex for @Astro-Han. |
likun666661
left a comment
There was a problem hiding this comment.
I found two provenance/compliance gaps in the closeout record.
| | 14 | `packages/core/src/user-question.ts:7-19` | [`baochipham942-eng/code-agent`](https://github.com/baochipham942-eng/code-agent) v0.2.4, `src/shared/types.ts:489-501` (MIT) | 50% | Short structural types for questions, IDs, and answers. No distinctive shared expression. No attribution. | | ||
| | 15 | `packages/eval/src/__tests__/fixtures/writer-worker.ts:3-22` | [`agent-awareness`](https://www.npmjs.com/package/agent-awareness/v/0.4.5) 0.4.5, `src/commands/codex-hooks.ts:10-29` (MIT) | 86% | Small concurrency-test worker composed of standard file markers, a polling loop, and exit status. Candidate purpose and identifiers differ. No attribution. File is absent from current `main`. | | ||
| | 16 | `packages/runtime/src/http-response.ts:9-14` | [`different-ai/openwork`](https://github.com/different-ai/openwork) `alpha-macos-v0.14.1-alpha.982-1aeb1e4`, `apps/server/src/server.ts:869-874` (MIT) | 35% | Necessary Fetch API reconstruction after deleting encoding/length headers. No distinctive expression. No attribution. | | ||
| | 17 | `packages/runtime/src/model-protocol.ts:89-106,123-142,211-227,275-290` | [`talkio`](https://www.npmjs.com/package/talkio/v/1.0.0-alpha.1) 1.0.0-alpha.1, `src/types/common.ts:16-33,23-42,72-88,104-119` (Apache-2.0) | 14% | **Real third-party lineage, wrong candidate.** The file declares its adaptation from `@ai-sdk/provider-utils@5.0.25` (Apache-2.0). The fixed AI SDK source is now named in `LICENSE`; desktop notices already carry its exact license. | |
There was a problem hiding this comment.
[P1] Add the Apache modification notice to the adapted source file
This says model-protocol.ts already declares its adaptation from @ai-sdk/provider-utils@5.0.25, but the source header currently only says the shapes are “structurally equivalent” and “Maka-owned”; it does not identify the fixed version, the adaptation relationship, or that the file was modified. Since this PR classifies the file as real third-party lineage, adding the component only to the root LICENSE does not satisfy the Apache-2.0 §4(b) requirement for modified files to carry prominent notices stating that they were changed. Please update the model-protocol.ts header with the fixed source and Maka modification notice (or revise this lineage conclusion if adaptation is not what happened).
| | Tool | Version | Scope | Data behavior | Preserved result | | ||
| |---|---:|---|---|---| | ||
| | ScanCode Toolkit | 32.5.0 | 2,542 tracked files; local license, copyright, and package analysis | Local only | The raw result expired; the contemporaneous count and conclusion are retained here | | ||
| | SCANOSS JS CLI | 0.40.2 | 2,231 files supported by its winnowing scanner | The public API received winnowing fingerprints with obfuscated file identifiers; it did not receive source files or repository-relative paths | The 2,231-file JSON and WFP were recovered locally and used to reconstruct the table below | |
There was a problem hiding this comment.
[P2] Record hashes for the recovered scan artifacts
The report depends on the recovered 2,231-file JSON and WFP, but neither artifact is retained here and the report records no SHA-256, byte size, or stable storage location. Because the reproduction section correctly notes that a fresh response can differ as the SCANOSS knowledge base changes, future reviewers cannot verify that this table came from the recovered artifacts described here. Please record at least the SHA-256 and byte size of both files, and preferably their controlled storage location or a retained sanitized copy.
Generated-by: OpenAI Codex
The code origin audit classified `packages/runtime/src/model-protocol.ts` as real third-party lineage adapted from the Apache-2.0 AI SDK, but the file header disclosed neither the source nor the adaptation, and the report claimed a declaration the file did not contain. Recording the component in the root `LICENSE` alone does not meet the Apache-2.0 section 4(b) requirement that modified files carry prominent notices stating that they were changed. Add the source, fixed versions, and modification notice to the file header, and separate the dependency-boundary claim from the ownership wording that made the header read as an authorship statement. Name `@ai-sdk/provider` alongside `@ai-sdk/provider-utils` in `LICENSE`. The adapted material spans both packages: `JSONValue` and the `SharedV4` provider option, provider reference, and file data shapes come from `@ai-sdk/provider`. Pin both components to the versions installed when the adaptation was made rather than the audit snapshot versions. Every adapted declaration is byte-identical across the two ranges, so both pinnings identify the same source material. Record the verification evidence and its reproduction command in the report so the lineage conclusion can be re-checked independently of the scanner, which matched an unrelated candidate at 14%. Generated-by: Claude Code
cc70cd5 to
594dcd0
Compare
The SCANOSS table covers only source code its winnowing scanner fingerprints. Two categories of incoming material sit outside it and were previously unrecorded. `tool-output.ts` and `edit-replace.ts` state that they are adapted from opencode, and the adaptation is substantial: the truncation helper follows upstream line for line down to its local names and asymmetric newline accounting, and the escape-normalizing regular expression is identical character for character with its nine branches in upstream order. Upstream is MIT and requires its notice to travel with the material, but "opencode" appears in none of the four attribution surfaces. The models.dev snapshot ships about 27,800 lines derived from an MIT database with no attribution and no recorded snapshot revision. The entries are facts, but the selection and arrangement are upstream's. Both gaps have one cause: the notice generator derives its inventory from npm production dependency trees, so vendored or adapted source and generated data are invisible to it by construction. State that blind spot explicitly, since it will hide the next such source too. Correct entry 23. The candidate is `MIT + Commons Clause`, not the `MIT` the scanner reported, which also makes the outcome summary's claim about source-available candidates wrong as written. Maka's file is byte-identical to it but demonstrably independent: this repository records it being created as the shadcn helper and later losing `twMerge` with the Astryx migration. Replace the weaker "no project-specific expression" reasoning with that evidence. Record that the recovered scan artifacts were not retained and cannot be hashed after the fact, so the table is verifiable through each row's named candidate rather than against the artifacts themselves. Generated-by: Claude Code
The scoped Apache override in this branch keeps the root LICENSE third-party appendices out of dependency notice sections. The committed artifact was regenerated on main with the unscoped generator, so rebasing reintroduced the leaked appendices and the check reported the artifact as stale. Regenerating removes 140 lines of Maka's own third-party appendices from the `@ai-sdk/provider-utils` section. No dependency entry changes. Generated-by: Claude Code
The regression test located the provider-utils section by the exact string `@ai-sdk/provider-utils@5.0.25`, so rebasing onto a main that had bumped the dependency to 5.0.27 failed the test on a missing section rather than on the leak it guards. Match the package prefix instead. Reverting the generator to read the whole root LICENSE still fails the test on the leaked `THIRD-PARTY COMPONENTS` appendix, so the guarantee is unchanged. Generated-by: Claude Code
|
@jackwener gentle ping — no rush on the bootstrap tooling question above, just flagging it in case it got buried. "Don't remember" or "wasn't recorded" is a perfectly good answer — I'll record it as not retained and move on. 简体中文轻轻提醒一下 —— 上面那条关于项目启动阶段工具来源的问题,不着急,只是怕被沉掉了。 「记不清了」或者「当时没记录」都是完全可以的回答,我会照实写成未留存,不会卡着你。 Posted via Claude Code for @Astro-Han. |
The CLI keeps its own generated notice artifact behind `check:cli-third-party-notices`, and the previous regeneration only covered the desktop target. CI caught the CLI artifact still carrying the leaked root LICENSE appendices. Removes the same 140 lines from the CLI artifact. No dependency entry changes. Generated-by: Claude Code
…tice `@ai-sdk/provider-utils` ships no license file, so the generator substitutes the root LICENSE as its Apache-2.0 text. It substituted the whole file. LICENSE also carries Maka's THIRD-PARTY COMPONENTS section, so 140 lines describing trycua/cua and the bundled fonts were filed under one npm package in both release notices — attributing material to a party that has nothing to do with it, in the artifact whose only job is to attribute correctly. Cut at the section header instead. The defect scales with LICENSE: every entry added there lands in that package's notice, which is what surfaced it. PR #2907 carries the same two-line fix for the same reason. It is repeated here because this branch adds LICENSE entries, and without it those entries would ship inside the provider-utils notice. Whichever lands second drops it. Generated-by: Claude Code
The code origin audit (#2907) found two pieces of third-party material that ship in every release and appear in none of Maka's attribution surfaces, both for the same structural reason: neither is an npm package, and the notice generator walks npm production dependency trees only. `tool-output.ts` and `edit-replace.ts` already said in prose that they adapt opencode, and the adaptation is real — the escape-normalizing replacer's regular expression and its nine branches are carried over unchanged. Prose is not the notice MIT requires. Each file now records source, revision, license, and copyright, and LICENSE carries the permission notice so it travels with the release. Both files are mixed-origin, so the notice is scoped to the adapted material and neither file gets a whole-file SPDX identifier; the in-repo precedent for a wholly-upstream file, `packages/ui/src/astryx-chat-reasoning.tsx`, is deliberately not followed here. The generated models.dev modules are a different claim and are worded as one. Individual model records are facts and are not copyrightable; what comes from upstream is the selection and arrangement — which providers and fields are carried, and upstream's normalized structures such as `lifecycle` and `thinkingOptions.efforts`. The LICENSE entry says that rather than calling it copied code. The headers also name the payload. models.dev publishes a rolling document with no version in its body, so the generator stamps the sync date and the sha256 of the exact api.json it read. That is provenance, not reproducibility: upstream serves whatever is current, so the digest tells you whether a file still matches its stated source, not how to fetch that source again. Re-running the sync against the snapshot these files were built from reproduces both bodies byte-for-byte, which is what makes the recorded digest checkable. Closes the first exit criterion of #3270. Generated-by: Claude Code
The generator's inventory is the npm production dependency closure. That is a complete answer to "which npm packages ship", and a structurally blind one to "what else ships": vendored, adapted, and generated-from-upstream material is not a package, so no amount of checking the walk's output can reach it. The previous commit's LICENSE entries were therefore guarded by nothing — an attribution header could be dropped in a routine edit and both release notices would still regenerate clean. Declare that material instead, in `scripts/non-npm-sources.mjs`, and check each declaration against the tree it describes: LICENSE must carry the copyright line, every listed file must exist, and each must still contain its marker. The marker is pinned to something that should not change silently — the upstream revision for adapted source, the attribution line for generated data, which a routine re-sync preserves and a dropped attribution does not. Failing means failing generation, so `check:third-party-notices` and its CLI twin now gate it and both notices carry the sections. Validation takes its content as arguments rather than reading the filesystem, so the failure paths are exercised in `non-npm-sources.test.mjs` against a stub instead of by editing tracked source. All three were also falsified end to end against the real tree before this commit. Both notice titles drop "npm": they no longer describe only npm. Two limits worth stating. This is a declared inventory, not a discovery mechanism — it proves what is declared is still true, not that everything true is declared; a scan for undeclared upstream markers belongs on top of #2907's audit, which is the allowlist such a scan needs. And neither notice check runs on pull requests today; both run only in the ASF source candidate workflow, so this gate fires at release preparation rather than at review. Generated-by: Claude Code
…tice `@ai-sdk/provider-utils` ships no license file, so the generator substitutes the root LICENSE as its Apache-2.0 text. It substituted the whole file. LICENSE also carries Maka's THIRD-PARTY COMPONENTS section, so 140 lines describing trycua/cua and the bundled fonts were filed under one npm package in both release notices — attributing material to a party that has nothing to do with it, in the artifact whose only job is to attribute correctly. Cut at the section header instead. The defect scales with LICENSE: every entry added there lands in that package's notice, which is what surfaced it. PR #2907 carries the same two-line fix for the same reason. It is repeated here because this branch adds LICENSE entries, and without it those entries would ship inside the provider-utils notice. Whichever lands second drops it. Generated-by: Claude Code
The code origin audit (#2907) found two pieces of third-party material that ship in every release and appear in none of Maka's attribution surfaces, both for the same structural reason: neither is an npm package, and the notice generator walks npm production dependency trees only. `tool-output.ts` and `edit-replace.ts` already said in prose that they adapt opencode, and the adaptation is real — the escape-normalizing replacer's regular expression and its nine branches are carried over unchanged. Prose is not the notice MIT requires. Each file now records source, revision, license, and copyright, and LICENSE carries the permission notice so it travels with the release. Both files are mixed-origin, so the notice is scoped to the adapted material and neither file gets a whole-file SPDX identifier; the in-repo precedent for a wholly-upstream file, `packages/ui/src/astryx-chat-reasoning.tsx`, is deliberately not followed here. The generated models.dev modules are a different claim and are worded as one. Individual model records are facts and are not copyrightable; what comes from upstream is the selection and arrangement — which providers and fields are carried, and upstream's normalized structures such as `lifecycle` and `thinkingOptions.efforts`. The LICENSE entry says that rather than calling it copied code. The headers also name the payload. models.dev publishes a rolling document with no version in its body, so the generator stamps the sync date and the sha256 of the exact api.json it read. That is provenance, not reproducibility: upstream serves whatever is current, so the digest tells you whether a file still matches its stated source, not how to fetch that source again. Re-running the sync against the snapshot these files were built from reproduces both bodies byte-for-byte, which is what makes the recorded digest checkable. Closes the first exit criterion of #3270. Generated-by: Claude Code
The generator's inventory is the npm production dependency closure. That is a complete answer to "which npm packages ship", and a structurally blind one to "what else ships": vendored, adapted, and generated-from-upstream material is not a package, so no amount of checking the walk's output can reach it. The previous commit's LICENSE entries were therefore guarded by nothing — an attribution header could be dropped in a routine edit and both release notices would still regenerate clean. Declare that material instead, in `scripts/non-npm-sources.mjs`, and check each declaration against the tree it describes: LICENSE must carry the copyright line, every listed file must exist, and each must still contain its marker. The marker is pinned to something that should not change silently — the upstream revision for adapted source, the attribution line for generated data, which a routine re-sync preserves and a dropped attribution does not. Failing means failing generation, so `check:third-party-notices` and its CLI twin now gate it and both notices carry the sections. Validation takes its content as arguments rather than reading the filesystem, so the failure paths are exercised in `non-npm-sources.test.mjs` against a stub instead of by editing tracked source. All three were also falsified end to end against the real tree before this commit. Both notice titles drop "npm": they no longer describe only npm. Two limits worth stating. This is a declared inventory, not a discovery mechanism — it proves what is declared is still true, not that everything true is declared; a scan for undeclared upstream markers belongs on top of #2907's audit, which is the allowlist such a scan needs. And neither notice check runs on pull requests today; both run only in the ASF source candidate workflow, so this gate fires at release preparation rather than at review. Generated-by: Claude Code
…tice `@ai-sdk/provider-utils` ships no license file, so the generator substitutes the root LICENSE as its Apache-2.0 text. It substituted the whole file. LICENSE also carries Maka's THIRD-PARTY COMPONENTS section, so 140 lines describing trycua/cua and the bundled fonts were filed under one npm package in both release notices — attributing material to a party that has nothing to do with it, in the artifact whose only job is to attribute correctly. Cut at the section header instead. The defect scales with LICENSE: every entry added there lands in that package's notice, which is what surfaced it. PR #2907 carries the same two-line fix for the same reason. It is repeated here because this branch adds LICENSE entries, and without it those entries would ship inside the provider-utils notice. Whichever lands second drops it. Generated-by: Claude Code
The code origin audit (#2907) found two pieces of third-party material that ship in every release and appear in none of Maka's attribution surfaces, both for the same structural reason: neither is an npm package, and the notice generator walks npm production dependency trees only. `tool-output.ts` and `edit-replace.ts` already said in prose that they adapt opencode, and the adaptation is real — the escape-normalizing replacer's regular expression and its nine branches are carried over unchanged. Prose is not the notice MIT requires. Each file now records source, revision, license, and copyright, and LICENSE carries the permission notice so it travels with the release. Both files are mixed-origin, so the notice is scoped to the adapted material and neither file gets a whole-file SPDX identifier; the in-repo precedent for a wholly-upstream file, `packages/ui/src/astryx-chat-reasoning.tsx`, is deliberately not followed here. The generated models.dev modules are a different claim and are worded as one. Individual model records are facts and are not copyrightable; what comes from upstream is the selection and arrangement — which providers and fields are carried, and upstream's normalized structures such as `lifecycle` and `thinkingOptions.efforts`. The LICENSE entry says that rather than calling it copied code. The headers also name the payload. models.dev publishes a rolling document with no version in its body, so the generator stamps the sync date and the sha256 of the exact api.json it read. That is provenance, not reproducibility: upstream serves whatever is current, so the digest tells you whether a file still matches its stated source, not how to fetch that source again. Re-running the sync against the snapshot these files were built from reproduces both bodies byte-for-byte, which is what makes the recorded digest checkable. Closes the first exit criterion of #3270. Generated-by: Claude Code
The generator's inventory is the npm production dependency closure. That is a complete answer to "which npm packages ship", and a structurally blind one to "what else ships": vendored, adapted, and generated-from-upstream material is not a package, so no amount of checking the walk's output can reach it. The previous commit's LICENSE entries were therefore guarded by nothing — an attribution header could be dropped in a routine edit and both release notices would still regenerate clean. Declare that material instead, in `scripts/non-npm-sources.mjs`, and check each declaration against the tree it describes: LICENSE must carry the copyright line, every listed file must exist, and each must still contain its marker. The marker is pinned to something that should not change silently — the upstream revision for adapted source, the attribution line for generated data, which a routine re-sync preserves and a dropped attribution does not. Failing means failing generation, so `check:third-party-notices` and its CLI twin now gate it and both notices carry the sections. Validation takes its content as arguments rather than reading the filesystem, so the failure paths are exercised in `non-npm-sources.test.mjs` against a stub instead of by editing tracked source. All three were also falsified end to end against the real tree before this commit. Both notice titles drop "npm": they no longer describe only npm. Two limits worth stating. This is a declared inventory, not a discovery mechanism — it proves what is declared is still true, not that everything true is declared; a scan for undeclared upstream markers belongs on top of #2907's audit, which is the allowlist such a scan needs. And neither notice check runs on pull requests today; both run only in the ASF source candidate workflow, so this gate fires at release preparation rather than at review. Generated-by: Claude Code
…tice `@ai-sdk/provider-utils` ships no license file, so the generator substitutes the root LICENSE as its Apache-2.0 text. It substituted the whole file. LICENSE also carries Maka's THIRD-PARTY COMPONENTS section, so 140 lines describing trycua/cua and the bundled fonts were filed under one npm package in both release notices — attributing material to a party that has nothing to do with it, in the artifact whose only job is to attribute correctly. Cut at the section header instead. The defect scales with LICENSE: every entry added there lands in that package's notice, which is what surfaced it. PR #2907 carries the same two-line fix for the same reason. It is repeated here because this branch adds LICENSE entries, and without it those entries would ship inside the provider-utils notice. Whichever lands second drops it. Generated-by: Claude Code
The code origin audit (#2907) found two pieces of third-party material that ship in every release and appear in none of Maka's attribution surfaces, both for the same structural reason: neither is an npm package, and the notice generator walks npm production dependency trees only. `tool-output.ts` and `edit-replace.ts` already said in prose that they adapt opencode, and the adaptation is real — the escape-normalizing replacer's regular expression and its nine branches are carried over unchanged. Prose is not the notice MIT requires. Each file now records source, revision, license, and copyright, and LICENSE carries the permission notice so it travels with the release. Both files are mixed-origin, so the notice is scoped to the adapted material and neither file gets a whole-file SPDX identifier; the in-repo precedent for a wholly-upstream file, `packages/ui/src/astryx-chat-reasoning.tsx`, is deliberately not followed here. The generated models.dev modules are a different claim and are worded as one. Individual model records are facts and are not copyrightable; what comes from upstream is the selection and arrangement — which providers and fields are carried, and upstream's normalized structures such as `lifecycle` and `thinkingOptions.efforts`. The LICENSE entry says that rather than calling it copied code. The headers also name the payload. models.dev publishes a rolling document with no version in its body, so the generator stamps the sync date and the sha256 of the exact api.json it read. That is provenance, not reproducibility: upstream serves whatever is current, so the digest tells you whether a file still matches its stated source, not how to fetch that source again. Re-running the sync against the snapshot these files were built from reproduces both bodies byte-for-byte, which is what makes the recorded digest checkable. Closes the first exit criterion of #3270. Generated-by: Claude Code
The generator's inventory is the npm production dependency closure. That is a complete answer to "which npm packages ship", and a structurally blind one to "what else ships": vendored, adapted, and generated-from-upstream material is not a package, so no amount of checking the walk's output can reach it. The previous commit's LICENSE entries were therefore guarded by nothing — an attribution header could be dropped in a routine edit and both release notices would still regenerate clean. Declare that material instead, in `scripts/non-npm-sources.mjs`, and check each declaration against the tree it describes: LICENSE must carry the copyright line, every listed file must exist, and each must still contain its marker. The marker is pinned to something that should not change silently — the upstream revision for adapted source, the attribution line for generated data, which a routine re-sync preserves and a dropped attribution does not. Failing means failing generation, so `check:third-party-notices` and its CLI twin now gate it and both notices carry the sections. Validation takes its content as arguments rather than reading the filesystem, so the failure paths are exercised in `non-npm-sources.test.mjs` against a stub instead of by editing tracked source. All three were also falsified end to end against the real tree before this commit. Both notice titles drop "npm": they no longer describe only npm. Two limits worth stating. This is a declared inventory, not a discovery mechanism — it proves what is declared is still true, not that everything true is declared; a scan for undeclared upstream markers belongs on top of #2907's audit, which is the allowlist such a scan needs. And neither notice check runs on pull requests today; both run only in the ASF source candidate workflow, so this gate fires at release preparation rather than at review. Generated-by: Claude Code
…tice `@ai-sdk/provider-utils` ships no license file, so the generator substitutes the root LICENSE as its Apache-2.0 text. It substituted the whole file. LICENSE also carries Maka's THIRD-PARTY COMPONENTS section, so 140 lines describing trycua/cua and the bundled fonts were filed under one npm package in both release notices — attributing material to a party that has nothing to do with it, in the artifact whose only job is to attribute correctly. Truncate at the section header. `split` returns the whole string when the delimiter is absent, which would silently reinstate this exact bug and leave `--check` demanding that the wrong output be committed, so the delimiter is required rather than assumed. The regression test comes from PR #2907, which found this defect and carries the same fix. It deliberately matches the package without its version, so a routine dependency bump does not fail it. Both are repeated here because this branch adds LICENSE entries, and without the fix those entries would ship inside the provider-utils notice. Whichever lands second drops the duplicate. The test is wired into `check:release` and into the CI planner's CLI-package inputs, so it runs on pull requests that touch it rather than only at release preparation. Generated-by: Claude Code
The code origin audit (#2907) found two pieces of third-party material that ship in every release and appear in none of Maka's attribution surfaces, both for the same structural reason: neither is an npm package, and the notice generator walks npm production dependency trees only. `tool-output.ts` and `edit-replace.ts` already said in prose that they adapt opencode, and the adaptation is real — the escape-normalizing replacer's regular expression and its nine branches are carried over unchanged. Prose is not the notice MIT requires. Each file now records source, revision, license, and copyright, and LICENSE carries the permission notice so it travels with the release. Both files are mixed-origin, so the notice is scoped to the adapted material and neither gets a whole-file SPDX identifier. The LICENSE entry records the whole upstream chain rather than stopping at the nearest one. opencode's edit.ts credits cline diff-apply and the gemini-cli editCorrector; that file is Copyright 2025 Google LLC under Apache-2.0, and its escape set shares its first eight branches, in order, with the replacer here. opencode added the ninth and changed the pattern. Whether that shared sequence carries protected expression is deliberately not adjudicated in LICENSE — it is recorded so a licensing review can see the chain and decide. The models.dev entry states what is copied instead of characterising it. The earlier draft said the individual records were uncopyrightable facts and that what came from upstream was the selection and arrangement. Both halves were wrong: `sync-model-metadata.mjs` copies `model.name` and `model.description` verbatim, and the snapshot carries 1779 upstream-authored descriptions; while the selection and the ordering are the generator's, not upstream's. The entry now lists the fields actually carried and leaves the legal conclusion out. The MIT text was already reproduced in full, so nothing about the obligation changes — only the accuracy of the sentence next to it. Upstream copyright lines were checked against the upstream LICENSE files rather than transcribed: both are `Copyright (c) 2025 opencode` and `Copyright (c) 2025 models.dev` verbatim. The generated headers name their payload. models.dev serves a rolling document with no version, so the generator stamps the sha256 of the data it extracted — not of api.json, which would move whenever any of the ~40 dropped providers changed and produce header-only diffs that say nothing about the file they sit in. Hashing after extraction makes the digest describe what ships and keeps the generator a pure function of its input: the same api.json produces the same bytes on any day. Verified by running it twice against the pinned payload. Closes the first exit criterion of #3270. Generated-by: Claude Code
…ifact notice The generator's inventory is the npm production dependency closure. That is a complete answer to "which npm packages ship" and a structurally blind one to "what else ships": vendored, adapted, and generated-from-upstream material is not a package, so no amount of checking the walk's output can reach it. The previous commit's LICENSE entries were guarded by nothing — an attribution header could be dropped in a routine edit and both notices would still regenerate clean. The obvious move is to declare that material in the generator. The first draft did, and it was wrong: it restated the repository, revision, copyright, and license text that LICENSE already holds, creating a second authority that could disagree with the first while every check passed. Passing a deliberately wrong repository and revision to that validator was accepted without complaint, and the notice printed them. LICENSE is the authority. ASF release policy puts the notice there, it ships with every artifact, and a human reviews it — and its THIRD-PARTY COMPONENTS section is already structured. So the generator parses it and reproduces the entries verbatim into both notices, and this module keeps only the one fact LICENSE cannot express: which file carries each entry and what text must still be in it. That inverts what the check is worth: - All four entries reach the notices, not the two a hand-written list happened to name. Geist is OFL-1.1 and was structurally undeclarable before, because the draft could only emit MIT. - License text is LICENSE's own, not rebuilt from a template around a hand-transcribed copyright line. - The check runs both ways. A LICENSE entry with no carrier decision fails, so #2907's Vercel AI SDK and Astryx entries cannot land unanchored; a carrier decision with no LICENSE entry fails too. - `trycua/cua` is now anchored. `palette.ts` calls itself a "faithful 1:1 port" — a stronger claim than the opencode adaptation — and nothing had been holding it. The notices' own prose no longer implies more than it delivers: it says the entries are LICENSE's section reproduced and checked against their carriers, not that everything vendored has been found. Discovering undeclared material is a scan whose allowlist is #2907's audit table, and it belongs there. Validation takes its inputs as arguments, so every failure path is exercised against fixtures rather than by editing tracked source. `non-npm-sources.mjs` and both test files are wired into the CI planner's CLI-package inputs, the Windows release path filter, and `check:release`, so changing the guard runs the guard. Generated-by: Claude Code
Summary
LICENSEafter confirming thatNOTICEneeds no changeLICENSEcannot leak into a dependency noticeRefs #2669
Verification
node --test scripts/generate-third-party-notices.test.mjsnpm run check:third-party-noticesnode scripts/gen-bundled-skill-catalog.mjs --checknpx biome check scripts/generate-third-party-notices.mjs scripts/generate-third-party-notices.test.mjs packages/runtime/resources/bundled-skills/provenance.jsongit diff --checkRepository-wide tests and typecheck were not run because this change is limited to documentation, provenance data, and the focused notice-generator regression.
Review focus and remaining gates
LICENSE/NOTICEconclusion.The second item does not block publishing or reviewing this report. The third item is deliberately narrow: it does not classify the Computer Use implementation as a whole as binary-derived.
AI assistance
OpenAI Codex reconstructed the recovered scanner evidence, compared it with the fixed source snapshot, and drafted the report, attribution changes, and regression fix. The human contributor of record retains responsibility for accuracy, provenance, licensing, and the submission decision.
Checklist
Does this PR entail a change in behavior?