feat: publish the enterprise layer under Apache-2.0 - #261
Merged
Conversation
NexusPuppet is now fully open source. Directory authentication (LDAP and Active Directory), single sign-on (OIDC) and audit forwarding move from the private repository into this one. There is no paid tier and no feature held back. Relicensed. The package carried its own "Proprietary and Confidential" LICENSE and declared "license": "UNLICENSED". Both are gone: the root Apache-2.0 LICENSE governs the whole repository, and the package README and description no longer claim otherwise. Publishing code labelled proprietary would have been worse than not publishing it. Retired scripts/enterprise.mjs, the enterprise:fetch script, and the NEXUSPUPPET_ENTERPRISE_REPO / _REF variables. They could not survive the code being in-repo: with packages/enterprise tracked, the script's existsSync() branch would run `git -C packages/enterprise fetch`, and with no nested .git that walks up and operates on THIS repository. Now a real workspace member. ldapts moves from an optional peer dependency to an ordinary one, the package's private lockfile is deleted, and the root lockfile covers it. A fresh clone builds with a single `npm install`, which is the point of publishing it. This also ends the split instruction where a deployment host and a dev checkout needed different install commands. Now linted. The package was in ESLint's global ignore list because it was foreign code. One real finding: a bare `transport.configured;` where the read IS the point, since the getter starts a lazy refresh as a side effect. Now `void transport.configured;`, which says so. CI's "Assert the enterprise layer is absent" step is replaced. The checks that still matter are kept: no static import outside enterprise.loader.ts, no committed certificate material, no private key blocks. ADR-0002 is amended, not superseded. Core still does not import the package -- it depends on interfaces in @nexuspuppet/contracts and the layer registers implementations at runtime. That seam is now an internal boundary rather than a commercial one, and whether it still earns its keep is left open. Verified: build, typecheck, lint and prettier clean; 879 api tests and 248 enterprise tests pass. Scanned the working tree and all 25 commits of the private repo's history for secrets and personal data before publishing: no keys, no tokens, no real infrastructure, no personal addresses, and every email a reserved test domain. Claude-Session: https://claude.ai/code/session_01HzdMh5WSqgEA1frZYNAtPf
Merged
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.
What
NexusPuppet is now fully open source. Directory authentication (LDAP and Active Directory), single sign-on (OIDC) and audit forwarding move from the private repository into this one — 44 files, ~3,900 lines. No paid tier, no feature held back.
Relicensed — the thing worth reviewing first
The package carried its own LICENSE reading "Proprietary and Confidential — NOT covered by the Apache License 2.0", with
"license": "UNLICENSED"and a README saying the same.Publishing the source while it was labelled proprietary would have been worse than not publishing it: legally contradictory, and it would deter exactly the contributors this is meant to attract. That LICENSE is gone (the root Apache-2.0 governs the repository),
licenseis nowApache-2.0, and the README and package description no longer claim otherwise.Retired the fetch mechanism
scripts/enterprise.mjs, theenterprise:fetchscript, andNEXUSPUPPET_ENTERPRISE_REPO/_REFare deleted. They could not survive the code being in-repo: withpackages/enterprisetracked, the script'sexistsSync()branch would rungit -C packages/enterprise fetch, and with no nested.gitthat walks up and operates on this repository.Now a real workspace member
ldaptsmoves from an optional peer dependency to an ordinary one, the package's private lockfile is deleted, and the root lockfile covers it. A fresh clone builds with a singlenpm install— which is the point of publishing it. This also ends the split instruction where a deployment host and a dev checkout needed different install commands.Now linted
The package sat in ESLint's global ignore list because it was foreign code. One real finding: a bare
transport.configured;insettings-transport.spec.ts, where the read is the point — the getter starts a lazy refresh as a side effect. Nowvoid transport.configured;, which says so.CI
Assert the enterprise layer is absentwould have failed outright. Replaced withAssert the runtime seam and no committed secrets, keeping the checks that still matter: no static import outsideenterprise.loader.ts, no committed certificate material, no private key blocks.ADR-0002 amended, not superseded
Core still does not import the package — it depends on interfaces in
@nexuspuppet/contracts, and the layer registers implementations at runtime. That seam is now an internal boundary that keeps these integrations independently testable, rather than a commercial one. Whether it still earns its keep with nothing private behind it is deliberately left open, for Stage 3.Pre-publication scan
Working tree and all 25 commits of the private repo's history were scanned before anything was pushed:
corp.local,DC01or bind accountsexample.com,.test,nexuspuppet.test)alice-password,test-admin-password)Verified
build · typecheck · lint · prettier all exit 0 · 879 api tests · 248 enterprise tests
🤖 Generated with Claude Code
https://claude.ai/code/session_01HzdMh5WSqgEA1frZYNAtPf