Align tag-name matching case sensitivity with bDS2 in post updates #92

Closed
opened 2026-07-20 19:44:03 +00:00 by hugo · 2 comments
Owner

Source: Audit section 3 (edge case).

Context: Tag names are case-insensitively unique per project (tags_project_name_idx + engine checks). When removing/renaming/merging tags inside posts' tag arrays, RuDS matches case-insensitively (crates/bds-core/src/engine/tag.rs rename_tag/merge_tags/delete_tag use eq_ignore_ascii_case), while bDS2 matches exactly (../bDS2/lib/bds/tags.ex delete_tag ~line 156 &(&1 == tag.name) and equivalents). If posts contain a differently-cased variant of a tag (possible via file edits + rebuild), RuDS rewrites it, bDS2 leaves it.

Task: Small decision + alignment: match bDS2's exact matching, or keep case-insensitive as deliberately more robust and note it in specs/tag.allium (RenameTag/DeleteTag/MergeTags rules). Also note eq_ignore_ascii_case doesn't fold non-ASCII (ä/Ä) — if keeping case-insensitive, use a proper Unicode-aware fold consistent with the uniqueness check. Add a test with a mixed-case tag in a post.

Acceptance: Documented, consistent behaviour with a test; spec updated + allium validated if semantics chosen differ from bDS2.

**Source:** Audit section 3 (edge case). **Context:** Tag names are case-insensitively unique per project (tags_project_name_idx + engine checks). When removing/renaming/merging tags inside posts' tag arrays, RuDS matches case-insensitively (`crates/bds-core/src/engine/tag.rs` rename_tag/merge_tags/delete_tag use `eq_ignore_ascii_case`), while bDS2 matches exactly (`../bDS2/lib/bds/tags.ex` delete_tag ~line 156 `&(&1 == tag.name)` and equivalents). If posts contain a differently-cased variant of a tag (possible via file edits + rebuild), RuDS rewrites it, bDS2 leaves it. **Task:** Small decision + alignment: match bDS2's exact matching, or keep case-insensitive as deliberately more robust and note it in `specs/tag.allium` (RenameTag/DeleteTag/MergeTags rules). Also note `eq_ignore_ascii_case` doesn't fold non-ASCII (ä/Ä) — if keeping case-insensitive, use a proper Unicode-aware fold consistent with the uniqueness check. Add a test with a mixed-case tag in a post. **Acceptance:** Documented, consistent behaviour with a test; spec updated + `allium` validated if semantics chosen differ from bDS2.
hugo added the bug label 2026-07-20 19:44:03 +00:00
Author
Owner

decision by the designer: you must follow exact bDS2 behaviour on this topic. also follow proper unicode aware fold operations.

decision by the designer: you must follow exact bDS2 behaviour on this topic. also follow proper unicode aware fold operations.
Author
Owner

Implemented in 3051331. Tag rename, merge, and delete now mutate portable post tag arrays using exact string equality, matching bDS2's json_each queries/replace_tag/merge_post_tags helpers and Allium's exact set-membership semantics. Case-insensitive behavior remains only for tag entity uniqueness and lookup. Added explicit code documentation and a regression exercising all three mutations with mixed-case variants: rename preserves Rust while replacing rust, merge preserves SOURCE/Target while replacing source and adding exact target, and delete preserves DELETE while removing delete. Neutral review checked every former eq_ignore_ascii_case call in the mutation paths against bDS2 and specs/tag.allium; no spec change was needed because the existing set operations are already exact. Verified with cargo clippy --workspace --all-targets -- -D warnings, cargo build --workspace, and cargo test --workspace (533 core tests passed, 1 explicitly ignored; all workspace tests passed).

Implemented in 3051331. Tag rename, merge, and delete now mutate portable post tag arrays using exact string equality, matching bDS2's json_each queries/replace_tag/merge_post_tags helpers and Allium's exact set-membership semantics. Case-insensitive behavior remains only for tag entity uniqueness and lookup. Added explicit code documentation and a regression exercising all three mutations with mixed-case variants: rename preserves Rust while replacing rust, merge preserves SOURCE/Target while replacing source and adding exact target, and delete preserves DELETE while removing delete. Neutral review checked every former eq_ignore_ascii_case call in the mutation paths against bDS2 and specs/tag.allium; no spec change was needed because the existing set operations are already exact. Verified with cargo clippy --workspace --all-targets -- -D warnings, cargo build --workspace, and cargo test --workspace (533 core tests passed, 1 explicitly ignored; all workspace tests passed).
hugo closed this issue 2026-07-22 16:59:00 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: hugo/RuDS#92