The target toggle (turning a target on or off) saves the whole target row. If an edit of the same target is saved at the same moment, the toggle can write the old name and settings back over the edit, and the edit is lost although it reported success. Once #418 lands, the same race can also leave a database target's archive file named for the new name while the old name is stored, so the next delivery after a restart starts a second archive.
Found in the rework of #418, which closed the same race for the webhook edit, the target edit and target creation with one lock in the handlers.
Definition of done
The toggle changes only the target's on/off state in the database, so it cannot write back any other field, or it takes the same lock as the target edit.
A test shows a toggle cannot undo an edit of the same target's name or settings.
Nothing else changes.
Model: opus-5-5
The target toggle (turning a target on or off) saves the whole target row. If an edit of the same target is saved at the same moment, the toggle can write the old name and settings back over the edit, and the edit is lost although it reported success. Once https://git.eeqj.de/sneak/webhooker/pulls/418 lands, the same race can also leave a database target's archive file named for the new name while the old name is stored, so the next delivery after a restart starts a second archive.
Found in the rework of https://git.eeqj.de/sneak/webhooker/pulls/418, which closed the same race for the webhook edit, the target edit and target creation with one lock in the handlers.
## Definition of done
- The toggle changes only the target's on/off state in the database, so it cannot write back any other field, or it takes the same lock as the target edit.
- A test shows a toggle cannot undo an edit of the same target's name or settings.
- Nothing else changes.
Model: opus-5-5
Plan. HandleTargetToggle in internal/handlers/source_management.go loads the target, flips Active and saves the whole row. Make it update only the active column, so a toggle can no longer write back the name or settings an edit saved meanwhile; it then needs no lock. HandleEntrypointToggle has the same shape: change it the same way if an entrypoint has any field an edit can change. A test loads the target as the toggle would, saves an edit of its name and settings, then lets the toggle finish, and shows the edit survives and the state flipped. Nothing else changes.
Model: opus-5-5
Plan. `HandleTargetToggle` in `internal/handlers/source_management.go` loads the target, flips `Active` and saves the whole row. Make it update only the `active` column, so a toggle can no longer write back the name or settings an edit saved meanwhile; it then needs no lock. `HandleEntrypointToggle` has the same shape: change it the same way if an entrypoint has any field an edit can change. A test loads the target as the toggle would, saves an edit of its name and settings, then lets the toggle finish, and shows the edit survives and the state flipped. Nothing else changes.
Model: opus-5-5
Opened #437. The target toggle now changes only the target's on/off state, so it can no longer write an older name or settings back over an edit. The new test saves an edit just after the toggle has read the target and checks that the edit survives. The entrypoint toggle is unchanged because an entrypoint has no edit form.
Judgement call: the target edit still saves the whole row, so an edit can still undo a toggle that lands between the edit's read and its save. That is outside this issue.
Model: opus-5-5
Opened https://git.eeqj.de/sneak/webhooker/pulls/437. The target toggle now changes only the target's on/off state, so it can no longer write an older name or settings back over an edit. The new test saves an edit just after the toggle has read the target and checks that the edit survives. The entrypoint toggle is unchanged because an entrypoint has no edit form.
Judgement call: the target edit still saves the whole row, so an edit can still undo a toggle that lands between the edit's read and its save. That is outside this issue.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
The target toggle (turning a target on or off) saves the whole target row. If an edit of the same target is saved at the same moment, the toggle can write the old name and settings back over the edit, and the edit is lost although it reported success. Once #418 lands, the same race can also leave a database target's archive file named for the new name while the old name is stored, so the next delivery after a restart starts a second archive.
Found in the rework of #418, which closed the same race for the webhook edit, the target edit and target creation with one lock in the handlers.
Definition of done
Model: opus-5-5
Plan.
HandleTargetToggleininternal/handlers/source_management.goloads the target, flipsActiveand saves the whole row. Make it update only theactivecolumn, so a toggle can no longer write back the name or settings an edit saved meanwhile; it then needs no lock.HandleEntrypointTogglehas the same shape: change it the same way if an entrypoint has any field an edit can change. A test loads the target as the toggle would, saves an edit of its name and settings, then lets the toggle finish, and shows the edit survives and the state flipped. Nothing else changes.Model: opus-5-5
Opened #437. The target toggle now changes only the target's on/off state, so it can no longer write an older name or settings back over an edit. The new test saves an edit just after the toggle has read the target and checks that the edit survives. The entrypoint toggle is unchanged because an entrypoint has no edit form.
Judgement call: the target edit still saves the whole row, so an edit can still undo a toggle that lands between the edit's read and its save. That is outside this issue.
Model: opus-5-5