Change: relicense the Engine to plain Apache-2.0 - #898
Merged
Conversation
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ause, #635) Replace the Apache-2.0 + Commons Clause template license with plain Apache-2.0. The Commons Clause protected a resale scenario the sole maintainer would never enforce and deterred adoption (source-available, not OSI-approved). Supersedes #635, which asked to strengthen the clause with an .engine/-scoped NOTICE. The recognizer's single source of truth (license_seeds.CURRENT_SEED) appends a plain-Apache seed whose Apache body is derived verbatim from the retired seed (byte-parity, no retyping). The retired Commons Clause seed stays in HISTORICAL_SEEDS so any repo templated before this relicense is still recognized by the standing detector. The sole delete-safety anchor is now a copyright-form holder line: copyright-form so GitHub's Licensee strips it and detects a named Apache-2.0, while recognize() matches the raw text and preserves any adopter's own Apache license. The preserve-on-doubt tests are re-anchored on the holder line (not inverted), with a red tripwire against stripping it. The first-run clear and boot detector are unchanged (they alias the seed). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
review) Post-deliverable-review cleanup: comments/docstrings/a test name in instantiator.py and test_instantiator.py still said 'Licensor' beside the new 'holder' vocabulary the relicense introduced. Comment/name-only; no behavior change. Graph fingerprints regenerated. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #635
Purpose
Relicense the Engine from Apache-2.0 + Commons Clause to plain Apache-2.0 — drop the Commons Clause.
.engine/-scopedNOTICEso the restriction would bind adopters. Working Engine fault: the Commons Clause may not bind an adopter without an .engine/-scoped NOTICE #635 surfaced the deeper call: an unenforced restriction that lowers adoption is pure cost, so the honest move is to drop it, not fortify it.Impact: the Engine now presents as a trusted, permissive Apache-2.0 project — GitHub shows a named "Apache-2.0" — with no restriction the maintainer never intended to defend.
Scope
A plain-Apache-2.0 seed appended to the license recognizer, the root
LICENSEand README reconciled to match, and the tests re-anchored..engine/tools/license_seeds.py: the current shipped seed is now plain Apache-2.0. It is derived from the retired seed's own Apache body (split at the 75-dash rule) so the license text is byte-identical to what shipped before — no retyping — with the Commons Clause header replaced by a single copyright-form holder line,Copyright 2026 StarshipSuperjam - The Engine (engine-template). The seed set is appended, not replaced:HISTORICAL_SEEDS = (retired Apache+Commons-Clause seed, new plain-Apache seed), so any repo generated from the template before this merge still recognizes its lingering Commons ClauseLICENSE.LICENSE: rewritten, byte-identical to the newCURRENT_SEED(bound by the parity test); Commons Clause header gone; aCopyright 2026 StarshipSuperjamholder line retained.README.md: the license badge and License section flip from "Source-available (Apache-2.0 + Commons Clause) … not OSI-approved … no right to Sell" to permissive Apache-2.0..engine/tools/instantiator.py: comments only — it aliases the seed/recognizer, no logic change.Change profile — the shape of this pull request at a glance:
Impact: the recognizer, the root LICENSE, and the operator-facing copy all move together and stay in sync.
Behaviors
The Engine presents as permissive Apache-2.0, and the first-run clear still deletes only the Engine's own license, never an adopter's.
gh api …/license→spdx_id: Apache-2.0).test_current_seed_is_plain_apache_without_commons_clause,test_matches_every_historical_seed.test_stock_apache_without_the_holder_line_is_preserved(the red tripwire) andtest_the_apache_body_without_the_holder_line_is_not_matched; a different/renamed holder is preserved —test_stock_apache_with_a_different_holder_is_preserved,test_a_renamed_holder_is_preserved_never_deleted.test_carries_two_members_after_the_apache_relicense; the rootLICENSEstays byte-identical to the seed —TestRepoLicenseIsTheTemplateSeed.Out of scope
The design-record corpus edit, a README-content test guard, and the copyright-line phrasing.
Copyright 2026 StarshipSuperjam - The Engine (engine-template)) — deliberate: it is the machine-readable delete-safety anchor, and it is copyright-form so GitHub's Licensee strips it before detecting Apache-2.0.Impact: these are bounded, disclosed choices — the smallest change that fully delivers the outcome — not gaps.
Risk
This narrows the delete-safety discriminator, and the automated guardrail can't see it — so the disclosure is manual; the relicense itself is forward-only and legally clean.
instantiator._seed_license) deletes a rootLICENSEthat the recognizer matches, and the boot detector offers to remove one. Dropping the Commons Clause narrows the sole discriminator between "the Engine's own traveled license" and "an adopter's own Apache-2.0" from the entire distinctive Commons Clause block down to the one holder line. This was adversarially tested: three independent reviews ran the recognizer against real adopter-shaped Apache licenses (stock GitHub-picker output, filled appendix, renamed holder, year-bumped, case-folded, whitespace variants) and none matched — preserve-on-doubt is intact (an adopter's own Apache differs in two independent places: no holder line and an unfilled appendix placeholder). The engine's guardrail-weakening check does not and cannot flag this class of change — it watches a check's wrapper script, not the imported library where this logic lives (the known blind spot, engine-template#895) — so noguardrail-ackfired. Do not read "no ack" as "nothing changed here": this is a real narrowing of a deletion mechanism, disclosed manually and reviewed on its merits..engine/NOTICE hedge moot (no restriction remains to bind), and shifts D-302's recognizer anchor from the Commons Clause licensor field to the holder line (a shape D-302's design already supported). Engine fault: the Commons Clause may not bind an adopter without an .engine/-scoped NOTICE #635 is superseded — closed in the direction opposite to what it originally asked. The design-corpus update is tracked as engine-mechanic Engine health: A concern raised while working wasn't given a disposition before the turn ended, so the engine logged it he... #54.Impact: the consequences are bounded, adversarially checked, and disclosed rather than silently shipped.
Validation
Full self-test and CI check-suite green on the final tree; recognizer safety independently re-verified by review; GitHub detection confirmed live.
selftest.pyPASSED (~5,000+ tests, 275s) on the reviewed tree;validate.py --suite CIpassed with no hard findings; the license/instantiator/health suites are green (18 / 271 / 14). The knowledge-graph fingerprint check passes on the regeneratedgraph.json.LICENSEas Apache-2.0 — verified viagh api repos/StarshipSuperjam/engine-template/license?ref=<branch>→spdx_id: Apache-2.0. The README's "named Apache-2.0" claim is confirmed, not assumed.LICENSEis byte-identical tolicense_seeds.CURRENT_SEED.main(no rebase needed); the knowledge graph was regenerated from the final tree and matched a true regeneration; the self-map was unaffected. No work lost, no hand-merge.Impact: an approver can rely on the behaviours above being exercised by committed tests, a live GitHub detection check, and a green full suite on the exact bytes proposed for merge.
Review
Reviewed to full (thorough) depth both before and after building; two gates, nine independent cold-context lenses, zero blocking findings.
8fa15a7and submittedb4d053c, 8 lines were added and 8 deleted or modified, a net change of +0 lines across 3 files — a trivial cosmetic delta, so no re-audit was warranted; the scoped tests and CI suite were re-run green on the final tree.Offered checks you can run: view the repository's license on GitHub (it now reads Apache-2.0); read the new root LICENSE; or run the recognizer tests —
uv run --directory .engine -- python -m unittest discover -s tools -p 'test_license_seeds.py'— the tripwire test proves a stock adopter Apache-2.0 is preserved.Impact: two review gates and an adversarial recognizer probe found no blocking issue; your merge is the binding gate.
Files of interest
The recognizer seed and the license artifact carry the whole change.
.engine/tools/license_seeds.py— the plain-Apache seed (derived byte-exact), the appended two-member set, and the docstring that marks the holder line as the load-bearing delete-safety anchor.LICENSE— the new plain Apache-2.0 (byte-identical to the seed).README.md— the license badge + section, now permissive Apache-2.0..engine/tools/test_license_seeds.py/test_instantiator.py— the re-anchored preserve-on-doubt tripwires.Impact: these determine whether the license is honest and whether the first-run clear can only ever delete the Engine's own license.
AI involvement
Claude Code (Opus 4.8) drove the design and implementation; the operator, as licensor, made the load-bearing call; cold-context AI reviews stress-tested the safety.
Impact: AI judgment is load-bearing on the seed design and the safety argument; the operator decided the relicense and its target, and the merge is theirs.