diff --git a/.gitignore b/.gitignore index 07882c6..bb2c54a 100644 --- a/.gitignore +++ b/.gitignore @@ -130,3 +130,4 @@ temp/ /npm/release.json /npm/transpile.worker.mjs /npm/glue.py +/npm/LICENSE diff --git a/AGENTS.md b/AGENTS.md index 626d593..719e425 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -63,8 +63,8 @@ Python entry points are `pineforge_codegen.transpile()` and `pineforge_codegen.transpile_full()`; the Pyodide package ships the `gate/glue.py` JSON protocol. See `docs/PUBLIC_CONTRACT.md`. -This is the **source-available** half of the PineForge stack (PolyForm -Noncommercial — see `LICENSE`). The runtime half (`pineforge-engine`, +This is the **source-available** half of the PineForge stack (PineForge +Source License 1.0 — see `LICENSE`). The runtime half (`pineforge-engine`, Apache-2.0) lives in a sibling repo and is typically checked out at `../pineforge-engine`. From 1.0.0 on, a released codegen `X.Y.Z` pairs only with engine `vX.Y.Z`; prereleases match exactly. Codegen 1.1.0 pairs with diff --git a/CLAUDE.md b/CLAUDE.md index 82f483f..ae85b03 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -63,8 +63,8 @@ Python entry points are `pineforge_codegen.transpile()` and `pineforge_codegen.transpile_full()`; the Pyodide package ships the `gate/glue.py` JSON protocol. See `docs/PUBLIC_CONTRACT.md`. -This is the **source-available** half of the PineForge stack (PolyForm -Noncommercial — see `LICENSE`). The runtime half (`pineforge-engine`, +This is the **source-available** half of the PineForge stack (PineForge +Source License 1.0 — see `LICENSE`). The runtime half (`pineforge-engine`, Apache-2.0) lives in a sibling repo and is typically checked out at `../pineforge-engine`. From 1.0.0 on, a released codegen `X.Y.Z` pairs only with engine `vX.Y.Z`; prereleases match exactly. Codegen 1.1.0 pairs with diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index de0e91b..9d2b696 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -4,7 +4,7 @@ This is the source-available PineScript v6 to C++ translator. Read the [license and contribution terms](LEGAL.md) before sending a material change. Contributions use the Developer Certificate of Origin: add a `Signed-off-by` line with `git commit -s`. Material contributions also require a Contributor -License Agreement so PineForge can include them in its commercial license; +License Agreement so pineforge, LLC can include them in its commercial licenses; contact luis@4pass.com.tw before opening a material pull request. ## Local setup diff --git a/LEGAL.md b/LEGAL.md index bf9d36d..1834238 100644 --- a/LEGAL.md +++ b/LEGAL.md @@ -4,13 +4,21 @@ Summary of licensing, third-party components, and trademarks for `pineforge-code ## License -`pineforge-codegen` is **source-available**, **not** OSI "open source." It is distributed under the **PolyForm Noncommercial License 1.0.0** with two supplemental terms — see [LICENSE](LICENSE), which is the controlling text: +`pineforge-codegen` is **source-available**, **not** OSI "open source." It is distributed under the **PineForge Source License 1.0** — see [LICENSE](LICENSE), which is the controlling text. -- **Personal Trading exception** — free to research, backtest, and trade your **own** capital, for an individual acting on their own behalf. -- **Commercial use** — companies, funds, managing third-party capital, embedding in a product, or operating a hosted/public-facing service requires a **commercial license** (email **luis@4pass.com.tw**). +- **Noncommercial use** — any noncommercial purpose, and use by a charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization or government institution for its teaching, research and other operations, is free. +- **Personal Trading** — free for a natural person to research, develop or backtest strategies and trade their **own** account with their **own** capital. Household, joint and retirement accounts and ordinary margin count as their own; a company's or fund's account does not, even a company they wholly own. +- **Investment management** — managing, advising on or trading investment capital, or researching strategies for it (a friend's, clients' or investors' capital, an endowment, a pension fund, a public fund, a foundation's treasury), is **Commercial Use for every individual and every organization**, noncommercial organizations included, except Personal Trading. +- **Commercial Use** — investment management and any other use that is not free, such as use by or for a company or fund, embedding the software or its output in a product or service for others, or operating a hosted/public-facing service with it, requires a **commercial license** (email **enterprise@pineforge.dev**; the commercial-license store is coming soon). Describe this project as **"source-available"** rather than "open source." The runtime it targets, [`pineforge-engine`](https://github.com/pineforge-4pass/pineforge-engine), is separate and **Apache-2.0**. +Releases up to and including 1.1.0 were published under the license text that came with them (the PolyForm Noncommercial License 1.0.0 with a PineForge supplement); copies of those releases keep that license. The PineForge Source License 1.0 is a separate license and is not a PolyForm license. + +## Copyright and licensor + +The licensor is **pineforge, LLC**, a Delaware limited liability company. It holds the copyright in `pineforge-codegen`; the founder's rights in the software are assigned to it. Commercial licenses are granted by pineforge, LLC. + ## What this repository is A pure-Python PineScript v6 → C++ transpiler that emits source against the public PineForge engine C-ABI. It implements PineScript v6 from **TradingView's publicly published language documentation**; it does **not** incorporate TradingView proprietary source. Names like "PineScript v6" are used **nominatively** to describe the input language. @@ -25,7 +33,7 @@ The transpiler has **no runtime dependencies** (`transpile()` and `transpile_ful ## Contributions -Contributions are accepted under a Developer Certificate of Origin (`Signed-off-by`). Because this project is **dual-licensed** (source-available + a sold commercial license), material contributions require a Contributor License Agreement granting PineForge the right to include the contribution in the commercial license; otherwise it cannot be accepted. See [CONTRIBUTING.md](CONTRIBUTING.md) (or contact luis@4pass.com.tw) before opening a material PR. +Contributions are accepted under a Developer Certificate of Origin (`Signed-off-by`). Because this project is **dual-licensed** (source-available + a sold commercial license), material contributions require a Contributor License Agreement granting pineforge, LLC the right to include the contribution in its commercial licenses; otherwise it cannot be accepted. See [CONTRIBUTING.md](CONTRIBUTING.md) (or contact luis@4pass.com.tw) before opening a material PR. ## No warranty diff --git a/LICENSE b/LICENSE index a1418cc..28efad9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,197 +1,240 @@ -PineForge Codegen — License +PineForge Source License 1.0 ============================ -Copyright 2025 PineForge +Copyright 2025-2026 pineforge, LLC -This software is made available under the **PolyForm Noncommercial License -1.0.0** (reproduced in full below), as modified by the two supplemental -sections that follow. In case of any conflict, the supplemental sections -("Additional Permission" and "Commercial Use") control over the base license. +Required Notice: Copyright 2025-2026 pineforge, LLC (https://github.com/pineforge-4pass/pineforge-codegen-oss) -Required Notice: Copyright 2025 PineForge (https://github.com/pineforge-4pass/pineforge-codegen-oss) +The software is free of charge for the permitted purposes below, including +Personal Trading. Commercial Use, defined below, needs a separate commercial +license from the licensor. -Additional Permission — Personal Trading ----------------------------------------- +## Acceptance -Notwithstanding the limitation to noncommercial purposes in the base license, -the licensor grants you, free of charge, an additional license to use the -software for **Personal Trading**, and Personal Trading is hereby a permitted -purpose under the base license — including its Copyright License, Distribution -License, Changes and New Works License, and Patent License. +In order to get any license under these terms, you must agree to them as both +strict obligations and conditions to all your licenses. -**Personal Trading** means use of the software by a natural person to research, -develop, backtest, and execute trades in financial instruments, where: - (a) the trades are placed for that same natural person's own account; and +## Copyright License - (b) the trades are funded solely by that person's own capital. +The licensor grants you a copyright license for the software to do everything +you might do with the software that would otherwise infringe the licensor's +copyright in it for any permitted purpose. However, you may only distribute +the software according to the Distribution License section, and make changes +or new works based on the software according to the Changes and New Works +License section. -Personal Trading does **not** include, and this Additional Permission does -**not** cover: - (1) managing, advising on, or trading capital belonging to any other person - or entity, whether or not for a fee; +## Distribution License - (2) use by, for, or on behalf of any company, fund, partnership, or other - organization, including use by an individual in the course of work for - such an organization; +The licensor grants you an additional copyright license to distribute copies +of the software. Your license to distribute covers distributing the software +with changes and new works permitted by the Changes and New Works License +section. Distributing copies under this section is not Commercial Use, and it +gives the people who get them no license beyond these terms. - (3) embedding the software, or output generated by it, into any product or - service made available to others; or - (4) operating any hosted, software-as-a-service, or otherwise public-facing - service that uses the software. +## Notices -The use described in (1)–(4) is Commercial Use. +You must ensure that anyone who gets a copy of any part of the software from +you also gets a copy of these terms or a link to them, as well as copies of +any plain-text lines beginning with `Required Notice:` that the licensor +provided with the software. For example: +> Required Notice: Copyright Yoyodyne, Inc. (http://example.com) -Commercial Use --------------- -Any use that is not a permitted purpose under the base license and is not -covered by the Additional Permission above — including the uses listed in -(1)–(4) of that section — requires a separate commercial license from the -licensor. +## Changes and New Works License -To obtain a commercial license, contact: luis@4pass.com.tw +The licensor grants you an additional copyright license to make changes and +new works based on the software for any permitted purpose. -================================================================================ -The remainder of this file is the verbatim text of the PolyForm Noncommercial -License 1.0.0. Where it differs from the supplemental sections above, the -supplemental sections control. -================================================================================ +## Patent License +The licensor grants you a patent license for the software that covers patent +claims the licensor can license, or becomes able to license, that you would +infringe by using the software for a permitted purpose. -# PolyForm Noncommercial License 1.0.0 - +## Permitted Purposes -## Acceptance +Each of the following is a permitted purpose: -In order to get any license under these terms, you must agree -to them as both strict obligations and conditions to all -your licenses. +- **Noncommercial purposes.** Any noncommercial purpose. -## Copyright License +- **Personal uses.** Personal use for research, experiment, and testing for + the benefit of public knowledge, personal study, private entertainment, + hobby projects, amateur pursuits, or religious observance, without any + anticipated commercial application. -The licensor grants you a copyright license for the -software to do everything you might do with the software -that would otherwise infringe the licensor's copyright -in it for any permitted purpose. However, you may -only distribute the software according to [Distribution -License](#distribution-license) and make changes or new works -based on the software according to [Changes and New Works -License](#changes-and-new-works-license). +- **Noncommercial organizations.** Use by any charitable organization, + educational institution, public research organization, public safety or + health organization, environmental protection organization, or government + institution for its teaching, research and other operations, regardless of + the source of funding or obligations resulting from the funding. -## Distribution License +- **Personal Trading**, as defined in the next section. -The licensor grants you an additional copyright license -to distribute copies of the software. Your license -to distribute covers distributing the software with -changes and new works permitted by [Changes and New Works -License](#changes-and-new-works-license). +Investment Management, defined in the Commercial Use section, is never a +permitted purpose, except as Personal Trading. That is so even when it is done +by a noncommercial organization or for a noncommercial purpose. -## Notices -You must ensure that anyone who gets a copy of any part of -the software from you also gets a copy of these terms or the -URL for them above, as well as copies of any plain-text lines -beginning with `Required Notice:` that the licensor provided -with the software. For example: +## Personal Trading -> Required Notice: Copyright Yoyodyne, Inc. (http://example.com) +**Personal Trading** means use of the software by a natural person to do any +of the following, solely for trades that meet conditions (a) and (b) below: +research, develop or backtest trading strategies, or execute trades in +securities, derivatives, currencies, crypto-assets, commodities or other +financial instruments. -## Changes and New Works License + (a) The trades are, or will be, placed for that person's own account. -The licensor grants you an additional copyright license to -make changes and new works based on the software for any -permitted purpose. + (b) The trades are, or will be, funded solely by that person's own + capital. -## Patent License +For Personal Trading: + + - A person's **household** is that person, their spouse or domestic + partner, and their dependants. + + - A person's **own account** includes an account held by the person alone + or jointly with members of their household; an account of a member of + their household; and a retirement, pension, education-savings or other + tax-advantaged account, or an account of a revocable trust, held for the + benefit of the person or members of their household. + + - A person's **own capital** includes capital belonging to members of + their household, and capital borrowed in the ordinary course from a + broker, bank or other lender, such as margin, leverage or credit on a + trading account, for which the person or their household is liable. + Money the person has received outright, such as pay, a gift or an + inheritance, is the person's own capital. -The licensor grants you a patent license for the software that -covers patent claims the licensor can license, or becomes able -to license, that you would infringe by using the software. + - Trading in the person's own name, for their own account and with their + own capital, is Personal Trading even when it is the person's business + or livelihood. -## Noncommercial Purposes + - Publishing or teaching about the person's own Personal Trading, + including its results, is part of Personal Trading even when the person + is paid for it, as long as they do not give Output to others. -Any noncommercial purpose is a permitted purpose. + - An account of a company, partnership, fund, trust or other + organization, other than an account described under own account above, + is not the person's own account, even if the person wholly owns or + controls it. -## Personal Uses + - Capital that an employer, a proprietary-trading firm, a funded-trader + program or anyone else outside the person's household provides or + allocates to the person to trade, and that the provider still owns or + whose losses the provider bears, is not the person's own capital, even + if the person shares in the profits. -Personal use for research, experiment, and testing for -the benefit of public knowledge, personal study, private -entertainment, hobby projects, amateur pursuits, or religious -observance, without any anticipated commercial application, -is use for a permitted purpose. -## Noncommercial Organizations +## Commercial Use + +**Investment Management** means using the software to manage, advise on, or +trade investment capital; to research, develop or backtest strategies for +investment capital that you, or anyone you do the work for, manage, advise on +or trade; or to operate the software for others who do any of these things; +in each case whoever the capital belongs to and whether or not for a fee. + +**Investment capital** means any money or other assets held for investment or +trading, including capital belonging to any other person or entity, such as a +friend or relative, clients or investors, an endowment, a pension or +retirement fund, a sovereign or other public fund, or the treasury or reserves +of a foundation or other organization. + +**Commercial Use** means any use of the software that is not a permitted +purpose, other than distributing copies under the Distribution License +section. Investment Management is Commercial Use for every individual and +every organization, including the noncommercial organizations listed under +Permitted Purposes, whatever its purpose, unless it is Personal Trading. +Unless it is a permitted purpose, each of the following is also Commercial +Use: + + (1) managing, advising on, or trading capital belonging to any other person + or entity, whether or not for a fee; + + (2) use by, for, or on behalf of any company, fund, partnership, or other + organization, including use by an individual in the course of work for + such an organization; + + (3) embedding the software, or its Output, into any product or service + made available to others, including using the software to generate + Output for such a product or service; and + + (4) operating any hosted, software-as-a-service, or otherwise public-facing + service through which others can run the software or receive its + Output. + +Commercial Use requires a separate commercial license from the licensor. To +obtain one, contact: enterprise@pineforge.dev + + +## Output + +**Output** means code that the software generates, such as the C++ source +code it generates from PineScript, and any program or library built from that +code. Backtest results, charts, reports and trade signals are not Output. -Use by any charitable organization, educational institution, -public research organization, public safety or health -organization, environmental protection organization, -or government institution is use for a permitted purpose -regardless of the source of funding or obligations resulting -from the funding. ## Fair Use -You may have "fair use" rights for the software under the -law. These terms do not limit them. +You may have "fair use" rights for the software under the law. These terms do +not limit them. + ## No Other Rights -These terms do not allow you to sublicense or transfer any of -your licenses to anyone else, or prevent the licensor from -granting licenses to anyone else. These terms do not imply -any other licenses. +These terms do not allow you to sublicense or transfer any of your licenses +to anyone else, or prevent the licensor from granting licenses to anyone +else. These terms do not imply any other licenses. + ## Patent Defense -If you make any written claim that the software infringes or -contributes to infringement of any patent, your patent license -for the software granted under these terms ends immediately. If -your company makes such a claim, your patent license ends -immediately for work on behalf of your company. +If you make any written claim that the software infringes or contributes to +infringement of any patent, your patent license for the software granted +under these terms ends immediately. If your company makes such a claim, your +patent license ends immediately for work on behalf of your company. + ## Violations -The first time you are notified in writing that you have -violated any of these terms, or done anything with the software -not covered by your licenses, your licenses can nonetheless -continue if you come into full compliance with these terms, -and take practical steps to correct past violations, within -32 days of receiving notice. Otherwise, all your licenses -end immediately. +The first time you are notified in writing that you have violated any of +these terms, or done anything with the software not covered by your licenses, +your licenses can nonetheless continue if you come into full compliance with +these terms, and take practical steps to correct past violations, within 32 +days of receiving notice. Otherwise, all your licenses end immediately. + ## No Liability -***As far as the law allows, the software comes as is, without -any warranty or condition, and the licensor will not be liable -to you for any damages arising out of these terms or the use -or nature of the software, under any kind of legal claim.*** +***As far as the law allows, the software comes as is, without any warranty +or condition, and the licensor will not be liable to you for any damages +arising out of these terms or the use or nature of the software, under any +kind of legal claim.*** + ## Definitions -The **licensor** is the individual or entity offering these -terms, and the **software** is the software the licensor makes -available under these terms. +The **licensor** is pineforge, LLC, and the **software** is the software the +licensor makes available under these terms. -**You** refers to the individual or entity agreeing to these -terms. +**You** refers to the individual or entity agreeing to these terms. -**Your company** is any legal entity, sole proprietorship, -or other kind of organization that you work for, plus all -organizations that have control over, are under the control of, -or are under common control with that organization. **Control** -means ownership of substantially all the assets of an entity, -or the power to direct its management and policies by vote, -contract, or otherwise. Control can be direct or indirect. +**Your company** is any legal entity, sole proprietorship, or other kind of +organization that you work for, plus all organizations that have control +over, are under the control of, or are under common control with that +organization. **Control** means ownership of substantially all the assets of +an entity, or the power to direct its management and policies by vote, +contract, or otherwise. Control can be direct or indirect. -**Your licenses** are all the licenses granted to you for the -software under these terms. +**Your licenses** are all the licenses granted to you for the software under +these terms. -**Use** means anything you do with the software requiring one -of your licenses. +**Use** means anything you do with the software requiring one of your +licenses. diff --git a/README.md b/README.md index 253ecdd..cab5924 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![PyPI](https://img.shields.io/pypi/v/pineforge-codegen.svg)](https://pypi.org/project/pineforge-codegen/) [![Python](https://img.shields.io/pypi/pyversions/pineforge-codegen.svg)](https://pypi.org/project/pineforge-codegen/) -[![License](https://img.shields.io/badge/license-PolyForm%20Noncommercial%201.0.0-orange.svg)](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/LICENSE) +[![License](https://img.shields.io/badge/license-PineForge%20Source%201.0-orange.svg)](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/LICENSE) [![Personal use](https://img.shields.io/badge/personal%20trading-free-22c55e.svg)](#license) A pure-Python library that turns a PineScript v6 strategy into a complete C++ @@ -531,28 +531,46 @@ use `python -m pytest --collect-only -q` for the current collection count. ## License -Source-available under the [PolyForm Noncommercial License 1.0.0](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/LICENSE), -with two supplemental sections (the `LICENSE` file is the controlling text; -where they conflict with the base license, the supplemental sections control): - -- **Additional Permission — Personal Trading** — a natural person may use the - software free of charge to research, develop, backtest and execute trades - for their own account, funded solely by their own capital. -- **Commercial Use** — managing, advising on or trading anyone else's capital; - use by, for or on behalf of a company, fund, partnership or other - organization (including an individual's work for one); embedding the - software or its output in a product or service made available to others; and - operating a hosted, software-as-a-service or other public-facing service - that uses the software all require a separate commercial license. - So does any other use that is neither a permitted purpose under the base - license nor covered by the Personal Trading permission. +Source-available under the [PineForge Source License 1.0](https://github.com/pineforge-4pass/pineforge-codegen-oss/blob/main/LICENSE); +the `LICENSE` file is the controlling text. The licensor is pineforge, LLC. + +- **Free for noncommercial use:** any noncommercial purpose, and use by a + charitable organization, educational institution, public research + organization, public safety or health organization, environmental + protection organization or government institution for its teaching, + research and other operations. +- **Free for Personal Trading:** a natural person may research, develop or + backtest strategies and execute trades for their own account with their + own capital. Their own account includes joint and household accounts + (spouse or domestic partner, dependants), retirement and other + tax-advantaged accounts and a revocable trust for their benefit; their own + capital includes margin and other ordinary borrowing from a broker or + lender. A company's or fund's account is not a personal account, even if + the person wholly owns the company. +- **Investment management is never free**, except Personal Trading: + managing, advising on or trading investment capital, or researching + strategies for it, whether the capital is a friend's, clients' or + investors', an endowment, a pension fund, a public fund or a foundation's + treasury, is Commercial Use for every individual and every organization, + noncommercial organizations included. +- **Commercial Use needs a commercial license:** besides investment + management, any other use that is not free, such as use by, for or on + behalf of a company, fund, partnership or other organization (including an + individual's work for one); embedding the software or its output in a + product or service made available to others; or operating a hosted, + software-as-a-service or other public-facing service through which others + run the software or receive its output. This is source-available, not OSI open source. ### Buying a commercial license -Commercial licenses are available — flexible terms for funds, products, and -hosted/embedded use. Email **luis@4pass.com.tw** with your use case for a quote. +Commercial licenses are annual: Solo for one person, Team for an +organization's own use, Fund for managers of others' capital and for +institutional investment capital such as endowments and pension or public +funds (by assets under management), and OEM / Embedded for products and +hosted services. Email **enterprise@pineforge.dev** with questions or for a +quote. The commercial-license store (coming soon) will take orders online. ## Explicit Pine execution attachment diff --git a/npm/package.json b/npm/package.json index 257f707..243342a 100644 --- a/npm/package.json +++ b/npm/package.json @@ -17,7 +17,8 @@ "tables.json", "release.json", "transpile.worker.mjs", - "glue.py" + "glue.py", + "LICENSE" ], "engines": { "node": ">=20" @@ -31,5 +32,5 @@ "type": "git", "url": "git+https://github.com/pineforge-4pass/pineforge-codegen-oss.git" }, - "license": "PolyForm-Noncommercial-1.0.0" + "license": "SEE LICENSE IN LICENSE" } diff --git a/pyproject.toml b/pyproject.toml index dbf08c0..4f0398f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -13,14 +13,14 @@ requires-python = ">=3.11" authors = [ { name = "PineForge", email = "luis@4pass.com.tw" }, ] -# PolyForm Noncommercial 1.0.0 + Personal Trading exception; see LICENSE. +# PineForge Source License 1.0 (source-available); see LICENSE. license = { file = "LICENSE" } readme = "README.md" keywords = ["pinescript", "transpiler", "trading", "backtesting", "tradingview"] classifiers = [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Financial and Insurance Industry", - "License :: Free for non-commercial use", + "License :: Other/Proprietary License", "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", diff --git a/scripts/build-npm-package.mjs b/scripts/build-npm-package.mjs index f2e6d12..c7ea205 100644 --- a/scripts/build-npm-package.mjs +++ b/scripts/build-npm-package.mjs @@ -31,15 +31,17 @@ const release = JSON.parse(readFileSync(RELEASE, "utf8")); if (release.codegen !== VERSION) fail(`release.json codegen ${release.codegen} != VERSION ${VERSION}`); // 1. Clean payload (keep tracked manifest + index). -for (const p of ["pineforge_codegen", "tables.json", "release.json", "glue.py", "transpile.worker.mjs"]) { +for (const p of ["pineforge_codegen", "tables.json", "release.json", "glue.py", "transpile.worker.mjs", "LICENSE"]) { rmSync(join(NPM, p), { recursive: true, force: true }); } const versionedArchive = `pineforge_codegen-${VERSION}.tar.gz`; rmSync(join(NPM, versionedArchive), { force: true }); -// 2. Validated archive (versioned filename) + release.json. +// 2. Validated archive (versioned filename) + release.json, and the LICENSE that +// package.json names ("SEE LICENSE IN LICENSE"). cpSync(SCRATCH_ARCHIVE, join(NPM, versionedArchive)); cpSync(RELEASE, join(NPM, "release.json")); +cpSync(join(ROOT, "LICENSE"), join(NPM, "LICENSE")); // 3. Unpacked source tree — extracted FROM the gate-validated archive (single // source of truth). Never re-copy the working tree: it could have drifted