What to build
The repo's release invariant is "nobody tags a release — CI does, only after the gem is live" (RELEASE.md:14-30; CLAUDE.md:101 says never re-add a tag trigger). Two Rake entry points contradict it:
- Rakefile:3
require 'bundler/gem_tasks' defines Bundler's release task, whose prerequisites are build, release:guard_clean, release:source_control_push (creates and pushes the v<version> git tag) and release:rubygem_push (pushes with a local API key). Running it from a checkout cuts a tag from a laptop before any gem exists on RubyGems — exactly the gem-less-tag failure RELEASE.md:102-127 documents. CLAUDE.md:33 still advertises it as the release command: "Release | bin/rake release (Vite build → vendor/assets/ → gem build → push)".
- Rakefile:240-241
task full: ['frontend:build', 'build', 'push'] (documented at RELEASE.md:179-184 as the maintainers' fallback). It skips release:check and release:package entirely, and its third prerequisite push is not defined anywhere: grep -n "task.*push" Rakefile finds nothing, and bundler/gem_tasks defines build, install, install:local, release and release:* — no bare push. bundle exec rake release:full therefore aborts with "Don't know how to build task 'push'". A documented fallback that cannot execute is worse than none.
Fix:
- Keep
build and install from bundler/gem_tasks but neutralise release: after the require, Rake::Task['release'].clear and redefine task :release to abort with a one-line message pointing at RELEASE.md ("releases are cut by CI from a lib/wurk/version.rb bump; see RELEASE.md"). Do the same for release:source_control_push and release:rubygem_push so nothing can tag or push from a checkout.
- Delete
release:full (Rakefile:240-241). If a local emergency push is still wanted, the existing bin/gem-build + bin/gem-push pair already does it and bin/gem-push at least requires a built .gem; make bin/gem-push run bundle exec rake release:check before pushing so the fallback goes through the same gate.
- CLAUDE.md:33: replace the row with "Release | bump
lib/wurk/version.rb + CHANGELOG, merge to main; CI publishes and tags (RELEASE.md)".
- RELEASE.md:179-184: rewrite the fallback section to name
bin/gem-build / bin/gem-push and state that the gate runs first.
- Add a unit test (test/unit/release_helpers_test.rb or a new test/unit/rakefile_release_test.rb that loads the Rakefile in a subprocess) asserting
rake release exits non-zero with the redirect message and that no task named release:full exists.
Acceptance criteria
Affected paths
Rakefile, bin/gem-push, CLAUDE.md, RELEASE.md, test/unit/release_helpers_test.rb (or a new test/unit/rakefile_release_test.rb)
Verified against
c346bc9
What to build
The repo's release invariant is "nobody tags a release — CI does, only after the gem is live" (RELEASE.md:14-30; CLAUDE.md:101 says never re-add a tag trigger). Two Rake entry points contradict it:
require 'bundler/gem_tasks'defines Bundler'sreleasetask, whose prerequisites arebuild,release:guard_clean,release:source_control_push(creates and pushes thev<version>git tag) andrelease:rubygem_push(pushes with a local API key). Running it from a checkout cuts a tag from a laptop before any gem exists on RubyGems — exactly the gem-less-tag failure RELEASE.md:102-127 documents. CLAUDE.md:33 still advertises it as the release command: "Release |bin/rake release(Vite build →vendor/assets/→ gem build → push)".task full: ['frontend:build', 'build', 'push'](documented at RELEASE.md:179-184 as the maintainers' fallback). It skipsrelease:checkandrelease:packageentirely, and its third prerequisitepushis not defined anywhere:grep -n "task.*push" Rakefilefinds nothing, and bundler/gem_tasks definesbuild,install,install:local,releaseandrelease:*— no barepush.bundle exec rake release:fulltherefore aborts with "Don't know how to build task 'push'". A documented fallback that cannot execute is worse than none.Fix:
buildandinstallfrom bundler/gem_tasks but neutraliserelease: after therequire,Rake::Task['release'].clearand redefinetask :releaseto abort with a one-line message pointing at RELEASE.md ("releases are cut by CI from a lib/wurk/version.rb bump; see RELEASE.md"). Do the same forrelease:source_control_pushandrelease:rubygem_pushso nothing can tag or push from a checkout.release:full(Rakefile:240-241). If a local emergency push is still wanted, the existingbin/gem-build+bin/gem-pushpair already does it andbin/gem-pushat least requires a built.gem; makebin/gem-pushrunbundle exec rake release:checkbefore pushing so the fallback goes through the same gate.lib/wurk/version.rb+ CHANGELOG, merge to main; CI publishes and tags (RELEASE.md)".bin/gem-build/bin/gem-pushand state that the gate runs first.rake releaseexits non-zero with the redirect message and that no task namedrelease:fullexists.Acceptance criteria
bundle exec rake releaseexits non-zero without creating a tag or touching RubyGems, and its message names RELEASE.md.bundle exec rake -T | grep releaselistsrelease:checkandrelease:packageonly (plus the abortingrelease).bin/gem-pushrunsrelease:checkbeforegem push.releasetask.Affected paths
Rakefile, bin/gem-push, CLAUDE.md, RELEASE.md, test/unit/release_helpers_test.rb (or a new test/unit/rakefile_release_test.rb)
Verified against
c346bc9