diff --git a/.agents/skills/merge-and-release/SKILL.md b/.agents/skills/merge-and-release/SKILL.md index bc979dca..f175e5ba 100644 --- a/.agents/skills/merge-and-release/SKILL.md +++ b/.agents/skills/merge-and-release/SKILL.md @@ -100,11 +100,22 @@ skill covers all of it, scoped down by what the maintainer actually asks for. report a timeout separately from a completed run's own conclusion, the tag or version it produced. A run that fails, times out, or never starts is reported, never silently retried. 7. In the hub, when the chosen scope includes a release, bring this checkout to the merged - content: `git fetch origin main`, then `git checkout -B main origin/main` to force the local - `main` to the fetched tip regardless of what it pointed to before. `skills_install.py` stamps - and installs from whatever this checkout's HEAD already is, so a plain `git checkout main` - would leave a local `main` that already existed pointing at its old, pre-fetch commit, and - skip the refresh silently. Only then run `python3 scripts/skills_install.py --report`, then + content without discarding or mixing in anything local. First assert `git status --porcelain` + is empty, and stop and report rather than proceeding over any uncommitted content, tracked or + not, since `skills_install.py` installs from whatever ends up on disk and a leftover local file + would ride along into the install silently. Then `git fetch origin main`, `git checkout main` + (or `git checkout -b main origin/main` the first time this checkout carries no local `main` at + all, `checkout` rather than `switch` since the fleet's own `git` floor is undeclared and + `checkout` needs no minimum version for this), and `git merge --ff-only origin/main`. + `checkout` still refuses a `main` checked out in another worktree, and `--ff-only` refuses + anything but a clean fast-forward, so either stops and reports on top of what the preflight + already ruled out, per Repository Boundaries and Write Safety. `--ff-only` does not fail when + local `main` is already ahead of `origin/main`, since a strict superset needs no fast-forward + and reports up to date, so assert `git rev-parse main` equals `git rev-parse origin/main` + afterward and stop and report on a mismatch, a local-only commit this checkout never pushed is + exactly the case a bare "up to date" would hide. `skills_install.py` stamps and installs from + whatever this checkout's HEAD already is, so running it against a stale, unrefreshed, or + locally-diverged `main` skips the refresh silently. Only then run `python3 scripts/skills_install.py --report`, then `python3 scripts/skills_install.py` to install, and confirm `--report` now reads current, regardless of whether step 5 or 6 dispatched, skipped, or failed a release, this step is gated only on the chosen scope, never on the release outcome. This refreshes only the machine running diff --git a/.claude-plugin/fleet-skills/.source-digest b/.claude-plugin/fleet-skills/.source-digest index 687e0260..6db97af8 100644 --- a/.claude-plugin/fleet-skills/.source-digest +++ b/.claude-plugin/fleet-skills/.source-digest @@ -1 +1 @@ -c766251ed9f8b42d +4259e0af969b1580 diff --git a/.claude-plugin/fleet-skills/skills/merge-and-release/SKILL.md b/.claude-plugin/fleet-skills/skills/merge-and-release/SKILL.md index bc979dca..f175e5ba 100644 --- a/.claude-plugin/fleet-skills/skills/merge-and-release/SKILL.md +++ b/.claude-plugin/fleet-skills/skills/merge-and-release/SKILL.md @@ -100,11 +100,22 @@ skill covers all of it, scoped down by what the maintainer actually asks for. report a timeout separately from a completed run's own conclusion, the tag or version it produced. A run that fails, times out, or never starts is reported, never silently retried. 7. In the hub, when the chosen scope includes a release, bring this checkout to the merged - content: `git fetch origin main`, then `git checkout -B main origin/main` to force the local - `main` to the fetched tip regardless of what it pointed to before. `skills_install.py` stamps - and installs from whatever this checkout's HEAD already is, so a plain `git checkout main` - would leave a local `main` that already existed pointing at its old, pre-fetch commit, and - skip the refresh silently. Only then run `python3 scripts/skills_install.py --report`, then + content without discarding or mixing in anything local. First assert `git status --porcelain` + is empty, and stop and report rather than proceeding over any uncommitted content, tracked or + not, since `skills_install.py` installs from whatever ends up on disk and a leftover local file + would ride along into the install silently. Then `git fetch origin main`, `git checkout main` + (or `git checkout -b main origin/main` the first time this checkout carries no local `main` at + all, `checkout` rather than `switch` since the fleet's own `git` floor is undeclared and + `checkout` needs no minimum version for this), and `git merge --ff-only origin/main`. + `checkout` still refuses a `main` checked out in another worktree, and `--ff-only` refuses + anything but a clean fast-forward, so either stops and reports on top of what the preflight + already ruled out, per Repository Boundaries and Write Safety. `--ff-only` does not fail when + local `main` is already ahead of `origin/main`, since a strict superset needs no fast-forward + and reports up to date, so assert `git rev-parse main` equals `git rev-parse origin/main` + afterward and stop and report on a mismatch, a local-only commit this checkout never pushed is + exactly the case a bare "up to date" would hide. `skills_install.py` stamps and installs from + whatever this checkout's HEAD already is, so running it against a stale, unrefreshed, or + locally-diverged `main` skips the refresh silently. Only then run `python3 scripts/skills_install.py --report`, then `python3 scripts/skills_install.py` to install, and confirm `--report` now reads current, regardless of whether step 5 or 6 dispatched, skipped, or failed a release, this step is gated only on the chosen scope, never on the release outcome. This refreshes only the machine running diff --git a/.github/skills/merge-and-release/SKILL.md b/.github/skills/merge-and-release/SKILL.md index bc979dca..f175e5ba 100644 --- a/.github/skills/merge-and-release/SKILL.md +++ b/.github/skills/merge-and-release/SKILL.md @@ -100,11 +100,22 @@ skill covers all of it, scoped down by what the maintainer actually asks for. report a timeout separately from a completed run's own conclusion, the tag or version it produced. A run that fails, times out, or never starts is reported, never silently retried. 7. In the hub, when the chosen scope includes a release, bring this checkout to the merged - content: `git fetch origin main`, then `git checkout -B main origin/main` to force the local - `main` to the fetched tip regardless of what it pointed to before. `skills_install.py` stamps - and installs from whatever this checkout's HEAD already is, so a plain `git checkout main` - would leave a local `main` that already existed pointing at its old, pre-fetch commit, and - skip the refresh silently. Only then run `python3 scripts/skills_install.py --report`, then + content without discarding or mixing in anything local. First assert `git status --porcelain` + is empty, and stop and report rather than proceeding over any uncommitted content, tracked or + not, since `skills_install.py` installs from whatever ends up on disk and a leftover local file + would ride along into the install silently. Then `git fetch origin main`, `git checkout main` + (or `git checkout -b main origin/main` the first time this checkout carries no local `main` at + all, `checkout` rather than `switch` since the fleet's own `git` floor is undeclared and + `checkout` needs no minimum version for this), and `git merge --ff-only origin/main`. + `checkout` still refuses a `main` checked out in another worktree, and `--ff-only` refuses + anything but a clean fast-forward, so either stops and reports on top of what the preflight + already ruled out, per Repository Boundaries and Write Safety. `--ff-only` does not fail when + local `main` is already ahead of `origin/main`, since a strict superset needs no fast-forward + and reports up to date, so assert `git rev-parse main` equals `git rev-parse origin/main` + afterward and stop and report on a mismatch, a local-only commit this checkout never pushed is + exactly the case a bare "up to date" would hide. `skills_install.py` stamps and installs from + whatever this checkout's HEAD already is, so running it against a stale, unrefreshed, or + locally-diverged `main` skips the refresh silently. Only then run `python3 scripts/skills_install.py --report`, then `python3 scripts/skills_install.py` to install, and confirm `--report` now reads current, regardless of whether step 5 or 6 dispatched, skipped, or failed a release, this step is gated only on the chosen scope, never on the release outcome. This refreshes only the machine running