# Release Checklist

Use this checklist before every npm release.

## 1. Scope

- Confirm the release version and dist-tag.
- Confirm whether the release is an initial prerelease `staging` publish, a
  separately approved `next` promotion, or a separately approved `latest`
  Stable/GA release.
- Confirm the supported product surface.
- Confirm unsupported surfaces are still documented.
- Confirm no generated evidence, experiments, or local fixtures are included in package contents.

## 2. Metadata

- `package.json` version is correct.
- `package-lock.json` root package version is aligned.
- release tag matches `v${package.json.version}`.
- `package.json` license is correct.
- Root `LICENSE` file exists.
- `README.md` describes the install flow for the target dist-tag.
- Language README links work.
- `CHANGELOG.md` has an entry for the release.
- Release notes are drafted from `docs/current/release/release-notes-template.md`.

## 3. Docs Stale Guard

Run this guard before release prep and again before publish if any smoke, runtime, CLI, or develop-doc update lands after the release-prep commit.

Check:

- `package.json`, `package-lock.json`, `CHANGELOG.md`, the current release note, and the develop README/current-status record all name the same intended release version.
- The current release note and CHANGELOG name the package/source type for every cited smoke result: registry package, local tarball, current tarball, or workspace install.
- Current-tarball or workspace smoke is never described as published registry behavior. Registry behavior may be claimed only after the protected-main and immutable-tag preflight, `npm view persona-harness@<version> version dist.shasum dist.integrity --json`, `npm dist-tag ls persona-harness`, and a downloaded-tarball SHA-256/package-content-identity comparison confirm the published package and dist-tag state.
- `CHANGELOG.md` and the release note both distinguish surface-verified smoke from full generated-app behavior verification.
- The release note explicitly says generated app product quality is not certified unless there is a separate, explicit product-quality certification decision.
- Registry state is recorded when relevant:
  - protected workflow source head and immutable matching tag checked before canonical packing;
  - npm dist-tag/version, SHA-1, and SRI checked;
  - downloaded registry tarball raw SHA-256 and package-content identity checked against the frozen canonical facts;
  - any registry-byte or channel mismatch recorded with whether smoke used the registry package, local tarball, or workspace install.
- Develop docs are checked for stale or missing smoke summaries when release notes cite those smoke results.
- If `/Users/yongtae/Documents/하네스/Persona-Harness/develop` is not a git worktree, the release report records that develop-doc changes have no commit.
- If develop docs are a git worktree, the release report records the commit hash or the explicit no-commit reason.

Do not proceed from this guard to publish, push, or tag. It is a documentation freshness gate only.

## 4. Package Contents

Run:

```bash
npm pack --dry-run --json
```

Check:

- `dist` is included.
- `README.md` and language README files are included.
- `LICENSE` is included.
- `.persona/harness.jsonc` is included.
- `.persona/rules` is included.
- Java MVP shared-skill reference subset is included.
- inactive shared-skills are excluded.
- Java no-excuse fixtures are excluded.
- `experiments/`, `.persona/evidence/`, `.persona-test-fixtures/`, and `.omo/` are excluded.

## 5. Verification

Run:

```bash
npm test
npm run typecheck
npm run build
npm run report:rules
npm run check:scope:strict
npm run check:injection-value
npm publish --dry-run --tag <dist-tag>
```

## 6. Publish / Tag Order

Use this order for prerelease refreshes:

1. Push the protected release-preparation commit to `main` and create the
   separately approved immutable matching `v${package.json.version}` tag.
2. Publish through `.github/workflows/publish.yml` with
   `dist_tag=staging` and `approval_scope=staging-only` after QA release GO.
3. Verify the registry package with `npm view persona-harness@<version> version dist.shasum dist.integrity --json` and a downloaded tarball SHA-256/package-content-identity comparison against the frozen canonical facts.
4. Verify dist-tags with `npm dist-tag ls persona-harness`.
5. Complete the staged installed-package gate before any separately approved
   `next` promotion dispatch.

The immutable matching tag is a required publish precondition, not a tag
movement performed by the publish workflow. Tag pushes do not create GitHub
releases and must not be used as the npm publish trigger.

Expected:

- Tests pass.
- Typecheck passes.
- Build passes.
- Rule diagnostics are `PASS`.
- Scope diagnostics are `PASS`.
- Injection value state is acceptable for the release.
- Publish dry-run reports the expected package version, files, and dist-tag.

The manual GitHub Release workflow runs the verification subset only after an
explicit GA-approved dispatch:

```bash
npm test
npm run typecheck
npm run build
npm run report:rules
npm run check:scope:strict
npm run check:injection-value
npm pack --dry-run
npm publish --dry-run --access public --tag <resolved-dist-tag>
```

## 6. Install Smoke

Use a temporary project outside the repository:

```bash
tmp_project=$(mktemp -d)
cd "$tmp_project"
npm init -y
npm install -D persona-harness@<dist-tag>
npx ph --help
npx ph init
```

Check:

- `.opencode/opencode.json` exists.
- `.persona/harness.jsonc` exists.
- `.persona/rules` exists.
- `npx ph --help` shows the CLI commands.

For a local pre-publish smoke, install the generated tarball instead of the registry package.

## 7. Publish

Only run real publish after explicit QA approval.

Use the GitHub Actions workflow:

```text
.github/workflows/publish.yml
```

Inputs:

- `dist_tag=staging` with `approval_scope=staging-only` for an initial
  prerelease staging publish.
- `dist_tag=next` with `approval_scope=next-promotion-approved` only after
  the staged package has passed its separate promotion gate.
- `dist_tag=latest` with `approval_scope=ga-approved` for a separately
  approved stable/GA release.

### GitHub Actions trusted publishing path

The `.github/workflows/publish.yml` workflow publishes the current ref with
trusted publishing.

- prerelease versions can publish only with `staging` or separately approved
  `next`.
- stable versions can publish only with separately approved `latest`.
- the approval scope must match the fixed selected channel.
- after publish, the workflow verifies registry `gitHead`, `dist.shasum`, and
  dist-tag state.

Required repository setup:

- configure npm trusted publishing for this GitHub repository;
- trusted publisher workflow file: `.github/workflows/publish.yml`;
- GitHub environment: `npm-publish`, if configured in npm/GitHub;
- push the version commit before running the publish workflow;
- create/push the git tag only after registry verification.

The `.github/workflows/release.yml` workflow is manual-only. It verifies an
explicitly supplied existing stable tag and creates GitHub release notes only
with `approval_scope=ga-approved`. It is not the npm publish path.

## 8. Post-publish

- Run `npm view persona-harness dist-tags --json`.
- Run `npm view persona-harness@<version> version`.
- Install in a fresh temporary project using the public dist-tag.
- Confirm `npx ph init` works from the published package.
- Update `CHANGELOG.md` date if it was left as `Unreleased`.
- Create GitHub release notes from the release notes template if this release gets a GitHub release.
- For separately approved stable GitHub releases, the manual workflow creates
  notes from `docs/current/release/v<version>-release-notes.md` using
  `scripts/generate-github-release-notes.mjs`.
