Three defects in release-plugin.mjs measured live by llm-security S4 during the
v8.1.0 release (order 20260922T185613Z-5930828122-from-.claude):
1. The header/token comments claimed the tag-push and catalog-push "share ONE
token" without qualifying the scope, which read as spanning a whole release
however many separate invocations it took. The push-approval token is
actually scoped to ONE script invocation (createPushGate consumes it as
soon as that run's first push succeeds) — chosen over making the token
survive across separate processes, since a persisted cross-invocation
authorisation is exactly the kind of standing grant the one-shot design
exists to avoid. Comments and the operator-facing BLOCKED message now say
this, and recommend the combined `--create-tag --write --commit --push`
as the one-token-one-release path.
2. `--write --commit` run after an earlier `--write`-only invocation reported
NOOP and committed nothing: a fresh process re-reads marketplace.json off
disk, sees the target ref already written (but uncommitted) by the prior
run, and planRelease — which has no git access — cannot tell that apart
from an already-released catalog.
3. NOOP returned before ever checking --push, so a pending write could also
never be pushed by a follow-up invocation.
Fixed by pendingCatalogChanges(), which checks the working tree for the
plugin's catalog files; a NOOP verdict with --commit requested against a
dirty tree now finishes the release (commit, push, Forgejo release object)
via a shared finishPublish() instead of silently reporting "nothing to do".
A genuinely clean NOOP is unchanged (still exits early, still never touches
the push gate).
Also isolates release-plugin.test.mjs's temp git fixtures from the
machine-global pre-push hook (installed today, order 20260918T004628Z, live
during this session) via a repo-local core.hooksPath override — those tests
exercise this script's own token/NOOP/push logic, not that unrelated global
CHANGELOG policy, and R-FJ1 specifically needs the tag-message fallback path
a real CHANGELOG.md would short-circuit.
TDD: BUG 2 and BUG 3 were written RED against the unmodified script (real
git temp repos, two-invocation traces reproducing the measured scenario)
before the fix; full suite 217/217, check-versions 0 ERROR (1 pre-existing
WARN on llm-security's in-flight, unrelated v8.1.1 bump).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>