diff --git a/.github/workflows/license-truth.yml b/.github/workflows/license-truth.yml new file mode 100644 index 0000000..e3bd31a --- /dev/null +++ b/.github/workflows/license-truth.yml @@ -0,0 +1,48 @@ +name: license-truth + +# LEGAL-001 gate for dispatch-edge. Blocks the class of defect fixed in #451/#39: every +# one of the five SDK manifests here (go, js, python, ruby, rust) declared MIT while +# LICENSE had been the Apache-2.0 text since e3b3fb8 — nothing in the existing gates read +# a license FILE, so nothing could see it. Also blocks the subtler sibling: a manifest +# declaring a license while its own package directory ships no LICENSE text at all (npm +# and cargo pack from the PACKAGE directory only, never a monorepo root, so a root-level +# LICENSE never travels with a `sdk/js` or `sdk/rust` publish). +# +# FAILS CLOSED. `node scripts/license-truth.mjs` exits 1 on divergence AND on "could not +# measure anything" (0 manifests found, or manifests found but none declares a license) — +# never green on an empty denominator. See the header comment in scripts/license-truth.mjs. +# +# The selftest runs first, every time: a detector that cannot catch a PLANTED bug is not +# trusted to report on the real tree. + +on: + pull_request: + push: + branches: [main] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + license-truth: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0 + with: + node-version: 22 + + - name: Drill the detector RED on seeded violations first + run: node scripts/license-truth.selftest.mjs + + - name: License truth gate + run: node scripts/license-truth.mjs diff --git a/README.md b/README.md index 5c19797..61f4e51 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ routing decision and **logs zero prompt content**; with local-first routing, mos [![PyPI](https://img.shields.io/pypi/v/wave-dispatch?label=PyPI)](https://pypi.org/project/wave-dispatch/) [![crates.io](https://img.shields.io/crates/v/wave-dispatch?label=crates.io)](https://crates.io/crates/wave-dispatch) [![Gem](https://img.shields.io/gem/v/wave-dispatch?label=gem)](https://rubygems.org/gems/wave-dispatch) -[![License: MIT](https://img.shields.io/badge/license-MIT-43d9ad)](./LICENSE) +[![License: Apache 2.0](https://img.shields.io/badge/license-Apache--2.0-43d9ad)](./LICENSE) @@ -137,4 +137,4 @@ Full breakdown → [pricing](https://dispatch.wave.online/pricing). ## License -MIT © 2026 WAVE Online, LLC. A [WAVE](https://wave.online) product — local-first by design. +Apache-2.0 © 2026 WAVE Online, LLC. A [WAVE](https://wave.online) product — local-first by design. diff --git a/scripts/lib/license-truth.mjs b/scripts/lib/license-truth.mjs new file mode 100644 index 0000000..10e2040 --- /dev/null +++ b/scripts/lib/license-truth.mjs @@ -0,0 +1,148 @@ +// license-truth — pure license-identity logic for LEGAL-001 (dispatch-edge#39 gate). +// +// Vendored from wave-av/claude-workstation governance/lib/license-truth.mjs, which is +// designed to be shared: "the fleet driver, a repo-local gate and the drill can all +// share one definition of 'what license is this really'." No IO, no network — every +// function here takes text it has already been given and returns a verdict. +// +// The one idea worth holding: you cannot catch a declared-vs-shipped license +// contradiction by comparing declarations to each other. Both sides can agree and +// still both be wrong about the file that actually travels. The only way is to READ +// THE LICENSE TEXT AND NAME IT. +// +// dispatch-edge is a monorepo with five SDK subdirectories (go, js, python, ruby, +// rust) each publishing to its own registry. npm and cargo pack from the PACKAGE +// directory and never walk up to a repo root — that is exactly the defect class +// this gate exists to catch (a subpackage declaring a license while shipping none +// of its own, silently relying on a root LICENSE that never travels with the +// published artifact). `resolveShippedLicense` is always called here with +// `strict: true` for that reason: every subpackage must carry its own copy. + +// Ordered most-specific-first. Each pattern targets a phrase that appears only +// inside that license's body, never a mere mention of its name. +export const LICENSE_FINGERPRINTS = [ + [/GNU AFFERO GENERAL PUBLIC LICENSE/i, "AGPL-3.0"], + [/GNU LESSER GENERAL PUBLIC LICENSE/i, "LGPL"], + [/GNU GENERAL PUBLIC LICENSE\s+Version 3/i, "GPL-3.0"], + [/GNU GENERAL PUBLIC LICENSE\s+Version 2/i, "GPL-2.0"], + [/Mozilla Public License Version 2\.0/i, "MPL-2.0"], + [/Apache License\s+Version 2\.0/i, "Apache-2.0"], + [/Permission is hereby granted, free of charge, to any person obtaining a copy/i, "MIT"], + [/Permission to use, copy, modify, and\/or distribute this software/i, "ISC"], + // BSD-2-Clause and BSD-3-Clause share this exact preamble verbatim — resolved + // below by checking for the extra "endorse or promote" clause BSD-3 alone carries. + [/Redistribution and use in source and binary forms/i, "BSD"], + [/This is free and unencumbered software released into the public domain/i, "Unlicense"], +]; + +const BSD3_ENDORSEMENT_CLAUSE = /may be used to endorse or promote products derived from this software/i; + +/** Name the license a blob of text actually IS. Never guesses from a filename. */ +export function identifyLicenseText(text) { + if (typeof text !== "string" || text.trim() === "") return "EMPTY"; + const flat = text.replace(/\s+/g, " "); + for (const [re, id] of LICENSE_FINGERPRINTS) { + if (!re.test(flat)) continue; + if (id === "BSD") return BSD3_ENDORSEMENT_CLAUSE.test(flat) ? "BSD-3-Clause" : "BSD-2-Clause"; + return id; + } + return "UNRECOGNIZED"; +} + +/** Normalize a declaration for comparison. A compound SPDX expression escalates. */ +export function normalizeDeclared(decl) { + if (!decl || typeof decl !== "string") return null; + const d = decl.trim(); + if (d === "") return null; + if (/\s(OR|AND)\s/i.test(d) || d.startsWith("(")) return { expression: d }; + const id = d + .replace(/-only$|-or-later$/i, "") + .replace(/^GPL-2\.0.*$/i, "GPL-2.0") + .replace(/^LGPL-.*$/i, "LGPL"); + return { id }; +} + +/** The verdict. Every non-ok path names WHY. */ +export function declarationMatches(declared, shippedId) { + const n = normalizeDeclared(declared); + if (!n) return { ok: false, reason: "no-declaration" }; + if (n.expression) return { ok: false, reason: "spdx-expression-needs-human" }; + const shipped = String(shippedId).replace(/^GPL-2\.0.*$/i, "GPL-2.0"); + if (shipped === "EMPTY") return { ok: false, reason: "license-file-empty" }; + if (shipped === "NO-LICENSE-FILE") return { ok: false, reason: "license-file-missing" }; + if (shipped === "UNREADABLE") return { ok: false, reason: "license-file-unreadable" }; + if (shipped === "UNRECOGNIZED") return { ok: false, reason: "license-text-unrecognized" }; + return n.id === shipped ? { ok: true } : { ok: false, reason: "declared-vs-shipped-divergence" }; +} + +export const MANIFEST_RE = /(^|\/)(package\.json|pyproject\.toml|Cargo\.toml|[^/]+\.gemspec)$/; +export const LICENSE_FILE_RE = /(^|\/)(LICEN[CS]E|COPYING)(\.(md|txt|rst))?$/i; +export const VENDOR_RE = /(^|\/)(node_modules|vendor|third_party|\.venv|target|dist|fixtures?|testdata)(\/|$)/; + +const pyName = (t) => t.match(/^\s*name\s*=\s*["']([^"']+)["']/mi)?.[1] ?? null; + +/** Read a manifest's license DECLARATION plus enough context to judge it. */ +export function parseManifest(path, text) { + try { + if (path.endsWith("package.json")) { + const j = JSON.parse(text); + return { + declared: typeof j.license === "string" ? j.license : null, + private: j.private === true, + name: j.name ?? null, + ecosystem: "npm", + files: Array.isArray(j.files) ? j.files : null, + }; + } + if (path.endsWith("pyproject.toml")) { + const block = text.match(/^\s*license\s*=\s*(.+)$/mi)?.[1] ?? ""; + const classifier = text.match(/License :: OSI Approved :: ([^"'\]]+?) License/i)?.[1]?.trim() ?? null; + if (/file\s*=/.test(block)) return { declared: null, classifier, private: false, name: pyName(text), ecosystem: "pypi", licenseByFile: true }; + const declared = block.match(/text\s*=\s*["']([^"']+)["']/)?.[1] ?? block.match(/^["']([^"']+)["']/)?.[1] ?? null; + return { declared, classifier, private: false, name: pyName(text), ecosystem: "pypi" }; + } + if (path.endsWith("Cargo.toml")) { + // A virtual workspace root ships nothing itself. + if (/^\s*\[workspace\]/m.test(text) && !/^\s*\[package\]/m.test(text)) return { declared: null, private: true, name: null, ecosystem: "cargo" }; + const excludeMatch = text.match(/^\s*exclude\s*=\s*\[([^\]]*)\]/mi)?.[1] ?? ""; + const includeMatch = text.match(/^\s*include\s*=\s*\[([^\]]*)\]/mi)?.[1] ?? null; + return { + declared: text.match(/^\s*license\s*=\s*["']([^"']+)["']/mi)?.[1] ?? null, + private: /^\s*publish\s*=\s*false/mi.test(text), + name: text.match(/^\s*name\s*=\s*["']([^"']+)["']/mi)?.[1] ?? null, + ecosystem: "cargo", + excludesLicense: /LICEN[CS]E/i.test(excludeMatch), + include: includeMatch, + }; + } + if (path.endsWith(".gemspec")) { + const filesMatch = text.match(/\.files\s*=\s*\[([^\]]*)\]/)?.[1] ?? null; + return { + declared: text.match(/\.licenses?\s*=\s*\[?\s*["']([^"']+)["']/)?.[1] ?? null, + private: false, + name: text.match(/\.name\s*=\s*["']([^"']+)["']/)?.[1] ?? null, + ecosystem: "rubygems", + files: filesMatch, + }; + } + } catch { return null; } + return null; +} + +/** + * Find the LICENSE that would actually travel with a manifest. + * + * `strict: true` models npm/cargo, which pack the LICENSE from the PACKAGE + * directory and never walk up to a repo root. Always strict here: every + * dispatch-edge subpackage must carry its own copy. + */ +export function resolveShippedLicense(manifestPath, licensePaths, { strict = true } = {}) { + const dirOf = (p) => (p.includes("/") ? p.slice(0, p.lastIndexOf("/")) : ""); + let dir = dirOf(manifestPath); + for (;;) { + const hit = licensePaths.find((L) => dirOf(L) === dir); + if (hit) return hit; + if (strict || dir === "") return null; + dir = dirOf(dir); + } +} diff --git a/scripts/license-truth.mjs b/scripts/license-truth.mjs new file mode 100644 index 0000000..1325625 --- /dev/null +++ b/scripts/license-truth.mjs @@ -0,0 +1,143 @@ +#!/usr/bin/env node +// license-truth — the repo-local LEGAL-001 gate for dispatch-edge. +// +// WHAT IT CATCHES: any of the five SDK subdirectories (go, js, python, ruby, rust) +// declaring a license in its own manifest that the LICENSE TEXT beside it does not +// back up — either because the text says something else (the #451 defect: every +// manifest here said MIT while LICENSE had been Apache-2.0 since e3b3fb8) or +// because there is no LICENSE text in that subpackage's own directory at all (npm +// and cargo pack from the package directory only, and never walk up to the repo +// root — a green root-level check would miss this class entirely). +// +// FAILS CLOSED. Absent input is a FAILURE, never a pass: zero manifests found, or +// zero of them declaring a license, means this gate could not measure anything — +// that is reported as a failure (exit 1), not a skip and not a green. +// +// Usage: node scripts/license-truth.mjs [--json] +// Exit: 0 consistent · 1 divergence found OR could not measure anything. +import { readFileSync, readdirSync, statSync } from "node:fs"; +import { dirname, join, relative, resolve } from "node:path"; +import { fileURLToPath } from "node:url"; +import { + identifyLicenseText, declarationMatches, parseManifest, + resolveShippedLicense, MANIFEST_RE, LICENSE_FILE_RE, VENDOR_RE, +} from "./lib/license-truth.mjs"; + +const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), ".."); + +function walk(dir, out) { + let entries; + try { entries = readdirSync(dir); } catch { return; } + for (const name of entries) { + const p = join(dir, name); + const rel = relative(ROOT, p); + if (rel.startsWith(".git")) continue; + if (VENDOR_RE.test(rel)) continue; + let st; + try { st = statSync(p); } catch { continue; } + if (st.isDirectory()) walk(p, out); + else out.push(rel); + } +} + +export function auditRepo(root = ROOT) { + const files = []; + walk(root, files); + const licensePaths = files.filter((f) => LICENSE_FILE_RE.test(f)); + const manifestPaths = files.filter((f) => MANIFEST_RE.test(f)); + + const licenseId = new Map(); + for (const p of licensePaths) { + try { licenseId.set(p, identifyLicenseText(readFileSync(join(root, p), "utf8"))); } + catch { licenseId.set(p, "UNREADABLE"); } + } + + const findings = []; + const units = []; + let declaredCount = 0; + + for (const mp of manifestPaths) { + let raw; + try { raw = readFileSync(join(root, mp), "utf8"); } catch { continue; } + const m = parseManifest(mp, raw); + if (!m || m.private || (!m.declared && !m.licenseByFile)) continue; + declaredCount += 1; + + const shippedPath = resolveShippedLicense(mp, licensePaths, { strict: true }); + const shipped = shippedPath ? licenseId.get(shippedPath) : "NO-LICENSE-FILE"; + const unit = { manifest: mp, pkg: m.name, ecosystem: m.ecosystem, declared: m.declared, shipped, shippedFrom: shippedPath }; + units.push(unit); + const dir = mp.replace(/[^/]+$/, "") || "./"; + + if (!shippedPath) { + findings.push({ ...unit, rule: "license-file-missing-in-package-dir", + detail: `${m.name ?? mp} declares ${m.declared} but ${dir} contains no LICENSE — the published artifact would carry no license text of its own.` }); + continue; + } + + // Ecosystems that do NOT auto-include a colocated LICENSE in the published + // artifact must say so explicitly. npm always includes a colocated LICENSE + // regardless of `files` (documented npm-packlist behavior), and cargo's + // default packlist is every git-tracked file in the package directory unless + // `exclude` says otherwise — so both are covered by the colocation check + // above, PLUS an explicit veto check here for the ways each can still opt out. + if (m.ecosystem === "rubygems") { + const licenseBase = shippedPath.split("/").pop(); + if (m.files === null || !new RegExp(`(^|[\\s'",])${licenseBase}([\\s'",]|$)`).test(m.files)) { + findings.push({ ...unit, rule: "license-not-in-gem-files", + detail: `${m.name ?? mp}: ${shippedPath} exists but s.files does not list it — RubyGems ships exactly the files named in s.files, nothing more.` }); + } + } + if (m.ecosystem === "cargo" && m.excludesLicense) { + findings.push({ ...unit, rule: "license-excluded-from-crate", + detail: `${m.name ?? mp}: Cargo.toml's [package].exclude removes the LICENSE file from the published crate.` }); + } + if (m.ecosystem === "cargo" && m.include && !new RegExp(`LICEN[CS]E`, "i").test(m.include)) { + findings.push({ ...unit, rule: "license-absent-from-crate-include", + detail: `${m.name ?? mp}: Cargo.toml sets [package].include and it does not name the LICENSE file, so cargo would omit it.` }); + } + + const verdict = declarationMatches(m.declared, shipped); + if (!verdict.ok) { + findings.push({ ...unit, rule: verdict.reason, + detail: `${m.name ?? mp} declares ${m.declared ?? "(nothing)"} but ships ${shipped} — ${shippedPath}.` }); + } + } + + return { files, licensePaths, manifestPaths, declaredCount, units, findings }; +} + +function main() { + const json = process.argv.includes("--json"); + const result = auditRepo(ROOT); + + if (result.manifestPaths.length === 0) { + console.error("license-truth: 0 publishable manifests found in this repo — CANNOT MEASURE. An empty denominator is not a pass."); + return 1; + } + if (result.declaredCount === 0) { + console.error(`license-truth: ${result.manifestPaths.length} manifest(s) found but none declares a license — CANNOT MEASURE. An unmeasured license state is not a passing one.`); + return 1; + } + + if (json) { + process.stdout.write(`${JSON.stringify(result, null, 2)}\n`); + return result.findings.length ? 1 : 0; + } + + console.log(`license-truth: ${result.manifestPaths.length} manifest(s) checked, ${result.declaredCount} declaring a license, ${result.licensePaths.length} LICENSE file(s) found`); + for (const u of result.units) console.log(` ${u.manifest}: declares ${u.declared ?? "(none)"} — ships ${u.shipped}${u.shippedFrom ? ` (${u.shippedFrom})` : ""}`); + + if (result.findings.length === 0) { + console.log("\nOK — every declared license matches the license text shipped beside it, in its own package directory."); + return 0; + } + + console.error(`\n${result.findings.length} unit(s) declare a license they do not (correctly) ship:`); + for (const f of result.findings) console.error(` [${f.rule}] ${f.manifest}\n ${f.detail}`); + return 1; +} + +if (process.argv[1] && resolve(process.argv[1]) === resolve(fileURLToPath(import.meta.url))) { + process.exit(main()); +} diff --git a/scripts/license-truth.selftest.mjs b/scripts/license-truth.selftest.mjs new file mode 100644 index 0000000..2ed3a76 --- /dev/null +++ b/scripts/license-truth.selftest.mjs @@ -0,0 +1,121 @@ +#!/usr/bin/env node +// license-truth.selftest — drills the detector RED on seeded violations before it is +// trusted to report on the real repo. A detector that cannot catch a PLANTED bug is +// not evidence about anything. Mirrors the shape of the org-wide +// governance/test/license-truth.selftest.mjs in claude-workstation. +// +// Exit 0 iff every seeded case produced the expected verdict; exit 1 otherwise. +import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { auditRepo } from "./license-truth.mjs"; + +const APACHE = ` Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +Licensed under the Apache License, Version 2.0 (the "License");`; +const MIT = `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.`; + +let failures = 0; +function check(name, cond) { + if (cond) { console.log(` ok ${name}`); } + else { console.error(` FAIL ${name}`); failures += 1; } +} + +function withFixture(files, fn) { + const dir = mkdtempSync(join(tmpdir(), "license-truth-selftest-")); + try { + for (const [path, content] of Object.entries(files)) { + const full = join(dir, path); + mkdirSync(full.slice(0, full.lastIndexOf("/")), { recursive: true }); + writeFileSync(full, content); + } + return fn(dir); + } finally { + rmSync(dir, { recursive: true, force: true }); + } +} + +console.log("license-truth.selftest — planting known-bad shapes, expecting RED\n"); + +// Case 1: declares MIT, ships Apache-2.0 text — the actual #451 defect this gate exists for. +withFixture({ + "sdk/js/package.json": JSON.stringify({ name: "@x/y", license: "MIT", files: ["index.js"] }), + "sdk/js/LICENSE": APACHE, +}, (dir) => { + const r = auditRepo(dir); + check("declares MIT / ships Apache-2.0 -> red", r.findings.some((f) => f.rule === "declared-vs-shipped-divergence")); +}); + +// Case 2: declares Apache-2.0, ships MIT text (the mirror image). +withFixture({ + "sdk/py/pyproject.toml": `[project]\nname = "y"\nlicense = "Apache-2.0"\n`, + "sdk/py/LICENSE": MIT, +}, (dir) => { + const r = auditRepo(dir); + check("declares Apache-2.0 / ships MIT -> red", r.findings.some((f) => f.rule === "declared-vs-shipped-divergence")); +}); + +// Case 3: declares a license, no LICENSE file anywhere in the package directory +// (npm/cargo never walk up to a repo root — this is the class a root-only check misses). +withFixture({ + "sdk/rs/Cargo.toml": `[package]\nname = "y"\nlicense = "Apache-2.0"\n`, + "LICENSE": APACHE, // present at repo root only — must NOT satisfy the strict subpackage check +}, (dir) => { + const r = auditRepo(dir); + check("declares a license / no LICENSE in package dir (root does not count) -> red", + r.findings.some((f) => f.rule === "license-file-missing-in-package-dir")); +}); + +// Case 4: gemspec declares a license, LICENSE file sits right beside it, but s.files +// never names it — RubyGems ships exactly what s.files lists, nothing more. +withFixture({ + "sdk/rb/wave.gemspec": `Gem::Specification.new do |s|\n s.name = "y"\n s.license = "Apache-2.0"\n s.files = ["lib/y.rb"]\nend\n`, + "sdk/rb/LICENSE": APACHE, +}, (dir) => { + const r = auditRepo(dir); + check("gemspec omits LICENSE from s.files -> red", r.findings.some((f) => f.rule === "license-not-in-gem-files")); +}); + +// Case 5: empty LICENSE file. +withFixture({ + "sdk/go/package.json": JSON.stringify({ name: "@x/z", license: "MIT" }), + "sdk/go/LICENSE": "", +}, (dir) => { + const r = auditRepo(dir); + check("empty LICENSE file -> red", r.findings.some((f) => f.rule === "license-file-empty")); +}); + +console.log("\nlicense-truth.selftest — consistent input, expecting GREEN\n"); + +// Consistent case must NOT go red — a detector that always fires is as useless as one that never does. +withFixture({ + "sdk/js/package.json": JSON.stringify({ name: "@x/y", license: "Apache-2.0" }), + "sdk/js/LICENSE": APACHE, +}, (dir) => { + const r = auditRepo(dir); + check("declares Apache-2.0 / ships Apache-2.0 -> green", r.findings.length === 0); +}); + +console.log("\nlicense-truth.selftest — the third state: absent input is a FAILURE, not a pass\n"); + +withFixture({}, (dir) => { + const r = auditRepo(dir); + check("0 manifests -> caller must treat as CANNOT-MEASURE (empty manifestPaths)", r.manifestPaths.length === 0); +}); +withFixture({ "sdk/go/go.mod": "module x\n\ngo 1.25\n" }, (dir) => { + const r = auditRepo(dir); + check("manifests present but none declares a license -> declaredCount 0", r.manifestPaths.length === 0 && r.declaredCount === 0); + // go.mod is intentionally not a MANIFEST_RE match (no license field to audit), + // so this fixture also proves manifestPaths stays empty rather than false-counting it. +}); + +if (failures) { + console.error(`\n${failures} selftest case(s) FAILED — the detector cannot be trusted; not running it against the real repo.`); + process.exit(1); +} +console.log("\nAll selftest cases passed — the detector catches every seeded shape."); +process.exit(0); diff --git a/sdk/js/LICENSE b/sdk/js/LICENSE new file mode 100644 index 0000000..6b79e20 --- /dev/null +++ b/sdk/js/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 WAVE, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/sdk/js/package-lock.json b/sdk/js/package-lock.json index 47e7f19..98dd9b0 100644 --- a/sdk/js/package-lock.json +++ b/sdk/js/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "@wave-av/dispatch", "version": "0.6.0", - "license": "MIT", + "license": "Apache-2.0", "devDependencies": { "typescript": "^5.9.0" }, diff --git a/sdk/js/package.json b/sdk/js/package.json index 68a1624..25a9236 100644 --- a/sdk/js/package.json +++ b/sdk/js/package.json @@ -13,7 +13,7 @@ }, "keywords": ["llm", "routing", "local-first", "cost", "edge", "wave", "dispatch", "x402", "agents"], "author": "WAVE Online, LLC", - "license": "MIT", + "license": "Apache-2.0", "homepage": "https://dispatch.wave.online", "repository": { "type": "git", "url": "git+https://github.com/wave-av/dispatch-edge.git" }, "engines": { "node": ">=18" }, diff --git a/sdk/python/LICENSE b/sdk/python/LICENSE new file mode 100644 index 0000000..6b79e20 --- /dev/null +++ b/sdk/python/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 WAVE, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/sdk/python/pyproject.toml b/sdk/python/pyproject.toml index 42d0bce..698c5df 100644 --- a/sdk/python/pyproject.toml +++ b/sdk/python/pyproject.toml @@ -1,5 +1,9 @@ [build-system] -requires = ["setuptools>=68"] +# setuptools>=77 for PEP 639: `license` as an SPDX expression plus `license-files`. The old +# `license = { text = "..." }` table is deprecated and stops building on 2027-02-18, and it is also +# what let this package ship a license CLAIM with no license TEXT — the table sets a metadata string +# and nothing else. This is a build-time floor only; the wheel still declares requires-python >=3.8. +requires = ["setuptools>=77"] build-backend = "setuptools.build_meta" [project] @@ -8,7 +12,8 @@ version = "0.7.0" description = "WAVE Dispatch — local-first AI router. `dispatch serve` runs an OpenAI-compatible proxy that routes each request to the cheapest capable model (local-first; escalate to your frontier only when needed). BYO keys + infra." readme = "README.md" requires-python = ">=3.8" -license = { text = "MIT" } +license = "Apache-2.0" +license-files = ["LICENSE"] authors = [{ name = "WAVE Online, LLC" }] keywords = ["llm", "routing", "local-first", "cost", "edge", "dispatch", "agents", "x402"] dependencies = [] diff --git a/sdk/ruby/LICENSE b/sdk/ruby/LICENSE new file mode 100644 index 0000000..6b79e20 --- /dev/null +++ b/sdk/ruby/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 WAVE, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/sdk/ruby/wave_dispatch.gemspec b/sdk/ruby/wave_dispatch.gemspec index 74e387d..ccc871c 100644 --- a/sdk/ruby/wave_dispatch.gemspec +++ b/sdk/ruby/wave_dispatch.gemspec @@ -5,8 +5,8 @@ Gem::Specification.new do |s| s.description = "Route each request to the cheapest capable model (local-first; escalate to your frontier only when needed). BYO keys + infra." s.authors = ["WAVE Online, LLC"] s.homepage = "https://dispatch.wave.online" - s.license = "MIT" - s.files = ["lib/wave_dispatch.rb"] + s.license = "Apache-2.0" + s.files = ["lib/wave_dispatch.rb", "LICENSE"] s.require_paths = ["lib"] s.required_ruby_version = ">= 2.7" s.metadata = { "source_code_uri" => "https://github.com/wave-av/dispatch-edge" } diff --git a/sdk/rust/Cargo.toml b/sdk/rust/Cargo.toml index 137c503..82c15b9 100644 --- a/sdk/rust/Cargo.toml +++ b/sdk/rust/Cargo.toml @@ -3,7 +3,7 @@ name = "wave-dispatch" version = "0.7.0" edition = "2021" description = "WAVE Dispatch — local-first AI router client. Route each request to the cheapest capable model (local-first; escalate to your frontier only when needed). BYO keys + infra." -license = "MIT" +license = "Apache-2.0" repository = "https://github.com/wave-av/dispatch-edge" homepage = "https://dispatch.wave.online" keywords = ["llm", "routing", "local-first", "dispatch"] diff --git a/sdk/rust/LICENSE b/sdk/rust/LICENSE new file mode 100644 index 0000000..6b79e20 --- /dev/null +++ b/sdk/rust/LICENSE @@ -0,0 +1,202 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2026 WAVE, Inc. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +