From ddbdd3e692859364c70a5f01f3b0a16975160892 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 2 Jul 2026 11:48:33 -0700 Subject: [PATCH 1/4] docs(skills): gate release tags on pre-tag docs --- .../SKILL.md | 63 +++++++++++++------ .../nemoclaw-maintainer-evening/SKILL.md | 32 +++++++--- 2 files changed, 66 insertions(+), 29 deletions(-) diff --git a/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md b/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md index 3146ffce6ad..02b7349b00c 100644 --- a/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md @@ -1,6 +1,6 @@ --- name: nemoclaw-maintainer-cut-release-tag -description: Creates deterministic NemoClaw semver release tags on origin/main, handles release housekeeping, and drafts release notes. Use when cutting a release, tagging a version, shipping a build, creating vX.Y.Z tags, or preparing release announcements. +description: Creates deterministic NemoClaw semver release tags on origin/main, handles release housekeeping, gates pre-tag release docs, and drafts announcement notes. Use when cutting a release, tagging a version, shipping a build, creating vX.Y.Z tags, or preparing release announcements. user_invocable: true --- @@ -11,16 +11,17 @@ user_invocable: true Use the release scripts for normal release operations. Do not run raw `git tag`, `git push`, `gh api`, or version-bump commands by hand for the normal release flow. -The release is one annotated semver tag on an already-merged `origin/main` commit. The GitHub workflow moves `latest`; release admins promote `lkg` manually after validation. After the tag and `latest` are verified, automatically move remaining open issues/PRs from the released version label to the next patch label, then draft release notes for the maintainer to post. +The release is one annotated semver tag on an already-merged `origin/main` commit. The GitHub workflow moves `latest`; release admins promote `lkg` manually after validation. Before the tag, confirm release-prep docs are merged or explicitly waived. After the tag and `latest` are verified, automatically move remaining open issues/PRs from the released version label to the next patch label, then draft announcement notes for the maintainer to post. ## Hard Rules - Tag only the commit captured in a generated release plan. - Ask the maintainer to paste the exact confirmation phrase from the plan before cutting the tag. +- Do not ask for the exact confirmation phrase until release-prep docs are merged or the maintainer explicitly waives them. - Push only the semver tag (`vX.Y.Z`) from the agent-controlled step. - Never push `latest` or `lkg` from this skill. - Never move, delete, or force-push an existing remote semver tag unless the maintainer explicitly starts protected-tag remediation. -- Draft release notes locally. Do not create the GitHub Discussion; the maintainer does that. +- Draft announcement notes locally. Do not create the GitHub Discussion; the maintainer does that. - Follow the shared [Git and GitHub Access Hard Stop](../_shared/git-github-hard-stop.md) for SSH, authentication, remote access, authorization, or permission failures. ## Workflow @@ -30,12 +31,13 @@ Copy this checklist and update it as you proceed: ```text Release Progress: - [ ] Step 1: Generate release plan -- [ ] Step 2: Show plan and exact confirmation phrase -- [ ] Step 3: Cut the semver tag from the confirmed plan -- [ ] Step 4: Wait for workflow-managed latest -- [ ] Step 5: Bump remaining open issues/PRs -- [ ] Step 6: Generate release-note data and draft Markdown -- [ ] Step 7: Hand off announcement steps +- [ ] Step 2: Show plan and pre-tag docs gate +- [ ] Step 3: Confirm release-prep docs are merged or waived +- [ ] Step 4: Ask for exact confirmation and cut the semver tag +- [ ] Step 5: Wait for workflow-managed latest +- [ ] Step 6: Bump remaining open issues/PRs +- [ ] Step 7: Generate announcement data and draft Markdown +- [ ] Step 8: Hand off announcement steps ``` ### Step 1: Generate Release Plan @@ -56,7 +58,7 @@ The script writes a plan outside the checkout root, for example: ../nemoclaw-release-v0.0.58/plan.json ``` -### Step 2: Show Plan and Ask for Exact Confirmation +### Step 2: Show Plan and Pre-Tag Docs Gate Read the generated `plan.json` and show the maintainer: @@ -65,9 +67,31 @@ Read the generated `plan.json` and show the maintainer: - target `origin/main` commit and headline, - plan hash, - forbidden operations, -- exact confirmation phrase, +- exact confirmation phrase, but do not request it yet, - open issue/PR housekeeping plan for the release label. +Start or verify release-prep docs before asking for the exact confirmation phrase: + +```text +/nemoclaw-contributor-update-docs for vX.Y.Z +``` + +Use the release version from `plan.json`, not the next patch label. +The docs PR should land with `area: docs` and the release label being prepared. +This work can run while final E2E validation finishes. + +### Step 3: Confirm Release-Prep Docs Status + +Report one of these statuses: + +- `merged`: release-prep docs PR from Step 2 landed for `vX.Y.Z`. +- `pending`: release-prep docs PR is still open. Do not proceed to tag confirmation. +- `waived`: maintainer explicitly accepted tagging without pre-tag docs and gave the reason. + +Proceed only when the status is `merged` or `waived`. + +### Step 4: Ask for Exact Confirmation and Cut the Semver Tag + Ask the maintainer to paste the exact phrase: ```text @@ -76,8 +100,6 @@ CONFIRM RELEASE vX.Y.Z Do not proceed on a generic "yes" at this step. -### Step 3: Cut the Semver Tag - Run the cut script with the plan and the maintainer's exact phrase: ```bash @@ -92,7 +114,7 @@ The script verifies a clean worktree, unchanged `origin/main`, tag availability, If the script fails because of SSH, authentication, remote access, authorization, or permissions, follow [Git and GitHub Access Hard Stop](../_shared/git-github-hard-stop.md). For other precondition failures, report the failed precondition and use the recovery guidance below. Do not improvise git commands. -### Step 4: Wait for Workflow-Managed `latest` +### Step 5: Wait for Workflow-Managed `latest` Run: @@ -108,7 +130,7 @@ The script waits until `vX.Y.Z^{}` and `latest^{}` both peel to the planned comm If it fails, report the failed workflow/status. Do not manually move `latest`. -### Step 5: Bump Remaining Open Issues/PRs +### Step 6: Bump Remaining Open Issues/PRs Move every remaining open issue or PR carrying the released version to the next patch label: @@ -116,7 +138,7 @@ Move every remaining open issue or PR carrying the released version to the next node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/bump-stragglers.ts ``` -This is automatic post-tag housekeeping covered by the release plan and exact confirmation in Step 2. The script creates the next patch label when needed, removes the released-version label, and adds the next-version label to every open straggler. Do not run it before Step 4 verifies both the semver tag and workflow-managed `latest`. +This is automatic post-tag housekeeping covered by the release plan and exact confirmation in Step 2. The script creates the next patch label when needed, removes the released-version label, and adds the next-version label to every open straggler. Do not run it before Step 5 verifies both the semver tag and workflow-managed `latest`. Then verify the released version has no open stragglers: @@ -130,9 +152,9 @@ Summarize: - open issues/PRs bumped to ``; - any items that need manual maintainer attention. -### Step 6: Generate Release-Note Data and Draft Markdown +### Step 7: Generate Announcement Data and Draft Markdown -Collect deterministic release-note input: +Collect deterministic announcement input: ```bash npm run release:notes-data -- --plan @@ -146,7 +168,7 @@ This writes: If `notes-data.json` has `status: "partial"` or non-empty `pullRequestWarnings`, report the warnings and ask the maintainer whether to fetch/fill the missing PR metadata before drafting. -Draft release notes from `notes-data.json` using the style from `nemoclaw-maintainer-release-notes`. Save only Markdown, outside the checkout root: +Draft announcement notes from `notes-data.json` using the style from `nemoclaw-maintainer-release-notes`. Save only Markdown, outside the checkout root: ```text /release-note-draft.md @@ -154,12 +176,13 @@ Draft release notes from `notes-data.json` using the style from `nemoclaw-mainta Do not create or update a GitHub Discussion. -### Step 7: Hand Off Announcement +### Step 8: Hand Off Announcement Return: - release tag, - confirmed release commit, +- release-prep docs status, - plan path and plan hash, - `cut-result.json`, `latest-result.json`, and `notes-data.json` paths, - Markdown draft path, diff --git a/.agents/skills/nemoclaw-maintainer-evening/SKILL.md b/.agents/skills/nemoclaw-maintainer-evening/SKILL.md index 4e2902d2a37..b74126887ff 100644 --- a/.agents/skills/nemoclaw-maintainer-evening/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-evening/SKILL.md @@ -1,12 +1,12 @@ --- name: nemoclaw-maintainer-evening -description: Runs the end-of-day maintainer handoff for NemoClaw. Checks version target progress, records stragglers for an automatic post-tag bump, generates a QA handoff summary, and cuts the release tag. Use at the end of the workday. Trigger keywords - evening, end of day, EOD, wrap up, ship it, cut tag, handoff, done for the day. +description: Runs the end-of-day maintainer handoff for NemoClaw. Checks version target progress, records stragglers for an automatic post-tag bump, generates a QA handoff summary, starts pre-tag docs, and cuts the release tag. Use at the end of the workday. Trigger keywords - evening, end of day, EOD, wrap up, ship it, cut tag, handoff, done for the day. user_invocable: true --- # NemoClaw Maintainer Evening -Wrap up the day: check progress, identify stragglers, summarize for QA, cut the tag, automatically bump stragglers to the next patch, and prepare release notes for posting. +Wrap up the day: check progress, identify stragglers, summarize for QA, run release-prep docs, cut the tag, automatically bump stragglers to the next patch, and prepare announcement notes for posting. See [PR-REVIEW-PRIORITIES.md](../nemoclaw-maintainer-day/PR-REVIEW-PRIORITIES.md) for the daily cadence. @@ -40,23 +40,36 @@ node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer This lists commits since the last tag, identifies risky areas touched, and suggests QA test focus areas. Format the output as a concise summary the user can paste into the tag annotation or a handoff channel. -## Step 4: Cut the Tag and Publish Release Notes +## Step 4: Start Pre-Tag Docs -Load `cut-release-tag`. The version is already known — default to patch bump, but still show the commit, changelog, post-tag bump plan, and release notes draft for confirmation. NemoClaw releases are tag-based: tag `main`, let the workflow move `latest`, automatically bump remaining open issues/PRs to the next patch label, and prepare the release notes announcement for the maintainer to post. +Load `nemoclaw-contributor-update-docs` for the release version before asking for the tag confirmation phrase. +This can run while final E2E validation finishes. +The release docs PR should use the release label being prepared, such as `v0.0.73`, and should land before the semver tag unless the maintainer explicitly records a docs waiver. -## Step 5: Confirm and Share +Report one of these docs statuses before continuing: -After the tag is cut and release notes are drafted or posted by the maintainer, present the final summary: +- `merged`: release-prep docs landed for ``. +- `pending`: release-prep docs PR is open and must finish before tag confirmation. +- `waived`: maintainer explicitly accepted tagging without pre-tag docs and gave the reason. + +## Step 5: Cut the Tag and Publish Announcement Notes + +Load `cut-release-tag`. The version is already known. Default to patch bump, but still show the commit, changelog, pre-tag docs status, post-tag bump plan, and announcement draft for confirmation. NemoClaw releases are tag-based: tag `main`, let the workflow move `latest`, automatically bump remaining open issues/PRs to the next patch label, and prepare the release announcement for the maintainer to post. + +## Step 6: Confirm and Share + +After the tag is cut and announcement notes are drafted or posted by the maintainer, present the final summary: - **Tag**: `v0.0.8` at commit `abc1234` -- **Release notes draft**: `../nemoclaw-release-v0.0.8/release-note-draft.md` +- **Release docs**: merged, pending, or waived with reason +- **Announcement draft**: `../nemoclaw-release-v0.0.8/release-note-draft.md` - **Shipped**: 4 items (#1234, #1235, #1236, #1237) - **Bumped to v0.0.9**: 1 item (#1238 — still needs CI fix) - **QA focus areas**: installer changes, new onboard preset This summary can be shared in the team's handoff channel. -## Step 6: Update State +## Step 7: Update State ```bash node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/state.ts history "tag-cut" "" "shipped N items, bumped M" @@ -64,7 +77,8 @@ node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer ## Notes -- Never cut a tag or hand off release notes without user confirmation. +- Never cut a tag or hand off announcement notes without user confirmation. +- Never ask for the exact tag confirmation phrase until release-prep docs are merged or explicitly waived. - If nothing was labeled or nothing shipped, ask whether to skip the tag today. - A PR version label activates release work; it is not a readiness claim. - If an open item misses the tag, post-tag housekeeping moves its target to the next patch version. From 5e042fe8a9fd6fa5bac818d8216ee0574b22da60 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 2 Jul 2026 12:18:41 -0700 Subject: [PATCH 2/4] docs(skills): clarify release docs final status --- .agents/skills/nemoclaw-maintainer-evening/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.agents/skills/nemoclaw-maintainer-evening/SKILL.md b/.agents/skills/nemoclaw-maintainer-evening/SKILL.md index b74126887ff..dcc11adf72d 100644 --- a/.agents/skills/nemoclaw-maintainer-evening/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-evening/SKILL.md @@ -61,7 +61,7 @@ Load `cut-release-tag`. The version is already known. Default to patch bump, but After the tag is cut and announcement notes are drafted or posted by the maintainer, present the final summary: - **Tag**: `v0.0.8` at commit `abc1234` -- **Release docs**: merged, pending, or waived with reason +- **Release docs**: merged or waived with reason - **Announcement draft**: `../nemoclaw-release-v0.0.8/release-note-draft.md` - **Shipped**: 4 items (#1234, #1235, #1236, #1237) - **Bumped to v0.0.9**: 1 item (#1238 — still needs CI fix) From 778aa60271e00830b1a9fdaa08ecb5befddb9d55 Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 2 Jul 2026 12:54:52 -0700 Subject: [PATCH 3/4] docs(skills): freeze release plans after readiness --- .../SKILL.md | 72 +++++++++---------- .../nemoclaw-maintainer-evening/SKILL.md | 31 +++++--- .../references/release-train.md | 36 +++++++++- .../SKILL.md | 2 +- test/maintainer-skills-policy.test.ts | 28 +++++++- 5 files changed, 117 insertions(+), 52 deletions(-) diff --git a/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md b/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md index 02b7349b00c..f59ebe7b6f7 100644 --- a/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md @@ -1,6 +1,6 @@ --- name: nemoclaw-maintainer-cut-release-tag -description: Creates deterministic NemoClaw semver release tags on origin/main, handles release housekeeping, gates pre-tag release docs, and drafts announcement notes. Use when cutting a release, tagging a version, shipping a build, creating vX.Y.Z tags, or preparing release announcements. +description: Creates deterministic NemoClaw semver release tags on origin/main after release readiness is frozen, handles release housekeeping, and drafts announcement notes. Use when cutting a release, tagging a version, shipping a build, creating vX.Y.Z tags, or preparing release announcements. user_invocable: true --- @@ -11,16 +11,18 @@ user_invocable: true Use the release scripts for normal release operations. Do not run raw `git tag`, `git push`, `gh api`, or version-bump commands by hand for the normal release flow. -The release is one annotated semver tag on an already-merged `origin/main` commit. The GitHub workflow moves `latest`; release admins promote `lkg` manually after validation. Before the tag, confirm release-prep docs are merged or explicitly waived. After the tag and `latest` are verified, automatically move remaining open issues/PRs from the released version label to the next patch label, then draft announcement notes for the maintainer to post. +The release is one annotated semver tag on an already-merged `origin/main` commit. The GitHub workflow moves `latest`; release admins promote `lkg` manually after validation. This skill consumes completed release readiness, generates the final plan as the commit-freeze boundary, pushes the semver tag, verifies `latest`, moves remaining open issues/PRs from the released version label to the next patch label, and drafts announcement notes for the maintainer to post. ## Hard Rules - Tag only the commit captured in a generated release plan. -- Ask the maintainer to paste the exact confirmation phrase from the plan before cutting the tag. -- Do not ask for the exact confirmation phrase until release-prep docs are merged or the maintainer explicitly waives them. +- Do not generate the release plan until release readiness is complete: docs merged or waived, docs scan delta reviewed, pre-tag checks complete or waived, and no further intended merge remains. +- Any merge after plan generation invalidates the plan. Regenerate the plan after re-checking readiness against the new candidate SHA. +- Ask the maintainer to paste the exact confirmation phrase from the final plan before cutting the tag. - Push only the semver tag (`vX.Y.Z`) from the agent-controlled step. - Never push `latest` or `lkg` from this skill. - Never move, delete, or force-push an existing remote semver tag unless the maintainer explicitly starts protected-tag remediation. +- Do not launch or merge the release-prep docs PR from this skill. Return to `nemoclaw-maintainer-evening` if mutable readiness work remains. - Draft announcement notes locally. Do not create the GitHub Discussion; the maintainer does that. - Follow the shared [Git and GitHub Access Hard Stop](../_shared/git-github-hard-stop.md) for SSH, authentication, remote access, authorization, or permission failures. @@ -30,17 +32,30 @@ Copy this checklist and update it as you proceed: ```text Release Progress: -- [ ] Step 1: Generate release plan -- [ ] Step 2: Show plan and pre-tag docs gate -- [ ] Step 3: Confirm release-prep docs are merged or waived -- [ ] Step 4: Ask for exact confirmation and cut the semver tag +- [ ] Step 1: Confirm release readiness and freeze inputs +- [ ] Step 2: Generate final release plan +- [ ] Step 3: Show final plan and ask for exact confirmation +- [ ] Step 4: Cut the semver tag from the confirmed plan - [ ] Step 5: Wait for workflow-managed latest - [ ] Step 6: Bump remaining open issues/PRs - [ ] Step 7: Generate announcement data and draft Markdown - [ ] Step 8: Hand off announcement steps ``` -### Step 1: Generate Release Plan +### Step 1: Confirm Release Readiness and Freeze Inputs + +Before running `release:plan`, confirm the maintainer can report: + +- cutoff inventory and post-tag straggler plan; +- release-prep docs status, either merged with PR and merge SHA or waived with reason; +- docs scan SHA, current candidate SHA, and the `docs_scan_sha..candidate_sha` delta review; +- required pre-tag checks, with waiver reasons for any skipped check; +- confirmation that no further intended merge remains. + +If release-prep docs are `pending`, stop before generating the release plan. +If any mutable release prerequisite is still in progress, return to `nemoclaw-maintainer-evening`. + +### Step 2: Generate Final Release Plan Run exactly one of: @@ -52,13 +67,17 @@ npm run release:plan -- --bump major Patch is the default if the maintainer says "yes", "go", or similar without choosing. +This is the commit-freeze boundary. +Do not merge additional PRs after this point. +If `origin/main` changes after plan generation, discard the stale plan, re-check release readiness, and generate a fresh plan. + The script writes a plan outside the checkout root, for example: ```text ../nemoclaw-release-v0.0.58/plan.json ``` -### Step 2: Show Plan and Pre-Tag Docs Gate +### Step 3: Show Final Plan and Ask for Exact Confirmation Read the generated `plan.json` and show the maintainer: @@ -66,32 +85,11 @@ Read the generated `plan.json` and show the maintainer: - next tag, - target `origin/main` commit and headline, - plan hash, +- release readiness summary, - forbidden operations, -- exact confirmation phrase, but do not request it yet, +- exact confirmation phrase, - open issue/PR housekeeping plan for the release label. -Start or verify release-prep docs before asking for the exact confirmation phrase: - -```text -/nemoclaw-contributor-update-docs for vX.Y.Z -``` - -Use the release version from `plan.json`, not the next patch label. -The docs PR should land with `area: docs` and the release label being prepared. -This work can run while final E2E validation finishes. - -### Step 3: Confirm Release-Prep Docs Status - -Report one of these statuses: - -- `merged`: release-prep docs PR from Step 2 landed for `vX.Y.Z`. -- `pending`: release-prep docs PR is still open. Do not proceed to tag confirmation. -- `waived`: maintainer explicitly accepted tagging without pre-tag docs and gave the reason. - -Proceed only when the status is `merged` or `waived`. - -### Step 4: Ask for Exact Confirmation and Cut the Semver Tag - Ask the maintainer to paste the exact phrase: ```text @@ -100,6 +98,8 @@ CONFIRM RELEASE vX.Y.Z Do not proceed on a generic "yes" at this step. +### Step 4: Cut the Semver Tag + Run the cut script with the plan and the maintainer's exact phrase: ```bash @@ -138,7 +138,7 @@ Move every remaining open issue or PR carrying the released version to the next node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/bump-stragglers.ts ``` -This is automatic post-tag housekeeping covered by the release plan and exact confirmation in Step 2. The script creates the next patch label when needed, removes the released-version label, and adds the next-version label to every open straggler. Do not run it before Step 5 verifies both the semver tag and workflow-managed `latest`. +This is automatic post-tag housekeeping covered by the release plan and exact confirmation in Step 4. The script creates the next patch label when needed, removes the released-version label, and adds the next-version label to every open straggler. Do not run it before Step 5 verifies both the semver tag and workflow-managed `latest`. Then verify the released version has no open stragglers: @@ -171,7 +171,7 @@ If `notes-data.json` has `status: "partial"` or non-empty `pullRequestWarnings`, Draft announcement notes from `notes-data.json` using the style from `nemoclaw-maintainer-release-notes`. Save only Markdown, outside the checkout root: ```text -/release-note-draft.md +/announcement-notes-draft.md ``` Do not create or update a GitHub Discussion. @@ -182,7 +182,7 @@ Return: - release tag, - confirmed release commit, -- release-prep docs status, +- release readiness summary, including docs status and docs scan delta review, - plan path and plan hash, - `cut-result.json`, `latest-result.json`, and `notes-data.json` paths, - Markdown draft path, diff --git a/.agents/skills/nemoclaw-maintainer-evening/SKILL.md b/.agents/skills/nemoclaw-maintainer-evening/SKILL.md index dcc11adf72d..eaee380a805 100644 --- a/.agents/skills/nemoclaw-maintainer-evening/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-evening/SKILL.md @@ -1,12 +1,12 @@ --- name: nemoclaw-maintainer-evening -description: Runs the end-of-day maintainer handoff for NemoClaw. Checks version target progress, records stragglers for an automatic post-tag bump, generates a QA handoff summary, starts pre-tag docs, and cuts the release tag. Use at the end of the workday. Trigger keywords - evening, end of day, EOD, wrap up, ship it, cut tag, handoff, done for the day. +description: Runs the end-of-day maintainer handoff for NemoClaw. Checks version target progress, records stragglers for an automatic post-tag bump, completes pre-plan release readiness, and cuts the release tag. Use at the end of the workday. Trigger keywords - evening, end of day, EOD, wrap up, ship it, cut tag, handoff, done for the day. user_invocable: true --- # NemoClaw Maintainer Evening -Wrap up the day: check progress, identify stragglers, summarize for QA, run release-prep docs, cut the tag, automatically bump stragglers to the next patch, and prepare announcement notes for posting. +Wrap up the day: check progress, identify stragglers, summarize for QA, complete pre-plan release readiness, cut the tag, automatically bump stragglers to the next patch, and prepare announcement notes for posting. See [PR-REVIEW-PRIORITIES.md](../nemoclaw-maintainer-day/PR-REVIEW-PRIORITIES.md) for the daily cadence. @@ -30,7 +30,7 @@ gh issue list --repo NVIDIA/NemoClaw --state open --label --limit 100 List open labeled PRs and issues as the post-tag housekeeping plan. Tell the maintainer that, after the tag and workflow-managed `latest` are verified, `cut-release-tag` will automatically move all of them to the next patch label. -If an item should leave the daily release flow instead of moving forward, remove it from the released-version label before asking for the release confirmation phrase. +If an item should leave the daily release flow instead of moving forward, remove it from the released-version label before declaring release readiness. ## Step 3: Generate Handoff Summary @@ -40,21 +40,28 @@ node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer This lists commits since the last tag, identifies risky areas touched, and suggests QA test focus areas. Format the output as a concise summary the user can paste into the tag annotation or a handoff channel. -## Step 4: Start Pre-Tag Docs +## Step 4: Complete Pre-Plan Release Readiness -Load `nemoclaw-contributor-update-docs` for the release version before asking for the tag confirmation phrase. +Load `nemoclaw-contributor-update-docs` for the release version before generating the final release plan. This can run while final E2E validation finishes. -The release docs PR should use the release label being prepared, such as `v0.0.73`, and should land before the semver tag unless the maintainer explicitly records a docs waiver. +The release docs PR should use the release label being prepared, such as `v0.0.73`, and should land before `release:plan` captures the frozen candidate SHA unless the maintainer explicitly records a docs waiver. Report one of these docs statuses before continuing: - `merged`: release-prep docs landed for ``. -- `pending`: release-prep docs PR is open and must finish before tag confirmation. +- `pending`: release-prep docs PR is open and must finish before the final release plan. - `waived`: maintainer explicitly accepted tagging without pre-tag docs and gave the reason. -## Step 5: Cut the Tag and Publish Announcement Notes +Stop on `pending`. +When docs are `merged` or `waived`, record the docs scan SHA, the current candidate SHA, and whether the `docs_scan_sha..candidate_sha` delta has additional docs impact. +Also confirm that all required pre-tag checks are complete or explicitly waived, and that no further intended merge remains. -Load `cut-release-tag`. The version is already known. Default to patch bump, but still show the commit, changelog, pre-tag docs status, post-tag bump plan, and announcement draft for confirmation. NemoClaw releases are tag-based: tag `main`, let the workflow move `latest`, automatically bump remaining open issues/PRs to the next patch label, and prepare the release announcement for the maintainer to post. +## Step 5: Freeze the Plan, Cut the Tag, and Publish Announcement Notes + +Load `cut-release-tag` only after release readiness is complete. +The version is already known. +Default to patch bump, but still show the commit, changelog, release-readiness status, post-tag bump plan, and announcement draft for confirmation. +NemoClaw releases are tag-based: tag `main`, let the workflow move `latest`, automatically bump remaining open issues/PRs to the next patch label, and prepare the release announcement for the maintainer to post. ## Step 6: Confirm and Share @@ -62,7 +69,8 @@ After the tag is cut and announcement notes are drafted or posted by the maintai - **Tag**: `v0.0.8` at commit `abc1234` - **Release docs**: merged or waived with reason -- **Announcement draft**: `../nemoclaw-release-v0.0.8/release-note-draft.md` +- **Readiness freeze**: docs scan SHA, candidate SHA, and delta review status +- **Announcement draft**: `../nemoclaw-release-v0.0.8/announcement-notes-draft.md` - **Shipped**: 4 items (#1234, #1235, #1236, #1237) - **Bumped to v0.0.9**: 1 item (#1238 — still needs CI fix) - **QA focus areas**: installer changes, new onboard preset @@ -78,7 +86,8 @@ node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer ## Notes - Never cut a tag or hand off announcement notes without user confirmation. -- Never ask for the exact tag confirmation phrase until release-prep docs are merged or explicitly waived. +- Never generate the final release plan until release-prep docs are merged or explicitly waived and no further intended merge remains. +- If any merge lands after plan generation, return to Step 4, re-check readiness, and generate a fresh plan. - If nothing was labeled or nothing shipped, ask whether to skip the tag today. - A PR version label activates release work; it is not a readiness claim. - If an open item misses the tag, post-tag housekeeping moves its target to the next patch version. diff --git a/.agents/skills/nemoclaw-maintainer-policies/references/release-train.md b/.agents/skills/nemoclaw-maintainer-policies/references/release-train.md index 750880212ed..2007595ac65 100644 --- a/.agents/skills/nemoclaw-maintainer-policies/references/release-train.md +++ b/.agents/skills/nemoclaw-maintainer-policies/references/release-train.md @@ -17,6 +17,22 @@ Daily release labels coordinate release work. They do not classify issues and th - A PR or issue leaves the daily release cycle only when its version label is removed without a replacement. - Version labels are pruned after seven days only after durable release history is preserved and no open PR still carries or depends on the old label. +## Release Lifecycle + +NemoClaw uses this release sequence: + +```text +prepare -> declare ready -> freeze/plan -> tag candidate -> validate -> promote lkg +``` + +The semver tag publishes the release candidate, including public docs and release artifacts. +Release-prep docs therefore gate the semver tag. +Exact-tag E2E and QA validation gate `lkg` promotion unless maintainers explicitly choose a different release model. + +The release plan is the commit-freeze boundary. +All mutable release readiness work must finish before `release:plan` captures the final `origin/main` SHA. +Any merge after plan generation invalidates the plan and requires maintainers to re-check readiness against the new candidate SHA before generating a fresh plan. + ## Cutoff The daily cutoff is the maintainer-defined point where the release tag is prepared. @@ -26,9 +42,23 @@ At cutoff: 1. List merged PRs carrying the target version label. 2. Confirm each is intended for the release. 3. List open PRs and issues still carrying the target label as post-tag stragglers. -4. Generate QA handoff from merged PRs. -5. Cut the release tag only with explicit maintainer confirmation. -6. After the tag and workflow-managed `latest` are verified, automatically move every open straggler to the next patch label. +4. Merge release-prep docs, or record a maintainer waiver with the reason. +5. Record the SHA through which docs were scanned and review any `docs_scan_sha..candidate_sha` delta for additional docs impact. +6. Finish or explicitly waive every pre-tag check required for the release. +7. Confirm that no further intended merge remains. +8. Generate the final release plan for the current `origin/main` SHA. +9. Cut the release tag only with explicit maintainer confirmation from the final plan. +10. After the tag and workflow-managed `latest` are verified, automatically move every open straggler to the next patch label. + +Release readiness is complete only when the maintainer can report: + +- the cutoff inventory and post-tag straggler plan; +- release-prep docs status, either merged with PR and merge SHA or waived with reason; +- docs scan SHA and candidate SHA delta review; +- pre-tag check status, including waivers and reasons; +- confirmation that no further intended merge remains before plan generation. + +If release-prep docs are still pending, stop before generating the release plan. ## Carry Forward diff --git a/.agents/skills/nemoclaw-maintainer-release-notes/SKILL.md b/.agents/skills/nemoclaw-maintainer-release-notes/SKILL.md index c25c3f436e3..97f9cb72be9 100644 --- a/.agents/skills/nemoclaw-maintainer-release-notes/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-release-notes/SKILL.md @@ -148,7 +148,7 @@ Keep the prose warm and polished, but concrete. Tie the narrative to actual PRs Create a Markdown draft outside the checkout root so the repo stays clean, for example: ```bash -../nemoclaw--release-note-draft.md +../nemoclaw--announcement-notes-draft.md ``` The Markdown body is the source the maintainer can paste into GitHub Discussions. diff --git a/test/maintainer-skills-policy.test.ts b/test/maintainer-skills-policy.test.ts index eebfab8dc28..3c9b6a04d21 100644 --- a/test/maintainer-skills-policy.test.ts +++ b/test/maintainer-skills-policy.test.ts @@ -75,7 +75,7 @@ describe("maintainer skills follow canonical workflow policy", () => { expect(evening).toContain("automatically bump stragglers to the next patch"); expect(release).toContain("scripts/bump-stragglers.ts"); - expect(release).toContain("Do not run it before Step 4"); + expect(release).toContain("Do not run it before Step 5"); expect(morning).toContain("post-tag housekeeping was interrupted"); expect(priorities).toContain("automatically bump stragglers to the next patch"); expect(policy).toContain("automatically move every open straggler to the next patch label"); @@ -86,6 +86,32 @@ describe("maintainer skills follow canonical workflow policy", () => { ).toBe(true); }); + it("freezes the release plan only after mutable readiness is complete", () => { + const evening = read(".agents/skills/nemoclaw-maintainer-evening/SKILL.md"); + const release = read(".agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md"); + const policy = read(".agents/skills/nemoclaw-maintainer-policies/references/release-train.md"); + + expect(policy).toContain( + "prepare -> declare ready -> freeze/plan -> tag candidate -> validate -> promote lkg", + ); + expect(policy).toContain("The release plan is the commit-freeze boundary."); + expect(policy).toContain( + "If release-prep docs are still pending, stop before generating the release plan.", + ); + expect(evening.indexOf("Load `nemoclaw-contributor-update-docs`")).toBeLessThan( + evening.indexOf("Load `cut-release-tag`"), + ); + expect(evening).toContain("Stop on `pending`."); + expect(release).toContain( + "Do not generate the release plan until release readiness is complete", + ); + expect(release).toContain("Any merge after plan generation invalidates the plan"); + expect(release).toContain( + "If release-prep docs are `pending`, stop before generating the release plan.", + ); + expect(release).not.toContain("/nemoclaw-contributor-update-docs"); + }); + it("keeps cross-issue sweeping separate from comparator scoring", () => { const sweep = read(".agents/skills/nemoclaw-maintainer-cross-issue-sweep/SKILL.md"); const comparator = read(".agents/skills/nemoclaw-maintainer-pr-comparator/SKILL.md"); From 5137b340176696245dcc70903e936ce65d8c82ce Mon Sep 17 00:00:00 2001 From: Miyoung Choi Date: Thu, 2 Jul 2026 13:09:25 -0700 Subject: [PATCH 4/4] docs(skills): narrow pre-tag docs gate --- .../nemoclaw-contributor-update-docs/SKILL.md | 1 + .../SKILL.md | 70 +++++++------------ .../nemoclaw-maintainer-evening/SKILL.md | 45 ++++-------- .../references/release-train.md | 38 ++-------- .../SKILL.md | 2 +- test/maintainer-skills-policy.test.ts | 25 +++---- 6 files changed, 57 insertions(+), 124 deletions(-) diff --git a/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md b/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md index e9f865c0459..651265730a5 100644 --- a/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md +++ b/.agents/skills/nemoclaw-contributor-update-docs/SKILL.md @@ -18,6 +18,7 @@ Scan recent git history for commits that affect user-facing behavior and draft d - Before a release, to catch any doc gaps. - During daily release prep, before opening the release-note docs PR. - Before cutting a release tag, so release-note docs land on the same release train. +- When maintainers run `/nemoclaw-contributor-update-docs for vX.Y.Z`, treat it as pre-tag release-prep docs for `vX.Y.Z` unless the tag already exists. - After a release only when maintainers missed the pre-tag docs step and need a catch-up PR. - When a contributor asks "what docs need updating?" diff --git a/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md b/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md index f59ebe7b6f7..e99c604afe4 100644 --- a/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md @@ -1,6 +1,6 @@ --- name: nemoclaw-maintainer-cut-release-tag -description: Creates deterministic NemoClaw semver release tags on origin/main after release readiness is frozen, handles release housekeeping, and drafts announcement notes. Use when cutting a release, tagging a version, shipping a build, creating vX.Y.Z tags, or preparing release announcements. +description: Creates deterministic NemoClaw semver release tags on origin/main, handles release housekeeping, and drafts release notes. Use when cutting a release, tagging a version, shipping a build, creating vX.Y.Z tags, or preparing release announcements. user_invocable: true --- @@ -11,19 +11,18 @@ user_invocable: true Use the release scripts for normal release operations. Do not run raw `git tag`, `git push`, `gh api`, or version-bump commands by hand for the normal release flow. -The release is one annotated semver tag on an already-merged `origin/main` commit. The GitHub workflow moves `latest`; release admins promote `lkg` manually after validation. This skill consumes completed release readiness, generates the final plan as the commit-freeze boundary, pushes the semver tag, verifies `latest`, moves remaining open issues/PRs from the released version label to the next patch label, and drafts announcement notes for the maintainer to post. +The release is one annotated semver tag on an already-merged `origin/main` commit. The GitHub workflow moves `latest`; release admins promote `lkg` manually after validation. After the tag and `latest` are verified, automatically move remaining open issues/PRs from the released version label to the next patch label, then draft release notes for the maintainer to post. ## Hard Rules - Tag only the commit captured in a generated release plan. -- Do not generate the release plan until release readiness is complete: docs merged or waived, docs scan delta reviewed, pre-tag checks complete or waived, and no further intended merge remains. -- Any merge after plan generation invalidates the plan. Regenerate the plan after re-checking readiness against the new candidate SHA. -- Ask the maintainer to paste the exact confirmation phrase from the final plan before cutting the tag. +- Do not generate the release plan until release-prep docs are merged or explicitly waived. +- If `origin/main` changes after plan generation, regenerate the plan before cutting the tag. +- Ask the maintainer to paste the exact confirmation phrase from the plan before cutting the tag. - Push only the semver tag (`vX.Y.Z`) from the agent-controlled step. - Never push `latest` or `lkg` from this skill. - Never move, delete, or force-push an existing remote semver tag unless the maintainer explicitly starts protected-tag remediation. -- Do not launch or merge the release-prep docs PR from this skill. Return to `nemoclaw-maintainer-evening` if mutable readiness work remains. -- Draft announcement notes locally. Do not create the GitHub Discussion; the maintainer does that. +- Draft release notes locally. Do not create the GitHub Discussion; the maintainer does that. - Follow the shared [Git and GitHub Access Hard Stop](../_shared/git-github-hard-stop.md) for SSH, authentication, remote access, authorization, or permission failures. ## Workflow @@ -32,30 +31,19 @@ Copy this checklist and update it as you proceed: ```text Release Progress: -- [ ] Step 1: Confirm release readiness and freeze inputs -- [ ] Step 2: Generate final release plan -- [ ] Step 3: Show final plan and ask for exact confirmation -- [ ] Step 4: Cut the semver tag from the confirmed plan -- [ ] Step 5: Wait for workflow-managed latest -- [ ] Step 6: Bump remaining open issues/PRs -- [ ] Step 7: Generate announcement data and draft Markdown -- [ ] Step 8: Hand off announcement steps +- [ ] Step 1: Generate release plan +- [ ] Step 2: Show plan and exact confirmation phrase +- [ ] Step 3: Cut the semver tag from the confirmed plan +- [ ] Step 4: Wait for workflow-managed latest +- [ ] Step 5: Bump remaining open issues/PRs +- [ ] Step 6: Generate release-note data and draft Markdown +- [ ] Step 7: Hand off announcement steps ``` -### Step 1: Confirm Release Readiness and Freeze Inputs +### Step 1: Generate Release Plan -Before running `release:plan`, confirm the maintainer can report: - -- cutoff inventory and post-tag straggler plan; -- release-prep docs status, either merged with PR and merge SHA or waived with reason; -- docs scan SHA, current candidate SHA, and the `docs_scan_sha..candidate_sha` delta review; -- required pre-tag checks, with waiver reasons for any skipped check; -- confirmation that no further intended merge remains. - -If release-prep docs are `pending`, stop before generating the release plan. -If any mutable release prerequisite is still in progress, return to `nemoclaw-maintainer-evening`. - -### Step 2: Generate Final Release Plan +Before this step, confirm release-prep docs are merged or explicitly waived. +Return to `nemoclaw-maintainer-evening` if docs are still pending. Run exactly one of: @@ -67,17 +55,13 @@ npm run release:plan -- --bump major Patch is the default if the maintainer says "yes", "go", or similar without choosing. -This is the commit-freeze boundary. -Do not merge additional PRs after this point. -If `origin/main` changes after plan generation, discard the stale plan, re-check release readiness, and generate a fresh plan. - The script writes a plan outside the checkout root, for example: ```text ../nemoclaw-release-v0.0.58/plan.json ``` -### Step 3: Show Final Plan and Ask for Exact Confirmation +### Step 2: Show Plan and Ask for Exact Confirmation Read the generated `plan.json` and show the maintainer: @@ -85,7 +69,6 @@ Read the generated `plan.json` and show the maintainer: - next tag, - target `origin/main` commit and headline, - plan hash, -- release readiness summary, - forbidden operations, - exact confirmation phrase, - open issue/PR housekeeping plan for the release label. @@ -98,7 +81,7 @@ CONFIRM RELEASE vX.Y.Z Do not proceed on a generic "yes" at this step. -### Step 4: Cut the Semver Tag +### Step 3: Cut the Semver Tag Run the cut script with the plan and the maintainer's exact phrase: @@ -114,7 +97,7 @@ The script verifies a clean worktree, unchanged `origin/main`, tag availability, If the script fails because of SSH, authentication, remote access, authorization, or permissions, follow [Git and GitHub Access Hard Stop](../_shared/git-github-hard-stop.md). For other precondition failures, report the failed precondition and use the recovery guidance below. Do not improvise git commands. -### Step 5: Wait for Workflow-Managed `latest` +### Step 4: Wait for Workflow-Managed `latest` Run: @@ -130,7 +113,7 @@ The script waits until `vX.Y.Z^{}` and `latest^{}` both peel to the planned comm If it fails, report the failed workflow/status. Do not manually move `latest`. -### Step 6: Bump Remaining Open Issues/PRs +### Step 5: Bump Remaining Open Issues/PRs Move every remaining open issue or PR carrying the released version to the next patch label: @@ -138,7 +121,7 @@ Move every remaining open issue or PR carrying the released version to the next node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/bump-stragglers.ts ``` -This is automatic post-tag housekeeping covered by the release plan and exact confirmation in Step 4. The script creates the next patch label when needed, removes the released-version label, and adds the next-version label to every open straggler. Do not run it before Step 5 verifies both the semver tag and workflow-managed `latest`. +This is automatic post-tag housekeeping covered by the release plan and exact confirmation in Step 2. The script creates the next patch label when needed, removes the released-version label, and adds the next-version label to every open straggler. Do not run it before Step 4 verifies both the semver tag and workflow-managed `latest`. Then verify the released version has no open stragglers: @@ -152,9 +135,9 @@ Summarize: - open issues/PRs bumped to ``; - any items that need manual maintainer attention. -### Step 7: Generate Announcement Data and Draft Markdown +### Step 6: Generate Release-Note Data and Draft Markdown -Collect deterministic announcement input: +Collect deterministic release-note input: ```bash npm run release:notes-data -- --plan @@ -168,21 +151,20 @@ This writes: If `notes-data.json` has `status: "partial"` or non-empty `pullRequestWarnings`, report the warnings and ask the maintainer whether to fetch/fill the missing PR metadata before drafting. -Draft announcement notes from `notes-data.json` using the style from `nemoclaw-maintainer-release-notes`. Save only Markdown, outside the checkout root: +Draft release notes from `notes-data.json` using the style from `nemoclaw-maintainer-release-notes`. Save only Markdown, outside the checkout root: ```text -/announcement-notes-draft.md +/release-note-draft.md ``` Do not create or update a GitHub Discussion. -### Step 8: Hand Off Announcement +### Step 7: Hand Off Announcement Return: - release tag, - confirmed release commit, -- release readiness summary, including docs status and docs scan delta review, - plan path and plan hash, - `cut-result.json`, `latest-result.json`, and `notes-data.json` paths, - Markdown draft path, diff --git a/.agents/skills/nemoclaw-maintainer-evening/SKILL.md b/.agents/skills/nemoclaw-maintainer-evening/SKILL.md index eaee380a805..4a2833e5486 100644 --- a/.agents/skills/nemoclaw-maintainer-evening/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-evening/SKILL.md @@ -1,12 +1,12 @@ --- name: nemoclaw-maintainer-evening -description: Runs the end-of-day maintainer handoff for NemoClaw. Checks version target progress, records stragglers for an automatic post-tag bump, completes pre-plan release readiness, and cuts the release tag. Use at the end of the workday. Trigger keywords - evening, end of day, EOD, wrap up, ship it, cut tag, handoff, done for the day. +description: Runs the end-of-day maintainer handoff for NemoClaw. Checks version target progress, records stragglers for an automatic post-tag bump, generates a QA handoff summary, and cuts the release tag. Use at the end of the workday. Trigger keywords - evening, end of day, EOD, wrap up, ship it, cut tag, handoff, done for the day. user_invocable: true --- # NemoClaw Maintainer Evening -Wrap up the day: check progress, identify stragglers, summarize for QA, complete pre-plan release readiness, cut the tag, automatically bump stragglers to the next patch, and prepare announcement notes for posting. +Wrap up the day: check progress, identify stragglers, summarize for QA, cut the tag, automatically bump stragglers to the next patch, and prepare release notes for posting. See [PR-REVIEW-PRIORITIES.md](../nemoclaw-maintainer-day/PR-REVIEW-PRIORITIES.md) for the daily cadence. @@ -30,7 +30,7 @@ gh issue list --repo NVIDIA/NemoClaw --state open --label --limit 100 List open labeled PRs and issues as the post-tag housekeeping plan. Tell the maintainer that, after the tag and workflow-managed `latest` are verified, `cut-release-tag` will automatically move all of them to the next patch label. -If an item should leave the daily release flow instead of moving forward, remove it from the released-version label before declaring release readiness. +If an item should leave the daily release flow instead of moving forward, remove it from the released-version label before asking for the release confirmation phrase. ## Step 3: Generate Handoff Summary @@ -40,44 +40,29 @@ node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer This lists commits since the last tag, identifies risky areas touched, and suggests QA test focus areas. Format the output as a concise summary the user can paste into the tag annotation or a handoff channel. -## Step 4: Complete Pre-Plan Release Readiness +## Pre-Tag Docs -Load `nemoclaw-contributor-update-docs` for the release version before generating the final release plan. -This can run while final E2E validation finishes. -The release docs PR should use the release label being prepared, such as `v0.0.73`, and should land before `release:plan` captures the frozen candidate SHA unless the maintainer explicitly records a docs waiver. +Run `/nemoclaw-contributor-update-docs for ` before loading `cut-release-tag`. +The release-prep docs PR must be merged, or explicitly waived with a reason, before `release:plan` captures the release commit. +If a docs PR or any other intended PR merges after `release:plan`, regenerate the plan before cutting the tag. -Report one of these docs statuses before continuing: +## Step 4: Cut the Tag and Publish Release Notes -- `merged`: release-prep docs landed for ``. -- `pending`: release-prep docs PR is open and must finish before the final release plan. -- `waived`: maintainer explicitly accepted tagging without pre-tag docs and gave the reason. +Load `cut-release-tag`. The version is already known — default to patch bump, but still show the commit, changelog, post-tag bump plan, and release notes draft for confirmation. NemoClaw releases are tag-based: tag `main`, let the workflow move `latest`, automatically bump remaining open issues/PRs to the next patch label, and prepare the release notes announcement for the maintainer to post. -Stop on `pending`. -When docs are `merged` or `waived`, record the docs scan SHA, the current candidate SHA, and whether the `docs_scan_sha..candidate_sha` delta has additional docs impact. -Also confirm that all required pre-tag checks are complete or explicitly waived, and that no further intended merge remains. +## Step 5: Confirm and Share -## Step 5: Freeze the Plan, Cut the Tag, and Publish Announcement Notes - -Load `cut-release-tag` only after release readiness is complete. -The version is already known. -Default to patch bump, but still show the commit, changelog, release-readiness status, post-tag bump plan, and announcement draft for confirmation. -NemoClaw releases are tag-based: tag `main`, let the workflow move `latest`, automatically bump remaining open issues/PRs to the next patch label, and prepare the release announcement for the maintainer to post. - -## Step 6: Confirm and Share - -After the tag is cut and announcement notes are drafted or posted by the maintainer, present the final summary: +After the tag is cut and release notes are drafted or posted by the maintainer, present the final summary: - **Tag**: `v0.0.8` at commit `abc1234` -- **Release docs**: merged or waived with reason -- **Readiness freeze**: docs scan SHA, candidate SHA, and delta review status -- **Announcement draft**: `../nemoclaw-release-v0.0.8/announcement-notes-draft.md` +- **Release notes draft**: `../nemoclaw-release-v0.0.8/release-note-draft.md` - **Shipped**: 4 items (#1234, #1235, #1236, #1237) - **Bumped to v0.0.9**: 1 item (#1238 — still needs CI fix) - **QA focus areas**: installer changes, new onboard preset This summary can be shared in the team's handoff channel. -## Step 7: Update State +## Step 6: Update State ```bash node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer-day/scripts/state.ts history "tag-cut" "" "shipped N items, bumped M" @@ -85,9 +70,7 @@ node --experimental-strip-types --no-warnings .agents/skills/nemoclaw-maintainer ## Notes -- Never cut a tag or hand off announcement notes without user confirmation. -- Never generate the final release plan until release-prep docs are merged or explicitly waived and no further intended merge remains. -- If any merge lands after plan generation, return to Step 4, re-check readiness, and generate a fresh plan. +- Never cut a tag or hand off release notes without user confirmation. - If nothing was labeled or nothing shipped, ask whether to skip the tag today. - A PR version label activates release work; it is not a readiness claim. - If an open item misses the tag, post-tag housekeeping moves its target to the next patch version. diff --git a/.agents/skills/nemoclaw-maintainer-policies/references/release-train.md b/.agents/skills/nemoclaw-maintainer-policies/references/release-train.md index 2007595ac65..3b83dc9c52b 100644 --- a/.agents/skills/nemoclaw-maintainer-policies/references/release-train.md +++ b/.agents/skills/nemoclaw-maintainer-policies/references/release-train.md @@ -17,21 +17,11 @@ Daily release labels coordinate release work. They do not classify issues and th - A PR or issue leaves the daily release cycle only when its version label is removed without a replacement. - Version labels are pruned after seven days only after durable release history is preserved and no open PR still carries or depends on the old label. -## Release Lifecycle +## Release-Prep Docs -NemoClaw uses this release sequence: - -```text -prepare -> declare ready -> freeze/plan -> tag candidate -> validate -> promote lkg -``` - -The semver tag publishes the release candidate, including public docs and release artifacts. -Release-prep docs therefore gate the semver tag. -Exact-tag E2E and QA validation gate `lkg` promotion unless maintainers explicitly choose a different release model. - -The release plan is the commit-freeze boundary. -All mutable release readiness work must finish before `release:plan` captures the final `origin/main` SHA. -Any merge after plan generation invalidates the plan and requires maintainers to re-check readiness against the new candidate SHA before generating a fresh plan. +Run `/nemoclaw-contributor-update-docs for vX.Y.Z` before generating the final release plan for `vX.Y.Z`. +Release-prep docs must be merged or explicitly waived before `release:plan` captures the release commit. +If any merge lands after `release:plan`, generate a fresh plan before cutting the tag. ## Cutoff @@ -42,23 +32,9 @@ At cutoff: 1. List merged PRs carrying the target version label. 2. Confirm each is intended for the release. 3. List open PRs and issues still carrying the target label as post-tag stragglers. -4. Merge release-prep docs, or record a maintainer waiver with the reason. -5. Record the SHA through which docs were scanned and review any `docs_scan_sha..candidate_sha` delta for additional docs impact. -6. Finish or explicitly waive every pre-tag check required for the release. -7. Confirm that no further intended merge remains. -8. Generate the final release plan for the current `origin/main` SHA. -9. Cut the release tag only with explicit maintainer confirmation from the final plan. -10. After the tag and workflow-managed `latest` are verified, automatically move every open straggler to the next patch label. - -Release readiness is complete only when the maintainer can report: - -- the cutoff inventory and post-tag straggler plan; -- release-prep docs status, either merged with PR and merge SHA or waived with reason; -- docs scan SHA and candidate SHA delta review; -- pre-tag check status, including waivers and reasons; -- confirmation that no further intended merge remains before plan generation. - -If release-prep docs are still pending, stop before generating the release plan. +4. Generate QA handoff from merged PRs. +5. Cut the release tag only with explicit maintainer confirmation. +6. After the tag and workflow-managed `latest` are verified, automatically move every open straggler to the next patch label. ## Carry Forward diff --git a/.agents/skills/nemoclaw-maintainer-release-notes/SKILL.md b/.agents/skills/nemoclaw-maintainer-release-notes/SKILL.md index 97f9cb72be9..c25c3f436e3 100644 --- a/.agents/skills/nemoclaw-maintainer-release-notes/SKILL.md +++ b/.agents/skills/nemoclaw-maintainer-release-notes/SKILL.md @@ -148,7 +148,7 @@ Keep the prose warm and polished, but concrete. Tie the narrative to actual PRs Create a Markdown draft outside the checkout root so the repo stays clean, for example: ```bash -../nemoclaw--announcement-notes-draft.md +../nemoclaw--release-note-draft.md ``` The Markdown body is the source the maintainer can paste into GitHub Discussions. diff --git a/test/maintainer-skills-policy.test.ts b/test/maintainer-skills-policy.test.ts index 3c9b6a04d21..79bd0938d5d 100644 --- a/test/maintainer-skills-policy.test.ts +++ b/test/maintainer-skills-policy.test.ts @@ -75,7 +75,7 @@ describe("maintainer skills follow canonical workflow policy", () => { expect(evening).toContain("automatically bump stragglers to the next patch"); expect(release).toContain("scripts/bump-stragglers.ts"); - expect(release).toContain("Do not run it before Step 5"); + expect(release).toContain("Do not run it before Step 4"); expect(morning).toContain("post-tag housekeeping was interrupted"); expect(priorities).toContain("automatically bump stragglers to the next patch"); expect(policy).toContain("automatically move every open straggler to the next patch label"); @@ -86,30 +86,21 @@ describe("maintainer skills follow canonical workflow policy", () => { ).toBe(true); }); - it("freezes the release plan only after mutable readiness is complete", () => { + it("runs release-prep docs before generating the final release plan", () => { + const updateDocs = read(".agents/skills/nemoclaw-contributor-update-docs/SKILL.md"); const evening = read(".agents/skills/nemoclaw-maintainer-evening/SKILL.md"); const release = read(".agents/skills/nemoclaw-maintainer-cut-release-tag/SKILL.md"); const policy = read(".agents/skills/nemoclaw-maintainer-policies/references/release-train.md"); - expect(policy).toContain( - "prepare -> declare ready -> freeze/plan -> tag candidate -> validate -> promote lkg", - ); - expect(policy).toContain("The release plan is the commit-freeze boundary."); - expect(policy).toContain( - "If release-prep docs are still pending, stop before generating the release plan.", - ); - expect(evening.indexOf("Load `nemoclaw-contributor-update-docs`")).toBeLessThan( + expect(updateDocs).toContain("/nemoclaw-contributor-update-docs for vX.Y.Z"); + expect(evening.indexOf("/nemoclaw-contributor-update-docs for ")).toBeLessThan( evening.indexOf("Load `cut-release-tag`"), ); - expect(evening).toContain("Stop on `pending`."); - expect(release).toContain( - "Do not generate the release plan until release readiness is complete", - ); - expect(release).toContain("Any merge after plan generation invalidates the plan"); expect(release).toContain( - "If release-prep docs are `pending`, stop before generating the release plan.", + "Do not generate the release plan until release-prep docs are merged or explicitly waived.", ); - expect(release).not.toContain("/nemoclaw-contributor-update-docs"); + expect(policy).toContain("Run `/nemoclaw-contributor-update-docs for vX.Y.Z`"); + expect(policy).toContain("If any merge lands after `release:plan`, generate a fresh plan"); }); it("keeps cross-issue sweeping separate from comparator scoring", () => {