## TL;DR
Check whether the release already exists before creating it, and serialize publishes so two runs cannot race. The agent published twice because creating was unconditional. An existence check turns the second publish into a no-op or an update.

```text
docs agent failed: double-published the same release notes
```

## Steps
1. Confirm the duplicate: list releases (`gh release list` or your forge's release page) and look for two entries with the same tag or version. Note which one is the duplicate.
2. Remove the duplicate: delete the extra release (keeping the tag if the tag itself is correct) or merge its notes into the surviving release. Expected: exactly one release per version.
3. Add the existence check to the agent: before publishing, the agent looks up the tag/version; if it exists, it updates the existing release in place instead of creating a new one. Expected: a rerun of the same publish step reports "already exists" and changes nothing.
4. Serialize the publish step: give the agent's release job a concurrency limit of one (a lock file, a CI concurrency group, or a single publisher run at a time). Expected: two overlapping runs can no longer both pass the existence check and both publish.
5. Rerun the publish flow end to end on a test version and confirm only one release appears. Expected: one release, one set of notes.

## Use this when
- the same release notes appear twice for one version
- an agent publish step is not safe to rerun
- two agent runs can overlap on release day

## Not for this skill when
- the notes are wrong but published once (content bug)
- duplicates were created by hand
- you publish separate notes per platform on purpose

## Variant phrasings
- release notes published twice for the same version
- duplicate release created by agent
- agent published the changelog entry two times

## Why it happens
The publish step was "create release" with no read-before-write, so reruns, retries after a timeout, and overlapping scheduled runs each created a fresh release. The API happily accepts duplicates because nothing told it the version already existed.

## Edge cases
- Deleting a release usually keeps the git tag: delete or move the tag too if the duplicate created one.
- A retry that timed out may have actually succeeded: always check existence before retrying any publish.
- Draft releases do not notify but still count as duplicates: include drafts in the existence check.
- If the two duplicates have different notes, merge the content before deleting one.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_Y-47Ou0eb7v12226646VHA
