Before, the companion held two tables that had already drifted:
roleOf's attribute when-ladder (\Sent→SENT, \Drafts→DRAFTS, \Junk→SPAM, \Trash→TRASH, \Archive→ARCHIVE), and
a separate SPECIAL_USE_ATTRIBUTES set for isServerSpecial that also listed \All and \Flagged — attributes with no role branch, so the two disagreed (e.g. a localized Gmail "All Mail" advertising \All was server-special yet classified NORMAL).
Both now read from one ordered ATTRIBUTE_ROLES: Map<String, FolderRole?> (a null value = server-special but role-less):
roleOf = first role-bearing entry the folder advertises (insertion order preserves the old ladder's precedence),
isServerSpecial = the folder advertises any key.
Behavior-preserving: every existing attribute keeps its exact (role, specialUse). PR #113's fidelity tests stay green.
Adds "\important" to null as one more role-less special-use key. Gmail advertises \Important on [Gmail]/Important; it's now recognized as server-provisioned, so the drawer de-dup renders Important - Gmail instead of leaking the raw Important ([Gmail]) namespace form.
Migration
None. The addition is purely additive — no (role, specialUse) mapping changed for any existing attribute, and specialUse remains a plain Boolean column re-derived from the server LIST response on the next folder refresh. No specialUse encoding change, so no Room migration.
Tests
FolderRoleTest: \Important in the isServerSpecial cases; a comprehensive table assertion pinning every attribute's (role, specialUse) incl. \Important; a table-order precedence guard; and a role-less-fallback guard (\All/\Important don't suppress the display-name role).
FolderMapperTest: extends the #64 role-less family (\All, \Flagged) with \Important at the FetchedFolder.toEntity mapper level.
Fast gate green locally: assembleDebug, testDebugUnitTest, lintDebug, ktlintCheck, detekt, compileDebugAndroidTestKotlin.
## What
Unifies `FolderRole`'s two hand-maintained RFC 6154 attribute tables into a single source of truth, and adds `\Important` (RFC 8457) to it.
### #65 — one attribute-to-role table
Before, the companion held two tables that had already drifted:
- `roleOf`'s attribute `when`-ladder (`\Sent`→SENT, `\Drafts`→DRAFTS, `\Junk`→SPAM, `\Trash`→TRASH, `\Archive`→ARCHIVE), and
- a separate `SPECIAL_USE_ATTRIBUTES` set for `isServerSpecial` that also listed `\All` and `\Flagged` — attributes with **no** role branch, so the two disagreed (e.g. a localized Gmail "All Mail" advertising `\All` was server-special yet classified NORMAL).
Both now read from one ordered `ATTRIBUTE_ROLES: Map<String, FolderRole?>` (a `null` value = server-special but role-less):
- `roleOf` = first role-bearing entry the folder advertises (insertion order preserves the old ladder's precedence),
- `isServerSpecial` = the folder advertises any key.
Behavior-preserving: every existing attribute keeps its exact `(role, specialUse)`. PR #113's fidelity tests stay green.
### #62 — add `\Important`
Adds `"\important" to null` as one more role-less special-use key. Gmail advertises `\Important` on `[Gmail]/Important`; it's now recognized as server-provisioned, so the drawer de-dup renders `Important - Gmail` instead of leaking the raw `Important ([Gmail])` namespace form.
## Migration
None. The addition is purely additive — no `(role, specialUse)` mapping changed for any existing attribute, and `specialUse` remains a plain Boolean column re-derived from the server LIST response on the next folder refresh. No `specialUse` encoding change, so no Room migration.
## Tests
- `FolderRoleTest`: `\Important` in the `isServerSpecial` cases; a comprehensive table assertion pinning every attribute's `(role, specialUse)` incl. `\Important`; a table-order precedence guard; and a role-less-fallback guard (`\All`/`\Important` don't suppress the display-name role).
- `FolderMapperTest`: extends the #64 role-less family (`\All`, `\Flagged`) with `\Important` at the `FetchedFolder.toEntity` mapper level.
Fast gate green locally: `assembleDebug`, `testDebugUnitTest`, `lintDebug`, `ktlintCheck`, `detekt`, `compileDebugAndroidTestKotlin`.
Closes #65
Closes #62
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
What
Unifies
FolderRole's two hand-maintained RFC 6154 attribute tables into a single source of truth, and adds\Important(RFC 8457) to it.#65 — one attribute-to-role table
Before, the companion held two tables that had already drifted:
roleOf's attributewhen-ladder (\Sent→SENT,\Drafts→DRAFTS,\Junk→SPAM,\Trash→TRASH,\Archive→ARCHIVE), andSPECIAL_USE_ATTRIBUTESset forisServerSpecialthat also listed\Alland\Flagged— attributes with no role branch, so the two disagreed (e.g. a localized Gmail "All Mail" advertising\Allwas server-special yet classified NORMAL).Both now read from one ordered
ATTRIBUTE_ROLES: Map<String, FolderRole?>(anullvalue = server-special but role-less):roleOf= first role-bearing entry the folder advertises (insertion order preserves the old ladder's precedence),isServerSpecial= the folder advertises any key.Behavior-preserving: every existing attribute keeps its exact
(role, specialUse). PR #113's fidelity tests stay green.#62 — add
\ImportantAdds
"\important" to nullas one more role-less special-use key. Gmail advertises\Importanton[Gmail]/Important; it's now recognized as server-provisioned, so the drawer de-dup rendersImportant - Gmailinstead of leaking the rawImportant ([Gmail])namespace form.Migration
None. The addition is purely additive — no
(role, specialUse)mapping changed for any existing attribute, andspecialUseremains a plain Boolean column re-derived from the server LIST response on the next folder refresh. NospecialUseencoding change, so no Room migration.Tests
FolderRoleTest:\Importantin theisServerSpecialcases; a comprehensive table assertion pinning every attribute's(role, specialUse)incl.\Important; a table-order precedence guard; and a role-less-fallback guard (\All/\Importantdon't suppress the display-name role).FolderMapperTest: extends the #64 role-less family (\All,\Flagged) with\Importantat theFetchedFolder.toEntitymapper level.Fast gate green locally:
assembleDebug,testDebugUnitTest,lintDebug,ktlintCheck,detekt,compileDebugAndroidTestKotlin.Closes #65
Closes #62
🤖 Generated with Claude Code