Renaming or editing a Sieve rule moved it to the bottom of the list. Order is evaluation order in Sieve, so this quietly changed which rule filed a message, and with ~25 rules and only up/down buttons, putting it back cost a click per place.
Two things caused it:
saveAndApply always appended the rule it was handed ([...existing.filter(≠id), r]). That is right for a rule created from a message, wrong for one being edited.
RuleDialog defaulted the "Also apply to existing messages" tick to on wherever the dialog offered it, so every edit in Settings → Filters took that path — including a plain rename. The unticked path already replaced in place correctly, which is why this only bit some of the time.
Changes:
New upsertRule(rules, rule) in lib/sieve.ts — replaces by id in place, appends only what is new. Used by both saveAndApply and the settings editor, which had its own copy of the same logic.
The tick now defaults to on only in "Filter messages like this…", where applying the rule is the point of the dialog; elsewhere it starts off. That also stops an unrelated rename from re-running a filter over the whole Inbox.
The success toast no longer calls an edited rule "created".
Not addressed here: the same issue asks for drag & drop reordering. That is an enhancement rather than the bug, so it is left for its own change.
Tested: npm run typecheck, npm test (182 web + 88 server, all passing) — including a new case covering that an edited rule keeps its index and a new one lands at the end.
Fixes #24.
Renaming or editing a Sieve rule moved it to the bottom of the list. Order is evaluation order in Sieve, so this quietly changed which rule filed a message, and with ~25 rules and only up/down buttons, putting it back cost a click per place.
Two things caused it:
- `saveAndApply` always appended the rule it was handed (`[...existing.filter(≠id), r]`). That is right for a rule created from a message, wrong for one being edited.
- `RuleDialog` defaulted the "Also apply to existing messages" tick to on wherever the dialog offered it, so every edit in Settings → Filters took that path — including a plain rename. The unticked path already replaced in place correctly, which is why this only bit some of the time.
Changes:
- New `upsertRule(rules, rule)` in `lib/sieve.ts` — replaces by id in place, appends only what is new. Used by both `saveAndApply` and the settings editor, which had its own copy of the same logic.
- The tick now defaults to on only in "Filter messages like this…", where applying the rule is the point of the dialog; elsewhere it starts off. That also stops an unrelated rename from re-running a filter over the whole Inbox.
- The success toast no longer calls an edited rule "created".
Not addressed here: the same issue asks for drag & drop reordering. That is an enhancement rather than the bug, so it is left for its own change.
Tested: `npm run typecheck`, `npm test` (182 web + 88 server, all passing) — including a new case covering that an edited rule keeps its index and a new one lands at the end.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
**Merged** 2026-08-25 as coffey-labs/ihasmail@9a8c7516d715
<sub>Rebuilt from: git history, session transcript.</sub>
This repo is archived. You cannot comment on issues.
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.
Fixes #24.
Renaming or editing a Sieve rule moved it to the bottom of the list. Order is evaluation order in Sieve, so this quietly changed which rule filed a message, and with ~25 rules and only up/down buttons, putting it back cost a click per place.
Two things caused it:
saveAndApplyalways appended the rule it was handed ([...existing.filter(≠id), r]). That is right for a rule created from a message, wrong for one being edited.RuleDialogdefaulted the "Also apply to existing messages" tick to on wherever the dialog offered it, so every edit in Settings → Filters took that path — including a plain rename. The unticked path already replaced in place correctly, which is why this only bit some of the time.Changes:
upsertRule(rules, rule)inlib/sieve.ts— replaces by id in place, appends only what is new. Used by bothsaveAndApplyand the settings editor, which had its own copy of the same logic.Not addressed here: the same issue asks for drag & drop reordering. That is an enhancement rather than the bug, so it is left for its own change.
Tested:
npm run typecheck,npm test(182 web + 88 server, all passing) — including a new case covering that an edited rule keeps its index and a new one lands at the end.🤖 Generated with Claude Code
Merged 2026-08-25 as coffey-labs/ihasmail@9a8c7516d7
Rebuilt from: git history, session transcript.