Skip to content

fix(legal): 52 packages declared Apache-2.0 and shipped the MIT text (LEGAL-001) - #80

Merged
yakimoto merged 1 commit into
mainfrom
chore/legal001-sdks-license-text
Sep 4, 2026
Merged

fix(legal): 52 packages declared Apache-2.0 and shipped the MIT text (LEGAL-001)#80
yakimoto merged 1 commit into
mainfrom
chore/legal001-sdks-license-text

Conversation

@yakimoto

@yakimoto yakimoto commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

LEGAL-001 — 52 packages declared Apache-2.0 and shipped the MIT text

The defect

Every sdk-typescript/packages/*/package.json in this repo declares "license": "Apache-2.0". The LICENSE file sitting beside each of them was the MIT text. Same for sdk-python and for the two Rust crates that declare Apache-2.0.

$ git show origin/main:sdk-typescript/packages/workflow-sdk/package.json | jq -r .license
Apache-2.0
$ git show origin/main:sdk-typescript/packages/workflow-sdk/LICENSE | head -1
MIT License

That pattern held for all 49 TypeScript packages:

$ for f in $(git ls-tree -r --name-only origin/main | grep 'LICENSE$'); do
    echo "$f :: $(git show origin/main:$f | head -1)"; done
LICENSE :: Apache License                    <-- the repo root
sdk-python/LICENSE :: MIT License
sdk-go/LICENSE :: MIT License
sdk-ruby/LICENSE :: MIT License
sdk-rust/LICENSE :: MIT License
sdk-typescript/packages/adk/LICENSE :: MIT License
… 49 more, all MIT

Why nobody saw it. The repository root LICENSE has been Apache-2.0 the whole time, and every existing check looks at the root. But npm, pip and cargo pack the LICENSE from the package directory, so the root file is not the one that ships.

It is already public. @wave-av/workflow-sdk@1.0.6 is on npm right now carrying the MIT text, published from a source tree that declares Apache-2.0:

$ curl -s https://registry.npmjs.org/@wave-av/workflow-sdk | jq -r '.versions["1.0.6"].license'
MIT

Every other sdk-typescript package is unpublished from this repo today. Publishing any of them before this lands means shipping 49 more packages whose metadata and license file disagree.

What this PR changes — and deliberately does not

No declaration is changed. Each LICENSE file is rewritten to the license its own manifest already declares:

path declares LICENSE was LICENSE now
49 × sdk-typescript/packages/* Apache-2.0 MIT Apache-2.0
sdk-python Apache-2.0 MIT Apache-2.0
sdk-rust/wave, sdk-rust/wave-core Apache-2.0 MIT (inherited from sdk-rust/LICENSE) Apache-2.0 (own file, per-crate, the Rust convention)
sdk-rust/wave-x402 MIT MIT (inherited) MIT (own file, now explicit)

Untouched on purpose: sdk-go, sdk-ruby and sdk-rust/LICENSE. Those are internally consistent at MIT — sdk-ruby/wave-sdk.gemspec has spec.license = "MIT", sdk-go's README says "License: MIT", and neither has a contradiction to fix. Moving a consistent package from MIT to Apache-2.0 is a relicensing decision, and that belongs to a human, not to a lane closing a CI gap. They are listed under "operator decision" below.

The gate

scripts/license-consistency.mjs (new) walks every publishable manifest — package.json, pyproject.toml, Cargo.toml, *.gemspec — finds the LICENSE that would actually travel with it (own directory, else nearest ancestor: the same lookup the packagers perform), reads the license text and names it, and fails when the declaration does not match. Comparing declarations to one another cannot catch this class of defect; only reading the file can. It skips "private": true manifests and any manifest that declares no license.

It is dependency-free on purpose: this repo has no root package.json, so the gate has to run against a bare checkout with nothing installed. Wired in as license-consistency / licenses on every PR and on main.

Proving runs

Red on origin/main — a detached worktree at origin/main with only the script copied in:

$ git worktree add --detach /tmp/before origin/main && cp scripts/license-consistency.mjs /tmp/before/scripts/
$ cd /tmp/before && node scripts/license-consistency.mjs
license-consistency: checked 54 publishable packages

52 package(s) declare a license they do not ship:

  sdk-python/pyproject.toml
    declares : Apache-2.0
    ships    : MIT (sdk-python/LICENSE)
  sdk-rust/wave-core/Cargo.toml
    declares : Apache-2.0
    ships    : MIT (sdk-rust/LICENSE)
  …
EXIT=1

Green on this branch:

$ node scripts/license-consistency.mjs ; echo EXIT=$?
license-consistency: checked 54 publishable packages
OK — every declared license matches the license text shipped beside it.
EXIT=0

The two packages that pass on both sides are sdk-ruby and sdk-rust/wave-x402 — the consistent-MIT ones this PR leaves alone. That is the gate proving it distinguishes contradiction from a license you may not like.

Contention

No open PR in this repo touches any LICENSE file. #51 touches sdk-typescript/package.json and #50 touches sdk-typescript/packages/mcp-server/package.json; neither path appears in this diff. Verified with gh pr view <n> --json files across all 26 open PRs.

Known gap this PR does not close

Apache-2.0 §4(d) requires redistributions to carry the NOTICE file. This repo has a root NOTICE, but npm includes LICENSE in a tarball automatically and never NOTICE — so no published WAVE package carries one (confirmed for all six npm packages and both PyPI wheels). Closing that means a per-package NOTICE plus a files entry in 49 manifests, which would bury this correctness fix in an unrelated 100-file diff. It is filed as a follow-up.

Rollback

Revert the commit. The change is 53 LICENSE files plus one new script and one new workflow; no source, build, manifest, or lockfile is touched, so nothing that compiles or publishes changes behaviour. Reverting restores the MIT text and removes the gate. This PR implies no republish — npm metadata for already-published versions is immutable, and any republish is an operator decision.

🤖 Generated with Claude Code


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Note

Medium Risk
Changes legal license text shipped with published SDK artifacts (compliance fix, not runtime code), with broad monorepo LICENSE churn that must stay aligned with unchanged manifest declarations.

Overview
Fixes a mismatch where many publishable packages declared Apache-2.0 in manifests but shipped MIT in per-package LICENSE files (what npm/pip/cargo actually pack). This PR replaces those LICENSE files with Apache-2.0 text for sdk-python, the TypeScript SDK packages shown in the diff, and sdk-rust/wave / wave-core, and adds an explicit MIT LICENSE for sdk-rust/wave-x402 where the crate already declares MIT.

Adds scripts/license-consistency.mjs, a dependency-free checker that walks publishable manifests (package.json, pyproject.toml, Cargo.toml, gemspecs), resolves the nearest LICENSE like packagers do, infers SPDX from the file text, and fails when it does not match the declaration. license-consistency GitHub Actions workflow runs that script on every PR and on main.

Reviewed by Cursor Bugbot for commit 92d936b. Bugbot is set up for automated code reviews on this repo. Configure here.

Review in cubic

Summary by Sourcery

Correct shipped package licensing and enforce consistency between package declarations and distributed license text.

Bug Fixes:

  • Align package-distributed license files with the Apache-2.0 or MIT license declared by each publishable package, resolving licensing inconsistencies across the SDKs.

Enhancements:

  • Add a dependency-free audit that discovers publishable manifests, identifies the license text packaged with each one, and reports declaration mismatches.

CI:

  • Run license consistency checks on every pull request, pushes to main, and manual workflow dispatches.

Chores:

  • Add explicit per-crate license files for the Rust packages.

…(LEGAL-001)

Every `sdk-typescript/packages/*/package.json` declares "license": "Apache-2.0".
The LICENSE file sitting beside each of them was the MIT text. Same for
sdk-python (pyproject declares Apache-2.0, sdk-python/LICENSE was MIT) and for
the two Rust crates that declare Apache-2.0 but resolved to the MIT
sdk-rust/LICENSE.

The repository ROOT LICENSE has been Apache-2.0 the whole time, which is exactly
why this went unseen: every existing check looks at the root, while npm, pip and
cargo pack the LICENSE from the PACKAGE directory. The consequence is already
public — @wave-av/workflow-sdk@1.0.6 is on npm carrying the MIT text from a
source tree that declares Apache-2.0.

This changes no declaration. Each LICENSE file is rewritten to the license its
own manifest ALREADY declares:
  - 49 sdk-typescript packages  -> Apache-2.0 (manifests already said so)
  - sdk-python                  -> Apache-2.0 (pyproject already said so)
  - sdk-rust/wave, wave-core    -> Apache-2.0 (Cargo.toml already said so)
  - sdk-rust/wave-x402          -> MIT        (Cargo.toml says MIT)
sdk-go, sdk-ruby and sdk-rust/LICENSE are untouched: they are internally
consistent at MIT, and moving them to Apache-2.0 would be a relicensing
decision, which is not a CI fix.

Added scripts/license-consistency.mjs, which reads the license TEXT beside each
manifest, names it, and fails when it does not match the declaration. Run against
origin/main it reports 52 failures out of 54 packages; against this branch, zero.
Wired in as the `license-consistency / licenses` check.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@codeant-ai

codeant-ai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Your free trial PR review limit of 300 PRs has been reached. Please upgrade your plan to continue using CodeAnt AI.

@qodo-code-review

Copy link
Copy Markdown

ⓘ Qodo reviews are paused because your workspace is out of credits. Ask your workspace admin to add credits to resume reviews. Manage billing

@coderabbitai

coderabbitai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 3 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available. Your 91 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Team

Run ID: 9297a6eb-c081-4ef8-9ff7-fcdaa8f6841e

📥 Commits

Reviewing files that changed from the base of the PR and between 70b2a04 and 92d936b.

📒 Files selected for processing (55)
  • .github/workflows/license-consistency.yml
  • scripts/license-consistency.mjs
  • sdk-python/LICENSE
  • sdk-rust/wave-core/LICENSE
  • sdk-rust/wave-x402/LICENSE
  • sdk-rust/wave/LICENSE
  • sdk-typescript/packages/adk/LICENSE
  • sdk-typescript/packages/audience/LICENSE
  • sdk-typescript/packages/autopilot/LICENSE
  • sdk-typescript/packages/billing/LICENSE
  • sdk-typescript/packages/camera-control/LICENSE
  • sdk-typescript/packages/captions/LICENSE
  • sdk-typescript/packages/chapters/LICENSE
  • sdk-typescript/packages/clips/LICENSE
  • sdk-typescript/packages/cloud-switcher/LICENSE
  • sdk-typescript/packages/collab/LICENSE
  • sdk-typescript/packages/connect/LICENSE
  • sdk-typescript/packages/console/LICENSE
  • sdk-typescript/packages/core/LICENSE
  • sdk-typescript/packages/creator/LICENSE
  • sdk-typescript/packages/desktop/LICENSE
  • sdk-typescript/packages/discovery/LICENSE
  • sdk-typescript/packages/distribution/LICENSE
  • sdk-typescript/packages/drm/LICENSE
  • sdk-typescript/packages/edge/LICENSE
  • sdk-typescript/packages/editor/LICENSE
  • sdk-typescript/packages/fleet/LICENSE
  • sdk-typescript/packages/ghost/LICENSE
  • sdk-typescript/packages/kernel/LICENSE
  • sdk-typescript/packages/marketplace/LICENSE
  • sdk-typescript/packages/mcp-server/LICENSE
  • sdk-typescript/packages/mesh/LICENSE
  • sdk-typescript/packages/notifications/LICENSE
  • sdk-typescript/packages/phone/LICENSE
  • sdk-typescript/packages/pipeline/LICENSE
  • sdk-typescript/packages/podcast/LICENSE
  • sdk-typescript/packages/prism/LICENSE
  • sdk-typescript/packages/prompter/LICENSE
  • sdk-typescript/packages/pulse/LICENSE
  • sdk-typescript/packages/qr/LICENSE
  • sdk-typescript/packages/replay/LICENSE
  • sdk-typescript/packages/scene/LICENSE
  • sdk-typescript/packages/sdk/LICENSE
  • sdk-typescript/packages/search/LICENSE
  • sdk-typescript/packages/sentiment/LICENSE
  • sdk-typescript/packages/signage/LICENSE
  • sdk-typescript/packages/slides/LICENSE
  • sdk-typescript/packages/studio-ai/LICENSE
  • sdk-typescript/packages/studio/LICENSE
  • sdk-typescript/packages/transcribe/LICENSE
  • sdk-typescript/packages/usb/LICENSE
  • sdk-typescript/packages/vault/LICENSE
  • sdk-typescript/packages/voice/LICENSE
  • sdk-typescript/packages/workflow-sdk/LICENSE
  • sdk-typescript/packages/zoom/LICENSE

Comment @coderabbitai help to get the list of available commands.

@cursor

cursor Bot commented Sep 4, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_c1fba266-16da-4540-a822-08b894a5ade6)

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @yakimoto, this account has used its review budget of 2,500,000 diff characters for the last 7 days.

You can request another review in 17 hours and 44 minutes by commenting @sourcery-ai review.

@cubic-dev-ai

cubic-dev-ai Bot commented Sep 4, 2026

Copy link
Copy Markdown

This PR has 11,773 reviewable changed lines after ignored/generated files are excluded, above this repository's 5,000-changed-line automatic review limit.

Most of the diff comes from:

  • sdk-python/LICENSE (~223 changed lines)
  • sdk-typescript/packages/adk/LICENSE (~223 changed lines)
  • sdk-typescript/packages/audience/LICENSE (~223 changed lines)
  • sdk-typescript/packages/autopilot/LICENSE (~223 changed lines)
  • sdk-typescript/packages/billing/LICENSE (~223 changed lines)

Comment @cubic-dev-ai review this to review it anyway. If the largest files are generated or fixture data, add them to your ignored files in review settings or ignorePatterns in cubic.yaml - cubic will then review the rest automatically. You can also raise this limit in review settings.

@sourcery-ai

sourcery-ai Bot commented Sep 4, 2026

Copy link
Copy Markdown

Reviewer's Guide

Aligns all contradictory publishable package LICENSE files with their existing manifest declarations and introduces a dependency-free repository-wide audit enforced on pull requests and main, while intentionally preserving consistent MIT licensing and leaving NOTICE propagation for a follow-up.

Flow diagram for license consistency enforcement

flowchart LR
    M[Publishable manifests] --> D[declaredLicense]
    M --> N[nearestLicense]
    N --> T[detectSpdxFromText]
    D --> C{declared matches shipped?}
    T --> C
    C -->|yes| O[CI passes]
    C -->|no| F[CI fails with mismatch]
Loading

File-Level Changes

Change Details Files
Replace package-level MIT license texts with the Apache-2.0 or MIT text declared by each publishable package.
  • Update 49 TypeScript package licenses and the Python package license to Apache-2.0.
  • Add explicit per-crate license files for the two Apache-licensed Rust crates and the MIT-licensed x402 crate.
  • Leave internally consistent Go, Ruby, and Rust workspace licensing unchanged.
sdk-python/LICENSE
sdk-rust/wave/LICENSE
sdk-rust/wave-core/LICENSE
sdk-rust/wave-x402/LICENSE
sdk-typescript/packages/*/LICENSE
Add a dependency-free audit that compares declared licenses with the license text actually found by package-directory/ancestor lookup.
  • Discover package.json, pyproject.toml, Cargo.toml, and gemspec manifests while skipping non-publishable/private trees.
  • Parse supported license declarations and identify Apache-2.0, MIT, MPL-2.0, BSD-3-Clause, ISC, or unknown text from LICENSE files.
  • Report mismatches, missing files, and optional JSON results with a failing exit status.
scripts/license-consistency.mjs
Enforce license consistency automatically in CI for pull requests and main.
  • Run the audit on pull_request, main pushes, and manual dispatch using Node 22.
  • Use read-only contents permissions, checkout credential isolation, concurrency cancellation, and a five-minute timeout.
.github/workflows/license-consistency.yml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@macroscopeapp

macroscopeapp Bot commented Sep 4, 2026

Copy link
Copy Markdown

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — The changes correct license text shipped by 53 packages and add a read-only CI consistency audit, without modifying normal request-path code. Human review remains warranted because the diff changes an artifact under the billing package and all changed files are outside the author’s designated ownership domain.

Not approved because:

  • Credit balance exhausted. Approvability relies on correctness review in order to determine eligibility

Review your spending limits in Billing settings. You can add or adjust custom eligibility rules. Learn more.

Comment on lines +43 to +50
export function declaredLicense(manifestPath) {
const text = readFileSync(manifestPath, 'utf8');
if (manifestPath.endsWith('.json')) {
const pkg = JSON.parse(text);
if (pkg.private === true) return null; // never published
const l = pkg.license;
return typeof l === 'string' ? l : l?.type ?? null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Edge Case: declaredLicense doesn't handle SPDX compound expressions in package.json

declaredLicense reads pkg.license as a plain string or {type} object, but npm also allows SPDX expressions like (MIT OR Apache-2.0) and the deprecated licenses: [...] array form. If any manifest is later authored with a compound expression, detectSpdxFromText will never return a matching compound string, so the gate will permanently fail that package even though it's technically valid — a false positive that could block a legitimate release. Not triggered today since all current manifests use plain SPDX-string licenses, but worth a comment or explicit handling (e.g., treat non-simple-identifier strings as unsupported and skip with a warning rather than silently mismatching).

Was this helpful? React with 👍 / 👎

Comment on lines +61 to +64
if (manifestPath.endsWith('Cargo.toml')) {
// Only a crate's own [package] license counts; a workspace Cargo.toml has none.
return text.match(/^\s*license\s*=\s*["']([^"']+)["']/m)?.[1] ?? null;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Edge Case: Cargo.toml license regex is not scoped to the [package] table

declaredLicense for Cargo.toml matches /^\s*license\s*=\s*["']([^"']+)["']/m against the whole file, so if any future dependency/workspace metadata table also defines a top-level license = "..." key before [package], or a crate is restructured, the regex could grab the wrong value. Current crates (sdk-rust/wave, wave-core, wave-x402) are unaffected since their only license key is under [package], but scoping the match to text between [package] and the next [ header would make the gate robust against future Cargo.toml changes.

Was this helpful? React with 👍 / 👎

Comment on lines +31 to +45
export function detectSpdxFromText(text) {
if (typeof text !== 'string' || !text.trim()) return 'UNKNOWN';
if (/apache\s+license\s*\n?\s*version\s+2\.0/i.test(text)) return 'Apache-2.0';
if (/mozilla public license\s*,?\s*(version\s+)?2\.0/i.test(text)) return 'MPL-2.0';
if (/\bbsd\b.*\blicense\b/i.test(text) && /neither the name of/i.test(text)) return 'BSD-3-Clause';
if (/permission to use, copy, modify,? and\/or distribute/i.test(text)) return 'ISC';
if (/\bmit license\b/i.test(text)) return 'MIT';
if (/permission is hereby granted, free of charge/i.test(text)) return 'MIT';
return 'UNKNOWN';
}

/** The license a manifest declares, or null when it declares none. */
export function declaredLicense(manifestPath) {
const text = readFileSync(manifestPath, 'utf8');
if (manifestPath.endsWith('.json')) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Quality: New license-consistency script has no unit tests

The script exports pure, easily-testable functions (detectSpdxFromText, declaredLicense, nearestLicense, audit) but ships with no automated test file — only manual "proving run" transcripts in the PR description. Since this is meant to be a required, long-lived CI gate, a small test suite (e.g. asserting detectSpdxFromText against known Apache/MIT/BSD/ISC sample texts, and nearestLicense ancestor fallback behavior) would prevent silent regressions when the script is later modified.

Was this helpful? React with 👍 / 👎

@gitar-bot

gitar-bot Bot commented Sep 4, 2026

Copy link
Copy Markdown

Note

Automatic reviews are paused because your team has used its included automatic processing for this billing period (headroom scales with your seat count). You can still comment "Gitar review" to run one anytime, and automatic reviews resume on their own by October 1. Add seats for more headroom.
Learn more

Code Review 👍 Approved with suggestions 0 resolved / 3 findings

Fixes 52 packages that declared Apache-2.0 but shipped MIT license text, and adds license-consistency.mjs to enforce declaration-to-file matching on all future packages. Consider handling SPDX compound expressions like (MIT OR Apache-2.0) in declaredLicense to avoid false positives, scope the Cargo.toml license regex to the [package] table for robustness, and add unit tests for the gate functions (detectSpdxFromText, declaredLicense, nearestLicense) to prevent regressions.

💡 Edge Case: declaredLicense doesn't handle SPDX compound expressions in package.json

📄 scripts/license-consistency.mjs:43-50

declaredLicense reads pkg.license as a plain string or {type} object, but npm also allows SPDX expressions like (MIT OR Apache-2.0) and the deprecated licenses: [...] array form. If any manifest is later authored with a compound expression, detectSpdxFromText will never return a matching compound string, so the gate will permanently fail that package even though it's technically valid — a false positive that could block a legitimate release. Not triggered today since all current manifests use plain SPDX-string licenses, but worth a comment or explicit handling (e.g., treat non-simple-identifier strings as unsupported and skip with a warning rather than silently mismatching).

💡 Edge Case: Cargo.toml license regex is not scoped to the [package] table

📄 scripts/license-consistency.mjs:61-64

declaredLicense for Cargo.toml matches /^\s*license\s*=\s*["']([^"']+)["']/m against the whole file, so if any future dependency/workspace metadata table also defines a top-level license = "..." key before [package], or a crate is restructured, the regex could grab the wrong value. Current crates (sdk-rust/wave, wave-core, wave-x402) are unaffected since their only license key is under [package], but scoping the match to text between [package] and the next [ header would make the gate robust against future Cargo.toml changes.

💡 Quality: New license-consistency script has no unit tests

📄 scripts/license-consistency.mjs:31-45

The script exports pure, easily-testable functions (detectSpdxFromText, declaredLicense, nearestLicense, audit) but ships with no automated test file — only manual "proving run" transcripts in the PR description. Since this is meant to be a required, long-lived CI gate, a small test suite (e.g. asserting detectSpdxFromText against known Apache/MIT/BSD/ISC sample texts, and nearestLicense ancestor fallback behavior) would prevent silent regressions when the script is later modified.

🤖 Prompt for agents
Code Review: Fixes 52 packages that declared Apache-2.0 but shipped MIT license text, and adds `license-consistency.mjs` to enforce declaration-to-file matching on all future packages. Consider handling SPDX compound expressions like `(MIT OR Apache-2.0)` in `declaredLicense` to avoid false positives, scope the Cargo.toml license regex to the `[package]` table for robustness, and add unit tests for the gate functions (`detectSpdxFromText`, `declaredLicense`, `nearestLicense`) to prevent regressions.

1. 💡 Edge Case: declaredLicense doesn't handle SPDX compound expressions in package.json
   Files: scripts/license-consistency.mjs:43-50

   `declaredLicense` reads `pkg.license` as a plain string or `{type}` object, but npm also allows SPDX expressions like `(MIT OR Apache-2.0)` and the deprecated `licenses: [...]` array form. If any manifest is later authored with a compound expression, `detectSpdxFromText` will never return a matching compound string, so the gate will permanently fail that package even though it's technically valid — a false positive that could block a legitimate release. Not triggered today since all current manifests use plain SPDX-string licenses, but worth a comment or explicit handling (e.g., treat non-simple-identifier strings as unsupported and skip with a warning rather than silently mismatching).

2. 💡 Edge Case: Cargo.toml license regex is not scoped to the [package] table
   Files: scripts/license-consistency.mjs:61-64

   `declaredLicense` for Cargo.toml matches `/^\s*license\s*=\s*["']([^"']+)["']/m` against the whole file, so if any future dependency/workspace metadata table also defines a top-level `license = "..."` key before `[package]`, or a crate is restructured, the regex could grab the wrong value. Current crates (`sdk-rust/wave`, `wave-core`, `wave-x402`) are unaffected since their only `license` key is under `[package]`, but scoping the match to text between `[package]` and the next `[` header would make the gate robust against future Cargo.toml changes.

3. 💡 Quality: New license-consistency script has no unit tests
   Files: scripts/license-consistency.mjs:31-45

   The script exports pure, easily-testable functions (`detectSpdxFromText`, `declaredLicense`, `nearestLicense`, `audit`) but ships with no automated test file — only manual "proving run" transcripts in the PR description. Since this is meant to be a required, long-lived CI gate, a small test suite (e.g. asserting `detectSpdxFromText` against known Apache/MIT/BSD/ISC sample texts, and `nearestLicense` ancestor fallback behavior) would prevent silent regressions when the script is later modified.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@yakimoto
yakimoto merged commit 110774f into main Sep 4, 2026
33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant