---
name: open_source_release_packaging
description: Take a private repo public cleanly. Run it when a codebase is about to be open sourced, published to GitHub, or cut as its first public release.
---

# Open Source Release Packaging

## Purpose
Take a repo from private to public without shipping secrets, licensing landmines, or docs that only make sense to insiders. It covers the full release discipline, not just a secret scan: license choice, history sanitization, setup docs strangers can actually follow, and the packaging steps that make the first release install cleanly.

## Workflow
1. **Inventory the repo.** Know what you are publishing: the language, the build system, what the code does, who it depends on. If parts of the repo (internal configs, vendor code, private assets) must not go public, split them out or plan their removal before anything else.
2. **Audit first.** Run `python3 bin/osr-audit.py /path/to/repo`. Treat every FAIL as a hard blocker. WARN items ship only if you can defend them in the release notes.
3. **Choose the license.** Read `references/license-decision.md` and pick with intent, not habit. Then put the real license text in `LICENSE` at the repo root and set the SPDX identifier in packaging metadata (pyproject.toml, package.json). Check every dependency for license conflicts: copyleft code inside a permissively licensed package is a real problem, and trademarks, fonts, datasets, and model weights each need their own review.
4. **Sanitize secrets and PII.** Anything the audit flagged gets rotated at the provider FIRST, then scrubbed from git history with `git filter-repo` (`--path <file> --invert-paths` for whole files, `--replace-text replacements.txt` for strings). History rewrites change every commit hash, so work on a fresh clone and verify before force pushing. Do not rely on deleting files in a new commit: old commits stay reachable by SHA until the host garbage collects them.
5. **Lock the gates going forward.** Add `.gitignore` entries for `.env`, key material, and build output before the first public commit. Enable the host's secret scanning and push protection (GitHub: secret scanning plus push protection). A pinned-version gitleaks or trufflehog run in CI keeps the repo clean after release day.
6. **Write docs for strangers.** README with a one-line description, install steps, and a working quickstart. CONTRIBUTING.md with how you take PRs. SECURITY.md with how to report vulnerabilities. Then verify: clone fresh into a clean machine or container, follow your own README, and confirm it works. If you cannot make it work from the docs, neither can anyone else.
7. **Package the release.** Python: complete pyproject.toml metadata (name, version, license, classifiers), build the wheel (python -m build), run `twine check`, and do a TestPyPI dry run. npm: license field set, `npm pack` and inspect the tarball for strays. Cut a version tag, write real release notes (what changed, what breaks, what to try first), and publish the release on the host.
8. **Re-audit and ship.** Run the audit one more time at the exact release commit. Zero FAILs, or it does not go out.

## Output Contract
- A go/no-go verdict for the public release, with every FAIL named and fixed
- A chosen license with the SPDX identifier, license text in the repo, and metadata fields set
- A sanitization record: what was rotated, what was rewritten in history, and what was verified clean
- README, CONTRIBUTING, SECURITY confirmed working via a fresh-clone test
- A versioned, installable first release (tag, release notes, published package)

## Operating Rules
1. Rotate before you scrub. A secret removed from history but still valid at the provider is still a live credential in the wild.
2. License conflicts block the release. Never ship a package whose dependencies contradict its license terms.
3. Never rely on a delete commit to hide something. Purge it from history or accept that it is public.
4. The audit runs at the exact release commit, not an earlier one. Last-minute changes can reintroduce problems.
5. Keep internal decisions, signing details, and private evidence out of the public repo entirely.
